From a2af0aa1ad55a8b86bdea27eb0e90335d21658fd Mon Sep 17 00:00:00 2001 From: Rahim Rahman Date: Wed, 13 Nov 2024 12:48:17 -0700 Subject: [PATCH 01/36] chore: patch getBuildSettings to allow run ios from cli (#8345) --- ...-community+cli-platform-apple+13.6.9.patch | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 patches/@react-native-community+cli-platform-apple+13.6.9.patch diff --git a/patches/@react-native-community+cli-platform-apple+13.6.9.patch b/patches/@react-native-community+cli-platform-apple+13.6.9.patch new file mode 100644 index 00000000000..2a688950b96 --- /dev/null +++ b/patches/@react-native-community+cli-platform-apple+13.6.9.patch @@ -0,0 +1,22 @@ +diff --git a/node_modules/@react-native-community/cli-platform-apple/build/commands/runCommand/getBuildSettings.js b/node_modules/@react-native-community/cli-platform-apple/build/commands/runCommand/getBuildSettings.js +index 147bb53..b7cb80c 100644 +--- a/node_modules/@react-native-community/cli-platform-apple/build/commands/runCommand/getBuildSettings.js ++++ b/node_modules/@react-native-community/cli-platform-apple/build/commands/runCommand/getBuildSettings.js +@@ -31,10 +31,16 @@ async function getBuildSettings(xcodeProject, mode, buildOutput, scheme, target) + encoding: 'utf8' + }); + const settings = JSON.parse(buildSettings); ++ const fistIndexForAppTarget = Math.max( ++ 0, ++ settings.findIndex(({ ++ buildSettings: bs ++ }) => bs.WRAPPER_EXTENSION === 'app') ++ ); + const targets = settings.map(({ + target: settingsTarget + }) => settingsTarget); +- let selectedTarget = targets[0]; ++ let selectedTarget = targets[fistIndexForAppTarget]; + if (target) { + if (!targets.includes(target)) { + _cliTools().logger.info(`Target ${_chalk().default.bold(target)} not found for scheme ${_chalk().default.bold(scheme)}, automatically selected target ${_chalk().default.bold(selectedTarget)}`); From 700c7086793b671af3de37008a79cd0bf0d345eb Mon Sep 17 00:00:00 2001 From: "unified-ci-app[bot]" <121569378+unified-ci-app[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 07:59:05 -0500 Subject: [PATCH 02/36] Bump app build number to 575 (#8350) Co-authored-by: runner --- android/app/build.gradle | 2 +- ios/Mattermost.xcodeproj/project.pbxproj | 8 ++++---- ios/Mattermost/Info.plist | 2 +- ios/MattermostShare/Info.plist | 2 +- ios/NotificationService/Info.plist | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 27b27383843..2c5dcfd5a75 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -111,7 +111,7 @@ android { applicationId "com.mattermost.rnbeta" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 572 + versionCode 575 versionName "2.22.0" testBuildType System.getProperty('testBuildType', 'debug') testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' diff --git a/ios/Mattermost.xcodeproj/project.pbxproj b/ios/Mattermost.xcodeproj/project.pbxproj index 4209dbbdabf..649483d979a 100644 --- a/ios/Mattermost.xcodeproj/project.pbxproj +++ b/ios/Mattermost.xcodeproj/project.pbxproj @@ -1984,7 +1984,7 @@ CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 572; + CURRENT_PROJECT_VERSION = 575; DEVELOPMENT_TEAM = UQ8HT4Q2XM; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = "$(inherited)"; @@ -2026,7 +2026,7 @@ CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 572; + CURRENT_PROJECT_VERSION = 575; DEVELOPMENT_TEAM = UQ8HT4Q2XM; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = "$(inherited)"; @@ -2169,7 +2169,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 572; + CURRENT_PROJECT_VERSION = 575; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = UQ8HT4Q2XM; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2219,7 +2219,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 572; + CURRENT_PROJECT_VERSION = 575; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = UQ8HT4Q2XM; GCC_C_LANGUAGE_STANDARD = gnu11; diff --git a/ios/Mattermost/Info.plist b/ios/Mattermost/Info.plist index dc787296f1b..64696aca29c 100644 --- a/ios/Mattermost/Info.plist +++ b/ios/Mattermost/Info.plist @@ -37,7 +37,7 @@ CFBundleVersion - 572 + 575 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/ios/MattermostShare/Info.plist b/ios/MattermostShare/Info.plist index ea978e7dee6..11577dbf3ed 100644 --- a/ios/MattermostShare/Info.plist +++ b/ios/MattermostShare/Info.plist @@ -21,7 +21,7 @@ CFBundleShortVersionString 2.22.0 CFBundleVersion - 572 + 575 UIAppFonts OpenSans-Bold.ttf diff --git a/ios/NotificationService/Info.plist b/ios/NotificationService/Info.plist index 1826f677e2b..1dc200eff87 100644 --- a/ios/NotificationService/Info.plist +++ b/ios/NotificationService/Info.plist @@ -21,7 +21,7 @@ CFBundleShortVersionString 2.22.0 CFBundleVersion - 572 + 575 NSExtension NSExtensionPointIdentifier From 1f28e9bd8b467c37480732011ad752f2d2b8c1ee Mon Sep 17 00:00:00 2001 From: Amy Blais <29708087+amyblais@users.noreply.github.com> Date: Fri, 15 Nov 2024 08:05:22 -0500 Subject: [PATCH 03/36] Update README.md (#8330) * Update README.md * Update full_description.txt * Update changelog --- README.md | 2 +- fastlane/metadata/android/en-US/full_description.txt | 2 +- fastlane/metadata/changelog | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 58e94e0d6e9..aebddd09245 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Mattermost Mobile v2 -- **Minimum Server versions:** Current ESR version (9.5.0+) +- **Minimum Server versions:** Current ESR version (9.11.0+) - **Supported iOS versions:** 13.4+ - **Supported Android versions:** 7.0+ diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 94884795fe9..55042eadc75 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -1,4 +1,4 @@ -Requires Mattermost Server v9.5.0+. Older servers may not be able to connect or have unexpected behavior. +Requires Mattermost Server v9.11.0+. Older servers may not be able to connect or have unexpected behavior. ------- diff --git a/fastlane/metadata/changelog b/fastlane/metadata/changelog index 98f32ca401a..740a94bc53f 100644 --- a/fastlane/metadata/changelog +++ b/fastlane/metadata/changelog @@ -1,4 +1,4 @@ -This version is compatible with Mattermost servers v9.5.0+. +This version is compatible with Mattermost servers v9.11.0+. Please see [changelog](https://docs.mattermost.com/administration/mobile-changelog.html) for full release notes. If you're interested in helping beta test upcoming versions before they are released, please see our [documentation](https://github.com/mattermost/mattermost-mobile#testing). From 0efa409023b11fdf055be79d82d7ce8ed9f9e927 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Fri, 15 Nov 2024 12:23:44 -0500 Subject: [PATCH 04/36] MM-61148 Rewrite table parsing and improve error handling around Markdown code (#8300) * MM-61148 Rewrite table parsing based off cmark-gfm * MM-61148 Add better error handling to Markdown code * Use logError instead of console.error * Switch back to published release * Update import paths --- app/components/markdown/error_boundary.tsx | 3 +- app/components/markdown/markdown.test.tsx | 140 +++++++++++++++++++++ app/components/markdown/markdown.tsx | 92 ++++++++++---- assets/base/i18n/en.json | 2 + package-lock.json | 8 +- package.json | 2 +- 6 files changed, 217 insertions(+), 30 deletions(-) create mode 100644 app/components/markdown/markdown.test.tsx diff --git a/app/components/markdown/error_boundary.tsx b/app/components/markdown/error_boundary.tsx index 0dffd3d7917..282e22a95f4 100644 --- a/app/components/markdown/error_boundary.tsx +++ b/app/components/markdown/error_boundary.tsx @@ -27,7 +27,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ }, })); -class ErrorBoundary extends React.PureComponent { +class ErrorBoundary extends React.PureComponent { constructor(props: Props) { super(props); this.state = {hasError: false}; @@ -38,7 +38,6 @@ class ErrorBoundary extends React.PureComponent { } render() { - // eslint-disable-next-line react/prop-types const {children, error, theme} = this.props; const {hasError} = this.state; const style = getStyleSheet(theme); diff --git a/app/components/markdown/markdown.test.tsx b/app/components/markdown/markdown.test.tsx new file mode 100644 index 00000000000..804a369165d --- /dev/null +++ b/app/components/markdown/markdown.test.tsx @@ -0,0 +1,140 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {screen} from '@testing-library/react-native'; +import * as CommonMark from 'commonmark'; +const {Node} = CommonMark; +import React from 'react'; + +import {Preferences} from '@constants'; +import {renderWithIntl} from '@test/intl-test-helper'; + +import Markdown from './markdown'; +import * as Transforms from './transform'; + +const Parser = jest.requireActual('commonmark').Parser; + +describe('Markdown', () => { + const baseProps: React.ComponentProps = { + baseTextStyle: {}, + enableInlineLatex: true, + enableLatex: true, + location: 'somewhere?', + maxNodes: 2000, + theme: Preferences.THEMES.denim, + }; + + describe('error handling', () => { + test('should render Markdown normally', () => { + renderWithIntl( + , + ); + + expect(screen.getByText('This is a test')).toBeVisible(); + }); + + test('should catch errors when parsing Markdown', () => { + jest.spyOn(CommonMark, 'Parser').mockImplementation(() => { + const parser = new Parser(); + parser.incorporateLine = () => { + throw new Error('test error'); + }; + return parser; + }); + + renderWithIntl( + , + ); + + expect(screen.queryByText('This is a text')).not.toBeVisible(); + expect(screen.getByText('An error occurred while parsing this text')).toBeVisible(); + }); + + test('should catch errors when parsing Markdown', () => { + jest.spyOn(CommonMark, 'Parser').mockImplementation(() => { + const parser = new Parser(); + parser.incorporateLine = () => { + throw new Error('test error'); + }; + return parser; + }); + + renderWithIntl( + , + ); + + expect(screen.queryByText('This is a text')).not.toBeVisible(); + expect(screen.getByText('An error occurred while parsing this text')).toBeVisible(); + }); + + test('should catch errors when transforming Markdown', () => { + jest.spyOn(Transforms, 'highlightMentions').mockImplementation(() => { + throw new Error('test error'); + }); + + renderWithIntl( + , + ); + + expect(screen.queryByText('This is a text')).not.toBeVisible(); + expect(screen.getByText('An error occurred while parsing this text')).toBeVisible(); + }); + + test('should catch errors when rendering Markdown', () => { + jest.spyOn(CommonMark, 'Parser').mockImplementation(() => { + const parser = new Parser(); + parser.parse = () => { + // This replicates what was returned by the parser to cause MM-61148 + const document = new Node('document'); + + const paragraph = new Node('paragraph'); + (paragraph as any)._string_content = 'some text'; + + document.appendChild(new Node('table')); + + return document; + }; + return parser; + }); + + renderWithIntl( + , + ); + + expect(screen.queryByText('This is a text')).not.toBeVisible(); + expect(screen.getByText('An error occurred while rendering this text')).toBeVisible(); + }); + + test('should catch errors when with Latex', () => { + const value = + '```latex\n' + + '\\\\\\\\asdfasdfasdf\n' + + '```\n'; + + renderWithIntl( + , + ); + + expect(screen.queryByText('This is a text')).not.toBeVisible(); + expect(screen.getByText('An error occurred while rendering this text')).toBeVisible(); + }); + }); +}); diff --git a/app/components/markdown/markdown.tsx b/app/components/markdown/markdown.tsx index c507797eaf4..934e7cdfb01 100644 --- a/app/components/markdown/markdown.tsx +++ b/app/components/markdown/markdown.tsx @@ -10,8 +10,10 @@ import {Dimensions, type GestureResponderEvent, Platform, type StyleProp, StyleS import CompassIcon from '@components/compass_icon'; import Emoji from '@components/emoji'; import FormattedText from '@components/formatted_text'; +import {logError} from '@utils/log'; import {computeTextStyle} from '@utils/markdown'; import {blendColors, changeOpacity, concatStyles, makeStyleSheetFromTheme} from '@utils/theme'; +import {typography} from '@utils/typography'; import {getScheme} from '@utils/url'; import AtMention from './at_mention'; @@ -98,6 +100,10 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { color: editedColor, opacity: editedOpacity, }, + errorMessage: { + color: theme.errorTextColor, + ...typography('Body', 100), + }, maxNodesWarning: { color: theme.errorTextColor, }, @@ -606,34 +612,74 @@ const Markdown = ({ const parser = useRef(new Parser({urlFilter, minimumHashtagLength})).current; const renderer = useMemo(createRenderer, [theme, textStyles]); - let ast = parser.parse(value.toString()); - - ast = combineTextNodes(ast); - ast = addListItemIndices(ast); - ast = pullOutImages(ast); - ast = parseTaskLists(ast); - if (mentionKeys) { - ast = highlightMentions(ast, mentionKeys); - } - if (highlightKeys) { - ast = highlightWithoutNotification(ast, highlightKeys); - } - if (searchPatterns) { - ast = highlightSearchPatterns(ast, searchPatterns); + + const errorLogged = useRef(false); + + let ast; + try { + ast = parser.parse(value.toString()); + + ast = combineTextNodes(ast); + ast = addListItemIndices(ast); + ast = pullOutImages(ast); + ast = parseTaskLists(ast); + if (mentionKeys) { + ast = highlightMentions(ast, mentionKeys); + } + if (highlightKeys) { + ast = highlightWithoutNotification(ast, highlightKeys); + } + if (searchPatterns) { + ast = highlightSearchPatterns(ast, searchPatterns); + } + + if (isEdited) { + const editIndicatorNode = new Node('edited_indicator'); + if (ast.lastChild && ['heading', 'paragraph'].includes(ast.lastChild.type)) { + ast.appendChild(editIndicatorNode); + } else { + const node = new Node('paragraph'); + node.appendChild(editIndicatorNode); + + ast.appendChild(node); + } + } + } catch (e) { + if (!errorLogged.current) { + logError('An error occurred while parsing Markdown', e); + + errorLogged.current = true; + } + + return ( + + ); } - if (isEdited) { - const editIndicatorNode = new Node('edited_indicator'); - if (ast.lastChild && ['heading', 'paragraph'].includes(ast.lastChild.type)) { - ast.appendChild(editIndicatorNode); - } else { - const node = new Node('paragraph'); - node.appendChild(editIndicatorNode); - ast.appendChild(node); + let output; + try { + output = renderer.render(ast); + } catch (e) { + if (!errorLogged.current) { + logError('An error occurred while rendering Markdown', e); + + errorLogged.current = true; } + + return ( + + ); } - return renderer.render(ast) as JSX.Element; + return output; }; export default Markdown; diff --git a/assets/base/i18n/en.json b/assets/base/i18n/en.json index 7741aebb8ea..76f2e399ed9 100644 --- a/assets/base/i18n/en.json +++ b/assets/base/i18n/en.json @@ -454,6 +454,8 @@ "login.username": "Username", "markdown.latex.error": "Latex render error", "markdown.max_nodes.error": "This message is too long to by shown fully on a mobile device. Please view it on desktop or contact an admin to increase this limit.", + "markdown.parse_error": "An error occurred while parsing this text", + "markdown.render_error": "An error occurred while rendering this text", "mentions.empty.paragraph": "You'll see messages here when someone mentions you or uses terms you're monitoring.", "mentions.empty.title": "No Mentions yet", "mobile.about.appVersion": "App Version: {version} (Build {number})", diff --git a/package-lock.json b/package-lock.json index 7256e058e52..f52d439905f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "@stream-io/flat-list-mvcp": "0.10.3", "@voximplant/react-native-foreground-service": "3.0.2", "base-64": "1.0.0", - "commonmark": "npm:@mattermost/commonmark@0.30.1-3", + "commonmark": "npm:@mattermost/commonmark@0.30.1-4", "commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#81b5d27509652bae50b4b510ede777dd3bd923cf", "deep-equal": "2.2.3", "deepmerge": "4.3.1", @@ -12057,9 +12057,9 @@ }, "node_modules/commonmark": { "name": "@mattermost/commonmark", - "version": "0.30.1-3", - "resolved": "https://registry.npmjs.org/@mattermost/commonmark/-/commonmark-0.30.1-3.tgz", - "integrity": "sha512-Kjsl/sZmb6R6PtpPVIifPfqBMrKs7z6Tukb1TJl/S0LfC5uNici3yol4waGxhGsJuvCF2kZqStwVQP7ieUbAgw==", + "version": "0.30.1-4", + "resolved": "https://registry.npmjs.org/@mattermost/commonmark/-/commonmark-0.30.1-4.tgz", + "integrity": "sha512-7O1xQfP3ILHf/+wjrxwF0rqowuvqQ7EY+SJOWsDaV+VXdj+lmft9yxkL0QPNYALinKFdPEj1gFtgR+pi4w8lzQ==", "dependencies": { "entities": "~3.0.1", "mdurl": "~1.0.1", diff --git a/package.json b/package.json index c8fd07de064..3ca3e2a2aef 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@stream-io/flat-list-mvcp": "0.10.3", "@voximplant/react-native-foreground-service": "3.0.2", "base-64": "1.0.0", - "commonmark": "npm:@mattermost/commonmark@0.30.1-3", + "commonmark": "npm:@mattermost/commonmark@0.30.1-4", "commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#81b5d27509652bae50b4b510ede777dd3bd923cf", "deep-equal": "2.2.3", "deepmerge": "4.3.1", From 97788aa22f5a7b2524292e56fc82a9c3efeae2a0 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Sat, 16 Nov 2024 06:53:36 +0800 Subject: [PATCH 05/36] include EMM/MDM integration in the arch diagram (#8327) --- docs/architecture-diagram.monopic | Bin 9584 -> 10583 bytes docs/architecture-diagram.png | Bin 249781 -> 600584 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/architecture-diagram.monopic b/docs/architecture-diagram.monopic index 55f14d1d04acfe361b50c0ce678deec67da418f9..843e25d90139768e83bc74fc9a9f9c8344008e0e 100644 GIT binary patch literal 10583 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 literal 9584 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 adB{pH`rl7JCN<0F&;JiJ#)2$cE&>3}W~?{> diff --git a/docs/architecture-diagram.png b/docs/architecture-diagram.png index 30ffb837a9f27fb9445456ab3d6a97071d60942c..54f58352a807cd66b622a4ae4aaebdd167250fa3 100644 GIT binary patch literal 600584 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�WaNP5&e}RXoal||ciGl9YyqV{% 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 z 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

8((KDKLd7l;x51Ya;UWxLFRq5mdswfH( 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

lVEXf{eC-Jv#GMnB=+LCze#96f7cMT>& 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

D^Zy#YBshnEymy{v>aE}H14#RNDRZ^;kq_bci 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

2AWQV2b7q8iSv4}f6_|y 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 literal 249781 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�Whx`8Rt^DV)hPGB|9OFmDkUM3q zG*%x*N^qjv8~2WxdslQ`1Cm0#G9QP zww+e;)}Gx>2|eE7%rjSDo~{_}+S)5*beU?r);n-8ObaQ}pD^9E{EAx>pyPU|?Y>Rxed~S02_1FzZc)bZ&)l#zD zl8jLai|gO>*^b~lYKduaPKSD6&zU*~BFxLrQ@Cw~vAga(eZkAab?0DoNAW59cSm%4 zz0IzF-~YE;lI1o|d&}hxP-)l~LZZw>Ciyh=4EX^@a`^Pb)n0p6`clrkAV8n<5h=c7 z*&z+i$wOi@Mr|`94FRxnZY`&XvCgcfj(T-L{ZGmAsvuV1_a)5mw1e55WO;8GhqOAU zcqgs&?mhm0e0RpD7A{)!_pbFrJN$1~3_h-08*W8^`iEfe($Ny&E?TtIEh6^5YnAp zf8d=<^6dmDkru@Xs6&+spU%+Ga&xW8H5U>^dy(h-TD`^}hY8SIl87n?0!WI!d*o@l zy!|v%-a`UM;cap^iVZF|G~^kjQWi& zTqLN5t%H#^6h^YZ0yjeSE7SurQqsn?hZzH9wNBADA&C=Q*Y80-H@2Ds0u6W-!$M!P z65Fms?^RGcOqo-oOt+r=dv8iWorEIl><8Kf>DU^}te?)3&Qw&z?{_%;ChK|`W)pg9YAMYg=58a79Yf~!H` z7o-=9>uG`+M3<(j%};yVGzVOPr<-wE~BH}{xPRjSyZg<+-G9y*J8 zAA*z0I5@yk+?M*-139sLfDf5MKlBdnzc$Z%pk^fQl=O5=FPvnvmyu^g?xBD)lOS2o zf!Tuvd37L7jyS76{DZ7TQMpJ~bv_YcD;x!V87_bD%F@H(L+XZZM3-neGHn72+c_n& ze%K%on%OI$d`qK`%9bVt8aUdy?JYova#0SSw+)}&^i9fFs$AmVqQa@0S9r?Se1IZz z236M=BwO460Eo~_8QWJGk{Te*vql*!w6iEQ>wD0vTM*(s9HBun0}O^Wq9(^xesSsf z_@vRRG?M|BIJ3?%DV|_0bG5p8g!|mVK(}l3&u$@-wDW{0$FO7 z6iyZ>zl)v*qd?{q7f*+PN=1*>Y+Q@s68Y&P^t zT_+}osdt~mf7$+iofg7t#C~7CMmf&j3n~L?&g_n(`g@X}WSbHbPCJ{T(KjMouSXB) zPuC*&>r*V`g4~3{tnRH4M9|J2%uE$Hf9yvB= z!|6h?Q22a>uFoZOPN#7F(vM>Kzm%VHg1AoSwRJXtYu@72`0<1a$I`(eDse8*=4~kc z(nM>O$Va5)A#IZgY=3oae-9|G6gl?`fefwV5#R=49-5f|K{4i{7{@+@G@5~^Ew_%d zD1SJH1~S@3<*dT8&$t99df?&<(~|ApELPESBbp-BTCme|z#u-TJf@HCK!lKa5$r;N z^@lGFKHwe)&fEZH{X2tyo?!ehPO?ZEI7z8$jf95<*5idq3>iMIdZ&8UttX<>&#^_7 z3Yb~XXZdy579XBi{@}FJ(q2{2!ict2l!;qs18en1+-21?(E{CDmTr<~+y>i{FeOq@ zq8!Cfe1%^RjezSE|Vl2!wpIbjWE%GQnEnd%!Jb+wXnaA z20uWNLeg~!Q>RdH-@%joox3O^X6j@50C-mQrNxUW47|opFTU=N;g?Y4>$-VVC@V39 zAL`lLIB>Tse-%6nqg)*U9k{i}mJ1SN)A;()FfQ}X3_3eO2O}tfWMsVhEPxsJw={?J zpxI8bbswREhKoJkJXE9m?QHs;N2V%S!nS{|Dn-izTUl)YgkHPHO{#&3N{YwiM6eI`a=4Jp((?cezIr zhW!Clxwke1-!7aKdRS8)n_YnGD9iTOqbjV-=tu3-VJ)ZB546kbwcMXum_M^$0t5Tn z>}NP!pFg1NUQfucxv;SW7%Wq?)lfQ=kw9Ly0xEej3(SO_pcj7mAo(Zn#N9klES_gS z*MAWR8*bY%{|wNu-44&!ZXJ2uTxc3_7{DWXT3b-o@F#oV~GJs9ECqqbG4k-D}E!FgwZXSSvV-|9D7u zfoyLHKl#V(BpstfT?!(~l3spDLQ*pKk23 z1>WrRNdDf1(&|!>!G)Ap>PHhSvS7^4I>Vn=lL>nFw@(g_*9APFydO)Vv1Y?1Ot>)m zgTYa+`0h@`c}ALrvF*g!TOJPg!W;9T0z(pD$Pa7NdmHQ>{eo9ipP0o8hh+2gt!Z$U zn_iK>1#{@WVu%^Yuv&Ga8>(G%q=@by#mIWr?~G2||HN(d4iSX;nl6z; z-r&HC8@#IBp6;4EVfcKNC3}8`!b<3Fl%6wJo9)c02_r9cnmHrRfwEPr=@3D;Q@;Ey zOYe7!?-(mmNXpij7I|0O*IL_Ngi?eXK?7ggo=7--a50L|L$>vwyB-`Ts!-Yyn7Q2i+Pc%RdkV#qxDMM z?tPU4l`b6wtZ5%pLTrxXRBpW|KM6xp5bND_7{%u&7eM)*iGgCU-1pT-f-6nIIOmTf z)8CDH_t?63UTVR48z@Kfv{B>)f{gL-H&&ip6~`>xK)zFz5*~bB`~mD&{a2C9FblfyO3FGDp=Z$!7sU1Om9F9- z#Am7D1>u?S!EDJ}OkQYWejM<)`OFIjt~* z(mpyQMrHUbB3kSKL0kXeZk}E=%bP6!<}uibyCELt8ScA0`hx@TBAmAz>5lt^8{Ld1 zvelXcRSwg=l4*c{FADG|s=))ERQN-q^WQET3%i>X+$Sb*pCAMQPHwh+Zm!8E*sjTb z+lNaiCH%S@xePpwpqAE0;paCP7+ytD?!PhJ10#{RIZpe(!Oa6db2i9l!d^>Gnq?qW z&1jG?DpYTB+%FYcWQRIaG&zkH%VdLk$%qpMmVG0^ryVpY=?he!*^XGiWSP0!D zZU|p>CD_2eNLWGL0N7`H0K|T&t2od@O9b`A^ol10NAVs>?!4iF5-2pFB?A@tjYD4n zMm7?xH6?Dzfh~>W_8L>`n>i)zHcoR*@K30y%vhM}Or$-}Oz50R8Iw_QaeXg(cW>M|dbk#Z@H)a1rTq|@e|5B3nf zvfGzJ(S3&mU$S}`Y7=M|hfQG^O5D>@uxq>ni2o0AP%><9*&bS8&N!!&uKz0wpuCLa z!+KbfU<;ibIYA^0M})zydpc~LWl=sdZgHUynp454werk>Xk#n6euZGZ#hVmfIf9ip zb=J+I1RD&{+(4fgVnnJHR|H(=AphZhKLGB-O%rC?G>ocTQs1Id#i#$yN!ady+ki*p zMDTYMV3321@rJGpLuk$v?zyu@x#cN7!v&3-fPa~TN&Q9LZJj4Q;B4jU!$-gqLcd@5$+Bh<3GXgIicWNJdp z`pLT6jges_VuHIs0OS-tajemW`3kd@1R~59;Eos$Ww*pylIQTKB}_CKN0?JH2r38K zcnU$t$ye<*x${e)-tUHODP{F8VIkMoNuaoIW8U0szQxGf2VAT4%DO>aysP{|eU&Ws zGC-kClEb@nEhK4?w5NGlZ+ZKfeDTeudm9 zKETF}P+9K_YN0H{dpYt4Uky7VSWIQ58Z`c;le)v><=vDLT|>d0#v*Qx7Hi} z(!A4ZwB1(;8|)RGxS2jVA@8fxx%`?_wLP6^9W}~0w=CZLKV4mRqvdav!L&W3w* zMd29hCc_PgIq{)O{cx}&B?Ni z84<0tBpu2n^e777#L=7U$flH{Maa5)32lxN{+ZcWZiQ6>c;hkW@!4-?lp}dj1iyoo z@ug=W=(S;Qq((sd#k+0Q${nCprcOQ>@^ZQ2-WxLXy$sy^xyOuRm(g-Ill;K6yZgg} zyrSi;UkRYU9TlOScIGiHSeO(`!bny&DQ&A_mlCSDOdaJzk|#UxwvbYlI2bPNg&90j zd<3xTa*1=0<2-Zx2UrQetWuaZ)h`d~*2XFbcDp`wdPc-OOcY(0kNB1YKCg5UJ}WH$ z6I{Q0G5zJJ&gT^3zTMnIjEGl;8zdc#P^2D8mEXC!!a){mEEGL7DCOjYn4=n2igB)lc z_c8>&-h}-D;e2@M(S*M}B2+F#=n`LFM14{j#306Zp2V5x=MY4`Ga;v%EGBebF@=*5%y(r?;u7S`Qxc8$s_ zT&}2Dhnv6vNWvt9r(Oi?3M4LlwXs4V3wZ)?T4wJg7iD}R*?(OlH+SF*K6fV^_#b|X zQ50qF<)IWHkc^x_W5|t1@w#Aw>NF_&IrI8AQKBKr`A-9U-pb^m*Kb$r_ci?S>4;g( zQAsg7|Nc*JOD021LcaP*2SAFUPP;JGmKb0=-Fa5unBW4FRH!Zpk*p<;qs|9m&v1Wa zrRH(+DJxvhMUgY@d@#^6FR1+5k)9!GGf1M#oxfo&)UjNv1OtwKy?lZJ?s;EFP?e`b z_X!yo*w^3sEL;|;ia;S@hC+Nn6)7D33rPo$R;d2-chN5EHB2&*cVK3P{n~|SegM+V zl2dafSatxo?tvtiAipnfZ;&F95lM^x;fhB4|HIx}MrGM#YV~uC96z}`W z^PKaTN9>xy-3SK`2U3pL`SMzg-9|J_G{Pt_1>Dvz#Ige1iOrl|gSF4(HJD4MfK?#s zLHCc)9{F!>z|YsC2hU$Ien?|K&99S!AsUe~#OpwLSc9ZV*a9et8j)#*RW^lyI)f%Z z^WvFKc;=`)hJk`4pvQ=dQ39|%o&k}K*qbA!L?n{MM@+T4yjdIg|6H%9*dRqTMWKGk zy^+Iq?)JvCsf+42w>|`Fg30ov8LF3EJAi&e8nTxKB6!gt2b{=sg*BE9cHwd8*~O)% zCU1lS4;fXuF3Nf*txFl-n}LwBrq*x&A@aLk!YO1;)Y1I#%GKno{et38MA&vieJ~Bs za29y#RM2MsXT()d4Em=lZZSWG>}Zv|B6y^kdO#6d-IE9nxS&;w=G&b6Xb=YQF}PBx z`kdxdqt5yXBu|;TY=k7w0uL|;FsyU9;>a>vhHMC8p5&U zzgIa|38~xLn`_qaP<1os_h^GK-&3J+0~9rHpA2ik_*=x7piB>OHPX!m{kB``NFWKy2km8np_su2Qy{NtX-J zvK5qQjiv@@76@gj%!r!B2Vnm6N*ta~zDRds2I;S|d4y7L_&?zCd%-#7XjAP^pIKSv zmDUYZu=W%x%%ms>-m`~NvK};XfyfN!4{WZO2bgG@rb;4Jv$tg$p}_Aq=l5Fs!JiURi)O3os8pkv zCRXr=IhX&Ouooqzkm*k`OfJ|mKt8<&((x$y;y(?rBAn+%$Sk zjsl3yU&jtRPe_tj+qf1O_ds&yy(^5OPh#?+Eb1mzQu}te#^}>Jw5^txNrKzGZ38l4 z{=sp#ky7cZuhaj)m{_0%GYu2&&kLj%|T0bqXkO>wUl-C!{=^Ov5&+8`Q(i;kE;wIsD;}L}bt~YRNX`*nVv< zKaA+AMJ~4Wa0k?ZOF->EbQa%{80f|lwe!J<%|_Xw(<4XDTFxt z^qC*4fgr~3*xAZ`upFxBb%eOTt7ZkqhF#3~y)nW3S$M9#vEK*Cn&`#c2uxw5J1>pk zyubSu6LcH%K2eSJ8$xv>soje`wu?T)I8HBM(71be~lfCIZ6%x!yg= z@A&qTNe@?5%+6_!du>x?`*HdRc>C4C&1|upz<;n;jsnsJbrA*DF{?X5z{Q#AI%^RQ zGB;PtLJAZ5bi|E{b$T9e$l2_a*w}ubK_FUMzwcwe>cg}Gss6{2Y!V=GIsVptP>x|S z{A-^t{=Z)+^upmw!o||Ei%Y$})4~nWyYeFjPH{Z-|mFkGZZAFvnXi>Am&_9 z&t6AErSuRYQ=eq0+mE-cY#UqnT4258NFy~LK|%)G#UM9g=X#~h59g@q;?O5tiy zDy@sHCo82(2UkSUi8z$9{6yQ~b0QgzbQmV5B0~?9<58$c8cjIwH4BUB$&Wp-?R7Y} z@WP@CAc}PwYA|4NTfok5#?x{t@Fb@FtYIQaSBv%gkp8^>f1LmhqT@w!CH^X>T@&z@ zAPp16;DBXh3BqtQf$y)X2T4cwrnu}zmCDuwBwyZDs$q8kNc%YoY~DUU-FA&T1ZqSC zuC0I}Xk4x4lNGs}^?&s(czCv0voI2zM%6h`E&NqkVS;3OlEdhHiQ^?y6l;G}R8k-A zy4R5rbqX%paGQ0U*T;IB2JTVvZs=T$p$usQn6$&&P(DryI_3|u$4_WvfzHY-X>7L;Z zjP~>7rMW)=aa|v>;A1x&!R7)_7ypZfu*ctJnFOT-R{Ax%Z-%{v_pdXuAXAZ&j$G?$ zmDLYG5$Dr`?k%_Bb-OjF#$dfD>KFyDn)}P3k>m-CTRhCSB$E=BvDj;z*ZCPN8?C`n z<28z2JSSuUmUJle#nS27r58Cd+zZGH7P+p-dV&T=lT&F1ob~BdOo8Gw1=wLez{9iw zLxlgis0ZVeg-20WkN>`0UhlvQ6uD1j!^HI!)kG--&q+t}LfjAS%@^53=gUK|%b;1w z?6vN$gJqozF@L53XUl@xzZ)vZuouE>@a&(~WYQ`_bpd2M(Ndc<0Dl0KeDR zQB#k*tfl-bzuPoH-Lr(b4>;|d>B1L;wA)dTDofd>1?u!pK|Sf3;A9t2)rMkgKx6XE ziTY?D5-P#ff*9f(32e2FN~B9*myk*xwS8A(1GrQL+r>aK8qrj14&~@XL46xAPELh? zj3m&UN~a?@j@t3AE*>jM0G-T(F75+0)f>vUr!Vix0=-j%c7yC%T})UMDnHvHo5W(k>6kSb4mNx zbF`oWAb?g)=NIG&{LZ__ze4{rI;4$kT!`LtlUAR#Y?&VZ#vuCV-ce(d9J$Fzb2}Js zh^N07JT#3w@bKbF?D~M9jOGXHL+?@-z@w65j{FDd?;pP$UG||Huq|&NNc`_09nouF zVWf})a-(k0v>Ai1ZbECKe8qPE&V~!>5JxAWI@P)a!+oAIbKKuI>aRup*N-v*xRgVw z5;4~`f1k&{ROCq{t{|2S;jcpeIi0YG1%%dK_|MDk5n=$O!ocR&62wv5zHb#fyS=fg zcImow+L)eEZ(B37gFxdn1PCxft48$TSwn#s6IR3U9N=a6pLR`{l>{#X;G-U)2f*`d z6AZhc;P*xLk>CVn0Q9PC#D0VF_b!mQd_H)Dc0aM-1U~5ff>5FDctK@>k9j{(z+hYv zC(Y;*sk1M;*D@}D46Lc+wIDl*^|_?uDz*!{&i))&;f%3-&bB|g+TdR_-qs8#!)q^* zQeM+FP2ck*0Rxv%P@MQHzh=|N$BXbY4&aMB0Lx9JUHwPStSBE9;C&=&2oOUy92+8E zG|qJWI?N2CkL$zaPI8Bxk_-6L$RYT=W0%x*;-eYb4ET^#3&nWfaCu!2Qpw z*k6C@<@pY(Mk63G;jtjS50nSNFFyZsX(4D%3}ls_!G|_~l^N*ACZg}qAQ^!{7M>lb zrtYB0?lhn>aV|r&$S7+HdTOgGq@=n8?IE`}YKss$iB<-feFSn-a0pF5rx4)JumvQ_ zD8JX5;BtI9qJSX^2XyP%C@gUs)ea~UC60-Bq#V9OA61G_m^4F&MH+{%q}LcJv;r-C z2Z+b+!H1~c=0lav;10~LI-o!?hArxF?KL3tp{0kC0kb&TkPqcl7xbX;KRuM0+ss}F z4?m8j(4y-p>yGzJn+Sq`A2Ez$c~L}^l)C}{n@KQLXRT&63Bw0>$e!&e-Cn;p8k{zW zj4o`~U<(f(`NCEg2KhxV+!u$<8-eGCZ1GX1A<7|iyJ(KA)W8+iS0?DDa*NvOe{^#o zq&tO1@%kxq|Av_g9>+i>=Cd`svuzq|MbiQ!#Wc`n6oCdg6)?-p%W$cS#fvF-2OFRe z%(QeK1xx5$=vdza-|nz#mX7C*dI#hirUKi_-bp*Sphn=Gt6MKVX9l<`w@Y>Crjl@! zlm7$Jfmi^HDy}{|LE55o(|~BN-u>5TZUY1!!<+uZ@F&t0NrksL@8gmK$|!$x zq3DmGR(wll03USY1JcTlkl1701t=~tt6-^mb2GWpF7WFJ+aaNc{&kx)32K?K2rXHG zkvva6@;kQK`n*9mKN+#TL>olyI}1^o12=+dwgDyUsj;d$Vzp>s1ayh4L#KG&f+zDX z0ow|*<~Z?&=^vM7!6oeKM|xg;`&IrRDnA}z*UNZx!p4wJw41vaX5CfQ8b_x?v>@^7 zbv1SMt&H13NzFJnf+CRTmlK=l#ui{XW);nxp^euC&IxC?{bVY_Z*f+$ z2}vbx_rNjd$UY+Ya_Iigtp;C6F#0O%KfaR?aC@qp2w-|Lv05__@QYQI9^9Oq7nk0^-fGljY zz-zd>pWN)h!}Ge;{%pd1;Em9?3$ugXZVKZ4n5ru??N_Q>d;m{tf&sN2ShzKs$acW% zWTXjs1a7P)){)sWo?-qLB>jfcR!3#2ElLx;IQo^M6y{Ur`;q0c;>3NC76d zo*DQ(kdUV@XKKM6kGO}e30lQ$Xi}A-q*r^RBg!qUTadR3$G{bF(RqMS2T=t8G5@lH ziurIMJFyy2%eM6d%VJ>ahG6_%XC3|U@KM=ds_`_SyIisXeRPFLv4o6&11L_LsUMMp z>m(v}T*!~R5n%$jODu0V)Fj!r_U~fxZ2fP)crZs=Yp|cs&wSqb%vT{?!Y84C0q>FA6^fww;{I(2B;sH{0%PK z&0v_WFF&ML@+QFOwa?u{l=u2eOAxcS>K0S&_kcudZ+A#7DH8i)f2J0c#;o$?1|=5* z>yhLDit_u6%E;Z`D(sZqkZ<73M&fMd2q)2jd(V*;bM=&1E2L$X>L}8T(|u(ZJXMC7b24g#kTqjl7t`pl3!#| zM!L|!V$y=Ap<(+C$G!O0`LhJOD~ZBoEaqoZ%ybj4$_WsAi@q=%n}?q$f>r)NHyS?_ z0Hsm$RWyzSolLDYfIsCTIeiU)+w@<3PCkBE-ed>X#JA=z&VN=#{?hQfImkPYmd5Ck zHPJ*h^|oRuBJvOUim5IhGbPG-LzF6ZH&*u@O*DR%T6fXN>w8iI(U5uF+)}3FCnN4l zL8B%sKvVm9;q1HOO9IaRj|4@DUns9UWv@45?GO_LLBTdh>g^1f?e&Chn7@TNB%Uqp z143k1y35u*+WO_S%{6#I>NQ-p?z@cT5q$?JN#Kl7j0OuH+i<%#BT=Wle9kt4zoo&5 zD8fIZRRRNeP9iZ`MMNV$4v~Sxf#W&_{1t8!l^o1dmll-k=7$1tTlB|(=UK9{Ny71^!8QVc!U&?Q(A|qaG%onCOx{dC@`<>GrN4#Lz`UD8U zwJ^LZWlJRo{1r_*vFn4VC1zWbgG!)Yz#E2ca&&|j&vS=cM)mdKD&&#JrrpuMHDhB^ z?+lixUBKMkmS@_{bn z?R%^rOC{YU4AE8lZs@AFOpF-MdZM(o z5EMAD6C91m$iAUM=`|0{_vd=%;1fFw597 ztLxq6;K<4;uh(h%UOuIhYs=H!oGV$LBBl1v$8K4}h-r<<70nzdf@>vIj$qR&)+t( z!@UCFU6TV5(YT{jL&kt|5IavHa^@k=ND@(LSx?e0N?SMdv-KOSeXR#^GGRvvVAd$+ zih4!0NnKjk9=coC)sHc|CVWo>Gv3a(- zx!>Vu?QX$-l^>_~@i?x+K8!uTgHSrv62k{OyW++HoI-f=ohb8A`5HU<=|qXqfK#Jo zSIEpH(fREOrLwFLlfo)m{T>FdG;H5(4^qB|02=(Qxj3DC#qACrn=YBUl`q;u&b?2O zlGTN%_2F;_FPRW=uHZV$TE)-`pYwm+=dNb1F;PlU)#sYrf>cugk@d-XuS(*1ke8`F z`b1!NiR{brIr%Oq8@;fA$M(%d?I@+IvssShKt9??e;{F15Q8T`T9{wi~@aCNRls#tec;{5o-gcI1* z?qdK-)4vSEmibk(DnNzuit7DDHh^lpneU*;8Y_RT@*3&#@us}oxloinFKuRmNX#c4 zuNDShcb^d$PZ`qIg5RR08i^7fJ=EKZQY?>GL_es*xQymRHbMnkMj!}rdHK* zP}Bt1p9c$Ol$q+j=A?CM+Fio0T>|6aHL8q73M+~EJIXFBKjb0z>7vufmd|-(T5akS zNv>-g5iNP5Gz?I=J~I7CD*@*{laQHf91WRP!`a+qdf|!*qgEW-9(6IK#G9J~pzM-L zxH{FIs;Y1AE47$o%Q*D?Q+tSkCL^iX&=#zCAtPsBN4#;+5_gi(xmBV=Eo%z~e2cpV zeBn+jo!{k0e84SYAo}ixAEbe2fRA4j#m(;=5#}r`xlvFp z77&9Pa;8=|NQOENl0%tw?L;-31Y#{O!NBU_Pur^H$yit`TLogc6gAO-D&l#Jfxi2>q*>` zTjNp~Ille5wR6a|vcsZvyjsLgdYe%qC6K1=WhIh7dN;-M3oO>MqZpimQptB})oq|D zV4JZSYkV)7T6a}Bc`U#4H5EC7TqyR}6E>OtTS%!A!XO;RyB0ywnHNu2e0b*`_c-*I zg|YQC+rHu=RPxlfMJNu5-W0&UV7lD!xO!U+gk8b=C|ef;Ej+dy0?YW>&6xui3pDgg zT@tI22aiF~2u_LDP0dQ&5{=MRAYc44_2KH4B!0`Ds%0S(@KfYhH3u2RX)cT1Ck4miGiho z+PagR!(uTwLA$d$LM-Oiq#IctB^oa$zrD@Dqg!Z)Yi3OJ74ed#xlp=sp-YCOPLyt% zd@xm+#s2F5s{B$h9Ue+*ByUzUuWL&Swfn9o7wZL>2vHuDP9KPFJr!_eCyi z4Yz=ZU0f&m?!!cc7bHs4yg5wH)ritslwZ4Z@;40t&Z$-y-Kd*o)Qx0_YC}AD8W%NO z)|(^LG^sxXeqtRBORP(BEWJFE8n9I$H@5BJ)F;RCJ>+Ddq?s{k(1{fuNkx`!++mNS zOB2UYIC93CCQPnTc9&U&b5NLDLxQfRHX32K4rZT5v zbvMW*75TfD)JAW4*h}kAYIZon##k64V0d~Yrkqh_0oqBm0HXDCs%I)#3udG$RL%$r zYXpmwj2j^hkkyMPO0=7ybp$p}>ZPF(WouT(`JH+vIr~*$-Ey?>m>Ok21e~QTsNuT- zQ!zq>uZ;xab^h^T3|{-zYQ8YfwU~b_x<#PgN`2tE%ccP*Xy)duzPTH@j_Sd+=6L?z z50B&%1aTcRFEaClA5|3##v(KzX2a*KY_2tpm7Kru*4|5G%|ziEBL0#EN%mp7+Soz2 zg<&>(8Ox=t{{HFlnosSYoQG*BUE`x&sz~M~g(G1O_4aNun$xRFaH-EOYd0VVZ&0gP z`KmMzGY@eye>wFzM9^m;(|iz ziGGMRzT+AK5Wp^qRr@*1prQS2=8SHTx*n1B6wj*j$XP&J&w`u2Edn74Ria{oQh5gFPi(x%vHMQf1b zv4Kg>V*=y(FV5_()1rk$y0HKA$gkv#TG~C2O{Mep>#WblUkk1OkXoEY*JTd=NK(GH zfYY<q;3G;#MVuZstH-LlP)nHZ-F^= z)ae~<|A?|r5elza$s)q*oUW~>H)9Qg!mTts9sPzF>&ZD`7_ zSBtAAdM->L^q&E&^H;!*P|0;$W^Bh?1*@)^8agW1W3InMIUVMT-Lmd4b}efWAO>~x z6l^K^z);gGj~tE!wQkbWwMx|UN6KJtZt=9+y~mba zPMaszN`U8@>-K~ypcfKW&qW!LtN<4G={25LB^ht9_UIcwX$#@L;hLcMN?D#NO~-lB zXt+g!oq@Y7;&p7eS4a!I(N6T=I(g z@kEkZn{b2b*5aA=QHjI{Ncwr5;s9n?99%R4$2ampteA3kaPm0t)i}F^_Mh^%QL^ba z=2WT(<+hZPRfL<;65?f4YiG#7$gDgNn|-Ge!f zx4FT}dpz6s=Nv}H4v)_3Y2ZMhnJ6YM(uG5@udkVXw|q{h#m>n|rDCdnbm-JX-njD^ z#hh1U9@xiqWL1tYj9N&4DRhGk*e-L3(!3FZPK~{;zOF8AybmazL_n-g6KOA`d@Zy% zllwJ{+83Mj@+gV8MeBgxvYkmoIn0qi;*MudE=jgjdvw`pl7fRZ;edxs-SQ>I1Oz;Y zZU^;7Ge2af%P+MFKe7E(-5*1GVF~#x6U~V~NEi!Y!@DRStZ85b^u)xhp)izup;Q63 zc)hc8c1p*za5{JQ!spuLmpNEFS~rEL`XKM~W7x}goRt!~o3Q_zj+Ty;dvTmJ^=jHc zDe%-04H2u0m+CB`7ug>%m8bD0?8Wzpy?Ay`?srA=p5-G7D)n5$=VD6D#lcv~pg1PE zF>@IwBpADA3WUr!GR$8#e}C0Ou01f0s(VIOu-m{y5)lg?ll9yml!hiH3DMXj0X5fr zmE2Qc*vQE2iRyb8gB9o4eF&d|i7)h}2GZ11lgeezCEi}?ckm>0hs?7Ksx)E+plQbQ zU8Ip|^ycDW1<+jG;!Cm5a74LeBEMG9HR<73(Vg^3VVukXGoKXp?mx6tWoOKH$J08O zyoeKzg{62-*hQHIE#2*{$qCQB=-PpDt4y75VUR(jR9&1)beKi`p&&j+;~iLfSv4<4 zfq5sr#Un|$Cm#`)#?phea4cGxTF&z*kjSJ^{)qR1bll0r6zK0}{M~&(U>dpwCIg9C zkEGirCG734HQY`;@6UA8|H&LQQQmc|!kh|+aI%B-Ne8%3ed4mcY>$-!E^#w54R+7G z!({=4o4-W_Cc)0oqDD_X4s9pspFd)fo8(tMu`Z43>l;=Gf z`@Gqt=zD>MHxY;W&hG7Y8hmCG(2Cvjal*sv)lO7Yd zTxLVX51Gur7c!KWKo*hMX|`_{mrbI>azCPI^>v&BEq@Xcf;$QQ&{C<-niP)5JuN8) z*Vr0no-F`*?!eU6a+}<|{7BsJ;~g+1;fX*wto&|jS$`8xl=?kKFOn=iQ>^`0zJ8lh{KSb(6wkNsJPPg;bEPZ$p?Z!~JgIw!jJaf2P zq#&^7Vgp0DB~QC~rOoz0%XEjeASd-P@zsOD4HpM@f`>+f&-5Q0uIKpp{8R*X>#%(T}Y?VaP-!B>izH-`95yNbHgKycNSj@BTjkuqhix2M%SG&OS zrOM*N^UK)7iw0hKTza*~Xx(or^ngo#zo=mvcn~~0#mjND^R3MEnssh~4`j4ki=SAv zl07w8lNk{V3vlhzN-S5ovxKn^+OxU8xf4sVM$x^F)A%lf5)DM!b(-Gu|w?^PKxLTE-FU-n%VbzY}Uz zq|BSaIVSpW8jL0!eLG6i8}d)_%Dy|*|ET}7QkX$FIJc`953?PrrqJ7tw&=U4ggoW8 zqKMyqK7_GeI9~Q(LhhX1w)08%QLzk*Pkz`7_shA@C(gQU}#r%G#be}US~Px&#a8YhT%)R?Be4>vt>&kvSjC5?5+979DC@Qey(%iVAY zLJ5@?<5Kgbw@gVr%Si)nYIlM4`dhMwLp)=^PG*gaWpi4ku>Fd)Y7v6{?)9XXA5-({ znNsPsU#h=G=U3*9%h3tt;O%6!XrD?Kwf1;q2_T4rhL0}(BYVb`3HQymxBO9$Dx_dT z`?Uo2k`G>)ySCy4rxRE+qkV$pff?}x~ z6w56OsRRQ)d>4Pk==zqwKp8p}6jxS2Vs5v5pq*Bt=017(o21&B81nsHf5~`$F@NBh z19UXEBBJjX3IETut@_ymDw_4-dJ4xmq4s(x(oI$BkN@)``0L|-aPw*j7c5AB&IAA6 zCS_Q#`2oY4gdt+e3@pE$FyX)FHT3AGvik2|{c{vQ|Ma-~t`pwVT_-%o|LTMXyKMA1 zkd7gLx%1J;Uv68#!3Ja6TD;@3*({j&B!NWywY!L{Z`50l%44gqEyndKFRNuU25suR zy?@<>tw`sbf1-)S6}hOpgaJgcBywLOxBL1X%8E)>Z*7ETxA*CX@fDZ)RPZ~b&Zua zj>1)q@X7j4RO4ighq1&-$o0#|!QbMlT*sMpkuAc`cT@ZKATtZ4$d=P~WULxfDy3i! zBi8m{ok}Z?2t@*(duPsh^*xG%deMy0@@dx!@;-5P!uqPZW=nX>V?h=?qwG2kBt{sP z^RviemZb=aPGhD0VnBk~A^vd?cPfM-_N|(TZfTHmlB{^Y$TU$8zQtb=&w}vRgq7;9 zNwJr%`xGk}0@K1ETi5u+vhK5&ZYY1#0?(|6nT(kI%mav`U?E(wJ!M^xpv3k2DE461 zXbG3i=_l3~OuZWiw26LvF=L$55+sSfimmwB%8&AYZ&8x6lZr3*Hi%%MCL;fEk{vy^9T-IkTXBR($lA3ugp*_B>C zt^-y*BXB~frs*_C9Q48?bEa>?Q#sSq1t_$HzFE37HLlm9;r)?uW)a!#n z#%I-tX{B?32+)Z(MVJKV0D_9LBk#Z(vZ$!DiL9tXcx_CCxj`Ni420gER;65qEjgO6 z=iPo~kfGQ_9C|@YQz4U^HyKW1@V}xRyE+=Ck9yEiprES@!hZ^DLMF zplm3~+7N~-WkLu8{lF4$!M+xD4`ud2KvD-V5%z|>h3V@X(pTill{;*+g_A5Wcih0} zCn}|f?*f4^k5GXeHq7W5_S`*XC*$(8@c%lrg7I=Em0w-}=ip4!jE{8r`Jw03%w`Kn z4sE@5o8TW?So9Eu)~IG`dw^Dim9~oyVx~`mYYL*O(so@r`=1^NS8cM!St(>>bXz8J z25K?W5Th*5X&Cq6HN#Zif%CL=f%^w%3h_~!G}w)9L4Y(ui7h`}H129ay0`X^8TPoR zA!YsIDrrU4yf)zJ%Th6l@mqX1D!O#|H_>oUT_1ov#j1T$`dK-IZ{|vuG zSAUHOPLSV}uj_R1JDMQ1ftkxUJrMH{%@V9(=-mxQbW+VNjOnK>MbOIeAI^zVQMlt1afI_pOuRuIZUD%9V6N3f;b?yS9S;(^_y1oB$7?mjI-O|LbF;b1J z1KPQ1s1L09=Fz}n#t9HDpcKRtUEe{pwSjU^$PF>twOEFJB?A!ie&}#-YWICVz#LCN zQW$f~MtgEz5^+6{3b0}1k-+-cS!fkzd*%QK?%9AUXBrxo8?S7j-DS_^ql=Z-Y+M*Z zYvI2<)`C_TWbOd)={2P@m;U@U$y32wWtIrgHc^Lx(Y-36;@6Sy2EhkXDdDm6HPnb9 zWnP>$9df3o-)l$4qK4F<`S9Yu!n{~^0PRk13c~jCEWzf3MaC9tu9;Qd<=0>nWVHb* zQFT@@2;qFroF49mSi$Xg%%GV-=6;z5CmLs6fj^Cy`^uXZ^XwkR`aETW^F><4Tp#~B z`XQe^uElHFsdo*Y<5`V0o@t8)F(cKP7d8N^q{VCWiid?-eba(hn}v(h?)B#lP=KNo z(?)8Ld)A;?sN^e@eAEp&g26B1S(hLVPpY!Hx2MX-xaq)nTaXOh*}uN+#}Yu8_~7&f zN06v>q9)vpm?|~2`p=_=f0eRzR?VI*wh11Ldr0$js$QW@Viu_JnMtk0W-=!rjK{%i z1nwo#x#Y+FP+)eEScQbx&DuFyKDNsJ^MEXCp)lnJ_cZ1$h0&Ao$6FrI@<58=5$G^Jngf=^|%z{#q-4JZ*wH7z9a6 zy(a~rjnB2%H&On`ucuH(PO#+dIxWrT8_1Sz@S3GH7hFLkGBIwmKL84LP;w@*MO?fk z%a|C_?ufr0CK=YR2Azh!J|4_elzW$Y!}}<6 z77ELF77p?zq z;pe*Jnf&-e#!zwzZ)meqA9PP-O~k$W@AZoyB^B24X9p;R3cBER7&U2Z&E5AWlvQvE z14`?}waE6ddkra{o190RW~Gq}39<$Ux19EZ{sNRs%L}h!@2m>QH}2~N1l=*f8BDqp z3h!!B0sOMO{5xaErde}<5Myczzq%2iu)v$K5~Q5YkPOsmQZ%iHhX09=RVZ?jJ$d4t zfqvQJh-fzBtDLdGlWUXa9wu2;xc+RCGvDY<#gIqPrDS>UjWdC&cxHts}G8Fs))#Nllwnjynd>U378LW zqYqdt>(sysRM3t%L5Rff1Uj0yci%uA(xd{;b296ok{JnC_yS30@;>?ePn6hO)6}~W zF=eEE)_Pw2)OZTe*|wgKIxMzYF}uJRp}gUBz&E&N!_Jxm@cbF!@5XZfJb21@oTO2! z$-CqjZmLKEa{Ev5VB**r0XeQ4qXIj}BaDGLXgP>q2>84)ah$;rBtm2W`@dquJK`G< zldP7X0ucjLBI7eGGflDHC=!cwp(8qB(pyvM(XVICwfZP{*cyIlCU$hN@(Xl+Bf*)e zmT`>bEj9u6=+VjT1z-(gKYZaW7%B)Ckv~Mkt^|8l7tgFuK2T<0Nqg(EgaRG+BS~@M z;jb^l2}b$eYYdIV3&u-_8KL6mgbRewf3}xnzL5En4Yp0m>n(m~K|^MYQnVmhtjDU4 z+hyAk<@@qM;3t}02iLQbn1!Ui$x_sFlrx)_WGxx$B92J^2A(U0OgNUf1JtLMrF$HxQlG0$&IJiX@nk!Q93CVsbcE5-7xt!#S`^Pn(`KImUp zfVKEWO|<@sn}OMT8f8kZpe>lhx_<5P>e2*o&jxm`duFjiR1XBdK&rUv#gNyebs~Zk zuePZKVUCDqsBr`rp)6&UO<~cY!@-$nC<7(By|+4@+1Z^9OJpL9VtY}XF05v~B^Sk) z$9-WDTr#)8tzh-5GW)kDG>iE>=!}{fx$n>R^+IPE5UM`HRf9wP%}p{x(2Qk65_JS( zlm(m`>CqZ?hXD-`sOH7EVnSE3v)+fyJh*8#o#e7623Qt2U#TpzJJ5sJ2qxeRN0`+OZTFm=tJ z9|!x|C(n{N`y=1Pt23-cY8-R{3rl-TtRfT2aUbW38a+zW4(p^_vOCYo?mLMuJ>7>p zw(k`IYw`Kp)h^i|ocprW&eQ*Rj#r|Xfp{73B(HS}(w2Y;?mfT@ za$({`ozec52q%F3?8JI?CzIaq6`VmqkW+k(BFc@S$&VD$OHW=*Y`GjrF!KJ#E!XbX zM9u z{NXXbpuLaqi3lYu8FH79he|HcaXLtp6ZWVsSBKOofIS*Y+G4bT`YM~fp6er`vTp!H zHwD`eas*+I;-PqxeBS|*)rsN)IOL%3X*yRVI3TAlc3~dM1Ak| z3hr9GH0tY%I!W*67+95>APD?%9%?IOY6Cb{>`gGKB#HQR9)nAg36+m%@%*i2uOp3Q z^fcK$Q zqa|`;c@;LIe3<^!e13Y|Z;sjvIgkSQZwy_Ikav9TVp&713X7sMRAkqM-T{|79}#~= z*3c_$2XaiYS4Z>0<~>BVcr{vfJ;L#&akIb9obD$<<5?=NVHq>@^*xF9i*cdPkhTSPTU*Fi=-G zISs(Gm;-pyk)3Mcv)m>i&!r!wzbDMI9H4l#`PV}EdrtxIv&nvNnWhZ>eVUSnKt1oT zas>(+EgVp%+%!zjfvPo?(H>mK@Kr?%f{?ml5=((#Y$W&loBnKn+owgqh!dthhkEXssHfZ zbs&*2ZO`)-W+M*031l@+hLp*7uoCZ-g1czp7u2M~5^xtpkQr!C)AIpwX5Mk#!wLc0(jS(3O7S3p{t~3 z?yp7?SfXJ$<#)n$*vka3T4+~ha79dy6mh5y)IA^C0v65yJ6}*uQ zw9TlKIB$3F{NKkpgWq`8bjIYQO5k411hP1e8CyPWa_s zpN;YD-qE1tnbFnR*gA?48y1}EaEogCJm4M|(uyVdouDWO7s^ZWw^MntzAPD0m!00` zE0DrDqG?e@!=kz@{p$P~j+!%%$+an5HZzeXo8{FCG~)R{$=DUJ+7Ao^l|ly=Wh*0R z0W*lF?}VYBi3&w(KQc-nILc(kx4^)qRMowvyW|X5M~L%Y1-Uh3nS@nrFQEszGPTlb zDQT_l;PF}8O_Nu}G{>&}TAE?uv%wkj<+RB^$egT$rGCCKXf9(MI4}2YuqMCo0Btu9 zI5llnoMy`ti96FvV$o3UcLSZH2M0+fl%c8biE*`hY-T41bna>7AfBEz(s0#DxAnc% zUoXm!LR3ssu$|hpofv#*x`-~;?0bTg&?`Uo}SgDZquu4 z9~)9#q}I`2&;|Gaa2CsqKvkahxC;%KKuR|qj$43MnRs!?ux%P)Z7@~Y?I}q8!K!u| z*1F>k+>8P4)aA&Eb|PrP22~fW7JGl zD9>!0Jey)!6Ug}FSmN=tx`Lmfr!}Lc?t{o*r)F`L^1g^x{YBqLlrPFKg{n$q_)83? zO>Fk$J{q!bphngXOZZoW25?kIGMTR)_JAV%da7_KWsYMeUY)D%Pi9lUcK=B;>`ggd zvOc*Jb)3C#q-~e*{hEyRTgnCjML%{W@GoFAk`O29=zv6~^q-dGfBn-?A#Cskr5<_3NMN3@5S@=`o-K)5eh7+#xxD_H%CLpMdy)pFv&PqS22OEj4r;2Q%`K^*Xu;N zl4gvR&r~Qi8&rKDo{JY6Q!o^^mi3dRz|dfGIR{dnLD!g$4(s_MPA>PY6Z%6@0QFPp zI`3A8L5MlRVDsRKRP8Tyib>3QaL;pn=gh=9zHM`+A^PP4>}dWOIn6me&n}v`q(fJk zU!;$wqTI_C1sFm|U_FnZH+Y3E9f|v%iZ!>6rzzMNSX*+hp&W%muM=QJn~N{W_+(w8 zS?dH`pchV9&x<-aW6@IG}6xz^9lV+9t`DbXTUFUC{}3OH z?2dqlx+cE~ao1BgK^^%Y-)&m5JIr7~C*y)47g#h6`JxSHLwO4B&-mR7tQZeg8AD3b zZ|VH^p8S_}7Y_12|C!)0>Z!PATD<=A@BPEy$_!z!7mltSdN=WVLH{4W?$^gCJcqX> zU{E^sfBi3hpNJ?6RG7ZAds6t}lKc;6_v`C^{@(vP+5g=ogFD;m?YPCLy9}6tp$%A+ zcosq@U@95NMDMG4b6*V(!H;IxBy)xpO?1!Wq8S-nZIX<4&>v1gc8yrUqfhn_mNw)< zY=(FA!;khZYb6LKalM7s(0;fz?*aOm}L~&;2mujVsNAw+_*C5ECeqENg#TNGWcl0R?(g&9ubOxYVk6=hFrhk zHkBHDEpEN83!e3v-L_%^7E}J}(mORj6o99Vk6_;Cu9Lvj~B(x{NtJGhlp{Q$5cUtxbQ{jeGkxfQm!KuKDfKDTwowu}|P2KCmNGz?PBz9_*8`t)S{1UQ!@NXY~UU@OEL7~=cdyk^Y_3`H!xviT3sdCa6LC?G$u;ZQe*4(Z zl9l@1YQWOU-um>1C1&(eWTgVwrb=*1k>_!6hn|@g&46ur9NC{D0Tv|&%}C(DaR3%y zZHmhbyJ<9;E%Y_ex=AzI@81K9<^X(YBA2Sf)jh6D==&SI3x0H8bo;PM(@8$w)H`(q zm-gN2V>1&b4;cE;%Ulu&xt{!AIyAHb{sle$!~d-`1!#BCVdIPa|MZ*x<#SvwlR~F; zgOj}O>OXw&fBE%)Ih6nRwg1b@4Hud2(hD0v>`ZdOOZ#}$1gX7~FQpvX=3ab+ozT*D zu<_#0eXarRb4Tv;#-yXUDw{HiNZ=zVDV;JoB>{ge zO!AX9(0+B7HV||4cF{FvX(tal;C^58D0TLDdm~F4SAFx5MyKsNY>4x8{1hYwqQrEv~iW&i(rzmwsh!?eN*(K+R5;!0?^{f&GgQkAE5zo zx}isL9X1aXskI!F&1aujk6w8L+=NO2*90F)Kt^3usq4VZC*1{GfCdptx3uhS?-Iq2 zy`cWHGAUfX2h~3HApZr0eUX1N>DyX9#nF2tkYQv=!Z_nQ#~ic6f|9`<0%r{Qs{TC|@LFS}k+6 zatQwA9Zrx!7CYUL4@mqvqf;;B7Jvn*z(%;4%djeX?yLWW1+W$CM$`n94hVDhz*i1H zU|4~9Yd2)a8He%ONWa>KpE?0WAYOQR4Ut?`WdBc3rh1CW;oO?FU%0T7JxU}%vH1lRk}36(EZ*N*jdn zL1mktOh9yH!8weg-cXzhdulhxnuh|5fYFPFF|mP1@=E0h>Y_Y7@|*#yDMYbO3g3{M z7oZyo6PKla1B39uMq{%TIERg|%^+I(C3*E(APdA5X_Nw3r3~s2qMNJ81O-T+G(!O# z(UV1m^&xdj$W|Y)Mm68UwB(gI2_Y63trip=1tIZA1@BwB8fDU*bmw-r_MtG?ZSC@_ z?*76TcmGu6j2R%Uoxr;#Q&t2xehR6k0dH;u8T}Ei8~nQbKoJH@>hol`*>AslfN!vl zZ26J)60y2jZgUpAgc(>XYF5b(%)@1+mg1jCh?xTT%>Tf?Kj+EVVs7&bOpvf@hP26ufxZ!#gf_d{_H)K_W%G&XXox$ zhY?g5h)iZ2Gzc{oYy{K~I|Ik$q29q-l*t4n6IwHsSGABQ(pP9R3&Y5j5LLDQ8~0PW z=>mqM^Tzi{JMCPT4lv*1DLD9a_iY&}gS)U+cJS8TzgO)9L9E`W^uAs1Z!~@+P`M)LfFhL__ zzVmd`U{n_;co1hI!KM!pCV(51rFd#s;e}w@Y&&UA7YQoQ6ujOc-W?iLI#>uP9IRa8 zN~d@Q=3+|SFr}>S9fDe?y)Jn;rydzL7X%%Y*DN4t`0zB~Td;?olI;YzlmkSShTr2fXa9ijwfshqpg+O_LaHS&MnE3K>`wX7o#^w#= z4f%^?<7}P(y!5OWU79AXLOt$o<@p}kw@)&waeOvW!d zFLPb}i!ei}^z$;MxoMM@tHPKVW&Ta06iQ0j$jM#$OFV7(IB7&Z->O>k^_LUh@}kpb z*VjqjCg;E_^xB^IrvA|hyL^Bjode&kO0pDCukd{Z`L#9HJK%q1IwX0=B`Wp7l2ab| zY<>NH3d~thO@%K3C9hjoXv%@V+X{s@f-pEq0kjxF%*c0MT@eKLTGfJmD8U+;Y65e9 z1`}^@J>8ZXf=Xmv_SUnm7*WXIyw@BP4o-K*DDtEzS(EQWU;xQ&Hb^}O==b%0h(silz25+|%LOJ&2byzYKIa}r zQFY65--475AA_gWBF500#h>x38Xpd_=|n7pTd?wNPPxvG=g9NPLDYIkn!e$(bjs;- zR<0@=W%h}@LocqVh3sWq*VNYb(aV!C2!>RS(wx>i2(ysM z!SJLbmFaHo7_hcl{*+-K<@hCQI*PWdffQ?{av(wNL*ct%fTDlW7TBVFC#@EMdH3o2=Z3 z8WDHeCSZH+u|RqKG+XbXs%4VFxAl_CPVwL*@#*b)3j2@y>x(yLpn;HMg0BY(>q&22 zNuY}rENoAgKT2}`{r=>MLR$;MbUmfpGoanr8<-NB0=`7uu(}U3v|s8I069wBWdB6u z*|6u_R>qr%N;SHUfJ29Nn-U za{bOmvd0l_aYwLz`0<)j(6^}H)?*r6#llfo0<#AGnq{vSo8PnDkK-GOkXeA2=uDeL z33I%kmANt>+xH5S3fAP?-7s1X=x~OvEGJd1pee7%LK0DjGjUKoN7_Rkwv=Z z!A(&zb)7=bbNq>%2>|Ky@-uRf@7R&lY&w12*(%!^)!=7s)fXvTUR!A5OK-N&sy`dE zqQLvnX!ZLv;mBo?<*UAZz~>^XErrslAfyn{RFrckK1seW!mn>DGI3j=Z=U{IL;u+Z z#}C|@-}T~hgT?`4=WR}VJ8ZYnqatm*Uyp1g!xq&*amVu3_d%Z+r%(YSW5e>K1=&j3 z@%z%rOMtZ(0`F_DyRvf`OptU zknZ*w80p-H-8zR;rU_4%aetIye~RZ?#%(9=mx$@3N&VvHukN|c4BLCqI{xBTFhS%0Q5-bhB2@xyLpHhv;qG9St5 z*5Tc(^w688P0&IQ=3L*hn4(nC!cVOtM9`AGnB}+qYhoc(QYu*xk zrl~|q9)(UkDkEV|@eYW>L{d$p)9u8%af)tz|Gj`v>=s{dF2+4!pa0B5PTkgSJH-}9 zqMCiM{BQ|#IG9X4BX7N{in**NqNO5WF_oW=2uA~_-aj!E4dN4Q&ZHF5UlAyuT5S@G zU@Y^QXin~E%6q4IQ()EwZ0_tJH?Si0%;xx73`2NZc1u*qf@5qX@nd?L;?zExdzEH_ z@oj>AIjlrUee!E#KHMceOlnnLntQA9`_VXu_tsLy%2}z{($uGcN$^}G`>KFg zomitl`#hp4a7%)`ryGI*Ndc*%6itCvnHFA#^!nkqlS{yiR54`g7;V)IDP zL?9vbz<~hoIw_^U|YadHEV>qN2({Pl;*}LnIsapnUo;%2o(?B?D)zdt94rZjQyP zK;peHJcRh}BF&mX$JBFe`$$|Hi()w>tED*^9U<+*y6!=|N^AalJ~Au>cJ^pyq3j-m z%jxNks0O#}eY!Kc0~=IZuCzsRJEI-0^uO;OE#8`7D#H@^bIBl%lPP+41#TaqCfark zZ?Mw)wh6{IWM(g%LZm4ZrcK&{+Ggh4Q(UNWlU{FBc zg*m(KtzY5Ij-L8w!|d@=rzpeMV#OynMAjKD+8@G`t}mXW}QkchE!JMKekrZ3{RiT^!g5@X3d4OQxyg~ zwyWnvwjwL}?j5vOY+9Zf5|tBKm;btY7!{6TW70C>`qvQIO^0+IEU)HxWM_Q0pcG{Z zf6Fj~i9Ww8o*Q?|70yJZmNc-(vtNA&BUHjB(=oWRqg5m6j154iEB`fmNX`}8sj4uv zFD+qktOMxCWZ3l$tLOIgu^E=CVEFkGr?}}=kx1v=Os7QEU^|zY!OGHka9QJ-^`X*x z7EeLDz8&Huq2~84ILm`F8HS(Vt6BF2VbpRLIKU}G=L2ERBhU{c&iHfADf23Z(4gu; zRXjRV-h+=hi(h$fWj~=HqAh*#os9SPECW7u$85e+yZ`Xn9}f)J;Z7$!!dtt$i_#j@ z6hyvkOXj3#jhegACv#jGUi}!??IRKt(8fvIFOso}v-mdEcuJUcDp{{OG|b}jipWBS z?+o;my|GRAMe(#}(`k~{@F;3IE1?Ompyh1m^*r-OwV%L*N70HFSTFL#wkL15e7CC> z(y3?{ifW8eD)~v5QkYfqT<#KkFGoj`mPn-gs^j9|NI4XKn?E@pYS3{^O~{>L_)-b{ z@cJCXv%{a_2U^kSx7PEJ?nti1*07;3ojKH=7MHRQ;%lf3ft!NXQ2<_si4G24xVE^6 za22G_vQKvVR^PU3ljEY|diooUt*d!A2ORN*YYut0e@tYkUw1t&BS5*m7urZ1WkB;A zYnCg1H)SO+4d=7m)OdT8QkS)x=+H+(6rgZXk|joNtddv20{BvFFuO3>Y| zZD4}v#5M0?rucNn0_11DuK|JKlCH-tuq$LSoT$dA#>ab%HV2EBIG2AO^3^@--bS`` z_4QD774bHf8J_c2oYiQQYHlNp;RVF>cP<{?77re?ms<@o(yMVPzbTUhk+!d)K5U zc1_jJlCM|P^5}NC(h1Xy7UsyN1q}VW-9~Hfl4---O2-zPmcqsrIn2I-A|@SQ!L>`} z-VD%dwnLOBd5Lbyxm^=?=`UDzq|nzpebmHSk7`1gPrB0Fe8Z;sdO^O$K`qm{ZSA7# zbn=N4n{tpYVvxMD0s8bSr*!6I)`ZkIM>eawFXF94Myw5T?4?t??fD5U+;n~2QoL2g zyGRf&$(XU4RnQkYv;S4lpfdYC?GlImn7W7|7uIdRHw zxTtr3w2hsC!?FZO$0);bK)Ishuq|6c>eK16++*iCE~L9kBgVUKQwOG6Z085bI>gtM zr&{ScO((OzN;C6rcz4?Dm)JgiUQTLj@b7h;MgS-_=QVzb7@_Yqz>HOv-L>Ss>BM4M zAyv(guOr2;BmI&MABF+A01>H&dsaEI*qGLjGjfhEyHos${m=3K&_Q8QFxAM5YZyOA z&y@%Jex<+jKX`$B=YSVTHI;g08$7il@)GEq#>2d~0hjh*JhVU`M{xkL&H znV}>GR?JrJE{pGK)HTF%G+pA>-zSVU1;$S}KT>NUhhdPwV!Y`URmoN#2h5GE@PSe3 zv->1DwZr>K%JKSVziyweKXq5~l$G}j>hm8&x^#jrsUuV1?PV$K2W}!C!{ZzHC~b#c z&bLJ5#Y=KgRoQ#n67pm(J-$%Aa00V`y=3+Z_+xR11gppELK0*QvhhNu+?BwER$6fA z-4vGAbfB02GFHX&)zPR!r5B*tSSq6jtEKODzqwj2O}Zi3z?=(Ldx5{|aGF%EsSkuhGOndTp?aYLBS9OaC9Z@p!xF}Tjk zig~62N{q2NzIsibXc+P!DyhG%yW%6LKU^sSlyJ+1=(l-ernAuW&6wr~8JG8;6C*13 zs$?c6+nuYPMR{eU*^=(V4Rkq6+J889Am|RHSNrL+akIp zh{QlHj@8eK;Y(%(vM@FSU(xamjL5GokJ&LF7m{~QI=ZIpvO$eCbDP%Hsp~x`f^E3eQhyt|L>y;FnbNp( zt0vo3{Ov6fDzm{ekGVQ`MB~S+Zv1rSpnA7UHhJ$WFc0)snpoeZ_8n_jJrk6w)ol6B zytEJ^7#if#!mS3`vg(6)z;#B%kWrNxcB1f%IhSSJ_d zhajBdA5%KPH@B=Q!jtP$(f;G9L$y?I*3A6)u1q@BISj`m0D@2lZVVv{=S4)jQ~w}) z>SFn~aJEz~o=E_(#SVlaQ5rX>79w0c?(H1e`Yv(x>2h`aXZaQ%!{Ne583uRb7Y~VX zW`08uUe*JVW4D7Oc;wqi!la3oj{PRF%J&HC+wH8(JXcSL)`!rus%9_2_~N^kja7Eu zFpBm4(_umvbnU>Yg|9k%jja|)eJvtqm!J)|5|P~+*^-@=GWlg5U%FBr8tAt0ZMIZ@ zp_ofRD|~iR#%+7t>B>h7xm}Me*5RquRnP!k*iE1f-i`+Is^;ws zd#29*?ybp)tFafS(rG|ACGahZBe*n6DEc>fPh5gvtiDi=^UgPR@_!-cQ|i3oj_C0Mm)&+8R^OMpX_+ooIHXamJ=sPvX7red2afuwJPWxR`AnVW?5n$B zS0VHw)H+UW@ia?d3Ib2CIwlaip_82RqrrCn8QM%rj)B&@*)S zo4F|QR>QM<*|f4+C*NYDQT^pCD~9b&$6E=1Z>gHSw7%($Z#Mf3WGCsYS!lP5`*J1k za)L2s4@LC#gGJ1yD=r{zo?mw&rRC(lV|dk#OQJyqRjuo@;8`Q5<8DUZ%7oD}NM~j9Sx!Fat-OH=V z7plyA`P$pbmCg+3*Mezy_=Ct>E3S--*!ZVLEZVwXY%S*^qod;M@_pLXPPQx$-y*3r zpbw4A&`>&tN8|s?!+A!Y2E6#J(o_VOgQ%45Rfd03g+@6v_uZ?zJHJ-%wqHyz5Es!> zua>Dx1)#265pRAb|FJ0hqa~oAZzOsyBEQIo1r29Y#0L+3pVt8e*9)Fo*`%E68SL{9FQl5vGu{&qvWczQ5-Fxjg z5wq-XY`h5x8FD@NosZ`LU7Bs|Vs0K)?wCIUJNWQK-pA>M?!Mcgt~e*6)xtWj?sTz4 z3Bn<{hn)%5X6q0STOkAo;&_Z>f*8Mjo>Z);|K+DMX&y;8QN`ebPiu!M3} zc=QVo$-xKyFa4k+V**wk$iXTjhma!eL}qFlntTA`{sNV3IqY|@oJNJf%THD$E4{uK zjj?LLY`=%^GCSibc$2mDE^ArsXzs`4`Nnsu}cr7XU>%DWKXwO!^5%x7BNC- zdru0--`4=<08JRiKmnYXIlbpH*AGkOHfPQE4=*;N@&UcvY$3Z~zjM0FTcm+jK zjZ(=_-?qQP!lg69jJtMX^YA^)!P~u}c!i_omgBF*o?L79D4>uCc2!=H|rDe7q57N>Znl3X{El%;78stWf2QhopdeS}(V^({)LhiyYJGmoUyWF~a1eh@0U_Z-7+d zM##+WI=~T+-p7L>Q!IkSC?4q~-aJZmKYJu_Y^h>I*DFw;n3cBN7weFC zj2D2XiSM1_7}xm2bSgZ;v7-i7N7cxOe;D*?Oo`-%zLX(*f?-&HLmSmz%a=g3x2E&XRK|P z=E6kTrm=0H8(dU5*C5LpY}EDgfk#s->2|!9A1dmtl*Q+g4iQdqduM+U`aLMG^k|N- zc^F3Tz-ceD^;mR2Zs28Gj()0hO=dx-)hG7U*FU`sFgG|qF&NAK=>?#>(ScDqqdTlR zl9v;<&8R7GdL+m)*PSH#j7=9T*y%{s`XlK=Dhk>dic4p7<%8sh&J31Bn7HZNxwszr zO`{;?RSao73##&>LY_!*BpKRH^ z!MdZHq=w~S%06hvL9L1XA^m_#E@%B~dQZ$qE8bF8XuFsmJ8g)3@@vfK`ZwUyN8?Cz zys`mg*d^q*;9y5yTwpXja-nA1qCK-Hd|^`2T63Cy(l)Dw#T7;`<9a%_#(%Dg2X${( zWbG?WW~&maXywH|MA;3Is{~rCam>EPAQMRW+XPyoqP(&5BT=iK({5GNL$2bBC@%_D zcILz4PPMu`uy6eRrblojm^lMFSfvY-wi1Y-Re7MDHqdCxEikoZ8@;OQn7J|NzB{X* zlXz&bEbSGeIwIm*B(E9{hO5Qd0J$PYk1_<3a24A#vyzVShbn7OMJRXKdyZB7p*>){ z#kd*uDM7H|A0oToPyd#-IJO7)v9WDf6RF(l)E0LnR$R;iJ&(SlNsx;u=J1=i(X~e3 zB*sx-ZaaC4HsMHZWO zMDa@#p*pqkOs!R^j_g--4JsAl9rd%wdj{iwK!(b_jJwA65j8H^<}mE_yPHhxz@2#D z#Di^FA+5<@qJPf0rtE-UMm!`0YE>*8T09__DGuMcj#RHlk0ZbnaRvce4Ow%`!087{nUe-jADon_z;M<+L?%kUtrfk zMR?(We0Lsn0OyGiZvnV>&$b-sfamuA?L%cuniQJy!>UTD1yK7QP$T5-UxVrO!*)3V zxi9}gd-mt{{hwbBC1UW0=zGeJ$FcNHV7LdI9L&La0{O~A1(;3;zTJ@nt3@dffhbjC z`0?K|<2XEHh=+(IDrvosm<64iyEP`f7XQrwaem|GMAIf(m` z9Cj5jJ~C<5Ns5wQ;2`Hm+v&DCV=kStR(Ll@LEhHg-QF8cgk zono}ziU1BrD5o&#D(WVEwFa^aZ9lBZN}}K)pl3z{9q;|&Bh(5DKR@uOFA({e-xOXo zdqV!(cjGCA0wbb9&A~X&{tTjFlt3M(4aKxB)W4r!6v83r%~id50-=UgCLqP3WHHVAGo9DLcM0@#Bf_4kC#RNWA3EAvGv6(s?pKBni>xX9G zE--uEfMNfaV}fI(2>xr7ICys6ox3}ro6QFCBOo@Fn)QKny7ILR#1=hy?~&JXd!-Zc z9^Bm~RsEjvpR@W9&iR5tY$!!G=8kHH%6W{&0MLRm0i4<~*QDJ86i~LB5vmPaUGsN?T1|_ z{UEd{(pkUC!76K1Lcaw}piNM_z+g+q`&1Kbh87PQ{)_|Yg!Le&3HVYxhmnMi$L_(} z)c2hGb@pgtQm4p%{TIA%#mF54098S%Zd+JG6+QW=ErsxzLsYboRLej`JWeFFmFSR; zhOtmVKZLj)+ht9^;}Gej)%N;%;`Ap?pTT3#`T5jnKxw1)RLJ%wN5Y|T^s>c*%>Jlq z>9J=hC3Ko`K^fl1c?e;+NEaR!CQ6{}+B1D<8oGAd_nFI0*^uspe4U~&&^q;k6_ZlV z)(4)+S$eRxLCAW_l}A67;n~SC3_$}I*wXA!24KNDz$}L&$vd>IM*@rvdYFH%pa1eN z5NX+tr6%+t`(xW{8mYJGsJt^a+Hf2{eiA_yP|l%`o1fW+q~GVkI0A?BR#$3X)35Q5 zpGD+ih4{NlfS#&}j4D8lUZb($1_Ske59~t&OMrbpgmSWoyL6xpl-H6`D7(4`MM(p& zQ%2j(P?wI}jqCcWVPi*oca!rP+{>Gmw_hA5 zo;r3s9-$!k?M~`gOMw3v0nn0z+!<^I!IX*;EAx;wX6E_6^o)fet#%rdfC|W31AL#spA{dk&%Pxgajl(tqNDe~1hx!UN}B2* znhR%7eBykCOlobc4+c0Fcc8j9QV}Ko`&8&!cf38|{`3K9`2GQ>6=*3ay8)^HP_LZ|n^H|5-5@mroY)z1LMygWA;1jEVbaT}`V zqG=J3S%O2$XLKv;$|hudf5BsPM;x{*{HRJ6&`)s(>~_qr6~7G*yHJGzB=H4l@2&so zp#4C&DLw?M{Ld6YNlC)PndS=V@ajXR)tH7NoF9)otDv}?2FfV>wO=F4RJdIS)Cw_KfQj-h<5mi3;rf31hXW;FFN!UmipMvMA zOC=PScO_<~m(byb#I&{?>9>!MDo0<=%!^yb@aYKRsB)%iJ&<4&!p7_8NH<#rSv4p5Isf}fq%6^9bR%k*T?Cf41k;~T87MBh$xZ2&6P3%|~Mi}X7k z2kf=Wbq6+|?)!TdJHTf2A2$(7AUU7BS$W$f23hqLoAS3k>VZ5nK!-X^(NvuWn_{$lCGgbL8pgE)V20{RN z&RsSC3XsAUAYs!hU{zLUlJ$484Umo>(Q7U#qJ$u$v_knTuD-kqPHq+ zrtcvAK1>a`!`^D1__IX2rELI;0z&)hEu5L|+{J}R%;>l)=+M}Ia|5`$cE^EpMsWB* zjP@lIL}t@hPs~m#YD$Bv&yPQCdVcS-3SV(t^rb9kAMer3`N$YnAdy++(*{+NDk$z_ z0j9Cc!Pj7rQPt9n`6LpdW>J!2d|_c48dDDYLO7JhC*<7JQ-sc|Xu#)JpkyQISjf=I@8`pB4Ibv+Wq-I1;T& zOS4U1=Mh9G2vUe?*g?tqjiI(XOLKI^wp1b`+`_fywN2zU0CqcfQVd2D#>5O<6f9eX zr^gWZX9uBLJ>X|?P(|@_4`*p!Ko$bo@EI14h1)b5>HT?lGiKES?j@T$mXyjHaFU-x zu=1-_B=OnbqCuVYCpclX$H2A|56(g71YhN9K;XY|FiYu%D5QuXfr;TrJDpbeguS zpj4^zTa^zbA^O=VJ9A5^0e`0=WPkT`GlyQ{k}u&H_s&C|HM6Nhj(E#ZxM%|*x$RQA zQnGY;6pg5h1JG%7bM+yClt-a+<8pugUCC~3OH;fQWqlXHX|Bm9HWmrJ!{0+5Xa81V(sP|5Vj@!uF@G&reBQ|1&1-rHYjOC+KSg zI>*9)aZ$|3EF6YGVy_0%Pz4NO6AY03v>A-HWtV^2ut!$v&|g~)3_Ijuje>U zseT7W+jGEX<58?w+_eK(`b>&M%y&prpas4O*kH0HKIrVvQxd9PUx3{xB`TCY!Wx1m zkdL>H_%h5lzTt~h(riBYa~CqwGyvFIp!y#!V&ZSW1xI;GI~wyBIE2w1Z?h)!U4LLC zvxm4FQ8*`xbhVh?@$sRFoccVF+`r*d`I^=P zT0ePW8(!FN_W1F)1s~KSZ=2FD$k7_=th|=SDc!;Eob2~EpePA|0ZAuN#>6h^^&SGVEW~APuzls; zXPO#8@FC(mbe`tW{Bsni6NTsK?Y@hJl6cWwK2J_>35C-lr3v)9CtekyCIT8R+FZ~s zMcDaDnV4OL$k93cJHP25O%wT{ZNWYg3*rwlN>YKNE3Wa|;)>C@S?UPT9nvi+2{dA@|& zOhXZA@iORAiebc+Yi3Yy4pcNMQN~BZn+# z^JbJah5k8+&tNwSIbjKL_GBRB&XB}j9ChxcdfwE8*E6Rw-$qR zL#juaS4hFvE~b_5TVhlwjz?Hn%j%+A1&;TD)eba|=J2wwgJWbr+>?iBE(NpBP7onY z-Gi$2rT(XC-)!DF>x?xBnaM}PT1Y0t+J>E0SKD|E#1Jn>wzo zw;7Lz(?b)yS<(YGI}#;H%pf#zwiwBRnn%I>D-RZ_aAq}AeRspZh}Qn=-K=98xf`?N z-0HM#x;NNDerchBH+KVMf&H*gXG58k!(0nze=l@lgPBEvC)#y+!pd0R4T)ajs@c8z z(QQvO~^P{{35? zb4MSq>+fL;|8l25=?q%*{Sq4Pf9e7MCPqQZhK1zAkUKc8W(DU%NEQc1;)CpgR#z5a z)c`M4ZGu$yt*D;l3qXs1yO4vs3pki?%dnNE7VdhL%GZ>Q$y|97abQ_+px{LoCd~h? zVqS7rd8Qp6m(fH9G-QqQ)8_9+=EHb- zz}UsW_@G`qketi7zTdv}?|SJS2Fjmm#hnWGgZ;4c}kT>}aWH&_F9p*eJv<`4?-5KH`$+u94;*~2B=M5&FNUga> zF|waVTFNntz;bhnk<0JCdz}V33v)2l-v_h)vf$FFJ!dGDxsv}rLUZscfUAZqgo^_x zV1)er&>{EoqUjyz#Dfr498ImEj@w2C3z?heFS^#hwT?X&U-3;5(klAA?>sum=%+e4-nLC*JB797B^yCn*X5% zy(n#@hUfVKIwiJZh~BtCn!AFs;-BD? zbQv@jJ^FEt7V<8UohAio6^sitpkhY0-0V>Ynn1t{N}+D)LpEnKG#bXpPnNqK`icEhh7!wGWQQZ|5*t8$op>`3`cRe&)HfyfzrXd?1bw>`)#96x5foc;5A0~c z_9bb=iY}>-pTS?b`MsI!1ydp$ZpMi^t%BbloWPqx0V{W5X$CCLiGLo| zJmUX1*A^aoD|8;Edc*Gf)ks$acyFn7?j$IF?wQ2eMiT!VgeWh$QDol?lGaANNhB$w zVAN4V0t|q_Tzqlt_L0PC=zx~g^OiN%CX^OY>+U)(9}?A{zYjg$4oi1VT3?L9d1i^z z;z3ms`7xSOsPXl*!TaevB4@8T@fQoZ|90N^NsJ)T#_s&7vU>#easLA2y+mJWm`Tv`j(XHbXNSzJSAp@c@Zcc8U zvU5w9^}4LJ@fpD`@^twTxW(hg=aqJcrfZ09gcZcG^LgQ); z;*x!Y?(11Kus}Z?O5%oepNv0gdJ$(tq~)IJ_p`3r#k*Pa&;7zrIKTBak~$+?kc9VUQY?OT zH_minJ8s);LGVJ$K>uWwUdx3GCe_W(&93(*AiIG%Q8Fl!Nn&r7Sd|vU*LLsQ}(`qr9PMG9Xw>KRos|h&Uw%D{$ZGD%$;0}?53%=9-BTzf;a!T z>QPnMix8c-Nytw~bTMPcmtS3kih7a#-M!{v26uNSE|$V^2SWQQZ+?=OLsxuVBf(I%v!q|)vNPC)V)GPPu+U8 z;=^k5>cXi*)9bIvyIh~e;rGUEW7^HK*yY=;^~Ue+tufWE#_3HyX)`+OX}(W4y(hS+ z`FeZWZvSWaw{m&G!Ntl3AD!3l!o1drPx2ZLw)nahx2_tLtjn+JfY7XFJfgcKzYK1T zO=w?=9XL&s^6turK7CNM}xijMC#>ZU(N7M?C ztBBPC^dRo(2kGW_XdZA&}t%z#SfwDH!5(Y#@u)_Jk8g;rSKXHYr z%B-7*UArU;$+%PQbBqNX_d2dA=kc`abevupNj<|M!eA`IU~wl>Hm#yGVOTeO;7CHl z{~%l#=$8e~8w)r-nE+1=z?OkGarZD8qvsmy5)h^uplyG>=cV-F+UZspIy%BOMVxG* zCXFsek6_7Z%;&^vC>CKf>4<9(A%Em)Y%;bZI8}@6M>4X)aBq2_KYXvS;??=KcNCq- z*ko~B+}LC*esm9Js`DCuK@5s#pAFrypY*}mDDjDE9R}Ds34N}R1!V-~44>f#+)g8i zXGy;Cob3F!ROx2wtJERIxPC?tTYAouF=C@Xw?eUMN}K=z!PQ^WY`R=F6n;jNvM>ZL z_wWA^zkR%?17dX4fZH1xsF)lnFqVWvB&%hoku*PThU>u#n zPrX^;qtY;amUy%v4C|<4;c8WZ`tPTF825gw8P*Gl-`D>)|F(Wv3)31VNjlqbVHkuT z=REzJU&i13o91=`umr5Zb-EF1MyBnJ#VEip8sN67*KAP&-_^6p9XMNh;;~zNK}T&OMTo zr|1PNnq9x9DprDaz3;f+>*~$HpMY{WT#vhZV$UQAcSneF2-FF;Fi?0q0%{g2&0%iRfJnr?z1MH-f0r z2sTfpa%*Ejm_a2&X>Qf@!P(Ny&23=q1|fhe%JVFZR(50wr!DQ`)YttE zK5_ynL2beY6jnUmFE!8nFE0`nq0uEzkVQy?o~|QaN*_-+t=9zsnxSu}`j?G`xHIe^|i(cabkiGQK&z2+f4bJdD=Yx}`&t3#+SH z&Yz=2pU#LIyLna9`9be_vM(AqhAlEF349XGveWt{s~1H`xFm5{f`!nx4NIeh3VM6_ zTH?1IzftfQHqqEQFPQk|qvg3o;+Z#jreuR;n{i#%@nt0OwR>G5LO8;U>33Tq3w^~) z_5%y5-Fq*P^^%j_q60A%D}0$wD`*~r%NHho?fOtvm2hV!B#C&pRhnD!Qam&FMo*|M z8f)^`MNvVD7r55p;ytUO>=STzmA9hih2>ffHNoOa3WRSf^~@&+n%k9pU7d8(yWk_! zWBqh6ZoAiz3tisMb;dcz=kvQCMW2Z%$EA#W1;^MX1!A>0&-4_I&z%mQf0t;!sJ|X? zW8E89Ns_UD@;Q7tbMu(?S{i_)ipm>5QYo@g_)!Br z&`n?X@MQhlzOJOsDZ+A1c&9JS-lD^f+vvzQY3jYs*zYdcJM?aj=J^~Uy3mpqa`>|2 z#i&f=bF@=j{Ulb1>X!M2uzYp~L zSBh6kVgL7B61O1ldFTFaZm?1S=UNDpM3P4So#R%*|98dy$M4+I$GJErH~jc|!yji2 zBPk9@s-j?^C()r=U?c@8U4bgOdb$QnVT5mhAyHu3eirs{KU6J{-#8|5)0zt)pLUDoo zb6pQwD}~Ae;M-|}=NGVQs2*?us-i4pzrba|Ievupk}N$i^9X(glid9(LoMu(H-l7V zJTP5eQ@S|2@^joUSw|jyY|VYH)Ej;j09-z zgbK^q!KPJ3*&n1#O6kK#-#D9l{r)U6gss5>GV)xN5`PqXFKfZVf(M0AuNi(Sx#mM; z4Wd(G`up&c=tCkc@PYrJbXe|t9Dci8bKdyrsJ!Qe)jCWDeD2U>>y}syW}E{v3`ah< zolR;Z6yH|`wn|E%C(r~PlWaxQv%G%)$cG=i2{VGu-9j+|iD4JkHvvRY>V6G#E#EGD z>Y^hIqB_Vqqx%w?b2x(bkEsnbvE0y0DqGPCScF5J!|~+JGg+xqb3OUjX`&Vf$}c=0 z_+di$_%+zDXwp2Y#H_&VArh?a>sfwWPXvdq^kG}sx0J^}Sq^6Feg1und0($JimNBK za%I3K**da+#$%gq;N1y|+n0afLR5h~QR4)=$k%N`d9U*q{_+gOo5^bNJsz=moHK1> z5d;WpwBSoqQ{gJGMk=KS)$23AwygR!tSSl%5?v6b+|ph1ZK3mVRMQkdKf_224uE_6 zg7-+I4yw#s;>SHqE<5;qJhTN;nd~FqK)I801bJa;J3{2xt=|V*t&hj_jv%;cLH2-i zIKEBPgF`_?l_E9c4$269x^vQF znQf00T2EF`7-`DJ88I2$?*r3a@1c8P>8W`u-h$0b&M2UJkn%OHgJd8TIfCuc7TV?CKw`T-7+81|)`@qa!seQ=}8SH(Cn{ zMgMZndCsvYq{z|;f^)$*ob@~k?qeOibhaIe?ARYB6TR|R%M%T5e!Y6I3Q6Ok@*6EQ zB>LmN8&P6YN7hE;V&7yxN93jc1=wZ{&^z-27!U?`?4D|TFAe%t1YU5Xo|oG}m=z9h zoS}DKKXIabdD~%Oi~G!a0xgv&UqEXjC(ogl_>r)DtxxB@iY{#^Hi~g8B1z&D4F+g= zYY!0xIFP^$E9SD*oq)-3*o_(h);RHhF1J;3iX@aMm$FOtj~C~6T{kUZ_7N=c#&>%dUJ&k?j78rKRQwLi zr)Oqg{KqRGtB+GAibwS+#}Wn9rjqRHIj?j0?)i^b8#=7Pt4b6(gA%(hS`277mOt@* z?|`jGhaw7%Zzw0-I*w|>BFkY>z4d3CV71D2$k-+3i1Fd7ZG(noXbdIBh=10a?T--t z0+>RbKIDh-@usZiI1%kyI%`x`LPXwF+1p<~$V!#Y!t!-E8$7r3{MRz9)d+ByQ@j~K ztvD5Td$(lLI1bpC`R4HQH}CfvnLjh{46 zqZ_MhN!k~e%owW*g);kgM4 zP^sxddGYKUoHb?8*{wVu{xv;BJ9iUSTKgJRw%G0|QEsy)O${{M{sO{+a z@AQt4fX-|&w>!|1t5dEdh~ss{As*r?S<_)-4`910%n&nWU(DD_cz2v@ivRqHH}$9! zj@Xl#l)CpSz^$8DUeuoDdaUE`6E*ZS>9F6~n6|IKF9Zs^;P1G3;U&kGs3%X1NUcBv zqud3_pU%+~1Q2)?#+z zTs8xb-I)RCwF$z-udcFEJVUz)DCwn|gWDKI*7=Vs!#ujaa!f*A4+tRd>%4 z@r|6i-hAUGM;hLp`L{E z2%z4V?sYu`zDoq(y|2`+QxzB?J=t7$z51BUywf-KfDV#D>2TZgyO1c0v~8^nWq`@f zQ^blsxstNwo#zVhL%>*FuRaTUE%WHj-1R3ZwfPdhO~}n#Iz+fsQ-9?`Gw@5;uV(>MT581S_-8c~H2SqW zXX%4KRTygU^&IkL`H%P*-uL%4>hQ7tu7C8ppr?(n1Iek&3UF#9hvOlGLhi8sX7Hgm zXVxp~1y%>7CIu)xs_k*;&e64~3mBE%PNnsJbE1ag>3fQrQ^>D3+*glU_K8(d{T*eV z3K0u9ki1wGT6YK+b2NB1A)}9+Z4Y(ql$>fu^n&+0@At(u2)m;!Mroa|@1jf3>u=2W z3%qsTs!#&%xGB_6E@0Tx*zd%2eF$z|+oh-8sXBB}Ki#8Uz7zM!7B_BYM3errU-UK= zw^mYN{owj^yClu>wZqgNz$aIAB)dH!v8z!fD93Qp+#630D019-_LHnIh2!W zh^M0+2w^>)r*f|MRa(DYm;3BrD9YO{mOJ{j_jdHQh7}ez!ys_!q<0q*7cD=8)|-AI zQ+s9Zi;A^^SaH(Ts;F58hb`Bkj!Bl@ZTffJ_JeWV+`>9_mHV}g#Nhi_oar6%1yU55 z${4P|tJv9i>D-J2HRNklYaJ2|^a*)#EXG>w&G`5wM*zH};wT^giBcGndPufIMwJGN zIxPpXqG{{wp#ryw)~6Ltww$}CN1!5F9hm~j@QMUIc3*$Te9)ZwXtSr zJ9mI8&btpR8D&$bf|^PxcPj0h^IHHtv}i~-4z=7tLsU%bYVEZUDZ&2 zq*`Ms{TSv=H8lDe98b21%?RzT&|is^ymsXqA4N%f*0|LQ_o9T|$(g`oU}B&+9cid; zqf~?Oaj3yqpF2Aw?=7{@#eBY!BvN2>2Zn&XOwb$P+r2E_siX^{6VqYh`02@s+DG-% zq0hcj2!>7hnMLMpN0~dHT}?I4%5-aq6!6;tRBRkVx76vhi5^xiLNslKUt!f&pH<2g zx4zX2EoP42dB09a`;z0$CXz<9tbBdNro9K?S=Nf?(9pa~a64az!ZMn&!LO82%=~%! zN%Gehx7zU|zx&44Z+&4IUZKtn>p0QP*+g)e>2|zx({_%ZBu%))6`)zY5h^{7=W=QX zDU8Ppg_Wthkuo;ZiOaZVQi$uxW7V#$S{4h<_T@WHyN`)N=Po~vBz(ZIA$xgovoK)g zZbq^2@P2r^W=joCoT6*T(K~)wK zE4xLLTBn(>pQ&A)47{RT=FM%=GhZGb`}GBX?BuQv+9CN3b2mg%4wiDZG4+U3wY6Sl zUXb&LDTC~^U`v|KjFrez?g(?&wah^7(LtBlL!h)iUY}kS|BTcdzh>b&-;WyBIY$BI zK4R_LdmU|001a?@jV~S2i`zDDU*x)N*S#$`C2nPT*flLG*kX5;$yvdXJ5}J4a+Nbw zf61-^&UejxBs*20O;oK?7BhAdv&_D9uM}Ii3v9iO?C}?gpa9EmgTliC7E4Ntq}y60 z=q?J4i$&iC1>@uEyDUrWfqBPqa?7{F{NvN+uUqJDpL{=OvMn4kze{|NBJTv*7do7M zmpF?-ymPRL{{Caci|w%UWKv{@&S~lmUNX;$;?x?U7mQVJoib{Jt(8Yd|qB1#oemxkFRT}{%q4nW;a%PqA%S(AZA zTbMVqYP@%k<_3Mo)^h@DY%03>*`6f#=EJ^6Xvmf+FVvWK>GNw7k(;P3e?0S+i5@-{ zHTjZ|`^?jkh*eNttNDWeOnwx7`}9@I>XJ#5xD5_x7(b|nfH`8ngg)>>$FI^2QQNdm z3yJ--iuJ75ap0`yGj7I`e+)pMilS4EO^W2=M{+p-2btem(G^krIBwPa1gb|}u0uxS zf^;%Pp4!3m>cs*tz~<#f7KzzwxztWK($Tsm3~#njym&Np)Eq5aeTOg*(eug4>I||J zVVut@Y!0oes>0=uW_?diCmdY+vB2 ztDW`p$)rK47}x1jba_>|>t+6wyf*_+u^afGyYq>_RxW_&YG!6-mz&@&RZ zBh#pMDqflD11)>4^U#8mv%T=TSYll=UF_amP=D%iz^cOhXmS#UzfvR4iMeg((et!t_)zVB#;t0O zZ+@CUfU?c;RvE(sBTckStVg!>`c|*BI3K5f%$Fk=*?qWJ=VAbTeGmih-d^L-PM}m7UJGQ@zX(p(hf&Pzd-S=&t=KvMI!e( zkdF583u%q3WY4#lDFO;@j$I9);_ZHCbMH9!t70Y(t+s8bD#@A-<+uPI?iIy(ITh|( z20HI&=#MZc;T=E6b3V5=AvwXrxd`YRTxVa6FYDL+7;5Df>5dP&U8R8`vx?CCzZ|QeR0TrRp4W!H>;Uh?HQf zhIMH1O+rn<>no?Nr7U?2TUHk??mf>|PHh&$=W*^!=+^R-9!%8a)TZpaax!Y-0v}P} z1B0(-jvrLFzJcU1%}ob>otM4-<)>kX9!mbaICk`>+tBp z{ITEHMTO6-18$dcJC*~S6V=^sd9NJeT{Gx8EFX9kFKkb+-|oWL_Z12E^aWr4Lb(Ni zEu+z%CZz4<+X=d#tB6FMA4w1i0g3;Qx%Upovj6|bt?bMSmA$hm*()J?Q+5btr(E`? z5RzF!gpiSv&4oe~A<5p^dlSCTvvI%g`~Cgg-{W)q{`wt9$9wLYQ&&TsI z`jgM@)Fy8I__%I*ta%V|_~!~TqMmOUs1lZYhexcb1a+qoaENpA?w*U;l$g2kF5=@3 z8I~+paF1+?UpX&|U~hslE}+@%*6v&CBDCq;?KY#=H`Go(c&fmo)c? zeU`U@SA~1{OwZ8ALVT6Ls?kT|^SZa}Hlsxu)zN}L2+nna=WRROGmr|r>t|`${*<^P zxQ*4sR}pca@oLVzZuj}jvFHAms?!>4L^skuKWZ=sz^$;W+{JQtZ@$Q(Ssahv+c{Y0 zDZ|oqsbddkhOY+Rw9x0P*W=Y~R`$HD@m$0qRxUG;A61vISd_10~if z0q)Oc(vSO;_L|vlkWqBQV}tHHO!;s^9Bt-9^K0R<~%!Syj(Vgr|p^he7X-s z=eO5-is^aVg)20$Sj^SY^FL^YD5R1qpz^eara_J=LAQ6UtiaCJ)axxWGfTnc>$fa8Bx9-c@$o^geLQyT%{;4lEwbj~nGV2- zye!ed5rE>vn-t&goO|X6Qc3HTlwz51iXdt}(?UPaxf`mlfz{-$YAi?&t)q6GyZ7e^ z(wx!wUJZW(+m{*sBhiT%nH~NWt zV?CP8)*`KeMPKMAE8%og^~2ycj*Cz4Vo2%xJd*x06+AAb@%z5A}DFcWXt6{b_9tQ~oA>|Tx zxETu$KtQyS^*qoKU^ipS#y_Efe~mm{2oS_ei`NNeW>!E^@Qrk>)2`i;I>7D{KgY#T zVw#MEvQS1r35%PS*KKHu_OlPx`=i?Fai~nF%HZIuC*!a^jC4E}iZ%pOlL4nh;Cab# zUe8>|@kp`v%3iO|eaS!hK8%iE{tGS-;ykh!GYRk;)#Ag!*#}e(c9#siQRAoFs@ta% zn$MGTIPQEq7Jl8E1&fs0FnbT)P8{Ni_on}zD->C8q7eti3+fB_q~e+{ndQAcY-?U_ zcxe%x7~Bw?RDNe(zv@CxKn3kpv^w;pag0TDImfJ`pAdH(@SmdxdB+;@!51A3)=ezz z=|yPe!*dO!@ie8$gF?x#$}kKyU-0w0%HML<1pj7guU_aub+TQrJNF&0_a_ZFj8`;q zO`4#=Wk%v!j6uYI+A`gU+it;_7C&{#rS6j^3P-SL^%T8PFdh!oZqITg%Q3rgUAhlr_thkuoT+JQ&4y;l)Wnp~qFMDGVL0hy z71>3Br#MOsAg2AUQFeO8LKfT?rob-TVEE+V8V*gODzXf8)N3+Yps-EpEZpyx*@oU* zlQ^Baz^JUy4Mr(EG#4HE&+DmAcgF*NUU4yyRzh0@`@}$HO8d0xb`>cz77l7ZWc#8$ zV>2kNf9N|ThB5M;XvGJ_-uvSPO`FI=429--2Ov6p;XSeFSt0iH)H~sOtJlwkCA!?` z$6b;hY=G)|!S-T@0F2xzQ4b=hHX@<{ByDaR=d1-x1`ej^7hXc%3^9@HH#Ls){~ChG z;6Qu3Tby=L$HONYBOAWsK%zM5Et7ea zv3c^!y>{+U9Mp&BJ}sU2OpAeMUk{eUM1?r&)jNrdKRJ8U8;yHjT+mQR$!Jadi= z_bpU9mEa-JoP73GH0y=2_m~RQFatHft!}}%WcslWPCxzK%;O#!;*00&RlISidBsk? zO**oWk4(goJ>8qvlyP_g0seIrHUMD3GO?Zl+XkHi*7aN-Mf4fA9*KTav)ByRRn)p1}{?2CoPCHZbQ;vy?F~X z<65gLxHHD%q`1}m<(I|e0JQB9e&KiCo*83NfOj|zsneUKP4nw+=y?!8Y4(5ks=RsIe<@9PGDJ#m{_?|9PxNF_atQc1UQyMNZRFK3X57fxD!edQnnTiVf`QNTGhxm@SUxq zDnkf;{^#Nd2*d|&0E3(=`>)L*fScVPPlsBcaqv#B$z7+hF$b75YQs=^7iz2LFi#9D z^0Sx;EYco}cidSS6KLx*1`%ni_}S`i*<61?fR|$7upvlj4p3As!=S+>rF$6*{3~W8 zfW&QS@G8h>lBk)-XVzA}4ZOC|=pl^@(8g#pi#~Hv-8zKP8OGch5j3<Leg?7{xXZ%yzs<5?J?X}2gw1KKk4wllLP`*&md%JGS`oQ74F2x zysc6yg0pCUD$LM)ggdhjx^XR2&z}0DLs@knpU03Pr5uK5gxc@{m82doch*ZuHjy^m z8dB_7aNN_=6L*`@w2nC|f5!0UiBJxHvasebh}u#$!E-qttR-A%d7oH^0lSc@|JybU zCLaO7kWYGbMSzIdDg|@U+%WGbTO+M7mK~%D&5Xx4XUN{6I`4Q4dD7aL&iC#j$5toq zG|B>*4VPM7>~e|Dki0qb!?Oxx9M(!vUdJOc@KMjCfsQ8%Q>gfd z%dnhtBi`9JR;JyvOCk>-ANA2N=eSD#8;`+J@W-vLPY*WLD002Oe?5oY*x^e=Lb|(a zC=|M{#%VU**yaG?Z|;)&%xeV1odu`#*P^9PYu=NJbrDk0)BW+ky~S0a1?d6qiI|(F>35`$N+|jPHF&%QA+g&l)mR}khC6r&&0(H4Ys?^)IM9Eg zDZ3I=AlX&#rS3)z(%hM%TVwS|_T$Zpo7@*jGTCs-e9`Iou2Ze8`wXq=Pl0KipXl)c zB@mgw-1*AxDE)H-eV`G&TgtGQHUHH3ue}s(@n z`S}I7<9k1U<*|Mv89Z~$b1Ohr%XOJIQhfZ_Cxwps)iu$HJ2W+Svd5UojURok1N5LH zdGZ#06Sv`8l3tpY@Og&n_OZsKYYBnZ&PcJ}#G!8(1O>p{rPFcUbW7>p?xCCWy=@I4 zM2pgkAFy_xuI^wo)2KE@q|K)}4$O;mPgUEy96d7&wI3|kqR|EAq#g}^{rYQRw&+4i zJ`&#Q6*+6?8owjo3%oAFWX?s{L4Jc~^$b<~*vE|sAMwt!VN$eMW5Mw~yVW?gK#NyPb_t>SVS4|*Q7bO26|>j z5A|O+9;1K-IJRcJ_CxiZu7( zM;a+2TC-wf#^zvY_FnR6dIo zg_WLp;$wO337*G0uTHf(dK-?jvdobZCp=@}jl_sPzOxUN_7wcEHhm}hHC((qi_x+a zr9`K|7p81aC62UL?ME_B(Zu_X%?{4AM3?W}i3?K19;;#d_rNkqmZ$T$6GwR>dJbn5 z#wUnrOzY@r+%A6K;nz0NYca&w_8iNN#QnunfSx8my=R8dWwzgw4+aL18Sxs@dYc$&ZsKRF~K{@HCF~eA-xnnIOCO zcl(DwIXnJ1#Y_!gtDNP=0oxHPbV6v3ejfAp>_1ouO_!&~4C{0GB*Ee8%f5sIHBqyK zWBtaiQm=L1$Yl@eZ-u5c*H*?PhxHon%Yyk(PnEJs-R*hBy7~B=*Cq>3B;4hD>n(pB ziGwULI}dCe1ucqxlU4k2jPcP7h}RD<=aLo-%ql;MCKTC$_Soya%XN!|@FJI0DutD9 zX`Nlw@}#%#U142UD5B>j(g@{}=2saB4ogI3lIa$Gn1}YB5KO!erje59qNn%ZBxRoC zU%o^bdpwk9r{(@{mJ~H`-PUta!#KJ2HMMv`goY}W$n#Q}O4Is_s}%D9XQf_H-^xl! z1Iu@5+M+tV&MGi%nz?Ro2xe8v)p|p*4~JCfq$O(JG*hh{p?p;GG-uYsTofv=FXZ@Mri4{BUmjYwRmd~w zG~Gd{lBT>5M7QE`l+cks>4-w&8nTIm`w}=jpiw~THC^(StzDsk{lq+%#=BP-p5R;k z98tFn;OV_ za?1n%n(tSrkm0A8ViwnJ-fr{hO@uDS$_T^T^I(Fvr)K%khcSR3pXK}{qU(!&28WhK z3zI$HiI2bNr1o%u98MsNf}gy|pzQw#FVbE#5#Oq{oW!WTc%Usypt%+ z=A6;CNDE7!vhhJ~TFg1DJ}JK&UPsy&9KZ1rSW*7wxAvVs)kj5vAB6B*L6gl%gD^G! z|8Rj$9M2?wD~na3U=HKh63E-U=San=Ef3GYDe`9Q-@VTtI>G*p+!pOw zhq>|xP$p7t?E-^51|oo3fn-B{aRhulra%uC51@oGj8bSWj(}~~B(M`BmBMW1fn=-j z?${j|kkY@SCQWiJML?5lz>{q!>Sw?1Ldp=n8hHOPimiCQCE;?8-#3w zhyga~c&iioDE@m7d5#AlIfOl?p9oPM1qNp9`N^1^;O)q z8I(|ZVN&(>&8=SbDR4>2gtQ@jns8R`N#?h)L9n7Z6o@4tsKYwGug3BiEF&Z7rA;4Sbm9ewGv~@lI|JNSH%a$~ zN1lZt4QKf(nqm+BO+L}$i}kst;qwU#KvG?|`fQpP-2mEn3Jv2(JSaGtKN)ET(o3?P zl_oxYUJ0SS^xgpFgjPE9+1@}*MZ^_QxvXHb6w`pdtkV9ASM#DhKEWgnmX+|I@z&3W zs}zCkN^=ruZ!`NBMLs!iH=gi(9GG(H<#tN`a+%P8YXk2!csKn-J$(bX$4r9nq)O6= z({*S(9W38~LohyZEW$-yW!;2@wNOUWy9PQ5z12~O8=Xv9x1A*ndB_qIf}{V^kP&+H zlN`FgnJm9c?O(jhzy8b6i*Mf32-9_A$ZE3L1@Z>P-H~M9FItMMAB_y}BWf!tpS>2~ zs}(+e0m00!AE9jFtXEC|SBP`P^dYQ9m0wh9+>31jC4#0t^#A=uTqA(RczfP^+S}>O zd0Pe${ayU-4B`=j!!DkWsgeVyazQh<2K}Tmlp%=4Ua>zdH3>7C%ejz8#SG&#+y6kh z{^vmjY+&jsHp`YOFl*_#B@*+KZ77G4>TmJR3yq1_0zO)n68J?%W$JW5K#pr^Quym6 z|Lcu1Aq3!9yl5qcP&9OnnG%Cylt>_FF04+WbDs|&NU0TKI;}yfpuA=E)hqnC4m?%IX01;e6&-jP2Owgw-U_3P^<(x61`6VihVhy(je+L ze@}j3wc7VdyG;^1f*DPbW3@VdRDlWTBWUe8MF}THU}(|f;U7!8I4YqFtHM#o)I*F* za50TQqkDBcu6MpR(PP-dWYtx2?HuL$zurxMGc43HCT+g(mj?!ETP+dptd7f4svF*w z1y-9${RALaI!kH!E~3)h9JsTj^EXY(OgFqcPma=l1`Z}8ssopnbvPe!4s6YLaT}Iz zh9&m&C6syA0d%$AyK4e{H7mq&%e2fgvE(0G37*cv^o9XO31#P15=MI1T<&jeGvpC zmTSmlZ5M`g%z5u(6?d+mCY_KC2JY7j);P^x5QnoPCTK|WdbbDJUyGRQ-WNO5VR zK?GiXF5fC9V^!j0UF4rnqyq$oMM~_58Cw2`T_bAu07?059UZxfOL&2&Dk@A?ATl5` zXx2MhGD5L8%(ATFJx^M1IihYt2#i_OJ=XcUxl9Pp?#;~}WyL-t%GAnYyCYT9<0vYg z{N92O63f+vs0uod_y@cH_hb0`c|`MJE~4en%w^O<`nV!A{LFwX#sYthW12|JWZM1h zt&HjJshSx9zx~CFdc<_W@KL#(lVa@oJJ)By6mysdQL;tWo}6{&!1UP#WY}#h*l4ES z;s;R}&1aRySv9wn*6yNV@yY|M=$aM+zE%_!f#nP!D3_4~yqkE~B#>aOp;)3H-KXO9 zVo+COJ~1b^Rst8F`L7)V`GTPl*)|$A7~XFyi~`e5)9kP^K5#7MNwX1$`5S>DuqI;e z=gKmo^_?)^A)VzD@wyUII{KKh#T+zQyB=`ayhoLWe37B{N5xIBcur3XQ4N>20XJ~b{rxZ^S zm1K6p$z^Bww=810r+a25IRjs#Q%S`>AfqfjudXZXoD)XXMuF2`fk25+B$mHgsSbj# z5(m(lDXIs=;i_4K0z;swg-zmMrp7W@Rj@(69iCh>g!?x&+59PnYR?sCW-If~2HT=& z)%azN`7l@ogPdI3|5&*Ux9|-~lUy1BaKqpB-~F2Cj7Y%ITY=9%RHoo?H*#M{5J;Uk zxN4Ry7E!(g=!HjKwe`x}T9+5X(OY z*+?JVdKm3pLn&W+F~hcuDI?sna|dvU^>p48cN&(cO0gbw%DLJWJLL`%RdqmMdl$~v z1c|6vCmx}L%qujB53fF5Mm5#^VtcAAz-0<$w2i*>vyyiE+^D`o` zx8F_2e!pJ=!AKQz;TJCINYb}zfX}XDhalZoy?&#a&Jona@qNQ(W0&_Q^HQdK3@%^I zZ|n11BjT&(_XDeEvHY3~Q+5XCi>OX7@ivdXi}Br}Z`0@R;LhkmJ(r&(2?cdK%Vur; zq>m+;=d~gUwT&tAr=J3X>>o=HsT;iA?kMPpgtxz<@Jq>;R`&YSAk>kUUxumRQnb)u zT@F8?Wy&#jUvQ7Ff8P3==1ZbC=E=-0A$-=aPDGK!IIN7;&wbVooS8wt1?#N)hOT&Y z9GespE5xVe{Ra~$WIV{<3yQaY23u#lZ^h5TOCl#yt_-pVykvI<>x^*gkGHldO({mL zF~$(j?TJ^Je)KC0zKCDB-O3GTuhskRjLZ)ugHTFSC z(~aeH9W$t5f9~}>-a_0P*)m!fSOs`$mgZxmYC$)vP7`nNNuk?3+gTEp2cHJc%zrTt8v?RQg$3i^jQ4w<2Ao%Q-mhL8tSkrtCW;p_onX6wAyb3f3{KB!eSBjSoZ6Lu+#ODiM?po zrFShM#)Aaq&EMxxud2B!uzv|zapYm(H7xUeZu13$^5nSsJ>zPZF`sC0zNQ-_nACI) zNxj!PRc4PvNu3^Cw^TWgQz?D6G57vgE|KFNYMb8bVy2r(Ut4WTZhSiJF<($N37&az zKv&f@w;~?mKYIlswgv77Um}(K;@A|O+OcN%axQ=wC#Ugr)f(1aDagF@00YkVYtU`j zS`^^YWD@o2;neH&>LnRTyEZ%vn|f~uG1lB*|MB*!ZR0Q?rF~HzZuCFilJi;VuG_%J-+C@cGwNx5mxL}QqtvV22HSPt=JKr+q8#ukzfo)oRk>4rJVj98VtFozSLI1gUQax@CQxyBW=_JiliV?C z_Y5jJL?4$dQ~8u&?a)XQ|3#{;!tysoscm(;iidNdJn(IB7PZ29A& zVF)dN=^4u_3^n*@5h^k9nMU(+qM#mVjg-Mo5>e-$a!~RBa70nWTA*iL)N5HU`hE$& zR8#A{ol84_A5S6(0_?n;%>qY<+jUd$z-!s<*yK$&?mq`rTCOJ~v)c7eTPun`m7#e_ zEqe0{$9>Z&tzIe|4HE+k$AcC`LD+iy;$V7vH;kCGpi91aM?<7h#<_4XXMZ$D(nQhF z^BSd3MZ&{@1t#?LNvG-V4XKE!LD5GlH*UKmrvCh3G08~7o;>|P+lCR-;kg$816&#@ z7I!-*^KFaPPV$)=pX|g9>YOUI`3&v}^6XH82`0!0hOWTv6VI)2v8>>qUe-A?Jhw3; z=y->bRD#Erc^E7sv_nZ~^N1}sU9CVSegc(v{2bh}&&_{`Sw+=r;b`neur`XvLR{@j zV5DHMoa}4u{^ZGd8*0gUQR2m&F}p5l(11_8kIT9-*+g+?ZZ+99)ji5xN7OJ1CzjDa z8hfLStL(=Lw@IO~XxZ~%7w+k(u>bIAp${CUCALH=8gvZYK9t$Cu$$|F=X?{63p|k7 z#pR&Hd3w=OC`bl`hCO-L`ICZ|N&ulyj`lxUJF2$^R_>a#E}j#YgL6|muDn;6QS2cvih8)(ubV=ZjRZQ_f;Sfxh@saMouAj~+bFtvL>07~Te6%W&*E+Ba^^$Gouk>Wr^dgfiYL2GG)&`dufGFjdcXn`AbAU7X$xwnDf}_1wJoCk_zM)!?cWpYM zOh*3B`)kH!qI!C)xDhyqwc2Xc9-qGgk~@n|g%*N$D{;@0#ffIi0fv!iAaW*?sM+{g zEV~GDlrHoFk7H3gQZ_c`crI_?n? z&7zA^Rw^U5!;rwuu4RoRe%UMiRqjqMw;zv|)yOr(6kp@pTMIrZATWWy;=wwhPIC+f ziN8Qu4tcDjQhx4txP})9CdC4Pdc%pMSvWIwZ!qb+U6=gj4si7n&b!@~nCk+Gds-RL zyKm1C-La8QpLqpW($5;8y15+)g20WHQf4u zGBL-d<6QQ~>aKW4J^sdpb1SnE%;ofS0o%!ZGzkLAN5DR6dZ(yp+Ytxa`TOeOq9mSD zmwce747yjyI^0Fc5FZ$=a=g@nwv2{Mkjh ztaH5?WHPgA@lG59w^>0PJrp>yH8`g#%!{8IQ&&8K$1*_w{VygMaw7uxk(O4q-=2$| z;Jp2}&s&oyz&?p0KM%@5C3~!uf?LuT>;amo4>AV9!NwY}Pl5N(A_Fd}|3LJ4=V&)) zMC``|&c}~|A1fs{X0Y?83%&9j&LAIS<0pBiE$P^rq}%%G?Ui%}tZTXVt!vXY<#!-mxD~Bs@wGo7}s+sFVZ11i!cdn7@cxFn0aGdecr2wbQh$5C-Ext)-f6Qy=Qr zJ%pCji!jXVR}Yh;89p9M0A;0iU$O2W94x$ETMPG%K6ZGA`hsPj-q!MnQ*ZPxk+M-R z9Gv%`TzYX6AI&=2xSs^dJ)LW$)1|y|W8gTn&;CgK_hH={?+uvxt())4a0+TT;Ew1t%WOJN`*$+5-ATO z!bHF=m?0WO^8>$v)eH8Mh@pj0 z2(spZ;g^C(O-2upGGbbG@B5FH^RsEQoAqwh@@`)nF{eF9i<4jg`FBL)udf*_31pUW zYgqNw8oj7%1W$?KWSUYBFns}zw8N$}tRUX#0xC(iHA_}e5ltE(&2^a}M`!Wl6q3)Y zHMOP1rn?COOG{T+cx*T4EjU~ z$N$TH?9cMI;=tS%|3SP+{GKfUg|pH4a=59Dik6gFhx+!c^uZLr#2|=kFWP@2GdVv_ zjq46rOqF1Iqo6{+j^mreK`8qOi5-DZl}>ycvJROw)xCi#*_uvl){6uak>8nMNcOEC zC=ePoY_5p!bpe*mJP>9)=T#$y!`!tvip{IRb@N8)57J1Kg(m*{cDUcvCc(`tFDRm_l^o2F@}W3Vta}#R6Qp*`vwqy!Ph!koWntbpdv5_L zVSYFtnvW7^&Os+ZASH3{`*>ImfTJFdBNJIxD{crSPX|@fRS>>Y`qu#^eiFvU)&7CP zt)~1Zw!MWr4A!Q=v>RbY%g>6hN-3OKm76B$DEREhBq^3Ov+G6+ zmbL~>WzOEKus@!w5!9CsBIiq~K&W^&rDfN03d-&VmI{F=BdaQeZV!~hx7qF!XxJPx z-5hQ&G2J?7B`~=IO7TTDi*HXjlHO1Sr+($q(DCues1rl6Hb=)B6n?IW_knB~#d+&3}qE#C*>X z93yVMx>Z!84{Re;&wBElKs30DmnyTIl|{Q8Pw9fLMRB(H*40#33%6wCJ4ELL8D{~3 zwFXPKITI=?WFR+cl4zv#+&$EiV8(vpSdm2L{A%8I6mQzXD|*qfD>TbQH8@3!$Fg!Z z8@i)w2Z@Nj|6~3cpvoZAR-r1Q5+}e;fHp5ca;*B?sS{+cQfgQ{ihp_|rz904Qf<}d z^yrkH*NR#;33qf)<(+w}l75f$dqK~fztzushl*kipI)K5>+eeG_W?&I)pvh7o_+7S zplPfH86W9hi-!~)Ey8H}`^W#!*Zv&M$Fi3Ls%Heoa2j++<_tQ*dS+n5qHmoQ?tBu; zWT?yh)0|6dh-c+OlJwJ$v4Iioaq(=sJuApj z1Pj6a%DIEi=qH(_0im2cSzJs`%`L7-YW;xFP*`FdaYX#G2WXy2Ab%s{25YbSH7f^} znAzXtmfS-Kn`DjiEveDufBn;BtC+xfxKt~+68q9H*x5>a5$>Y~#)>#FR%G2d38Oxp z5G7i=?-gagoaR+T^V1hIml@vEorONvG4hr;m#3Vrr-qZSfBN}?yzpZ~_D&re3n8E0 z>#8H}VGIFo%;;UAp?3VKpQLGX0_RlH1om6Z0jlhpELwO#h0BNqH@6fHBXc`@KK{6u z_mJBV%LFgNsrpeKKGb{QS>vf`-3U)vNaMu(^-G-ztoHA)8b7w@F+u1p?I%Qm-l$E2 z?4c_v00>_k7!Z=Ax4113|LEtmfnf;W`B1e?NX`Sfa}0*yEcSD1&CpGN&}N| z*S$2$K0pNCTF6_)e1b7;a^{#j{J>Aswsgd_?a_e{>rcuL3mI>KeO+O&%Ay`PcCY}ro#s59``4wrmjFymj#k1?U#nHu;%&giqOi~A7cnpF~d9Z zko)>Cf8>~A($e^<+?P*LZ!C?}Nk7-0xcC|zSXtX(3_D>XsJfbe@q+zV-q6}RVEyB{ zF~dmjy%IpX{B}aoZ&9Cq;=g|{I#@>QksSAb%w>}QkS^i@hiiL*4aH>)OsTHG1&ZaB z27B^&swo6i1l^Kq<;yExR}AQ6nsir)W$g9;&Jp>)?tF*>x@h=IkvZUII_j*judsv5 zo3i0kddLP1PgeTxwL%9}{$6bE8^1UD0Au!FtP5}!zV-FR0yO+ZCn4CYyI;A0*|AbRvH-OdEExaE+KI|M#793(tGp4Cx!kHGXJ_X5@hL&MR_pj=xz6C+lwZoGbm**7gWE=ZcdKBegYW!FYn)MFar~t>82yUsXKo68r^e zmeuJ+_QT4NLz@-8Q8MEbWP`P6Dbi*|^cfW`_8mJa!)61=f{@rVsbP%MxjCulU^Iww z)4x-Fck$XT08&%11IEFGT^V+QEC3+8Ktjn0Bnf>^`&9L3H7V}X9xFoaKV>vPmzhNR zxQW+@O)AU~atsH5^N9bT8~-7m1;mkmD|1Q%81+)=QIX$)3P@|&fkvb4`2n<;N`Q7f z2fI0eHCewcn7eUGI>6^bmN~gcx?e~wS!F+}^772Q>ZT1c!bkNGIRSzD`!9E_cx)08 znb{EWy9*pE5>WCehWoasNt^vUGD>3O8riwD3BboZxVS<0rx3?opPu=@$gwKjC#&ZQ|n}_YAur^ zu0~B0VEe!bqDr00g<7Beb3+aQLPV)GmwwpUXrP>4f?%K+#9|g9WC0y6YBu|}6neQ5 zVP$v_8nq|k{-yo@wcmXpD|SRpgu?7vU?h+EkEiypfhw}b(#?VMNOVJ&S`_%xS%pRA zO;TX;vYQawBc)(`pMrG_q#+l2vjJv&Dveqhz4wD7NLuB}Q$#x59QQize&OyN(VEf| z6#~}eE-)v4A6K{5%4M?7)YT_#QZ}#^ddAVYpz)ShCB+-Wi~hS&>kPFAPtf2GFlbkX zIyoW0N!64mKkK79Q7YNj$!hVApk9|yVd%uy%I(LWipRCRL5QKP>^hTHN2&zHKR5hf z6^4N#uCXqwTeETqM>V@8nRhzg71?2d`C`#g)i<0vyUStEn?Q+e6nzJ>m0>JexFz7` zlb{pm-NrAV;GJ{$(Uq9&k)zK-(VPdc2(NdMjp_M)x9^ZQ!#lVEX>Lq=p@-nwC^RC- zawpye_RZbTw{Jep88!v|O1<)c-dt+L^^FDnyeHV3k$1iY$CpM|y=5f0p*Py6&AC@f!HYUf7Pn~P zTA72Olom7sZL;^~j^2qWFa7ZXfVk6)CsE(7k*Mm5eaCE*y)1v4q#;%)+oJJaL#p)g z_t$^fKnM8aLm7b2lFt~x%}6$XqrGy%=C9`kKTHOMTXD^XZT$KkF+SjS^d)f*k8bND)t zZ}aIh;I6h`@;ZXj{UI3J>C;}4TI}g{`OcM+h5(P}%)vUMkrPuR{yud;4ouIbql%&n!v^a zJX6R~3|nVZn@eYRA`>psqyl-cb`Tg)${LcclPxpnbS0Qp#qax0lV_(01Pc5z;{0>u z5HbK(kA)$S{QDRueB?jHBTF+pH}$j_=WLww*TnI_tbzVFc9s`OL((@(%f)Kv^71Dk z>-u$fu>^FpPgxVD@dIA*MDpD!2d}V=Lczk2@vRq`QLz9*wMA*XvGfUWVmG4mBRW4B z(m4;pSG&Y|K{Niz5Lb`S>9Tjdt7(fCpV4tBmXa@nL!^DyTSshVBmM^@{323-(PdqK zA5MP7(6kU{Ysl=el$$;><_`W7;H3AiU7xp3VU(t3lIhE>$itr>f$h(h?_$nG`9FHD zzn=^NZVcugit&ieWbx&4;NxULRCz19Yb}rqa>nj3T;JG_)`WMIn`WfkO2b>HS?tV7|fc~{Y=J?S>8GusIK!6^M_E+6WnJb+5XrX4=%Q;ffSi zy(pc_*|#aSkN#QsRg-ayvkLuZtdFB&-V(!@@c^YIB*8voi3)cPg^!=hw>u_@seIK2 zojCW?N9U`yZTs_-Z+^(QUV2RQ+ox_hI5sCiOA~F;3H2N`v#C{}z#YU2$QL!IWQ{*w z?L}iV!&R-#Q10Qvakb?6mwW?_to8rrLk7I8FT&#?#z4kO1hN7rIVkjc(DIw`cx4p5 zPB2b@Ct9t54L3RiECQZ#npD0arjsz-B=VHE`Rq9k-snsXFUU)(W;LH$Hx81@9T9jS z&Xq{TNz*J1ZALU`*M0YMj>o=gr3=)#NEGCZgPJ?eloWZZdv%u0 zNl;?-$yaZ7uuaoCZV1+{IzX<-KAR>&*_hDXC;VRwB%pvi`tVMoo&p`qtIii*xdjk+ zZV}t2ONkLgLtN&CK^|IC*r2%$;IqL1e&O?2U|FN8YP6H#3zXCn7!ln&4;gHipKfuC zeZ=4^LDaV@??fkVTO0vDO>ZdJqEP4IQ`M2NU1~Z`Bv=7rIW$$4o(%#P|12CY3r9`i zRGEZqiaXx~v0w^}FIykIgLt-hrqc?a5vnLeV&O~Z^T)_ofZDL+Vo8PPkv17Cq&mpM zTVp{_W3V4zdL(lbA4ZL5+)bMYJs$qbX!z8#+OSWzy&CiB)n|*#VZbwMeSYN;R?m}P z4@CXIIYfAlw!oAFE_}@a5T<&hBwjm0NtCBwkQY^I`U=*w_H(7@PC3AT&6k*6(P*1B zST3mfkP6B~;hcu05g1ySnN#}i8vu2+M`7dCL+46=jENqGz+X#yjjfS#YSe)$pHe+l z;;KS4okO&f!?yuop$}MuJF=g2oqHSfZEd&y%zNXSWzKsP5H0b0EPiGKHMSluZqpPi zQ;1l!6Shkv?4r%w{HYYUbC)g@r-%!~l=NCN|-fp{pH^QGU>gKLv3B(-0GSXRa(HQ?3_DEPHYm~J1; zbyUyHg9osjpV`q`Rx{b-!sbcRN4M6Tv@y*N9k6awYq=u~2LfKoNLdt+^5 zuL5{yeD54=Y6f~lmqun{5I_8t+aIU#oHkG+6YUYdhTPoEDxS_RiGj!Y7ge0?%U_Ul%dQ41jo z&Jx>BCh*lXn1rEw0>D4#f@UF#0h};Zj18!iE^xg~tAM-laT=qn^U3_SjiV}=BJYw_ z%lk;8H0;3&fdm}FN63VJWJ0(WMSD9F9u4<%lh<1zr)0Io+N>Jf>AkXRdgYdWCxdOOq(K~oc-`F`PYu50m$!AhUNI^ol00xfhVV+YY1Yq>AA7j*FR2-~JSr^-%K~y8O$oo{y|a58dgN(!(SH%j+e#mQOi` zFC~2pp?=npBURU_Hj8@7CpOd}aAIWV61vL-ChHFo3Q!F{3IyGk&q(gu1zBIgKrXDy zUrluk7nm?S;<9;s!1D7TRyv7Uz;*jAsYW$EgwI6thrSEfF?>d3>N%u8)epjybBRjQ z)S-tj;dZr}yMXVFa;nu)57?tv_Z&DU>;uZt)f8hee_^Pd*6J(F&R^4iJAzeY{bOhK z+#YnNQR?cuuM&*5nXfT`OULD$obhjM$kFM$f2^pAe-a5ziSzYC48dCghKP9b`Vpjm zl%;w5uBgOJ{iiDj)ASP`&T4UT{w@?Jg#)0k<-kBPz}BMXo@4UWz@S-#b= z49l=n>*^~=Yra3%3}+il`_u%*9Y@5`qXK$Lfj-E7mF$BUF;#Cjd1{Hx-HqGBnNz}| zxD(<_<(Ez(y*4y#k98Xb{}qYSw8bfI)pbLr#Cp0vhwJ7o`I7#HMrFKAfG=8?Ky`kv zJdlJ?#V`9#8scuY=$+1RHHKsw58u#X9$`)I@1@;!O^*&5_Uwd>-7ktx@)`|mW*z^y zYT0NRSXgPuPV~EZ?=2<@e+!|bSExpW4|)ygUY_U5>KCt4|J2X@_5K`zsWYz-;_~|+ zVnT7$5!;AZEqu@}sRh^1fjA4Nslw3o7No_wWEJVU>l0Xz6_WY#H!OV4ep^u{$-{UFv!dguI7jt$3m0_5JIFNk@n6YD8$80 zmu;Ebn(6(FR~RK5z)LiHqiBwyy^ep=1{_=B!KH-DvIj{4znTJdKT>v{hIN5z>7 zH&190Hx+qaImhA+3+o&$;R;x|ee=L0Im-cf%`N;KO`!!<_cUk0+(&Tv9R+eZKrr-GO?y%ryE%!uFz z*^o^SF}iA3t+Zgi_XC6!fqSru-lN7|forB7UAS)~Eu<>_y_*GlYIpEqS~dV$!p z`EU;e_s8h>E`p|{U1S1$!Jl;pr&9i&XLki;(20=2B*h5-O6d zG|Md*IzZFK@ChG%i}x^HhF6>At7vUhw^7c{%4w}v*DnW*EqwpFmA z(mlK~))*gn2$3hmuE2uf+`!I7jF?a5Ht#DyAVn$f8L8x-|&Ul0?sCYQ1 zgd+ncLW)t)K}%1(1ho04{SUvbB^=f8Ipduj@y6mHj@II~41R7x!th`(WP-OCLhr7Xed>fdl`sp2_B!+*5p}_JMMxsZd&*KtPAxDI$En z>F&;0hZ6b@#N$6gL{IHY9ZOcxje?|{yyp5f+ z(efET`?pV>AfwN4@5N^^e7_W6U(Fc2nepQVdKrbU*lct1uxVHQ3o^(ORT9EHY-e|B z*qAk{n^VKq2V+oceT$Y4W9y;`#kd?rS6?dt#Loutl?X(BHHV3glwOJ(5KqeE*Lr%m zVaQ4Ku$hm*w7u$WDde8?)%sMO6?J`A9q`O-Ea&2(klp&;a;#C6+icFjsuszg@KPmR z|6Y~*gxYk-KQPc>nM%`p45b=n>Tc^S&m&>6ZW`Enn*&uF!|A-i>GUh$3Fi6Aq}OSq ztE4i#AR*eCD|g@KG&*l$0O--X3OqI2xg)&#U$VJ~`OInuaaiXsChu;Vx=L(Iv#Y1r zo}zsLtMzJfxkylkceNN*$4>Q}4odvKX|H2p$BGonC5883qajfEKe4wz7-il?OMeeA z{gvlTmgw&*X5#eu)XDVI1|c*FR}FZU!0bvjv#Td^Gt^hi9{KoLX6!Gd?f=IB_2-ZL zea|EwzN-XU?SOZTF(wWI>}7i$0>d>5E}>jb{+l+nwBSNX-<1rH8n@C_zBfWYLMCCz_+cu!tk5+kq~t|9-w`0baRBY?Bi^g zM%hH>U(Zj>3yh*fij&W)>5mCJ4sswgU)_Rh@iL~;>SR80Xj%09G;`6wZE9E5E4fQK zxNA}%5E0l6QT_YnKrZ=?7DLqwb!0`Sw14`Bz9vhdZ8?TDvkQ!18` zx0quV9r0FVsV4eX($Y`;S&0Gi$51tKFBqoCk&6_|IJ&w1uy?WIg7QDV?awDy(oJuX z83uQ_q`mdEH3|pz>@|4ORq?Hm6mCI7|GIS=i3;N50q0MyAWvoX|MIE)uW$RkEa1Jl zQWW^F{r5-y=X(47f5|wVf9$x3dT!XZ++SF*hj0*MrPFwS|4~iPW8uaR%Qi~*U4JhL z4)t_MFw}k~cMQ>Sx?I)qJcJ`k8;-p0L|A^$-xOFGNO|u#fB5t%Ucj=6rRwI~rGE*y z%^>79t2IVuTCjCnf06ilA0+%5h=)!tP%|n>^S46~*X;T8|A(^cj^}#+{t*=tl0?bK zNQ$g%K8mtcvRBC_%HE@C6f#0)GLn@YnU(ClvQ@TZ@AW$`zpPypm%6!$8%H)ghm zHtIoE?J}<4v_e|HS{Aw?_+<3Um-(wrE;nB6aeslGTyZ$)KIxBpy%<;mU0(4!hVPX3 zAAc!xqK@p~!77+9FVmWzA9}v-#_oXJlHWS4=;t2)^{Ha8v7wcbAp>)mI&*HY zKy~km&7H^ca?!>Sg46QyGP1<00KVAa>=;yMA>!5Qnj}*MJs%%mGNXz2f#PN`Nkszb z%GZ{|avfPl0VB>6c09#>@~ord{95ue$KYlw5Afdle0SN;TR4sX2I7fzbXxgZNCBk6F0%YSQ>g9aX_V#ObM>qUew#G z_4_(1DaJNwOMZ;T^*layK`J%?FxCRR&na+XcUx4S5?>Hi-rpiSdA(?5EU5|9lXSC| z9G5YVP8nnugLU{Z&N9Exi>s9k&YI;IiGyfUF<|F6TmFSS3w=YoQrJKtMo=zsqfKK9| zf13G>g++MA;cI&N!?Mj)*G+k=dp$8ZAlQD|3`sekXo0w>{Y{_M%A+*RIOrHWdllT( zY>3mEtKOjQDv(6;Uhrjl>8{MGF#7to-wB<6Q(?Hqf}u%s9ljs={X6@QM{B={+x)Z& zNQ@rfPX58cOlW>Icrw&EWpEbwxrnzz>%qL}rL@Sp{YV2XDpUrbl@<*3M_AfL6W~?a zv9GEq-&+D*_F!hcZ~$yUU~YM%DVD-fUJ*b^43kelMF*4=CM${BLT&M~VLD-5fSqW3 z@osM(D}gHTI08x88`GXa`!WRCT0q)qkTK#k_pL`gBO@c3ZU~Xqo`974ZY-J)J2&1M zo+CCq37b}bV~#~0Jci7NC$1P=7w8!FdZ9icE(%HDVG=zP&A;4@-(n1PYb(B|c;R~3j?sodhe z>o8JFcC#GeHohX(*1!7Lp-D}23aXhsqvL2?46t4w9iLn%N>n;fzceTO6{v=?H>ZK; zrT@)Z3xt9(i}{=LX|A5VM6Hg)Ks@GJ3^~UC^y=-pQlw{hC{~_)Hoo4|x3Q3W8R{+^ zlYOU-POcC1HwoB&<62BsPFA`0O<{b#2{P}-ppbXD{r0}Y&UbY++CMpeIs{A1gR#H7 zy&dusKPYBGSvQAxiXTsZDZgN~2_3Qh>z+AfvuorU55g?Wq7r(Fw2w^AhI9=dt7hn3 zbS8B^>TTV}>M$JY~$;LX}$XL4b;V4xx}VD!b$nX0|)IzW$Sl`{9CnaJXrT9fJZV zYZf(b@41IrEu^0q?6MbbQ0LDJC0jBnlT;MTp6`-N`FFdau@L}?S_2cLu-dr zF4D$SmF%7&ctAw`O+}da(14vbZ;byYJ!s;qS}dWt%cqZ5L`~71Hsze)n636KY&G8O zgEF`uar!{7uEVBr9n+ucob24TT3gxOG7Og1$M>FeAZhZ+2?_{MSn_pUdtNaFa(?3~ z+}qLKH3kt67hN(GeyL!;$UB>mBQjQsN-TGTbuTE4XkE; zb5cjV4@88WEr(xYF}wH6BUvhni>O^0d-vqj(324rt7dkakp@xVjM1SZ9rNERU=v#e=xxjCgCGn)ADtNiWLn$``da=e6}W ztQZDM2u(82et_ZVEbd{i#kt@8kv(ol9b$=#$Uf5#(MqtXXSkE78C9stNH8=zabVy& z4Vqa`;n};pbv4hSSW)>QVJ|XAaxz?iF5xK%m02C_tFIlXRg}XWVZvEWZtiH|mGxbz zpU)H;4cY|mnU>niNc{*ve>L<-YVhBe&GS5&b#PsT<|e!9&QgIP^Ma?N zUM~3@Qy@XmNn{)nH2cOhZtMr`ngpYB!;)zf>qBR<8&@0i)e4GyiEqsJ+kHF7WT9F9 z5OW@dKAQga_VyJg(;L$+haYqei{uU_yQul53(GUjxTJ>-vnRPu3sM_V@Jy~Ut_Tk4 zJ9*Y=7qC7t5cKtgC~gG@%Jo9wlr=#*KN4(l@neqbcpWn4X~#|KP#lUAh4j(0J|i{q zWfU)AA6Sd%xps2iqkisd8N7^PLA&_sTF@CWHMahz7tNDhi%W+M{Jzb+z-nqed?FT8GHF5)1W>_ zF7!e~LP_ncU)IzelhnKq4|&?i?7xJHXyzT8(rI18am8MOeC!^wF?VJSoh278vf^Dp znQg$IQr7Kyv)30}qunJu=;MlR%0d10;x*{}dZf_gHEETM_o+idFCe;A2v{n71KgE+ zad^(f@KzUSj|fw6_WAQRH z(e2Ytb~>oa_o-KVtUUQ>Jf7w4XkQOdo;x)&iWFI=TI+1o=mgxw_nS@vw!#(j5=a9v zQ`(y=%3=;T&la%E>s?fg5{oL=p@`~QmVRIMbXDx=b!Q=X14@0LVF_5k5@5#ea3`PMu4nxiu@R>% z9Nb$-3R}qlRZTN%$~Ehuywxjp2t*FyFc+rn+44Z4bpar90-Cnin;q=s^JA?6$ z3a?bNWc4Ybfs(g-7-f~mWIrrG0PDH(yzljpm2Uy04NYm<#kyRB`97Hb0#y>N;#zs- zq1vjdjB$J%k!nbHYSZ&CbbZbvqDtA<1eKe+F8e_Hl zxI(#(ePoW7w%xKzdTYB~l&}AMQCh3ZiK7ARuG9IkI!7AEWIik<=U>kgPAS-WEqtLI zeqtYf9&`l=a8{*7wz4E)kggLy`63N!W#TA}5%L+};y_=o*Qr%)suI8} zTx!M}B2$v$c*&+Lz#rpuPj_g}goXhk(KYU9`J7|-!JswBBSEn|yIspG*cSVe2Sob~a0xy%= z>oJ?j>bZ4Sp1Geb#mew(3#*v{aR7Jg;P7zQ>=Bh`HL;`DuPSO~rcJuw_DZqbdecd9&?Tv)EZ!I$7tHY+$WxLT&9-6KfN@Woj>Y5j^I z4+r`!Sh7i-pZRr(T#lCZo^en$`lBm!2kqa~HI!S5M!qg1of4qRt){q43bjUBeA#McQ~ylk zLUt_x;8mdb9t7%^KQuimfcH^D*aSj>3Xru@DL3Yhc^f!YPGxlp4F)PC_XG-m;1nJ| z@2>D_-jkGxUht+s996;Z4(_c-QGdMLs ztW}XOuMR2rl)}O^R2@8xj`={gi%f8Rpp$3*^x^a<=1ZQf@w@lw&lf*&OQ;kA`RKp} zN%KrK(R|bcL$&~lUlMbyTAA@_-7tv?zy!fVhz zpT3tZXN9tU_7X?mVs@u|*>#Q~wxhvU9zJ`)AHXi0w4stJ&%)-rN7oCJxNiXQ+(w8F ze+QpOX|AS(G(gpZ94^FyQ{>wPaC^_|`p|v?A`nmB+<5leT$rGoK=0RXe8K$qxUU)L z2?7Dh^CR);}zPLIePw&dx+2O&#N_aH7pzi&Yzm5kKd7GHoJxH-#cI4!DtAV8)QnnsX8p6> zN;vD}s@kkht-{iw6u6=#`(kSK^_&kRz1l22Rpc&_*KwrYl%#Dc9G}2{_#J_D=ORYF z6Qg?2@H*zO3g6`Ea)LWFtT(VlR=KP-?G9dV^5$OLggE13sDu$96*@LMJByq{B#o*} z>SL|=eWY4sbA5$ZB$77|sFoqptw}KK>DEQvLYsaHn5-vAewHR6#?X)5+%zl?;gla{R`Y~jl} zrmELnfQ*0&i?6JPZfygV0ku3;9iICHD5rt~X2*kv&@AH^Z)JK*#3BWi@<$wVB1*2~ zbSf%cj?jl51lGE&er9~CUFvu&kKDaIG=8_RN9R^nA|1c6Z>&5Egz>s}*KV|z`OmHS z(VjayRIzm~&^{`^b#ebBd3mFdfC)$M;{0d(n(^gKcfroexoP|N5}a`=ZkXQ7g3EiU zAb?T3Xed{=Y@m9TZQna}f*%r`j343shktLq8C>j6Q4K8FJdfBI| zy%g2^a;l0l*Eqann%DiZ2iIF zf&xJS!@2zNR8kX$w*I#c+R8gUxQJDD3a-Cq;1EtLe?9~cfV&nhQ-P~L0df)xQ0aT8 zW(mMlKhgp9E5&oYxnwnQi|*rK`Izr^Z{sVB6N-Hiwpuy13@4{F7@LbnSwan=-zz-= zeBZqD(0pS;e&D7bU(v><=pK1*smb(QXbck08ZwF8_IA)loT2t_AgUSh8d-4(FG_nk znHcFbQ>pJB3)|qn4B$ynBA%u6{X+A2(Yr^`x2!SSFS*jLkEeH-o#)G}!^T-ZLEZ{@ zyBG=5I1Ti6U9e6&q2=yAN7Ar4RS1~u(EVta{7oqM9>cWti%=J^Iy7J0iLqvZ26siY z75A?7##*B?T$Wmgy{ySmHrYxP4MDD;^EJozoKLzoC-SUuY;WqZNayu23PRpiMXan- zRPFFd$e+`CE$e05gpHG#P|CE5){~SVt(GrPKIlO{yWpFxbEh|&P!6D^2bzz%rj2kN z&Z#KR@lF=Z)>uzB%Zr4{V~@WqSL(Ng({m!{qv)SsxBC*Vj^?SFm!Uu2b|JQdJQCUK z)8Z2Lquwl7Q+BT1-M#Xn37G|hhstTJV#MO9i4ah3OVefp(3HnL4zay);@g&CI#K8x zaIZrPNJ4caUVXcx=37RVK2v7d*HXKbYy&eRMBdetwJ)mFnGh$tm_)i*&jF-rI5dr< z7x1Ex|R_4_QtliHRAIx9a`Q{D}&tgEf6SP1F&`>2PI4huEP~(UP z74j394Oo@+jNtCvcstu`=Jv&oJ1m}y`TJO_h2h{KKI!L^1_PbPSsRP9S2mst?;cxy z2|W#t$)vH}BA^SQ5){jv99otq$Ul{!moogpE)pS)Ux(~#CRSrSizbuKAfSmND(8#- zMt8oUW97%>@ed9sU&=vmdMtCycX%bMYQ_V@xJMTk+a3QoAp$yLwDX=7>%zG$mASN(=R1}d-i;9+?kLOu^!lrF@TeMziQDZf!_;O=v z5f|!608Xz76TWnmyc^Q6rCU#AFnkKd&;2|m=rH#p?^d*SS3FiBq%T_1ZSA!OlrJ!X zVM;OSXj8pR!TCd^=nE0L`2gB@P1hqw^qipZpSBOWVn&$XWG>ruHP!CSdVfl9`?czm zSZS{2g=X~=rf~>jtgp6kn7mS);|MA){b#uA0x^rL;W?1FRl#8$rZ9Y)Em2S~g8p?A&U|zV@>fG`z5BE;IPy zrKN!*lz}Svi7cPKms*gTG)hhuGO|@?~04)_Mlb<_zp>T@>c43(wOXI8q(d!#sISieef=GMEKRhM5@feVdEC!M}kza!S`{tJ(TJHTokq zKtS7xGk0!%8xYybGvI%tv=?=0Cc$*P_BgPv$14pB%<2O~8&S{O4daP7Rd88nj_WJw zmb4R=$slUWfCjA+RRUmCuwg1HV{Iv)PXzhPBZQ}oNd4c-S6Av2dsP9g< z)J$0HcKK6dd{pR=19hfbdvUH-E;*-|$_J}a1C?C9?H(L8-qcFxg#c0It$Vpl2Ulti zENr8!=x7>-M-P<8tQ|j1SUyAQd|j@XZ@@=3aX z=|?xxjT)NL1LdmEJ?}_!se7}VF>VjtZA8)ck z5FU(PZ#V}Xd*7>=eOf(HlId>UA$r?(P@aK78u%g=-BR&KayKkO(SzQ+FJP0K}ehV5Qr>2>s zcm9Wa!sz1*LQ_5F2fwEdjuHMheqR6K-7ZO8g?r7oT8h2=*EX)4g$3QYQhWk}K`=Qw z;0%$k@CsPL=?a3c2KzknzlJ=S)IyF3#ltFB@V4`ZwE=Rj$AHj@4-m*N0Y<6^r4wx> zf?UB}=0PkU6{0+3X&>e>3xudu$u}H+4DyU89C}r}dh$|FbLPv)wLKQp%ahmFCd^&O z4PyvD2oOn*##T$USOT*RBqwK>)pL?TtE^-G`i?V9@FoX9I}+tk87b!<^#YIA#HjzI(B6LLd0y3kn{BDGh=! zqSfaV3NjpEA3vb(DT-M}oZ|m=O1Ew20AKx5=PO;{FMfzmDu-Cv4DHE@y z<*K@7whbgelInR2@C?p~7Em@gfH*-KaIryf*?NLzF?=jC>3~Ex%n5pKfxyWnSJ#KR z%r?Z6dcm6dAD*-HAwy|>G99W#fT6rom?HOf)}J(B_H;!y!8Yc0Tj_K*o3I-^tR~Ih$ z95EWptqT=<;0h*-#tAOKBQD!D^Q|*mdIP$QAso3qHeoX1yp61VP&O{FPr9<@$GqBw zYjV+;BZtp&=%Z)>KpQW*?S~_1TYGPnQz4a94X+SX! zwHPvv*L-2xkr9KHTG@*fdzojGQ#SfF`t{D-uqe zd`ih}EFmiDZhdI>*kE|#HnNFJZh$p>rC5Uv8lZ`myCucp(0q%twz1N@;yASEazFk2 zk(I$^+L-It@a8!84v0K>-T(Pye|XjWZSPDs%M zRa#qgoWU%1;B>v9=mtKL&e6q*uHe8@HLOyY))xHrYeP1jfc02l;F;Sj>7C8}O>hd~ zMscj>k4-`0T2@8=xK#Wt^qFOt32UHv;+3>3ZHP8i?w(%J&{GrLg|8hPU}rtr^ClNh z>KibXxJ=q)zzK}>N!U3!#4owOrON>tM*8W7ytlv-BYVtZpOCzeC7Tch=ml@Qz#yUA z^COX^?dNW-YOrarm1!O;9nRBg`rW`EMY-lOI24s0#Rj{@4;OY6tmgzG0qr`ODC zm6wjqmapB@CKac$EWBBGz}oq4)E5Uy-|>5!oA&ckPi+c_Uu_h>wVt?VGt+f-!{7Yr zK5hr0Nk}AY_BH)RXp|`2k;b%9zXa22@jWB(aXubYO1xaQhJ$^nHV^0z8`|zAz0lE` z;6SAD3O*rTusp6=t_)y$0NuT*r&c$bjX>1t&qu97+dgU~p+*zkGEfM5;B!rPh+s^k z>5SDxCpT|LZ~LuLp*KLl=rHp9dIVhGPQTJgNu0e$uH}(*f@hYvw*-i)vR%-$A{0>^ zxFtA@DVxr`-}mmw<&nlS>+i*(4HFaL z^Hh${fO5Nau?3;GnzvU&Za&$436@B73qfr4xcs`!l=j z0?yN@sPm-shQ)G0@Xfb&<#D-L74Qn|V?^>(H1aNkM*uAWIcp%K zd=+=`NWWg4qB}f9A9?gb+qM?~9R64O+l%)w-?&}%*M0xj*Yrne)Q$hOuek33e2aw` z8K4)DU_8S_r%B4?w-~4($3AQYa2U7+DrP_|?5B6szN2B?tf+xnkkBVizS`#Z9)}2F z%nI*-^-%LNy|i`o7mV5VP2WpJ7KJP1t)AS`Z4-ib7t;Y$W*h|)NC2Go_o93pzUG80 zKJ!@yRU_vEU_WMnKgjq2=!jpu4Uzi^jj-%@RCv2&``@pq3=hV*w&*rS_m~$gf2d1! z4?$tb`D@m7++xJ?jd9P&hg?&h!(u=pb8@a8W=qAvoimnLqY(WBG(bv_e;H6SnGC~7 zAk<$B8_Uuzbiqz76&9g!dU$_JGRtB4NWqR|mBZav>1K&F z~z!VK!seyk_3*}#7k?vA)t|jeL+!xLzy?{@HOBLeLhIz$79BU z|8Ii!_QUAK+k5CV=ERj3G|(&|C1gZ1L9NEyWC6)J20TB%06BhUV*{8au2bg>;A@O% zAsST!cj$f8geIw3DM5}361CTS+`!j1>Mh7aBcba+AEl%07XeeA5JzzX2}TkP5b^P8 zq$@Nhzs6ge5(!SZ@ogZYB2v495rP!RgsEg4d#u|%v%OL^PrFm4ID+^l{yzM)6eLF| zt@)0aI(4|j{9=j6MhHXE}KB}s(Itx?ce+HFAC;hPYi8s432uHDGNZ%cX7xzi}2 z5-M-=u@<+lClp`aZK(&q;lI%4x7Q3t2Afi1D|y|apm}QHSJ;#C?o0Rde9+J`#uObk zdo2oWEBz*G@it%?gze~sK14Il$a$7UP^o=PY8$I6hFpxt{XJ6tLSPJC$;dqRt{#ox zf}B6y6|~R>GsbSlH}iMV>^AQ#2iDy?oG=$~)a9`KrlDHwQW(gl-HX#*1PNbhM?i)v z22(73GI|e7$2V62K@h$F}bN@X=*Co z;cQP)H@M9i#%;m~l?i9-z1`uva-SuAlMCf2OSVhG%F92SlzKj?3;H9sGw**j(9`ow z?R;4p5At>%(YGi%4Gaua07>ZF%r0s)dnZQ3EQcla_1TrhNj6ArA0w)*+cm0$oY0qG z3#Kgi>IO}Yq@Q_1@Q$(1wq)Sa`_|psfY@kZ*3t z_!=c9Sv0E=+elMcL#7msE(U4n6`53Rc_t1bc5c5|8RNtx!g16{T~em8xM8`u5cGos zyuDqw*WvFO_@DmPj~&iE{hBKr#Qy~(*gE0et@a=1@UsO4pZ-bMaIy*Pjmp1#2#1tg z`yd5(#NJ&$@W7BtR5=nfiB(REDmY!U;>~h@tf~K;v8zRgP{`4d;l6au{P|wttZBFa% z?)D#}p7@1Ce{l>xUTcgEYsb$}F7*t3{G_D8Mw8=4_d@Tu{bGKh)va4y@>M@xyqha- zo#3oY9_UZwpmN%npcneVqQr6!kEuFi)bu{QuDY7##Npwe9}9)@J?sKjd0JM*U&2qn z0@em~f3v4&x_XWF!;2J8YSGsTY|0y(oznltF;G}Rmx={Q9d;V#`{PS4dVvB^QR&0zjuZOCrz zTry4o?MlbGz}dDu1Dv^mA~Jg z2NIW99j^NyH}t0)cPqy(OR1_hE;uUxRqz z|L!f`Jh0T&w=onVNB4cXgwm9F6@;Gle)wNLO~3ju$~Gq&$3Fc99{ZP#!oaZI&MBUmnUQ+wn)Us}-uiM(B6+{HePS`r zj-T)M_&w}35t>4#f0suL1YUWU4bNsks?|06NdUh02^!Qyud4i1 z>y6C~iKp88o}5&r1Cf0Y6sYG>dWo#C`qqYcngEe3wtDRH?|01iCxyyn#yt|ZY`0pk z1>kO0b`TAUN5WcTVBjoBLgflIzKHQrp~h|DVCE0u;DLh&530t~%OTj-EN}228uD}` zOaw|~Z$dYllOZwh(RhM*`6yPX)`NhYEh3(B@zgJi;FkscPZu7_4ClXook{0IDdjK( zCA4e+RB&dDPw1I@3e4p}ZfOTY7BiS&r5hEY zNeD15O$x|EV#=o@MO=$aVe$%n{=w{8SfLfks+j}Ox(!$ZNW z;KN~GWT|ZIhz1!~L#1=}gEqV-qwd$YB-A*FY`%3f!_?s?&@}hh)foxuN2EVX1W(1L zr$`nkqX}1M12}f1A&gRx2{}z0QwaQIuhgNW!In~^RU{CEPDzY=vzq);4oogXib>UJ zWo1$DFUYa_`tcF~1Ei6P@c0=K8AcLt>q7gQ`ubo1RqtVX`+7wNeECkYXf9;mC&X+VQ+8GakC%8Y=&!)i{ofkXrt7@TGqh9-b8ea}QGNPTp@ zP``okCU;wO3&iHI{!S1tYHcjnyPoGN1}6h#wg+pw3c?8$NreDph4#?EI96r!7P>U7 zFw%vHk4L}e5SmVQu8E8IHF%lQ8s#@xfWz0>ra2m|dgL1gus9uz^~peUVpOV zSankH$FE$7F`|6$0C3||VfDIE1y+hA4dP+g9QZ_J;b*q&E zelTbRk54i(+dTYl)GfQm{cVONKa#@QuRRcaB6=kzln%1csaGcusr)q`0 z#PlNS#W^A&-OiPF)EhJ)#)t((F7&!4naXM*OgwKSGuF2Ig!@L`%r^DSH~!^u?adPi zQ0WGH9*$d|#g?H{%7Qv{hJF*^NIa%858xe(>&9$Utyd{<5BIP)E83+fnsDzq!^AYF zthMvLbu-N%ps-A_8$X&*NB!e>cgmYIuW71W#PQAYz$TEsBBq?NKAI3E z(`Ut?%Hp9c5a)at0KCyY093;QUBwLFp)9W(z*9u7wL?xE8y7dX=rt| zCitcfZrC!N5Kn53ZT`1&&u<_0vuexubH1b3&*Pz~#YJl~(%L?f%C@btcMQ6~WOTtA zSFLAm8V>(6tCTn2Kx`s4HQB#^>4Nfy9xw;nQYM0BR3%VB^}urj9ZM+E4kDX3Fp{V; zN{Bev5h+e7x1_32dMww4Nen*I~Qiu2dnJGIXKJiFSj+lpoj^N4(Hs< z`kI%3H^HKCt52uaJs*>CO!MvsA&r#~F>A=EPfo#7M9jM9`?jVa+J5VPG5kCtIz02QH}1ViQZa6N;RJS^Bn=;l zL!9Kp^e2>9EE0nBIp95O1AFX2}IeNmj!YWjaPd_)<@-M>RmS!0Jdf_ zFPOfs%KaKJSDTAB?f5i%Y~a8|-T?NH8t4K6Gy}#cp=SMF3Jx(~Cb9w>d@tM37_Vxi zs;X*gX9Ds6o4fd#VI#jB0Gvf)x?q4Di8C8-?<0#ko!^?R##!Uy01Mo%T04t5?8 zPNdR-H?TV2S@3K(#128i3XsNoDsc^272AL4zQyqi zF!m3%Cj)&0=vG5H^rY~zwv6!ph0=kn6p#6hmyzaYsfGRAPWEqQl`-@dI zm5HqMdhE_nEjlmu7nQw`md=Ld6zKY@V@F}JVvTNC*t&HtJvB%w4Rf?_3z!yVbT z%hjcMUqUYVF{Ll%x&T?0Z9vNZTBfUS@3>@l1O9yyg+hht*UefEqYOr!S&4#hidlfK z!kdC!Q^E*?9<~N-G{TwH$pAtNqY?0tfy8tic`_6>nb~OxwUId))IMc^x*=CS3ZNy( ze$9MLT3*nuD4uG}LBUV~^rU{!6HwSkEqvrulHCMF_ObB)kOjbrQo@8?e4cY9meXpd z`)3?Rc)Q3HB;p2yKYdqdw#>jG-8Bl|Vc8O7INp+Yy>9&r^`;-}TRD{FRDmCeZdEGy zJ6Y+eZ=uvk|ExM_1Dq)&?&Aa9KggHl*jbjxq_Qao4o`aJ#?KtzH0>==HOn7mMEt6O zhn#hO&|a+s&$zGMkkI89s-;F8%4!DR2vR506dET`P2fa4>PD{MGBg%uW~q29&?n3o zQE^@Rv^&5avR1&`gDP%sN}>VxVnW;>mu!nyBPx@eTP9$XaS-I08%ze3cAbwh?`+qU z|0;I45h396Q*7XURy~8w{6ksuhsHyI8+IbU({w4vanY=i+61{~XOA!OLhGurUy*Rf z2B`7AX5>@em}*N>W<#SBWp7SE#27?!X8B-nM}@SB5xLtn@9!Ax%udn(Gk*Ph-B2M_ z0t0knEGq@nu5xH593L!`iMgo=$ounCF1aewYvL)BN*kY0>u7sT6(2AodXPv7}3mhQ^Y!{wCT_b zmIPNbuahy6`Bmwu{ck`L%m>OwpptbZkEtUc{Ax9(FfJpy04Dh}B1&qPe5W0@CVk|C z%KQ8rlUOWLL|F95Z@4-$tVwbgQBEqKp2+lZNfwtmz9@ax^d6v}tdX)1* zs4A^;HOyJ#ivOJNmDaVOV@xB(2&0&|Ycf2O0oStFR*7Ue86u8wQdQv8GY*p9szW zZ@sj}@&iDUtp@;UypN=T6Gti!1F>H3y$1>8`V>Y010#yoWhh)Or@o!~o@7>>#L@~j z06s9~FS&~jN&hBR`tfBRqS@iTJW0L!0tC)jngsvsT_o=BpEP)>n@A2t&C~<17FlN} zn#0EW-HI!CqlpNIcn>M>L{{?vq|x}&gWG5-ha@0Ep1`fAVm1L5-ERv7giL&PdlRIWFGeDZ0OvrdS$9r{{|elB2s@k3P=R)a1~KtkS>Jf z=_Z1+Brxe~A5FezNqpOU%VlVAa5=7cZi`s_{S~=iW-1wi@xtcjn&KEfLXyw0tJ;Ai)|5c0^Tis`0oY#obM<6AGRTwL$xCqJAdH5bJ^Lz}; zf7>2gYc5dOJ-mrW_xu*=`;QaCj_DQbWmWK4bplP2#nRL@qlRdA)XHBPBApzH=E`Y# zb?qDs90^8sd=u!ynY{4+zotrh9!4 zR1Dmm{`V6o1zc;F$*bQf*z}_PAd1i@YeBheXC2@0kx@{uLYFzD)t(%N+jQlc%b%5I zP%nc7QWr@A0Tc3{*pqUse3~@?|*g~9W_;+M!#)!selp?5a>eq)UPOBt~J+%r$_RxcqGPK z%r!g*(5_36r;t|G)ja{@#7Y4Bbzwpe;?o5bq5(KyvQP<(yW>SrCk5C-!8TNoiqriA zC=%0RxdsSDjC&b4>8Akfrw!ohKyqf?{u>vRiTCw!?N|mBkEar3YCOI`x3THZ2r7o8 z`*OCi;`r%-Mp=<_C#L#KCTFjbj2Kr?yDU9JQDf*SGMsu*sGaln?b&9LKRC{@CWzzQ zt_j?$H~=IT_zJ%P*UH3a-c}FMv0OKtGX3X);mHJ?*#O`Tb}hfN?arTCC1$N;|DR_z z<|Qs&Uy!V|cgyeZU-wlBLY|V8)6N__!l5hCeGDj-ad<7Qx7Bmaf(Te&V?dcncDWu= zT4DVWNrrLgd2PAgfCbduSRTU$jF$Z%8L1eB1>Mablx7>d48FFj4KN8p(YQU8%EAS> zJu~pb4`NS&9p$%7>$5whxexI=SvJ>C@fYwetO~v;1=4ez>*fX+j>i!DLxlICFnf$mZm-}ml5{oJLL$Z4dpg@ zl4aJ@$$EX_we_dP()|N}F+==qft5(ZA}wr*|E;N8VTYyJ*xU(r^w%cx9S|*8mN+d{ zq7$rn0K@cEU0wjH6Yc!y%VNr}FVx{B4FbQ3lrVbBUG!yMr!VCG_mb^i+FO(L;**__ z0PSY&iGsYmJpI9D03F+K9vEw?rOJeIJnb=sfi|a0%N(LvVvUIrUZV$BIeKA1U zM0{;KbJrifsQ7{-Qg>&+1^`9-(5_lMWTBOaMm6-V7r^Mfq`CspEC^>7A1lH5p<73lcbi~0jwD7H`i#4sZ z0E*0XU+e7N2S*($j%T)sL!dE-9XANGv|cqw*z6xoP;l0YU%qwJs_Z&pY}*YW z|HojpgKT zfV(N%;pe}t01QntE@Vym_w8VUhcp--?Wg>P==G(d1!|$Ydf>0xQWrrr5QyBBthhBb zr`zy9x9-iqJPMvCvb}Jix5En50P8do(E^85uQ97OJ<# zON4503LO}5M$h{?ANbN1pme6UTw>5_2f*p-?rCEKbmTz(&9m+R_jhh3*n^;$h&J&5 zfy?da`;*A*=UKGB11V_$q<~AAm=N^@&S1FSpD5CrY@l`7zb<8Q=KI!wnJ3ys1x7<4 zg~8*o1%dTJ^>QdbWh2+toRDO>qdmyNy15+4l^tKlH{%e{4s%A&l(&hX1B@l#494#u ze-))-#B2=EgXOQ(cK0ahgu&TIOe!CJXRqR_K;YEM$UG}t(iVu7$6v@|fS=WSB{00A}I8P*_5x%=bp1@LLKFKLCf2nySAyek1hFx)AN7xl; z>z>5Y#+?DqXu^;Q<~hmYNaH)F6qBsk#wO{a7dj0#~)%H=q(aV4M@UNP+eYUxLNu0!ocNh;|vk~y~>QUsx-%!F-R#?OWI z3}#kwlmp|I-4~g~)iY%TNQjUc@lfck^AfdH)wfkumVRk5ksF?dLc6rm=#4g@NFGJ% zUp5eQ0c=;B)0T8_zhb8Y{zyiC=EkuyZcD_UwZmCiiwo<&wp@^X9#zMYXz^*?#lRd8 z6PipMC$b8Y#<9bFfcq6$8;SrEM+{0)ed_Z3b9@HOzf+dk+P!yiLbIqQFCg~&!}X)X zV)0W>+5|yP8~`n;>ikgfdYv-C9YrXo{=Ft0f;Fah-~B;)9mZ2QKy=dR)(TKx$PqAE zAk~cEQVr{JVN6;V8=L+jsDjnrHdbBwrJ2h_Z?NA==L{tWA)4GP+ypgHb>U*K33Y-F6C0a6w40b9yZ1_3K_ZcX zNvK?9o^mnABxmQRk)5V^Ok0POyS~@#ymAQPQ3EJ%<6ujcs!EymO)PcSy#s*G>_a|` z1@K^>1Vws0MvG0*(!!#~I4|EgwRx;gY12Eu4pu%1`*}@IWuC%aw|Cn2bklne{bt`icMCQYy%4Q8Wp!g*g((YQbokh<~XK<9T3Zgu1psVD{rmxC4yT^Yrk^U9m{|PdnU=?zaC!;fC`bvoPmh zF8t>$Z2!uA4pn&0!#XlePD0V&c0_Hxb#G-(+kRHpCxtLLTd z`9g^ATul0t@2uS|0*dpOPT(S8bA}M3m1X#t?JMH&mrsi9$L2JU12oD)?VWGLX$)9q6~A^2hy!W>~a zvhJI21%%7;(Y@W47dU6Dn(@_O2t|FZaTRc*PnQlm0I1tx*pt~zM8!|);w#i8w0y zh&pTa1_p4F@+Ps^qGTm~k#a35?1`r}h?9by06+${7KD z_bDclvy`Izf1VZIK&*D~=ZZ7E-AO8PUjq;cJPRppy-K7S{}nM${!s|O*aLE|1s!x z!lG1W-i#(FrtP9s58EYWLUZe7j#bERLLDk_m_ZH13}~m5?u7wK!%}i`KCq=rUA+qk zu_bLtEgTxV75xtACRL^h3;PS95^V%U)aSDJ1S3LT`7=1yo}HTybi3rY1?YdjBr#dQ zXnNGP5tIGvnk5!RlWr=2Umg+sr2VC$v<-0iv&LU)73SkTlo2>5!J^+ON7&!e>tfxY zb+=w%vcONxKTL&f~RX@NsI8XM2f(RZS+xY*E-@!U-;!8=_)t)73c zx&Jt=Pved}=8=)D`V$Sc!n1@i%#;pfR3sDZ+0gmtOMFg8=4Bw>*=5S|zZWMhLG0dv z2&mVLR$*?)Oa|d{DjVBjafYoYImlQtES1-&0897o$&%%hx);5?V@s|*pkiDpC-%WS za|DY4b=Le5y3BM`C>cCw{tlD5d*Dq8(C7%9OwIdR%Imrv9{EYz~{kt$1o?+t^knN(Bgo^2i|uIaaYy(A1RfLTOU@XZp`Dl z4et*w_-}%idne%zUnpPcq_A48K=9ju6nt|Od~+T@>v3{-FZzpLhdp)rioC3nGg9{4 zrM>9?5{;S&Ekom%v(*f%XEe192@_~gTy?*Fpx-i%#+Kj_%mdhg9bS(e{rFd;(1QS; zL#Ke>I{CypdDi^*FF(O5+9fHBRzL$zj722Tn9|oS@|Jr59=*Es;~^Ygq*s7E%Lh}1 z>4mC0gagpyFgaD#w1CN#471a?Tl?TZ){ZC^+(Jh~AfoBg!0Xw0QfZ6I`F-(3OW-U~ z5l>K6Zg?+j5Ol6MO)fgMlamEUPta4tnz(3)eTlDrw>8Vc1i{!@xSWs2f86*ZM}KB; z+`AAh#m|!dm$@Zm;#VOh15HzBNbMLDAWRbxqvEv!k{!OobyBxaX zry-1>P9<`@0y0wj-BU{-eAfNeotFVwi8NSecMpPH%wx#FLzltM5x4`gx{$zd558t$ z2(<$`nJyp%?9x0Px}=SLuNM^S*a^->;;p=4AJ9LbcPmtbNOIBE?$X)xOMC9pOqK4Y zu7JtgvXTfdf-psYihIN!`4mcysL&Mo1JWpuwDeKoRvXAoXL)v58cJ_H=ue#)G!fz- z8Gh)}OMh5OT6z$aBwXIMa3RUUoEuADh!7-d7z!PWCm_yYN;+e-f^a0%RaicvxCuFS zwU*-q0~B;JPnn_!Ru(2$z{cnm#EfQ*#TtX2Ew^o&i-Lej9;`3YmHz#WSdgn^8wUXc zExv}J{u(zI`TPwKduBlV3t?mhmrNL4aD$cWLF>KmPiXF9?x`@d{KPAXml;yDywRv=1nRCqfn(-U>^aj(RJV@9n`#0!8Kj+B`i z23&5rz)8m&J@X8Jsv*%Dl&~@0IhNIi4MbO+r%zujIV_WTOo_VSeVM?hUwepI>c^P7MUe zKRx{X8L(;l=SG|L01u8KcOh`LgHgURqyknWG{^($ypYidu1#$MPlN*DU^eyTY)`#k zgQFY99?y{NA*DwgmUO3O+Cq~6*h5o*aqeDfVGXrhvxqFCd>KbJ4dD8WHeTHM2}Ks1~)?ge0sl+Xpvwd0 zxnph<_2)4=ZLJNvU#C-ypIhpjHB&toKimV|drX^T;au$<=+<(_Wlqd#~f5J#Vbbwpe~Chb~pscJ6gWD z%rKo0Rn#QIW;ga4f^K~I?*Ak1y8~+O+qkub6s0IFQdWcZ9%i%%X&ddStt}xGA~a50 z15Hhh)1tjQ?b9IbI;C++ z4rN#e8?LF0F^XRh_hIpNb7A*f&~{+_ zoLAA!?J{BeAWm7g1r8WE{6Zp67Md?hbpZm{jbR#h)CdNC!NvLEoW7u~fv z*LUtZ(7JG8_a8+M!=-2#x!FT9`{RYw+t7FTQ%i$RPi+Beh2#FM{jVXW{XK18+a^J} zfwq1tsEAENT{Tkz3Dc+fb-kZ?LUR|ZSi&ljSlmwxI|Zb*petA)OX|l>N?{-$K z_>=FX-w$WuX9~wQ!`FAZ&vk@7^AJj-gdEmSdbt>(>q zqipNZeg?TX%PKJqak;dJT%RJhl*Z}3d*|~pujOx6Y@56FC`U0Zm;F`=+0>^4IbQ4& z*%s{1o!4n3zusf4%Ua~569Q>+0alq7*A?D4pE(M|An~Z@ZUXHSA%5)6A=7zMF*nr9 zQ11;Mo)OB;jXw2a_`1yb>1q|3Pah-0n>Ov-SX5h-xMpl@6h-_`|5IHacLdRN9B>V` zo^+c$VT7kD6zh^_@KA2P>4a(vY%UwOFU=T3XGASS4kz|?$0|E{T%Z?{_g~mH16+WQ z=29^%nZ$}qohQVIvM`miharA7T%Ps^S4K=>k-hSYLMUKE&Wdd>rh$r^f$3GCE!0ml50U{01deQ!zCG@y!ANa{PKBV zfT%dJGBB?PjzR>vai5L@@ONveSo9ch$yTX;luPW9^L=raDsk==Ov3#)6q4{1W6E)~hUxx78AqI|VZ7zu*=0RplXuvYuiG7$>}d zHr8Km_w`^r(b|ih20NADicZ!r4ks*@RUB-ZpWryHs0^0J$0VaSsZt zkcV{w#@E(zxO$i|B9fUVrm6f~p#b4Q-N2K82~PcEdNd>p$Esjm+bI;iN*f*lP3YXStgA}n9?r<2)# zc>$Q+cl)O9&eT+Lj_?6d4}@grEjCT=IJ5V8)0;Gdo;G`8*$^-Qj{sgJ!lD}muJ8&3 z!6TYY%OcV9z{WdXp5$ZWZ}1u5khgG>fqTIdf5T_u#@W@ju7S%a?Q?M-5u#!PlH4Kz zuReAeNZ~Rj2BvpggEh{E(RK@`^!>>4>2`CtY0yz*Ops#Q zfllr&wri8Kjumi+6asOshs%IONG;~i9>Ielf9w3-cg4-1V$VE|vFov`4COMQTO%~Z z___)Q6wUA^_d9eMcpq}07`U?8P4=We?X0v+GKnE~Pu)HSZ8EyfHpNC|*1`83r6Pe^ zzG}8m$OYscnVd^Cq?iv+q?a%gngUHiX!_%#a#b3(x0ddjx$H8dPC~NY-9s}zg^Fnf zT@TE>unX_lm69P#P0t_KXGWAtkqh`rNNLZxoTg}TYZhq7nEB-#{{E+#l2KzzxTzHi zdYLB5{&Carg?lRy4H!>yP4f8yB80fnPhzmsl2O@6TUwS6U(R7P=uWi{_b5-() zUeWJ_{?Ma;-VnnoGYyM{k=AF0m2wnsNH#~ z+|e&NQ`{SVE#u5)8s*(2Snyq|v3|pNX;)@lg9jM; zO-VJJXo!Dv`bma=-PN>U3B{6Q=8C2n*tLQADvSmZYIoc2>G|)wGmnlE14ES7LX}5c zZs)9&rWv$kupC^NGv&68GC1$Zu_nGQA93w`rZCVBrz34wQyK3&^~u5-R+Uv#u&$tK zhD*qDmctujf?OjSIC`v`EaQN(ertp{SLW(~sUDf+Z(3|2&qvV zLwWSaBRIaE2g;-MYw!`SQthBk#!f?Y+vHJ{kc0+ z5$K0K%n~eqy&adOSWJ88t#}_}i>$0>L&Y(q=*sl%%lV&wl;*uV3jSx0)J--5EC10X z9CRTg^(Oh|CRYA9ElGCjIM|aR-~BOd`=ped7a%|hX+y$sJMyG~%t31d?_kSkdCTpb zp86kMnmC++X=3|gl1Mf^`@`H57g&_vBRxvoIXy9ntvw#mu&{idm)J$9?;r*XEuP@T zSLbhLdVhy8{g4{hJM%uM39V2LP63bv7dpd|NkevhPUKI@T|btJD7(iI*#JKuD)Lly z?~RbKi`A}oefT+mP-yt9uuIP+)4Dk~&>H%6=PTiU8Y;HgVL~806W8YhtEn4(drkW< zs^+)2B`ESNB2WIkYW1{$Vd7aey0#3fW5<4!=jaNgfj`+a!6{AT7jz6H2tM8oV zObiacHwb9ahSEk&9eb?SN+BJ`80dNm<8mEJWo%}Q3QbDmm}*&T8jAywJZXD_X2DeF zm|dC5gso8GB89_D2M^_HV&}xxsuzn^U6VA4e*2m+N0E(9-b@n9&|;SoxE7Men}BLUnvUY5BVmj8quM zUEG3S!XP~xH6rp>y{l78oU+L) z*bpt#VfR8_(3lq*wfsW^5(iMK;^$tVt&<_T8RK;!!I(9o{ z@$F>~*DCAc5zfIL>x}fmZbjtgam3;gmrNRqCXSVxNu!yFT17y1@MU%@4cof1ZKklR zw@KDm6Rj3}7hX0)xx7cxKCTc9wT9KjPukibG$X5$VP!qGM=bF1?^7184Dw}NS(Z-& z<^HN4pesJBQ|LT+-8X-Jv2d-SxsL_fCQO{`Y<9`o)Z*5GHnCCP3aQSLE5bp8oV}@f z+o4jZj z!X+i?_@>-t|gUDHBrasMPq8dN#EQtxm{)7vy6{zjA9RN2f|S8b@_3>q9SK*uO_~`8~$l8jG8@-ueIKOd5a_uDVX7qs)O$z~y@xu?oJ@q>{+$Xua zbyePT2lY`|-AO0(w(F)QbVc4N9P2_`m3l1lRvGPa@HDpy3%t^IBTbP19{JTn=rHbv zFm!GNxFJG*tgP8+k_nOA3x?7|2+D&tGI3MR3*O&*BLya^NnanY;zTERE4TNNPNW>& z{+c%@-be2zS$lw;(TcI)VitfT7_m;8=ik_j(uBeFf4|p-vQ-m|_3J?9D@waN3|G5% zu5ZfL=Nlz5VB~RjAuHUtd~Hr2CB_gy1jdFg4TsN;j zug`03j6!fh&!}UO&C;D%@7Vpk54MSFT45j2YLA!Gm|L}+*1TK37xly}#4Nh|tGMf= zWm>8)TEL8H5i!h-pr;82xaCMpfRGI1mIE7_b*>hGxn6&ol19Z78(~O8_A-KEQtuQc z#DQ_nlnmo9yoy1V43E2Oz)%Ri+D@^Oh0~UT4|$UVua`kEin0Asy^liNBaqQKX|P%K z>TV%!Gfy|gWgr^_o$_aY$2gXC8`qeC6SIyA{tfB?ak2RIc6~RNQrIg zqUNa-Z%V)u2ZBc|<{)jfB~BVXSJ zM{pCEFQ7lvdKSGYV`iu>7+7|dV|6C zvGfPgM8d~!PZMZCoXWyhw>M4|Q2F@k1eTWs%dXWL+Bb454_-sW`SRr*LCmK;k5MuI zP?1~o4OWT(KGx}=ETih3i*0xNoI?I&U$pEnYflczu9%5jFRc)<|xwFLekO5Psh3)Div2#X>cVN8Fc24t&Q zfZFihlD%$R2s#Uuku7e062l=kYmT;4k2Zvf)+Sq0xMrU*U40Y@zg>va~pZbfkiTm~mXjG@<_6tghB>J`;?Y}Zm)ZLFWT|3+_I4#q8FS;K80=8iCTCN!(vCgY_?2&_Xn3AT}>g9 z)a2l8&UdxKh@n7Mag^?2{fIcUIe_J=HoJX86pll-l=m(~^*b|J=*TVjay0Hg^OR}Y zQZ>7h2meMH*gzMH-sfl#%vgT!|Ct`#p}seEq(JoGI~Z0Tv(0MG^#%q|wTMX9k!E6U z&2;g)0PE_z;yn;udbCkyE}+^0uIM=SO?tao*>vqb?>KW7nP%Um-tSJ4IPVfBH~Bv8 z@Z#3H-B-^|C1&KU-SDlM7oA{jiuawWy;RzvnC2H!MzPBHio|dYS9Mq6G&!r@I?xp{ zGEhFI+xDH1hdm`qU0#h|;_#fm5acoR zN-K<`yOW&z!VZ-LC6BLqD$5ZMEv%e>xx#Q1AXaFfPjz>k1$W ztKp;ZrtT>nFc(;fT3@XsZR@%DO!mgCu>*_^@+aZ|DHzT?Tgkp#^{6zoQ zF5b{CK%`OZxXHT(`&CF%{+zt$fhliC(9Of98@5-`Tp%stuj*BL^C#3hPl=F?Iiupf z&8=H8-411BG<&%UCNum;Ez87u9dYwp&N=XVmWTFnwSGljg=xV!On~%c`Uxet>P{u- z@tb*e<4d8B=UP730vwH#uoR?k;-FN)x!+s3g_xefOJO1@hPLVB-$6@$9{4e*D5Qw$ zg3);HfaQ7KJMD=qL(gOvu6Et<=Z^#V=I}Jew&=s~AU zfCK9VNYE5ScdrOQTA+e5Z4vEUgptVt{|MCXqQx`B#oRTMaPR`8?aYVZ8~fR7DYpCV z1K$?g+5#y-a~ALx9+*oody3{2+3R_$kKY=9mzXcB72H zO!OS9(6BfqmLt}fYKfiW73quVDOU39TSlFZ&_%a#YjfGc8;%3cy9qnEgoRcQaC)-6 z!Va5p9`4|9fQ6N<_2q|RTI0AbZr*1z-8NOzra6Dl0?g|P0&NF1(L&OVV_`e2s@BMM zcc4Kx_yR%~ycas=VI7nuH3X;Y+!fP=Y(59iz!PcJ=I-;t8Y%Oc>S-}H*=<**@L5*F zRt=^)m2d~ET>bQUSG2Zpfb!&5XSb5gO(GAEt4lW0Ub8UJ}-#91Qfnu6WUM0 zK@-(BFe$ z#chYadw-LE!E!F_qkGOKx`s+Vdw4p(l|9uoCc$1mWh;S~#|Pb)>K0+Q{NnnayJJPs zmPs54Y4iEXm04@+FcvU0f+F@g2tW(Sdf#C;<1tM3I0GEiBWf}KPTE=K|-XOABY0nt{NMUmhOTj(WeAN%8 zg4RV)4WASf&4bC@p zytUkvwve1WG|u4Ndm0KNdfH`a87M;u#tPB9DNjG+uogR!W;X?Eq6ibWZdd?;ZLi04 zTMB(;S-Kp8T(sYhIkx8-L%NT2{uO$+NX^1?O@L+ziN9j#L0wd1&;gad5BL}&l&{*btJ>wGO!Rh8j31apt~G8 z0#t=~;AqUsy1j+NVD=Cofl=MfDV88jLo_i53Jv$DHV#t4}=Mn#}hXe@QxZap^t z($amG+ADGVTo))k>qL#MPk^kxPITxJ(Kz!cTcg!D|9oM&SL8up2F!o+U*HBtNFKIU z$4vLU`=1xdzFkcmEH8*VpC_rdcX*E_4bF-hX+}}sfLkkd$>Kfj>e1olS?W;ZQ=wBX z1n!gW_$K*3K{75aa-gdU%YNwYyXtURy|t#T-)Q+u%G$2+z6vaXS5>c=w>&p0Ddl1&I*_3 zU}}qV5Q}(X+Q53Mbfa)}MXc7eo=d;^MExr>>-U;g;g%1=LL%#kWE6kB_lHGr@HO}Q zfm`9PR^&euA~$}!0@aSUK>wubx+uoDQHA+D2KJDJFleuhnHxin?QgS);jeY^j1iTo zzx&v8rN!u)D0qi+`P`5f+_kc>t10HBCd~gUfk$M&O=ae{7iEgxR7|nuR-#c8&w?TK z)l*p(Khfd*q}Y~*X#5$(CW41t?zMJwfl%9Kr}^j_T)&1mxEo-QQ1q)fFA61q)znsQ&=`26*aT28ZD{eBxHx1r#AJcqdzo&NOZN z?IfH%STcP_=Eg|$;RVC(8v8Yje!Y{e|8MUE2zJMvfDbJ6|NWf+kb2B13(_V2|GtyM z*O`>|{PvaqzB+$jyVX=E>j3A&|t!0QB{`0}9nQ1duG_kVfKkK`SC4o_g{#6DH1Hj24mS{DNC z+RqofUI*HeU?hq|wgi)K!d_=m-ow2G4YL8o;ERusM=mvEpj~?yueo8P2Os6+sV{Ig zJ_lPJ%rH39o&%l_Gj1N`LqG?sq60^`F<4ytYd35oSEQQHEd#L@FUVZ-MqO~oFaZUs zOh-l=SBz}k_;^2-9Yoc+Y*UR6!?BOrkdmq&-kx5P?D_rPHSdggr z>pa+{`Q^oVf#=6=R)jnOd!BDY&`byTH2KxeuY_-B9fU5XCuFFr;a`|i1s|iAT2iC$ zri7?B0=uvZ8qjGDt(jKjO9gfxJaUpv9!>pc6z8ZcjP9s_cvNBk`SKl|&^GjN7Hq(! zjE4YndFBeLCRMR_5?oe?{_9btz~uuYcEfpfKco$>hJ2WHh#u!zkzlBzHML53bdW%xifCQ%@!&deBWx*Zl2Y4=n;z$?Bnm*Ai-X|P~{6Vwn&+n+Z`UN3K zKn^?yX3Qv8_qgmbheO>llAQd6Id7;F9u z+mqD~^FTP8_I^%}?>>hN-RWTFo#`rz)Q2YB(Z;|e>K894DnhA{py6Qxn%s-gpdB#f zFLsUX7XKvw2(%^fqneChUKiAb!pTFVT!02~sq5+kg*Yma60ikJXn~6TtSt>9!v1zh z|F+gU4@TRXAe#9QY`SBzeq)we^wN_;4zjnu>98f_=xD26Vr?QwyKYI-{Rn)*)I3vnl{YH@9H=MW2uYUEtUvIbEw>;q4EHY~UH1B-=WqlSSrmJTaXuBFUJ^=|(;k zUh*=TGhQYgz~2^1(JJoPAnNqHLc);MK<2#k4Pfe6XL?kIdT?(0gv;Hbyc5cOE)=+W zezDt9a1V%W%fdi@yo)r)c3ie$wWdl-hj)ehEat@-D(XW|WHxhgLF4gq>_rhYaI+x5 zV115giBBa4HtzuUCk$nQ@r9^nfH{@U)>sJY+T{V)l8vs6}falG847M5Z#fYR*|i zmjccZ=gyr+5sJw= z3YESqV~aaH-_}T*Ju6vGf5m=xICDvu^y_QJ+!i9Kz3r#q1Va;DtaSUP4ls{t5a&?Q zs+nK8mJ@07sU^JW2XZkB&30d$iZDqn*4kM)H_Wwy{mBWKB68Q z*W3*;NGi8?o+v2p7+TJn0ct8gP;XL@sAsja!v@M33!#%B^i(+`(Y^3v0`*9fbP5&(a`qys=Z!i7NWgBMtnT9_b^BbLQM#Uh;SI_Duiz~|3znM1wWMbw-;Iwbo?TU`5hC&-Zc9DjoLEKe#ua%dsr?45x zQ@+Q$J~`9!6{LXzPFwh$_B{?tWgNZ>baxXx?od)^t{}Vb!L)CbRblJ&4fN|TF&DtO zG_wzEzUtl7rn5|nKvQE=1i>jGA|us|;;MY%1`g*Vw0b_rjRm}pUuPjU=6zwv>~XzV z4y=(5V2xxO zzmz;G)cHH6d-x%=0kPOOUEa-o-io?W8>))fffvfs5o#BDEKAg$WzuTHRXx`NOb4Dg zn!G4R!-u#X0q^i*;Rn1f)GVpY-glBW1y-M^wJg*rnmK^+DK7eo4a2^7UW~zMtG$~W zt_=|z_Y~(lSf;ww&HJdC9N)uE>!>-gx)!L|3akO|aOp9I391yE3@C{C^MV>}YbhPH?J0rRp(MclI8YX7pl zW|xOx(>|MzU#T^7yrQa&s(1{WrcHBXL%qCdS?Lo9P*o<(e1y4$HPK{JM#8K`bUW}1 zgiJykD3|0$`FR-CZHrVAV8UqP!WQ1JU$~m}pqfC@T@^1**Ey3Hf_TVR6>oEVf0M$29z_zYV*T|~{pm#i~zE1gZb-qx{=mhYGX&(03r6htW*{ z+00fwa|6IV;`q&vYtdn#wyM%&_o73^GfqLZKwtCJ1)kRyn{^DEV3RWw#>Cdz>fQRS zLDlc1MYr))=H4(Ji1inEf%u%NEgZFztB6kHD7~WT%=Z;GbCI^eH)sVAAI zrcco>54hQ90Yj~U@TkLnd+pEGke4kR1ZKQA%JN`_R42wAF)iratMaW>Wa?Z$LyWB< zI?b()nIy}S!62qjMYceXWr`zbQdHV9DQfAIo}(_ zRo1}qmUD-2SI#S$$}Bx;dogJNv&VfM1x}YgS{B!TYw5B8y^p9rEOK?>r}S&tX^!2% zwmjwQf;|CPYhmUw9FT~F=AhHvfn|vIWh72NjWBSnp9igBxvSJk#3>mjauROzyT)n* z|5w&Q@uc7l0!T(OU^IFltF-B6_bAS zZ6g0c+_H$_?n)+pcqz9s2lo`FIhU7Vm=P?+Hxfb&J*0=gnfOdkDB%^y zU=S00O9ua~+ZL%;O|y#lKe^^ddaQ@{CqH^>x3m&IEm~UMPsyS;upaeNv~j6?J*1Q> zIAd-4cCbU?t-{;S{4x?G4I~U|q)r#sqCXT?p3uhaBHga;ATE_*@9wI99q*ujI866+ zk|yn-d+|s?(ItGOg?3Di1K@t~YK`ZH!%~W_NWk4k3jZ-H?D{H6+?IDK0~>`1@-Mqr zG}T4~`b>VP(YzA`WcbPVqMco|4~W*m;>R|YMR;FF&k8wWEaVpxV{IR>fGO_9{@hD7wGViuCg! zA1>7Iy((e*Am?&rfarFWMc)d&a(cxgdbirD&p3==&=@GbK4lr^mbwai@M=?(SC?xA zR!{G@?NgaGF5oOACWIxNF&H^`LxC%pd`zyC1eI|O*o58)i`CCDgx+N!Jg%3+X0h`o z{T!2(hi-&|VNe!$0{%Fa0gj||BC2KNe5GJ|L zbQT{Dc{M|$$OYCmuR&$dlABu+N0qV3$A0H60fw4~JN6raUG|>rXyh}OCQ;?s#Fq>N z6pXnTca;2|pY*ZQq}wQ5R3%bITPMqm8<2kYveTzMfx>W5z=z;Zv1H23qPI%5swru( zagq$(-k`0#`nJJEy7V;ont)d^+3NXy8;NvWjAWj*F-6Ol-Jj|JywR=g+t;XEaF;== zZo#VoxC1tQ!ylmrRR(aR#!5R7q?R9WoRqQ zuw6tg=}WI%!W+Tp#WKxa+i#1$>v9!8nNT+*4SwiP7JCaT!=Y%68oS|wG)6tlam$eY ztrxGn94bR60Pn^LU|Bil)sZ3Fjts!XEbBTKjC27p2yu+4URb%NxoaOrt{t%d&a6X|y7(e7 zdN1YsOYimp?`@qAAy}gmr5sSrX9;wUuSX@N=D**oqw)$c&I?o!&Ttr*4?9WMtvOfU zy=Ar%|5p%&;q@KrT(c1#Xz#7NPf=r`u=1I^ayn?flGFRM;5kW79>c&DNjJtdV4(|J z=Pi#XY33aAx}HF!>Y|@)i?nQ`Qh>7ct7eTk%NDvL@B&b6IR zU4Y}=AGbAKI?7^S^0%W^)BCNp0zIHc_g+_0iLZbuR+WDV#K4)1+vVR-e>)AU(!2rzvjQAKU#QMRHtel#bFZre7-PbOlnhDzrx9M}xUm68s zF7G&K=mV{N6_`wO&Uwdx1;xN(oaRzaVE2D$Od;@-IeqcmJomUGg#|3zN46^<*)xB^ zeDo?8ARC&i195YTb6w;(Y?K3(Dxn;Bk*bA|n@>M<33DW(h9%JM#9H;WiJFZ^sE7|e zYA6+1J)3Zje&VCrWj`0~nA>jn&woWutnxEdERwGzK-yEV$>%WTqPHGVoj{%nC=Hi% zsKYm4xw_AzDYW^ENw>ZsFC2gab)Ru*sg5lofgRM3kX&LGiqmBi|LKp%1HP#o*@8eu zxdOY;Ng7OI@-d%6W7-deN?TEwvDey?=^Vs4p1T>N9|kHe+s<@uru~Ep0~)$+63~fy zj*D_F4EPH=k9^}pyxV4hKJYdWM3iv0@6w>GS^_6)_TqeLZy>zaf*rKAK$#i6_YBJ; zk=={%jE-Sn=7+9@HuaqcM;r6;tlHL6xzOHdMT)s`+k${&c+?lH zY>FyxSk2y(AjK4|&jahN-oE!W7KTmBcPITax?fniHm%%LoI7B7Mruq^7I#S6D*~4D z5Bs3{U_aB0oWQ5Q0P7FrP%xz1vP6Mp84?x(j>D*{{31_f_SDb{usHT|v--#SIv*YJ zyrWS(J!bnH^!I!hO zZgBB=E?MYct+V{?2~|<(?+>%TzI>bPNl{1iB~qs1d!WnP<3vaRZ)_hDB|AP zg2hQJ0q(B%1v92*V@Q#bO zV-LVNwDIk6_+vv!zZe+3E9%|PRWi7PJQSx#dcXrKfsY@1C6#RF*mlKj?~M<77bC`Y?L2Wby*zA0WbIrMaqAW@iN>%vNOd7%xaYny03K+r}=!WX}u)#Iu-#!gT$mBgAhXP`MxXqXW z>!hhI4z7KZNzxg?`BBEB@Ks^7;TaZV`1WRX=&@}AZL75{v#=*fv}=Jk!VQwRG>FLR zZj}UEr6stMRMkJRp7m(GaOS`uPM}%z+SRD-oWdpn=KW9+?88`PJet;IqNNJFqi~XP z^XQYRr?H`b@4P?$q@X}XXg%5g`fXZfJ!5Ky zz+Z_yX6m;3_Fa*W7qXEncF>WcS6LWs-kJwS<*{jgcQc5O*o+CUQus!6|~Ee+~X4= zBGDbxvlgK_y7tAh^CuiO2LI<J2$U*TzNj(dF78i94!OB3tAlGLx!e5 zN27=LzH%O4Ku%vhN18G9NXWc+?uE5W&Z5JMS8UF135yQMZE3EiABed%NCG`;@Z3;W zIHfTyKxM%fq_Zu@vGOLh+rt`%)m`>JFog&Jw;?CJky>F!f2FJ9=SCWpzQ@wRl2d4< z+(MEuH0a-YcdGKBM^w|av%_%RbD-1p&FduDU1#loWl^=bSbE7?*`*6yIj{HKN{cu* zjyaRXGGIi8yCB&x`+@T!C+*mHCI?u4@J6faP6D4~&#PQ$0&^4lpkL2-&Gs{72ab(# zq|GgsA1b3#NDA4wbDc-FbR0LfTnW!*M-zt|A&KsAjaX*H9~icJr=#%`OsEA2lVht2y zZ}*xmb<$JL=KE1GZU#w5gY@)EDC9#qvS9tXyaSX8$)H+_y}dIpph?^%IQ#S2&es0N z`etL=VlNP#Cez-RF#ka6FTDE~j-%iOt{3&sgtNH<9elu;$A7Jy9tq*}z|?J~`k#ij z|MI*T_D4sQ17h{}vx7ekY9V_R0K`-*fn54L_{va0QK8k##1}XE!A7ppzlPg8Xs>Yhf(KC*vz5DGFqxmJCJ7V;s;y9&-C(PfO+rPd`qr& zlmF#Ep0*D;!xtAlvdMe)W=cOd)j3wAi<6s0PHuTSzpREH(XK(}CtFV3ne(_lNu%SV z5VQGZoW;Y1@9%u6X@_rueauoPuPr;gi#}^(uvm`e{zW1(+iRS)6RK2(FCNSf_8I^A zsFxVwh1Zg|zDxM&pVBIIn6NG1a}dQj+8-!c64uIii54K!gH0n#AgIV9_fgt$c25;P zL6r^H02Y9h9*NW0G^%AmyB5?$e5Y6Uo9}Nz|IfJf|{=yVZE6> z(r>V}sIuWT2mV12sJL8NOhri0;hjZEG4!RsyjBul$sb2?zli)V&JMIzxbGyhcnfn43(qqKI_L#U?C|DNE&7eX$yhwkT|5gzDA0Nqxx9w zr*M>;)dNcTgeqwBL}JY7l%~MHQJE81x8a~~p`GZw2V3^z#8Xz$bI5X+#aO02`U`;8 z7!NR3R+sj^v{2yUE08z1QxY`bM#$k7T$F3Uc4|O>Z=N~1>;BwYGok;t1(vr1830Uz zb~wSb137G<6fcyt>{AF6wwLhWds03ECm{p$!XM|PVtn%9X2_&X=!F@?&DRi0bkxLv zLJe@5TPWmB1qr#0-13lH=vagc6!13F1;_S8>>>1O)pl_BARFg)TuB3rMykL#?-c&E z|5tD)5hg<}hc5v^Iv%sdS__%)fal^YaD@*XUF5wTY?)RzBze-fIH?)f47|u8S5hF# zb$E{?Akeiz0u%YPgY{v7FlWhh^IhP32Nc3{YG9%kd7{zDdLttl;rEvp0I*T)zEzZ`y(X@LW0}fyu};&m%Dq8ZGWdd2x>nVkSi*A` zjCIZo-4+8_^JDtAQ92C_(Or?S5JV%@kNuT9ax4_!KMna=g|KiUgbckiiB0c+COsvQ zNz3{X3$CS?Fq+?MfmZ)R|0Km9SJ5BW<8MzPI*{s0s@@?4!voNz2B6Y81zYavqum=E zM2551K!R&OhfFf39K{&BKTRXD(~j<1+ugpeHK7&Je7V4}ci}rSI@t%VLjndtKisUi z(&$>-hG0$|3lmd4#5iI7ob0P_(;@x{mLF&V&Q7$a48dIb6}0Zv(1-EBH=G5rc+K-q zC-ud>mW$U(8-Zw9E`u<2*H@DorJ;~CW>gQV1ze0W9)z0SoyY)(?{4B}MYVJ4&c-{S)Q@%3&|MbM%Hg&R0co4bwj zXR)9B$&qbgz6#Eav{f*+wlpIzFR{4Zb?t%vHoILykeI9|yJ| zc)@sfu(}1t>`O4Q9R&WZ@Wc<&8?w|WkJ(4tb_O_fT%EI%nT_XQNuJ=&P)vpkjFFCEyQNuYddwjU;67d7HTL?Z zdrL3CaXli%kD&ij2EXRIeZ6XI9}9rW5hfySOIPSqxE!HKVdEs7W!ejPP~K&TY0=%7 zrLMzwo1j!@U8s|Hh~J$3Eu@R4AIF=$a^4dY^VQ zz^J3^%}>hhlOcwMR1b;rQ-fHT~_Lx?PY2`p`$ z$Yxp84?n9IbAH>=;5WIJ-4-nofS*BmWtuC}}g*d^7 zP{vS0FmYoO9HkqKICk@awhPc0!6UyQWUQs-qDwM%W<2`CgRLwAFA=rOby_|`+GU|3 zYz)|tXW;m<=nhJ6Qhqq#mAg_p#ZpXod@?N4H)y+>QSKC}1(@w!Qqi}ue zEx99;q!SZ=+?+nQ$-FAd{VxT$7W9)+OD$MCM)KsMCOf~MAKCa_0x#n23YjWqP@tl* zV{!l3uC#fuX5Daan5Ky*=^bic(Q{srNF_Zpgb6JN#V+WFCr3(^@I^ooZ1jkPsv+4C z2zT)i#mbKbF4Q@EwxwwcNVYYlKseCfC}10lyP2%rPpd}cQk5rAt;ZhE*MEh<(oEh?IyL4SL$}J6^f@wy)nvmldDs9Fo z-v&$3&%acQl<7L!4?>e0HTL8-s`-&yEkMmU+vqA$QNIF5blwt3Vn!11j{xea)}NxJ zzz?>(opi}9jilvk>aq%AEn@|l{({IMExXP9t0mRu5>`R@ecALT865b0~-yg ze@>Q;EYA#hXn*(nFKe6M$D^O7MJrND+%p~yodK68xf-eN&}bMF29;*wB6`$`($o@i zq)R7f2^lyw=_PR<<@XCsNmy3riFVcSYwvh0cX`{#ct3rWO*88mej#d|qcmPZe{%8c zddhy$4suw_%zS6tFTIg1kfKk1=+zFsyM_YbPq#@8Aj|kzb6tbq&O79fB;0 zK=5~zOdh06WbpUSk=9^lOSr97r9k2|-trP0dRE(}2}6C-RwQ zMmQJqSUH~Dd2U~eTG*q1IsX5+@BjMg$%`efuX6S}wO&Ay;VMAZ&oS8YEbe=PRJwNar8PWv6H0$0fn0gltbw?U`vbgO;V-V=6cIq3tha)FrQ*()+ z?xfW1Ivs#%Tx7POa0JaV-1&oT*CB_%#HvGBxIrG~!f!(Nf``4?bgLpl#rJb#fMn~t zU=%r}QMKX;Nx)MkgZs?z{4(^6l(WNRp@;uCTmEsP|I;ZSJwV&J$$+p&!!Rl(?SSde zOP}j8Iru%;w_Vl>O@Mf@D{?>s*APP_rUV!y4WEUI2C>3z@>n~QYJqG>NO0v73Ay5K z1kLJuH0ywj+YRZe_R!s}0)f!qx@yrIgK2-RvwR~|5o0fnD`-Z$75dOE2p~;Q;mm~j z_vH3WXM)ZgFEfGEA^oAf#8j1aLSO4dY&-8v1S>gSB)1L}m1u=5gYw#d7H9tc& z`BL?QO&@?bA<>uUcDHeu0kigKcft5}>B(z%g&| zpeAPnegks|#Kw8FFn~vDQ{6P`gV0kDXJK^NeU$cF@!Ilv=ux?K8j-^(w26h_&Y*~r zPrz`TT2Fb~|>rFa!C*P=+KdPCkJzdRd+_5i#PD_hzJ zYusd#E|%CX3N{|o$IuX5itgiWC3wW_2j;9XNa%U*T=mt;<{S8-h`+3(GtL`z zd*BgL0V2#}tQxTE<*DP-Cjr2)&Rh^%MP#}z;7X{@yI*akA$NUKL}M=hKLHmnlkOCW zt-z^wv_nio^5;J(=ZY?UJA>_D9&nC;!s$4Wh_%zN`KVyTRN=A;%rt5L+1K)|^T4CE_;zR;`g)_kQ2x+6 z^if~Q7vy5mn?^G4+%iH?=-&rzjq;s-yCF)$()Ukl?3iCUUrGPuSAPm@vNkiVEM)=} zm)vi+>dELYRF6qAKo!;cPP3ctWONDTMe11r?TpVNE>Q5gnmZRw)YhK9u;Ci0kVpGH z@1o88B?yV*hN^Mvo|hn2`|U-2_JYl}KxGM&E%<4NpNfyzdj*!MLJaNCS4?Yq%Gd1+ z)+;|>k){0RQ?dOTk>rOcT-ih|jJn%_22_}Jte-e!{N^p?#;5E-pHkfI@aauHfm9Mv z_qUz1`(sBaJOu@4@Xc$F#lb|oA+|+r`w{eTngG{b)rJpcR>??Ege&ByywZQ**cr@@ zgX&0uhty`)mT>49bcakY&t_b>bQj&M8aCt}sV~`Ncfnk#3ZcQ&@e;p1)D2Z2puxw4 z%GrEiesRH^&u)WFRE{0RTG=HaNLf+JGewm2A%2})3PXFDa{@<)C z_|--f*^v47L{rmpy2b%?ith+^)K>u@N3j%PgGV8@!3SAuz9a5e=a|_0O zv#{JN29-sD2F%_C4U2~sVvD1_kHTSVK?oKHMQBTku6T6^TZJdvseL~;8TS^3Dz<&R zr~c>dp`k(!g;AOes1=GZmmpaIF>>O8tAYZcTq2N+0|wNGT#AxW7mCEbH?QE+ulu3^ zRRlRz#Nk7aq<&O-ux-x`(>*_*9#|>Dy;?9~Ch_x4{jnhas*e7AluQ2rI4|nx9EK|_ z`>1Y?3WPY@kh_{TgdajW3Va|$IMjj((btBFd(`7dCW8nYU4LVoaDEZ(VP;&5d=gq* zy3P4ePY9mcCRUg&km`XAvsm>(E&YvD@n@?Vd=6U=iq5gk(QosI+h8#IM(2#{HB*~16T>~Ts!DV0$5eOdd zn0;9^Um${phbhr%aiT+zJA(4(CW$==p@d9}tk!>8#r(E5e?Koaws<&IPPfI8Tq+QM z`ASFB-&^=D4U1Rv9?+?N7Dx&owlY-dPP&H>{ygCR%P-}kAqQLOFkK56V<5Z>T+#_9 zNcSOKPx*7vlpofJzbYO;_@@Aee|~qrA8y~NHY8;5aC;z!I^p{-kZISsQ%Gl^s|L)6 zUUS}`@9N+cSfl<$|?| z>7Q;hbN`m}JNr4mb4~$LDhKjvL2fkjL~iu+FL{NKVYUgbSoP)o*#@22YeXjInGXI) z8qn%m4bE1+6c(=N zHqY@bq1Y1vf)A;#Q~;rPq@5)ZH0uITGa{j${5X#SuQ z;gcHXR09|B*RtqaK^<_1FvPmz7-EeV3=j0SLV_8h0eBb~Lbai|9FK4^9_jHr4zNa=Lfy6a#NgaX@;!*$5Pj$9 zo3Lnss^)|GB!F~NRK-Bgn@4KLk)B83yVTmf^a>P46^1(G0nmt|0BkCDaG2f#E>{R? z7Q3RaPo19ya(<4qYKzlR5dbdZk9Zp|S!LxU3bi1S{@|hoNDu9OA=^cq8AUC62`{=; z!m`iCrXGP9ry-ixuSHOFu;nc?mduWS4L97}%HaZ#6xzqRQ6g56q=IGBqSp&S7GxBlG=$adeIvs*qiyL8L7TjG*la}WNyC^R$Fd@mJ zB6Lt!yi=}Uzn+{6O>O!34U08Z4t4M-%cNUJJ1Dzi<i~t{#`>g`qiWC>ZU_CB`Hwb7?nl_gB+Z<2@2@1GVzB|JYf`# z7gPaQ8uSVl`@Gy-BHf-nd;W`4!X3K}P1)JI`R)bC=tbig|1U13}Wq1YtI?9Bqn>DUEUeB~9kkuQ51!HYp7 zQF}qXcm!_Zxmy+rCYn}-)vj{X*VoUwBe5td7+(&ycbOPb+=a$)3l}VOGmP(x8;d6a zlSi(Kbw)A4QG3^HhhSkAFjL154sZkdM@@j4T^36nT^%tX@iGL|<1Et;I1_JiI2!qO zJGDtQo@5(3+BhnXQ0yY7D`G6kC)B)Vu=hkQU%8$Vc)3fpsB_;_J(}uLa;P?rKjMb% z;Y>}`#WnrF0NFsDc-{C6ffxc139r81BFGubg8Y!xP=M~QIJo_0S->55**2{=RNu}n z$?`7bl5wqtnH`_M%pnsb)65#AX$3u>bg+mx)CmnQ-Qm$+WmXEga<9#%KE{I z#3S|Q{euI=F0xLYXZ6U$S2n=c5vvOU*~^gPd49F}5Rx0GZ4KB)aBjrtbyZaaT*urz!n_;j@p`WuzS3s|oCr8i0p z?8y;!7C{np&Waccn?opd_+rJdBiz(AtFi$aybKp*&yYudV`%q5TYlq>elZy(C2DI~ zS-oYEGgD!ZJJ+JrUzt97J1?L%$o93T1cv{5Cxns9xqco8v~wadCcmujAuaBYkv+`=F!pr%EUs zAnsDzX_JMZIN&YuSG9|5|65x3@ZlETMreK9SljJvn*;^{!Wl9lrjQBjs`6*A8}C*t(VeWp{L_?0P1q=1guOIySSjsqc%5TG@Mhd-ZK>Y%u$^bP}+p>l$8C zwL~UrCuJ{ddeDAluQt2v6Wzc6VI3Vxn{#5=hL;oeX-OG-w8+DL9()Ar|z7Mw@oQ(}i;xEb$ z{^k3*erX^?ijG}L`?w`IybS_4a?QO?LxlPdzV@ZTbsBc>RhrGx^nRwkImc9++1Aw5 z_nu!1TCWMxg>#;#@7EGxH_1So6tSM^}{?)-H!Db zxuNRfOr)3WC=jy8*_dP=X|P@X!jE>E&`U8yy~t2t(pha}WMs2m|8Xf*R#uh|fh)t1 zA%Cw$vZW^`dyivzA!JizTDS}m{B#m|czF}o*K{NaN|~>-tl{wstUK38&ve!I36qc& zu0P7*H-7}4(=kZT%HiCiGAR#C0yEwfMXngz-_}-PCu2GO%A-TV&au~GV-KRxAL&c- zgDV`~@o?bo-Mc3p42Yeu<*BEqrzPB->wz{=tGhJgzq5AR?a2?T<{Z)sbZS=*Uy#CP~3?8#nq0nb|EkTX=EFuG@RUcU9OX z_s*RA*QFpE%Ez-UfO|>bi~t4S(|Z6v z{MZCL6T?0h;ms5*4_;5ZjN7M9&rGH?eVNY{Opp^X11{;8&jLgnm%8F*p#i(&|a|- zKC{~nzQg`jVVC3tdx&N>>U2A3BAm7|_lTZ0R8wt)l!$>^XSn$Mw!E?DiDoLl(`V6e zPw}ys&K45gc7E;C@(603eet#8x6znWwwXm?QWtCBN-2k9Sm#M7{L`4rV(~tl5PH_Y zVB;{*IxUDOr~Iy}p~UnNK?~FdHa0!{t?tj~Pl*`W(#nEyW(U!-Oc!We6bIhiI0(mD zLf0&_x?0D@n^zIOu%e->Up3I}?0(xC(ndNh^hSGElLmk@3 z9I{xwadKoFE5@XyRwQWY{Lq_{KvTjuBo(XA*$sxOY*uDwW_9s}e;IFbOcSMyj>UsX zruQPmYYFbqq?yO3U_cLq&(Yv;ZG@Ff?QnV;p!E`+z_`h@g_VV+ z@W2*H$v2&zgD>Q(d;2&)hlX(W4ci##>!Hx?9Dak=e0{_12NmwKV0$T zE=Bs^ry`YlJ%d<1Ep}!5i2=#Kd+nt{Oh=}bS6Z9!XVIZ{+gj4>7Ti#C<~Er|6Lengk?S#U%C5)v$O2`4cO-^sWSy1q1N0}bF%#Wx z%Q+9*<%b2cm6nz^LJOBF>6A{#yd2M@ah0ijZ%xi7Qo@}xS2@)e;i{n2^r76;saIsQ zn+~q!#dbLY0MJn28Z?B6`# zJ}&#g^dC74aQwL~C>2WTn96wKC zijifhr@R;@ck+>8t%@)=^Qt);o1Z?T(qYoU*c+5&Q5OAbPzW3Dt9brqlYfMA#3)Fn zj&#M1T)*4RpGHzr!*W`KfTFM{hKDJW?WL8Ej0_`A|}8+_zL&7V$@T!tVfDe0p2Wuyz-{ww$n z_$e{qr(`bsO1euZ+N3&=62WK1qeg#-1ch+!D^`mWeZ0L}Pka0L1l-iE?!A4}Um1Bl zVk^a1jE16x0SZ01xxt~rSnV+<>58Z*#aesa9%Tn%m6dQLhp`S3z=W?Ci19o;JSxhu z|BDbXGufZXL%NRnseoP05sv<~-bRYwTOK3}pMl%MO%XRFat_~SSQxjak<1m_39iEm zXHT@!%x8ZXAEENeul()OusPx@ETlRT0`9Q>|`zQ8qle__Te3*Xt%%+ zWx7D8oq8_>l1TFW!qpv557!$_@f;v1%&pBWr;L7+~8%LPDRHU@({hd8HXyh}Bs(tgTyldleHYQAh2M;0tFG zz*u-E$#Q3S@bu864~$fx zYf#pKK{ib%3qN$OfdETaU!V->3CuqkRspa_z)eDste5aW6A6wZh6l*vu{VGwt~IFc zCFi9QbD;E2U6<-9m2^=M(cl6FYNK5#StJp!1tfv5)cZ*m)c-lEspI_TsHSzU|NB&h z@ZOx99BpHL{d=`4FK6+%dkBxqme@wh5Fn*t!u_>P$4H-)$6=8Cg1~@)b8hB|1k?(? z8KR4N3}ba93*FyH%H9sIn9$&lwI074JPkDD;gcX}@KWO90UcgGJ_%aNvuKfjH3)?( z{f|hPHIn!+DHI+RZr)77WleD4`m=akT0jNXz;P^x!pygQ$XGI!3L2!O9-%VnqI#;m z_dE&1!Qv6)ilE9#hT9aOi%Se8`BK}pjOQ$xblNEbng&vdI&h)`>sS`W>!t+*^?q=J zHJFA5kwA2zF|Y@K!OEOAonK7M9dgTdcd2VRo82X zaT3b&2RqvpQlI_q2iCRikzFo%S|i#Ix~x_bU$M5$!D$6lS3aJ2+H3hVnr;Ph#}Vu;I#%N+Pl!rJF9NA0C+xKyv84!|ndM}Y zrL+581_b5`I7mOwN&WpRRX|`uJR^hfynvna9+n<4evc|DlfdZj8zKEfOcfBg^vJ%H zIir#OYVMHAfWWE-%-nM#X!9RKi5Lh&-K)tT=?Un^4~m_Kj!z92Wi`{$b{TqzmORh|U#GDVyT7d$ylz$tS+kl?jKq ziA>^-m_#jMmM|+(A#I0?#o4*#*Bv~|6=FsD?&~^~E1GJjMg<<#`LRx2xII$SjQp=3 z>Ig#$olyVNhqI+1oLxjJ>WXa(D;pcFsHmtwcw{ykgfOXTY4ar3cu5NRWc@Ln>CcHy zfBq)AY+O+7oFk|rT2c6y8$JiHD230DTXPT*`xPZ0S!^;tfA~A%xhd)@%wiRbm@)zd u=*bunOcqmibyd{e_Rl>3zu<-&TTb05A1paC7P$oeDJ$&X9kc6%+rI(YL=%_* From 59a49b3972ab414cd921fa7703dc18d0e5e20b03 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Mon, 18 Nov 2024 17:49:44 +0800 Subject: [PATCH 06/36] fix entry logic to not re-fetch data for the initial team (#8349) --- app/actions/remote/entry/common.ts | 10 +++++++++- app/actions/remote/thread.ts | 10 ++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/app/actions/remote/entry/common.ts b/app/actions/remote/entry/common.ts index c9c1ab2142d..8a68e7e6be7 100644 --- a/app/actions/remote/entry/common.ts +++ b/app/actions/remote/entry/common.ts @@ -396,6 +396,11 @@ async function restDeferredAppEntryActions( const sortedTeamIds = new Set(teamsOrder?.value.split(',')); const membershipSet = new Set(teamData.memberships.map((m) => m.team_id)); const teamMap = new Map(teamData.teams.map((t) => [t.id, t])); + if (initialTeamId) { + sortedTeamIds.delete(initialTeamId); + membershipSet.delete(initialTeamId); + teamMap.delete(initialTeamId); + } let myTeams: Team[]; if (sortedTeamIds.size) { @@ -411,7 +416,10 @@ async function restDeferredAppEntryActions( myTeams = teamData.teams. sort((a, b) => a.display_name.toLocaleLowerCase().localeCompare(b.display_name.toLocaleLowerCase())); } - fetchTeamsChannelsThreadsAndUnreadPosts(serverUrl, since, myTeams, isCRTEnabled); + + if (myTeams.length) { + fetchTeamsChannelsThreadsAndUnreadPosts(serverUrl, since, myTeams, isCRTEnabled); + } } }); diff --git a/app/actions/remote/thread.ts b/app/actions/remote/thread.ts index a6b6534c187..0549c6ae1de 100644 --- a/app/actions/remote/thread.ts +++ b/app/actions/remote/thread.ts @@ -14,7 +14,6 @@ import {getConfigValue, getCurrentChannelId, getCurrentTeamId} from '@queries/se import {getIsCRTEnabled, getThreadById, getTeamThreadsSyncData} from '@queries/servers/thread'; import {getCurrentUser} from '@queries/servers/user'; import {getFullErrorMessage} from '@utils/errors'; -import {isMinimumServerVersion} from '@utils/helpers'; import {logDebug, logError} from '@utils/log'; import {showThreadFollowingSnackbar} from '@utils/snack_bar'; import {getThreadsListEdges} from '@utils/thread'; @@ -286,15 +285,10 @@ export const syncThreadsIfNeeded = async (serverUrl: string, isCRTEnabled: boole return {models: []}; } - const {database, operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl); + const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl); const promises = []; const models: Model[][] = []; - // this is to keep backwards compatibility with servers that send the - // threads for DM / GM regardless for every team - const version = await getConfigValue(database, 'Version'); - const hasThreadExclusions = isMinimumServerVersion(version, 10, 2, 0); - if (teams?.length) { for (const team of teams) { promises.push(syncTeamThreads(serverUrl, team.id, true, true)); @@ -312,7 +306,7 @@ export const syncThreadsIfNeeded = async (serverUrl: string, isCRTEnabled: boole const flat = models.flat(); if (!fetchOnly && flat.length) { - const uniqueArray = hasThreadExclusions ? flat : removeDuplicatesModels(flat); + const uniqueArray = removeDuplicatesModels(flat); await operator.batchRecords(uniqueArray, 'syncThreadsIfNeeded'); } From 7d8d4a4c6840a21e2136b66a9ca1ec962158fdc4 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 18 Nov 2024 12:47:13 +0100 Subject: [PATCH 07/36] Translations update from Mattermost Weblate (#8355) Automatic Merge --- assets/base/i18n/cs.json | 7 ++ assets/base/i18n/de.json | 7 ++ assets/base/i18n/ko.json | 24 +++---- assets/base/i18n/nl.json | 9 +++ assets/base/i18n/pl.json | 9 +++ assets/base/i18n/pt-BR.json | 42 +++++++++++- assets/base/i18n/uk.json | 127 +++++++++++++++++++----------------- 7 files changed, 152 insertions(+), 73 deletions(-) diff --git a/assets/base/i18n/cs.json b/assets/base/i18n/cs.json index d49a17b9763..baf8deb5b7b 100644 --- a/assets/base/i18n/cs.json +++ b/assets/base/i18n/cs.json @@ -1175,6 +1175,13 @@ "user.settings.notifications.email_threads.description": "Upozornit mě na všechny odpovědi na vlákna, která sleduji", "user.tutorial.long_press": "Dlouze stiskněte položku, abyste zobrazili profil uživatele", "user_profile.custom_status": "Vlastní Status", + "user_settings.notifications.test_notification.body": "Nezobrazuje se vám upozornění? Nejprve pošlete testovací upozornění na všechna svá zařízení, abyste ověřili, zda fungují správně. Pokud problém přetrvává, zkuste jej vyřešit pomocí kroků pro odstraňování problémů.", + "user_settings.notifications.test_notification.go_to_docs": "Dokumentace k odstraňování problémů", + "user_settings.notifications.test_notification.send_button.error": "Chyba při odesílání testovacího upozornění", + "user_settings.notifications.test_notification.send_button.send": "Poslat testovací upozornění", + "user_settings.notifications.test_notification.send_button.sending": "Posílám testovací upozornění", + "user_settings.notifications.test_notification.send_button.sent": "Testovací upozornění bylo zasláno", + "user_settings.notifications.test_notification.title": "Odstraňování problémů s upozorněními", "user_status.away": "Pryč", "user_status.dnd": "NerušiT", "user_status.offline": "Offline", diff --git a/assets/base/i18n/de.json b/assets/base/i18n/de.json index c49168a2de7..e0655ea01eb 100644 --- a/assets/base/i18n/de.json +++ b/assets/base/i18n/de.json @@ -1175,6 +1175,13 @@ "user.settings.notifications.email_threads.description": "Benachrichtige mich über alle Antworten auf Unterhaltungen, die ich verfolge", "user.tutorial.long_press": "Langes Drücken auf ein Element, um das Profil eines Benutzers anzuzeigen", "user_profile.custom_status": "Benutzerdefinierter Status", + "user_settings.notifications.test_notification.body": "Du erhältst keine Benachrichtigungen? Beginne damit, eine Testbenachrichtigung an alle deine Geräte zu senden, um zu prüfen, ob sie wie erwartet funktionieren. Wenn es weiterhin Probleme gibt, kannst du sie mit den Schritten zur Fehlerbehebung lösen.", + "user_settings.notifications.test_notification.go_to_docs": "Hinweise zur Fehlerbehebung", + "user_settings.notifications.test_notification.send_button.error": "Fehler beim Senden der Testbenachrichtigung", + "user_settings.notifications.test_notification.send_button.send": "Testbenachrichtigung senden", + "user_settings.notifications.test_notification.send_button.sending": "Versende eine Testbenachrichtigung", + "user_settings.notifications.test_notification.send_button.sent": "Testbenachrichtigung gesendet", + "user_settings.notifications.test_notification.title": "Fehlersuche bei Benachrichtigungen", "user_status.away": "Abwesend", "user_status.dnd": "Nicht stören", "user_status.offline": "Offline", diff --git a/assets/base/i18n/ko.json b/assets/base/i18n/ko.json index f368bf0d045..1a6b74e7776 100644 --- a/assets/base/i18n/ko.json +++ b/assets/base/i18n/ko.json @@ -26,8 +26,8 @@ "alert.removed_from_team.title": "팀에서 제거되었습니다", "announcment_banner.dismiss": "공지 닫기", "announcment_banner.okay": "확인", - "api.channel.add_guest.added": "{username}이(가) {addedUsername}을(를) 채널에 게스트로 추가했습니다.", - "api.channel.add_member.added": "{username}이(가) {addedUsername}을(를) 채널에 추가했습니다.", + "api.channel.add_guest.added": "{username}님이 {addedUsername}님을 채널에 게스트로 추가했습니다.", + "api.channel.add_member.added": "{username}님이 {addedUsername}님을 채널에 추가했습니다.", "api.channel.guest_join_channel.post_and_forget": "{username}이(가) 채널에 게스트로 들어왔습니다.", "apps.error": "오류: {error}", "apps.error.command.field_missing": "필수 항목 누락: `{fieldName}`.", @@ -189,14 +189,14 @@ "channel_notification_preferences.reset_default": "기본값으로 되돌리기", "channel_notification_preferences.thread_replies": "스레드 댓글", "channel_notification_preferences.unmute_content": "채널 음소거 해제", - "combined_system_message.added_to_channel.many_expanded": "{actor}가 {users}와 {lastUser}을(를) **채널에 추가**했습니다.", - "combined_system_message.added_to_channel.one": "{actor}가 {firstUser}을(를) **채널에 추가**했습니다.", + "combined_system_message.added_to_channel.many_expanded": "{actor}님이 {users}와 {lastUser}님을 **채널에 추가**했습니다.", + "combined_system_message.added_to_channel.one": "{actor}님이 {firstUser}님을 **채널에 추가**했습니다.", "combined_system_message.added_to_channel.one_you": "{actor}이(가) 당신을 **채널에 추가**했습니다.", - "combined_system_message.added_to_channel.two": "{actor}이(가) {firstUser}, {secondUser}을(를) **채널에 추가**했습니다.", - "combined_system_message.added_to_team.many_expanded": "{actor}이(가) {users}와 {lastUser}을(를) **팀에 추가**했습니다.", - "combined_system_message.added_to_team.one": "{actor}이(가) {firstUser}을(를) **팀에 추가**했습니다.", + "combined_system_message.added_to_channel.two": "{actor}님이 {firstUser}, {secondUser}님을 **채널에 추가**했습니다.", + "combined_system_message.added_to_team.many_expanded": "{actor}님이 {users}와 {lastUser}님을 **팀에 추가**했습니다.", + "combined_system_message.added_to_team.one": "{actor}님이 {firstUser}님을 **팀에 추가**했습니다.", "combined_system_message.added_to_team.one_you": "{actor}이(가) 당신을 **팀에 추가**했습니다.", - "combined_system_message.added_to_team.two": "{actor}이(가) {firstUser}, {secondUser}을(를) **팀에 추가**했습니다.", + "combined_system_message.added_to_team.two": "{actor}님이 {firstUser}, {secondUser}님을 **팀에 추가**했습니다.", "combined_system_message.joined_channel.many_expanded": "{users}, {lastUser}이(가) **채널에 가입**했습니다.", "combined_system_message.joined_channel.one": "{firstUser}이(가) **채널에 가입**했습니다.", "combined_system_message.joined_channel.one_you": "**채널에 가입**했습니다.", @@ -408,7 +408,7 @@ "login.signIn": "로그인", "login.signingIn": "로그인 중", "login.username": "사용자명", - "login_mfa.enterToken": "인증을 완료하시려면 스마트폰 인증 앱에 표시된 토큰 정보를 입력해주세요.", + "login_mfa.enterToken": "인증을 완료하려면 스마트폰 인증 앱에 표시된 토큰 정보를 입력해 주세요.", "login_mfa.token": "MFA 토큰 입력", "login_mfa.tokenReq": "MFA 토큰을 입력하세요", "markdown.latex.error": "LaTeX 렌더 오류", @@ -445,7 +445,7 @@ "mobile.calls_headset": "헤드셋", "mobile.calls_host": "호스트", "mobile.calls_host_rec": "이 회의를 녹음하는 중입니다. 모든 사람에게 이 회의가 녹음되고 있음을 알리는 것이 좋습니다.", - "mobile.calls_host_rec_error": "녹화를 다시 시도하십시오. 시스템 관리자에게 문의하여 문제 해결에 도움을 받을 수도 있습니다.", + "mobile.calls_host_rec_error": "녹화를 다시 시도해 보세요. 시스템 관리자에게 문의해 문제 해결에 도움을 받을 수도 있습니다.", "mobile.calls_host_rec_error_title": "녹화에 문제가 발생했습니다", "mobile.calls_host_rec_stopped": "처리가 완료되면 이 통화의 채팅 스레드에서 녹음 내용을 찾을 수 있습니다.", "mobile.calls_host_rec_stopped_title": "녹화가 중지되었습니다. 처리 중...", @@ -527,7 +527,7 @@ "mobile.custom_status.clear_after.title": "사용자 지정 상태를 해제한 후", "mobile.custom_status.modal_confirm": "완료", "mobile.deep_link.invalid": "열려고 하는 링크가 잘못되었습니다.", - "mobile.diagnostic_id.empty": "이 서버에 진단 ID 값이 없습니다. 시스템 관리자에게 문의하여 이 값을 검토하고 서버를 다시 시작하세요.", + "mobile.diagnostic_id.empty": "이 서버에 진단 식별자가 없습니다. 시스템 관리자에게 문의해 이 값을 검토하고 서버를 다시 시작하세요.", "mobile.direct_message.error": "{displayName}의 DM을 열 수 없습니다.", "mobile.display_settings.clockDisplay": "시간 표시", "mobile.display_settings.crt": "축소된 응답 글타래", @@ -545,7 +545,7 @@ "mobile.edit_post.error": "이 메시지를 편집하는 동안 문제가 발생했습니다. 다시 시도해 주세요.", "mobile.edit_post.title": "메시지 편집", "mobile.error_handler.button": "재실행", - "mobile.error_handler.description": "\n재실행을 클릭하여 앱을 다시 엽니다. 다시 시작한 후 설정 메뉴에서 문제를 보고할 수 있습니다.\n", + "mobile.error_handler.description": "\n재실행을 클릭해 앱을 다시 엽니다. 다시 시작한 후 설정 메뉴에서 문제를 보고할 수 있습니다.\n", "mobile.error_handler.title": "예기치 않은 오류가 발생했습니다", "mobile.file_upload.disabled2": "모바일에서 파일 업로드는 비활성화되어 있습니다.", "mobile.file_upload.max_warning": "파일 업로드는 최대 {count}개로 제한됩니다.", diff --git a/assets/base/i18n/nl.json b/assets/base/i18n/nl.json index aa19fe13d84..c4a4d93b7c5 100644 --- a/assets/base/i18n/nl.json +++ b/assets/base/i18n/nl.json @@ -454,6 +454,8 @@ "login_mfa.tokenReq": "Voer een MFA-token in", "markdown.latex.error": "Fout bij renderen van Latex", "markdown.max_nodes.error": "Dit bericht is te lang om volledig te worden weergegeven op een mobiel apparaat. Bekijk het op een desktop of neem contact op met een beheerder om deze limiet te verhogen.", + "markdown.parse_error": "Er is een fout opgetreden tijdens het verwerken van deze tekst", + "markdown.render_error": "Er is een fout opgetreden tijdens het weergeven van deze tekst", "mentions.empty.paragraph": "Je ziet hier berichten wanneer iemand je vernoemt of termen gebruikt die je in de gaten houdt.", "mentions.empty.title": "Nog geen vermeldingen", "mobile.about.appVersion": "Appversie: {version} (Build {number})", @@ -1175,6 +1177,13 @@ "user.settings.notifications.email_threads.description": "Verwittig mij over alle reacties op draadjes die ik volg", "user.tutorial.long_press": "Druk lang op een item om het profiel van een gebruiker te bekijken", "user_profile.custom_status": "Aangepaste status", + "user_settings.notifications.test_notification.body": "Ontvang je geen meldingen? Begin met het sturen van een testmelding naar al je apparaten om te controleren of ze werken zoals verwacht. Als er problemen blijven bestaan, onderzoek dan manieren om ze op te lossen met stappen voor probleemoplossing.", + "user_settings.notifications.test_notification.go_to_docs": "Documenten voor probleemoplossing", + "user_settings.notifications.test_notification.send_button.error": "Fout bij verzenden van de testmelding", + "user_settings.notifications.test_notification.send_button.send": "Een testmelding versturen", + "user_settings.notifications.test_notification.send_button.sending": "Een testmelding versturen", + "user_settings.notifications.test_notification.send_button.sent": "Testmelding verzonden", + "user_settings.notifications.test_notification.title": "Problemen met meldingen oplossen", "user_status.away": "Afwezig", "user_status.dnd": "Niet Storen", "user_status.offline": "Offline", diff --git a/assets/base/i18n/pl.json b/assets/base/i18n/pl.json index d43faab17cc..56bd87420c2 100644 --- a/assets/base/i18n/pl.json +++ b/assets/base/i18n/pl.json @@ -454,6 +454,8 @@ "login_mfa.tokenReq": "Wprowadź token MFA", "markdown.latex.error": "Błąd renderowania Latex", "markdown.max_nodes.error": "Ta wiadomość jest zbyt długa, aby wyświetlić ją w całości na urządzeniu mobilnym. Wyświetl ją na komputerze lub skontaktuj się z administratorem, aby zwiększyć limit.", + "markdown.parse_error": "Wystąpił błąd podczas analizowania tego tekstu", + "markdown.render_error": "Wystąpił błąd podczas renderowania tego tekstu", "mentions.empty.paragraph": "Zobaczysz tutaj wiadomości, gdy ktoś wspomni o Tobie lub użyje terminów, które monitorujesz.", "mentions.empty.title": "Nie ma jeszcze wzmianek", "mobile.about.appVersion": "Wersja Aplikacji: {version} (Build {number})", @@ -1175,6 +1177,13 @@ "user.settings.notifications.email_threads.description": "Powiadamiaj mnie o wszystkich odpowiedziach na wątki, które śledzę", "user.tutorial.long_press": "Długie naciśnięcie na element umożliwia wyświetlenie profilu użytkownika", "user_profile.custom_status": "Własny Status", + "user_settings.notifications.test_notification.body": "Nie otrzymujesz powiadomień? Zacznij od wysłania powiadomienia testowego do wszystkich urządzeń, aby sprawdzić, czy działają zgodnie z oczekiwaniami. Jeśli problemy nie ustąpią, zapoznaj się z krokami rozwiązywania problemów.", + "user_settings.notifications.test_notification.go_to_docs": "Dokumenty dotyczące rozwiązywania problemów", + "user_settings.notifications.test_notification.send_button.error": "Błąd wysyłania powiadomienia testowego", + "user_settings.notifications.test_notification.send_button.send": "Wyślij powiadomienie testowe", + "user_settings.notifications.test_notification.send_button.sending": "Wysyłanie powiadomienia testowego", + "user_settings.notifications.test_notification.send_button.sent": "Wysłano testowe powiadomienie", + "user_settings.notifications.test_notification.title": "Rozwiązywanie problemów z powiadomieniami", "user_status.away": "Zaraz wracam", "user_status.dnd": "Nie przeszkadzać", "user_status.offline": "Offline", diff --git a/assets/base/i18n/pt-BR.json b/assets/base/i18n/pt-BR.json index 4be6c964e2d..f26063d1457 100644 --- a/assets/base/i18n/pt-BR.json +++ b/assets/base/i18n/pt-BR.json @@ -85,7 +85,7 @@ "autocomplete_selector.unknown_channel": "Canal desconhecido", "browse_channels.archivedChannels": "Canais Arquivados", "browse_channels.dropdownTitle": "Mostrar", - "browse_channels.noMore": "", + "browse_channels.noMore": "Não há mais canais para participar", "browse_channels.publicChannels": "Canais Públicos", "browse_channels.sharedChannels": "Canais Compartilhados", "browse_channels.showArchivedChannels": "Mostrar: Canais Arquivados", @@ -96,13 +96,39 @@ "camera_type.video.option": "Gravar Vídeo", "center_panel.archived.closeChannel": "Fechar Canal", "channel_add_members.add_members.button": "Adicionar Membros", + "channel_bookmark.add.detail_title": "Título", + "channel_bookmark.add.emoji": "Adicionar emoji", + "channel_bookmark.add.failed_title": "Erro ao adicionar marcador", + "channel_bookmark.add.file_cancel": "Cancelar", + "channel_bookmark.add.file_title": "Anexo", + "channel_bookmark.add.file_upload_error": "Erro ao carregar o arquivo. Por favor, tente novamente.", + "channel_bookmark.add.file_uploading": "Fazendo upload... ({progress}%)", + "channel_bookmark.add_edit.failed_desc": "Detalhes: {error}", + "channel_bookmark.copy_option": "Copiar link", + "channel_bookmark.delete.confirm": "Tem certeza de que deseja excluir o marcador {displayName}?", + "channel_bookmark.delete.confirm_title": "Excluir marcador", + "channel_bookmark.delete.failed_detail": "Detalhes: {error}", + "channel_bookmark.delete.failed_title": "Erro ao excluir o marcador", + "channel_bookmark.delete.yes": "Sim", + "channel_bookmark.delete_option": "Excluir", + "channel_bookmark.edit.failed_title": "Erro ao editar o marcador", + "channel_bookmark.edit.save_button": "Salvar", + "channel_bookmark.edit_option": "Editar", + "channel_bookmark.share_option": "Compartilhar", + "channel_bookmark_add.link": "Link", + "channel_bookmark_add.link.input.description": "Adicionar um link para qualquer publicação, arquivo ou link externo", + "channel_bookmark_add.link.invalid": "Digite um link válido", "channel_files.empty.paragraph": "Os arquivos postados neste canal serão exibidos aqui.", "channel_files.empty.title": "Nenhum arquivo ainda", "channel_files.noFiles.paragraph": "Este canal não contém nenhum arquivo com os filtros aplicados", "channel_files.noFiles.title": "Nenhum arquivo encontrado", "channel_header.directchannel.you": "{displayName} (você)", "channel_header.info": "Ver informações", - "channel_header.member_count": "", + "channel_header.member_count": "{count, plural, one {# membro} other {# membros}}", + "channel_info.add_bookmark": "Adicionar um marcador", + "channel_info.add_bookmark.file": "Anexar um arquivo", + "channel_info.add_bookmark.link": "Adicionar um link", + "channel_info.add_bookmark.max_reached": "Este canal atingiu o número máximo de marcadores.", "channel_info.add_members": "Adicionar membros", "channel_info.alertNo": "Não", "channel_info.alertYes": "Sim", @@ -112,6 +138,8 @@ "channel_info.archive_description.cannot_view_archived": "Isso arquivará o canal da equipe e o removerá da interface do usuário. Canais arquivados podem ser desarquivados se necessário novamente.\n\nTem certeza de que deseja arquivar o {term} {name}?", "channel_info.archive_failed": "Ocorreu um erro ao tentar arquivar o canal {displayName}", "channel_info.archive_title": "Arquivar {term}", + "channel_info.channel_auto_follow_threads": "Siga todos os tópicos deste canal", + "channel_info.channel_auto_follow_threads_failed": "Ocorreu um erro ao tentar seguir automaticamente todos os tópicos no canal {displayName}", "channel_info.channel_files": "Arquivos", "channel_info.close": "Fechar", "channel_info.close_dm": "Fechar mensagem direta", @@ -119,6 +147,16 @@ "channel_info.close_gm": "Fechar mensagem de grupo", "channel_info.close_gm_channel": "Tem certeza de que deseja fechar esta mensagem em grupo? Isso o removerá da tela inicial, mas você sempre poderá abri-lo novamente.", "channel_info.convert_failed": "Não foi possível converter {displayName} em um canal privado.", + "channel_info.convert_gm_to_channel": "Converter para Canal Privado", + "channel_info.convert_gm_to_channel.button_text": "Converter para Canal Privado", + "channel_info.convert_gm_to_channel.button_text_converting": "Convertendo...", + "channel_info.convert_gm_to_channel.conversion_error": "Algo deu errado. Falha ao converter a Mensagem de Grupo em Canal Privado.", + "channel_info.convert_gm_to_channel.loading.footer": "Obtendo detalhes...", + "channel_info.convert_gm_to_channel.screen_title": "Converter para Canal Privado", + "channel_info.convert_gm_to_channel.team_selector_list.title": "Selecionar Equipe", + "channel_info.convert_gm_to_channel.warning.body.yourself": "você mesmo", + "channel_info.convert_gm_to_channel.warning.bodyXXXX": "Você está prestes a converter a Mensagem de Grupo com {memberNames} em um Canal. Isso não pode ser desfeito.", + "channel_info.convert_gm_to_channel.warning.header": "O histórico de conversas ficará visível para todos os membros do canal", "channel_info.convert_private": "Converter para canal privado", "channel_info.convert_private_description": "Quando você converte {displayName} em um canal privado, o histórico e os membros são preservados. Os arquivos compartilhados publicamente permanecem acessíveis a qualquer pessoa com o link. A adesão a um canal privado é apenas por convite.\n\nA alteração é permanente e não pode ser desfeita.\n\nTem certeza de que deseja converter {displayName} em um canal privado?", "channel_info.convert_private_success": "{displayName} agora é um canal privado.", diff --git a/assets/base/i18n/uk.json b/assets/base/i18n/uk.json index 6d82e9dfd82..f1fa8baaeef 100644 --- a/assets/base/i18n/uk.json +++ b/assets/base/i18n/uk.json @@ -13,24 +13,24 @@ "account.logout_from": "Вийти з {serverName}", "account.settings": "Налаштування", "account.your_profile": "Ваш профіль", - "alert.channel_deleted.description": "Канал {displayName} був заархівований.", - "alert.channel_deleted.title": "Канал заархівований", - "alert.push_proxy.button": "Добре", + "alert.channel_deleted.description": "Канал {displayName} було заархівовано.", + "alert.channel_deleted.title": "Архівний канал", + "alert.push_proxy.button": "Гаразд", "alert.push_proxy_error.description": "Через конфігурацію цього сервера сповіщення не можуть бути отримані в мобільному додатку. Зверніться до свого системного адміністратора для отримання додаткової інформації.", - "alert.push_proxy_error.title": "Сповіщення не можуть бути отримані з цього сервера", - "alert.push_proxy_unknown.description": "З невідомих причин цей сервер не зміг отримати push-нотифікацію. Під час наступного підключення спроба буде повторена.", - "alert.push_proxy_unknown.title": "Повідомлення не може бути отримано з цього сервера", - "alert.removed_from_channel.description": "Вас видалили з каналу {displayName}.", + "alert.push_proxy_error.title": "Неможливо отримувати сповіщення з цього сервера", + "alert.push_proxy_unknown.description": "Цей сервер не зміг отримати push-сповіщення з невідомої причини. Спробу буде повторено під час наступного підключення.", + "alert.push_proxy_unknown.title": "Не вдалося отримати сповіщення з цього сервера", + "alert.removed_from_channel.description": "Вас було видалено з каналу {displayName}.", "alert.removed_from_channel.title": "Видалено з каналу", - "alert.removed_from_team.description": "Вас було видалино з команди {displayName}.", + "alert.removed_from_team.description": "Вас було видалено з команди {displayName}.", "alert.removed_from_team.title": "Видалено з команди", - "announcment_banner.dismiss": "Відхилити оголошення", - "announcment_banner.okay": "Добре", - "api.channel.add_guest.added": "{addedUsername} доданий до каналу під гостьовим ім'ям {username}.", - "api.channel.add_member.added": "{addedUsername} додано до каналу за {username}.", - "api.channel.guest_join_channel.post_and_forget": "{username} приєднався до каналу як гість.", - "apps.error": "Помилка:{error}", - "apps.error.command.field_missing": "Обов'язкові поля відсутні:`{fieldName}`.", + "announcment_banner.dismiss": "Приховати оголошення", + "announcment_banner.okay": "Гаразд", + "api.channel.add_guest.added": "{addedUsername} додано до каналу як гостя користувачем {username}.", + "api.channel.add_member.added": "{addedUsername} додано до каналу користувачем {username}.", + "api.channel.guest_join_channel.post_and_forget": "{username} приєднався(лась) до каналу як гість.", + "apps.error": "Помилка: {error}", + "apps.error.command.field_missing": "Відсутні обов'язкові поля: `{fieldName}`.", "apps.error.command.same_channel": "Канал повторюється для поля `{fieldName}`: `{option}`.", "apps.error.command.same_option": "Опція повторюється для поля `{fieldName}`: `{option}`.", "apps.error.command.same_user": "Користувач повторюється для поля `{fieldName}`: `{option}`.", @@ -42,39 +42,39 @@ "apps.error.form.no_source": "`source` не визначено.", "apps.error.form.no_submit": "`надіслати` не визначено", "apps.error.form.refresh": "Виникла помилка при отриманні вибраних полів. Зверніться до розробника програми. Деталі: {details}", - "apps.error.form.refresh_no_refresh": "Викликається оновлення на полі без оновлення.", - "apps.error.form.submit.pretext": "Виникла помилка при надсиланні модальності. Зверніться до розробника програми. Деталі: {деталі}", - "apps.error.lookup.error_preparing_request": "Помилка підготовки запиту на пошук: {повідомлення_про_помилку}", + "apps.error.form.refresh_no_refresh": "Викликано оновлення для поля, яке не підтримує оновлення.", + "apps.error.form.submit.pretext": "Виникла помилка при надсиланні форми. Зв'яжіться з розробником додатку. Деталі: {details}", + "apps.error.lookup.error_preparing_request": "Помилка підготовки запиту на пошук: {errorMessage}", "apps.error.malformed_binding": "Ця прив'язка не сформована належним чином. Зверніться до розробника програми.", - "apps.error.parser": "Помилка аналізу: {Помилка}", + "apps.error.parser": "Помилка синтаксичного аналізу: {error}", "apps.error.parser.empty_value": "Порожні значення не допускаються.", "apps.error.parser.execute_non_leaf": "Ви повинні вибрати підкоманду.", "apps.error.parser.missing_binding": "Відсутні прив'язки команд.", "apps.error.parser.missing_field_value": "Значення поля відсутнє.", - "apps.error.parser.missing_list_end": "Очікується токен закриття списку.", + "apps.error.parser.missing_list_end": "Очікуваний маркер закриття списку.", "apps.error.parser.missing_quote": "Очікується збіг подвійних лапок до кінця введення.", "apps.error.parser.missing_source": "Форма не має ні відправника, ні джерела.", - "apps.error.parser.missing_submit": "Ніяких обов'язкових умов або форми.", - "apps.error.parser.missing_tick": "Очікується збіг котирувань до кінця введення.", + "apps.error.parser.missing_submit": "Немає виклику відправлення в прив'язці або формі.", + "apps.error.parser.missing_tick": "Перед кінцем вхідного рядка очікується парний апостроф.", "apps.error.parser.multiple_equal": "Множинні знаки `=` не допускаються.", - "apps.error.parser.no_argument_pos_x": "Неможливо ідентифікувати аргумент.", - "apps.error.parser.no_bindings": "Ніяких прив'язок до команд.", + "apps.error.parser.no_argument_pos_x": "Не вдалося ідентифікувати аргумент.", + "apps.error.parser.no_bindings": "Відсутні прив'язки до команд.", "apps.error.parser.no_form": "Форму не знайдено.", - "apps.error.parser.no_match": "`{команда}`: У цій робочій області не знайдено відповідної команди.", + "apps.error.parser.no_match": "`{command}`: У цьому робочому просторі не знайдено відповідної команди.", "apps.error.parser.no_slash_start": "Команда повинна починатися з `/`.", "apps.error.parser.unexpected_character": "Несподіваний символ.", "apps.error.parser.unexpected_comma": "Несподівана кома.", "apps.error.parser.unexpected_error": "Несподівана помилка.", - "apps.error.parser.unexpected_flag": "Команда не приймає прапор `{Ім'я_прапора}`.", + "apps.error.parser.unexpected_flag": "Команда не приймає прапор `{flagName}`.", "apps.error.parser.unexpected_squared_bracket": "Несподіване відкриття списку.", - "apps.error.parser.unexpected_state": "Недосяжний: Неочікуваний стан у пов'язаних_збігах: `{стан}`.", - "apps.error.parser.unexpected_whitespace": "Недосяжний: Несподіваний пробіл.", + "apps.error.parser.unexpected_state": "Недоступно: Неочікуваний стан у matchBinding: `{state}`.", + "apps.error.parser.unexpected_whitespace": "Недоступно: Несподіваний пробіл.", "apps.error.responses.form.no_form": "Тип відповіді - `форма`, але до відповіді не було додано жодної форми.", - "apps.error.responses.navigate.no_url": "Тип відповіді - `навігація`, але у відповіді не було додано жодної адреси.", + "apps.error.responses.navigate.no_url": "Тип відповіді - `navigate`, але у відповіді не було додано жодної URL-адреси.", "apps.error.responses.unexpected_error": "Отримано неочікувану помилку.", - "apps.error.responses.unexpected_type": "Тип відповіді програми не очікувався. Тип відповіді: {тип}", - "apps.error.responses.unknown_field_error": "Отримано помилку для невідомого поля. Ім'я поля: `{поле}`. Помилка: `{помилка}`.", - "apps.error.responses.unknown_type": "Тип відповіді програми не підтримується. Тип відповіді: {тип}.", + "apps.error.responses.unexpected_type": "Тип відповіді застосунку не відповідає очікуваному. Тип відповіді: {type}", + "apps.error.responses.unknown_field_error": "Отримано помилку для невідомого поля. Назва поля: `{field}`. Помилка: `{error}`.", + "apps.error.responses.unknown_type": "Тип відповіді програми не підтримується. Тип відповіді: {type}.", "apps.error.unknown": "Виникла невідома помилка.", "apps.suggestion.dynamic.error": "Помилка динамічного вибору", "apps.suggestion.errors.parser_error": "Помилка аналізу", @@ -104,7 +104,7 @@ "channel_bookmark.add.file_upload_error": "Помилка при завантаженні файлу. Будь ласка, спробуйте ще раз.", "channel_bookmark.add.file_uploading": "Завантаження... ({progress}%)", "channel_bookmark.add_edit.failed_desc": "Деталі: {error}", - "channel_bookmark.copy_option": "Копіювати посилання", + "channel_bookmark.copy_option": "Скопіювати Посилання", "channel_bookmark.delete.confirm": "Ви дійсно хочете видалити закладку {displayName}?", "channel_bookmark.delete.confirm_title": "Видалити закладку", "channel_bookmark.delete.failed_detail": "Подробиці: {error}", @@ -133,7 +133,7 @@ "channel_info.alertNo": "Ні", "channel_info.alertYes": "Так", "channel_info.alert_retry": "Спробуйте ще раз", - "channel_info.archive": "Архівний канал", + "channel_info.archive": "Заархівувати канал", "channel_info.archive_description.can_view_archived": "Це призведе до архівування каналу від команди. Вміст каналу все ще буде доступним для учасників каналу.\n\nВи впевнені, що хочете заархівувати {термін} {назва}?", "channel_info.archive_description.cannot_view_archived": "Це заархівує канал з команди і видалить його з інтерфейсу користувача. Заархівовані канали можна розархівувати, якщо вони знадобляться знову.\n\nВи впевнені, що хочете заархівувати {термін} {назва}?", "channel_info.archive_failed": "Виникла помилка при спробі заархівувати канал {Ім'я_відображення}", @@ -164,13 +164,13 @@ "channel_info.convert_private_success": "{ім'я_відображення} тепер є приватним каналом.", "channel_info.convert_private_title": "Перетворити {ім'я_відображення} на приватний канал?", "channel_info.copied": "Скопійовано", - "channel_info.copy_link": "Скопіювати посилання", + "channel_info.copy_link": "Скопіювати Посилання", "channel_info.copy_purpose_text": "Копіювання тексту призначення", "channel_info.custom_status": "Особливий статус:", "channel_info.edit_header": "Редагувати заголовок", "channel_info.error_close": "Закрити", "channel_info.favorite": "Улюблене", - "channel_info.favorited": "Додано до вибраного", + "channel_info.favorited": "Додано до обраного", "channel_info.header": "Заголовок:", "channel_info.ignore_mentions": "Ігнорувати @channel, @here, @all", "channel_info.leave": "Покинути", @@ -178,7 +178,7 @@ "channel_info.leave_private_channel": "Ви впевнені, що хочете покинути приватний канал {ім'я_відображення}? Ви не зможете знову приєднатися до каналу, якщо вас не запросять знову.", "channel_info.leave_public_channel": "Ви впевнені, що хочете покинути публічний канал {displayName}? Ви завжди зможете знову приєднатися.", "channel_info.local_time": "Місцевий час", - "channel_info.members": "Учасники", + "channel_info.members": "Члени", "channel_info.mention": "Згадка", "channel_info.mobile_notifications": "Мобільні сповіщення", "channel_info.muted": "Вимкнути звук", @@ -203,8 +203,8 @@ "channel_intro.createdBy": "Створено {користувачем} {дата}", "channel_intro.createdOn": "Створено {дата}", "channel_list.channels_category": "Канали", - "channel_list.dms_category": "Прямі повідомлення", - "channel_list.favorites_category": "Вибрані", + "channel_list.dms_category": "Особисті повідомлення", + "channel_list.favorites_category": "Обране", "channel_list.find_channels": "Знайти канали...", "channel_loader.someone": "Хтось", "channel_modal.descriptionHelp": "Опишіть, як слід використовувати цей канал.", @@ -363,13 +363,13 @@ "general_settings.notifications": "Сповіщення", "general_settings.report_problem": "Повідомити про проблему", "generic.back": "Назад", - "get_post_link_modal.title": "Скопіювати посилання", + "get_post_link_modal.title": "Скопіювати Посилання", "global_threads.allThreads": "Всі твої потоки", "global_threads.emptyThreads.message": "Будь-які теми, в яких ви згадувалися або брали участь, будуть показані тут, а також теми, за якими ви стежили.", "global_threads.emptyThreads.title": "Ще немає потоків, за якими стежать", "global_threads.emptyUnreads.message": "Схоже, ви вже в курсі.", "global_threads.emptyUnreads.title": "Немає непрочитаних потоків", - "global_threads.markAllRead.cancel": "Відміна", + "global_threads.markAllRead.cancel": "Скасувати", "global_threads.markAllRead.markRead": "Позначити, як прочитане", "global_threads.markAllRead.message": "Це очистить статус непрочитаних для всіх ваших потоків, показаних тут", "global_threads.markAllRead.title": "Ви впевнені, що хочете позначити всі потоки як прочитані?", @@ -448,12 +448,14 @@ "login.password": "Пароль", "login.signIn": "Увійти", "login.signingIn": "Вхід у систему", - "login.username": "Ім'я користувача", + "login.username": "Логін", "login_mfa.enterToken": "Щоб завершити процес входу, будь ласка, введіть код з програми-автентифікатора вашого мобільного пристрою.", "login_mfa.token": "Введіть MFA Token", "login_mfa.tokenReq": "Будь-ласка, введіть токен MFA", "markdown.latex.error": "Помилка рендерингу Latex", "markdown.max_nodes.error": "Це повідомлення занадто довге для повного відображення на мобільному пристрої. Будь ласка, перегляньте його на комп'ютері або зверніться до адміністратора, щоб збільшити цей ліміт.", + "markdown.parse_error": "При розборі цього тексту сталася помилка", + "markdown.render_error": "Виникла помилка при відтворенні цього тексту", "mentions.empty.paragraph": "Тут ви побачите повідомлення, коли хтось згадає вас або використає терміни, які ви відстежуєте.", "mentions.empty.title": "Ще немає згадок", "mobile.about.appVersion": "Версія програми: {version} (Збірка {number})", @@ -484,7 +486,7 @@ "mobile.calls_end_permission_msg": "У вас немає дозволу на завершення виклику. Попросіть абонента завершити виклик.", "mobile.calls_end_permission_title": "Помилка", "mobile.calls_ended_at": "Закінчується на", - "mobile.calls_error_message": "Помилка: {Помилка}", + "mobile.calls_error_message": "Помилка: {error}", "mobile.calls_error_title": "Помилка", "mobile.calls_group_calls_not_available": "Дзвінки доступні тільки в приватних каналах.", "mobile.calls_headset": "Навушники", @@ -532,7 +534,7 @@ "mobile.calls_not_available_title": "Дзвінки не ввімкнено", "mobile.calls_not_connected": "Ви не підключені до виклику в поточному каналі.", "mobile.calls_ok": "ОК", - "mobile.calls_okay": "Добре", + "mobile.calls_okay": "Гаразд", "mobile.calls_open_channel": "Відкрити канал", "mobile.calls_participant_limit_title_GA": "Цей дзвінок вичерпав свій ліміт", "mobile.calls_participant_rec": "Ведучий розпочав запис цієї зустрічі. Залишаючись на зустрічі, ви даєте згоду на запис.", @@ -551,7 +553,7 @@ "mobile.calls_recording_start_no_permissions": "У вас немає дозволу на початок запису. Попросіть абонента розпочати запис.", "mobile.calls_recording_stop_no_permissions": "У вас немає дозволу на зупинку запису. Попросіть абонента зупинити запис.", "mobile.calls_recording_stop_none_in_progress": "Запис не ведеться.", - "mobile.calls_remove": "Видалити", + "mobile.calls_remove": "Вилучити", "mobile.calls_remove_alert_body": "Ви впевнені, що хочете видалити {displayName} з розмови? ", "mobile.calls_remove_alert_title": "Видалити учасника", "mobile.calls_remove_participant": "Видалити з виклику", @@ -681,7 +683,7 @@ "mobile.manage_members.section_title_admins": "АДМІНІСТРАЦІЯ КАНАЛУ", "mobile.manage_members.section_title_members": "УЧАСНИКИ", "mobile.managed.blocked_by": "Заблоковано {vendor}", - "mobile.managed.exit": "Вхід", + "mobile.managed.exit": "Вихід", "mobile.managed.jailbreak": "Пристрій з джейлбрейком або рутованою системою не довіряється {vendor}.\n\nДодаток зараз закриється.", "mobile.managed.not_secured.android": "Цей пристрій повинен бути захищений блокуванням екрана, щоб використовувати Mattermost.", "mobile.managed.not_secured.ios": "Щоб користуватися Mattermost, цей пристрій потрібно захистити паролем.\n\nПерейдіть до Налаштування > Face ID та пароль.", @@ -719,15 +721,15 @@ "mobile.participants.header": "Учасники потоку", "mobile.permission_denied_dismiss": "Не дозволяти", "mobile.permission_denied_retry": "Налаштування", - "mobile.post.cancel": "Відміна", + "mobile.post.cancel": "Скасувати", "mobile.post.delete_question": "Ви впевнені, що хочете видалити це повідомлення?", "mobile.post.delete_title": "Видалити публікацію", "mobile.post.failed_delete": "Видалити повідомлення", "mobile.post.failed_retry": "Спробуй ще раз", "mobile.post_info.add_reaction": "Додати реакцію", - "mobile.post_info.copy_text": "Копіювати текст", + "mobile.post_info.copy_text": "Копіювати Текст", "mobile.post_info.mark_unread": "Позначити непрочитаним", - "mobile.post_info.pin": "Прикріпити в каналі", + "mobile.post_info.pin": "Закріпити в каналі", "mobile.post_info.reply": "Відповідь", "mobile.post_info.save": "Зберегти", "mobile.post_info.unpin": "Відкріпити від каналу", @@ -735,7 +737,7 @@ "mobile.post_pre_header.pinned": "Закріплено", "mobile.post_pre_header.pinned_saved": "Закріплено та збережено", "mobile.post_pre_header.saved": "Збережено", - "mobile.post_textbox.entire_channel.cancel": "Відміна", + "mobile.post_textbox.entire_channel.cancel": "Скасувати", "mobile.post_textbox.entire_channel.confirm": "Підтвердьте", "mobile.post_textbox.entire_channel.message": "Використовуючи @all або @channel, ви збираєтеся надіслати сповіщення {totalMembers, number} {totalMembers, plural, one {людині} few {людям} other {людям}}. Ви впевнені, що хочете це зробити?", "mobile.post_textbox.entire_channel.message.with_timezones": "Використовуючи @all або @channel, ви збираєтеся надіслати сповіщення {totalMembers, number} {totalMembers, plural, one {людині} other {людям}} в {timezones, number} {timezones, plural, one {часовому поясі} other {часових поясах}}. Ви впевнені, що хочете це зробити?", @@ -754,7 +756,7 @@ "mobile.rename_channel.display_name_required": "Назва каналу є обов'язковою", "mobile.request.invalid_request_method": "Неправильний метод запиту", "mobile.request.invalid_response": "Отримано недійсну відповідь від сервера.", - "mobile.reset_status.alert_cancel": "Відміна", + "mobile.reset_status.alert_cancel": "Скасувати", "mobile.reset_status.alert_ok": "ОК", "mobile.reset_status.title_ooo": "Вимкнути \"Out Of Office\"?", "mobile.routes.code": "{language} код", @@ -806,7 +808,7 @@ "mobile.system_message.update_channel_purpose_message.updated_from": "{username} змінив(ла) заголовок каналу з {oldPurpose} на {newPurpose}", "mobile.system_message.update_channel_purpose_message.updated_to": "{username} встановив(ла) заголовок каналу: {newPurpose}", "mobile.tos_link": "Умови обслуговування", - "mobile.user_list.deactivated": "Деактивувати", + "mobile.user_list.deactivated": "Деактивований", "mobile.write_storage_permission_denied_description": "Збережіть файли на своєму пристрої. Відкрийте Налаштування, щоб надати {назва_програми} доступ на запис до файлів на цьому пристрої.", "modal.manual_status.auto_responder.message_": "Ви хочете змінити свій статус на \"{status}\" і вимкнути автоматичні відповіді?", "modal.manual_status.auto_responder.message_away": "Ви хочете змінити свій статус на \"Далеко\" і вимкнути автоматичні відповіді?", @@ -886,7 +888,7 @@ "password_send.generic_error": "Ми не змогли надіслати вам посилання для скидання пароля. Будь ласка, зверніться за допомогою до вашого системного адміністратора.", "password_send.link": "Якщо обліковий запис існує, електронний лист для зміни пароля буде надіслано на адресу:", "password_send.link.title": "Надіслано посилання для скидання", - "password_send.reset": "Скинути пароль", + "password_send.reset": "Скинути Ваш пароль", "password_send.return": "Повернутися до входу в систему", "permalink.error.access.text": "Повідомлення, яке ви намагаєтеся переглянути, знаходиться в каналі, до якого у вас немає доступу, або було видалено.", "permalink.error.access.title": "Повідомлення недоступне для перегляду", @@ -904,7 +906,7 @@ "permalink.error.public_channel_and_team.button": "Приєднуйтесь до каналу та команди", "permalink.error.public_channel_and_team.text": "Повідомлення, яке ви намагаєтеся переглянути, знаходиться в каналі, до якого ви не належите, і в команді, членом якої ви не є. Ви хочете приєднатися до **{Назва_каналу}** та команди **{Назва_команди}**, щоб переглянути його?", "permalink.error.public_channel_and_team.title": "Приєднуйтесь до каналу та команди", - "permalink.show_dialog_warn.cancel": "Відміна", + "permalink.show_dialog_warn.cancel": "Скасувати", "permalink.show_dialog_warn.description": "Ви збираєтеся приєднатися до {каналу} без явного додавання адміністратором каналу. Ви впевнені, що хочете приєднатися до цього приватного каналу?", "permalink.show_dialog_warn.join": "Приєднатися", "permalink.show_dialog_warn.title": "Приєднуйтесь до приватного каналу", @@ -1027,7 +1029,7 @@ "servers.edit": "Редагувати", "servers.login": "Авторизуватися", "servers.logout": "Вийти", - "servers.remove": "Видалити", + "servers.remove": "Вилучити", "settings.about": "Про {appTitle}", "settings.about.app.version": "Версія додатку: {version} (Збірка {number})", "settings.about.app.version.title": "Версія додатку:", @@ -1044,7 +1046,7 @@ "settings.about.server.version.noBuild": "Версія сервера: {version}", "settings.about.server.version.title": "Версія сервера:", "settings.about.server.version.value": "{version} (Збірка {buildNumber})", - "settings.advanced.cancel": "Відмінити", + "settings.advanced.cancel": "Скасувати", "settings.advanced.delete": "Видалити", "settings.advanced.delete_data": "Видалення локальних файлів", "settings.advanced.delete_message.confirmation": "\nЦе призведе до видалення всіх файлів, завантажених через додаток для цього сервера. Будь ласка, підтвердіть, щоб продовжити.\n", @@ -1119,7 +1121,7 @@ "suggestion.mention.nonmembers": "Не в каналі", "suggestion.mention.special": "Особливі згадки", "suggestion.mention.users": "Користувачі", - "suggestion.search.direct": "Особисті повідомлення", + "suggestion.search.direct": "Особисті Повідомлення", "suggestion.search.private": "Приватні канали", "suggestion.search.public": "Публічні канали", "system_notice.dont_show": "Не показувати знову", @@ -1134,7 +1136,7 @@ "terms_of_service.api_error": "Не вдалося завершити запит. Якщо ця проблема не зникає, зверніться до системного адміністратора.", "terms_of_service.decline": "Відхилити", "terms_of_service.error.description": "Не вдалося отримати Умови обслуговування з сервера.", - "terms_of_service.error.logout": "Вихід", + "terms_of_service.error.logout": "Вийти з системи", "terms_of_service.error.retry": "Спробувати знову", "terms_of_service.error.title": "Не вдалося отримати Умови обслуговування(ToS).", "terms_of_service.terms_declined.ok": "ОК", @@ -1171,10 +1173,17 @@ "user.settings.general.lastName": "Прізвище", "user.settings.general.nickname": "Псевдонім", "user.settings.general.position": "Посада", - "user.settings.general.username": "Ім'я користувача", + "user.settings.general.username": "Логін", "user.settings.notifications.email_threads.description": "Сповіщати мене про всі відповіді в обговореннях, за якими я стежу", "user.tutorial.long_press": "Затисніть елемент, щоб переглянути профіль користувача", "user_profile.custom_status": "Користувацький статус", + "user_settings.notifications.test_notification.body": "Не отримуєте сповіщення? Почніть з надсилання тестового сповіщення на всі ваші пристрої, щоб перевірити, чи працюють вони належним чином. Якщо проблема не зникає - спробуйте вирішити їх за допомогою кроків з усунення несправностей.", + "user_settings.notifications.test_notification.go_to_docs": "Документація з усунення несправностей", + "user_settings.notifications.test_notification.send_button.error": "Помилка надсилання тестового сповіщення", + "user_settings.notifications.test_notification.send_button.send": "Надіслати тестове сповіщення", + "user_settings.notifications.test_notification.send_button.sending": "Надсилання тестового сповіщення", + "user_settings.notifications.test_notification.send_button.sent": "Тестове сповіщення відправлено", + "user_settings.notifications.test_notification.title": "Усунення несправностей з сповіщеннями", "user_status.away": "Відійшов", "user_status.dnd": "Не турбувати", "user_status.offline": "Не в мережі", From 37fd1609c71f94056c11efeebee77882145aa2c5 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Tue, 19 Nov 2024 08:36:47 +0800 Subject: [PATCH 08/36] fix screen position for server / login / forgot password & mfa (#8340) * fix screen position for server / login / forgot password & mfa * refactor to use a hook * fix scroll to offset not to height * feedback review --- app/hooks/device.ts | 14 +++++++ app/screens/forgot_password/index.tsx | 26 +++---------- app/screens/index.tsx | 2 +- app/screens/login/form.tsx | 11 ++++-- app/screens/login/index.tsx | 13 ++++--- app/screens/mfa/index.tsx | 24 +++--------- app/screens/server/form.tsx | 55 +++------------------------ app/screens/server/index.tsx | 3 +- 8 files changed, 48 insertions(+), 100 deletions(-) diff --git a/app/hooks/device.ts b/app/hooks/device.ts index 410437b01b2..72266b0b3a3 100644 --- a/app/hooks/device.ts +++ b/app/hooks/device.ts @@ -9,6 +9,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'; import {DeviceContext} from '@context/device'; import type {KeyboardTrackingViewRef, KeyboardWillShowEventData} from '@mattermost/keyboard-tracker'; +import type {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view'; const utilsEmitter = new NativeEventEmitter(RNUtils); @@ -147,3 +148,16 @@ export function useKeyboardOverlap(viewRef: RefObject, containerHeight: nu return overlap; } + +export function useAvoidKeyboard(ref: RefObject, dimisher = 3) { + const height = useKeyboardHeight(); + + useEffect(() => { + let offsetY = height / dimisher; + if (offsetY < 80) { + offsetY = 0; + } + + ref.current?.scrollToPosition(0, offsetY); + }, [height, dimisher, ref]); +} diff --git a/app/screens/forgot_password/index.tsx b/app/screens/forgot_password/index.tsx index 24a64a1ffac..480275ec538 100644 --- a/app/screens/forgot_password/index.tsx +++ b/app/screens/forgot_password/index.tsx @@ -15,7 +15,7 @@ import FloatingTextInput from '@components/floating_text_input_label'; import FormattedText from '@components/formatted_text'; import {Screens} from '@constants'; import useAndroidHardwareBackHandler from '@hooks/android_back_handler'; -import {useIsTablet} from '@hooks/device'; +import {useAvoidKeyboard} from '@hooks/device'; import Background from '@screens/background'; import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles'; import {isEmail} from '@utils/helpers'; @@ -93,7 +93,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ const ForgotPassword = ({componentId, serverUrl, theme}: Props) => { const dimensions = useWindowDimensions(); const translateX = useSharedValue(dimensions.width); - const isTablet = useIsTablet(); const [email, setEmail] = useState(''); const [error, setError] = useState(''); const [isPasswordLinkSent, setIsPasswordLinkSent] = useState(false); @@ -101,25 +100,13 @@ const ForgotPassword = ({componentId, serverUrl, theme}: Props) => { const keyboardAwareRef = useRef(null); const styles = getStyleSheet(theme); + useAvoidKeyboard(keyboardAwareRef); + const changeEmail = useCallback((emailAddress: string) => { setEmail(emailAddress); setError(''); }, []); - const onFocus = useCallback(() => { - if (Platform.OS === 'ios') { - let offsetY = 150; - if (isTablet) { - const {width, height} = dimensions; - const isLandscape = width > height; - offsetY = (isLandscape ? 230 : 150); - } - requestAnimationFrame(() => { - keyboardAwareRef.current?.scrollToPosition(0, offsetY); - }); - } - }, [dimensions]); - const onReturn = useCallback(() => { Navigation.popTo(Screens.LOGIN); }, []); @@ -146,7 +133,7 @@ const ForgotPassword = ({componentId, serverUrl, theme}: Props) => { id: 'password_send.generic_error', defaultMessage: 'We were unable to send you a reset password link. Please contact your System Admin for assistance.', })); - }, [email]); + }, [email, formatMessage, serverUrl]); const getCenterContent = () => { if (isPasswordLinkSent) { @@ -188,7 +175,7 @@ const ForgotPassword = ({componentId, serverUrl, theme}: Props) => { { keyboardType='email-address' label={formatMessage({id: 'login.email', defaultMessage: 'Email'})} onChangeText={changeEmail} - onFocus={onFocus} onSubmitEditing={submitResetPassword} returnKeyType='next' spellCheck={false} @@ -270,7 +256,7 @@ const ForgotPassword = ({componentId, serverUrl, theme}: Props) => { const unsubscribe = Navigation.events().registerComponentListener(listener, componentId); return () => unsubscribe.remove(); - }, [dimensions]); + }, [componentId, dimensions]); useEffect(() => { translateX.value = 0; diff --git a/app/screens/index.tsx b/app/screens/index.tsx index 839f539114c..30e9b206825 100644 --- a/app/screens/index.tsx +++ b/app/screens/index.tsx @@ -295,6 +295,6 @@ export function registerScreens() { const serverScreen = require('@screens/server').default; const onboardingScreen = require('@screens/onboarding').default; Navigation.registerComponent(Screens.ONBOARDING, () => withGestures(withIntl(withManagedConfig(onboardingScreen)), undefined)); - Navigation.registerComponent(Screens.SERVER, () => withGestures(withIntl(withManagedConfig(serverScreen)), undefined)); + Navigation.registerComponent(Screens.SERVER, () => withSafeAreaInsets(withGestures(withIntl(withManagedConfig(serverScreen)), undefined))); Navigation.registerComponent(Screens.HOME, () => withGestures(withSafeAreaInsets(withServerDatabase(withManagedConfig(homeScreen))), undefined)); } diff --git a/app/screens/login/form.tsx b/app/screens/login/form.tsx index 025d13a4852..325a5896188 100644 --- a/app/screens/login/form.tsx +++ b/app/screens/login/form.tsx @@ -3,7 +3,7 @@ import {useManagedConfig} from '@mattermost/react-native-emm'; import {Button} from '@rneui/base'; -import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; +import React, {useCallback, useEffect, useMemo, useRef, useState, type RefObject} from 'react'; import {useIntl} from 'react-intl'; import {Keyboard, TextInput, TouchableOpacity, View} from 'react-native'; @@ -13,6 +13,7 @@ import FloatingTextInput from '@components/floating_text_input_label'; import FormattedText from '@components/formatted_text'; import Loading from '@components/loading'; import {FORGOT_PASSWORD, MFA} from '@constants/screens'; +import {useAvoidKeyboard} from '@hooks/device'; import {t} from '@i18n'; import {goToScreen, loginAnimationOptions, resetToHome} from '@screens/navigation'; import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles'; @@ -22,10 +23,12 @@ import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; import {tryOpenURL} from '@utils/url'; import type {LaunchProps} from '@typings/launch'; +import type {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view'; interface LoginProps extends LaunchProps { config: Partial; license: Partial; + keyboardAwareRef: RefObject; serverDisplayName: string; theme: Theme; } @@ -77,7 +80,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ }, })); -const LoginForm = ({config, extra, serverDisplayName, launchError, launchType, license, serverUrl, theme}: LoginProps) => { +const LoginForm = ({config, extra, keyboardAwareRef, serverDisplayName, launchError, launchType, license, serverUrl, theme}: LoginProps) => { const styles = getStyleSheet(theme); const loginRef = useRef(null); const passwordRef = useRef(null); @@ -93,6 +96,8 @@ const LoginForm = ({config, extra, serverDisplayName, launchError, launchType, l const usernameEnabled = config.EnableSignInWithUsername === 'true'; const ldapEnabled = license.IsLicensed === 'true' && config.EnableLdap === 'true' && license.LDAP === 'true'; + useAvoidKeyboard(keyboardAwareRef); + const preSignIn = preventDoubleTap(async () => { setIsLoading(true); @@ -222,7 +227,7 @@ const LoginForm = ({config, extra, serverDisplayName, launchError, launchType, l }; goToScreen(FORGOT_PASSWORD, '', passProps, loginAnimationOptions()); - }, [theme]); + }, [config.ForgotPasswordLink, serverUrl, theme]); const togglePasswordVisiblity = useCallback(() => { setIsPasswordVisible((prevState) => !prevState); diff --git a/app/screens/login/index.tsx b/app/screens/login/index.tsx index cbda077076b..f56f43644ea 100644 --- a/app/screens/login/index.tsx +++ b/app/screens/login/index.tsx @@ -119,7 +119,7 @@ const LoginOptions = ({ defaultMessage="You can't log in to your account yet. At least one login option must be configured. Contact your System Admin for assistance." /> ); - }, [hasLoginForm, numberSSOs, theme]); + }, [hasLoginForm, numberSSOs, styles.subheader]); const goToSso = preventDoubleTap((ssoType: string) => { goToScreen(Screens.SSO, '', {config, extra, launchError, launchType, license, theme, ssoType, serverDisplayName, serverUrl}, loginAnimationOptions()); @@ -160,7 +160,7 @@ const LoginOptions = ({ }); return () => navigationEvents.remove(); - }, []); + }, [closeButtonId, componentId, serverUrl]); useEffect(() => { translateX.value = 0; @@ -178,7 +178,7 @@ const LoginOptions = ({ const unsubscribe = Navigation.events().registerComponentListener(listener, Screens.LOGIN); return () => unsubscribe.remove(); - }, [dimensions]); + }, [dimensions, translateX]); useNavButtonPressed(closeButtonId || '', componentId, dismiss, []); useAndroidHardwareBackHandler(componentId, pop); @@ -219,11 +219,11 @@ const LoginOptions = ({ { const dimensions = useWindowDimensions(); const translateX = useSharedValue(dimensions.width); - const isTablet = useIsTablet(); const keyboardAwareRef = useRef(null); const intl = useIntl(); const [token, setToken] = useState(''); @@ -109,20 +108,6 @@ const MFA = ({componentId, config, goToHome, license, loginId, password, serverD const styles = getStyleSheet(theme); - const onFocus = useCallback(() => { - if (Platform.OS === 'ios') { - let offsetY = 150; - if (isTablet) { - const {width, height} = dimensions; - const isLandscape = width > height; - offsetY = (isLandscape ? 270 : 150); - } - requestAnimationFrame(() => { - keyboardAwareRef.current?.scrollToPosition(0, offsetY); - }); - } - }, [dimensions]); - const handleInput = useCallback((userToken: string) => { setToken(userToken); setError(''); @@ -156,6 +141,8 @@ const MFA = ({componentId, config, goToHome, license, loginId, password, serverD }; }, []); + useAvoidKeyboard(keyboardAwareRef, 2); + useEffect(() => { const listener = { componentDidAppear: () => { @@ -168,7 +155,7 @@ const MFA = ({componentId, config, goToHome, license, loginId, password, serverD const unsubscribe = Navigation.events().registerComponentListener(listener, componentId); return () => unsubscribe.remove(); - }, [dimensions]); + }, [componentId, dimensions, translateX]); useEffect(() => { translateX.value = 0; @@ -190,7 +177,7 @@ const MFA = ({componentId, config, goToHome, license, loginId, password, serverD void; handleDisplayNameTextChanged: (text: string) => void; handleUrlTextChanged: (text: string) => void; - isModal?: boolean; - keyboardAwareRef: MutableRefObject; + keyboardAwareRef: RefObject; theme: Theme; url?: string; urlError?: string; @@ -79,65 +78,27 @@ const ServerForm = ({ handleConnect, handleDisplayNameTextChanged, handleUrlTextChanged, - isModal, keyboardAwareRef, theme, url = '', urlError, }: Props) => { const {formatMessage} = useIntl(); - const isTablet = useIsTablet(); - const dimensions = useWindowDimensions(); const displayNameRef = useRef(null); const urlRef = useRef(null); const styles = getStyleSheet(theme); - const focus = () => { - if (Platform.OS === 'ios') { - let offsetY = isModal ? 120 : 160; - if (isTablet) { - const {width, height} = dimensions; - const isLandscape = width > height; - offsetY = isLandscape ? 230 : 100; - } - requestAnimationFrame(() => { - keyboardAwareRef.current?.scrollToPosition(0, offsetY); - }); - } - }; - - const onBlur = useCallback(() => { - if (Platform.OS === 'ios') { - const reset = !displayNameRef.current?.isFocused() && !urlRef.current?.isFocused(); - if (reset) { - keyboardAwareRef.current?.scrollToPosition(0, 0); - } - } - }, []); + useAvoidKeyboard(keyboardAwareRef); const onConnect = useCallback(() => { Keyboard.dismiss(); handleConnect(); - }, [buttonDisabled, connecting, displayName, theme, url]); - - const onFocus = useCallback(() => { - focus(); - }, [dimensions]); + }, [handleConnect]); const onUrlSubmit = useCallback(() => { displayNameRef.current?.focus(); }, []); - useEffect(() => { - if (Platform.OS === 'ios' && isTablet) { - if (urlRef.current?.isFocused() || displayNameRef.current?.isFocused()) { - focus(); - } else { - keyboardAwareRef.current?.scrollToPosition(0, 0); - } - } - }, [dimensions, isTablet]); - const buttonType = buttonDisabled ? 'disabled' : 'default'; const styleButtonText = buttonTextStyle(theme, 'lg', 'primary', buttonType); const styleButtonBackground = buttonBackgroundStyle(theme, 'lg', 'primary', buttonType); @@ -176,9 +137,7 @@ const ServerForm = ({ id: 'mobile.components.select_server_view.enterServerUrl', defaultMessage: 'Enter Server URL', })} - onBlur={onBlur} onChangeText={handleUrlTextChanged} - onFocus={onFocus} onSubmitEditing={onUrlSubmit} ref={urlRef} returnKeyType='next' @@ -198,9 +157,7 @@ const ServerForm = ({ id: 'mobile.components.select_server_view.displayName', defaultMessage: 'Display Name', })} - onBlur={onBlur} onChangeText={handleDisplayNameTextChanged} - onFocus={onFocus} onSubmitEditing={onConnect} ref={displayNameRef} returnKeyType='done' diff --git a/app/screens/server/index.tsx b/app/screens/server/index.tsx index 1ff20c262f2..41ec13d3525 100644 --- a/app/screens/server/index.tsx +++ b/app/screens/server/index.tsx @@ -376,7 +376,7 @@ const Server = ({ Date: Tue, 19 Nov 2024 17:43:35 +0800 Subject: [PATCH 09/36] bump cross-spawn (#8357) --- package-lock.json | 266 +++++----------------------------------------- 1 file changed, 24 insertions(+), 242 deletions(-) diff --git a/package-lock.json b/package-lock.json index f52d439905f..9e3d760a6ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4533,26 +4533,12 @@ "integrity": "sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==", "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3" + "cross-spawn": "^7.0.6" }, "engines": { "node": ">=12" } }, - "node_modules/@expo/spawn-async/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@expo/vector-icons": { "version": "14.0.2", "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-14.0.2.tgz", @@ -12360,6 +12346,20 @@ "node-fetch": "^2.6.12" } }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", @@ -12669,29 +12669,13 @@ "node": ">=6" } }, - "node_modules/default-gateway/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "license": "MIT", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, "node_modules/default-gateway/node_modules/execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "license": "MIT", "dependencies": { - "cross-spawn": "^6.0.0", + "cross-spawn": "^7.0.6", "get-stream": "^4.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", @@ -12745,48 +12729,6 @@ "node": ">=4" } }, - "node_modules/default-gateway/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/default-gateway/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -13510,7 +13452,7 @@ "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", @@ -14026,20 +13968,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/eslint/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/eslint/node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -14340,7 +14268,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dependencies": { - "cross-spawn": "^7.0.3", + "cross-spawn": "^7.0.6", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", @@ -14357,19 +14285,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -15153,7 +15068,7 @@ "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -15163,20 +15078,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/foreground-child/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/foreground-child/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -20964,11 +20865,6 @@ "integrity": "sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==", "license": "MIT" }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, "node_modules/nocache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/nocache/-/nocache-3.0.4.tgz", @@ -21461,27 +21357,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/os-locale/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "peer": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/os-locale/node_modules/execa": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "peer": true, "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "get-stream": "^5.0.0", "human-signals": "^1.1.1", "is-stream": "^2.0.0", @@ -21741,21 +21623,7 @@ "license": "0BSD", "dependencies": { "ansi-escapes": "^4.3.2", - "cross-spawn": "^7.0.3" - } - }, - "node_modules/password-prompt/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" + "cross-spawn": "^7.0.6" } }, "node_modules/patch-package": { @@ -21767,7 +21635,7 @@ "@yarnpkg/lockfile": "^1.1.0", "chalk": "^4.1.2", "ci-info": "^3.7.0", - "cross-spawn": "^7.0.3", + "cross-spawn": "^7.0.6", "find-yarn-workspace-root": "^2.0.0", "fs-extra": "^9.0.0", "json-stable-stringify": "^1.0.2", @@ -21837,20 +21705,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/patch-package/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/patch-package/node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -27392,29 +27246,13 @@ "node": ">=8" } }, - "node_modules/username/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "peer": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, "node_modules/username/node_modules/execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "peer": true, "dependencies": { - "cross-spawn": "^6.0.0", + "cross-spawn": "^7.0.6", "get-stream": "^4.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", @@ -27482,48 +27320,6 @@ "node": ">=4" } }, - "node_modules/username/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "peer": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/username/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "peer": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/username/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/username/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "peer": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -27711,7 +27507,7 @@ "@webpack-cli/serve": "^1.7.0", "colorette": "^2.0.14", "commander": "^7.0.0", - "cross-spawn": "^7.0.3", + "cross-spawn": "^7.0.6", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", "interpret": "^2.2.0", @@ -27761,20 +27557,6 @@ "node": ">= 10" } }, - "node_modules/webpack-cli/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/webpack-merge": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", From 9b450cf68b60b47ebcb4ca84af9cc07293397567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Vay=C3=A1?= Date: Tue, 19 Nov 2024 11:19:57 +0100 Subject: [PATCH 10/36] prevent overlap of clear button, fix font, reduce space on recent statuses (#8322) * prevent overlap of clear button, fix font, reduce space on recent statuses * remove font size * prevent newlines on android external keyboard * move to reducer action * change newline behaviour to space --- .../custom_status/components/custom_status_input.tsx | 12 ++++-------- .../custom_status_suggestion.tsx | 4 +++- app/screens/custom_status/custom_status.tsx | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/screens/custom_status/components/custom_status_input.tsx b/app/screens/custom_status/components/custom_status_input.tsx index bac11f81d5e..42d82bb50d5 100644 --- a/app/screens/custom_status/components/custom_status_input.tsx +++ b/app/screens/custom_status/components/custom_status_input.tsx @@ -8,6 +8,7 @@ import {TextInput, View} from 'react-native'; import ClearButton from '@components/custom_status/clear_button'; import {CUSTOM_STATUS_TEXT_CHARACTER_LIMIT} from '@constants/custom_status'; import {changeOpacity, getKeyboardAppearanceFromTheme, makeStyleSheetFromTheme} from '@utils/theme'; +import {typography} from '@utils/typography'; import CustomStatusEmoji from './custom_status_emoji'; @@ -29,24 +30,19 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { marginRight: 16, marginLeft: 52, }, - clearButton: { - position: 'absolute', - top: 3, - right: 14, - }, input: { alignSelf: 'stretch', color: theme.centerChannelColor, flex: 1, - fontSize: 17, paddingHorizontal: 16, textAlignVertical: 'center', height: '100%', + ...typography('Body', 200, 'Regular'), }, inputContainer: { justifyContent: 'center', alignItems: 'center', - height: 48, + height: 80, backgroundColor: theme.centerChannelBg, flexDirection: 'row', }, @@ -83,11 +79,11 @@ const CustomStatusInput = ({emoji, isStatusSet, onChangeText, onClearHandle, onO style={style.input} secureTextEntry={false} underlineColorAndroid='transparent' + multiline={true} value={text} /> {isStatusSet ? ( { paddingTop: 14, paddingBottom: 14, justifyContent: 'center', - width: '70%', + width: '93%', flex: 1, }, divider: { @@ -57,6 +58,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { }, customStatusText: { color: theme.centerChannelColor, + ...typography('Body', 200, 'Regular'), }, }; }); diff --git a/app/screens/custom_status/custom_status.tsx b/app/screens/custom_status/custom_status.tsx index 5422c315de6..361c9e6d952 100644 --- a/app/screens/custom_status/custom_status.tsx +++ b/app/screens/custom_status/custom_status.tsx @@ -128,7 +128,7 @@ function reducer(state: NewStatusType, action: { return state; } case 'text': - return {...state, text: action.value}; + return {...state, text: action.value?.replace('\n', ' ')}; case 'emoji': return {...state, emoji: action.value}; case 'duration': From d259fb00b4893286f708f45bd17e7e94ef5c70b4 Mon Sep 17 00:00:00 2001 From: "unified-ci-app[bot]" <121569378+unified-ci-app[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 13:13:20 +0100 Subject: [PATCH 11/36] Bump app build and version number (#8364) * Bump app build number to 576 * Bump app version number to 2.23.0 --------- Co-authored-by: runner --- android/app/build.gradle | 4 ++-- ios/Mattermost.xcodeproj/project.pbxproj | 8 ++++---- ios/Mattermost/Info.plist | 4 ++-- ios/MattermostShare/Info.plist | 4 ++-- ios/NotificationService/Info.plist | 4 ++-- package-lock.json | 2 +- package.json | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 2c5dcfd5a75..35747177aed 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -111,8 +111,8 @@ android { applicationId "com.mattermost.rnbeta" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 575 - versionName "2.22.0" + versionCode 576 + versionName "2.23.0" testBuildType System.getProperty('testBuildType', 'debug') testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } diff --git a/ios/Mattermost.xcodeproj/project.pbxproj b/ios/Mattermost.xcodeproj/project.pbxproj index 649483d979a..741f49bf85c 100644 --- a/ios/Mattermost.xcodeproj/project.pbxproj +++ b/ios/Mattermost.xcodeproj/project.pbxproj @@ -1984,7 +1984,7 @@ CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 575; + CURRENT_PROJECT_VERSION = 576; DEVELOPMENT_TEAM = UQ8HT4Q2XM; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = "$(inherited)"; @@ -2026,7 +2026,7 @@ CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 575; + CURRENT_PROJECT_VERSION = 576; DEVELOPMENT_TEAM = UQ8HT4Q2XM; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = "$(inherited)"; @@ -2169,7 +2169,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 575; + CURRENT_PROJECT_VERSION = 576; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = UQ8HT4Q2XM; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2219,7 +2219,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 575; + CURRENT_PROJECT_VERSION = 576; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = UQ8HT4Q2XM; GCC_C_LANGUAGE_STANDARD = gnu11; diff --git a/ios/Mattermost/Info.plist b/ios/Mattermost/Info.plist index 64696aca29c..1b78a280637 100644 --- a/ios/Mattermost/Info.plist +++ b/ios/Mattermost/Info.plist @@ -21,7 +21,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.22.0 + 2.23.0 CFBundleSignature ???? CFBundleURLTypes @@ -37,7 +37,7 @@ CFBundleVersion - 575 + 576 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/ios/MattermostShare/Info.plist b/ios/MattermostShare/Info.plist index 11577dbf3ed..bde83abb689 100644 --- a/ios/MattermostShare/Info.plist +++ b/ios/MattermostShare/Info.plist @@ -19,9 +19,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 2.22.0 + 2.23.0 CFBundleVersion - 575 + 576 UIAppFonts OpenSans-Bold.ttf diff --git a/ios/NotificationService/Info.plist b/ios/NotificationService/Info.plist index 1dc200eff87..fa1b423644b 100644 --- a/ios/NotificationService/Info.plist +++ b/ios/NotificationService/Info.plist @@ -19,9 +19,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 2.22.0 + 2.23.0 CFBundleVersion - 575 + 576 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 9e3d760a6ae..d7a5d4ccd6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "mattermost-mobile", - "version": "2.22.0", + "version": "2.23.0", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index 3ca3e2a2aef..bf9a592feae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mattermost-mobile", - "version": "2.22.0", + "version": "2.23.0", "description": "Mattermost Mobile with React Native", "repository": "git@github.com:mattermost/mattermost-mobile.git", "author": "Mattermost, Inc.", From f803edfbf4cd3ce23f7887125eefa561670a348f Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Thu, 21 Nov 2024 08:16:19 -0500 Subject: [PATCH 12/36] Increase branch test coverage to over 80% for actions/local (#8366) --- app/actions/local/category.test.ts | 27 ++++++++-- app/actions/local/draft.test.ts | 18 +++++-- app/actions/local/file.test.ts | 22 ++++++++- app/actions/local/group.test.ts | 34 +++++++++++++ app/actions/local/post.test.ts | 44 ++++++++++++----- app/actions/local/systems.test.ts | 79 ++++++++++++++++++++++++++++++ app/actions/local/thread.test.ts | 67 ++++++++++++++++++++++--- 7 files changed, 263 insertions(+), 28 deletions(-) diff --git a/app/actions/local/category.test.ts b/app/actions/local/category.test.ts index 21326e71df5..7c785519905 100644 --- a/app/actions/local/category.test.ts +++ b/app/actions/local/category.test.ts @@ -14,6 +14,7 @@ import { } from './category'; import type ServerDataOperator from '@database/operator/server_data_operator'; +import type ChannelModel from '@typings/database/models/servers/channel'; describe('handleConvertedGMCategories', () => { const serverUrl = 'baseHandler.test.com'; @@ -66,7 +67,7 @@ describe('handleConvertedGMCategories', () => { }; await operator.handleCategoryChannels({categoryChannels: [dmCategoryChannel, customCategoryChannel], prepareRecordsOnly: false}); - const {models, error} = await handleConvertedGMCategories(serverUrl, channelId, teamId1, true); + const {models, error} = await handleConvertedGMCategories(serverUrl, channelId, teamId1); expect(error).toBeUndefined(); expect(models).toBeDefined(); expect(models!.length).toBe(3); // two for removing channel for a custom and a DM category, and one for adding it to default channels category @@ -83,7 +84,7 @@ describe('handleConvertedGMCategories', () => { }); it('error - database not prepared', async () => { - const {error} = await handleConvertedGMCategories(serverUrl, channelId, teamId1, true); + const {error} = await handleConvertedGMCategories('', channelId, teamId1, true); expect(error).toBeDefined(); }); }); @@ -124,6 +125,11 @@ describe('category crud', () => { expect(error2).toBeUndefined(); }); + it('deleteCategory - handle database not found', async () => { + const {error} = await deleteCategory('', ''); + expect(error).toBeDefined(); + }); + it('storeCategories', async () => { const defaultCategory: CategoryWithChannels = { id: 'default_category_id', @@ -143,6 +149,11 @@ describe('category crud', () => { expect(models!.length).toBe(3); }); + it('storeCategories - handle database not found', async () => { + const {error} = await storeCategories('', []); + expect(error).toBeDefined(); + }); + it('toggleCollapseCategory', async () => { const defaultCategory: Category = { id: 'default_category_id', @@ -163,6 +174,11 @@ describe('category crud', () => { expect(categoryResult2).toBeDefined(); expect(categoryResult2?.collapsed).toBe(defaultCategory.collapsed); }); + + it('toggleCollapseCategory - handle database not found', async () => { + const {error} = await toggleCollapseCategory('', ''); + expect(error).toBeDefined(); + }); }); describe('addChannelToDefaultCategory', () => { @@ -221,6 +237,11 @@ describe('addChannelToDefaultCategory', () => { expect(dmError).toBeUndefined(); expect(dmModels).toBeDefined(); expect(dmModels!.length).toBe(1); // one for the dm channel + + const {models: channelModels, error: channelModelError} = await addChannelToDefaultCategory(serverUrl, {teamId: teamId1, id: channelId} as ChannelModel); + expect(channelModelError).toBeUndefined(); + expect(channelModels).toBeDefined(); + expect(channelModels!.length).toBe(1); // one for the channel }); it('error - no current user', async () => { @@ -233,7 +254,7 @@ describe('addChannelToDefaultCategory', () => { }); it('error - database not prepared', async () => { - const {error} = await addChannelToDefaultCategory(serverUrl, channel); + const {error} = await addChannelToDefaultCategory('', channel); expect(error).toBeDefined(); }); }); diff --git a/app/actions/local/draft.test.ts b/app/actions/local/draft.test.ts index faae4a98e0d..a876c450148 100644 --- a/app/actions/local/draft.test.ts +++ b/app/actions/local/draft.test.ts @@ -70,7 +70,7 @@ describe('updateDraftFile', () => { it('update draft file', async () => { await operator.handleDraft({drafts: [{...draft, files: [{...fileInfo, localPath: 'path0'}]}], prepareRecordsOnly: false}); - const {draft: draftModel, error} = await updateDraftFile(serverUrl, channelId, '', fileInfo, false); + const {draft: draftModel, error} = await updateDraftFile(serverUrl, channelId, '', fileInfo); expect(error).toBeUndefined(); expect(draftModel).toBeDefined(); expect(draftModel?.files?.length).toBe(1); @@ -101,7 +101,7 @@ describe('removeDraftFile', () => { it('remove draft file', async () => { await operator.handleDraft({drafts: [{...draft, files: [fileInfo]}], prepareRecordsOnly: false}); - const {draft: draftModel, error} = await removeDraftFile(serverUrl, channelId, '', 'clientid', false); + const {draft: draftModel, error} = await removeDraftFile(serverUrl, channelId, '', 'clientid'); expect(error).toBeUndefined(); expect(draftModel).toBeDefined(); }); @@ -137,7 +137,7 @@ describe('updateDraftMessage', () => { it('update draft message', async () => { await operator.handleDraft({drafts: [{...draft, files: [fileInfo]}], prepareRecordsOnly: false}); - const result = await updateDraftMessage(serverUrl, channelId, '', 'newmessage', false) as {draft: DraftModel; error: unknown}; + const result = await updateDraftMessage(serverUrl, channelId, '', 'newmessage') as {draft: DraftModel; error: unknown}; expect(result.error).toBeUndefined(); expect(result.draft).toBeDefined(); expect(result.draft.message).toBe('newmessage'); @@ -178,7 +178,7 @@ describe('addFilesToDraft', () => { it('add draft files', async () => { await operator.handleDraft({drafts: [draft], prepareRecordsOnly: false}); - const result = await addFilesToDraft(serverUrl, channelId, '', [fileInfo], false) as {draft: DraftModel; error: unknown}; + const result = await addFilesToDraft(serverUrl, channelId, '', [fileInfo]) as {draft: DraftModel; error: unknown}; expect(result.error).toBeUndefined(); expect(result.draft).toBeDefined(); expect(result?.draft.files.length).toBe(1); @@ -201,7 +201,15 @@ describe('removeDraft', () => { it('remove draft', async () => { await operator.handleDraft({drafts: [draft], prepareRecordsOnly: false}); - const result = await removeDraft(serverUrl, channelId, ''); + const result = await removeDraft(serverUrl, channelId); + expect(result.error).toBeUndefined(); + expect(result.draft).toBeDefined(); + }); + + it('remove draft with root id', async () => { + await operator.handleDraft({drafts: [{...draft, root_id: 'postid'}], prepareRecordsOnly: false}); + + const result = await removeDraft(serverUrl, channelId, 'postid'); expect(result.error).toBeUndefined(); expect(result.draft).toBeDefined(); }); diff --git a/app/actions/local/file.test.ts b/app/actions/local/file.test.ts index 067d5cd3f9e..a2c0231ada2 100644 --- a/app/actions/local/file.test.ts +++ b/app/actions/local/file.test.ts @@ -6,12 +6,13 @@ import DatabaseManager from '@database/manager'; import { updateLocalFile, updateLocalFilePath, + getLocalFileInfo, } from './file'; import type ServerDataOperator from '@database/operator/server_data_operator'; import type FileModel from '@typings/database/models/servers/file'; -describe('updateLocalFiles', () => { +describe('files', () => { let operator: ServerDataOperator; const serverUrl = 'baseHandler.test.com'; const fileInfo: FileInfo = { @@ -52,4 +53,23 @@ describe('updateLocalFiles', () => { const {error} = await updateLocalFilePath(serverUrl, fileInfo.id as string, 'newpath'); expect(error).toBeUndefined(); }); + + it('updateLocalFilePath - no file', async () => { + const {error} = await updateLocalFilePath(serverUrl, fileInfo.id as string, 'newpath'); + expect(error).toBeUndefined(); + }); + + it('getLocalFileInfo - handle not found database', async () => { + const {error} = await getLocalFileInfo('foo', ''); + expect(error).toBeTruthy(); + }); + + it('getLocalFileInfo', async () => { + await operator.handleFiles({files: [fileInfo], prepareRecordsOnly: false}); + + const {file, error} = await getLocalFileInfo(serverUrl, fileInfo.id as string); + expect(error).toBeUndefined(); + expect(file).toBeDefined(); + expect(file!.id).toBe(fileInfo.id); + }); }); diff --git a/app/actions/local/group.test.ts b/app/actions/local/group.test.ts index 7d13939e7ff..5763a86a32e 100644 --- a/app/actions/local/group.test.ts +++ b/app/actions/local/group.test.ts @@ -66,6 +66,16 @@ describe('searchGroups', () => { expect(models[0].id).toBe(group.id); }); + it('searchGroupsByName', async () => { + const groupModels = await operator.handleGroups({groups: [group], prepareRecordsOnly: false}); + mockedRemoteGroups.fetchGroupsForAutocomplete.mockReturnValueOnce(Promise.resolve(groupModels)); + + const models = await searchGroupsByName(serverUrl, group.name); + expect(models).toBeDefined(); + expect(models.length).toBe(1); + expect(models[0].id).toBe(group.id); + }); + it('searchGroupsByNameInTeam - handle not found database', async () => { const models = await searchGroupsByNameInTeam('foo', 'test', teamId); expect(models).toBeDefined(); @@ -90,6 +100,18 @@ describe('searchGroups', () => { expect(models[0].id).toBe(group.id); }); + it('searchGroupsByNameInTeam', async () => { + const groupModels = await operator.handleGroups({groups: [group], prepareRecordsOnly: false}); + await operator.handleGroupTeamsForTeam({groups: [group], teamId, prepareRecordsOnly: false}); + + mockedRemoteGroups.fetchFilteredTeamGroups.mockReturnValueOnce(Promise.resolve(groupModels)); + + const models = await searchGroupsByNameInTeam(serverUrl, group.name, teamId); + expect(models).toBeDefined(); + expect(models.length).toBe(1); + expect(models[0].id).toBe(group.id); + }); + it('searchGroupsByNameInChannel - handle not found database', async () => { const models = await searchGroupsByNameInChannel('foo', 'test', channelId); expect(models).toBeDefined(); @@ -113,4 +135,16 @@ describe('searchGroups', () => { expect(models.length).toBe(1); expect(models[0].id).toBe(group.id); }); + + it('searchGroupsByNameInChannel', async () => { + const groupModels = await operator.handleGroups({groups: [group], prepareRecordsOnly: false}); + await operator.handleGroupChannelsForChannel({groups: [group], channelId, prepareRecordsOnly: false}); + + mockedRemoteGroups.fetchFilteredChannelGroups.mockReturnValueOnce(Promise.resolve(groupModels)); + + const models = await searchGroupsByNameInChannel(serverUrl, group.name, channelId); + expect(models).toBeDefined(); + expect(models.length).toBe(1); + expect(models[0].id).toBe(group.id); + }); }); diff --git a/app/actions/local/post.test.ts b/app/actions/local/post.test.ts index aa8707abe1e..f7a920fdd2b 100644 --- a/app/actions/local/post.test.ts +++ b/app/actions/local/post.test.ts @@ -36,6 +36,16 @@ jest.mock('@utils/general', () => { }; }); +let mockGetIsCRTEnabled: jest.Mock; +jest.mock('@queries/servers/thread', () => { + const original = jest.requireActual('@queries/servers/thread'); + mockGetIsCRTEnabled = jest.fn(() => true); + return { + ...original, + getIsCRTEnabled: mockGetIsCRTEnabled, + }; +}); + const channelId = 'channelid1'; const user: UserProfile = { id: 'userid', @@ -62,7 +72,7 @@ describe('sendAddToChannelEphemeralPost', () => { it('base case', async () => { const users = await operator.handleUsers({users: [user], prepareRecordsOnly: false}); - const {posts, error} = await sendAddToChannelEphemeralPost(serverUrl, users[0], ['username2'], ['added username2'], channelId, ''); + const {posts, error} = await sendAddToChannelEphemeralPost(serverUrl, users[0], ['username2'], ['added username2'], channelId); expect(error).toBeUndefined(); expect(posts).toBeDefined(); expect(posts?.length).toBe(1); @@ -86,7 +96,7 @@ describe('sendEphemeralPost', () => { it('handle no user', async () => { await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: 'useridcurrent'}], prepareRecordsOnly: false}); - const {post, error} = await sendEphemeralPost(serverUrl, 'newmessage', channelId, ''); + const {post, error} = await sendEphemeralPost(serverUrl, 'newmessage', channelId); expect(error).toBeUndefined(); expect(post).toBeDefined(); expect(post?.user_id).toBe('useridcurrent'); @@ -122,6 +132,12 @@ describe('removePost', () => { expect(rPost).toBeDefined(); }); + it('base case - missing post', async () => { + const {post: rPost, error} = await removePost(serverUrl, post); + expect(error).toBeUndefined(); + expect(rPost).toBeDefined(); + }); + it('base case - system message', async () => { const systemPost = {...TestHelper.fakePost(channelId), id: `${COMBINED_USER_ACTIVITY}id1_id2`, type: Post.POST_TYPES.COMBINED_USER_ACTIVITY as PostType, props: {system_post_ids: ['id1']}}; @@ -189,22 +205,24 @@ describe('storePostsForChannel', () => { expect(error).toBeTruthy(); }); - it('base case', async () => { + it('base case - CRT on', async () => { await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false}); - await operator.handleConfigs({ - configs: [ - {id: 'CollapsedThreads', value: 'default_on'}, - {id: 'FeatureFlagCollapsedThreads', value: 'true'}, - ], - configsToDelete: [], - prepareRecordsOnly: false, - }); const {models, error} = await storePostsForChannel(serverUrl, channelId, [post], [post.id], '', ActionType.POSTS.RECEIVED_IN_CHANNEL, [user], false); expect(error).toBeUndefined(); expect(models).toBeDefined(); expect(models?.length).toBe(5); // Post, PostsInChannel, User, MyChannel, Thread }); + + it('base case - CRT off', async () => { + await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false}); + mockGetIsCRTEnabled.mockImplementationOnce(() => false); + + const {models, error} = await storePostsForChannel(serverUrl, channelId, [post], [post.id], '', ActionType.POSTS.RECEIVED_IN_CHANNEL, [user]); + expect(error).toBeUndefined(); + expect(models).toBeDefined(); + expect(models?.length).toBe(4); // Post, PostsInChannel, User, MyChannel + }); }); describe('getPosts', () => { @@ -267,7 +285,7 @@ describe('addPostAcknowledgement', () => { prepareRecordsOnly: false, }); - const {model, error} = await addPostAcknowledgement(serverUrl, post.id, user.id, 123, false); + const {model, error} = await addPostAcknowledgement(serverUrl, post.id, user.id, 123); expect(error).toBeUndefined(); expect(model).toBeDefined(); }); @@ -296,7 +314,7 @@ describe('removePostAcknowledgement', () => { prepareRecordsOnly: false, }); - const {model, error} = await removePostAcknowledgement(serverUrl, post.id, user.id, false); + const {model, error} = await removePostAcknowledgement(serverUrl, post.id, user.id); expect(error).toBeUndefined(); expect(model).toBeDefined(); }); diff --git a/app/actions/local/systems.test.ts b/app/actions/local/systems.test.ts index be3fd8e6be6..b4cda2eb81f 100644 --- a/app/actions/local/systems.test.ts +++ b/app/actions/local/systems.test.ts @@ -50,6 +50,41 @@ describe('storeConfigAndLicense', () => { expect(models.length).toBe(0); }); + it('handle undefined config - storeConfig', async () => { + const models = await storeConfig(serverUrl, undefined); + expect(models).toBeDefined(); + expect(models.length).toBe(0); + }); + + it('base case - storeConfig', async () => { + await operator.handleConfigs({ + configs: [ + {id: 'DataRetentionEnableMessageDeletion', value: 'true'}, + {id: 'AboutLink', value: 'link'}, + ], + configsToDelete: [], + prepareRecordsOnly: false, + }); + + const models = await storeConfig(serverUrl, {AboutLink: 'link'} as ClientConfig); + expect(models).toBeDefined(); + expect(models.length).toBe(1); // data retention removed + }); + + it('nothing to update - storeConfig', async () => { + await operator.handleConfigs({ + configs: [ + {id: 'AboutLink', value: 'link'}, + ], + configsToDelete: [], + prepareRecordsOnly: false, + }); + + const models = await storeConfig(serverUrl, {AboutLink: 'link'} as ClientConfig); + expect(models).toBeDefined(); + expect(models.length).toBe(0); + }); + it('handle not found database', async () => { const models = await storeConfigAndLicense('foo', {} as ClientConfig, {} as ClientLicense); expect(models).toBeDefined(); @@ -76,6 +111,12 @@ describe('dataRetention', () => { expect(models.length).toBe(2); // data retention and granular data retention policies }); + it('empty case - storeDataRetentionPolicies', async () => { + const models = await storeDataRetentionPolicies(serverUrl, {} as DataRetentionPoliciesRequest); + expect(models).toBeDefined(); + expect(models.length).toBe(2); // data retention and granular data retention policies + }); + it('handle not found database - updateLastDataRetentionRun', async () => { const {error} = await updateLastDataRetentionRun('foo', 0) as {error: unknown}; expect(error).toBeDefined(); @@ -87,6 +128,12 @@ describe('dataRetention', () => { expect(models.length).toBe(1); // data retention }); + it('no time provided - updateLastDataRetentionRun', async () => { + const models = await updateLastDataRetentionRun(serverUrl) as SystemModel[]; + expect(models).toBeDefined(); + expect(models.length).toBe(1); // data retention + }); + it('handle not found database - dataRetentionCleanup', async () => { const {error} = await dataRetentionCleanup('foo'); expect(error).toBeDefined(); @@ -134,6 +181,33 @@ describe('dataRetention', () => { expect(error).toBeDefined(); // LokiJSAdapter doesn't support unsafeSqlQuery spy.mockRestore(); }); + + it('already cleaned today - dataRetentionCleanup', async () => { + const channel: Channel = { + id: 'channelid1', + team_id: 'teamid1', + total_msg_count: 0, + } as Channel; + + await operator.handleConfigs({ + configs: [ + {id: 'DataRetentionEnableMessageDeletion', value: 'true'}, + ], + configsToDelete: [], + prepareRecordsOnly: false, + }); + await operator.handleSystem({systems: + [ + {id: SYSTEM_IDENTIFIERS.LAST_DATA_RETENTION_RUN, value: Date.now()}, + {id: SYSTEM_IDENTIFIERS.LICENSE, value: {IsLicensed: 'true', DataRetention: 'true'}}, + {id: SYSTEM_IDENTIFIERS.GRANULAR_DATA_RETENTION_POLICIES, value: {team: [{team_id: 'teamid1', post_duration: 100}], channel: [{channel_id: 'channelid1', post_duration: 100}]}}, + ], + prepareRecordsOnly: false}); + await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); + + const {error} = await dataRetentionCleanup(serverUrl); + expect(error).toBeUndefined(); + }); }); describe('setLastServerVersionCheck', () => { @@ -146,6 +220,11 @@ describe('setLastServerVersionCheck', () => { const {error} = await setLastServerVersionCheck(serverUrl); expect(error).toBeUndefined(); }); + + it('base case - reset', async () => { + const {error} = await setLastServerVersionCheck(serverUrl, true); + expect(error).toBeUndefined(); + }); }); describe('setGlobalThreadsTab', () => { diff --git a/app/actions/local/thread.test.ts b/app/actions/local/thread.test.ts index cb7b7c22094..b12879cc084 100644 --- a/app/actions/local/thread.test.ts +++ b/app/actions/local/thread.test.ts @@ -38,6 +38,7 @@ jest.mock('@store/navigation_store', () => { return { ...original, waitUntilScreenIsTop: jest.fn(() => Promise.resolve()), + getScreensInStack: jest.fn(() => []), }; }); @@ -99,7 +100,25 @@ describe('switchToGlobalThreads', () => { await operator.handleTeam({teams: [team], prepareRecordsOnly: false}); await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}], prepareRecordsOnly: false}); - const {models, error} = await switchToGlobalThreads(serverUrl, undefined, false); + const {models, error} = await switchToGlobalThreads(serverUrl, undefined); + expect(error).toBeUndefined(); + expect(models).toBeDefined(); + expect(models?.length).toBe(1); // history + }); + + it('base case - provided team id', async () => { + let mockIsTablet: jest.Mock; + jest.mock('@utils/helpers', () => { + const original = jest.requireActual('@utils/helpers'); + mockIsTablet = jest.fn(() => true); + return { + ...original, + isTablet: mockIsTablet, + }; + }); + await operator.handleTeam({teams: [team], prepareRecordsOnly: false}); + + const {models, error} = await switchToGlobalThreads(serverUrl, team.id); expect(error).toBeUndefined(); expect(models).toBeDefined(); expect(models?.length).toBe(1); // history @@ -121,7 +140,7 @@ describe('switchToThread', () => { await operator.handleUsers({users: [user], prepareRecordsOnly: false}); await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user.id}], prepareRecordsOnly: false}); - const {error} = await switchToThread(serverUrl, '', false); + const {error} = await switchToThread(serverUrl, ''); expect((error as Error).message).toBe('Post not found'); }); @@ -136,7 +155,7 @@ describe('switchToThread', () => { prepareRecordsOnly: false, }); - const {error} = await switchToThread(serverUrl, post.id, false); + const {error} = await switchToThread(serverUrl, post.id); expect((error as Error).message).toBe('Channel not found'); }); @@ -157,6 +176,42 @@ describe('switchToThread', () => { const {error} = await switchToThread(serverUrl, post.id, true); expect(error).toBeUndefined(); }); + + it('base case not from notification', async () => { + EphemeralStore.theme = Preferences.THEMES.denim; + await operator.handleUsers({users: [user, user2], prepareRecordsOnly: false}); + await operator.handleTeam({teams: [team], prepareRecordsOnly: false}); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: 'teamid2'}, {id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user.id}], prepareRecordsOnly: false}); + await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); + const post = {...TestHelper.fakePost(channelId, user2.id), id: 'postid', create_at: 1}; + await operator.handlePosts({ + actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL, + order: [post.id], + posts: [post], + prepareRecordsOnly: false, + }); + + const {error} = await switchToThread(serverUrl, post.id, false); + expect(error).toBeUndefined(); + }); + + it('base case for DM', async () => { + EphemeralStore.theme = Preferences.THEMES.denim; + await operator.handleUsers({users: [user, user2], prepareRecordsOnly: false}); + await operator.handleTeam({teams: [team], prepareRecordsOnly: false}); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: 'teamid2'}, {id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user.id}], prepareRecordsOnly: false}); + await operator.handleChannel({channels: [{...channel, team_id: '', type: 'D', display_name: 'user1-user2'}], prepareRecordsOnly: false}); + const post = {...TestHelper.fakePost(channelId, user2.id), id: 'postid', create_at: 1}; + await operator.handlePosts({ + actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL, + order: [post.id], + posts: [post], + prepareRecordsOnly: false, + }); + + const {error} = await switchToThread(serverUrl, post.id, true); + expect(error).toBeUndefined(); + }); }); describe('createThreadFromNewPost', () => { @@ -181,7 +236,7 @@ describe('createThreadFromNewPost', () => { await operator.handleUsers({users: [user2], prepareRecordsOnly: false}); const post = {...TestHelper.fakePost(channelId, user2.id), id: 'postid', create_at: 1}; - const {models, error} = await createThreadFromNewPost(serverUrl, post, false); + const {models, error} = await createThreadFromNewPost(serverUrl, post); expect(error).toBeUndefined(); expect(models).toBeDefined(); expect(models?.length).toBe(1); // thread @@ -215,7 +270,7 @@ describe('processReceivedThreads', () => { }, ] as Thread[]; - const {models, error} = await processReceivedThreads(serverUrl, thread, team.id, false); + const {models, error} = await processReceivedThreads(serverUrl, thread, team.id); expect(error).toBeUndefined(); expect(models).toBeDefined(); expect(models?.length).toBe(4); // post, thread, thread participant, thread in team @@ -289,7 +344,7 @@ describe('updateTeamThreadsSync', () => { }); it('base case', async () => { - const {models, error} = await updateTeamThreadsSync(serverUrl, {id: 'id1', earliest: 1, latest: 2}, false); + const {models, error} = await updateTeamThreadsSync(serverUrl, {id: 'id1', earliest: 1, latest: 2}); expect(error).toBeUndefined(); expect(models).toBeDefined(); }); From 84d320afcf4a096f64d8f244cbd96de11e3082a7 Mon Sep 17 00:00:00 2001 From: Rahim Rahman Date: Thu, 21 Nov 2024 10:30:30 -0700 Subject: [PATCH 13/36] test: more meaningful AnimatedNumber component test (#8309) * better unit test for animated_number * updated test * update test * clean up based on comments --- app/components/animated_number/index.test.tsx | 133 ++++++++++++++++++ app/components/animated_number/index.tsx | 65 +++++---- 2 files changed, 171 insertions(+), 27 deletions(-) create mode 100644 app/components/animated_number/index.test.tsx diff --git a/app/components/animated_number/index.test.tsx b/app/components/animated_number/index.test.tsx new file mode 100644 index 00000000000..472d978a87e --- /dev/null +++ b/app/components/animated_number/index.test.tsx @@ -0,0 +1,133 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {fireEvent, render, waitFor, screen} from '@testing-library/react-native'; +import React from 'react'; +import {Animated} from 'react-native'; + +import AnimatedNumber from '.'; + +const NUMBER_HEIGHT = 10; + +describe('AnimatedNumber', () => { + // running on jest, since Animated is a native module, Animated.timing.start needs to be mocked in order to update to the final Animated.Value. + // Ex: 1 => 2, the Animated.Value should be -20 (from -10) after the animation is done + jest.spyOn(Animated, 'timing').mockImplementation((a, b) => ({ + + // @ts-expect-error mock implementation for testing + start: jest.fn().mockImplementation(() => a.setValue(b.toValue)), + }) as unknown as Animated.CompositeAnimation); + + it('should render the non-animated number', () => { + render(); + + const text = screen.getByTestId('no-animation-number'); + expect(text.children).toContainEqual('123'); + }); + + it('should removed the non-animation number after getting the correct height', () => { + render(); + + const text = screen.getByTestId('no-animation-number'); + + fireEvent(text, 'onLayout', {nativeEvent: {layout: {height: NUMBER_HEIGHT}}}); + + const removedText = screen.queryByTestId('no-animation-number'); + + expect(removedText).toBeNull(); + }); + + it('should switch to the animated number view', async () => { + render(); + + const text = screen.getByTestId('no-animation-number'); + + fireEvent(text, 'onLayout', {nativeEvent: {layout: {height: NUMBER_HEIGHT}}}); + + const animatedView = screen.getByTestId('animation-number-main'); + expect(animatedView).toBeTruthy(); + }); + + describe.each([1, 23, 579, -123, 6789, 23456])('should show the correct number of animated views based on the digits', (animateToNumber: number) => { + const numberOfDigits = animateToNumber.toString().length; + it(`should display ${numberOfDigits} view(s) for ${animateToNumber}`, async () => { + render(); + + const text = screen.getByTestId('no-animation-number'); + + fireEvent(text, 'onLayout', {nativeEvent: {layout: {height: NUMBER_HEIGHT}}}); + + await waitFor(() => { + const animatedView = screen.getByTestId('animation-number-main'); + expect(animatedView.children).toHaveLength(numberOfDigits); + }); + }); + }); + + describe.each([123, 9982, 12345, 901876, -157])('should show the correct number', (animateToNumber: number) => { + const absAnimatedNumberString = String(Math.abs(animateToNumber)); + const numberOfDigits = absAnimatedNumberString.length; + it(`should display the number ${animateToNumber}`, async () => { + render(); + + const text = screen.getByTestId('no-animation-number'); + + fireEvent(text, 'onLayout', {nativeEvent: {layout: {height: NUMBER_HEIGHT}}}); + + const checkEachDigit = absAnimatedNumberString.split('').map(async (number, index) => { + const useIndex = numberOfDigits - 1 - index; + + // every digit will have a row of 10 numbers, so the translateY should be the height of the number * the number * -1 (since the animation is going up) + const transformedView = screen.getByTestId(`animated-number-view-${useIndex}`); + const {translateY} = transformedView.props.style.transform[0]; + + expect(Math.abs(translateY / NUMBER_HEIGHT)).toEqual(Number(number)); + }); + + await Promise.all(checkEachDigit); + }); + }); + + describe.each([146, 144, 1, 1000000, -145])('should rerender the correct number that it animates to', (animateToNumber: number) => { + it(`should display the number ${animateToNumber}`, async () => { + const startingNumber = 145; + render(); + + const text = screen.getByTestId('no-animation-number'); + + fireEvent(text, 'onLayout', {nativeEvent: {layout: {height: NUMBER_HEIGHT}}}); + + screen.rerender(); + + const animateToNumberString = String(Math.abs(animateToNumber)); + const checkEachDigit = animateToNumberString.split('').map(async (number, index) => { + const useIndex = animateToNumberString.length - 1 - index; + + const transformedView = screen.getByTestId(`animated-number-view-${useIndex}`); + const {translateY} = transformedView.props.style.transform[0]; + + expect(Math.abs((translateY) / NUMBER_HEIGHT)).toEqual(Number(number)); + }); + + await Promise.all(checkEachDigit); + }); + }); + + it('KNOWN UI BUG: should show that there will be an issue if the text height changes, due to the non-animated number view has been removed', async () => { + // the number text will get cut-off if the user changes the text size on their mobile devices + render(); + + const text = screen.getByTestId('no-animation-number'); + + fireEvent(text, 'onLayout', {nativeEvent: {layout: {height: NUMBER_HEIGHT}}}); + + try { + fireEvent(text, 'onLayout', {nativeEvent: {layout: {height: NUMBER_HEIGHT + NUMBER_HEIGHT}}}); + } catch (e) { + expect(e).toEqual(new Error('Unable to find node on an unmounted component.')); + } + + const animatedView = screen.getByTestId('animation-number-main'); + expect(animatedView).toBeTruthy(); + }); +}); diff --git a/app/components/animated_number/index.tsx b/app/components/animated_number/index.tsx index 3b8ee973f3e..f8a61328f70 100644 --- a/app/components/animated_number/index.tsx +++ b/app/components/animated_number/index.tsx @@ -94,43 +94,54 @@ const AnimatedNumber = ({ return ( <> {numberHeight !== 0 && ( - + {animateToNumber < 0 && ( {'-'} )} - {Array.from(animateToNumberString, Number).map((_, index) => ( - - { + const useIndex = animateToNumberString.length - 1 - index; + return ( + - {NUMBERS.map((number, i) => ( - - - {number} - - - ))} - - - ))} + + {NUMBERS.map((number, i) => ( + + + {number} + + + ))} + + + ); + })} )} {numberHeight === 0 && {animateToNumberString} From 8d2e52b8179bb64a09ab356156f83ea366378dde Mon Sep 17 00:00:00 2001 From: "unified-ci-app[bot]" <121569378+unified-ci-app[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 13:13:58 +0100 Subject: [PATCH 14/36] Bump app build number to 577 (#8369) Co-authored-by: runner --- android/app/build.gradle | 2 +- ios/Mattermost.xcodeproj/project.pbxproj | 8 ++++---- ios/Mattermost/Info.plist | 2 +- ios/MattermostShare/Info.plist | 2 +- ios/NotificationService/Info.plist | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 35747177aed..af06626206e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -111,7 +111,7 @@ android { applicationId "com.mattermost.rnbeta" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 576 + versionCode 577 versionName "2.23.0" testBuildType System.getProperty('testBuildType', 'debug') testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' diff --git a/ios/Mattermost.xcodeproj/project.pbxproj b/ios/Mattermost.xcodeproj/project.pbxproj index 741f49bf85c..1e23581eb9f 100644 --- a/ios/Mattermost.xcodeproj/project.pbxproj +++ b/ios/Mattermost.xcodeproj/project.pbxproj @@ -1984,7 +1984,7 @@ CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 576; + CURRENT_PROJECT_VERSION = 577; DEVELOPMENT_TEAM = UQ8HT4Q2XM; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = "$(inherited)"; @@ -2026,7 +2026,7 @@ CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 576; + CURRENT_PROJECT_VERSION = 577; DEVELOPMENT_TEAM = UQ8HT4Q2XM; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = "$(inherited)"; @@ -2169,7 +2169,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 576; + CURRENT_PROJECT_VERSION = 577; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = UQ8HT4Q2XM; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2219,7 +2219,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 576; + CURRENT_PROJECT_VERSION = 577; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = UQ8HT4Q2XM; GCC_C_LANGUAGE_STANDARD = gnu11; diff --git a/ios/Mattermost/Info.plist b/ios/Mattermost/Info.plist index 1b78a280637..f609d9918a4 100644 --- a/ios/Mattermost/Info.plist +++ b/ios/Mattermost/Info.plist @@ -37,7 +37,7 @@ CFBundleVersion - 576 + 577 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/ios/MattermostShare/Info.plist b/ios/MattermostShare/Info.plist index bde83abb689..bf6c754123c 100644 --- a/ios/MattermostShare/Info.plist +++ b/ios/MattermostShare/Info.plist @@ -21,7 +21,7 @@ CFBundleShortVersionString 2.23.0 CFBundleVersion - 576 + 577 UIAppFonts OpenSans-Bold.ttf diff --git a/ios/NotificationService/Info.plist b/ios/NotificationService/Info.plist index fa1b423644b..28e598e923d 100644 --- a/ios/NotificationService/Info.plist +++ b/ios/NotificationService/Info.plist @@ -21,7 +21,7 @@ CFBundleShortVersionString 2.23.0 CFBundleVersion - 576 + 577 NSExtension NSExtensionPointIdentifier From 99383f265f6eb2c2d0df504795e5f4dfa8be81a6 Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Mon, 25 Nov 2024 11:58:50 -0500 Subject: [PATCH 15/36] Add tests for actions/remote/category (#8371) --- app/actions/remote/category.test.ts | 239 ++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 app/actions/remote/category.test.ts diff --git a/app/actions/remote/category.test.ts b/app/actions/remote/category.test.ts new file mode 100644 index 00000000000..f338c919b52 --- /dev/null +++ b/app/actions/remote/category.test.ts @@ -0,0 +1,239 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {storeCategories} from '@actions/local/category'; +import {CHANNELS_CATEGORY, DMS_CATEGORY, FAVORITES_CATEGORY} from '@constants/categories'; +import {SYSTEM_IDENTIFIERS} from '@constants/database'; +import DatabaseManager from '@database/manager'; +import NetworkManager from '@managers/network_manager'; +import {getFullErrorMessage} from '@utils/errors'; +import {logDebug} from '@utils/log'; + +import {fetchCategories, toggleFavoriteChannel} from './category'; + +import type ServerDataOperator from '@database/operator/server_data_operator'; + +jest.mock('@managers/network_manager'); +jest.mock('@utils/log'); +jest.mock('@utils/errors'); +jest.mock('@actions/local/category'); + +const serverUrl = 'baseHandler.test.com'; +let operator: ServerDataOperator; + +const teamId = 'teamid1'; +const channelId = 'channelid1'; +const channel = {id: channelId, type: 'O'} as Channel; +const mockCategories = [{id: 'category1'}, {id: 'category2'}]; +const error = new Error('Test error'); + +beforeEach(async () => { + jest.clearAllMocks(); + await DatabaseManager.init([serverUrl]); + operator = DatabaseManager.serverDatabases[serverUrl]!.operator; +}); + +describe('fetchCategories', () => { + it('should fetch categories successfully', async () => { + const mockClient = { + getCategories: jest.fn().mockResolvedValue({categories: mockCategories}), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + const result = await fetchCategories(serverUrl, teamId); + + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.getCategories).toHaveBeenCalledWith('me', teamId); + expect(storeCategories).toHaveBeenCalledWith(serverUrl, mockCategories, false); + expect(result).toEqual({categories: mockCategories}); + }); + + it('should only fetch categories successfully', async () => { + const mockClient = { + getCategories: jest.fn().mockResolvedValue({categories: mockCategories}), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + const result = await fetchCategories(serverUrl, teamId, false, true); + + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.getCategories).toHaveBeenCalledWith('me', teamId); + expect(result).toEqual({categories: mockCategories}); + }); + + it('should handle error during fetch categories', async () => { + const mockClient = { + getCategories: jest.fn().mockRejectedValue(error), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + (getFullErrorMessage as jest.Mock).mockReturnValue('Full error message'); + + const result = await fetchCategories(serverUrl, teamId); + + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.getCategories).toHaveBeenCalledWith('me', teamId); + expect(logDebug).toHaveBeenCalledWith('error on fetchCategories', 'Full error message'); + expect(result).toEqual({error}); + }); +}); + +describe('toggleFavoriteChannel', () => { + const favCategory: Category = { + id: 'fav_category_id', + team_id: teamId, + type: FAVORITES_CATEGORY, + } as Category; + + const categoryChannels: CategoryChannel = { + id: 'teamid1_channelid1', + category_id: 'fav_category_id', + channel_id: channelId, + sort_order: 1, + }; + + const defaultCategory: Category = { + id: 'default_category_id', + team_id: teamId, + type: CHANNELS_CATEGORY, + } as Category; + + const dmCategory: Category = { + id: 'dm_category_id', + team_id: teamId, + type: DMS_CATEGORY, + } as Category; + + it('should handle no channel found', async () => { + const result = await toggleFavoriteChannel(serverUrl, channelId, true); + + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(result).toEqual({error: 'channel not found'}); + }); + + it('should handle no channel category', async () => { + await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); + const result = await toggleFavoriteChannel(serverUrl, channelId, true); + + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(result).toEqual({error: 'channel does not belong to a category'}); + }); + + it('should error on no target category', async () => { + await operator.handleCategoryChannels({categoryChannels: [categoryChannels], prepareRecordsOnly: false}); + await operator.handleCategories({categories: [favCategory], prepareRecordsOnly: false}); + await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}], prepareRecordsOnly: false}); + const mockClient = { + updateChannelCategories: jest.fn().mockResolvedValue({}), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + const result = await toggleFavoriteChannel(serverUrl, channelId, true); + + expect(result).toEqual({error: 'target category not found'}); + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + }); + + it('should unfavorite channel successfully', async () => { + await operator.handleCategoryChannels({categoryChannels: [categoryChannels], prepareRecordsOnly: false}); + await operator.handleCategories({categories: [favCategory, defaultCategory], prepareRecordsOnly: false}); + await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}], prepareRecordsOnly: false}); + const mockClient = { + updateChannelCategories: jest.fn().mockResolvedValue({}), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + const result = await toggleFavoriteChannel(serverUrl, channelId, true); + + expect(result).toEqual({data: true}); + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.updateChannelCategories).toHaveBeenCalled(); + }); + + it('should unfavorite DM channel successfully', async () => { + await operator.handleCategoryChannels({categoryChannels: [categoryChannels], prepareRecordsOnly: false}); + await operator.handleCategories({categories: [favCategory, dmCategory], prepareRecordsOnly: false}); + await operator.handleChannel({channels: [{...channel, type: 'D', display_name: 'displayname'}], prepareRecordsOnly: false}); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}], prepareRecordsOnly: false}); + const mockClient = { + updateChannelCategories: jest.fn().mockResolvedValue({}), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + const result = await toggleFavoriteChannel(serverUrl, channelId, true); + + expect(result).toEqual({data: true}); + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.updateChannelCategories).toHaveBeenCalled(); + }); + + it('should favorite channel successfully', async () => { + await operator.handleCategoryChannels({categoryChannels: [{...categoryChannels, category_id: defaultCategory.id}], prepareRecordsOnly: false}); + await operator.handleCategories({categories: [favCategory, defaultCategory], prepareRecordsOnly: false}); + await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}], prepareRecordsOnly: false}); + const mockClient = { + updateChannelCategories: jest.fn().mockResolvedValue({}), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + const result = await toggleFavoriteChannel(serverUrl, channelId, true); + + expect(result).toEqual({data: true}); + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.updateChannelCategories).toHaveBeenCalled(); + }); + + it('should favorite channel successfully with no snack bar', async () => { + await operator.handleCategoryChannels({categoryChannels: [{...categoryChannels, category_id: defaultCategory.id}], prepareRecordsOnly: false}); + await operator.handleCategories({categories: [favCategory, defaultCategory], prepareRecordsOnly: false}); + await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}], prepareRecordsOnly: false}); + const mockClient = { + updateChannelCategories: jest.fn().mockResolvedValue({}), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + const result = await toggleFavoriteChannel(serverUrl, channelId, false); + + expect(result).toEqual({data: true}); + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.updateChannelCategories).toHaveBeenCalled(); + }); + + it('should error on no favorites category', async () => { + await operator.handleCategoryChannels({categoryChannels: [{...categoryChannels, category_id: defaultCategory.id}], prepareRecordsOnly: false}); + await operator.handleCategories({categories: [defaultCategory], prepareRecordsOnly: false}); + await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}], prepareRecordsOnly: false}); + const mockClient = { + updateChannelCategories: jest.fn().mockResolvedValue({}), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + const result = await toggleFavoriteChannel(serverUrl, channelId, true); + + expect(result).toEqual({error: 'No favorites category'}); + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + }); + + it('should handle error during toggle favorite channel', async () => { + await operator.handleCategoryChannels({categoryChannels: [categoryChannels], prepareRecordsOnly: false}); + await operator.handleCategories({categories: [favCategory, defaultCategory], prepareRecordsOnly: false}); + await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}], prepareRecordsOnly: false}); + const mockClient = { + updateChannelCategories: jest.fn().mockRejectedValue(error), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + (getFullErrorMessage as jest.Mock).mockReturnValue('Full error message'); + + const result = await toggleFavoriteChannel(serverUrl, channelId); + + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.updateChannelCategories).toHaveBeenCalled(); + expect(logDebug).toHaveBeenCalledWith('error on toggleFavoriteChannel', 'Full error message'); + expect(result).toEqual({error}); + }); +}); From 71f1d99041a9e3666b7b960419b04385de35d5c9 Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Mon, 25 Nov 2024 12:02:34 -0500 Subject: [PATCH 16/36] Increase branch test coverage of actions/remote files (#8370) * Increase branch test coverage for actions/remote/command * Increase branch test coverage for actions/remote/session * Increase branch test coverage for actions/remote/post --- app/actions/remote/command.test.ts | 103 +++++++++ app/actions/remote/post.test.ts | 340 ++++++++++++++++++++++++++++- app/actions/remote/session.test.ts | 88 ++++++++ app/actions/remote/session.ts | 2 + 4 files changed, 531 insertions(+), 2 deletions(-) diff --git a/app/actions/remote/command.test.ts b/app/actions/remote/command.test.ts index 005a81a3706..3e565ea5cd2 100644 --- a/app/actions/remote/command.test.ts +++ b/app/actions/remote/command.test.ts @@ -107,6 +107,15 @@ describe('executeCommand', () => { expect(result).toEqual({error: 'invalid_url database not found'}); }); + it('handle client error', async () => { + jest.spyOn(NetworkManager, 'getClient').mockImplementationOnce(() => { + throw error; + }); + + const result = await executeCommand(serverUrl, intl, message, channelId, rootId); + expect(result).toEqual({error}); + }); + it('handle apps enabled', async () => { jest.spyOn(AppsManager, 'isAppsEnabled').mockResolvedValue(true); const parser = { @@ -164,6 +173,34 @@ describe('executeCommand', () => { expect(result).toEqual({data: {trigger_id: 'trigger_id'}}); }); + it('handle /code command execution with successful response', async () => { + await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); + + jest.spyOn(AppsManager, 'isAppsEnabled').mockResolvedValue(false); + const mockSetTriggerId = jest.fn(); + jest.spyOn(IntegrationsManager, 'getManager').mockReturnValue({ + setTriggerId: mockSetTriggerId, + } as any); + + const result = await executeCommand(serverUrl, intl, '/code', channelId, rootId); + + expect(mockClient.executeCommand).toHaveBeenCalledWith('/code ', args); + expect(mockSetTriggerId).toHaveBeenCalledWith('trigger_id'); + expect(result).toEqual({data: {trigger_id: 'trigger_id'}}); + }); + + it('handle command execution with no trigger id', async () => { + await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); + + jest.spyOn(AppsManager, 'isAppsEnabled').mockResolvedValue(false); + mockClient.executeCommand.mockResolvedValueOnce({} as never); + + const result = await executeCommand(serverUrl, intl, message, channelId, rootId); + + expect(mockClient.executeCommand).toHaveBeenCalledWith(message, args); + expect(result).toEqual({data: {}}); + }); + it('handle command execution with error response', async () => { await operator.handleChannel({channels: [channel], prepareRecordsOnly: false}); @@ -181,6 +218,16 @@ describe('executeCommand', () => { describe('executeAppCommand', () => { const msg = 'test message'; + it('should handle a undefined creq', async () => { + const parser = { + composeCommandSubmitCall: jest.fn().mockResolvedValue({errorMessage: 'Error occurred'}), + }; + + const result = await executeAppCommand(serverUrl, intl, parser as any, msg, args); + + expect(result).toEqual({error: {message: 'Error occurred'}}); + }); + it('should handle a successful command execution with OK response', async () => { const parser = { composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}), @@ -196,6 +243,20 @@ describe('executeAppCommand', () => { expect(result).toEqual({data: {}}); }); + it('should handle OK response with no text', async () => { + const parser = { + composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}), + }; + (AppCommandParser as jest.Mock).mockReturnValue(parser); + (doAppSubmit as jest.Mock).mockResolvedValue({data: {type: AppCallResponseTypes.OK}}); + + const result = await executeAppCommand(serverUrl, intl, parser as any, msg, args); + + expect(parser.composeCommandSubmitCall).toHaveBeenCalledWith(msg); + expect(doAppSubmit).toHaveBeenCalledWith(serverUrl, {}, intl); + expect(result).toEqual({data: {}}); + }); + it('should handle an error response', async () => { const parser = { composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}), @@ -210,6 +271,20 @@ describe('executeAppCommand', () => { expect(result).toEqual({error: {message: 'Error occurred'}}); }); + it('should handle an error response with no text', async () => { + const parser = { + composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}), + }; + (AppCommandParser as jest.Mock).mockReturnValue(parser); + (doAppSubmit as jest.Mock).mockResolvedValue({error: {}}); + + const result = await executeAppCommand(serverUrl, intl, parser as any, msg, args); + + expect(parser.composeCommandSubmitCall).toHaveBeenCalledWith(msg); + expect(doAppSubmit).toHaveBeenCalledWith(serverUrl, {}, intl); + expect(result).toEqual({error: {message: 'Unknown error.'}}); + }); + it('should handle a form response', async () => { const parser = { composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {context: {}}, errorMessage: null}), @@ -225,6 +300,20 @@ describe('executeAppCommand', () => { expect(result).toEqual({data: {}}); }); + it('should handle a form response with no form', async () => { + const parser = { + composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {context: {}}, errorMessage: null}), + }; + (AppCommandParser as jest.Mock).mockReturnValue(parser); + (doAppSubmit as jest.Mock).mockResolvedValue({data: {type: AppCallResponseTypes.FORM}}); + + const result = await executeAppCommand(serverUrl, intl, parser as any, msg, args); + + expect(parser.composeCommandSubmitCall).toHaveBeenCalledWith(msg); + expect(doAppSubmit).toHaveBeenCalledWith(serverUrl, {context: {}}, intl); + expect(result).toEqual({data: {}}); + }); + it('should handle a navigate response', async () => { const parser = { composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}), @@ -239,6 +328,20 @@ describe('executeAppCommand', () => { expect(result).toEqual({data: {}}); }); + it('should handle a navigate response with no url', async () => { + const parser = { + composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}), + }; + (AppCommandParser as jest.Mock).mockReturnValue(parser); + (doAppSubmit as jest.Mock).mockResolvedValue({data: {type: AppCallResponseTypes.NAVIGATE}}); + + const result = await executeAppCommand(serverUrl, intl, parser as any, msg, args); + + expect(parser.composeCommandSubmitCall).toHaveBeenCalledWith(msg); + expect(doAppSubmit).toHaveBeenCalledWith(serverUrl, {}, intl); + expect(result).toEqual({data: {}}); + }); + it('should handle an unknown response type', async () => { const parser = { composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}), diff --git a/app/actions/remote/post.test.ts b/app/actions/remote/post.test.ts index 428381c3fe0..998d4765dee 100644 --- a/app/actions/remote/post.test.ts +++ b/app/actions/remote/post.test.ts @@ -3,7 +3,7 @@ /* eslint-disable max-lines */ -import {ActionType, Post} from '@constants'; +import {ActionType, Post, ServerErrors} from '@constants'; import {SYSTEM_IDENTIFIERS} from '@constants/database'; import DatabaseManager from '@database/manager'; import PostModel from '@database/models/server/post'; @@ -121,6 +121,16 @@ jest.mock('@queries/servers/thread', () => { }; }); +let mockAddRecentReaction: jest.Mock; +jest.mock('@actions/local/reactions', () => { + const original = jest.requireActual('@actions/local/reactions'); + mockAddRecentReaction = jest.fn(() => [{user_id: 'userid1', emoji_name: 'smile'}]); + return { + ...original, + addRecentReaction: mockAddRecentReaction, + }; +}); + beforeAll(() => { // eslint-disable-next-line // @ts-ignore @@ -143,6 +153,28 @@ describe('create, update & delete posts', () => { expect(result.error).toBeTruthy(); }); + it('createPost - handle client error', async () => { + jest.spyOn(NetworkManager, 'getClient').mockImplementationOnce(throwFunc); + + const result = await createPost(serverUrl, post1); + expect(result).toBeDefined(); + expect(result.error).toBeTruthy(); + }); + + it('createPost - handle existing failed post', async () => { + await operator.handlePosts({ + actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL, + order: [post1.id], + posts: [{...post1, props: {failed: false}}], + prepareRecordsOnly: false, + }); + + const result = await createPost(serverUrl, {...post1, pending_post_id: post1.id}); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.data).toBe(false); + }); + it('createPost - fail create', async () => { mockClient.createPost.mockImplementationOnce(jest.fn(throwFunc)); await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); @@ -153,6 +185,45 @@ describe('create, update & delete posts', () => { expect(result.data).toBeTruthy(); }); + it('createPost - fail on deleted root post server error', async () => { + mockClient.createPost.mockImplementationOnce(jest.fn(() => { + // eslint-disable-next-line no-throw-literal + throw {message: 'error', server_error_id: ServerErrors.DELETED_ROOT_POST_ERROR}; + })); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + + const result = await createPost(serverUrl, post1); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.data).toBeTruthy(); + }); + + it('createPost - fail on town square read only server error', async () => { + mockClient.createPost.mockImplementationOnce(jest.fn(() => { + // eslint-disable-next-line no-throw-literal + throw {message: 'error', server_error_id: ServerErrors.TOWN_SQUARE_READ_ONLY_ERROR}; + })); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + + const result = await createPost(serverUrl, post1); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.data).toBeTruthy(); + }); + + it('createPost - fail on plugin dismissed post server error', async () => { + mockClient.createPost.mockImplementationOnce(jest.fn(() => { + // eslint-disable-next-line no-throw-literal + throw {message: 'error', server_error_id: ServerErrors.PLUGIN_DISMISSED_POST_ERROR}; + })); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + + const result = await createPost(serverUrl, post1); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.data).toBeTruthy(); + }); + it('createPost - root', async () => { await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); @@ -162,6 +233,16 @@ describe('create, update & delete posts', () => { expect(result.data).toBeTruthy(); }); + it('createPost - without reactions', async () => { + mockAddRecentReaction.mockImplementationOnce(() => []); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + + const result = await createPost(serverUrl, post1); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.data).toBeTruthy(); + }); + it('createPost - reply', async () => { await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); @@ -177,6 +258,14 @@ describe('create, update & delete posts', () => { expect(result.error).toBeTruthy(); }); + it('retryFailedPost - handle client error', async () => { + jest.spyOn(NetworkManager, 'getClient').mockImplementationOnce(throwFunc); + + const result = await retryFailedPost(serverUrl, mockPostModel({id: post1.id, prepareUpdate: jest.fn(), toApi: async () => post1})); + expect(result).toBeDefined(); + expect(result.error).toBeTruthy(); + }); + it('retryFailedPost - base case', async () => { await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); @@ -192,6 +281,42 @@ describe('create, update & delete posts', () => { expect(result.error).toBeTruthy(); }); + it('retryFailedPost - fail on deleted root post server error', async () => { + mockClient.createPost.mockImplementationOnce(jest.fn(() => { + // eslint-disable-next-line no-throw-literal + throw {message: 'error', server_error_id: ServerErrors.DELETED_ROOT_POST_ERROR}; + })); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + + const result = await retryFailedPost(serverUrl, mockPostModel({id: post1.id, prepareUpdate: jest.fn(), toApi: async () => post1})); + expect(result).toBeDefined(); + expect(result.error).toBeDefined(); + }); + + it('retryFailedPost - fail on town square read only server error', async () => { + mockClient.createPost.mockImplementationOnce(jest.fn(() => { + // eslint-disable-next-line no-throw-literal + throw {message: 'error', server_error_id: ServerErrors.TOWN_SQUARE_READ_ONLY_ERROR}; + })); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + + const result = await retryFailedPost(serverUrl, mockPostModel({id: post1.id, prepareUpdate: jest.fn(), toApi: async () => post1})); + expect(result).toBeDefined(); + expect(result.error).toBeDefined(); + }); + + it('retryFailedPost - fail on plugin dismissed post server error', async () => { + mockClient.createPost.mockImplementationOnce(jest.fn(() => { + // eslint-disable-next-line no-throw-literal + throw {message: 'error', server_error_id: ServerErrors.PLUGIN_DISMISSED_POST_ERROR}; + })); + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + + const result = await retryFailedPost(serverUrl, mockPostModel({id: post1.id, prepareUpdate: jest.fn(), toApi: async () => post1})); + expect(result).toBeDefined(); + expect(result.error).toBeDefined(); + }); + it('togglePinPost - handle database not found', async () => { const result = await togglePinPost('foo', ''); expect(result).toBeDefined(); @@ -382,6 +507,65 @@ describe('get posts', () => { expect(result.posts?.length).toBe(2); }); + it('fetchPostsForChannel - base case with since', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + await operator.handleMyChannel({channels: [{ + id: channelId, + team_id: teamId, + total_msg_count: 0, + creator_id: user1.id, + } as Channel], + myChannels: [{ + id: 'id', + channel_id: channelId, + user_id: user1.id, + msg_count: 0, + } as ChannelMembership], + prepareRecordsOnly: false}); + await operator.handlePosts({ + actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL, + order: [post1.id], + posts: [post1], + prepareRecordsOnly: false, + }); + + const result = await fetchPostsForChannel(serverUrl, channelId, true); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.posts).toBeTruthy(); + expect(result.posts?.length).toBe(2); + }); + + it('fetchPostsForChannel - no posts with since', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + await operator.handleMyChannel({channels: [{ + id: channelId, + team_id: teamId, + total_msg_count: 0, + creator_id: user1.id, + } as Channel], + myChannels: [{ + id: 'id', + channel_id: channelId, + user_id: user1.id, + msg_count: 0, + } as ChannelMembership], + prepareRecordsOnly: false}); + await operator.handlePosts({ + actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL, + order: [post1.id], + posts: [post1], + prepareRecordsOnly: false, + }); + + mockClient.getPostsSince.mockImplementationOnce(jest.fn(() => ({posts: {}, order: []}))); + const result = await fetchPostsForChannel(serverUrl, channelId, true); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.posts).toBeTruthy(); + expect(result.posts?.length).toBe(0); + }); + it('fetchPostsForChannel - request error', async () => { mockClient.getPosts.mockImplementationOnce(jest.fn(throwFunc)); @@ -419,8 +603,30 @@ describe('get posts', () => { expect(result.posts?.length).toBe(2); }); + it('fetchPosts - no CRT', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockGetIsCRTEnabled.mockImplementationOnce(() => false); + + const result = await fetchPosts(serverUrl, channelId); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.posts).toBeTruthy(); + expect(result.posts?.length).toBe(2); + }); + + it('fetchPosts - no authors needed', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockClient.getProfilesByIds.mockImplementationOnce(jest.fn(() => [])); + + const result = await fetchPosts(serverUrl, channelId); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.posts).toBeTruthy(); + expect(result.posts?.length).toBe(2); + }); + it('fetchPostsBefore - handle database not found', async () => { - const result = await fetchPostsBefore('foo', '', '') as {error: unknown}; + const result = await fetchPostsBefore('foo', '', '', 50, true) as {error: unknown}; expect(result).toBeDefined(); expect(result.error).toBeTruthy(); }); @@ -438,6 +644,48 @@ describe('get posts', () => { expect(result.posts?.length).toBe(2); }); + it('fetchPostsBefore - no CRT', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockGetIsCRTEnabled.mockImplementationOnce(() => false); + + const result = await fetchPostsBefore(serverUrl, channelId, post1.id) as { + posts: Post[]; + order: string[]; + previousPostId: string | undefined; + }; + expect(result).toBeDefined(); + expect(result.posts).toBeTruthy(); + expect(result.posts?.length).toBe(2); + }); + + it('fetchPostsBefore - no authors needed', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockClient.getProfilesByIds.mockImplementationOnce(jest.fn(() => [])); + + const result = await fetchPostsBefore(serverUrl, channelId, post1.id) as { + posts: Post[]; + order: string[]; + previousPostId: string | undefined; + }; + expect(result).toBeDefined(); + expect(result.posts).toBeTruthy(); + expect(result.posts?.length).toBe(2); + }); + + it('fetchPostsBefore - no posts', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockClient.getPostsBefore.mockImplementationOnce(jest.fn(() => ({posts: {}, order: []}))); + + const result = await fetchPostsBefore(serverUrl, channelId, post1.id) as { + posts: Post[]; + order: string[]; + previousPostId: string | undefined; + }; + expect(result).toBeDefined(); + expect(result.posts).toBeTruthy(); + expect(result.posts?.length).toBe(0); + }); + it('fetchPostsSince - handle database not found', async () => { const result = await fetchPostsSince('foo', '', 0); expect(result).toBeDefined(); @@ -500,6 +748,40 @@ describe('get posts', () => { expect(result.posts?.[1].id).toBe(reply1.id); }); + it('fetchPostThread - no CRT', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockGetIsCRTEnabled.mockImplementationOnce(() => false); + + const result = await fetchPostThread(serverUrl, post1.id); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.posts).toBeTruthy(); + expect(result.posts?.length).toBe(2); + expect(result.posts?.[0].id).toBe(post1.id); + expect(result.posts?.[1].id).toBe(reply1.id); + }); + + it('fetchPostThread - no authors needed', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockClient.getProfilesByIds.mockImplementationOnce(jest.fn(() => [])); + + const result = await fetchPostThread(serverUrl, post1.id); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.posts).toBeTruthy(); + }); + + it('fetchPostThread - no posts', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockClient.getPostThread.mockImplementationOnce(jest.fn(() => ({posts: {}, order: []}))); + + const result = await fetchPostThread(serverUrl, post1.id); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.posts).toBeTruthy(); + expect(result.posts?.length).toBe(0); + }); + it('fetchPostsAround - handle database not found', async () => { const result = await fetchPostsAround('foo', '', ''); expect(result).toBeDefined(); @@ -516,6 +798,28 @@ describe('get posts', () => { expect(result.posts?.length).toBe(2); }); + it('fetchPostsAround - no CRT', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockGetIsCRTEnabled.mockImplementationOnce(() => false); + + const result = await fetchPostsAround(serverUrl, channelId, post2.id, 100, true); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.posts).toBeTruthy(); + expect(result.posts?.length).toBe(2); + }); + + it('fetchPostsAround - no authors needed', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockClient.getProfilesByIds.mockImplementationOnce(jest.fn(() => [])); + + const result = await fetchPostsAround(serverUrl, channelId, post2.id, 100, true); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.posts).toBeTruthy(); + expect(result.posts?.length).toBe(2); + }); + it('fetchMissingChannelsFromPosts - handle database not found', async () => { const result = await fetchMissingChannelsFromPosts('foo', []); expect(result).toBeDefined(); @@ -548,6 +852,38 @@ describe('get posts', () => { expect(result.post?.id).toBe(post2.id); }); + it('fetchPostById - no CRT', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockGetIsCRTEnabled.mockImplementationOnce(() => false); + + const result = await fetchPostById(serverUrl, post2.id); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.post).toBeDefined(); + expect(result.post?.id).toBe(post2.id); + }); + + it('fetchPostById - no authors needed', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + mockClient.getProfilesByIds.mockImplementationOnce(jest.fn(() => [])); + + const result = await fetchPostById(serverUrl, post2.id); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.post).toBeDefined(); + expect(result.post?.id).toBe(post2.id); + }); + + it('fetchPostById - fetch only', async () => { + await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false}); + + const result = await fetchPostById(serverUrl, post2.id, true); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + expect(result.post).toBeDefined(); + expect(result.post?.id).toBe(post2.id); + }); + it('fetchSavedPosts - handle database not found', async () => { const result = await fetchSavedPosts('foo'); expect(result).toBeDefined(); diff --git a/app/actions/remote/session.test.ts b/app/actions/remote/session.test.ts index ae92fb0eb58..09051d2b8c6 100644 --- a/app/actions/remote/session.test.ts +++ b/app/actions/remote/session.test.ts @@ -3,6 +3,8 @@ /* eslint-disable max-lines */ +import {Platform} from 'react-native'; + import {GLOBAL_IDENTIFIERS, SYSTEM_IDENTIFIERS} from '@constants/database'; import DatabaseManager from '@database/manager'; import NetworkManager from '@managers/network_manager'; @@ -12,6 +14,7 @@ import { forceLogoutIfNecessary, fetchSessions, login, + logout, cancelSessionNotification, scheduleSessionNotification, sendPasswordResetEmail, @@ -109,6 +112,13 @@ describe('sessions', () => { expect(result.error).toBeDefined(); }); + it('addPushProxyVerificationStateFromLogin - no verification', async () => { + mockGetPushProxyVerificationState.mockImplementationOnce(() => ''); + const result = await addPushProxyVerificationStateFromLogin(serverUrl); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + }); + it('addPushProxyVerificationStateFromLogin - base case', async () => { const result = await addPushProxyVerificationStateFromLogin(serverUrl); expect(result).toBeDefined(); @@ -146,6 +156,13 @@ describe('sessions', () => { expect(result).toBeUndefined(); }); + it('fetchSessions - handle client error', async () => { + jest.spyOn(NetworkManager, 'getClient').mockImplementationOnce(throwFunc); + + const result = await fetchSessions(serverUrl, user1.id); + expect(result).toBeUndefined(); + }); + it('fetchSessions - base case', async () => { const result = await fetchSessions(serverUrl, user1.id); expect(result).toBeDefined(); @@ -168,6 +185,21 @@ describe('sessions', () => { expect(result.failed).toBe(true); }); + it('login - handle throw after login request', async () => { + jest.spyOn(DatabaseManager, 'setActiveServerDatabase').mockImplementationOnce(throwFunc); + + const result = await login(serverUrl, {config: {DiagnosticId: 'diagnosticid'}} as LoginArgs); + expect(result).toBeDefined(); + expect(result.error).toBeDefined(); + expect(result.failed).toBe(false); + }); + + it('logout - base case', async () => { + const result = await logout(serverUrl, true, true, true); + expect(result).toBeDefined(); + expect(result.data).toBeDefined(); + }); + it('cancelSessionNotification - handle not found database', async () => { const result = await cancelSessionNotification('foo'); expect(result).toBeDefined(); @@ -192,6 +224,12 @@ describe('sessions', () => { expect(result.error).toBeUndefined(); }); + it('cancelSessionNotification - no expired session', async () => { + const result = await cancelSessionNotification(serverUrl); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + }); + it('scheduleSessionNotification - handle not found database', async () => { const result = await scheduleSessionNotification('foo'); expect(result).toBeDefined(); @@ -216,6 +254,20 @@ describe('sessions', () => { expect(result.error).toBeUndefined(); }); + it('scheduleSessionNotification - no session', async () => { + mockClient.getSessions.mockImplementationOnce(() => []); + const result = await scheduleSessionNotification(serverUrl); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + }); + + it('scheduleSessionNotification - null sessions', async () => { + mockClient.getSessions.mockImplementationOnce(() => null as any); + const result = await scheduleSessionNotification(serverUrl); + expect(result).toBeDefined(); + expect(result.error).toBeUndefined(); + }); + it('sendPasswordResetEmail - handle error', async () => { mockClient.sendPasswordResetEmail.mockImplementationOnce(jest.fn(throwFunc)); const result = await sendPasswordResetEmail('foo', ''); @@ -245,6 +297,15 @@ describe('sessions', () => { expect(result.failed).toBe(false); }); + it('ssoLogin - handle throw after login request', async () => { + jest.spyOn(DatabaseManager, 'setActiveServerDatabase').mockImplementationOnce(throwFunc); + + const result = await ssoLogin(serverUrl, 'servername', 'diagnosticid', 'authtoken', 'csrftoken'); + expect(result).toBeDefined(); + expect(result.error).toBeDefined(); + expect(result.failed).toBe(false); + }); + it('findSession - handle not found database', async () => { const result = await findSession('foo', []); expect(result).toBeUndefined(); @@ -277,8 +338,35 @@ describe('sessions', () => { expect(session).toBeDefined(); }); + it('findSession - non-match device token', async () => { + await DatabaseManager.appDatabase?.operator.handleGlobal({ + globals: [{id: GLOBAL_IDENTIFIERS.DEVICE_TOKEN, value: 'diffdeviceid'}], + prepareRecordsOnly: false, + }); + + const session = await findSession(serverUrl, [session1]); + expect(session).toBeDefined(); + }); + it('findSession - by csrf', async () => { const session = await findSession(serverUrl, [session1]); expect(session).toBeDefined(); }); + + it('findSession - no csrf token', async () => { + mockGetCSRFFromCookie.mockResolvedValueOnce(''); + const session = await findSession(serverUrl, [session1]); + expect(session).toBeUndefined(); + }); + + it('findSession - by os', async () => { + const session = await findSession(serverUrl, [{...session1, props: {os: Platform.OS, csrf: 'diffcsrfid'}}]); + expect(session).toBeDefined(); + }); + + it('findSession - handle error', async () => { + jest.spyOn(DatabaseManager, 'getServerDatabaseAndOperator').mockImplementationOnce(throwFunc); + const result = await findSession(serverUrl, []); + expect(result).toBeUndefined(); + }); }); diff --git a/app/actions/remote/session.ts b/app/actions/remote/session.ts index 60c8845ce94..fbe42bfb29e 100644 --- a/app/actions/remote/session.ts +++ b/app/actions/remote/session.ts @@ -149,6 +149,8 @@ export const logout = async (serverUrl: string, skipServerLogout = false, remove if (!skipEvents) { DeviceEventEmitter.emit(Events.SERVER_LOGOUT, {serverUrl, removeServer}); } + + return {data: true}; }; export const cancelSessionNotification = async (serverUrl: string) => { From 1f29c77a6e5a81b057afc655cc9351e4942852c6 Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Mon, 25 Nov 2024 12:02:59 -0500 Subject: [PATCH 17/36] MM-59432 Add tests for actions/remote/custom_emoji (#8372) * Add tests for actions/remote/custom_emoji * Expect calls to forceLogoutIfNecessary in tests --- app/actions/remote/custom_emoji.test.ts | 124 ++++++++++++++++++++++++ app/actions/remote/custom_emoji.ts | 12 ++- 2 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 app/actions/remote/custom_emoji.test.ts diff --git a/app/actions/remote/custom_emoji.test.ts b/app/actions/remote/custom_emoji.test.ts new file mode 100644 index 00000000000..69f3f4ad3f6 --- /dev/null +++ b/app/actions/remote/custom_emoji.test.ts @@ -0,0 +1,124 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {forceLogoutIfNecessary} from '@actions/remote/session'; +import DatabaseManager from '@database/manager'; +import NetworkManager from '@managers/network_manager'; +import {getFullErrorMessage} from '@utils/errors'; +import {logDebug} from '@utils/log'; + +import {fetchCustomEmojis, searchCustomEmojis, fetchCustomEmojiInBatchForTest} from './custom_emoji'; + +jest.mock('@managers/network_manager'); +jest.mock('@utils/log'); +jest.mock('@utils/errors'); +jest.mock('@actions/remote/session'); + +const serverUrl = 'baseHandler.test.com'; + +const emojiId = 'emoji_id'; +const emoji = {id: emojiId, name: 'emoji_name'}; +const mockEmojis = [emoji]; +const error = new Error('Test error'); + +beforeEach(async () => { + jest.clearAllMocks(); + await DatabaseManager.init([serverUrl]); +}); + +describe('fetchCustomEmojis', () => { + it('should fetch custom emojis successfully', async () => { + const mockClient = { + getCustomEmojis: jest.fn().mockResolvedValue(mockEmojis), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + const result = await fetchCustomEmojis(serverUrl); + + expect(result).toEqual({data: mockEmojis}); + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.getCustomEmojis).toHaveBeenCalled(); + }); + + it('should handle error during fetch custom emojis', async () => { + const mockClient = { + getCustomEmojis: jest.fn().mockRejectedValue(error), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + (getFullErrorMessage as jest.Mock).mockReturnValue('Full error message'); + + const result = await fetchCustomEmojis(serverUrl); + + expect(result).toEqual({error}); + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.getCustomEmojis).toHaveBeenCalled(); + expect(logDebug).toHaveBeenCalledWith('error on fetchCustomEmojis', 'Full error message'); + expect(forceLogoutIfNecessary).toHaveBeenCalled(); + }); +}); + +describe('searchCustomEmojis', () => { + it('should search custom emojis successfully', async () => { + const term = 'emoji'; + const mockClient = { + searchCustomEmoji: jest.fn().mockResolvedValue(mockEmojis), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + const result = await searchCustomEmojis(serverUrl, term); + + expect(result).toEqual({data: mockEmojis}); + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.searchCustomEmoji).toHaveBeenCalledWith(term); + }); + + it('should handle error during search custom emojis', async () => { + const term = 'emoji'; + const mockClient = { + searchCustomEmoji: jest.fn().mockRejectedValue(error), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + (getFullErrorMessage as jest.Mock).mockReturnValue('Full error message'); + + const result = await searchCustomEmojis(serverUrl, term); + + expect(result).toEqual({error}); + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.searchCustomEmoji).toHaveBeenCalledWith(term); + expect(logDebug).toHaveBeenCalledWith('error on searchCustomEmojis', 'Full error message'); + expect(forceLogoutIfNecessary).toHaveBeenCalled(); + }); +}); + +describe('fetchEmojisByName', () => { + it('should fetch emojis by name successfully', async () => { + const mockClient = { + getCustomEmojiByName: jest.fn().mockResolvedValue(emoji), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + await fetchCustomEmojiInBatchForTest(serverUrl, emoji.name); + + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.getCustomEmojiByName).toHaveBeenCalledWith(emoji.name); + }); + + it('should handle no emojis', async () => { + const mockClient = { + getCustomEmojiByName: jest.fn().mockRejectedValue('error message'), + }; + (NetworkManager.getClient as jest.Mock).mockReturnValue(mockClient); + + await fetchCustomEmojiInBatchForTest(serverUrl, emoji.name); + + expect(NetworkManager.getClient).toHaveBeenCalledWith(serverUrl); + expect(mockClient.getCustomEmojiByName).toHaveBeenCalledWith(emoji.name); + }); + + it('should handle error during fetch emojis by name', async () => { + (NetworkManager.getClient as jest.Mock).mockRejectedValue('error message'); + await fetchCustomEmojiInBatchForTest(serverUrl, emoji.name); + + expect(logDebug).toHaveBeenCalled(); + }); +}); diff --git a/app/actions/remote/custom_emoji.ts b/app/actions/remote/custom_emoji.ts index 3a309420043..4b5188311f6 100644 --- a/app/actions/remote/custom_emoji.ts +++ b/app/actions/remote/custom_emoji.ts @@ -53,7 +53,8 @@ export const searchCustomEmojis = async (serverUrl: string, term: string) => { }; const names = new Set(); -const debouncedFetchEmojiByNames = debounce(async (serverUrl: string) => { + +export const fetchEmojisByName = async (serverUrl: string) => { try { const client = NetworkManager.getClient(serverUrl); const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl); @@ -77,7 +78,9 @@ const debouncedFetchEmojiByNames = debounce(async (serverUrl: string) => { logDebug('error on debouncedFetchEmojiByNames', getFullErrorMessage(error)); return {error}; } -}, 200, false, () => { +}; + +const debouncedFetchEmojiByNames = debounce(fetchEmojisByName, 200, false, () => { names.clear(); }); @@ -85,3 +88,8 @@ export const fetchCustomEmojiInBatch = (serverUrl: string, emojiName: string) => names.add(emojiName); return debouncedFetchEmojiByNames.apply(null, [serverUrl]); }; + +export const fetchCustomEmojiInBatchForTest = (serverUrl: string, emojiName: string) => { + names.add(emojiName); + return fetchEmojisByName(serverUrl); +}; From 50a7b14b6a6bb586bcbf59d06c6cd141306a68fa Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 25 Nov 2024 18:47:29 +0100 Subject: [PATCH 18/36] Translations update from Mattermost Weblate (#8373) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Translated using Weblate (Swedish) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/sv/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/uk/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/uk/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/uk/ * Translated using Weblate (Czech) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/cs/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/uk/ * Translated using Weblate (German) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/de/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/uk/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/uk/ * Translated using Weblate (English (Australia)) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/en_AU/ * Translated using Weblate (Turkish) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/tr/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/uk/ * Translated using Weblate (Japanese) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/ja/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/uk/ * Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/zh_Hans/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (1194 of 1194 strings) Translation: Mattermost/mattermost-mobile-v2 Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile-v2/uk/ --------- Co-authored-by: MArtin Johnson Co-authored-by: Serhii Khomiuk Co-authored-by: Martin Mičuda Co-authored-by: jprusch Co-authored-by: Matthew Williams Co-authored-by: Kaya Zeren Co-authored-by: kaakaa Co-authored-by: ThrRip --- assets/base/i18n/cs.json | 2 + assets/base/i18n/de.json | 2 + assets/base/i18n/en_AU.json | 9 + assets/base/i18n/ja.json | 9 + assets/base/i18n/sv.json | 9 + assets/base/i18n/tr.json | 10 + assets/base/i18n/uk.json | 628 ++++++++++++++++++------------------ assets/base/i18n/zh-CN.json | 19 +- 8 files changed, 369 insertions(+), 319 deletions(-) diff --git a/assets/base/i18n/cs.json b/assets/base/i18n/cs.json index baf8deb5b7b..70ad3bee214 100644 --- a/assets/base/i18n/cs.json +++ b/assets/base/i18n/cs.json @@ -454,6 +454,8 @@ "login_mfa.tokenReq": "Zadejte prosím token MFA", "markdown.latex.error": "Chyba při vykreslování Latexu", "markdown.max_nodes.error": "Tato zpráva je příliš dlouhá na to, aby byla plně zobrazena na mobilním zařízení. Zobrazte ji na desktopu nebo kontaktujte správce, aby zvýšil tento limit.", + "markdown.parse_error": "Chyba při zpracování tohoto textu", + "markdown.render_error": "Došlo k chybě při vykreslování tohoto textu", "mentions.empty.paragraph": "Zde uvidíte zprávy, když vás někdo zmíní nebo použije termíny, které sledujete.", "mentions.empty.title": "Zatím žádné zmínky", "mobile.about.appVersion": "Verze aplikace: {version} (Build {number})", diff --git a/assets/base/i18n/de.json b/assets/base/i18n/de.json index e0655ea01eb..cf351d2e499 100644 --- a/assets/base/i18n/de.json +++ b/assets/base/i18n/de.json @@ -454,6 +454,8 @@ "login_mfa.tokenReq": "Bitte gib den MFA-Token ein", "markdown.latex.error": "Latex-Rendering-Fehler", "markdown.max_nodes.error": "Diese Nachricht ist zu lang, um auf einem mobilen Gerät vollständig angezeigt zu werden. Bitte sehen Sie sie sich auf dem Desktop an oder kontaktieren Sie einen Administrator, um dieses Limit zu erhöhen.", + "markdown.parse_error": "Beim Verarbeiten dieses Textes ist ein Fehler aufgetreten", + "markdown.render_error": "Beim Rendern dieses Textes ist ein Fehler aufgetreten", "mentions.empty.paragraph": "Hier wirst Du benachrichtigt, wenn jemand dich erwähnt oder Begriffe verwendet, die Du überwachst.", "mentions.empty.title": "Noch keine Erwähnungen", "mobile.about.appVersion": "App Version: {version} (Build {number})", diff --git a/assets/base/i18n/en_AU.json b/assets/base/i18n/en_AU.json index 10cd75d904d..e409c81314e 100644 --- a/assets/base/i18n/en_AU.json +++ b/assets/base/i18n/en_AU.json @@ -454,6 +454,8 @@ "login_mfa.tokenReq": "Please enter an MFA token", "markdown.latex.error": "Latex render error", "markdown.max_nodes.error": "This message is too long to by shown fully on a mobile device. Please view it on desktop or contact an admin to increase this limit.", + "markdown.parse_error": "An error occurred while parsing this text", + "markdown.render_error": "An error occurred while rendering this text", "mentions.empty.paragraph": "You'll see messages here when someone mentions you or uses terms you're monitoring.", "mentions.empty.title": "No Mentions yet", "mobile.about.appVersion": "App Version: {version} (Build {number})", @@ -1175,6 +1177,13 @@ "user.settings.notifications.email_threads.description": "Notify me about all replies to threads I'm following", "user.tutorial.long_press": "Long-press on an item to view a user's profile", "user_profile.custom_status": "Custom Status", + "user_settings.notifications.test_notification.body": "Not receiving notifications? Start by sending a test notification to all your devices to check if they’re working as expected. If issues persist, explore ways to solve them with troubleshooting steps.", + "user_settings.notifications.test_notification.go_to_docs": "Troubleshooting docs", + "user_settings.notifications.test_notification.send_button.error": "Error sending test notification", + "user_settings.notifications.test_notification.send_button.send": "Send a test notification", + "user_settings.notifications.test_notification.send_button.sending": "Sending a test notification", + "user_settings.notifications.test_notification.send_button.sent": "Test notification sent", + "user_settings.notifications.test_notification.title": "Troubleshooting notifications", "user_status.away": "Away", "user_status.dnd": "Do Not Disturb", "user_status.offline": "Offline", diff --git a/assets/base/i18n/ja.json b/assets/base/i18n/ja.json index 8623325a3d9..d47f264e1e8 100644 --- a/assets/base/i18n/ja.json +++ b/assets/base/i18n/ja.json @@ -454,6 +454,8 @@ "login_mfa.tokenReq": "多要素認証トークンを入力してください", "markdown.latex.error": "Latex表示エラー", "markdown.max_nodes.error": "このメッセージは長すぎるため、モバイルデバイスでは完全に表示されません。デスクトップで表示するか、管理者に連絡して制限を増やしてください。", + "markdown.parse_error": "このテキストの解析中にエラーが発生しました", + "markdown.render_error": "このテキストのレンダリング中にエラーが発生しました", "mentions.empty.paragraph": "誰かがあなたにメンションしたり、あなたがモニタリングしている用語を使用した場合、ここにメッセージが表示されます。", "mentions.empty.title": "またメンションはありません", "mobile.about.appVersion": "バージョン: {version} (ビルド {number})", @@ -1175,6 +1177,13 @@ "user.settings.notifications.email_threads.description": "フォローしているスレッドに対するすべての返信を通知する", "user.tutorial.long_press": "ユーザーのプロフィールを表示するために、アイテムを長押ししてください", "user_profile.custom_status": "カスタムステータス", + "user_settings.notifications.test_notification.body": "通知が届きませんか? まず、すべてのデバイスにテスト通知を送信し、期待通りに動作しているか確認してみましょう。問題が解決しない場合、トラブルシューティングの手順で解決方法を探ってみてください。", + "user_settings.notifications.test_notification.go_to_docs": "トラブルシューディング文書", + "user_settings.notifications.test_notification.send_button.error": "テスト通知の送信エラー", + "user_settings.notifications.test_notification.send_button.send": "テスト通知を送信する", + "user_settings.notifications.test_notification.send_button.sending": "テスト通知を送信しています", + "user_settings.notifications.test_notification.send_button.sent": "テスト通知が送信されました", + "user_settings.notifications.test_notification.title": "通知のトラブルシューティング", "user_status.away": "離席中", "user_status.dnd": "取り込み中", "user_status.offline": "オフライン", diff --git a/assets/base/i18n/sv.json b/assets/base/i18n/sv.json index 3b84af9b3a4..4ba9ab24a1b 100644 --- a/assets/base/i18n/sv.json +++ b/assets/base/i18n/sv.json @@ -454,6 +454,8 @@ "login_mfa.tokenReq": "Ange ett MFA Token", "markdown.latex.error": "Fel i Latex-återgivning", "markdown.max_nodes.error": "Meddelandet är för långt för att kunna visas på en mobil. Du kan se det i en dator eller kontakta en administratör för att utöka gränsen.", + "markdown.parse_error": "Ett fel inträffade vid tolkningen av texten", + "markdown.render_error": "Ett fel inträffade vid återskapandet av texten", "mentions.empty.paragraph": "Här visas meddelanden när någon nämner dig eller använder termer som du bevakar.", "mentions.empty.title": "Inga omnämnanden ännu", "mobile.about.appVersion": "App-version: {version} (Build {number})", @@ -1175,6 +1177,13 @@ "user.settings.notifications.email_threads.description": "Notifiera mig om alla svar i trådar som jag följer", "user.tutorial.long_press": "Tryck länge på ett objekt för att visa en användares profil", "user_profile.custom_status": "Anpassad status", + "user_settings.notifications.test_notification.body": "Får du inga aviseringar? Börja med att skicka ett testnotifiering till alla dina enheter för att kontrollera om de fungerar som förväntat. Om problemen kvarstår, lösa dem med hjälp av felsökningsstegen.", + "user_settings.notifications.test_notification.go_to_docs": "Felsökningsinformation", + "user_settings.notifications.test_notification.send_button.error": "Fel vid sändning av testnotifiering", + "user_settings.notifications.test_notification.send_button.send": "Skicka en notifiering för test", + "user_settings.notifications.test_notification.send_button.sending": "Skickar en testnotifiering", + "user_settings.notifications.test_notification.send_button.sent": "Testnotifiering skickad", + "user_settings.notifications.test_notification.title": "Felsök notifieringar", "user_status.away": "Tillfälligt borta", "user_status.dnd": "Stör ej", "user_status.offline": "Offline", diff --git a/assets/base/i18n/tr.json b/assets/base/i18n/tr.json index a8600d8fccc..676d010a1cd 100644 --- a/assets/base/i18n/tr.json +++ b/assets/base/i18n/tr.json @@ -454,6 +454,8 @@ "login_mfa.tokenReq": "Lütfen bir ÇAD kodu yazın", "markdown.latex.error": "Latex oluşturma hatası", "markdown.max_nodes.error": "Bu ileti bir mobil aygıtta tam olarak görüntülenemeyecek kadar uzun. Lütfen iletiyi masaüstü uygulamasından görüntüleyin ya da bu sınırı artırmak için bir yönetici ile görüşün.", + "markdown.parse_error": "Bu metin işlenirken bir sorun çıktı", + "markdown.render_error": "Bu metin oluşturulurken bir sorun çıktı", "mentions.empty.paragraph": "Birisi sizi andığında ya da izlediğiniz terimleri kullandığında burada iletiler görürsünüz.", "mentions.empty.title": "Henüz bir anma yok", "mobile.about.appVersion": "Uygulama sürümü: {version} (Build {number})", @@ -938,6 +940,7 @@ "post_body.check_for_out_of_channel_mentions.message_last": "? Tüm ileti geçmişini görebilirler.", "post_body.commentedOn": "{name}{apostrophe} iletisine yorum yapıldı: ", "post_body.deleted": "(ileti silindi)", + "post_header.visible_message": "(Yalnızca siz görebilirsiniz)", "post_info.auto_responder": "Otomatik yanıt", "post_info.bot": "Bot", "post_info.del": "Sil", @@ -1174,6 +1177,13 @@ "user.settings.notifications.email_threads.description": "İzlediğim konulara yazılan tüm yanıtlar ile ilgili bildirim gönderilsin", "user.tutorial.long_press": "Bir kullanıcının profilini görüntülemek için bir ögeye uzun dokunun", "user_profile.custom_status": "Özel durum", + "user_settings.notifications.test_notification.body": "Bildirimleri almıyor musunuz? Beklendiği gibi çalışıp çalışmadıklarını kontrol etmek için tüm aygıtlarınıza bir deneme bildirimi gönderin. Sorun sürüyorsa, sorun giderme adımlarıyla bunları çözmenin yollarını öğrenin.", + "user_settings.notifications.test_notification.go_to_docs": "Sorun giderme belgeleri", + "user_settings.notifications.test_notification.send_button.error": "Deneme bildirimi gönderilirken sorun çıktı", + "user_settings.notifications.test_notification.send_button.send": "Deneme bildirimi gönder", + "user_settings.notifications.test_notification.send_button.sending": "Deneme bildirimi gönderiliyor", + "user_settings.notifications.test_notification.send_button.sent": "Deneme bildirimi gönderildi", + "user_settings.notifications.test_notification.title": "Sorun çözme bildirimleri", "user_status.away": "Uzakta", "user_status.dnd": "Rahatsız etmeyin", "user_status.offline": "Çevrim dışı", diff --git a/assets/base/i18n/uk.json b/assets/base/i18n/uk.json index f1fa8baaeef..0fdeb6a409f 100644 --- a/assets/base/i18n/uk.json +++ b/assets/base/i18n/uk.json @@ -1,14 +1,14 @@ { "about.date": "Дата збірки:", - "about.enterpriseEditionLearn": "Детальніше про Корпоративну версію читайте на ", + "about.enterpriseEditionLearn": "Детальніше про версію Enterprise читайте на ", "about.enterpriseEditionSt": "Сучасне спілкування у вашій локальній мережі.", - "about.enterpriseEditione1": "Корпоративна версія", + "about.enterpriseEditione1": "Версія Enterprise", "about.hash": "Геш збірки:", "about.hashee": "Геш збірки EE:", "about.teamEditionLearn": "Приєднуйтесь до спільноти Mattermost на", "about.teamEditionSt": "Вся комунікація вашої команди в одному місці, з миттєвим пошуком і доступом з будь-якого місця.", "about.teamEditiont0": "Командне видання", - "about.teamEditiont1": "Корпоративне видання", + "about.teamEditiont1": "Версія Enterprise", "account.logout": "Вийти", "account.logout_from": "Вийти з {serverName}", "account.settings": "Налаштування", @@ -78,25 +78,25 @@ "apps.error.unknown": "Виникла невідома помилка.", "apps.suggestion.dynamic.error": "Помилка динамічного вибору", "apps.suggestion.errors.parser_error": "Помилка аналізу", - "apps.suggestion.no_dynamic": "Для динамічних пропозицій не було отримано жодних даних", + "apps.suggestion.no_dynamic": "Дані для динамічних підказок не були отримані", "apps.suggestion.no_static": "Немає відповідних варіантів.", "apps.suggestion.no_suggestion": "Немає відповідних пропозицій.", - "archivedChannelMessage": "Ви переглядаєте **архівований канал**. Нові повідомлення не можуть бути опубліковані.", + "archivedChannelMessage": "Ви переглядаєте **архівний канал**. Нові повідомлення не можуть бути опубліковані.", "autocomplete_selector.unknown_channel": "Невідомий канал", - "browse_channels.archivedChannels": "Архівні канали", + "browse_channels.archivedChannels": "Архівні Канали", "browse_channels.dropdownTitle": "Показати", "browse_channels.noMore": "Більше немає каналів для приєднання", - "browse_channels.publicChannels": "Публічні канали", - "browse_channels.sharedChannels": "Спільні канали", + "browse_channels.publicChannels": "Публічні Канали", + "browse_channels.sharedChannels": "Спільні Канали", "browse_channels.showArchivedChannels": "Показати: Архівні канали", - "browse_channels.showPublicChannels": "Показати: Загальні канали", + "browse_channels.showPublicChannels": "Показати: Публічні канали", "browse_channels.showSharedChannels": "Показати: Спільні канали", "browse_channels.title": "Перегляд каналів", "camera_type.photo.option": "Зробити фото", "camera_type.video.option": "Записати відео", - "center_panel.archived.closeChannel": "Закрити канал", - "channel_add_members.add_members.button": "Додати учасників", - "channel_bookmark.add.detail_title": "Заголовок", + "center_panel.archived.closeChannel": "Закрити Канал", + "channel_add_members.add_members.button": "Додати Учасників", + "channel_bookmark.add.detail_title": "Назва", "channel_bookmark.add.emoji": "Додати емодзі", "channel_bookmark.add.failed_title": "Помилка додавання закладки", "channel_bookmark.add.file_cancel": "Скасування", @@ -118,35 +118,35 @@ "channel_bookmark_add.link": "Посилання", "channel_bookmark_add.link.input.description": "Додайте посилання на будь-яку публікацію, файл або будь-яке зовнішнє посилання", "channel_bookmark_add.link.invalid": "Будь ласка, введіть дійсне посилання", - "channel_files.empty.paragraph": "Файли, розміщені в цьому каналі, будуть показуватися тут.", + "channel_files.empty.paragraph": "Файли, розміщені на цьому каналі, будуть показуватися тут.", "channel_files.empty.title": "Файлів ще немає", "channel_files.noFiles.paragraph": "Цей канал не містить файлів із застосованими фільтрами", - "channel_files.noFiles.title": "Файлів не знайдено", - "channel_header.directchannel.you": "{ім'я відображення} (ви)", + "channel_files.noFiles.title": "Файлів не Знайдено", + "channel_header.directchannel.you": "{displayName} (ви)", "channel_header.info": "Переглянути інформацію", - "channel_header.member_count": "{кількість, множина, один {# учасник} інші {# учасники}}", - "channel_info.add_bookmark": "Додати закладку", + "channel_header.member_count": "{count, plural, one {# учасник} few {# учасника} other {# учасників}}", + "channel_info.add_bookmark": "Додати в закладки", "channel_info.add_bookmark.file": "Прикріпіть файл", "channel_info.add_bookmark.link": "Додати посилання", "channel_info.add_bookmark.max_reached": "Цей канал досяг максимальної кількості закладок.", "channel_info.add_members": "Додати учасників", "channel_info.alertNo": "Ні", "channel_info.alertYes": "Так", - "channel_info.alert_retry": "Спробуйте ще раз", + "channel_info.alert_retry": "Спробуйте Знову", "channel_info.archive": "Заархівувати канал", - "channel_info.archive_description.can_view_archived": "Це призведе до архівування каналу від команди. Вміст каналу все ще буде доступним для учасників каналу.\n\nВи впевнені, що хочете заархівувати {термін} {назва}?", - "channel_info.archive_description.cannot_view_archived": "Це заархівує канал з команди і видалить його з інтерфейсу користувача. Заархівовані канали можна розархівувати, якщо вони знадобляться знову.\n\nВи впевнені, що хочете заархівувати {термін} {назва}?", - "channel_info.archive_failed": "Виникла помилка при спробі заархівувати канал {Ім'я_відображення}", - "channel_info.archive_title": "Архів {термін}", + "channel_info.archive_description.can_view_archived": "Це призведе до архівування каналу від команди. Вміст каналу все ще буде доступний учасникам каналу. \n\nВи впевнені, що хочете заархівувати {term}{name}?", + "channel_info.archive_description.cannot_view_archived": "Це заархівує канал з команди і видалить його з інтерфейсу користувача. Заархівовані канали можна розархівувати, якщо вони знадобляться знову. \n\nВи впевнені, що хочете заархівувати {term}{name}?", + "channel_info.archive_failed": "Виникла помилка при спробі заархівувати канал {displayName}", + "channel_info.archive_title": "Архівувати {term}", "channel_info.channel_auto_follow_threads": "Слідкуйте за всіма обговореннями на цьому каналі", "channel_info.channel_auto_follow_threads_failed": "Виникла помилка при спробі автоматичного відстеження всіх обговорень у каналі {displayName}", "channel_info.channel_files": "Файли", "channel_info.close": "Закрити", - "channel_info.close_dm": "Закрити пряме повідомлення", - "channel_info.close_dm_channel": "Ви впевнені, що хочете закрити це пряме повідомлення? Це прибере його з вашої домашньої сторінки, але ви завжди зможете відкрити його знову.", + "channel_info.close_dm": "Закрити приватне повідомлення", + "channel_info.close_dm_channel": "Ви впевнені, що хочете закрити це особисте повідомлення? Це прибере його з вашої домашньої сторінки, але ви завжди зможете відкрити його знову.", "channel_info.close_gm": "Закрити повідомлення групи", - "channel_info.close_gm_channel": "Ви впевнені, що хочете закрити це повідомлення групи? Це прибере його з вашої домашньої сторінки, але ви завжди зможете відкрити його знову.", - "channel_info.convert_failed": "Нам не вдалося перетворити <ім'я_відображення> на приватний канал.", + "channel_info.close_gm_channel": "Ви впевнені, що хочете закрити це повідомлення групи? Це прибере його з вашого головного екрана, але ви завжди зможете відкрити його знову.", + "channel_info.convert_failed": "Не вдалося перетворити {displayName} на приватний канал.", "channel_info.convert_gm_to_channel": "Перетворити на Приватний канал", "channel_info.convert_gm_to_channel.button_text": "Перетворити на Приватний канал", "channel_info.convert_gm_to_channel.button_text_converting": "Конвертація...", @@ -160,22 +160,22 @@ "channel_info.convert_gm_to_channel.warning.no_teams.body": "Групове повідомлення не може бути перетворене на канал, оскільки учасники не є членами однієї команди. Додайте всіх учасників до однієї команди, щоб перетворити це групове повідомлення на канал.", "channel_info.convert_gm_to_channel.warning.no_teams.header": "Неможливо перетворити на канал, оскільки учасники групи є членами різних команд", "channel_info.convert_private": "Перетворити на приватний канал", - "channel_info.convert_private_description": "Коли ви перетворюєте {ім'я_відображення} на приватний канал, історія та членство зберігаються. Загальнодоступні файли залишаються доступними для всіх, хто має посилання. Членство в приватному каналі можливе лише за запрошенням.\n\nЗміна є остаточною і не може бути скасована.\n\nВидійсно хочете перетворити {Ім'я_відображення} на приватний канал?", - "channel_info.convert_private_success": "{ім'я_відображення} тепер є приватним каналом.", - "channel_info.convert_private_title": "Перетворити {ім'я_відображення} на приватний канал?", + "channel_info.convert_private_description": "Коли ви перетворюєте {displayName} на приватний канал, історія та членство зберігаються. Загальнодоступні файли залишаються доступними для всіх, хто має посилання. Членство в приватному каналі можливе лише за запрошенням. \n\nЗміна є остаточною і не може бути скасована. \n\nВи впевнені, що хочете перетворити {displayName} на приватний канал?", + "channel_info.convert_private_success": "{displayName} тепер є приватним каналом.", + "channel_info.convert_private_title": "Перетворити {displayName} на приватний канал?", "channel_info.copied": "Скопійовано", "channel_info.copy_link": "Скопіювати Посилання", "channel_info.copy_purpose_text": "Копіювання тексту призначення", - "channel_info.custom_status": "Особливий статус:", + "channel_info.custom_status": "Користувацький статус:", "channel_info.edit_header": "Редагувати заголовок", "channel_info.error_close": "Закрити", - "channel_info.favorite": "Улюблене", + "channel_info.favorite": "Обране", "channel_info.favorited": "Додано до обраного", "channel_info.header": "Заголовок:", "channel_info.ignore_mentions": "Ігнорувати @channel, @here, @all", "channel_info.leave": "Покинути", "channel_info.leave_channel": "Покинути канал", - "channel_info.leave_private_channel": "Ви впевнені, що хочете покинути приватний канал {ім'я_відображення}? Ви не зможете знову приєднатися до каналу, якщо вас не запросять знову.", + "channel_info.leave_private_channel": "Ви впевнені, що бажаєте залишити приватний канал {displayName}? Ви не зможете повторно приєднатися до каналу, поки вас не запросять знову.", "channel_info.leave_public_channel": "Ви впевнені, що хочете покинути публічний канал {displayName}? Ви завжди зможете знову приєднатися.", "channel_info.local_time": "Місцевий час", "channel_info.members": "Члени", @@ -187,47 +187,47 @@ "channel_info.notification.default": "За замовчуванням", "channel_info.notification.mention": "Згадки", "channel_info.notification.none": "Ніколи", - "channel_info.pinned_messages": "Закріплені повідомлення", + "channel_info.pinned_messages": "Закріплені Повідомлення", "channel_info.position": "Посада", - "channel_info.private_channel": "Приватний канал", + "channel_info.private_channel": "Приватний Канал", "channel_info.public_channel": "Публічний канал", "channel_info.send_a_mesasge": "Надіслати повідомлення", "channel_info.send_mesasge": "Надіслати повідомлення", - "channel_info.set_header": "Встановити заголовок", + "channel_info.set_header": "Встановити Заголовок", "channel_info.unarchive": "Розархівувати канал", - "channel_info.unarchive_description": "Ви впевнені, що хочете розархівувати {термін} {назва}?", - "channel_info.unarchive_failed": "Виникла помилка при спробі розархівувати канал {ім'я_відображення}", - "channel_info.unarchive_title": "Розархівувати {термін}", + "channel_info.unarchive_description": "Ви впевнені, що бажаєте розархівувати {term} {name}?", + "channel_info.unarchive_failed": "Під час спроби розархівувати канал {displayName} сталася помилка", + "channel_info.unarchive_title": "Розархівувати {term}", "channel_into.convert_gm_to_channel.team_selector.label": "Команда", "channel_into.convert_gm_to_channel.team_selector.placeholder": "Виберіть команду", - "channel_intro.createdBy": "Створено {користувачем} {дата}", - "channel_intro.createdOn": "Створено {дата}", + "channel_intro.createdBy": "Створено {user}{date}", + "channel_intro.createdOn": "Створено {date}", "channel_list.channels_category": "Канали", "channel_list.dms_category": "Особисті повідомлення", - "channel_list.favorites_category": "Обране", + "channel_list.favorites_category": "Обрані", "channel_list.find_channels": "Знайти канали...", "channel_loader.someone": "Хтось", "channel_modal.descriptionHelp": "Опишіть, як слід використовувати цей канал.", "channel_modal.header": "Заголовок", - "channel_modal.headerEx": "Використовуйте розкривний список для форматування тексту заголовка", + "channel_modal.headerEx": "Використовуйте Markdown для форматування тексту заголовка", "channel_modal.headerHelp": "Вкажіть текст, який буде відображатися в заголовку каналу поруч з назвою каналу. Наприклад, додайте часто використовувані посилання, ввівши текст посилання [Назва посилання](http://example.com).", - "channel_modal.makePrivate.description": "Якщо канал встановлено як приватний, лише запрошені учасники команди можуть мати доступ до нього та брати участь у ньому", + "channel_modal.makePrivate.description": "Якщо канал встановлено як приватний, лише запрошені члени команди можуть отримати доступ та брати участь у ньому", "channel_modal.makePrivate.label": "Зробити приватним", "channel_modal.name": "Ім'я", "channel_modal.nameEx": "Помилки, Маркетинг", "channel_modal.optional": "(не обов'язково)", - "channel_modal.purpose": "Призначення", - "channel_modal.purposeEx": "Канал для повідомлення про помилки та покращень", + "channel_modal.purpose": "Мета", + "channel_modal.purposeEx": "Канал для відправки повідомлень про помилки та поліпшення", "channel_notification_preferences.default": "(за замовчуванням)", - "channel_notification_preferences.muted_content": "Ви можете змінити налаштування сповіщень, але ви не отримуватимете сповіщень, доки у каналу не буде увімкнено звук.", - "channel_notification_preferences.muted_title": "Цей канал вимкнено", + "channel_notification_preferences.muted_content": "Ви можете змінити налаштування сповіщень, але ви їх не отримуватимете, доки не ввімкнете сповіщення каналу.", + "channel_notification_preferences.muted_title": "Сповіщення для цього каналу вимкнено", "channel_notification_preferences.notification.all": "Всі нові повідомлення", "channel_notification_preferences.notification.mention": "Тільки згадки", "channel_notification_preferences.notification.none": "Нічого", - "channel_notification_preferences.notification.thread_replies": "Сповіщати мене про відповіді на теми, за якими я стежу в цьому каналі", + "channel_notification_preferences.notification.thread_replies": "Сповіщати мене про відповіді на обговорення, за якими я стежу в цьому каналі", "channel_notification_preferences.notify_about": "Сповістити мене про...", "channel_notification_preferences.reset_default": "Скидання до налаштувань за замовчуванням", - "channel_notification_preferences.thread_replies": "Відповіді на теми", + "channel_notification_preferences.thread_replies": "Відповіді на обговорення", "channel_notification_preferences.unmute_content": "Увімкнути звук на каналі", "combined_system_message.added_to_channel.many_expanded": "{users} та {lastUser} були **додані до каналу** користувачем {actor}.", "combined_system_message.added_to_channel.one": "{firstUser} **запрошується на канал** користувачем {actor}.", @@ -243,78 +243,78 @@ "combined_system_message.joined_channel.two": "{firstUser} і {secondUser} **приєдналися до каналу**.", "combined_system_message.joined_team.many_expanded": "{users} і {lastUser} **приєдналися до команди**.", "combined_system_message.joined_team.one": "{firstUser} **приєднується до команди**.", - "combined_system_message.joined_team.one_you": "**приєднався до команди**.", + "combined_system_message.joined_team.one_you": "Ви **приєдналися до команди**.", "combined_system_message.joined_team.two": "{firstUser} і {secondUser} **приєдналися до команди**.", - "combined_system_message.left_channel.many_expanded": "{users} і {lastUser} **залишив канал**.", + "combined_system_message.left_channel.many_expanded": "{users} і {lastUser} **покинули канал**.", "combined_system_message.left_channel.one": "{firstUser}**покидає канал**.", "combined_system_message.left_channel.one_you": "Ви **залишили канал**.", "combined_system_message.left_channel.two": "{firstUser} і {secondUser} **покинули канал**.", - "combined_system_message.left_team.many_expanded": "{users} і {lastUser} **залишили команду**.", + "combined_system_message.left_team.many_expanded": "{users} і {lastUser} **покинули команду**.", "combined_system_message.left_team.one": "{firstUser} **залишає команду**.", - "combined_system_message.left_team.one_you": "**залишив команду**.", - "combined_system_message.left_team.two": "{firstUser} та {secondUser} **залишили команду**.", - "combined_system_message.removed_from_channel.many_expanded": "{users} та {lastUser} **видалені з каналу**.", - "combined_system_message.removed_from_channel.one": "{firstUser} **було видалено з каналу**.", - "combined_system_message.removed_from_channel.one_you": "Ви були **видалені з каналу**.", - "combined_system_message.removed_from_channel.two": "{firstUser} та {secondUser} були **видалені з каналу**.", + "combined_system_message.left_team.one_you": "Ви **покинули команду**.", + "combined_system_message.left_team.two": "{firstUser} та {secondUser} **покинули команду**.", + "combined_system_message.removed_from_channel.many_expanded": "{users} та {lastUser} було **видалено з каналу**.", + "combined_system_message.removed_from_channel.one": "{firstUser} було **видалено з каналу**.", + "combined_system_message.removed_from_channel.one_you": "Вас було **видалено з каналу**.", + "combined_system_message.removed_from_channel.two": "{firstUser} та {secondUser} було **видалено з каналу**.", "combined_system_message.removed_from_team.many_expanded": "{users} і {lastUser} **видалені з команди**.", - "combined_system_message.removed_from_team.one": "{firstUser} був **видалений з команди**.", - "combined_system_message.removed_from_team.one_you": "Ви були **вилучені з команди**.", - "combined_system_message.removed_from_team.two": "{firstUser} і {secondUser} **видалені з команди**.", + "combined_system_message.removed_from_team.one": "{firstUser} було **видалено з команди**.", + "combined_system_message.removed_from_team.one_you": "Вас **видалили з команди**.", + "combined_system_message.removed_from_team.two": "{firstUser} і {secondUser} було **видалено з команди**.", "combined_system_message.you": "Ви", "connection_banner.connected": "З'єднання відновлено", "connection_banner.connecting": "З'єднання...", "connection_banner.not_connected": "Немає підключення до Інтернету", "connection_banner.not_reachable": "Сервер недоступний", - "create_direct_message.title": "Створити пряме повідомлення", - "create_post.deactivated": "Ви переглядаєте архівований канал з деактивованим користувачем.", - "create_post.thread_reply": "Відповісти на цю тему...", + "create_direct_message.title": "Створити приватне повідомлення", + "create_post.deactivated": "Ви переглядаєте архівний канал з деактивованим користувачем.", + "create_post.thread_reply": "Відповісти в цьому обговоренні...", "create_post.write": "Написати у {channelDisplayName}", - "custom_status.expiry.at": "біля", + "custom_status.expiry.at": "о", "custom_status.expiry.until": "Доки", - "custom_status.expiry_dropdown.custom": "На вибір", + "custom_status.expiry_dropdown.custom": "Користувацькі", "custom_status.expiry_dropdown.date_and_time": "Дата і час", "custom_status.expiry_dropdown.dont_clear": "Не очищати", "custom_status.expiry_dropdown.four_hours": "4 години", "custom_status.expiry_dropdown.one_hour": "1 година", "custom_status.expiry_dropdown.thirty_minutes": "30 хвилин", - "custom_status.expiry_dropdown.this_week": "Цей тиждень", + "custom_status.expiry_dropdown.this_week": "Цього тижня", "custom_status.expiry_dropdown.today": "Сьогодні", "custom_status.expiry_time.today": "Сьогодні", "custom_status.expiry_time.tomorrow": "Завтра", "custom_status.failure_message": "Не вдалося оновити статус. Спробуйте ще раз", - "custom_status.set_status": "Встановіть спеціальний статус", + "custom_status.set_status": "Встановіть власний статус", "custom_status.suggestions.in_a_meeting": "На зустрічі", "custom_status.suggestions.on_a_vacation": "У відпустці", - "custom_status.suggestions.out_for_lunch": "Вийшов на обід", + "custom_status.suggestions.out_for_lunch": "На обіді", "custom_status.suggestions.out_sick": "Захворів(ла)", - "custom_status.suggestions.recent_title": "Нещодавно", + "custom_status.suggestions.recent_title": "Останні", "custom_status.suggestions.title": "Пропозиції", "custom_status.suggestions.working_from_home": "Працюю з дому", "date_separator.today": "Сьогодні", "date_separator.yesterday": "Вчора", - "default_skin_tone": "Відтінок шкіри за замовчуванням", + "default_skin_tone": "Тон шкіри За замовчуванням", "display_settings.clock.military": "24-годинний", "display_settings.clock.standard": "12-годинний", "display_settings.clockDisplay": "Відображення годинника", - "display_settings.crt": "Згорнуті теми відповідей", - "display_settings.crt.off": "Вимкнути", + "display_settings.crt": "Згорнуті відповіді в обговореннях", + "display_settings.crt.off": "Відключено", "display_settings.crt.on": "Увімкнути", "display_settings.theme": "Тема", "display_settings.timezone": "Часовий пояс", "display_settings.tz.auto": "Автоматично", - "display_settings.tz.manual": "Інструкція", + "display_settings.tz.manual": "Вручну", "download.error": "Не вдалося завантажити файл. Спробуйте пізніше", "edit_post.editPost": "Редагувати повідомлення...", "edit_post.save": "Зберегти", "edit_server.description": "Вкажіть ім'я відображення для цього сервера", - "edit_server.display_help": "Сервер: {посилання}", + "edit_server.display_help": "Сервер: {url}", "edit_server.save": "Зберегти", "edit_server.saving": "Збереження", - "edit_server.title": "Редагувати назву сервера", + "edit_server.title": "Редагувати ім'я сервера", "emoji_picker.activities": "Діяльність", "emoji_picker.animals-nature": "Тварини та природа", - "emoji_picker.custom": "На вибір", + "emoji_picker.custom": "Користувацькі", "emoji_picker.flags": "Прапори", "emoji_picker.food-drink": "Їжа та напої", "emoji_picker.objects": "Об'єкти", @@ -328,23 +328,23 @@ "emoji_skin.default": "тон шкіри за замовчуванням", "emoji_skin.light_skin_tone": "світлий відтінок шкіри", "emoji_skin.medium_dark_skin_tone": "середньо-темний відтінок шкіри", - "emoji_skin.medium_light_skin_tone": "середньо-світлий тон шкіри", - "emoji_skin.medium_skin_tone": "середній тон шкіри", + "emoji_skin.medium_light_skin_tone": "середньо-світлий відтінок шкіри", + "emoji_skin.medium_skin_tone": "середній відтінок шкіри", "extension.no_memberships.description": "Щоб ділитися контентом, вам потрібно бути членом команди на сервері Mattermost.", - "extension.no_memberships.title": "Ще не є учасником жодної команди", + "extension.no_memberships.title": "Ще не є членом жодної команди", "extension.no_servers.description": "Щоб ділитися контентом, вам потрібно увійти на сервер Mattermost.", "extension.no_servers.title": "Не підключений до жодного сервера", "file_upload.fileAbove": "Файли повинні бути меншими за {max}", "find_channels.directory": "Каталог", - "find_channels.new_channel": "Новий канал", - "find_channels.open_dm": "Відкрити в ПП", + "find_channels.new_channel": "Новий Канал", + "find_channels.open_dm": "Відкрити ПП", "find_channels.title": "Знайти канали", - "friendly_date.daysAgo": "{кількість} {кількість, множина, один {день} інші {дні}} тому", - "friendly_date.hoursAgo": "{кількість} {підрахунок, множина, одна {година} інші {години}} тому", - "friendly_date.minsAgo": "{кількість} {кількість, множина, одна {хв} інші {хвилини}} тому", - "friendly_date.monthsAgo": "{кількість} {кількість, множина, один {місяць} інші {місяці}} тому", + "friendly_date.daysAgo": "{count} {count, plural, one {день} few{дня} other {днів}} тому", + "friendly_date.hoursAgo": "{count} {count, plural, one {година} few{години} other {годин}} тому", + "friendly_date.minsAgo": "{count} {count, plural, one {хвилина} few{хвилини} other {хвилин}} тому", + "friendly_date.monthsAgo": "{count} {count, plural, one {місяць} few{місяці} other {місяців}} тому", "friendly_date.now": "Зараз", - "friendly_date.yearsAgo": "{кількість} {кількість, множина, один {рік} інші {роки}} тому", + "friendly_date.yearsAgo": "{count} {count, plural, one {рік} few{роки} other {років}} тому", "friendly_date.yesterday": "Вчора", "gallery.copy_link.failed": "Не вдалося скопіювати посилання в буфер обміну", "gallery.downloading": "Завантаження...", @@ -356,7 +356,7 @@ "gallery.save_failed": "Не вдається зберегти файл", "gallery.unsupported": "Попередній перегляд не підтримується для цього типу файлів. Спробуйте завантажити або поділитися, щоб відкрити його в іншій програмі.", "gallery.video_saved": "Відео збережено", - "general_settings.about": "Про додаток {Назва_додатку}", + "general_settings.about": "Про {appTitle}", "general_settings.advanced_settings": "Розширені налаштування", "general_settings.display": "Відображення", "general_settings.help": "Допомога", @@ -364,25 +364,25 @@ "general_settings.report_problem": "Повідомити про проблему", "generic.back": "Назад", "get_post_link_modal.title": "Скопіювати Посилання", - "global_threads.allThreads": "Всі твої потоки", - "global_threads.emptyThreads.message": "Будь-які теми, в яких ви згадувалися або брали участь, будуть показані тут, а також теми, за якими ви стежили.", - "global_threads.emptyThreads.title": "Ще немає потоків, за якими стежать", - "global_threads.emptyUnreads.message": "Схоже, ви вже в курсі.", - "global_threads.emptyUnreads.title": "Немає непрочитаних потоків", + "global_threads.allThreads": "Всі ваші обговорення", + "global_threads.emptyThreads.message": "Будь-які обговорення, в яких ви згадувалися або брали участь, будуть показані тут, а також теми, за якими ви стежили.", + "global_threads.emptyThreads.title": "Ще немає відслідковуваних обговорень", + "global_threads.emptyUnreads.message": "Схоже, ви вже все зрозуміли.", + "global_threads.emptyUnreads.title": "Немає непрочитаних обговорень", "global_threads.markAllRead.cancel": "Скасувати", "global_threads.markAllRead.markRead": "Позначити, як прочитане", - "global_threads.markAllRead.message": "Це очистить статус непрочитаних для всіх ваших потоків, показаних тут", - "global_threads.markAllRead.title": "Ви впевнені, що хочете позначити всі потоки як прочитані?", - "global_threads.options.mark_as_read": "Позначити як прочитане", - "global_threads.options.open_in_channel": "Відкрити в каналі", - "global_threads.options.title": "Дії з потоками", + "global_threads.markAllRead.message": "Це очистить статус непрочитаних для всіх ваших обговорень, показаних тут", + "global_threads.markAllRead.title": "Ви впевнені, що хочете позначити всі обговорення як прочитані?", + "global_threads.options.mark_as_read": "Позначити як Прочитане", + "global_threads.options.open_in_channel": "Відкрити в Каналі", + "global_threads.options.title": "Дії з обговореннями", "global_threads.unreads": "Непрочитані", - "home.header.plus_menu": "Параметри", + "home.header.plus_menu": "Опції", "integration_selector.multiselect.submit": "Готово", - "interactive_dialog.submit": "Надіслати", + "interactive_dialog.submit": "Відправити", "intro.add_members": "Додати учасників", - "intro.channel_info": "Інфо", - "intro.created_by": "створено {створювачем} {дата}.", + "intro.channel_info": "Інформація", + "intro.created_by": "створено {creator}{date}.", "intro.direct_message": "Це початок вашої розмови з {teammate}. Повідомлення та файли, якими ви обмінюєтеся тут, не будуть показані нікому іншому.", "intro.group_message.after_gm_as_dm": "Це початок вашої розмови з цією групою. Повідомлення та файли, якими ви ділитеся тут, не показуються нікому за межами групи.", "intro.group_message.all": "Ви отримаєте сповіщення про всю активність в цьому груповому повідомленні.", @@ -390,102 +390,102 @@ "intro.group_message.mention": "Ви обрали отримувати сповіщення лише коли вас згадують в цьому груповому повідомленні.", "intro.group_message.muted": "Це повідомлення групи наразі вимкнено, тому ви не отримаєте сповіщення.", "intro.group_message.none": "Ви вибрали опцію ніколи не отримувати сповіщення у цьому груповому повідомленні.", - "intro.private_channel": "Приватний канал", - "intro.public_channel": "Громадський канал", + "intro.private_channel": "Приватний Канал", + "intro.public_channel": "Публічний канал", "intro.townsquare": "Ласкаво просимо до {name}. Кожен автоматично стає учасником цього каналу, коли приєднується до команди.", - "intro.welcome": "Ласкаво просимо до каналу {Ім'я_відображення}.", + "intro.welcome": "Ласкаво просимо до каналу {displayName}.", "intro.welcome.private": "Лише запрошені користувачі можуть бачити повідомлення, розміщені в цьому приватному каналі.", "intro.welcome.public": "Додайте ще кількох членів команди до каналу або почніть розмову нижче.", "invite.members.already_member": "Ця людина вже є членом команди", "invite.members.user_is_guest": "Зверніться до адміністратора, щоб зробити цього гостя повноправним учасником", "invite.search.email_invite": "запросити", - "invite.search.no_results": "Ніхто відповідний не знайдений", + "invite.search.no_results": "Збігів не знайдено", "invite.searchPlaceholder": "Введіть ім'я або адресу електронної пошти…", - "invite.sendInvitationsTo": "Надсилайте запрошення до…", + "invite.sendInvitationsTo": "Надіслати запрошення до…", "invite.send_error": "Під час спроби надіслати запрошення сталася помилка. Будь ласка, перевірте підключення до мережі та повторіть спробу.", "invite.send_invite": "Надіслати", - "invite.shareLink": "Поділіться посиланням", - "invite.summary.back": "Повернутись", + "invite.shareLink": "Поділитись посиланням", + "invite.summary.back": "Повернутись назад", "invite.summary.done": "Готово", - "invite.summary.email_invite": "Електронного листа із запрошенням надіслано", - "invite.summary.error": "{invitationCount, множина, одне {Запрошення} інші {Запрошення}} не вдалося надіслати успішно", - "invite.summary.member_invite": "Запрошено як члена команди {Ім'я_відображення_команди}", - "invite.summary.not_sent": "{Кількість_не_надіслано, множина, одне {Запрошення не було} інші {Запрошення не були}} надіслано", - "invite.summary.report.notSent": "[кількість] {кількість, множина, одне {запрошення} інші {запрошення}} не надіслано", - "invite.summary.report.sent": "{кількість} успішні {кількість, множина, одне {запрошення} інші {запрошення}}", - "invite.summary.sent": "Ваші {Кількість_надісланих, множина, одне {запрошення є} інші {запрошення є}} відправлені", + "invite.summary.email_invite": "Електронний лист із запрошенням надіслано", + "invite.summary.error": "{invitationsCount, plural, one {Запрошення} other {Запрошень}} не вдалося успішно надіслати", + "invite.summary.member_invite": "Запрошено як учасника {teamDisplayName}", + "invite.summary.not_sent": "{notSentCount, plural, one {Запрошення не було} few {Запрошення не були} other {Запрошення не були}} надіслані", + "invite.summary.report.notSent": "{count} {count, plural, one {запрошення} few {запрошення} other {запрошень}} не надіслано", + "invite.summary.report.sent": "{count} {count, plural, one {запрошення} other {запрошень}} успішно відправлено", + "invite.summary.sent": "Ваше {sentCount, plural, one {запрошення було} other {запрошення були}} надіслано(і)", "invite.summary.smtp_failure": "SMTP не налаштовано в системній консолі", - "invite.summary.some_not_sent": "{Кількість_не_надісланих, множина, один {Запрошення було} інші {Декілька запрошень було}} не надіслано", - "invite.summary.try_again": "Спробуйте ще раз", + "invite.summary.some_not_sent": "{notSentCount, plural, one {Запрошення не було} other {Деякі запрошення не були}} надіслані", + "invite.summary.try_again": "Спробуйте знову", "invite.title": "Запросити", - "invite.title.summary": "Запросити підсумок", + "invite.title.summary": "Статистика запрошень", "invite_people_to_team.message": "Ось посилання для співпраці та спілкування з нами на Mattermost.", - "invite_people_to_team.title": "Приєднуйтесь до команди {команда}", + "invite_people_to_team.title": "Приєднуйтесь до команди {team}", "join_team.error.group_error": "Щоб приєднатися до цієї команди, ви повинні бути членом пов'язаної групи.", "join_team.error.message": "Виникла помилка при приєднанні до команди", "join_team.error.title": "Помилка приєднання до команди", - "last_users_message.added_to_channel.type": "Ви були **додані до каналу** користувачем {actor}.", - "last_users_message.added_to_team.type": "Ви були **додані в команду** користувачем {actor}.", + "last_users_message.added_to_channel.type": "були **додані до каналу** користувачем {actor}.", + "last_users_message.added_to_team.type": "були **додані в команду** користувачем {actor}.", "last_users_message.first": "{firstUser} і ", "last_users_message.joined_channel.type": "**приєдналися до каналу**.", "last_users_message.joined_team.type": "**приєднався до команди**.", - "last_users_message.left_channel.type": "**залишив канал**.", - "last_users_message.left_team.type": "**залишив команду**.", + "last_users_message.left_channel.type": "**покинув канал**.", + "last_users_message.left_team.type": "**покинув команду**.", "last_users_message.others": "{numOthers} інших ", - "last_users_message.removed_from_channel.type": "Ви були **видалені з каналу**.", - "last_users_message.removed_from_team.type": "Ви були **вилучені з команди**.", + "last_users_message.removed_from_channel.type": "були **видалені з каналу**.", + "last_users_message.removed_from_team.type": "були **вилучені з команди**.", "load_categories_error.message": "Виникла проблема із завантаженням контенту для цього сервера.", - "load_categories_error.title": "Не вдалося завантажити категорії для {Ім'я_сервера}", + "load_categories_error.title": "Не вдалося завантажити категорії для {serverName}", "load_channels_error.message": "Виникла проблема із завантаженням контенту для цієї команди.", - "load_channels_error.title": "Не вдалося завантажити {Ім'я_відображення_команди}", + "load_channels_error.title": "Не вдалося завантажити {teamDisplayName}", "load_teams_error.message": "Виникла проблема із завантаженням контенту для цього сервера.", - "load_teams_error.title": "Не вдалося завантажити {Ім'я_сервера}", + "load_teams_error.title": "Не вдалося завантажити {serverName}", "login.email": "Електронна пошта", "login.forgot": "Забули свій пароль?", "login.invalid_credentials": "Неправильна комбінація адреси електронної пошти та пароля", - "login.ldapUsername": "Ім'я користувача AD/LDAP", + "login.ldapUsername": "AD/LDAP Ім'я користувача", "login.or": "або", "login.password": "Пароль", - "login.signIn": "Увійти", + "login.signIn": "Авторизуватися", "login.signingIn": "Вхід у систему", "login.username": "Логін", "login_mfa.enterToken": "Щоб завершити процес входу, будь ласка, введіть код з програми-автентифікатора вашого мобільного пристрою.", - "login_mfa.token": "Введіть MFA Token", - "login_mfa.tokenReq": "Будь-ласка, введіть токен MFA", + "login_mfa.token": "Введіть токен БФА", + "login_mfa.tokenReq": "Будь-ласка, введіть токен БФА", "markdown.latex.error": "Помилка рендерингу Latex", "markdown.max_nodes.error": "Це повідомлення занадто довге для повного відображення на мобільному пристрої. Будь ласка, перегляньте його на комп'ютері або зверніться до адміністратора, щоб збільшити цей ліміт.", "markdown.parse_error": "При розборі цього тексту сталася помилка", "markdown.render_error": "Виникла помилка при відтворенні цього тексту", "mentions.empty.paragraph": "Тут ви побачите повідомлення, коли хтось згадає вас або використає терміни, які ви відстежуєте.", - "mentions.empty.title": "Ще немає згадок", - "mobile.about.appVersion": "Версія програми: {version} (Збірка {number})", + "mentions.empty.title": "Ще немає Згадок", + "mobile.about.appVersion": "Версія додатку: {version} (Збірка {number})", "mobile.account.settings.save": "Зберегти", "mobile.acknowledgements.header": "Подяки", "mobile.action_menu.select": "Виберіть параметр", - "mobile.add_team.create_team": "Створіть нову команду", - "mobile.add_team.join_team": "Приєднуйтесь до іншої команди", - "mobile.android.back_handler_exit": "Повторно натисніть назад, щоб вийти", - "mobile.android.photos_permission_denied_description": "Завантажте фотографії на сервер або збережіть їх на своєму пристрої. Відкрийте \"Налаштування\", щоб надати {ім'я_додатку} доступ на читання та запис до вашої фототеки.", + "mobile.add_team.create_team": "Створити нову команду", + "mobile.add_team.join_team": "Приєднатись до іншої команди", + "mobile.android.back_handler_exit": "Натисніть ще раз, щоб вийти", + "mobile.android.photos_permission_denied_description": "Завантажте фотографії на сервер або збережіть їх на своєму пристрої. Відкрийте Налаштування, щоб надати {applicationName} доступ на читання та запис до вашої фототеки.", "mobile.android.photos_permission_denied_title": "{applicationName} хотів би отримати доступ до ваших фотографій", "mobile.announcement_banner.title": "Оголошення", "mobile.calls_audio_device": "Виберіть аудіопристрій", "mobile.calls_bluetooth": "Bluetooth", "mobile.calls_call_ended": "Дзвінок завершено", - "mobile.calls_call_screen": "Зателефонувати", - "mobile.calls_call_thread": "Потік дзвінка", + "mobile.calls_call_screen": "Дзвінок", + "mobile.calls_call_thread": "Обгоровення дзвінка", "mobile.calls_cancel": "Скасувати", "mobile.calls_captions": "Титри", "mobile.calls_captions_turned_on": "Ввімкнено субтитри в реальному часі", "mobile.calls_disable": "Вимкнути дзвінки", - "mobile.calls_dismiss": "Відбій", + "mobile.calls_dismiss": "Відхилити", "mobile.calls_enable": "Увімкнути дзвінки", "mobile.calls_end_call_title": "Завершити дзвінок", - "mobile.calls_end_msg_channel": "Ви впевнені, що хочете завершити виклик з {Номер_учасника} учасниками в {Ім'я_відображення}?", + "mobile.calls_end_msg_channel": "Ви впевнені, що хочете завершити виклик з {numParticipants} учасниками в {displayName}?", "mobile.calls_end_msg_channel_default": "Ви впевнені, що хочете завершити дзвінок?", - "mobile.calls_end_msg_dm": "Ви впевнені, що хочете завершити виклик з {Ім'я_відображення}?", + "mobile.calls_end_msg_dm": "Ви впевнені, що хочете завершити виклик з {displayName}?", "mobile.calls_end_permission_msg": "У вас немає дозволу на завершення виклику. Попросіть абонента завершити виклик.", "mobile.calls_end_permission_title": "Помилка", - "mobile.calls_ended_at": "Закінчується на", + "mobile.calls_ended_at": "Закінчилося о", "mobile.calls_error_message": "Помилка: {error}", "mobile.calls_error_title": "Помилка", "mobile.calls_group_calls_not_available": "Дзвінки доступні тільки в приватних каналах.", @@ -502,7 +502,7 @@ "mobile.calls_host_rec_stop_body": "Запис розмови буде оброблено і розміщено в темі обговорення. Ви впевнені, що хочете зупинити запис?", "mobile.calls_host_rec_stop_confirm": "Зупинити запис", "mobile.calls_host_rec_stop_title": "Зупинити запис", - "mobile.calls_host_rec_stopped": "You will be able to find the recording in the chat of this call as soon as it is processed.", + "mobile.calls_host_rec_stopped": "Ви зможете знайти запис у чаті цього дзвінка, щойно він буде оброблений.", "mobile.calls_host_rec_stopped_title": "Запис зупинено. Обробка...", "mobile.calls_host_rec_title": "Ви записуєте", "mobile.calls_host_rec_trans_stop_body": "Файли запису та транскрипції дзвінка будуть оброблені та опубліковані в темі дзвінка. Ви впевнені, що хочете зупинити запис та транскрипцію?", @@ -512,13 +512,13 @@ "mobile.calls_incoming_dm": "{name} запрошує вас на дзвінок", "mobile.calls_incoming_gm": "{name} запрошує вас на дзвінок з {num, plural, one {# іншим} other {# іншими}}", "mobile.calls_join": "Приєднатись", - "mobile.calls_join_call": "Приєднуйтесь до дзвінка", - "mobile.calls_joining": "Доєднується...", - "mobile.calls_lasted": "Тривало {тривалість}", + "mobile.calls_join_call": "Приєднатись до дзвінка", + "mobile.calls_joining": "Приєднання...", + "mobile.calls_lasted": "Тривалість {duration}", "mobile.calls_leave": "Покинути", - "mobile.calls_leave_call": "Покинути дзвінок", - "mobile.calls_limit_msg": "Максимальна кількість учасників в одному дзвінку становить {макс_учасників}. Зверніться до системного адміністратора, щоб збільшити ліміт.", - "mobile.calls_limit_msg_GA": "Оновіть версію до Cloud Professional або Cloud Enterprise, щоб увімкнути групові виклики з більшою кількістю учасників {макс_учасників}.", + "mobile.calls_leave_call": "Відключитись", + "mobile.calls_limit_msg": "Максимальна кількість учасників в одному дзвінку становить {maxParticipants}. Зверніться до системного адміністратора, щоб збільшити ліміт.", + "mobile.calls_limit_msg_GA": "Оновіть версію до Cloud Professional або Cloud Enterprise, щоб увімкнути групові виклики з більшою кількістю учасників {maxParticipants}.", "mobile.calls_limit_reached": "Ліміт учасників досягнуто", "mobile.calls_lower_hand": "Опустити руку", "mobile.calls_make_host": "Зробити хостом", @@ -536,7 +536,7 @@ "mobile.calls_ok": "ОК", "mobile.calls_okay": "Гаразд", "mobile.calls_open_channel": "Відкрити канал", - "mobile.calls_participant_limit_title_GA": "Цей дзвінок вичерпав свій ліміт", + "mobile.calls_participant_limit_title_GA": "Цей дзвінок вичерпано", "mobile.calls_participant_rec": "Ведучий розпочав запис цієї зустрічі. Залишаючись на зустрічі, ви даєте згоду на запис.", "mobile.calls_participant_rec_title": "Запис триває", "mobile.calls_participant_transcription": "Організатор розпочав запис та розшифровку цієї зустрічі. Залишаючись на зустрічі, ви даєте згоду на те, щоб вас записували і розшифровували.", @@ -545,8 +545,8 @@ "mobile.calls_people": "Люди", "mobile.calls_phone": "Телефон", "mobile.calls_quality_warning": "Якість зв'язку може погіршитися через нестабільні умови роботи мережі.", - "mobile.calls_raise_hand": "Підніміть руку", - "mobile.calls_raised_hand": "{ім'я} {число, множина, =0 {} інше {+# більше }}підняв руку", + "mobile.calls_raise_hand": "Підняти руку", + "mobile.calls_raised_hand": "{name} {num, plural, =0 {} other {+# декілька учасників }} підняли руку", "mobile.calls_react": "Реакція", "mobile.calls_record": "Запис", "mobile.calls_recording_start_in_progress": "Запис вже триває.", @@ -560,41 +560,41 @@ "mobile.calls_removed_alert_body": "Організатор відключив вас від дзвінка.", "mobile.calls_removed_alert_title": "Вас було видалено з розмови", "mobile.calls_request_message": "Наразі дзвінки працюють у тестовому режимі, і лише системні адміністратори можуть їх запускати. Зверніться за допомогою безпосередньо до системного адміністратора", - "mobile.calls_request_title": "Дзвінки зараз не ввімкнено", + "mobile.calls_request_title": "Наразі дзвінки не увімкнені", "mobile.calls_see_logs": "Дивіться логи сервера", "mobile.calls_show_cc": "Показувати субтитри в реальному часі", - "mobile.calls_speaker": "Промовець", - "mobile.calls_start_call": "Почати дзвінок", - "mobile.calls_start_call_exists": "У каналі вже триває заклик.", + "mobile.calls_speaker": "Спікер", + "mobile.calls_start_call": "Почати Дзвінок", + "mobile.calls_start_call_exists": "У каналі вже триває дзвінок.", "mobile.calls_started_call": "Дзвінок розпочався", "mobile.calls_starting": "Початок...", - "mobile.calls_stop_recording": "Зупинити запис", + "mobile.calls_stop_recording": "Зупинити Запис", "mobile.calls_stop_screenshare": "Зупинити спільне використання екрана", "mobile.calls_tablet": "Планшет", - "mobile.calls_thread": "Потік", + "mobile.calls_thread": "Обговорення", "mobile.calls_unmute": "Увімкнути звук", "mobile.calls_user_left_channel_error_message": "Ви залишили канал і були відключені від дзвінка.", "mobile.calls_user_left_channel_error_title": "Ви покинули канал", "mobile.calls_user_removed_from_channel_error_message": "Вас видалено з каналу і від'єднано від дзвінка.", "mobile.calls_user_removed_from_channel_error_title": "Вас видалено з каналу", "mobile.calls_view_profile": "Переглянути профіль", - "mobile.calls_viewing_screen": "Ви переглядаєте екран користувача {ім'я}", - "mobile.calls_you": "(Ви)", + "mobile.calls_viewing_screen": "Ви переглядаєте екран користувача {name}", + "mobile.calls_you": "(ви)", "mobile.calls_you_2": "Ви", - "mobile.camera_photo_permission_denied_description": "Зробіть фотографії та завантажте їх на сервер або збережіть на своєму пристрої. Відкрийте \"Налаштування\", щоб надати {ім'я_додатку} доступ на читання та запис до вашої камери.", - "mobile.camera_photo_permission_denied_title": "{Ім'я_додатку} хоче отримати доступ до вашої камери", + "mobile.camera_photo_permission_denied_description": "Зробіть фотографії та завантажте їх на сервер або збережіть на своєму пристрої. Відкрийте Налаштування, щоб надати {applicationName} доступ на читання та запис до вашої камери.", + "mobile.camera_photo_permission_denied_title": "{applicationName} хоче отримати доступ до вашої камери", "mobile.camera_type.title": "Параметри камери", "mobile.channel_add_members.error": "Сталася помилка, і ми не змогли додати цих користувачів до каналу.", "mobile.channel_info.alertNo": "Ні", "mobile.channel_info.alertYes": "Так", - "mobile.channel_list.recent": "Нещодавні", - "mobile.channel_list.unreads": "Непрочитане", - "mobile.commands.error_title": "Помилка виконання команди", + "mobile.channel_list.recent": "Останні", + "mobile.channel_list.unreads": "Непрочитані", + "mobile.commands.error_title": "Помилка при виконанні команди", "mobile.components.select_server_view.connect": "Підключитися", "mobile.components.select_server_view.connecting": "Підключення", - "mobile.components.select_server_view.displayHelp": "Виберіть ім'я відображення для вашого сервера", - "mobile.components.select_server_view.displayName": "Ім'я відображення", - "mobile.components.select_server_view.enterServerUrl": "Введіть адресу сервера", + "mobile.components.select_server_view.displayHelp": "Виберіть відображуване ім'я для вашого сервера", + "mobile.components.select_server_view.displayName": "Відображуване ім'я", + "mobile.components.select_server_view.enterServerUrl": "Введіть URL-адресу сервера", "mobile.components.select_server_view.msg_connect": "Підключімося до сервера", "mobile.components.select_server_view.msg_description": "Сервер - це комунікаційний центр вашої команди, доступ до якого здійснюється за унікальною URL-адресою", "mobile.components.select_server_view.msg_welcome": "Ласкаво просимо", @@ -606,36 +606,36 @@ "mobile.create_post.read_only": "Цей канал доступний лише для читання.", "mobile.custom_list.no_results": "Немає результатів", "mobile.custom_status.choose_emoji": "Виберіть емодзі", - "mobile.custom_status.clear_after": "Очистити після", + "mobile.custom_status.clear_after": "Очистити Після", "mobile.custom_status.clear_after.title": "Очистити статус користувача після", "mobile.custom_status.modal_confirm": "Готово", "mobile.deep_link.invalid": "Посилання, яке ви намагаєтеся відкрити, є недійсним.", "mobile.diagnostic_id.empty": "Для цього сервера відсутнє значення DiagnosticId. Зверніться до системного адміністратора, щоб перевірити це значення і перезавантажити сервер.", "mobile.direct_message.error": "Ми не змогли відкрити ПП з {displayName}.", "mobile.display_settings.clockDisplay": "Відображення годинника", - "mobile.display_settings.crt": "Згорнуті відповіді потоків", + "mobile.display_settings.crt": "Згорнуті відповіді в обговореннях", "mobile.display_settings.theme": "Тема", "mobile.display_settings.timezone": "Часовий пояс", - "mobile.document_preview.failed_description": "Під час відкриття документа сталася помилка. Будь ласка, переконайтеся, що ви встановили програму перегляду {fileType} та повторіть спробу.\n", - "mobile.document_preview.failed_title": "Відкрити документ не вдалося", - "mobile.downloader.disabled_description": "Завантаження файлів вимкнено на цьому сервері. Щоб отримати докладнішу інформацію, зв'яжіться зі своїм системним адміністратором.\n", - "mobile.downloader.disabled_title": "Завантаження відключене", - "mobile.downloader.failed_description": "Під час завантаження файлу сталася помилка. Перевірте підключення до Інтернету та повторіть спробу.\n", + "mobile.document_preview.failed_description": "Виникла помилка при відкритті документа. Переконайтеся, що у вас встановлено програму для перегляду {fileType} та спробуйте ще раз.\n", + "mobile.document_preview.failed_title": "Не вдалося відкрити документ", + "mobile.downloader.disabled_description": "Завантаження файлів на цьому сервері вимкнено. Будь ласка, зверніться до вашого системного адміністратора для отримання більш детальної інформації.\n", + "mobile.downloader.disabled_title": "Завантаження вимкнено", + "mobile.downloader.failed_description": "Під час завантаження файлу сталася помилка. Будь ласка, перевірте підключення до Інтернету та спробуйте ще раз.\n", "mobile.downloader.failed_title": "Помилка завантаження", "mobile.edit_channel": "Зберегти", - "mobile.edit_post.delete_question": "Ви дійсно хочете видалити це повідомлення?", + "mobile.edit_post.delete_question": "Ви впевнені, що хочете видалити цей Допис?", "mobile.edit_post.delete_title": "Підтвердіть видалення повідомлення", "mobile.edit_post.error": "Виникла проблема з редагуванням цього повідомлення. Будь ласка, спробуйте ще раз.", "mobile.edit_post.title": "Редагування повідомлення", - "mobile.error_handler.button": "Перезапустити", - "mobile.error_handler.description": "\nНатисніть на кнопку \"Запустити знову\", щоб відкрити програму заново. Після запуску, ви можете повідомити про проблему через меню налаштувань.\n", - "mobile.error_handler.title": "Сталася неочікувана помилка", - "mobile.file_upload.disabled2": "Завантаження файлів із мобільного пристрою вимкнено.", + "mobile.error_handler.button": "Перезапуск", + "mobile.error_handler.description": "\nНатисніть на Перезапустити, щоб знову відкрити програму. Після перезапуску ви можете повідомити про проблему в меню налаштувань.\n", + "mobile.error_handler.title": "Виникла непередбачувана помилка", + "mobile.file_upload.disabled2": "Завантаження файлів з мобільного вимкнено.", "mobile.file_upload.max_warning": "Максимальна кількість завантажень - не більше {count} файлів.", - "mobile.files_paste.error_description": "Помилка при направленні повідомлення. Будь-ласка, спробуйте знову.", + "mobile.files_paste.error_description": "Виникла помилка під час вставки файлу(ів). Будь ласка, спробуйте ще раз.", "mobile.files_paste.error_dismiss": "Відхилити", "mobile.files_paste.error_title": "Не вдалося вставити", - "mobile.gallery.title": "{index} з {total}", + "mobile.gallery.title": "{index} із {total}", "mobile.integration_selector.loading_channels": "Завантаження каналів...", "mobile.integration_selector.loading_options": "Завантаження параметрів...", "mobile.ios.photos_permission_denied_description": "Завантажте фото та відео на сервер або збережіть їх на свій пристрій. Відкрийте налаштування, щоб надати {applicationName} доступ на читання та запис до вашої бібліотеки фото та відео.", @@ -653,7 +653,7 @@ "mobile.ios.plist.NSSpeechRecognitionUsageDescription": "Увімкнення вашого пристрою для відправки даних користувача в Apple дозволить вам надсилати голосові повідомлення в {applicationName}.", "mobile.join_channel.error": "Ми не змогли приєднатися до каналу {displayName}.", "mobile.leave_and_join_confirmation": "Покинути та приєднатися", - "mobile.leave_and_join_message": "Ви вже перебуваєте у розмові з каналом у ~{залишити_Назва_каналу}. Ви хочете вийти з поточної розмови і приєднатися до розмови в ~{приєднатися_до_каналу}?", + "mobile.leave_and_join_message": "Ви вже перебуваєте у розмові з каналом ~{leaveChannelName}. Ви хочете залишити поточний виклик і приєднатися до виклику в ~{joinChannelName}?", "mobile.leave_and_join_title": "Ви впевнені, що хочете переключитися на інший дзвінок?", "mobile.link.error.text": "Не вдалося відкрити посилання.", "mobile.link.error.title": "Помилка", @@ -664,101 +664,101 @@ "mobile.login_options.google": "Google", "mobile.login_options.heading": "Увійдіть до свого облікового запису", "mobile.login_options.none": "Ви ще не можете увійти до свого облікового запису. Необхідно налаштувати принаймні один варіант входу. Зверніться за допомогою до системного адміністратора.", - "mobile.login_options.openid": "Відкритий ідентифікатор", + "mobile.login_options.openid": "Open ID", "mobile.login_options.saml": "SAML", "mobile.login_options.select_option": "Виберіть варіант входу нижче.", "mobile.login_options.separator_text": "або увійдіть за допомогою", "mobile.manage_members.admin": "Адміністратор", "mobile.manage_members.cancel": "Скасувати", "mobile.manage_members.change_role.error": "Виникла помилка при спробі оновити роль. Будь ласка, перевірте з'єднання та повторіть спробу.", - "mobile.manage_members.done": "Виконано", - "mobile.manage_members.make_channel_admin": "Зробити адміністратором каналу", - "mobile.manage_members.make_channel_member": "Стати учасником каналу", + "mobile.manage_members.done": "Готово", + "mobile.manage_members.make_channel_admin": "Призначити адміністратора каналу", + "mobile.manage_members.make_channel_member": "Призначити учасником каналу", "mobile.manage_members.manage": "Керувати", "mobile.manage_members.manage_member": "Керувати учасником", "mobile.manage_members.member": "Учасник", "mobile.manage_members.message": "Ви впевнені, що хочете видалити вибраного користувача з каналу?", "mobile.manage_members.remove": "Вилучити", - "mobile.manage_members.remove_member": "Вилучити з каналу", - "mobile.manage_members.section_title_admins": "АДМІНІСТРАЦІЯ КАНАЛУ", + "mobile.manage_members.remove_member": "Видалити з каналу", + "mobile.manage_members.section_title_admins": "АДМІНІСТРАТОРИ КАНАЛУ", "mobile.manage_members.section_title_members": "УЧАСНИКИ", "mobile.managed.blocked_by": "Заблоковано {vendor}", "mobile.managed.exit": "Вихід", "mobile.managed.jailbreak": "Пристрій з джейлбрейком або рутованою системою не довіряється {vendor}.\n\nДодаток зараз закриється.", - "mobile.managed.not_secured.android": "Цей пристрій повинен бути захищений блокуванням екрана, щоб використовувати Mattermost.", + "mobile.managed.not_secured.android": "Щоб використовувати Mattermost, цей пристрій має бути захищено блокуванням екрана.", "mobile.managed.not_secured.ios": "Щоб користуватися Mattermost, цей пристрій потрібно захистити паролем.\n\nПерейдіть до Налаштування > Face ID та пароль.", "mobile.managed.not_secured.ios.touchId": "Щоб користуватися Mattermost, цей пристрій потрібно захистити паролем.\n\nПерейдіть до Налаштування > Touch ID та пароль.", "mobile.managed.secured_by": "Захищено {vendor}", "mobile.managed.settings": "Перейдіть до налаштувань", - "mobile.markdown.code.copy_code": "Копія коду", - "mobile.markdown.code.plusMoreLines": "+{кількість, число} більше {кількість, множина, один {рядок} інші {рядки}}", + "mobile.markdown.code.copy_code": "Скопіювати Код", + "mobile.markdown.code.plusMoreLines": "ще +{count, number} {count, plural, one {рядок} few {рядка} other {рядків}}", "mobile.markdown.copy_header": "Скопіювати текст заголовка", - "mobile.markdown.image.too_large": "Зображення перевищує макс. розміри {maxWidth} до {maxHeight}:", - "mobile.markdown.link.copy_url": "Копіювати URL", + "mobile.markdown.image.too_large": "Зображення перевищує максимальні розміри {maxWidth} на {maxHeight}:", + "mobile.markdown.link.copy_url": "Скопіювати URL-адресу", "mobile.mention.copy_mention": "Копіювати згадування", - "mobile.message_length.message": "Ваше поточне повідомлення задовге. Поточний символ: {max}/{count}", + "mobile.message_length.message": "Ваше поточне повідомлення занадто довге. Поточна кількість символів: {count}/{max}", "mobile.message_length.message_split_left": "Повідомлення перевищує ліміт символів", "mobile.message_length.title": "Довжина повідомлення", - "mobile.no_results.spelling": "Перевірте орфографію або спробуйте інший пошук.", - "mobile.no_results_with_term": "Немає результатів для \"{термін}\"", - "mobile.no_results_with_term.files": "Немає файлів, що відповідають \"{термін}\"", - "mobile.no_results_with_term.messages": "Нічого не знайдено для \"{термін}\"", + "mobile.no_results.spelling": "Перевірте написане або спробуйте інший пошук.", + "mobile.no_results_with_term": "Немає результатів для \"{term}\"", + "mobile.no_results_with_term.files": "Немає файлів, що відповідають \"{term}\"", + "mobile.no_results_with_term.messages": "Не знайдено збігів для \"{term}\"", "mobile.oauth.failed_to_login": "Ваша спроба входу була невдалою. Спробуйте ще раз.", "mobile.oauth.failed_to_open_link": "Посилання не вдалося відкрити. Будь ласка, спробуйте ще раз.", "mobile.oauth.failed_to_open_link_no_browser": "Посилання не вдалося відкрити. Переконайтеся, що на пристрої встановлений браузер.", "mobile.oauth.something_wrong.okButton": "ОК", "mobile.oauth.success.description": "Виконується вхід, зачекайте...", "mobile.oauth.success.title": "Автентифікація пройдена успішно", - "mobile.oauth.switch_to_browser": "Вас перенаправлено до вашого постачальника послуг входу", + "mobile.oauth.switch_to_browser": "Переспрямування до постачальника послуг входу до системи", "mobile.oauth.switch_to_browser.error_title": "Помилка входу в систему", "mobile.oauth.switch_to_browser.title": "Перенаправлення...", - "mobile.oauth.try_again": "Спробуйте ще раз", + "mobile.oauth.try_again": "Спробуйте знову", "mobile.onboarding.next": "Далі", - "mobile.onboarding.sign_in": "Увійдіть в систему", + "mobile.onboarding.sign_in": "Увійти", "mobile.onboarding.sign_in_to_get_started": "Увійдіть, щоб почати", - "mobile.open_dm.error": "Не вдалося відкрити пряме повідомлення з {ім'я_відображення}. Будь ласка, перевірте ваше з'єднання і спробуйте ще раз.", - "mobile.open_gm.error": "Помилка з'єднання із групи з цими користувачами. Будь-ласка, перевірте підключення та спробуйте заново.", - "mobile.participants.header": "Учасники потоку", + "mobile.open_dm.error": "Не вдалося відкрити особисті повідомлення з {displayName}. Будь ласка, перевірте ваше з'єднання і спробуйте ще раз.", + "mobile.open_gm.error": "Не вдалося відкрити групове повідомлення з цими користувачами. Будь ласка, перевірте з'єднання та спробуйте ще раз.", + "mobile.participants.header": "Учасники обговорення", "mobile.permission_denied_dismiss": "Не дозволяти", "mobile.permission_denied_retry": "Налаштування", "mobile.post.cancel": "Скасувати", - "mobile.post.delete_question": "Ви впевнені, що хочете видалити це повідомлення?", - "mobile.post.delete_title": "Видалити публікацію", + "mobile.post.delete_question": "Ви впевнені, що хочете видалити цей допис?", + "mobile.post.delete_title": "Видалити допис", "mobile.post.failed_delete": "Видалити повідомлення", - "mobile.post.failed_retry": "Спробуй ще раз", - "mobile.post_info.add_reaction": "Додати реакцію", + "mobile.post.failed_retry": "Спробуйте Знову", + "mobile.post_info.add_reaction": "Додати Реакцію", "mobile.post_info.copy_text": "Копіювати Текст", - "mobile.post_info.mark_unread": "Позначити непрочитаним", + "mobile.post_info.mark_unread": "Позначити як Непрочитане", "mobile.post_info.pin": "Закріпити в каналі", "mobile.post_info.reply": "Відповідь", "mobile.post_info.save": "Зберегти", "mobile.post_info.unpin": "Відкріпити від каналу", - "mobile.post_info.unsave": "Не збережено", + "mobile.post_info.unsave": "Скасувати збереження", "mobile.post_pre_header.pinned": "Закріплено", "mobile.post_pre_header.pinned_saved": "Закріплено та збережено", "mobile.post_pre_header.saved": "Збережено", "mobile.post_textbox.entire_channel.cancel": "Скасувати", - "mobile.post_textbox.entire_channel.confirm": "Підтвердьте", + "mobile.post_textbox.entire_channel.confirm": "Підтвердити", "mobile.post_textbox.entire_channel.message": "Використовуючи @all або @channel, ви збираєтеся надіслати сповіщення {totalMembers, number} {totalMembers, plural, one {людині} few {людям} other {людям}}. Ви впевнені, що хочете це зробити?", "mobile.post_textbox.entire_channel.message.with_timezones": "Використовуючи @all або @channel, ви збираєтеся надіслати сповіщення {totalMembers, number} {totalMembers, plural, one {людині} other {людям}} в {timezones, number} {timezones, plural, one {часовому поясі} other {часових поясах}}. Ви впевнені, що хочете це зробити?", - "mobile.post_textbox.entire_channel.title": "Підтвердьте надсилання повідомлень на весь канал", - "mobile.post_textbox.entire_channel_here.message": "Використовуючи @here, ви збираєтеся надіслати сповіщення до {кількість_Учасників, кількість} {кількість_Учасників, множина, одна {особа} інші {люди}}. Ви впевнені, що хочете це зробити?", - "mobile.post_textbox.entire_channel_here.message.with_timezones": "Використовуючи @here, ви збираєтеся надіслати сповіщення до {кількість_Учасників, кількість} {кількість_Учасників, множина, одна {особа} інші {люди}} в {часова_зона, кількість} {часова_зона, множина, одна {часова_зона} інші {часові_зони}}. Ви впевнені, що хочете це зробити?", - "mobile.post_textbox.groups.title": "Confirm sending notifications to groups", - "mobile.post_textbox.uploadFailedDesc": "Деякі вкладення не змогли завантажити на сервер. Ви впевнені, що хочете опублікувати це повідомлення?", - "mobile.post_textbox.uploadFailedTitle": "Вкладення несправності", - "mobile.privacy_link": "Privacy Policy", - "mobile.push_notification_reply.button": "Відправити", - "mobile.push_notification_reply.placeholder": "Написати відповідь ...", + "mobile.post_textbox.entire_channel.title": "Підтвердити надсилання сповіщень до всього каналу", + "mobile.post_textbox.entire_channel_here.message": "Використовуючи @here, ви збираєтеся надіслати сповіщення {totalMembers, number} {totalMembers, plural, one {людині} other {людям}}. Ви впевнені, що хочете це зробити?", + "mobile.post_textbox.entire_channel_here.message.with_timezones": "Використовуючи @here, ви збираєтеся надіслати сповіщення {totalMembers, number} {totalMembers, plural, one {людині} other {людям}} в {timezones, number} {timezones, plural, one {часовій зоні} other {часових зонах}}. Ви впевнені, що хочете це зробити?", + "mobile.post_textbox.groups.title": "Підтвердити відправку сповіщень групам", + "mobile.post_textbox.uploadFailedDesc": "Деякі вкладення не вдалося завантажити на сервер. Ви впевнені, що хочете опублікувати повідомлення?", + "mobile.post_textbox.uploadFailedTitle": "Помилка прикріплення", + "mobile.privacy_link": "Політика конфіденційності", + "mobile.push_notification_reply.button": "Надіслати", + "mobile.push_notification_reply.placeholder": "Відповісти...", "mobile.push_notification_reply.title": "Відповідь", - "mobile.rename_channel.display_name_maxLength": "Назва каналу має бути меншою за символи {maxLength, number}", - "mobile.rename_channel.display_name_minLength": "Назва каналу має містити {minLength, number} або більше символів", + "mobile.rename_channel.display_name_maxLength": "Назва каналу не повинна перевищувати {maxLength, number} символів", + "mobile.rename_channel.display_name_minLength": "Назва каналу має містити не менше, ніж {minLength, number} символів", "mobile.rename_channel.display_name_required": "Назва каналу є обов'язковою", "mobile.request.invalid_request_method": "Неправильний метод запиту", "mobile.request.invalid_response": "Отримано недійсну відповідь від сервера.", "mobile.reset_status.alert_cancel": "Скасувати", "mobile.reset_status.alert_ok": "ОК", - "mobile.reset_status.title_ooo": "Вимкнути \"Out Of Office\"?", + "mobile.reset_status.title_ooo": "Вимкнути \"Не в офісі\"?", "mobile.routes.code": "{language} код", "mobile.routes.code.noLanguage": "Код", "mobile.routes.custom_status": "Встановіть власний статус", @@ -777,25 +777,25 @@ "mobile.search.team.select": "Виберіть команду для пошуку", "mobile.server_identifier.exists": "Ви вже підключені до цього сервера.", "mobile.server_link.error.text": "Посилання не вдалося знайти на цьому сервері.", - "mobile.server_link.error.title": "Link Error", - "mobile.server_link.unreachable_channel.error": "Постійне посилання належить до видаленого повідомлення або до каналу, на який ви не маєте доступу.", - "mobile.server_link.unreachable_team.error": "Постійне посилання належить до видаленого повідомлення або до каналу, на який ви не маєте доступу.", + "mobile.server_link.error.title": "Помилка посилання", + "mobile.server_link.unreachable_channel.error": "Це посилання належить видаленому каналу або каналу, до якого у вас немає доступу.", + "mobile.server_link.unreachable_team.error": "Це посилання належить видаленій команді або команді, до якої у вас немає доступу.", "mobile.server_link.unreachable_user.error": "Ми не можемо перенаправити вас до ПП. Вказаний користувач невідомий.", "mobile.server_name.exists": "Ви використовуєте це ім'я для іншого сервера.", "mobile.server_ping_failed": "Не вдається з'єднатися з сервером.", - "mobile.server_requires_client_certificate": "Для автентифікації серверу потрібен сертифікат клієнта.", + "mobile.server_requires_client_certificate": "Серверу потрібен сертифікат клієнта для автентифікації.", "mobile.server_upgrade.button": "OK", "mobile.server_upgrade.description": "\nДля використання програми Mattermost потрібне оновлення сервера. Будь ласка, зверніться до вашого системного адміністратора за деталями.\n", "mobile.server_upgrade.title": "Потрібно оновлення сервера", - "mobile.server_url.deeplink.emm.denied": "Ця програма контролюється EMM, а адреса сервера DeepLink не збігається з дозволеним сервером EMM", - "mobile.server_url.empty": "Введіть дійсну URL-адресу сервера", - "mobile.server_url.invalid_format": "Адреса повинен починатися з http:// або https://", - "mobile.session_expired.title": "Сесія завершилася", + "mobile.server_url.deeplink.emm.denied": "Ця програма контролюється EMM, а адреса URL-сервера DeepLink не збігається з дозволеним сервером EMM", + "mobile.server_url.empty": "Будь ласка, введіть дійсну URL-адресу сервера", + "mobile.server_url.invalid_format": "URL-адреса повинна починатися з http:// або https://", + "mobile.session_expired.title": "Сесія закінчилася", "mobile.session_expired_days": "Будь ласка, увійдіть, щоб продовжувати отримувати сповіщення. Сесії для {siteName} налаштовані на закінчення терміну кожні {daysCount, number} {daysCount, plural, one {день} few {дні} other {днів}}.", "mobile.session_expired_days_hrs": "Будь ласка, увійдіть, щоб продовжувати отримувати сповіщення. Сесії для {siteName} налаштовані на закінчення терміну кожні {daysCount, number} {daysCount, plural, one {день} few {дні} other {днів}} та {hoursCount, number} {hoursCount, plural, one {година} few {години} other {годин}}.", "mobile.session_expired_hrs": "Будь ласка, увійдіть, щоб продовжувати отримувати сповіщення. Сесії для {siteName} налаштовані на закінчення терміну кожні {hoursCount, number} {hoursCount, plural, one {година} few {години} other {годин}}.", "mobile.set_status.dnd": "Не турбувати", - "mobile.storage_permission_denied_description": "Завантажте файли на ваш сервер. Відкрийте Налаштування, щоб надати {назва_програми} доступ до читання і запису файлів на цьому пристрої.", + "mobile.storage_permission_denied_description": "Завантажте файли на ваш сервер. Відкрийте Налаштування, щоб надати {applicationName} доступ до читання і запису файлів на цьому пристрої.", "mobile.storage_permission_denied_title": "{applicationName} хоче отримати доступ до ваших файлів", "mobile.suggestion.members": "Учасники", "mobile.system_message.channel_archived_message": "{username} архівував канал", @@ -807,26 +807,26 @@ "mobile.system_message.update_channel_purpose_message.removed": "{username} видалив заголовок каналу (було: {oldPurpose})", "mobile.system_message.update_channel_purpose_message.updated_from": "{username} змінив(ла) заголовок каналу з {oldPurpose} на {newPurpose}", "mobile.system_message.update_channel_purpose_message.updated_to": "{username} встановив(ла) заголовок каналу: {newPurpose}", - "mobile.tos_link": "Умови обслуговування", + "mobile.tos_link": "Умови надання послуг", "mobile.user_list.deactivated": "Деактивований", - "mobile.write_storage_permission_denied_description": "Збережіть файли на своєму пристрої. Відкрийте Налаштування, щоб надати {назва_програми} доступ на запис до файлів на цьому пристрої.", + "mobile.write_storage_permission_denied_description": "Збережіть файли на своєму пристрої. Відкрийте Налаштування, щоб надати {applicationName} доступ на запис до файлів на цьому пристрої.", "modal.manual_status.auto_responder.message_": "Ви хочете змінити свій статус на \"{status}\" і вимкнути автоматичні відповіді?", - "modal.manual_status.auto_responder.message_away": "Ви хочете змінити свій статус на \"Далеко\" і вимкнути автоматичні відповіді?", - "modal.manual_status.auto_responder.message_dnd": "Ви хочете змінити свій статус на \"Не турбувати\" та вимкнути автоматичні відповіді?", - "modal.manual_status.auto_responder.message_offline": "Ви хочете змінити свій статус на \"Offline\" і вимкнути автоматичні відповіді?", - "modal.manual_status.auto_responder.message_online": "Хочете переключити свій статус на \"Online\" і вимкнути автоматичні відповіді?", - "more_messages.text": "{кількість} new {кількість, множина, one {повідомлення} other {повідомлення}}", - "msg_typing.areTyping": "{users} і {last} друкують...", - "msg_typing.isTyping": "{user} друкує...", + "modal.manual_status.auto_responder.message_away": "Ви хочете змінити свій статус на \"Відсутній\" і вимкнути Автоматичні відповіді?", + "modal.manual_status.auto_responder.message_dnd": "Бажаєте змінити свій статус на \"Не турбувати\" та вимкнути Автоматичні відповіді?", + "modal.manual_status.auto_responder.message_offline": "Бажаєте змінити свій статус на \"Не в мережі\" та вимкнути Автоматичні відповіді?", + "modal.manual_status.auto_responder.message_online": "Бажаєте змінити свій статус на \"В мережі\" і вимкнути Автоматичні відповіді?", + "more_messages.text": "{count} {count, plural, one {нове повідомлення} other {нових повідомлень}}", + "msg_typing.areTyping": "{users} та {last} пишуть...", + "msg_typing.isTyping": "{user} пише...", "native.ios.notifications.not_verified": "Ми не змогли перевірити це сповіщення на сервері", "notification.message_not_found": "Повідомлення не знайдено", "notification.no_connection": "Сервер недоступний, і не вдалося отримати інформацію про конкретне повідомлення для сповіщення.", - "notification.no_post": "Повідомлення не було знайдено.", + "notification.no_post": "Повідомлення не знайдено.", "notification.not_channel_member": "Це повідомлення належить каналу, в якому ви не є учасником.", "notification.not_team_member": "Це повідомлення належить команді, членом якої ви не є.", - "notification_settings.auto_responder": "Автоматичні відповіді", - "notification_settings.auto_responder.default_message": "Привіт, я не в офісі і не можу відповідати на повідомлення.", - "notification_settings.auto_responder.footer.message": "Встановіть спеціальне повідомлення, яке автоматично надсилатиметься у відповідь на прямі повідомлення, наприклад, відповідь про відсутність на робочому місці або відпустку. Увімкнення цього параметра змінює ваш статус на \"Не в офісі\" і вимикає сповіщення.", + "notification_settings.auto_responder": "Автоматичні Відповіді", + "notification_settings.auto_responder.default_message": "Привіт, я не на робочому місці і не можу відповісти на повідомлення.", + "notification_settings.auto_responder.footer.message": "Встановіть спеціальне повідомлення, яке автоматично надсилатиметься у відповідь на приватні повідомлення, наприклад, відповідь про відсутність на робочому місці або відпустку. Увімкнення цього параметра змінює ваш статус на \"Не на робочому місці\" і вимикає сповіщення.", "notification_settings.auto_responder.message": "Повідомлення", "notification_settings.auto_responder.to.enable": "Увімкнути автоматичні відповіді", "notification_settings.call_notification": "Сповіщення про дзвінки", @@ -837,103 +837,103 @@ "notification_settings.calls.dynamic": "Динамічний", "notification_settings.calls.enable_sound": "Звук сповіщення про вхідні дзвінки", "notification_settings.calls.urgent": "Терміново", - "notification_settings.calls_off": "Вимкнути", + "notification_settings.calls_off": "Відключено", "notification_settings.calls_on": "Увімкнути", - "notification_settings.email": "Сповіщення електронною поштою", - "notification_settings.email.crt.emailInfo": "Якщо увімкнено, будь-яка відповідь на тему, за якою ви стежите, надсилатиме вам сповіщення на електронну пошту", - "notification_settings.email.crt.send": "Сповіщення про відповіді в темі", + "notification_settings.email": "Сповіщення Електронною поштою", + "notification_settings.email.crt.emailInfo": "Якщо увімкнено, будь-яка відповідь в обговоренні, за яким ви стежите, надсилатиме сповіщення на електронну пошту", + "notification_settings.email.crt.send": "Сповіщення про відповіді в обговореннях", "notification_settings.email.emailHelp2": "Ваш системний адміністратор вимкнув електронну пошту. Поки її не буде ввімкнено, сповіщення не надсилатимуться.", - "notification_settings.email.emailInfo": "Сповіщення надсилаються на електронну пошту для згадок і прямих повідомлень, коли ви не в мережі або відсутні більше 5 хвилин.", + "notification_settings.email.emailInfo": "Сповіщення надсилаються на електронну пошту для згадок і особистих повідомлень, коли ви перебуваєте в офлайні або відсутні більше 5 хвилин.", "notification_settings.email.everyHour": "Щогодини", "notification_settings.email.fifteenMinutes": "Кожні 15 хвилин", "notification_settings.email.immediately": "Негайно", "notification_settings.email.never": "Ніколи", - "notification_settings.email.send": "Надсилати сповіщення на електронну пошту", - "notification_settings.mention.reply": "Надсилайте сповіщення про відповідь для", + "notification_settings.email.send": "Надсилати сповіщення електронною поштою", + "notification_settings.mention.reply": "Надсилати сповіщення про відповідь для", "notification_settings.mentions": "Згадки", - "notification_settings.mentions.channelWide": "Загальноканальні згадки", + "notification_settings.mentions.channelWide": "Згадки для всього каналу", "notification_settings.mentions.keywords": "Введіть інші ключові слова", "notification_settings.mentions.keywordsLabel": "Ключові слова не чутливі до регістру. Відокремлюйте ключові слова комами.", - "notification_settings.mentions.keywords_mention": "Ключові слова, які викликають згадки", + "notification_settings.mentions.keywords_mention": "Ключові слова, що викликають згадування", "notification_settings.mentions.sensitiveName": "Ваше ім'я з урахуванням регістру", "notification_settings.mentions.sensitiveUsername": "Ваше ім'я користувача без врахування регістру", "notification_settings.mentions_replies": "Згадки та відповіді", "notification_settings.mobile": "Push-сповіщення", - "notification_settings.mobile.away": "Відійшов або в режимі офлайн", - "notification_settings.mobile.offline": "Офлайн", - "notification_settings.mobile.online": "Онлайн, відійшов чи офлайн", + "notification_settings.mobile.away": "Відійшов або офлайн", + "notification_settings.mobile.offline": "Не в мережі", + "notification_settings.mobile.online": "Онлайн, відійшов чи не в мережі", "notification_settings.mobile.trigger_push": "Запускати push-сповіщення, коли...", "notification_settings.ooo_auto_responder": "Автоматичні відповіді", "notification_settings.pushNotification.all_new_messages": "Всі нові повідомлення", - "notification_settings.pushNotification.disabled_long": "Push-сповіщення для мобільних пристроїв було вимкнено вашим системним адміністратором.", + "notification_settings.pushNotification.disabled_long": "Push-сповіщення для мобільних пристроїв вимкнено вашим системним адміністратором.", "notification_settings.pushNotification.mentions_only": "Тільки для згадок, особистих та групових повідомлень (за замовчуванням)", "notification_settings.pushNotification.nothing": "Нічого", "notification_settings.push_notification": "Push-сповіщення", - "notification_settings.push_threads.following": "Сповіщати мене про відповіді на теми, за якими я стежу в цьому каналі", - "notification_settings.push_threads.replies": "Thread replies", + "notification_settings.push_threads.following": "Сповіщати мене про відповіді на обговорення, за якими я стежу в цьому каналі", + "notification_settings.push_threads.replies": "Відповіді на обговорення", "notification_settings.send_notification.about": "Сповістити мене про...", - "notification_settings.threads_mentions": "Згадки в темах", - "notification_settings.threads_start": "Теми, які я починаю", - "notification_settings.threads_start_participate": "Теми, які я започатковую або в яких беру участь", + "notification_settings.threads_mentions": "Згадки в обговореннях", + "notification_settings.threads_start": "Обговорення, які я починаю", + "notification_settings.threads_start_participate": "Обговорення, які я започатковую або в яких беру участь", "onboarding.calls": "Миттєво розпочинайте захищені аудіовиклики", - "onboarding.calls_description": "Якщо ви не встигаєте набирати текст, переключіться з чату на основі каналу на захищений аудіовиклик одним дотиком.", + "onboarding.calls_description": "Коли введення тексту недостатньо швидке, перемикайтеся з чату в каналі на безпечні аудіодзвінки одним натисканням.", "onboarding.integrations": "Інтеграція з улюбленими інструментами", "onboarding.integrations_description": "Виходьте за межі чату за допомогою тісно інтегрованих продуктових рішень, узгоджених із загальними процесами розробки.", "onboarding.realtime_collaboration": "Співпрацюйте в режимі реального часу", - "onboarding.realtime_collaboration_description": "Постійні канали, прямі повідомлення та обмін файлами працюють безперебійно, щоб ви могли залишатися на зв'язку, де б ви не були.", + "onboarding.realtime_collaboration_description": "Постійні канали, приватні повідомлення та обмін файлами працюють безперебійно, щоб ви могли залишатися на зв'язку, де б ви не були.", "onboarding.welcome": "Ласкаво просимо", "onboaring.welcome_description": "Mattermost - це платформа з відкритим вихідним кодом для співпраці розробників. Безпечна, гнучка та інтегрована з вашими інструментами.", - "password_send.description": "Щоб скинути свій пароль, введіть адресу електронної пошти, яку ви використовували для реєстрації", + "password_send.description": "Щоб скинути пароль, введіть адресу електронної пошти, яку ви використовували при реєстрації", "password_send.error": "Будь-ласка, введіть коректну адресу електронної пошти.", "password_send.generic_error": "Ми не змогли надіслати вам посилання для скидання пароля. Будь ласка, зверніться за допомогою до вашого системного адміністратора.", - "password_send.link": "Якщо обліковий запис існує, електронний лист для зміни пароля буде надіслано на адресу:", + "password_send.link": "Якщо обліковий запис існує, на нього буде надіслано лист зі зміною пароля:", "password_send.link.title": "Надіслано посилання для скидання", "password_send.reset": "Скинути Ваш пароль", - "password_send.return": "Повернутися до входу в систему", + "password_send.return": "Повернутися до Входу в систему", "permalink.error.access.text": "Повідомлення, яке ви намагаєтеся переглянути, знаходиться в каналі, до якого у вас немає доступу, або було видалено.", "permalink.error.access.title": "Повідомлення недоступне для перегляду", "permalink.error.cancel": "Скасувати", "permalink.error.okay": "Гаразд", "permalink.error.private_channel.button": "Приєднатися до каналу", - "permalink.error.private_channel.text": "Повідомлення, яке ви намагаєтеся переглянути, знаходиться в приватному каналі, до якого вас не запрошували, але ви маєте доступ як адміністратор. Ви все ще хочете приєднатися до **{назва_каналу}**?", + "permalink.error.private_channel.text": "Повідомлення, яке ви намагаєтеся переглянути, знаходиться в приватному каналі, до якого вас не запрошували, але ви маєте доступ як адміністратор. Ви все ще хочете приєднатися до **{channelName}**?", "permalink.error.private_channel.title": "Приєднуйтесь до приватного каналу", "permalink.error.private_channel_and_team.button": "Приєднуйтесь до каналу та команди", - "permalink.error.private_channel_and_team.text": "Повідомлення, яке ви намагаєтеся переглянути, знаходиться в приватному каналі в команді, членом якої ви не є. Ви маєте доступ як адміністратор. Ви хочете приєднатися до **{Ім'я_каналу}** та команди **{Назва_команди}**, щоб переглянути його?", + "permalink.error.private_channel_and_team.text": "Повідомлення, яке ви намагаєтеся переглянути, знаходиться в приватному каналі в команді, членом якої ви не є. Ви маєте доступ як адміністратор. Ви хочете приєднатися до **{channelName}** та команди **{teamName}**, щоб переглянути його?", "permalink.error.private_channel_and_team.title": "Приєднуйтесь до приватного каналу та команди", "permalink.error.public_channel.button": "Приєднатися до каналу", - "permalink.error.public_channel.text": "Повідомлення, яке ви намагаєтеся переглянути, знаходиться в каналі, до якого ви не належите. Ви хочете приєднатися до **{назва_каналу}**, щоб переглянути його?", + "permalink.error.public_channel.text": "Повідомлення, яке ви намагаєтеся переглянути, знаходиться в каналі, до якого ви не належите. Ви хочете приєднатися до **{channelName}**, щоб переглянути його?", "permalink.error.public_channel.title": "Приєднатися до каналу", "permalink.error.public_channel_and_team.button": "Приєднуйтесь до каналу та команди", - "permalink.error.public_channel_and_team.text": "Повідомлення, яке ви намагаєтеся переглянути, знаходиться в каналі, до якого ви не належите, і в команді, членом якої ви не є. Ви хочете приєднатися до **{Назва_каналу}** та команди **{Назва_команди}**, щоб переглянути його?", + "permalink.error.public_channel_and_team.text": "Повідомлення, яке ви намагаєтеся переглянути, знаходиться в каналі, до якого ви не належите, і в команді, членом якої ви не є. Ви хочете приєднатися до **{channelName}** та команди **{teamName}**, щоб переглянути його?", "permalink.error.public_channel_and_team.title": "Приєднуйтесь до каналу та команди", "permalink.show_dialog_warn.cancel": "Скасувати", - "permalink.show_dialog_warn.description": "Ви збираєтеся приєднатися до {каналу} без явного додавання адміністратором каналу. Ви впевнені, що хочете приєднатися до цього приватного каналу?", + "permalink.show_dialog_warn.description": "Ви збираєтеся приєднатися до {channel} без явного додавання адміністратором каналу. Ви впевнені, що хочете приєднатися до цього приватного каналу?", "permalink.show_dialog_warn.join": "Приєднатися", "permalink.show_dialog_warn.title": "Приєднуйтесь до приватного каналу", "persistent_notifications.confirm.cancel": "Скасувати", "persistent_notifications.confirm.description": "Вказані одержувачі будуть отримувати повідомлення кожні {interval, plural, one {хвилину} few {{interval} хвилини} other {{interval} хвилин}}, доки вони не підтвердять або не нададуть відповідь на повідомлення.", "persistent_notifications.confirm.send": "Надіслати", - "persistent_notifications.confirm.title": "Надсилайте постійні сповіщення", + "persistent_notifications.confirm.title": "Надсилання постійних сповіщень", "persistent_notifications.dm_channel.description": "{username} отримуватиме сповіщення кожні {interval, plural, one {хвилину} few {хвилини} other {{interval} хвилин}}до тих пір, поки не підтвердить або відповість на повідомлення.", - "persistent_notifications.error.max_recipients.description": "Ви можете надсилати постійні сповіщення максимум {макс} одержувачам. У вашому повідомленні згадано {кількість} одержувачів. Вам потрібно буде змінити тих, кого ви вказали, перш ніж надсилати.", + "persistent_notifications.error.max_recipients.description": "Ви можете надсилати постійні сповіщення максимум {max} одержувачам. У вашому повідомленні згадано {count} одержувачів. Вам потрібно буде змінити тих, кого ви вказали, перш ніж надсилати повідомлення.", "persistent_notifications.error.max_recipients.title": "Занадто багато одержувачів", - "persistent_notifications.error.no_mentions.description": "У вашому повідомленні не вказано жодного одержувача. Вам потрібно буде додати їх, щоб мати змогу надсилати постійні сповіщення.", + "persistent_notifications.error.no_mentions.description": "У вашому повідомленні не вказано жодного одержувача. Вам потрібно додати їх, щоб мати змогу надсилати постійні сповіщення.", "persistent_notifications.error.no_mentions.title": "Одержувачі повинні бути @згадані", "persistent_notifications.error.okay": "Гаразд", "persistent_notifications.error.special_mentions": "Не можна використовувати @channel, @all або @here для зазначення отримувачів постійних сповіщень.", "pinned_messages.empty.paragraph": "Щоб закріпити важливі повідомлення, натисніть і утримуйте повідомлення, а потім виберіть \"Закріпити в каналі\". Закріплені повідомлення будуть видимі всім користувачам цього каналу.", - "pinned_messages.empty.title": "Ще немає закріплених повідомлень", - "plus_menu.browse_channels.title": "Перегляд каналів", - "plus_menu.create_new_channel.title": "Створити новий канал", - "plus_menu.invite_people_to_team.title": "Запрошуйте людей до команди", - "plus_menu.open_direct_message.title": "Відкрити пряме повідомлення", - "post.options.title": "Параметри", + "pinned_messages.empty.title": "Немає закріплених повідомлень", + "plus_menu.browse_channels.title": "Перегляд Каналів", + "plus_menu.create_new_channel.title": "Створити новий Канал", + "plus_menu.invite_people_to_team.title": "Запросити людей до команди", + "plus_menu.open_direct_message.title": "Відкрити Приватне повідомлення", + "post.options.title": "Опції", "post.reactions.title": "Реакції", "postList.scrollToBottom.newMessages": "Нові повідомлення", "postList.scrollToBottom.newReplies": "Нові відповіді", - "post_body.check_for_out_of_channel_groups_mentions.message": "did not get notified by this mention because they are not in the channel. They cannot be added to the channel because they are not a member of the linked groups. To add them to this channel, they must be added to the linked groups.", + "post_body.check_for_out_of_channel_groups_mentions.message": "не отримали сповіщення про цю згадку, оскільки вони не підписані на канал. Вони також не є членами груп, пов'язаних з цим каналом.", "post_body.check_for_out_of_channel_mentions.link.and": " і ", - "post_body.check_for_out_of_channel_mentions.link.private": "додайте їх до цього приватного каналу", + "post_body.check_for_out_of_channel_mentions.link.private": "додайте їх у цей приватний канал", "post_body.check_for_out_of_channel_mentions.link.public": "додати їх до каналу", "post_body.check_for_out_of_channel_mentions.message.multiple": "були згадані, але вони не перебувають у каналі. Чи хотіли б Ви ", "post_body.check_for_out_of_channel_mentions.message.one": "було згадано, але користувач не на каналі. Чи хотіли б Ви ", @@ -948,38 +948,38 @@ "post_info.guest": "Гість", "post_info.system": "Система", "post_message_view.edited": "(змінено)", - "post_priority.button.acknowledge": "Визнати", + "post_priority.button.acknowledge": "Підтвердити", "post_priority.label.important": "ВАЖЛИВО", "post_priority.label.urgent": "ТЕРМІНОВО", "post_priority.picker.apply": "Застосувати", "post_priority.picker.beta": "БЕТА", "post_priority.picker.cancel": "Скасувати", "post_priority.picker.label.important": "Важливо", - "post_priority.picker.label.persistent_notifications": "Надсилайте постійні сповіщення", - "post_priority.picker.label.persistent_notifications.description": "Одержувачі отримують сповіщення кожні {інтервал, множина, одна {хвилина} інша {інтервал} хвилин}}, поки вони не підтвердять або не дадуть відповідь.", + "post_priority.picker.label.persistent_notifications": "Надсилання постійних сповіщень", + "post_priority.picker.label.persistent_notifications.description": "Одержувачі отримують сповіщення {interval, plural, one {кожну хвилину} other {кожні {interval} хвилин}}, поки вони не підтвердять або не дадуть відповідь.", "post_priority.picker.label.request_ack": "Запит на підтвердження", "post_priority.picker.label.request_ack.description": "Кнопка підтвердження з'явиться разом з вашим повідомленням", "post_priority.picker.label.standard": "Стандартний", "post_priority.picker.label.urgent": "Терміново", "post_priority.picker.title": "Пріоритет повідомлення", - "posts_view.newMsg": "Нові повідомлення", + "posts_view.newMsg": "Нові Повідомлення", "public_link_copied": "Посилання скопійовано в буфер обміну", "rate.button.needs_work": "Потребує доопрацювання", - "rate.button.yes": "Обожнюю!", - "rate.dont_ask_again": "Не питай мене більше", + "rate.button.yes": "Мені подобається!", + "rate.dont_ask_again": "Не запитувати мене більше", "rate.error.text": "Виникла помилка при відкритті модального вікна перегляду.", "rate.error.title": "Помилка", "rate.subtitle": "Дайте нам знати, що ви думаєте.", "rate.title": "Подобається Mattermost?", - "requested_ack.title": "Запит на отримання подяки", - "saved_messages.empty.paragraph": "Щоб зберегти щось пізніше, натисніть і утримуйте повідомлення, а потім виберіть Зберегти в меню. Збережені повідомлення бачите тільки ви.", + "requested_ack.title": "Запит на Підтвердження", + "saved_messages.empty.paragraph": "Щоб зберегти повідомлення на пізніше, натисніть і утримуйте повідомлення, а потім виберіть Зберегти в меню. Збережені повідомлення бачите тільки ви.", "saved_messages.empty.title": "Ще немає збережених повідомлень", - "screen.channel_files.header.recent_files": "Нещодавні файли", + "screen.channel_files.header.recent_files": "Нещодавні Файли", "screen.channel_files.results.filter.title": "Фільтр за типом файлу", "screen.mentions.subtitle": "Повідомлення, в яких вас згадували", - "screen.mentions.title": "Нещодавні згадки", + "screen.mentions.title": "Нещодавні Згадки", "screen.saved_messages.subtitle": "Всі повідомлення, які ви зберегли для подальших дій", - "screen.saved_messages.title": "Збережені повідомлення", + "screen.saved_messages.title": "Збережені Повідомлення", "screen.search.header.files": "Файли", "screen.search.header.messages": "Повідомлення", "screen.search.modifier.header": "Параметри пошуку", @@ -1023,7 +1023,7 @@ "server_list.push_proxy_unknown": "Не вдалося отримати сповіщення від цього сервера через його конфігурацію. Вийдіть з системи та увійдіть знову, щоб повторити спробу.", "server_upgrade.alert_description": "На вашому сервері {serverDisplayName} використовується непідтримувана версія сервера. Користувачі можуть зіткнутися з проблемами сумісності, які спричиняють збої або серйозні помилки, що порушують основну функціональність програми. Необхідне оновлення до версії сервера {supportedServerVersion} або новішої.", "server_upgrade.dismiss": "Відхилити", - "server_upgrade.learn_more": "Дізнатися більше", + "server_upgrade.learn_more": "Дізнайтеся Більше", "servers.create_button": "Додати сервер", "servers.default": "Сервер за замовчуванням", "servers.edit": "Редагувати", @@ -1051,7 +1051,7 @@ "settings.advanced.delete_data": "Видалення локальних файлів", "settings.advanced.delete_message.confirmation": "\nЦе призведе до видалення всіх файлів, завантажених через додаток для цього сервера. Будь ласка, підтвердіть, щоб продовжити.\n", "settings.advanced_settings": "Розширені налаштування", - "settings.display": "Зображення", + "settings.display": "Відображення", "settings.link.error.text": "Не вдалося відкрити посилання.", "settings.link.error.title": "Помилка", "settings.notice_mobile_link": "мобільні додатки", @@ -1068,7 +1068,7 @@ "settings_display.custom_theme": "Користувацька тема", "settings_display.timezone.automatically": "Встановити автоматично", "settings_display.timezone.manual": "Змінити часовий пояс", - "settings_display.timezone.off": "Вимкнути", + "settings_display.timezone.off": "Відключено", "settings_display.timezone.select": "Виберіть часовий пояс", "share_extension.channel_error": "Ви не є членом команди на вибраному сервері. Виберіть інший сервер або відкрийте Mattermost, щоб приєднатися до команди.", "share_extension.channel_label": "Канал", @@ -1105,25 +1105,25 @@ "snack.bar.text.copied": "Скопійовано в буфер обміну", "snack.bar.undo": "Відмінити", "snack.bar.unfavorite.channel": "Цей канал був видалений з обраних", - "snack.bar.unfollow.thread": "Відписатися від обговорення", + "snack.bar.unfollow.thread": "Відписка від обговорення успішно виконана", "snack.bar.unmute.channel": "Сповіщення для цього каналу були увімкнені", "status_dropdown.set_away": "Не на місці", "status_dropdown.set_dnd": "Не турбувати", "status_dropdown.set_offline": "Не в мережі", "status_dropdown.set_online": "В мережі", "status_dropdown.set_ooo": "Поза офісом", - "suggestion.mention.all": "Повідомляє всіх у каналі", - "suggestion.mention.channel": "Повідомляє всіх у каналі", + "suggestion.mention.all": "Повідомити всіх на цьому каналі", + "suggestion.mention.channel": "Повідомити всіх на цьому каналі", "suggestion.mention.channels": "Мої канали", - "suggestion.mention.groups": "Групові згадування", - "suggestion.mention.here": "Повідомляє всіх у каналі", + "suggestion.mention.groups": "Групові згадки", + "suggestion.mention.here": "Сповіщає всіх хто онлайн у цьому каналі", "suggestion.mention.morechannels": "Інші канали", "suggestion.mention.nonmembers": "Не в каналі", "suggestion.mention.special": "Особливі згадки", "suggestion.mention.users": "Користувачі", "suggestion.search.direct": "Особисті Повідомлення", - "suggestion.search.private": "Приватні канали", - "suggestion.search.public": "Публічні канали", + "suggestion.search.private": "Приватні Канали", + "suggestion.search.public": "Публічні Канали", "system_notice.dont_show": "Не показувати знову", "system_notice.remind_me": "Нагадати пізніше", "system_notice.title.gm_as_dm": "Оновлення у групових повідомленнях", @@ -1132,12 +1132,12 @@ "team_list.no_other_teams.title": "Немає інших команд для приєднання", "terms_of_service.acceptButton": "Прийняти", "terms_of_service.alert_cancel": "Скасувати", - "terms_of_service.alert_retry": "Спробуйте ще раз", + "terms_of_service.alert_retry": "Спробуйте Знову", "terms_of_service.api_error": "Не вдалося завершити запит. Якщо ця проблема не зникає, зверніться до системного адміністратора.", - "terms_of_service.decline": "Відхилити", + "terms_of_service.decline": "Відмовити", "terms_of_service.error.description": "Не вдалося отримати Умови обслуговування з сервера.", "terms_of_service.error.logout": "Вийти з системи", - "terms_of_service.error.retry": "Спробувати знову", + "terms_of_service.error.retry": "Спробуйте ще раз", "terms_of_service.error.title": "Не вдалося отримати Умови обслуговування(ToS).", "terms_of_service.terms_declined.ok": "ОК", "terms_of_service.terms_declined.text": "Ви повинні прийняти умови обслуговування, щоб отримати доступ до цього сервера. Будь ласка, зв'яжіться з вашим системним адміністратором для отримання додаткової інформації. Тепер ви вийдете з системи. Увійдіть знову, щоб прийняти умови обслуговування.", @@ -1157,8 +1157,8 @@ "threads.following": "Відслідковується", "threads.newReplies": "{count} нова {count, plural, one {відповідь} few {відповіді} other {відповідей}}", "threads.replies": "{count} {count, plural, one {відповідь} few {відповіді} other {відповідей}}", - "threads.unfollowMessage": "Відписатися від повідомлення", - "threads.unfollowThread": "Відписатися від обговорення", + "threads.unfollowMessage": "Відписатися від Повідомлення", + "threads.unfollowThread": "Відписатися від Обговорення", "unreads.empty.paragraph": "Вимкніть фільтр непрочитаних повідомлень, щоб показати всі ваші канали.", "unreads.empty.show_all": "Показати всі", "unreads.empty.title": "Більше немає непрочитаних", diff --git a/assets/base/i18n/zh-CN.json b/assets/base/i18n/zh-CN.json index 1b64f98dbfc..526252a3d36 100644 --- a/assets/base/i18n/zh-CN.json +++ b/assets/base/i18n/zh-CN.json @@ -139,7 +139,7 @@ "channel_info.archive_failed": "在试图归档频道{displayName}时发生错误", "channel_info.archive_title": "归档{term}", "channel_info.channel_auto_follow_threads": "关注此频道中的所有话题", - "channel_info.channel_auto_follow_threads_failed": "尝试自动关注频道{displayName}中的所有对话时发生错误", + "channel_info.channel_auto_follow_threads_failed": "尝试自动关注频道{displayName}中的所有话题时发生错误", "channel_info.channel_files": "文件", "channel_info.close": "关闭", "channel_info.close_dm": "关闭对话", @@ -454,6 +454,8 @@ "login_mfa.tokenReq": "请输入多重验证令牌", "markdown.latex.error": "Latex渲染错误", "markdown.max_nodes.error": "此信息过长,无法在移动客户端上完整显示。请在PC客户端上查看或联系管理员以增加消息限制长度。", + "markdown.parse_error": "解析此文本时遇到错误", + "markdown.render_error": "渲染此文本时遇到错误", "mentions.empty.paragraph": "当有人提及您或者使用了您真正关注的术语时您将看到相关消息。", "mentions.empty.title": "目前没有提及", "mobile.about.appVersion": "应用版本:{version} (Build {number})", @@ -497,13 +499,13 @@ "mobile.calls_host_rec": "您正在录制此会议。考虑让所有人知道此次会议将被录制。", "mobile.calls_host_rec_error": "请尝试再次录制。您也可以联系系统管理员寻求帮助。", "mobile.calls_host_rec_error_title": "此录制出现错误", - "mobile.calls_host_rec_stop_body": "通话录制将被处理并发布于通话的对话中。您确定要停止录制吗?", + "mobile.calls_host_rec_stop_body": "通话录制将被处理并发布于通话的话题中。您确定要停止录制吗?", "mobile.calls_host_rec_stop_confirm": "停止录制", "mobile.calls_host_rec_stop_title": "停止录制", - "mobile.calls_host_rec_stopped": "处理完成后,您可以在此通话的对话中找到录制。", + "mobile.calls_host_rec_stopped": "处理完成后,您可以在此通话的话题中找到录制。", "mobile.calls_host_rec_stopped_title": "录制已经停止。处理中…", "mobile.calls_host_rec_title": "您正在录制中", - "mobile.calls_host_rec_trans_stop_body": "通话录制和转录文件将被处理并发布于通话的对话中。您确定要停止录制和转录吗?", + "mobile.calls_host_rec_trans_stop_body": "通话录制和转录文件将被处理并发布于通话的话题中。您确定要停止录制和转录吗?", "mobile.calls_host_rec_trans_stop_title": "停止录制和转录", "mobile.calls_host_transcription": "考虑让每个人都知道这次会议正在被记录。", "mobile.calls_host_transcription_title": "记录已开始", @@ -716,7 +718,7 @@ "mobile.onboarding.sign_in_to_get_started": "登录后开始", "mobile.open_dm.error": "我们无法打开私信 {displayName}。请检查您的网络连接再尝试。", "mobile.open_gm.error": "我们无法打开和这些用户的团体消息。请检查您的网络连接再尝试。", - "mobile.participants.header": "对话参与者", + "mobile.participants.header": "话题参与者", "mobile.permission_denied_dismiss": "不允许", "mobile.permission_denied_retry": "设定", "mobile.post.cancel": "取消", @@ -1175,6 +1177,13 @@ "user.settings.notifications.email_threads.description": "通知我有关我关注的主题的所有回复", "user.tutorial.long_press": "长按项目查看用户的介绍", "user_profile.custom_status": "自定义状态", + "user_settings.notifications.test_notification.body": "无法收到通知?先向您的所有设备发送一条测试通知,以检查是否符合预期。如果仍有问题,通过故障排除步骤寻找解决的方法。", + "user_settings.notifications.test_notification.go_to_docs": "故障排除文档", + "user_settings.notifications.test_notification.send_button.error": "发送测试通知时出错", + "user_settings.notifications.test_notification.send_button.send": "发送测试通知", + "user_settings.notifications.test_notification.send_button.sending": "发送测试通知中", + "user_settings.notifications.test_notification.send_button.sent": "测试通知已发送", + "user_settings.notifications.test_notification.title": "排查通知问题", "user_status.away": "离开", "user_status.dnd": "请勿打扰", "user_status.offline": "离线", From 7123c7f3c0be5d6d789a5eb249d7aaa540487a85 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Tue, 26 Nov 2024 20:15:34 +0800 Subject: [PATCH 19/36] Ensure myTeam.id is not undefined (#8375) --- .../team_sidebar/team_list/index.test.tsx | 243 ++++++++++++++++++ .../team_sidebar/team_list/index.ts | 34 +-- 2 files changed, 250 insertions(+), 27 deletions(-) create mode 100644 app/components/team_sidebar/team_list/index.test.tsx diff --git a/app/components/team_sidebar/team_list/index.test.tsx b/app/components/team_sidebar/team_list/index.test.tsx new file mode 100644 index 00000000000..fb13a3ffa32 --- /dev/null +++ b/app/components/team_sidebar/team_list/index.test.tsx @@ -0,0 +1,243 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {render, waitFor} from '@testing-library/react-native'; +import React from 'react'; +import {of as of$} from 'rxjs'; + +import TeamList from './team_list'; + +import TeamListWrapper from './'; + +// Mock database queries +jest.mock('@queries/servers/team', () => { + const {of} = require('rxjs'); + return { + queryMyTeams: jest.fn(() => of([])), + queryJoinedTeams: jest.fn(() => ({ + observe: jest.fn(() => of([])), + })), + }; +}); + +jest.mock('@queries/servers/preference', () => { + const {of} = require('rxjs'); + return { + queryPreferencesByCategoryAndName: jest.fn(() => ({ + observe: jest.fn(() => of([])), + observeWithColumns: jest.fn(() => of([])), + })), + }; +}); + +const {queryPreferencesByCategoryAndName} = require('@queries/servers/preference'); +const {queryMyTeams, queryJoinedTeams} = require('@queries/servers/team'); + +// Mock WatermelonDB HOCs +jest.mock('@nozbe/watermelondb/react', () => ({ + withDatabase: jest.fn((Component) => Component), + withObservables: jest.fn((_, observableMapper) => { + // eslint-disable-next-line react/display-name + return (Component: any) => (props: any) => { + const observables = observableMapper(props); + const mockedProps: Record = {}; + // eslint-disable-next-line guard-for-in + for (const key in observables) { + observables[key].subscribe((value: any) => { + mockedProps[key] = value; + }); + } + return ( + ); + }; + }), +})); + +jest.mock('./team_list', () => { + return jest.fn(() => null); // Mock implementation for TeamList +}); + +describe('withTeams HOC', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should handle valid data correctly', async () => { + queryMyTeams.mockReturnValue({ + observe: jest.fn(() => of$([{id: '1', roles: 'team_user'}])), + }); + + queryJoinedTeams.mockReturnValue({ + observe: jest.fn(() => of$([ + {id: '1', displayName: 'Team 1'}, + {id: '2', displayName: 'Team 2'}, + ])), + }); + + queryPreferencesByCategoryAndName.mockReturnValue({ + observeWithColumns: jest.fn(() => of$([{value: '1,2'}])), + }); + + render(); + + await waitFor(() => { + expect(TeamList).toHaveBeenCalledWith( + expect.objectContaining({ + myOrderedTeams: [{id: '1', roles: 'team_user'}], + }), + expect.anything(), + ); + }); + }); + + it('should handle missing team IDs gracefully', async () => { + queryMyTeams.mockReturnValue({ + observe: jest.fn(() => of$([{id: '1', roles: 'team_user'}])), + }); + + queryJoinedTeams.mockReturnValue({ + observe: jest.fn(() => of$([ + {id: '1', displayName: 'Team 1'}, + {id: undefined, displayName: 'Team 2'}, + ])), + }); + + queryPreferencesByCategoryAndName.mockReturnValue({ + observeWithColumns: jest.fn(() => of$([{value: '1,2'}])), + }); + + render(); + + await waitFor(() => { + expect(TeamList).toHaveBeenCalledWith( + expect.objectContaining({ + myOrderedTeams: [{id: '1', roles: 'team_user'}], + }), + expect.anything(), + ); + }); + }); + + it('should handle empty team order preferences gracefully', async () => { + queryMyTeams.mockReturnValue({ + observe: jest.fn(() => of$([{id: '1', roles: 'team_user'}])), + }); + + queryJoinedTeams.mockReturnValue({ + observe: jest.fn(() => of$([ + {id: '1', displayName: 'Team 1'}, + {id: '2', displayName: 'Team 2'}, + ])), + }); + + queryPreferencesByCategoryAndName.mockReturnValue({ + observeWithColumns: jest.fn(() => of$([])), + }); + + render(); + + await waitFor(() => { + expect(TeamList).toHaveBeenCalledWith( + expect.objectContaining({ + myOrderedTeams: [{id: '1', roles: 'team_user'}], + }), + expect.anything(), + ); + }); + }); + + it('should handle undefined in team order preferences gracefully', async () => { + queryMyTeams.mockReturnValue({ + observe: jest.fn(() => of$([ + {id: '1', roles: 'team_user'}, + {id: '2', roles: 'team_user'}, + ])), + }); + + queryJoinedTeams.mockReturnValue({ + observe: jest.fn(() => of$([ + {id: '1', displayName: 'Team 1'}, + {id: '2', displayName: 'Team 2'}, + ])), + }); + + queryPreferencesByCategoryAndName.mockReturnValue({ + observeWithColumns: jest.fn(() => of$([{value: '1,,2'}])), + }); + + render(); + + await waitFor(() => { + expect(TeamList).toHaveBeenCalledWith( + expect.objectContaining({ + myOrderedTeams: [ + {id: '1', roles: 'team_user'}, + {id: '2', roles: 'team_user'}, + ], + }), + expect.anything(), + ); + }); + }); + + it('should handle wrong data in team order preferences gracefully', async () => { + queryMyTeams.mockReturnValue({ + observe: jest.fn(() => of$([ + {id: '1', roles: 'team_user'}, + {id: '2', roles: 'team_user'}, + ])), + }); + + queryJoinedTeams.mockReturnValue({ + observe: jest.fn(() => of$([ + {id: '1', displayName: 'Team 1'}, + {id: '2', displayName: 'Team 2'}, + ])), + }); + + queryPreferencesByCategoryAndName.mockReturnValue({ + observeWithColumns: jest.fn(() => of$([{value: '1,undefined,2'}])), + }); + + render(); + + await waitFor(() => { + expect(TeamList).toHaveBeenCalledWith( + expect.objectContaining({ + myOrderedTeams: [ + {id: '1', roles: 'team_user'}, + {id: '2', roles: 'team_user'}, + ], + }), + expect.anything(), + ); + }); + }); + + it('should handle empty teams list gracefully', async () => { + queryMyTeams.mockReturnValue({ + observe: jest.fn(() => of$([])), + }); + + queryJoinedTeams.mockReturnValue({ + observe: jest.fn(() => of$([])), + }); + + queryPreferencesByCategoryAndName.mockReturnValue({ + observeWithColumns: jest.fn(() => of$([])), + }); + + render(); + await waitFor(() => { + expect(TeamList).toHaveBeenCalledWith( + expect.objectContaining({ + myOrderedTeams: [], + }), + expect.anything(), + ); + }); + }); +}); diff --git a/app/components/team_sidebar/team_list/index.ts b/app/components/team_sidebar/team_list/index.ts index 117c9c9c8db..17461f34f6a 100644 --- a/app/components/team_sidebar/team_list/index.ts +++ b/app/components/team_sidebar/team_list/index.ts @@ -14,12 +14,6 @@ import {queryJoinedTeams, queryMyTeams} from '@queries/servers/team'; import TeamList from './team_list'; import type {WithDatabaseArgs} from '@typings/database/database'; -import type MyTeamModel from '@typings/database/models/servers/my_team'; - -interface TeamWithLowerName { - myTeam: MyTeamModel; - lowerName?: string; -} const withTeams = withObservables([], ({database}: WithDatabaseArgs) => { const myTeams = queryMyTeams(database).observe(); @@ -37,35 +31,21 @@ const withTeams = withObservables([], ({database}: WithDatabaseArgs) => { if (sortedTeamIds.size) { const mySortedTeams = [...sortedTeamIds]. - filter((id) => membershipMap.has(id)). + filter((id) => id && membershipMap.has(id)). map((id) => membershipMap.get(id)!); const extraTeams = teams. - filter((t) => !sortedTeamIds.has(t.id) && membershipMap.has(t.id)). - map((t) => ({ - myTeam: membershipMap.get(t.id)!, - lowerName: t.displayName.toLocaleLowerCase(), - } as TeamWithLowerName)). - sort((a, b) => a.lowerName!.localeCompare(b.lowerName!)). - map((t) => { - delete t.lowerName; - return t; - }); + filter((t) => t.id && !sortedTeamIds.has(t.id) && membershipMap.has(t.id)). + sort((a, b) => a.displayName.toLocaleLowerCase().localeCompare(b.displayName.toLocaleLowerCase())). + map((t) => membershipMap.get(t.id)!); return [...mySortedTeams, ...extraTeams]; } return teams. - filter((t) => membershipMap.has(t.id)). - map((t) => ({ - myTeam: membershipMap.get(t.id)!, - lowerName: t.displayName.toLocaleLowerCase(), - } as TeamWithLowerName)). - sort((a, b) => a.lowerName!.localeCompare(b.lowerName!)). - map((t) => { - delete t.lowerName; - return t.myTeam; - }); + filter((t) => t.id && membershipMap.has(t.id)). + sort((a, b) => a.displayName.toLocaleLowerCase().localeCompare(b.displayName.toLocaleLowerCase())). + map((t) => membershipMap.get(t.id)!); }), ); return { From f911a29e4c9aac1800b8eacea6b97e40421c3fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Espino=20Garc=C3=ADa?= Date: Wed, 27 Nov 2024 16:18:08 +0100 Subject: [PATCH 20/36] Fix MM-61710 (#8368) --- app/components/autocomplete_selector/index.tsx | 3 ++- app/components/formatted_text/index.tsx | 4 +--- .../markdown/channel_mention/channel_mention.tsx | 3 ++- app/components/markdown/markdown_image/index.tsx | 3 ++- .../markdown/markdown_table_image/index.tsx | 3 ++- .../combined_user_activity.tsx | 12 +++++++----- .../combined_user_activity/last_users.tsx | 15 ++++++++++----- .../body/content/image_preview/image_preview.tsx | 3 ++- .../message_attachments/action_button/index.tsx | 3 ++- .../message_attachments/message_attachment.tsx | 3 ++- .../content/opengraph/opengraph_image/index.tsx | 6 ++---- .../post/system_message/system_message.tsx | 3 ++- app/components/selected_users/index.tsx | 6 +++--- app/database/components/index.tsx | 3 ++- app/screens/apps_form/apps_form_component.tsx | 11 ++++++++--- .../header/skintone_selector/skin_selector.tsx | 3 +-- .../skintone_selector/skintone_selector.tsx | 3 +-- app/screens/in_app_notification/index.tsx | 3 ++- .../integration_selector/integration_selector.tsx | 12 ++++++++---- app/screens/interactive_dialog/index.tsx | 11 ++++++++--- app/screens/invite/invite.tsx | 8 +++++--- app/screens/invite/summary_report.tsx | 3 ++- app/screens/permalink/permalink.tsx | 3 ++- app/utils/types.ts | 6 ++++++ 24 files changed, 84 insertions(+), 49 deletions(-) create mode 100644 app/utils/types.ts diff --git a/app/components/autocomplete_selector/index.tsx b/app/components/autocomplete_selector/index.tsx index 64f0842bb0b..9412a343670 100644 --- a/app/components/autocomplete_selector/index.tsx +++ b/app/components/autocomplete_selector/index.tsx @@ -19,6 +19,7 @@ import {getUserById, observeTeammateNameDisplay} from '@queries/servers/user'; import {goToScreen} from '@screens/navigation'; import {preventDoubleTap} from '@utils/tap'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import {displayUsername} from '@utils/user'; import type {WithDatabaseArgs} from '@typings/database/database'; @@ -93,7 +94,7 @@ async function getItemName(serverUrl: string, selected: string, teammateNameDisp return ''; } - const database = DatabaseManager.serverDatabases[serverUrl]?.database; + const database = secureGetFromRecord(DatabaseManager.serverDatabases, serverUrl)?.database; switch (dataSource) { case ViewConstants.DATA_SOURCE_USERS: { diff --git a/app/components/formatted_text/index.tsx b/app/components/formatted_text/index.tsx index fd8f335aa1f..a9b591aced1 100644 --- a/app/components/formatted_text/index.tsx +++ b/app/components/formatted_text/index.tsx @@ -46,9 +46,7 @@ const FormattedText = (props: FormattedTextProps) => { // when the `message` is formatted. This allows the formatted // message to then be broken-up into parts with references to the // React Elements inserted back in. - Object.keys(values).forEach((name) => { - const value = values[name]; - + Object.entries(values).forEach(([name, value]) => { if (isValidElement(value)) { const token = generateToken(); tokenizedValues[name] = tokenDelimiter + token + tokenDelimiter; diff --git a/app/components/markdown/channel_mention/channel_mention.tsx b/app/components/markdown/channel_mention/channel_mention.tsx index 1377e891df3..5dceb752f62 100644 --- a/app/components/markdown/channel_mention/channel_mention.tsx +++ b/app/components/markdown/channel_mention/channel_mention.tsx @@ -10,6 +10,7 @@ import {useServerUrl} from '@context/server'; import {t} from '@i18n'; import {alertErrorWithFallback} from '@utils/draft'; import {preventDoubleTap} from '@utils/tap'; +import {secureGetFromRecord} from '@utils/types'; import type ChannelModel from '@typings/database/models/servers/channel'; import type TeamModel from '@typings/database/models/servers/team'; @@ -40,7 +41,7 @@ function getChannelFromChannelName(name: string, channels: ChannelModel[], chann }); while (channelName.length > 0) { - if (channelsByName[channelName]) { + if (secureGetFromRecord(channelsByName, channelName)) { return channelsByName[channelName]; } diff --git a/app/components/markdown/markdown_image/index.tsx b/app/components/markdown/markdown_image/index.tsx index db4a679927e..23bead8ca58 100644 --- a/app/components/markdown/markdown_image/index.tsx +++ b/app/components/markdown/markdown_image/index.tsx @@ -29,6 +29,7 @@ import {bottomSheetSnapPoint} from '@utils/helpers'; import {calculateDimensions, getViewPortWidth, isGifTooLarge} from '@utils/images'; import {getMarkdownImageSize} from '@utils/markdown'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import {normalizeProtocol, tryOpenURL} from '@utils/url'; import type {GalleryItemType} from '@typings/screens/gallery'; @@ -80,7 +81,7 @@ const MarkdownImage = ({ const style = getStyleSheet(theme); const managedConfig = useManagedConfig(); const genericFileId = useRef(generateId('uid')).current; - const metadata = imagesMetadata?.[source] || Object.values(imagesMetadata || {})[0]; + const metadata = secureGetFromRecord(imagesMetadata, source) || Object.values(imagesMetadata || {})[0]; const [failed, setFailed] = useState(isGifTooLarge(metadata)); const originalSize = getMarkdownImageSize(isReplyPost, isTablet, sourceSize, metadata, layoutWidth, layoutHeight); const serverUrl = useServerUrl(); diff --git a/app/components/markdown/markdown_table_image/index.tsx b/app/components/markdown/markdown_table_image/index.tsx index 042887befee..a285b141f22 100644 --- a/app/components/markdown/markdown_table_image/index.tsx +++ b/app/components/markdown/markdown_table_image/index.tsx @@ -13,6 +13,7 @@ import {useGalleryItem} from '@hooks/gallery'; import {fileToGalleryItem, openGalleryAtIndex} from '@utils/gallery'; import {generateId} from '@utils/general'; import {calculateDimensions, isGifTooLarge} from '@utils/images'; +import {secureGetFromRecord} from '@utils/types'; import type {GalleryItemType} from '@typings/screens/gallery'; @@ -33,7 +34,7 @@ const style = StyleSheet.create({ }); const MarkTableImage = ({disabled, imagesMetadata, location, postId, serverURL, source}: MarkdownTableImageProps) => { - const metadata = imagesMetadata[source]; + const metadata = secureGetFromRecord(imagesMetadata, source); const fileId = useRef(generateId('uid')).current; const [failed, setFailed] = useState(isGifTooLarge(metadata)); const currentServerUrl = useServerUrl(); diff --git a/app/components/post_list/combined_user_activity/combined_user_activity.tsx b/app/components/post_list/combined_user_activity/combined_user_activity.tsx index 845688c0437..eafea6dd27b 100644 --- a/app/components/post_list/combined_user_activity/combined_user_activity.tsx +++ b/app/components/post_list/combined_user_activity/combined_user_activity.tsx @@ -16,6 +16,7 @@ import {bottomSheetModalOptions, showModal, showModalOverCurrentContext} from '@ import {emptyFunction} from '@utils/general'; import {getMarkdownTextStyles} from '@utils/markdown'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import LastUsers from './last_users'; import {postTypeMessages} from './messages'; @@ -76,7 +77,7 @@ const CombinedUserActivity = ({ const usernamesValues = Object.values(usernamesById); const usernames = userIds.reduce((acc: string[], id: string) => { if (id !== currentUserId && id !== currentUsername) { - const name = usernamesById[id] ?? usernamesValues.find((n) => n === id); + const name = secureGetFromRecord(usernamesById, id) ?? usernamesValues.find((n) => n === id); acc.push(name ? `@${name}` : someone); } return acc; @@ -112,7 +113,7 @@ const CombinedUserActivity = ({ return null; } let actor = ''; - if (usernamesById[actorId]) { + if (secureGetFromRecord(usernamesById, actorId)) { actor = `@${usernamesById[actorId]}`; } @@ -141,11 +142,11 @@ const CombinedUserActivity = ({ const secondUser = usernames[1]; let localeHolder; if (numOthers === 0) { - localeHolder = postTypeMessages[postType].one; + localeHolder = secureGetFromRecord(postTypeMessages, postType)?.one; if ( (userIds[0] === currentUserId || userIds[0] === currentUsername) && - postTypeMessages[postType].one_you + secureGetFromRecord(postTypeMessages, postType)?.one_you ) { localeHolder = postTypeMessages[postType].one_you; } @@ -153,7 +154,8 @@ const CombinedUserActivity = ({ localeHolder = postTypeMessages[postType].two; } - const formattedMessage = intl.formatMessage(localeHolder, {firstUser, secondUser, actor}); + // We default to empty string, but this should never happen + const formattedMessage = localeHolder ? intl.formatMessage(localeHolder, {firstUser, secondUser, actor}) : ''; return ( { diff --git a/app/components/post_list/post/body/content/message_attachments/action_button/index.tsx b/app/components/post_list/post/body/content/message_attachments/action_button/index.tsx index 4778aea3ed9..328c85a5036 100644 --- a/app/components/post_list/post/body/content/message_attachments/action_button/index.tsx +++ b/app/components/post_list/post/body/content/message_attachments/action_button/index.tsx @@ -9,6 +9,7 @@ import {useServerUrl} from '@context/server'; import {getStatusColors} from '@utils/message_attachment_colors'; import {preventDoubleTap} from '@utils/tap'; import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import ActionButtonText from './action_button_text'; @@ -65,7 +66,7 @@ const ActionButton = ({buttonColor, cookie, disabled, id, name, postId, theme}: if (buttonColor) { const STATUS_COLORS = getStatusColors(theme); - const hexColor = STATUS_COLORS[buttonColor] || theme[buttonColor] || buttonColor; + const hexColor = secureGetFromRecord(STATUS_COLORS, buttonColor) || secureGetFromRecord(theme, buttonColor) || buttonColor; customButtonStyle = {borderColor: changeOpacity(hexColor, 0.25), backgroundColor: '#ffffff'}; customButtonTextStyle = {color: hexColor}; } diff --git a/app/components/post_list/post/body/content/message_attachments/message_attachment.tsx b/app/components/post_list/post/body/content/message_attachments/message_attachment.tsx index ed557d6df04..97f1afd271e 100644 --- a/app/components/post_list/post/body/content/message_attachments/message_attachment.tsx +++ b/app/components/post_list/post/body/content/message_attachments/message_attachment.tsx @@ -7,6 +7,7 @@ import {View} from 'react-native'; import {getMarkdownBlockStyles, getMarkdownTextStyles} from '@utils/markdown'; import {getStatusColors} from '@utils/message_attachment_colors'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import {isValidUrl} from '@utils/url'; import AttachmentActions from './attachment_actions'; @@ -62,7 +63,7 @@ export default function MessageAttachment({attachment, channelId, layoutWidth, l if (attachment.color) { if (attachment.color[0] === '#') { borderStyle = {borderLeftColor: attachment.color}; - } else if (STATUS_COLORS[attachment.color]) { + } else if (secureGetFromRecord(STATUS_COLORS, attachment.color)) { borderStyle = {borderLeftColor: STATUS_COLORS[attachment.color]}; } } diff --git a/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx b/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx index c6ee80a68f6..e8615387783 100644 --- a/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx +++ b/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx @@ -16,6 +16,7 @@ import {isTablet} from '@utils/helpers'; import {calculateDimensions} from '@utils/images'; import {type BestImage, getNearestPoint} from '@utils/opengraph'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import {extractFilenameFromUrl, isValidUrl} from '@utils/url'; import type {GalleryItemType} from '@typings/screens/gallery'; @@ -71,10 +72,7 @@ const OpengraphImage = ({isReplyPost, layoutWidth, location, metadata, openGraph const imageUrl = (bestImage.secure_url || bestImage.url)!; const imagesMetadata = metadata?.images; - let ogImage; - if (imagesMetadata && imagesMetadata[imageUrl]) { - ogImage = imagesMetadata[imageUrl]; - } + let ogImage = secureGetFromRecord(imagesMetadata, imageUrl); if (!ogImage) { ogImage = openGraphImages.find((i: BestImage) => i.url === imageUrl || i.secure_url === imageUrl); diff --git a/app/components/post_list/post/system_message/system_message.tsx b/app/components/post_list/post/system_message/system_message.tsx index 479253c39a5..f7c88540452 100644 --- a/app/components/post_list/post/system_message/system_message.tsx +++ b/app/components/post_list/post/system_message/system_message.tsx @@ -12,6 +12,7 @@ import {useTheme} from '@context/theme'; import {t} from '@i18n'; import {getMarkdownTextStyles} from '@utils/markdown'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import {typography} from '@utils/typography'; import type PostModel from '@typings/database/models/servers/post'; @@ -276,7 +277,7 @@ export const SystemMessage = ({post, location, author, hideGuestTags}: SystemMes return renderAddGuestToChannelMessage({post, author, location, styles, intl, theme}, hideGuestTags); } - const renderer = systemMessageRenderers[post.type]; + const renderer = secureGetFromRecord(systemMessageRenderers, post.type); if (!renderer) { return ( { const u = []; - for (const id of Object.keys(selectedIds)) { - if (!selectedIds[id]) { + for (const [id, user] of Object.entries(selectedIds)) { + if (!user) { continue; } u.push( (Component: if (server) { const database = - DatabaseManager.serverDatabases[server.url]?.database; + secureGetFromRecord(DatabaseManager.serverDatabases, server.url)?.database; if (database) { setState({ diff --git a/app/screens/apps_form/apps_form_component.tsx b/app/screens/apps_form/apps_form_component.tsx index 5ca04c7e065..bf438c3c95c 100644 --- a/app/screens/apps_form/apps_form_component.tsx +++ b/app/screens/apps_form/apps_form_component.tsx @@ -20,6 +20,7 @@ import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles'; import {checkDialogElementForError, checkIfErrorsMatchElements} from '@utils/integrations'; import {getMarkdownBlockStyles, getMarkdownTextStyles} from '@utils/markdown'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import DialogIntroductionText from '../interactive_dialog/dialog_introduction_text'; import {buildNavigationButton, dismissModal, setButtons} from '../navigation'; @@ -263,7 +264,7 @@ function AppsFormComponent({ elements?.forEach((element) => { const newError = checkDialogElementForError( element, - element.name === form.submit_buttons ? button : values[element.name], + element.name === form.submit_buttons ? button : secureGetFromRecord(values, element.name), ); if (newError) { hasErrors = true; @@ -408,13 +409,17 @@ function AppsFormComponent({ /> } {form.fields && form.fields.filter((f) => f.name !== form.submit_buttons).map((field) => { + const value = secureGetFromRecord(values, field.name); + if (!value) { + return null; + } return ( diff --git a/app/screens/emoji_picker/picker/header/skintone_selector/skin_selector.tsx b/app/screens/emoji_picker/picker/header/skintone_selector/skin_selector.tsx index 41bf06fd42d..2ef00eb9f5c 100644 --- a/app/screens/emoji_picker/picker/header/skintone_selector/skin_selector.tsx +++ b/app/screens/emoji_picker/picker/header/skintone_selector/skin_selector.tsx @@ -68,8 +68,7 @@ const SkinSelector = ({onSelectSkin, selected, skins}: Props) => { /> - {Object.keys(skins).map((key) => { - const name = skins[key]; + {Object.entries(skins).map(([key, name]) => { return ( >((result, value) => { - const skin = skinCodes[value]; +const skins = Object.entries(skinCodes).reduce>((result, [value, skin]) => { if (value === 'default') { result[value] = 'hand'; } else { diff --git a/app/screens/in_app_notification/index.tsx b/app/screens/in_app_notification/index.tsx index 787f0190ce2..54bb67d6563 100644 --- a/app/screens/in_app_notification/index.tsx +++ b/app/screens/in_app_notification/index.tsx @@ -15,6 +15,7 @@ import {useIsTablet} from '@hooks/device'; import {dismissOverlay} from '@screens/navigation'; import {preventDoubleTap} from '@utils/tap'; import {changeOpacity} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import Icon from './icon'; import Server from './server'; @@ -148,7 +149,7 @@ const InAppNotification = ({componentId, serverName, serverUrl, notification}: I // eslint-disable-next-line new-cap const gesture = Gesture.Pan().activeOffsetY(-20).onStart(() => runOnJS(animateDismissOverlay)()); - const database = DatabaseManager.serverDatabases[serverUrl]?.database; + const database = secureGetFromRecord(DatabaseManager.serverDatabases, serverUrl)?.database; return ( diff --git a/app/screens/integration_selector/integration_selector.tsx b/app/screens/integration_selector/integration_selector.tsx index 434bf0d8922..8cc324f2c70 100644 --- a/app/screens/integration_selector/integration_selector.tsx +++ b/app/screens/integration_selector/integration_selector.tsx @@ -24,6 +24,7 @@ import { } from '@screens/navigation'; import {filterChannelsMatchingTerm} from '@utils/channel'; import {changeOpacity, getKeyboardAppearanceFromTheme, makeStyleSheetFromTheme} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import {typography} from '@utils/typography'; import ChannelListRow from './channel_list_row'; @@ -68,7 +69,8 @@ const extractItemKey = (dataSource: string, item: DataType): string => { const toggleFromMap = (current: MultiselectSelectedMap, key: string, item: T): MultiselectSelectedMap => { const newMap = {...current}; - if (current[key]) { + const hasValue = Boolean(secureGetFromRecord(current, key)); + if (hasValue) { delete newMap[key]; } else { newMap[key] = item; @@ -96,7 +98,7 @@ const filterSearchData = (source: string, searchData: DataTypeList, searchTerm: const handleIdSelection = (dataSource: string, currentIds: {[id: string]: DataType}, item: DataType) => { const newSelectedIds = {...currentIds}; const key = extractItemKey(dataSource, item); - const wasSelected = currentIds[key]; + const wasSelected = secureGetFromRecord(currentIds, key); if (wasSelected) { Reflect.deleteProperty(newSelectedIds, key); @@ -239,7 +241,9 @@ function IntegrationSelector( } else { setMultiselectSelected((current) => { const multiselectSelectedItems = {...current}; - delete multiselectSelectedItems[itemKey]; + if (secureGetFromRecord(multiselectSelectedItems, itemKey) !== undefined) { + delete multiselectSelectedItems[itemKey]; + } return multiselectSelectedItems; }); } @@ -470,7 +474,7 @@ function IntegrationSelector( }, [multiselectSelected, theme, isMultiselect]); const renderOptionItem = useCallback((itemProps: any) => { - const itemSelected = Boolean(multiselectSelected[itemProps.item.value]); + const itemSelected = Boolean(secureGetFromRecord(multiselectSelected, itemProps.item.value)); return ( { - const newError = checkDialogElementForError(elem, values[elem.name]); + const newError = checkDialogElementForError(elem, secureGetFromRecord(values, elem.name)); if (newError) { newErrors[elem.name] = intl.formatMessage({id: newError.id, defaultMessage: newError.defaultMessage}, newError.values); hasErrors = true; @@ -244,6 +245,10 @@ function InteractiveDialog({ /> } {Boolean(elements) && elements.map((e) => { + const value = secureGetFromRecord(values, e.name); + if (value === undefined) { + return null; + } return ( ); diff --git a/app/screens/invite/invite.tsx b/app/screens/invite/invite.tsx index fd81ccea49c..de6f1ea0a00 100644 --- a/app/screens/invite/invite.tsx +++ b/app/screens/invite/invite.tsx @@ -19,6 +19,7 @@ import {dismissModal, setButtons} from '@screens/navigation'; import {isEmail} from '@utils/helpers'; import {mergeNavigationOptions} from '@utils/navigation'; import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import {isGuest} from '@utils/user'; import Selection from './selection'; @@ -183,7 +184,7 @@ export default function Invite({ const id = email ? item : (item as UserProfile).id; const newSelectedIds = Object.assign({}, selectedIds); - if (!selectedIds[id]) { + if (!secureGetFromRecord(selectedIds, id)) { newSelectedIds[id] = item; } @@ -301,8 +302,9 @@ export default function Invite({ } for (const email of emails) { - if (membersWithError[email]) { - notSent.push({userId: email, reason: membersWithError[email]}); + const error = secureGetFromRecord(membersWithError, email); + if (error) { + notSent.push({userId: email, reason: error}); } else { sent.push({userId: email, reason: formatMessage({id: 'invite.summary.email_invite', defaultMessage: 'An invitation email has been sent'})}); } diff --git a/app/screens/invite/summary_report.tsx b/app/screens/invite/summary_report.tsx index 8819ca6b2bc..35ec7f41b02 100644 --- a/app/screens/invite/summary_report.tsx +++ b/app/screens/invite/summary_report.tsx @@ -9,6 +9,7 @@ import CompassIcon from '@components/compass_icon'; import UserItem from '@components/user_item'; import {useTheme} from '@context/theme'; import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme'; +import {secureGetFromRecord} from '@utils/types'; import {typography} from '@utils/typography'; import TextItem, {TextItemType} from './text_item'; @@ -114,7 +115,7 @@ export default function SummaryReport({ {invites.map(({userId, reason}) => { - const item = selectedIds[userId]; + const item = secureGetFromRecord(selectedIds, userId); return ( (v: Record | undefined, key: string) { + return typeof v === 'object' && v && Object.prototype.hasOwnProperty.call(v, key) ? v[key] : undefined; +} From 732b17a75c635812ad20424a941cb457c5635bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Espino=20Garc=C3=ADa?= Date: Thu, 28 Nov 2024 15:59:30 +0100 Subject: [PATCH 21/36] Add post props validation (#8323) * Validate props * Add calls changes and fix attachments * Address feedback --- app/actions/local/post.ts | 2 +- app/actions/remote/post.ts | 4 +- app/actions/remote/search.ts | 2 +- app/components/files/files.tsx | 2 +- .../channel_mention/channel_mention.tsx | 30 +- .../markdown/channel_mention/index.ts | 2 - app/components/markdown/markdown.tsx | 3 +- .../combined_user_activity.tsx | 19 +- .../post_list/combined_user_activity/index.ts | 7 +- .../post_list/post/avatar/avatar.tsx | 10 +- .../post/body/add_members/add_members.tsx | 53 +++- .../button_binding/index.tsx | 2 +- .../body/content/embedded_bindings/index.tsx | 5 +- .../post_list/post/body/content/index.tsx | 13 +- .../action_button/index.tsx | 2 +- .../message_attachment.tsx | 2 +- app/components/post_list/post/body/index.tsx | 5 +- .../post_list/post/body/message/message.tsx | 11 +- .../post_list/post/header/header.tsx | 7 +- .../post/system_message/system_message.tsx | 32 +- app/helpers/api/user.ts | 6 +- .../components/calls_custom_message/index.ts | 2 +- app/products/calls/utils.test.ts | 14 +- app/products/calls/utils.ts | 29 +- app/screens/gallery/footer/footer.tsx | 5 +- app/utils/apps.ts | 295 ++++++++++++++++++ app/utils/gallery/index.ts | 2 +- app/utils/message_attachment.ts | 195 ++++++++++++ app/utils/message_attachment_colors.test.ts | 2 +- app/utils/message_attachment_colors.ts | 13 - app/utils/post/index.test.ts | 12 +- app/utils/post/index.ts | 14 +- app/utils/post_list/index.test.ts | 18 +- app/utils/post_list/index.ts | 63 +++- app/utils/types.ts | 36 +++ package-lock.json | 10 +- package.json | 2 +- types/api/files.d.ts | 2 +- types/api/posts.d.ts | 2 +- types/database/models/servers/post.ts | 2 +- types/screens/gallery.ts | 2 +- 41 files changed, 801 insertions(+), 138 deletions(-) create mode 100644 app/utils/message_attachment.ts delete mode 100644 app/utils/message_attachment_colors.ts diff --git a/app/actions/local/post.ts b/app/actions/local/post.ts index 8dffef59988..5a9b159a747 100644 --- a/app/actions/local/post.ts +++ b/app/actions/local/post.ts @@ -160,7 +160,7 @@ export async function markPostAsDeleted(serverUrl: string, post: Post, prepareRe p.message = ''; p.messageSource = ''; p.metadata = null; - p.props = undefined; + p.props = null; }); if (!prepareRecordsOnly) { diff --git a/app/actions/remote/post.ts b/app/actions/remote/post.ts index e358a094cb8..fd3193178d6 100644 --- a/app/actions/remote/post.ts +++ b/app/actions/remote/post.ts @@ -80,7 +80,7 @@ export async function createPost(serverUrl: string, post: Partial, files: const pendingPostId = post.pending_post_id || `${currentUserId}:${timestamp}`; const existing = await getPostById(database, pendingPostId); - if (existing && !existing.props.failed) { + if (existing && !existing.props?.failed) { return {data: false}; } @@ -240,7 +240,7 @@ export const retryFailedPost = async (serverUrl: string, post: PostModel) => { // timestamps will remain the same as the initial attempt for createAt // but updateAt will be use for the optimistic post UI post.prepareUpdate((p) => { - p.props = newPost.props; + p.props = newPost.props || null; p.updateAt = timestamp; }); await operator.batchRecords([post], 'retryFailedPost - first update'); diff --git a/app/actions/remote/search.ts b/app/actions/remote/search.ts index 7f99bb6e945..2a5783eacda 100644 --- a/app/actions/remote/search.ts +++ b/app/actions/remote/search.ts @@ -161,7 +161,7 @@ export const searchFiles = async (serverUrl: string, teamId: string, params: Fil }, {}); files.forEach((f) => { if (f.post_id) { - f.postProps = idToPost[f.post_id]?.props; + f.postProps = idToPost[f.post_id]?.props || {}; } }); return {files, channels}; diff --git a/app/components/files/files.tsx b/app/components/files/files.tsx index da11d676f2d..710466ea79e 100644 --- a/app/components/files/files.tsx +++ b/app/components/files/files.tsx @@ -24,7 +24,7 @@ type FilesProps = { location: string; isReplyPost: boolean; postId: string; - postProps: Record; + postProps: Record; publicLinkEnabled: boolean; } diff --git a/app/components/markdown/channel_mention/channel_mention.tsx b/app/components/markdown/channel_mention/channel_mention.tsx index 5dceb752f62..554dfbf1bf5 100644 --- a/app/components/markdown/channel_mention/channel_mention.tsx +++ b/app/components/markdown/channel_mention/channel_mention.tsx @@ -10,12 +10,38 @@ import {useServerUrl} from '@context/server'; import {t} from '@i18n'; import {alertErrorWithFallback} from '@utils/draft'; import {preventDoubleTap} from '@utils/tap'; -import {secureGetFromRecord} from '@utils/types'; +import {secureGetFromRecord, isRecordOf} from '@utils/types'; import type ChannelModel from '@typings/database/models/servers/channel'; import type TeamModel from '@typings/database/models/servers/team'; -export type ChannelMentions = Record; +export type ChannelMentions = Record; + +export function isChannelMentions(v: unknown): v is ChannelMentions { + return isRecordOf(v, (e) => { + if (typeof e !== 'object' || !e) { + return false; + } + + if (!('display_name' in e) || typeof e.display_name !== 'string') { + return false; + } + + if ('team_name' in e && typeof e.team_name !== 'string') { + return false; + } + + if ('id' in e && typeof e.id !== 'string') { + return false; + } + + if ('name' in e && typeof e.name !== 'string') { + return false; + } + + return true; + }); +} type ChannelMentionProps = { channelMentions?: ChannelMentions; diff --git a/app/components/markdown/channel_mention/index.ts b/app/components/markdown/channel_mention/index.ts index 6843061f79e..7e56b7f4800 100644 --- a/app/components/markdown/channel_mention/index.ts +++ b/app/components/markdown/channel_mention/index.ts @@ -12,8 +12,6 @@ import ChannelMention from './channel_mention'; import type {WithDatabaseArgs} from '@typings/database/database'; -export type ChannelMentions = Record; - const enhance = withObservables([], ({database}: WithDatabaseArgs) => { const currentTeamId = observeCurrentTeamId(database); const channels = currentTeamId.pipe( diff --git a/app/components/markdown/markdown.tsx b/app/components/markdown/markdown.tsx index 934e7cdfb01..369c435a222 100644 --- a/app/components/markdown/markdown.tsx +++ b/app/components/markdown/markdown.tsx @@ -17,7 +17,7 @@ import {typography} from '@utils/typography'; import {getScheme} from '@utils/url'; import AtMention from './at_mention'; -import ChannelMention, {type ChannelMentions} from './channel_mention'; +import ChannelMention from './channel_mention'; import Hashtag from './hashtag'; import MarkdownBlockQuote from './markdown_block_quote'; import MarkdownCodeBlock from './markdown_code_block'; @@ -33,6 +33,7 @@ import MarkdownTableImage from './markdown_table_image'; import MarkdownTableRow, {type MarkdownTableRowProps} from './markdown_table_row'; import {addListItemIndices, combineTextNodes, highlightMentions, highlightWithoutNotification, highlightSearchPatterns, parseTaskLists, pullOutImages} from './transform'; +import type {ChannelMentions} from './channel_mention/channel_mention'; import type { MarkdownAtMentionRenderer, MarkdownBaseRenderer, MarkdownBlockStyles, MarkdownChannelMentionRenderer, MarkdownEmojiRenderer, MarkdownImageRenderer, MarkdownLatexRenderer, MarkdownTextStyles, SearchPattern, UserMentionKey, HighlightWithoutNotificationKey, diff --git a/app/components/post_list/combined_user_activity/combined_user_activity.tsx b/app/components/post_list/combined_user_activity/combined_user_activity.tsx index eafea6dd27b..c176b02905f 100644 --- a/app/components/post_list/combined_user_activity/combined_user_activity.tsx +++ b/app/components/post_list/combined_user_activity/combined_user_activity.tsx @@ -1,7 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useCallback, useEffect} from 'react'; +import React, {useCallback, useEffect, useMemo} from 'react'; import {useIntl} from 'react-intl'; import {Keyboard, type StyleProp, TouchableHighlight, View, type ViewStyle} from 'react-native'; @@ -15,6 +15,7 @@ import {useIsTablet} from '@hooks/device'; import {bottomSheetModalOptions, showModal, showModalOverCurrentContext} from '@screens/navigation'; import {emptyFunction} from '@utils/general'; import {getMarkdownTextStyles} from '@utils/markdown'; +import {isUserActivityProp} from '@utils/post_list'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; import {secureGetFromRecord} from '@utils/types'; @@ -71,6 +72,13 @@ const CombinedUserActivity = ({ const content = []; const removedUserIds: string[] = []; + const userActivity = useMemo(() => { + if (isUserActivityProp(post?.props?.user_activity)) { + return post?.props?.user_activity; + } + return undefined; + }, [post?.props?.user_activity]); + const getUsernames = (userIds: string[]) => { const someone = intl.formatMessage({id: 'channel_loader.someone', defaultMessage: 'Someone'}); const you = intl.formatMessage({id: 'combined_system_message.you', defaultMessage: 'You'}); @@ -170,11 +178,12 @@ const CombinedUserActivity = ({ }; useEffect(() => { - if (!post) { + if (!userActivity) { return; } - const {allUserIds, allUsernames} = post.props.user_activity; + const allUserIds = userActivity.allUserIds; + const allUsernames = userActivity.allUsernames; if (allUserIds.length) { fetchMissingProfilesByIds(serverUrl, allUserIds); } @@ -182,14 +191,14 @@ const CombinedUserActivity = ({ if (allUsernames.length) { fetchMissingProfilesByUsernames(serverUrl, allUsernames); } - }, [post?.props.user_activity.allUserIds, post?.props.user_activity.allUsernames]); + }, [userActivity?.allUserIds, userActivity?.allUsernames]); if (!post) { return null; } const itemTestID = `${testID}.${post.id}`; - const {messageData} = post.props.user_activity; + const messageData = userActivity?.messageData || []; for (const message of messageData) { const {postType, actorId} = message; const userIds = new Set(message.userIds); diff --git a/app/components/post_list/combined_user_activity/index.ts b/app/components/post_list/combined_user_activity/index.ts index 5ad70b51367..de0b5b6e703 100644 --- a/app/components/post_list/combined_user_activity/index.ts +++ b/app/components/post_list/combined_user_activity/index.ts @@ -11,7 +11,7 @@ import {queryPostsById} from '@queries/servers/post'; import {observePermissionForPost} from '@queries/servers/role'; import {observeCurrentUserId} from '@queries/servers/system'; import {observeUser, queryUsersByIdsOrUsernames} from '@queries/servers/user'; -import {generateCombinedPost, getPostIdsForCombinedUserActivityPost} from '@utils/post_list'; +import {generateCombinedPost, getPostIdsForCombinedUserActivityPost, isUserActivityProp} from '@utils/post_list'; import CombinedUserActivity from './combined_user_activity'; @@ -35,10 +35,11 @@ const withCombinedPosts = withObservables(['postId'], ({database, postId}: WithD const usernamesById = post.pipe( switchMap( (p) => { - if (!p) { + const userActivity = isUserActivityProp(p?.props?.user_activity) ? p.props.user_activity : undefined; + if (!userActivity) { return of$>({}); } - return queryUsersByIdsOrUsernames(database, p.props.user_activity.allUserIds, p.props.user_activity.allUsernames).observeWithColumns(['username']). + return queryUsersByIdsOrUsernames(database, userActivity.allUserIds, userActivity.allUsernames).observeWithColumns(['username']). pipe( // eslint-disable-next-line max-nested-callbacks switchMap((users) => { diff --git a/app/components/post_list/post/avatar/avatar.tsx b/app/components/post_list/post/avatar/avatar.tsx index 22e56729550..ac8f8aa4cbe 100644 --- a/app/components/post_list/post/avatar/avatar.tsx +++ b/app/components/post_list/post/avatar/avatar.tsx @@ -14,6 +14,7 @@ import {useServerUrl} from '@context/server'; import {useTheme} from '@context/theme'; import {openAsBottomSheet} from '@screens/navigation'; import {preventDoubleTap} from '@utils/tap'; +import {ensureString} from '@utils/types'; import type PostModel from '@typings/database/models/servers/post'; import type UserModel from '@typings/database/models/servers/user'; @@ -39,12 +40,15 @@ const Avatar = ({author, enablePostIconOverride, isAutoReponse, location, post}: const fromWebHook = post.props?.from_webhook === 'true'; const iconOverride = enablePostIconOverride && post.props?.use_user_icon !== 'true'; + const propsIconUrl = ensureString(post.props?.override_icon_url); + const propsUsername = ensureString(post.props?.override_username); + if (fromWebHook && iconOverride) { const isEmoji = Boolean(post.props?.override_icon_emoji); const frameSize = ViewConstant.PROFILE_PICTURE_SIZE; const pictureSize = isEmoji ? ViewConstant.PROFILE_PICTURE_EMOJI_SIZE : ViewConstant.PROFILE_PICTURE_SIZE; const borderRadius = isEmoji ? 0 : ViewConstant.PROFILE_PICTURE_SIZE / 2; - const overrideIconUrl = buildAbsoluteUrl(serverUrl, post.props?.override_icon_url); + const overrideIconUrl = buildAbsoluteUrl(serverUrl, propsIconUrl); let iconComponent: ReactNode; if (overrideIconUrl) { @@ -95,8 +99,8 @@ const Avatar = ({author, enablePostIconOverride, isAutoReponse, location, post}: userId: author.id, channelId: post.channelId, location, - userIconOverride: post.props?.override_username, - usernameOverride: post.props?.override_icon_url, + userIconOverride: propsIconUrl, + usernameOverride: propsUsername, }; Keyboard.dismiss(); diff --git a/app/components/post_list/post/body/add_members/add_members.tsx b/app/components/post_list/post/body/add_members/add_members.tsx index 0217af3e830..c9a0247b287 100644 --- a/app/components/post_list/post/body/add_members/add_members.tsx +++ b/app/components/post_list/post/body/add_members/add_members.tsx @@ -14,6 +14,7 @@ import {useServerUrl} from '@context/server'; import {t} from '@i18n'; import {getMarkdownTextStyles} from '@utils/markdown'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {isStringArray} from '@utils/types'; import type PostModel from '@typings/database/models/servers/post'; import type UserModel from '@typings/database/models/servers/user'; @@ -26,6 +27,39 @@ type AddMembersProps = { theme: Theme; } +export type AddMemberPostProps = { + post_id: string; + not_in_channel_user_ids?: string[]; + not_in_groups_usernames?: string[]; + not_in_channel_usernames?: string[]; + user_ids?: string[]; + usernames?: string[]; +} + +export function isAddMemberProps(v: unknown): v is AddMemberPostProps { + if (typeof v !== 'object' || !v) { + return false; + } + + if (!('post_id' in v) || typeof v.post_id !== 'string') { + return false; + } + + if (('not_in_channel_user_ids' in v) && !isStringArray(v.not_in_channel_user_ids)) { + return false; + } + + if (('not_in_groups_usernames' in v) && !isStringArray(v.not_in_groups_usernames)) { + return false; + } + + if (('not_in_channel_usernames' in v) && !isStringArray(v.not_in_channel_usernames)) { + return false; + } + + return true; +} + const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { return { message: { @@ -41,20 +75,17 @@ const AddMembers = ({channelType, currentUser, location, post, theme}: AddMember const styles = getStyleSheet(theme); const textStyles = getMarkdownTextStyles(theme); const serverUrl = useServerUrl(); - const postId: string = post.props.add_channel_member?.post_id; - const noGroupsUsernames = post.props.add_channel_member?.not_in_groups_usernames; - let userIds: string[] = post.props.add_channel_member?.not_in_channel_user_ids; - let usernames: string[] = post.props.add_channel_member?.not_in_channel_usernames; - - if (!postId || !channelType) { + if (!isAddMemberProps(post.props?.add_channel_member)) { return null; } - if (!userIds) { - userIds = post.props.add_channel_member?.user_ids; - } - if (!usernames) { - usernames = post.props.add_channel_member?.usernames; + const postId = post.props.add_channel_member.post_id; + const noGroupsUsernames = post.props.add_channel_member.not_in_groups_usernames || []; + const userIds = post.props.add_channel_member.not_in_channel_user_ids || post.props.add_channel_member.user_ids || []; + const usernames = post.props.add_channel_member.not_in_channel_usernames || post.props.add_channel_member?.usernames || []; + + if (!postId || !channelType) { + return null; } const handleAddChannelMember = () => { diff --git a/app/components/post_list/post/body/content/embedded_bindings/button_binding/index.tsx b/app/components/post_list/post/body/content/embedded_bindings/button_binding/index.tsx index b4b6fbc4d38..dafa0671e4d 100644 --- a/app/components/post_list/post/body/content/embedded_bindings/button_binding/index.tsx +++ b/app/components/post_list/post/body/content/embedded_bindings/button_binding/index.tsx @@ -15,7 +15,7 @@ import {observeChannel} from '@queries/servers/channel'; import {observeCurrentTeamId} from '@queries/servers/system'; import {showAppForm} from '@screens/navigation'; import {createCallContext} from '@utils/apps'; -import {getStatusColors} from '@utils/message_attachment_colors'; +import {getStatusColors} from '@utils/message_attachment'; import {preventDoubleTap} from '@utils/tap'; import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme'; diff --git a/app/components/post_list/post/body/content/embedded_bindings/index.tsx b/app/components/post_list/post/body/content/embedded_bindings/index.tsx index 3c6d1a3858c..afad7f7d2d2 100644 --- a/app/components/post_list/post/body/content/embedded_bindings/index.tsx +++ b/app/components/post_list/post/body/content/embedded_bindings/index.tsx @@ -4,6 +4,9 @@ import React from 'react'; import {View} from 'react-native'; +import {isAppBinding, validateBindings} from '@utils/apps'; +import {isArrayOf} from '@utils/types'; + import EmbeddedBinding from './embedded_binding'; import type PostModel from '@typings/database/models/servers/post'; @@ -16,7 +19,7 @@ type Props = { const EmbeddedBindings = ({location, post, theme}: Props) => { const content: React.ReactNode[] = []; - const embeds: AppBinding[] = post.props.app_bindings; + const embeds: AppBinding[] = isArrayOf(post.props?.app_bindings, isAppBinding) ? validateBindings(post.props.app_bindings) : []; embeds.forEach((embed, i) => { content.push( diff --git a/app/components/post_list/post/body/content/index.tsx b/app/components/post_list/post/body/content/index.tsx index 38ae3b79b18..abf34b557ab 100644 --- a/app/components/post_list/post/body/content/index.tsx +++ b/app/components/post_list/post/body/content/index.tsx @@ -3,6 +3,7 @@ import React from 'react'; +import {isMessageAttachmentArray} from '@utils/message_attachment'; import {isYoutubeLink} from '@utils/url'; import EmbeddedBindings from './embedded_bindings'; @@ -31,7 +32,9 @@ const contentType: Record = { const Content = ({isReplyPost, layoutWidth, location, post, theme}: ContentProps) => { let type: string | undefined = post.metadata?.embeds?.[0].type; - if (!type && post.props?.app_bindings?.length) { + + const nAppBindings = Array.isArray(post.props?.app_bindings) ? post.props.app_bindings.length : 0; + if (!type && nAppBindings) { type = contentType.app_bindings; } @@ -39,6 +42,8 @@ const Content = ({isReplyPost, layoutWidth, location, post, theme}: ContentProps return null; } + const attachments = isMessageAttachmentArray(post.props?.attachments) ? post.props.attachments : []; + switch (contentType[type]) { case contentType.image: return ( @@ -74,10 +79,10 @@ const Content = ({isReplyPost, layoutWidth, location, post, theme}: ContentProps /> ); case contentType.message_attachment: - if (post.props.attachments?.length) { + if (attachments.length) { return ( |undefined => { if (!isReplyPost || (isCRTEnabled && location === Screens.PERMALINK)) { diff --git a/app/components/post_list/post/body/message/message.tsx b/app/components/post_list/post/body/message/message.tsx index f15cfb2c1a9..d8101ce8d34 100644 --- a/app/components/post_list/post/body/message/message.tsx +++ b/app/components/post_list/post/body/message/message.tsx @@ -1,11 +1,12 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useCallback, useState} from 'react'; +import React, {useCallback, useMemo, useState} from 'react'; import {type LayoutChangeEvent, ScrollView, useWindowDimensions, View} from 'react-native'; import Animated from 'react-native-reanimated'; import Markdown from '@components/markdown'; +import {isChannelMentions} from '@components/markdown/channel_mention/channel_mention'; import {SEARCH} from '@constants/screens'; import {useShowMoreAnimatedStyle} from '@hooks/show_more'; import {getMarkdownTextStyles, getMarkdownBlockStyles} from '@utils/markdown'; @@ -69,6 +70,10 @@ const Message = ({currentUser, isHighlightWithoutNotificationLicensed, highlight const onLayout = useCallback((event: LayoutChangeEvent) => setHeight(event.nativeEvent.layout.height), []); const onPress = () => setOpen(!open); + const channelMentions = useMemo(() => { + return isChannelMentions(post.props?.channel_mentions) ? post.props.channel_mentions : {}; + }, [post.props?.channel_mentions]); + return ( <> @@ -86,7 +91,7 @@ const Message = ({currentUser, isHighlightWithoutNotificationLicensed, highlight baseTextStyle={style.message} blockStyles={blockStyles} channelId={post.channelId} - channelMentions={post.props?.channel_mentions} + channelMentions={channelMentions} imagesMetadata={post.metadata?.images} isEdited={isEdited} isReplyPost={isReplyPost} @@ -100,7 +105,7 @@ const Message = ({currentUser, isHighlightWithoutNotificationLicensed, highlight highlightKeys={isHighlightWithoutNotificationLicensed ? (currentUser?.highlightKeys ?? EMPTY_HIGHLIGHT_KEYS) : EMPTY_HIGHLIGHT_KEYS} searchPatterns={searchPatterns} theme={theme} - isUnsafeLinksPost={post.props.unsafe_links && post.props.unsafe_links !== ''} + isUnsafeLinksPost={Boolean(post.props?.unsafe_links && post.props.unsafe_links !== '')} /> diff --git a/app/components/post_list/post/header/header.tsx b/app/components/post_list/post/header/header.tsx index f79583e8dc9..76649cb34f6 100644 --- a/app/components/post_list/post/header/header.tsx +++ b/app/components/post_list/post/header/header.tsx @@ -12,6 +12,7 @@ import {useTheme} from '@context/theme'; import {DEFAULT_LOCALE} from '@i18n'; import {postUserDisplayName} from '@utils/post'; import {makeStyleSheetFromTheme} from '@utils/theme'; +import {ensureString} from '@utils/types'; import {typography} from '@utils/typography'; import {displayUsername, getUserCustomStatus, getUserTimezone, isCustomStatusExpired} from '@utils/user'; @@ -96,6 +97,8 @@ const Header = (props: HeaderProps) => { isCustomStatusEnabled && displayName && customStatus && !(isSystemPost || author?.isBot || isAutoResponse || isWebHook), ) && !isCustomStatusExpired(author) && Boolean(customStatus?.emoji); + const userIconOverride = ensureString(post.props?.override_icon_url); + const usernameOverride = ensureString(post.props?.override_username); return ( <> @@ -109,9 +112,9 @@ const Header = (props: HeaderProps) => { rootPostAuthor={rootAuthorDisplayName} shouldRenderReplyButton={shouldRenderReplyButton} theme={theme} - userIconOverride={post.props?.override_icon_url} + userIconOverride={userIconOverride} userId={post.userId} - usernameOverride={post.props?.override_username} + usernameOverride={usernameOverride} showCustomStatusEmoji={showCustomStatusEmoji} customStatus={customStatus!} /> diff --git a/app/components/post_list/post/system_message/system_message.tsx b/app/components/post_list/post/system_message/system_message.tsx index f7c88540452..9339b619793 100644 --- a/app/components/post_list/post/system_message/system_message.tsx +++ b/app/components/post_list/post/system_message/system_message.tsx @@ -12,7 +12,7 @@ import {useTheme} from '@context/theme'; import {t} from '@i18n'; import {getMarkdownTextStyles} from '@utils/markdown'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; -import {secureGetFromRecord} from '@utils/types'; +import {secureGetFromRecord, ensureString} from '@utils/types'; import {typography} from '@utils/typography'; import type PostModel from '@typings/database/models/servers/post'; @@ -101,8 +101,8 @@ const renderHeaderChangeMessage = ({post, author, location, styles, intl, theme} } const username = renderUsername(author.username); - const oldHeader = post.props?.old_header; - const newHeader = post.props?.new_header; + const oldHeader = ensureString(post.props?.old_header); + const newHeader = ensureString(post.props?.new_header); let localeHolder; if (post.props?.new_header) { @@ -144,12 +144,12 @@ const renderPurposeChangeMessage = ({post, author, location, styles, intl, theme } const username = renderUsername(author.username); - const oldPurpose = post.props?.old_purpose; - const newPurpose = post.props?.new_purpose; + const oldPurpose = ensureString(post.props?.old_purpose); + const newPurpose = ensureString(post.props?.new_purpose); let localeHolder; - if (post.props?.new_purpose) { - if (post.props?.old_purpose) { + if (newPurpose) { + if (oldPurpose) { localeHolder = { id: t('mobile.system_message.update_channel_purpose_message.updated_from'), defaultMessage: '{username} updated the channel purpose from: {oldPurpose} to: {newPurpose}', @@ -166,7 +166,7 @@ const renderPurposeChangeMessage = ({post, author, location, styles, intl, theme values = {username, oldPurpose, newPurpose}; return renderMessage({post, styles, intl, location, localeHolder, values, skipMarkdown: true, theme}); - } else if (post.props?.old_purpose) { + } else if (oldPurpose) { localeHolder = { id: t('mobile.system_message.update_channel_purpose_message.removed'), defaultMessage: '{username} removed the channel purpose (was: {oldPurpose})', @@ -180,8 +180,8 @@ const renderPurposeChangeMessage = ({post, author, location, styles, intl, theme }; const renderDisplayNameChangeMessage = ({post, author, location, styles, intl, theme}: RenderersProps) => { - const oldDisplayName = post.props?.old_displayname; - const newDisplayName = post.props?.new_displayname; + const oldDisplayName = ensureString(post.props?.old_displayname); + const newDisplayName = ensureString(post.props?.new_displayname); if (!(author?.username)) { return null; @@ -224,13 +224,13 @@ const renderUnarchivedMessage = ({post, author, location, styles, intl, theme}: }; const renderAddGuestToChannelMessage = ({post, location, styles, intl, theme}: RenderersProps, hideGuestTags: boolean) => { - if (!post.props.username || !post.props.addedUsername) { + const username = renderUsername(ensureString(post.props?.username)); + const addedUsername = renderUsername(ensureString(post.props?.addedUsername)); + + if (!username || !addedUsername) { return null; } - const username = renderUsername(post.props.username); - const addedUsername = renderUsername(post.props.addedUsername); - const localeHolder = hideGuestTags ? postTypeMessages[Post.POST_TYPES.ADD_TO_CHANNEL].one : { id: t('api.channel.add_guest.added'), defaultMessage: '{addedUsername} added to the channel as a guest by {username}.', @@ -241,11 +241,11 @@ const renderAddGuestToChannelMessage = ({post, location, styles, intl, theme}: R }; const renderGuestJoinChannelMessage = ({post, styles, location, intl, theme}: RenderersProps, hideGuestTags: boolean) => { - if (!post.props.username) { + const username = renderUsername(ensureString(post.props?.username)); + if (!username) { return null; } - const username = renderUsername(post.props.username); const localeHolder = hideGuestTags ? postTypeMessages[Post.POST_TYPES.JOIN_CHANNEL].one : { id: t('api.channel.guest_join_channel.post_and_forget'), defaultMessage: '{username} joined the channel as a guest.', diff --git a/app/helpers/api/user.ts b/app/helpers/api/user.ts index f0576f5841f..bccc6bf5ec9 100644 --- a/app/helpers/api/user.ts +++ b/app/helpers/api/user.ts @@ -3,6 +3,7 @@ import {General} from '@constants'; import {MENTIONS_REGEX} from '@constants/autocomplete'; +import {isMessageAttachmentArray} from '@utils/message_attachment'; export const getNeededAtMentionedUsernames = (usernames: Set, posts: Post[], excludeUsername?: string) => { const usernamesToLoad = new Set(); @@ -36,8 +37,9 @@ export const getNeededAtMentionedUsernames = (usernames: Set, posts: Pos // These correspond to the fields searched by getMentionsEnabledFields on the server findNeededUsernames(post.message); - if (post.props?.attachments) { - for (const attachment of post.props.attachments) { + const attachments = isMessageAttachmentArray(post.props?.attachments) ? post.props.attachments : undefined; + if (attachments) { + for (const attachment of attachments) { findNeededUsernames(attachment.pretext); findNeededUsernames(attachment.text); } diff --git a/app/products/calls/components/calls_custom_message/index.ts b/app/products/calls/components/calls_custom_message/index.ts index 559a8e98197..a5cd48febd5 100644 --- a/app/products/calls/components/calls_custom_message/index.ts +++ b/app/products/calls/components/calls_custom_message/index.ts @@ -30,7 +30,7 @@ const enhanced = withObservables(['post'], ({serverUrl, post, database}: OwnProp ); // The call is not active, so return early with what we need to render the post. - if (post.props.end_at) { + if (post.props?.end_at) { return { currentUser, isMilitaryTime, diff --git a/app/products/calls/utils.test.ts b/app/products/calls/utils.test.ts index cf59dc1c364..c9465fa4639 100644 --- a/app/products/calls/utils.test.ts +++ b/app/products/calls/utils.test.ts @@ -194,12 +194,12 @@ describe('getCallPropsFromPost', () => { const props = getCallPropsFromPost(post); - expect(props.title).toBe(post.props.title); - expect(props.start_at).toBe(post.props.start_at); - expect(props.end_at).toBe(post.props.end_at); - expect(props.recordings).toBe(post.props.recordings); - expect(props.recording_files).toBe(post.props.recording_files); - expect(props.transcriptions).toBe(post.props.transcriptions); - expect(props.participants).toBe(post.props.participants); + expect(props.title).toBe(post.props?.title); + expect(props.start_at).toBe(post.props?.start_at); + expect(props.end_at).toBe(post.props?.end_at); + expect(props.recordings).toBe(post.props?.recordings); + expect(props.recording_files).toBe(post.props?.recording_files); + expect(props.transcriptions).toBe(post.props?.transcriptions); + expect(props.participants).toBe(post.props?.participants); }); }); diff --git a/app/products/calls/utils.ts b/app/products/calls/utils.ts index 13969feb07b..2b1917d1325 100644 --- a/app/products/calls/utils.ts +++ b/app/products/calls/utils.ts @@ -2,6 +2,7 @@ // See LICENSE.txt for license information. import {makeCallsBaseAndBadgeRGB, rgbToCSS} from '@mattermost/calls'; +import {type CallsConfig, type CallPostProps, isCaption, type Caption, isCallJobMetadata, type CallJobMetadata} from '@mattermost/calls/lib/types'; import {Alert} from 'react-native'; import {SelectedTrackType, TextTrackType, type ISO639_1, type SelectedTrack, type TextTracks} from 'react-native-video'; @@ -9,6 +10,7 @@ import {buildFileUrl} from '@actions/remote/file'; import {Calls, Post} from '@constants'; import {NOTIFICATION_SUB_TYPE} from '@constants/push_notification'; import {isMinimumServerVersion} from '@utils/helpers'; +import {ensureNumber, ensureString, isArrayOf, isRecordOf, isStringArray} from '@utils/types'; import {displayUsername} from '@utils/user'; import type { @@ -17,7 +19,6 @@ import type { CallsTheme, CallsVersion, } from '@calls/types/calls'; -import type {CallsConfig, Caption, CallPostProps} from '@mattermost/calls/lib/types'; import type PostModel from '@typings/database/models/servers/post'; import type UserModel from '@typings/database/models/servers/user'; import type {IntlShape} from 'react-intl'; @@ -217,17 +218,17 @@ export function isCallsStartedMessage(payload?: NotificationData) { return (payload?.message === 'You\'ve been invited to a call' || callsMessageRegex.test(payload?.message || '')); } -export const hasCaptions = (postProps?: Record & { captions?: Caption[] }): boolean => { - return !(!postProps || !postProps.captions?.[0]); +export const hasCaptions = (postProps?: Record): boolean => { + return Boolean(isArrayOf(postProps?.captions, isCaption) && postProps.captions[0]); }; -export const getTranscriptionUri = (serverUrl: string, postProps?: Record & { captions?: Caption[] }): { +export const getTranscriptionUri = (serverUrl: string, postProps?: Record): { tracks?: TextTracks; selected: SelectedTrack; } => { // Note: We're not using hasCaptions above because this tells typescript that the caption exists later. // We could use some fancy typescript to do the same, but it's not worth the complexity. - if (!postProps || !postProps.captions?.[0]) { + if (!isArrayOf(postProps?.captions, isCaption) || !postProps.captions[0]) { return { tracks: undefined, selected: {type: SelectedTrackType.DISABLED, value: ''}, @@ -247,20 +248,16 @@ export const getTranscriptionUri = (serverUrl: string, postProps?: Record(post.props?.recordings, isCallJobMetadata) ? post.props.recordings : {}, + transcriptions: isRecordOf(post.props?.transcriptions, isCallJobMetadata) ? post.props.transcriptions : {}, + participants: isStringArray(post.props?.participants) ? post.props.participants : [], // DEPRECATED - recording_files: Array.isArray(post.props?.recording_files) ? post.props.recording_files : [], + recording_files: isStringArray(post.props?.recording_files) ? post.props.recording_files : [], }; } diff --git a/app/screens/gallery/footer/footer.tsx b/app/screens/gallery/footer/footer.tsx index 9969468a8c7..a12b0e0c18f 100644 --- a/app/screens/gallery/footer/footer.tsx +++ b/app/screens/gallery/footer/footer.tsx @@ -9,6 +9,7 @@ import {SafeAreaView, type Edge, useSafeAreaInsets} from 'react-native-safe-area import {Events} from '@constants'; import {GALLERY_FOOTER_HEIGHT} from '@constants/gallery'; import {changeOpacity} from '@utils/theme'; +import {ensureString} from '@utils/types'; import {displayUsername} from '@utils/user'; import Actions from './actions'; @@ -71,14 +72,14 @@ const Footer = ({ let overrideIconUrl; if (enablePostIconOverride && post?.props?.use_user_icon !== 'true' && post?.props?.override_icon_url) { - overrideIconUrl = post.props.override_icon_url; + overrideIconUrl = ensureString(post.props.override_icon_url); } let userDisplayName; if (item.type === 'avatar') { userDisplayName = item.name; } else if (enablePostUsernameOverride && post?.props?.override_username) { - userDisplayName = post.props.override_username as string; + userDisplayName = ensureString(post.props.override_username); } else { userDisplayName = displayUsername(author, undefined, teammateNameDisplay); } diff --git a/app/utils/apps.ts b/app/utils/apps.ts index bd21068c690..0f2fb2426db 100644 --- a/app/utils/apps.ts +++ b/app/utils/apps.ts @@ -4,6 +4,7 @@ import {AppBindingLocations, AppCallResponseTypes, AppFieldTypes} from '@constants/apps'; import {generateId} from './general'; +import {isArrayOf, isStringArray} from './types'; export function cleanBinding(binding: AppBinding, topLocation: string): AppBinding|null { return cleanBindingRec(binding, topLocation, 0); @@ -253,3 +254,297 @@ export const makeCallErrorResponse = (errMessage: string): AppCallResponse }; export const filterEmptyOptions = (option: AppSelectOption): boolean => Boolean(option.value && !option.value.match(/^[ \t]+$/)); + +function isAppExpand(v: unknown): v is AppExpand { + if (typeof v !== 'object' || v === null) { + return false; + } + + const expand = v as AppExpand; + + if (expand.app !== undefined && typeof expand.app !== 'string') { + return false; + } + + if (expand.acting_user !== undefined && typeof expand.acting_user !== 'string') { + return false; + } + + if (expand.channel !== undefined && typeof expand.channel !== 'string') { + return false; + } + + if (expand.config !== undefined && typeof expand.config !== 'string') { + return false; + } + + if (expand.mentioned !== undefined && typeof expand.mentioned !== 'string') { + return false; + } + + if (expand.parent_post !== undefined && typeof expand.parent_post !== 'string') { + return false; + } + + if (expand.post !== undefined && typeof expand.post !== 'string') { + return false; + } + + if (expand.root_post !== undefined && typeof expand.root_post !== 'string') { + return false; + } + + if (expand.team !== undefined && typeof expand.team !== 'string') { + return false; + } + + if (expand.user !== undefined && typeof expand.user !== 'string') { + return false; + } + + return true; +} + +function isAppCall(obj: unknown): obj is AppCall { + if (typeof obj !== 'object' || obj === null) { + return false; + } + + const call = obj as AppCall; + + if (typeof call.path !== 'string') { + return false; + } + + if (call.expand !== undefined && !isAppExpand(call.expand)) { + return false; + } + + // Here we're assuming that 'state' can be of any type, so no type check for 'state' + + return true; +} + +function isAppFormValue(v: unknown): v is AppFormValue { + if (typeof v === 'string') { + return true; + } + + if (typeof v === 'boolean') { + return true; + } + + if (v === null) { + return true; + } + + return isAppSelectOption(v); +} + +function isAppSelectOption(v: unknown): v is AppSelectOption { + if (typeof v !== 'object' || v === null) { + return false; + } + + const option = v as AppSelectOption; + + if (typeof option.label !== 'string' || typeof option.value !== 'string') { + return false; + } + + if (option.icon_data !== undefined && typeof option.icon_data !== 'string') { + return false; + } + + return true; +} + +function isAppField(v: unknown): v is AppField { + if (typeof v !== 'object' || v === null) { + return false; + } + + const field = v as AppField; + + if (typeof field.name !== 'string' || typeof field.type !== 'string') { + return false; + } + + if (field.is_required !== undefined && typeof field.is_required !== 'boolean') { + return false; + } + + if (field.readonly !== undefined && typeof field.readonly !== 'boolean') { + return false; + } + + if (field.value !== undefined && !isAppFormValue(field.value)) { + return false; + } + + if (field.description !== undefined && typeof field.description !== 'string') { + return false; + } + + if (field.label !== undefined && typeof field.label !== 'string') { + return false; + } + + if (field.hint !== undefined && typeof field.hint !== 'string') { + return false; + } + + if (field.position !== undefined && typeof field.position !== 'number') { + return false; + } + + if (field.modal_label !== undefined && typeof field.modal_label !== 'string') { + return false; + } + + if (field.refresh !== undefined && typeof field.refresh !== 'boolean') { + return false; + } + + if (field.options !== undefined && !isArrayOf(field.options, isAppSelectOption)) { + return false; + } + + if (field.multiselect !== undefined && typeof field.multiselect !== 'boolean') { + return false; + } + + if (field.lookup !== undefined && !isAppCall(field.lookup)) { + return false; + } + + if (field.subtype !== undefined && typeof field.subtype !== 'string') { + return false; + } + + if (field.min_length !== undefined && typeof field.min_length !== 'number') { + return false; + } + + if (field.max_length !== undefined && typeof field.max_length !== 'number') { + return false; + } + + return true; +} + +function isAppForm(v: unknown): v is AppForm { + if (typeof v !== 'object' || v === null) { + return false; + } + + const form = v as AppForm; + + if (form.title !== undefined && typeof form.title !== 'string') { + return false; + } + + if (form.header !== undefined && typeof form.header !== 'string') { + return false; + } + + if (form.footer !== undefined && typeof form.footer !== 'string') { + return false; + } + + if (form.icon !== undefined && typeof form.icon !== 'string') { + return false; + } + + if (form.submit_buttons !== undefined && typeof form.submit_buttons !== 'string') { + return false; + } + + if (form.cancel_button !== undefined && typeof form.cancel_button !== 'boolean') { + return false; + } + + if (form.submit_on_cancel !== undefined && typeof form.submit_on_cancel !== 'boolean') { + return false; + } + + if (form.fields !== undefined && !isArrayOf(form.fields, isAppField)) { + return false; + } + + if (form.source !== undefined && !isAppCall(form.source)) { + return false; + } + + if (form.submit !== undefined && !isAppCall(form.submit)) { + return false; + } + + if (form.depends_on !== undefined && !isStringArray(form.depends_on)) { + return false; + } + + return true; +} + +export function isAppBinding(obj: unknown): obj is AppBinding { + if (typeof obj !== 'object' || obj === null) { + return false; + } + + const binding = obj as AppBinding; + + if (typeof binding.app_id !== 'string' || typeof binding.label !== 'string') { + return false; + } + + if (binding.location !== undefined && typeof binding.location !== 'string') { + return false; + } + + if (binding.icon !== undefined && typeof binding.icon !== 'string') { + return false; + } + + if (binding.hint !== undefined && typeof binding.hint !== 'string') { + return false; + } + + if (binding.description !== undefined && typeof binding.description !== 'string') { + return false; + } + + if (binding.role_id !== undefined && typeof binding.role_id !== 'string') { + return false; + } + + if (binding.depends_on_team !== undefined && typeof binding.depends_on_team !== 'boolean') { + return false; + } + + if (binding.depends_on_channel !== undefined && typeof binding.depends_on_channel !== 'boolean') { + return false; + } + + if (binding.depends_on_user !== undefined && typeof binding.depends_on_user !== 'boolean') { + return false; + } + + if (binding.depends_on_post !== undefined && typeof binding.depends_on_post !== 'boolean') { + return false; + } + + if (binding.bindings !== undefined && !isArrayOf(binding.bindings, isAppBinding)) { + return false; + } + + if (binding.form !== undefined && !isAppForm(binding.form)) { + return false; + } + + if (binding.submit !== undefined && !isAppCall(binding.submit)) { + return false; + } + + return true; +} diff --git a/app/utils/gallery/index.ts b/app/utils/gallery/index.ts index 80148f71e9c..ba177001ceb 100644 --- a/app/utils/gallery/index.ts +++ b/app/utils/gallery/index.ts @@ -29,7 +29,7 @@ export const clampVelocity = (velocity: number, minVelocity: number, maxVelocity return Math.max(Math.min(velocity, -minVelocity), -maxVelocity); }; -export const fileToGalleryItem = (file: FileInfo, authorId?: string, postProps?: Record, lastPictureUpdate = 0): GalleryItemType => { +export const fileToGalleryItem = (file: FileInfo, authorId?: string, postProps?: Record, lastPictureUpdate = 0): GalleryItemType => { let type: GalleryItemType['type'] = 'file'; if (isVideo(file)) { type = 'video'; diff --git a/app/utils/message_attachment.ts b/app/utils/message_attachment.ts new file mode 100644 index 00000000000..10ec5ff50c4 --- /dev/null +++ b/app/utils/message_attachment.ts @@ -0,0 +1,195 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {isArrayOf} from './types'; + +export function getStatusColors(theme: Theme): Dictionary { + return { + good: '#00c100', + warning: '#dede01', + danger: theme.errorTextColor, + default: theme.centerChannelColor, + primary: theme.buttonBg, + success: theme.onlineIndicator, + }; +} + +export function isMessageAttachmentArray(v: unknown): v is MessageAttachment[] { + return isArrayOf(v, isMessageAttachment); +} + +function isPostActionOption(v: unknown): v is PostActionOption { + if (typeof v !== 'object' || !v) { + return false; + } + + if ('text' in v && typeof v.text !== 'string') { + return false; + } + + if ('value' in v && typeof v.value !== 'string') { + return false; + } + + return true; +} + +function isPostAction(v: unknown): v is PostAction { + if (typeof v !== 'object' || !v) { + return false; + } + + if (!('id' in v)) { + return false; + } + + if (typeof v.id !== 'string') { + return false; + } + + if (!('name' in v)) { + return false; + } + + if (typeof v.name !== 'string') { + return false; + } + + if ('type' in v && typeof v.type !== 'string') { + return false; + } + + if ('disabled' in v && typeof v.disabled !== 'boolean') { + return false; + } + + if ('style' in v && typeof v.style !== 'string') { + return false; + } + + if ('data_source' in v && typeof v.data_source !== 'string') { + return false; + } + + if ('options' in v && !isArrayOf(v.options, isPostActionOption)) { + return false; + } + + if ('default_option' in v && typeof v.default_option !== 'string') { + return false; + } + + if ('cookie' in v && typeof v.cookie !== 'string') { + return false; + } + + return true; +} + +function isMessageAttachmentField(v: unknown) { + if (typeof v !== 'object') { + return false; + } + + if (!v) { + return false; + } + + if (!('title' in v)) { + return false; + } + + if (typeof v.title !== 'string') { + return false; + } + + if (!('value' in v)) { + return false; + } + + if (typeof v.value === 'object' && v.value && 'toString' in v.value && typeof v.value.toString !== 'function') { + return false; + } + + if ('short' in v && typeof v.short !== 'boolean') { + return false; + } + + return true; +} + +function isMessageAttachment(v: unknown): v is MessageAttachment { + if (typeof v !== 'object' || !v) { + return false; + } + + if ('fallback' in v && typeof v.fallback !== 'string') { + return false; + } + + // We may consider adding more validation to what color may be + if ('color' in v && typeof v.color !== 'string') { + return false; + } + + if ('pretext' in v && typeof v.pretext !== 'string') { + return false; + } + + if ('author_name' in v && typeof v.author_name !== 'string') { + return false; + } + + // Where it is used, we are calling isUrlSafe. We could consider calling it here + if ('author_link' in v && typeof v.author_link !== 'string') { + return false; + } + + // We may need more validation since this is going to be passed to an img src prop + if ('author_icon' in v && typeof v.author_icon !== 'string') { + return false; + } + + if ('title' in v && typeof v.title !== 'string') { + return false; + } + + // Where it is used, we are calling isUrlSafe. We could consider calling it here + if ('title_link' in v && typeof v.title_link !== 'string') { + return false; + } + + if ('text' in v && typeof v.text !== 'string') { + return false; + } + + // We may need more validation since this is going to be passed to an img src prop + if ('image_url' in v && typeof v.image_url !== 'string') { + return false; + } + + // We may need more validation since this is going to be passed to an img src prop + if ('thumb_url' in v && typeof v.thumb_url !== 'string') { + return false; + } + + // We are truncating if the size is more than some constant. We could check this here + if ('footer' in v && typeof v.footer !== 'string') { + return false; + } + + // We may need more validation since this is going to be passed to an img src prop + if ('footer_icon' in v && typeof v.footer_icon !== 'string') { + return false; + } + + if ('fields' in v && v.fields !== null && !isArrayOf(v.fields, isMessageAttachmentField)) { + return false; + } + + if ('actions' in v && !isArrayOf(v.actions, isPostAction)) { + return false; + } + + return true; +} diff --git a/app/utils/message_attachment_colors.test.ts b/app/utils/message_attachment_colors.test.ts index 3ee07e98404..bea0b023342 100644 --- a/app/utils/message_attachment_colors.test.ts +++ b/app/utils/message_attachment_colors.test.ts @@ -3,7 +3,7 @@ import {Preferences} from '@constants'; -import {getStatusColors} from './message_attachment_colors'; +import {getStatusColors} from './message_attachment'; describe('getStatusColors', () => { const mockTheme = Preferences.THEMES.denim; diff --git a/app/utils/message_attachment_colors.ts b/app/utils/message_attachment_colors.ts deleted file mode 100644 index 210e02d0893..00000000000 --- a/app/utils/message_attachment_colors.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -export function getStatusColors(theme: Theme): Dictionary { - return { - good: '#00c100', - warning: '#dede01', - danger: theme.errorTextColor, - default: theme.centerChannelColor, - primary: theme.buttonBg, - success: theme.onlineIndicator, - }; -} diff --git a/app/utils/post/index.test.ts b/app/utils/post/index.test.ts index 463577f2bd4..b6620ea2b8f 100644 --- a/app/utils/post/index.test.ts +++ b/app/utils/post/index.test.ts @@ -85,7 +85,7 @@ describe('post utils', () => { const post = { props: { from_webhook: 'true', - }, + } as Record, } as PostModel; const result = isFromWebhook(post); @@ -96,7 +96,7 @@ describe('post utils', () => { const post = { props: { from_webhook: 'false', - }, + } as Record, } as PostModel; const result = isFromWebhook(post); @@ -149,7 +149,7 @@ describe('post utils', () => { const post = { props: { failed: true, - }, + } as Record, pendingPostId: 'id', id: 'id', updateAt: Date.now() - Post.POST_TIME_TO_FAIL - 1000, @@ -471,7 +471,7 @@ describe('post utils', () => { props: { from_webhook: 'true', override_username: 'webhook_user', - }, + } as Record, } as PostModel; const result = postUserDisplayName(post, undefined, undefined, true); @@ -482,7 +482,7 @@ describe('post utils', () => { const post = { props: { from_webhook: 'false', - }, + } as Record, } as PostModel; const author = { username: 'user1', @@ -497,7 +497,7 @@ describe('post utils', () => { const post = { props: { from_webhook: 'false', - }, + } as Record, } as PostModel; const author = { username: 'user1', diff --git a/app/utils/post/index.ts b/app/utils/post/index.ts index 7cceeed5f08..dd29cdd5c6e 100644 --- a/app/utils/post/index.ts +++ b/app/utils/post/index.ts @@ -11,6 +11,7 @@ import DatabaseManager from '@database/manager'; import {DEFAULT_LOCALE} from '@i18n'; import {getUserById} from '@queries/servers/user'; import {toMilliseconds} from '@utils/datetime'; +import {ensureString} from '@utils/types'; import {displayUsername, getUserIdFromChannelName} from '@utils/user'; import type PostModel from '@typings/database/models/servers/post'; @@ -36,7 +37,7 @@ export function areConsecutivePosts(post: PostModel, previousPost: PostModel) { } export function isFromWebhook(post: PostModel | Post): boolean { - return post.props && post.props.from_webhook === 'true'; + return post.props?.from_webhook === 'true'; } export function isEdited(post: PostModel): boolean { @@ -48,7 +49,7 @@ export function isPostEphemeral(post: PostModel): boolean { } export function isPostFailed(post: PostModel): boolean { - return post.props?.failed || ((post.pendingPostId === post.id) && (Date.now() > post.updateAt + POST_TIME_TO_FAIL)); + return Boolean(post.props?.failed) || ((post.pendingPostId === post.id) && (Date.now() > post.updateAt + POST_TIME_TO_FAIL)); } export function isPostPendingOrFailed(post: PostModel): boolean { @@ -64,8 +65,13 @@ export function fromAutoResponder(post: PostModel): boolean { } export function postUserDisplayName(post: PostModel, author?: UserModel, teammateNameDisplay?: string, enablePostUsernameOverride = false) { - if (isFromWebhook(post) && post.props?.override_username && enablePostUsernameOverride) { - return post.props.override_username; + const overrideUsername = ensureString(post.props?.override_username); + if ( + isFromWebhook(post) && + enablePostUsernameOverride && + overrideUsername + ) { + return overrideUsername; } return displayUsername(author, author?.locale || DEFAULT_LOCALE, teammateNameDisplay, true); diff --git a/app/utils/post_list/index.test.ts b/app/utils/post_list/index.test.ts index 29432aafb81..64cff6488a1 100644 --- a/app/utils/post_list/index.test.ts +++ b/app/utils/post_list/index.test.ts @@ -319,7 +319,7 @@ describe('generateCombinedPost', () => { const result = generateCombinedPost('combined-post-id', systemPosts); // Ensure all post ids are included in the system_post_ids prop - expect(result.props.system_post_ids).toEqual(['post1', 'post2', 'post3']); + expect(result.props?.system_post_ids).toEqual(['post1', 'post2', 'post3']); }); it('should include combined messages in the props object', () => { @@ -331,7 +331,7 @@ describe('generateCombinedPost', () => { const result = generateCombinedPost('combined-post-id', systemPosts); // Ensure the messages prop includes all individual messages - expect(result.props.messages).toEqual(['Message 1', 'Message 2']); + expect(result.props?.messages).toEqual(['Message 1', 'Message 2']); }); it('should set the post type to COMBINED_USER_ACTIVITY', () => { @@ -387,7 +387,7 @@ describe('generateCombinedPost', () => { const result = generateCombinedPost(combinedPostId, systemPosts); // Extract the post types from the sorted messages in the combined post props - const sortedPostTypes = result.props.user_activity_posts.map((post: PostModel) => post.type); + const sortedPostTypes = (result.props?.user_activity_posts as any).map((post: PostModel) => post.type); // Expect the post types to be sorted based on their priorities in comparePostTypes expect(sortedPostTypes).toEqual([ @@ -422,9 +422,9 @@ describe('generateCombinedPost', () => { const result = generateCombinedPost(combinedPostId, systemPosts); // Ensure user activities are combined for ADD_TO_TEAM - expect(result.props.user_activity_posts.length).toBe(2); - expect(result.props.user_activity_posts[0].props.addedUserId).toBe('user1'); - expect(result.props.user_activity_posts[1].props.addedUserId).toBe('user2'); + expect((result.props?.user_activity_posts as any).length).toBe(2); + expect((result.props?.user_activity_posts as any)[0].props.addedUserId).toBe('user1'); + expect((result.props?.user_activity_posts as any)[1].props.addedUserId).toBe('user2'); }); it('should combine user activity for REMOVE_FROM_CHANNEL posts correctly', () => { @@ -451,9 +451,9 @@ describe('generateCombinedPost', () => { const result = generateCombinedPost(combinedPostId, systemPosts); // Ensure user activities are combined for REMOVE_FROM_CHANNEL - expect(result.props.user_activity_posts.length).toBe(2); - expect(result.props.user_activity_posts[0].props.removedUserId).toBe('user3'); - expect(result.props.user_activity_posts[1].props.removedUserId).toBe('user4'); + expect((result.props?.user_activity_posts as any).length).toBe(2); + expect((result.props?.user_activity_posts as any)[0].props.removedUserId).toBe('user3'); + expect((result.props?.user_activity_posts as any)[1].props.removedUserId).toBe('user4'); }); it('should handle empty systemPosts gracefully', () => { diff --git a/app/utils/post_list/index.ts b/app/utils/post_list/index.ts index b5f7496659b..76f6e2a212f 100644 --- a/app/utils/post_list/index.ts +++ b/app/utils/post_list/index.ts @@ -6,6 +6,7 @@ import moment from 'moment-timezone'; import {Post} from '@constants'; import {toMilliseconds} from '@utils/datetime'; import {isFromWebhook} from '@utils/post'; +import {ensureString, isArrayOf, isStringArray} from '@utils/types'; import type {PostList, PostWithPrevAndNext} from '@typings/components/post_list'; import type PostModel from '@typings/database/models/servers/post'; @@ -154,9 +155,11 @@ function isJoinLeavePostForUsername(post: PostModel, currentUsername: string): b return false; } - if (post.props.user_activity_posts) { + // We can be more lax with the types here because the recursive function only checks + // whether it is an array, or comparison with strings, so it should be safe enough. + if (Array.isArray(post.props.user_activity_posts)) { for (const childPost of post.props.user_activity_posts as PostModel[]) { - if (isJoinLeavePostForUsername(childPost, currentUsername)) { + if (childPost && isJoinLeavePostForUsername(childPost, currentUsername)) { // If any of the contained posts are for this user, the client will // need to figure out how to render the post return true; @@ -264,8 +267,8 @@ function combineUserActivitySystemPost(systemPosts: PostModel[]) { postType === Post.POST_TYPES.ADD_TO_CHANNEL || postType === Post.POST_TYPES.REMOVE_FROM_CHANNEL ) { - const userId = post.props.addedUserId || post.props.removedUserId; - const username = post.props.addedUsername || post.props.removedUsername; + const userId = ensureString(post.props?.addedUserId) || ensureString(post.props?.removedUserId); + const username = ensureString(post.props?.addedUsername) || ensureString(post.props?.removedUsername); if (combinedPostType) { if (Array.isArray(combinedPostType[post.userId])) { throw new Error('Invalid Post activity data'); @@ -384,3 +387,55 @@ export function shouldFilterJoinLeavePost(post: PostModel, showJoinLeave: boolea // Don't filter out join/leave messages about the current user return !isJoinLeavePostForUsername(post, currentUsername); } + +export type MessageData = { + actorId: string; + postType: string; + userIds: string[]; +} + +function isMessageData(v: unknown): v is MessageData { + if (typeof v !== 'object' || !v) { + return false; + } + + if (!('actorId' in v) || typeof v.actorId !== 'string') { + return false; + } + + if (!('postType' in v) || typeof v.postType !== 'string') { + return false; + } + + if (!('userIds' in v) || !isStringArray(v.userIds)) { + return false; + } + + return true; +} + +export type UserActivityProp = { + allUserIds: string[]; + allUsernames: string[]; + messageData: MessageData[]; +} + +export function isUserActivityProp(v: unknown): v is UserActivityProp { + if (typeof v !== 'object' || !v) { + return false; + } + + if (!('allUserIds' in v) || !isStringArray(v.allUserIds)) { + return false; + } + + if (!('allUsernames' in v) || !isStringArray(v.allUsernames)) { + return false; + } + + if (!('messageData' in v) || !isArrayOf(v.messageData, isMessageData)) { + return false; + } + + return true; +} diff --git a/app/utils/types.ts b/app/utils/types.ts index 40c8ff17faa..a78a3b8bfc8 100644 --- a/app/utils/types.ts +++ b/app/utils/types.ts @@ -1,6 +1,42 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +export function isArrayOf(v: unknown, check: (e: unknown) => boolean): v is T[] { + if (!Array.isArray(v)) { + return false; + } + + return v.every(check); +} + +export function isStringArray(v: unknown): v is string[] { + return isArrayOf(v, (e) => typeof e === 'string'); +} + +export function isRecordOf(v: unknown, check: (e: unknown) => boolean): v is Record { + if (typeof v !== 'object' || !v) { + return false; + } + + if (!(Object.keys(v).every((k) => typeof k === 'string'))) { + return false; + } + + if (!(Object.values(v).every(check))) { + return false; + } + + return true; +} + +export function ensureString(v: unknown): string { + return typeof v === 'string' ? v : ''; +} + +export function ensureNumber(v: unknown): number { + return typeof v === 'number' ? v : 0; +} + export function secureGetFromRecord(v: Record | undefined, key: string) { return typeof v === 'object' && v && Object.prototype.hasOwnProperty.call(v, key) ? v[key] : undefined; } diff --git a/package-lock.json b/package-lock.json index d7a5d4ccd6c..616f26d4736 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@formatjs/intl-numberformat": "8.10.3", "@formatjs/intl-pluralrules": "5.2.14", "@gorhom/bottom-sheet": "4.6.4", - "@mattermost/calls": "github:mattermost/calls-common#07607cf603f1e3f0c86ae248b2332e8da17f9cf8", + "@mattermost/calls": "github:mattermost/calls-common#030ff7c0a37ee9b0ccc5fae0b2ea9c0e1c08473f", "@mattermost/compass-icons": "0.1.45", "@mattermost/hardware-keyboard": "file:./libraries/@mattermost/hardware-keyboard", "@mattermost/keyboard-tracker": "file:./libraries/@mattermost/keyboard-tracker", @@ -5837,11 +5837,11 @@ "node_modules/@mattermost/calls": { "name": "@mattermost/calls-common", "version": "0.27.2", - "resolved": "git+ssh://git@github.com/mattermost/calls-common.git#07607cf603f1e3f0c86ae248b2332e8da17f9cf8", - "integrity": "sha512-aZIYwtgRVj8tdWJUPtAr4TPNa6tNM3lnRkC74CkSsFCpwZ1miwov0B4TLYG4Srj1rTgUqUwG3gQz4o5JHJ2fuQ==", + "resolved": "git+ssh://git@github.com/mattermost/calls-common.git#030ff7c0a37ee9b0ccc5fae0b2ea9c0e1c08473f", + "integrity": "sha512-qtMUUGHrl6VOGgjyQ+Ft4YddWo5RV8MDK8zSaYRU/1MiiY/zqq5kW6nvuzMB2S0xAvPwYlcFEBfmM4QZrReD6w==", "dependencies": { - "@msgpack/msgpack": "^3.0.0-beta2", - "fflate": "^0.8.2" + "@msgpack/msgpack": "3.0.0-beta2", + "fflate": "0.8.2" } }, "node_modules/@mattermost/calls/node_modules/@msgpack/msgpack": { diff --git a/package.json b/package.json index bf9a592feae..4ecea74abe6 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@formatjs/intl-numberformat": "8.10.3", "@formatjs/intl-pluralrules": "5.2.14", "@gorhom/bottom-sheet": "4.6.4", - "@mattermost/calls": "github:mattermost/calls-common#07607cf603f1e3f0c86ae248b2332e8da17f9cf8", + "@mattermost/calls": "github:mattermost/calls-common#030ff7c0a37ee9b0ccc5fae0b2ea9c0e1c08473f", "@mattermost/compass-icons": "0.1.45", "@mattermost/hardware-keyboard": "file:./libraries/@mattermost/hardware-keyboard", "@mattermost/keyboard-tracker": "file:./libraries/@mattermost/keyboard-tracker", diff --git a/types/api/files.d.ts b/types/api/files.d.ts index 3e5f4d48bc6..0d0affb6fad 100644 --- a/types/api/files.d.ts +++ b/types/api/files.d.ts @@ -22,7 +22,7 @@ type FileInfo = { uri?: string; user_id: string; width: number; - postProps?: Record; + postProps?: Record; }; type FilesState = { diff --git a/types/api/posts.d.ts b/types/api/posts.d.ts index a9b3a3c6031..01d350e0648 100644 --- a/types/api/posts.d.ts +++ b/types/api/posts.d.ts @@ -71,7 +71,7 @@ type Post = { message_source?: string; type: PostType; participants?: null | UserProfile[]|string[]; - props: Record; + props: Record | undefined; hashtags: string; pending_post_id: string; reply_count: number; diff --git a/types/database/models/servers/post.ts b/types/database/models/servers/post.ts index e81b543bd04..e3a9be36a88 100644 --- a/types/database/models/servers/post.ts +++ b/types/database/models/servers/post.ts @@ -71,7 +71,7 @@ declare class PostModel extends Model { userId: string; /** props : Additional attributes for this props */ - props: any; + props: Record | null; /** drafts : Every draft associated with this Post */ drafts: Query; diff --git a/types/screens/gallery.ts b/types/screens/gallery.ts index 44cec0860d9..950586b0590 100644 --- a/types/screens/gallery.ts +++ b/types/screens/gallery.ts @@ -76,7 +76,7 @@ export type GalleryItemType = { authorId?: string; size?: number; postId?: string; - postProps?: Record & {captions?: Caption[]}; + postProps?: Record & {captions?: Caption[]}; }; export type GalleryAction = 'none' | 'downloading' | 'copying' | 'sharing' | 'opening' | 'external'; From d25c6fe245c9d8bd7e1c1005784a574d5a68a322 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Fri, 29 Nov 2024 11:58:13 +0800 Subject: [PATCH 22/36] Extra keyboard (#8348) * Add support to use the keyboard area with a component * fix import * add missing providers to involved screens * Change the way we handle the keyboard to allow using custom components in that area * review feedback --- app/components/post_draft/post_draft.tsx | 47 +- .../post_draft/post_input/post_input.tsx | 8 +- app/components/post_list/post/post.tsx | 25 +- app/constants/post_draft.ts | 3 - app/context/extra_keyboard/index.tsx | 183 ++++++ app/hooks/device.ts | 45 +- app/hooks/keyboard_tracking.ts | 52 -- app/screens/channel/channel.tsx | 33 +- .../channel_post_list/channel_post_list.tsx | 2 +- app/screens/home/index.tsx | 8 +- .../home/recent_mentions/recent_mentions.tsx | 5 +- .../home/saved_messages/saved_messages.tsx | 5 +- .../home/search/results/post_results.tsx | 57 +- app/screens/permalink/permalink.tsx | 5 +- .../pinned_messages/pinned_messages.tsx | 25 +- app/screens/thread/thread.tsx | 32 +- .../thread_post_list/thread_post_list.tsx | 21 +- app/store/navigation_store.ts | 13 + ios/Podfile.lock | 25 - .../Extensions/UIResponder+FirstResponder.h | 6 - .../Extensions/UIResponder+FirstResponder.m | 17 - .../ios/MattermostKeyboardTrackerView.h | 17 - .../ios/MattermostKeyboardTrackerView.mm | 169 ----- .../MattermostKeyboardTrackerViewManager.mm | 127 ---- .../ios/Views/KeyboardTrackingView.h | 50 -- .../ios/Views/KeyboardTrackingView.m | 622 ------------------ .../ios/Views/ObservingInputAccessoryView.h | 36 - .../ios/Views/ObservingInputAccessoryView.m | 172 ----- .../mattermost-keyboard-tracker.podspec | 23 - .../@mattermost/keyboard-tracker/package.json | 16 - ...rmostKeyboardTrackerViewNativeComponent.ts | 70 -- .../keyboard-tracker/src/index.tsx | 64 -- .../mattermost/rnutils/RNUtilsModuleImpl.kt | 20 + .../android/src/newarch/RNUtilsModule.kt | 8 + .../android/src/oldarch/RNUtilsModule.kt | 10 + libraries/@mattermost/rnutils/ios/RNUtils.mm | 16 + .../@mattermost/rnutils/src/NativeRNUtils.ts | 3 + package-lock.json | 8 +- package.json | 1 - patches/react-native-navigation+7.40.1.patch | 31 + test/intl-test-helper.tsx | 5 +- 41 files changed, 427 insertions(+), 1658 deletions(-) create mode 100644 app/context/extra_keyboard/index.tsx delete mode 100644 app/hooks/keyboard_tracking.ts delete mode 100644 libraries/@mattermost/keyboard-tracker/ios/Extensions/UIResponder+FirstResponder.h delete mode 100644 libraries/@mattermost/keyboard-tracker/ios/Extensions/UIResponder+FirstResponder.m delete mode 100644 libraries/@mattermost/keyboard-tracker/ios/MattermostKeyboardTrackerView.h delete mode 100644 libraries/@mattermost/keyboard-tracker/ios/MattermostKeyboardTrackerView.mm delete mode 100644 libraries/@mattermost/keyboard-tracker/ios/ViewManagers/MattermostKeyboardTrackerViewManager.mm delete mode 100644 libraries/@mattermost/keyboard-tracker/ios/Views/KeyboardTrackingView.h delete mode 100644 libraries/@mattermost/keyboard-tracker/ios/Views/KeyboardTrackingView.m delete mode 100644 libraries/@mattermost/keyboard-tracker/ios/Views/ObservingInputAccessoryView.h delete mode 100644 libraries/@mattermost/keyboard-tracker/ios/Views/ObservingInputAccessoryView.m delete mode 100644 libraries/@mattermost/keyboard-tracker/mattermost-keyboard-tracker.podspec delete mode 100644 libraries/@mattermost/keyboard-tracker/package.json delete mode 100644 libraries/@mattermost/keyboard-tracker/src/MattermostKeyboardTrackerViewNativeComponent.ts delete mode 100644 libraries/@mattermost/keyboard-tracker/src/index.tsx diff --git a/app/components/post_draft/post_draft.tsx b/app/components/post_draft/post_draft.tsx index f86e060a10b..704c14d057e 100644 --- a/app/components/post_draft/post_draft.tsx +++ b/app/components/post_draft/post_draft.tsx @@ -1,16 +1,13 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import KeyboardTrackingView, {type KeyboardTrackingViewRef} from '@mattermost/keyboard-tracker'; -import React, {type RefObject, useEffect, useState} from 'react'; -import {Platform} from 'react-native'; -import {useSafeAreaInsets} from 'react-native-safe-area-context'; +import React, {useEffect, useState} from 'react'; import Autocomplete from '@components/autocomplete'; -import {View as ViewConstants} from '@constants'; +import {ExtraKeyboard} from '@context/extra_keyboard'; import {useServerUrl} from '@context/server'; import {useAutocompleteDefaultAnimatedValues} from '@hooks/autocomplete'; -import {useIsTablet, useKeyboardHeight} from '@hooks/device'; +import {useKeyboardHeight} from '@hooks/device'; import {useDefaultHeaderHeight} from '@hooks/header'; import Archived from './archived'; @@ -20,7 +17,6 @@ import ReadOnly from './read_only'; const AUTOCOMPLETE_ADJUST = -5; type Props = { testID?: string; - accessoriesContainerID?: string; canPost: boolean; channelId: string; channelIsArchived?: boolean; @@ -30,18 +26,13 @@ type Props = { isSearch?: boolean; message?: string; rootId?: string; - scrollViewNativeID?: string; - keyboardTracker: RefObject; containerHeight: number; isChannelScreen: boolean; canShowPostPriority?: boolean; } -const {KEYBOARD_TRACKING_OFFSET} = ViewConstants; - function PostDraft({ testID, - accessoriesContainerID, canPost, channelId, channelIsArchived, @@ -51,8 +42,6 @@ function PostDraft({ isSearch, message = '', rootId = '', - scrollViewNativeID, - keyboardTracker, containerHeight, isChannelScreen, canShowPostPriority, @@ -61,9 +50,7 @@ function PostDraft({ const [cursorPosition, setCursorPosition] = useState(message.length); const [postInputTop, setPostInputTop] = useState(0); const [isFocused, setIsFocused] = useState(false); - const isTablet = useIsTablet(); - const keyboardHeight = useKeyboardHeight(keyboardTracker); - const insets = useSafeAreaInsets(); + const keyboardHeight = useKeyboardHeight(); const headerHeight = useDefaultHeaderHeight(); const serverUrl = useServerUrl(); @@ -73,12 +60,7 @@ function PostDraft({ setCursorPosition(message.length); }, [channelId, rootId]); - const keyboardAdjustment = (isTablet && isChannelScreen) ? KEYBOARD_TRACKING_OFFSET : 0; - const insetsAdjustment = (isTablet && isChannelScreen) ? 0 : insets.bottom; - const autocompletePosition = AUTOCOMPLETE_ADJUST + Platform.select({ - ios: (keyboardHeight ? keyboardHeight - keyboardAdjustment : (postInputTop + insetsAdjustment)), - default: postInputTop + insetsAdjustment, - }); + const autocompletePosition = AUTOCOMPLETE_ADJUST + keyboardHeight + postInputTop; const autocompleteAvailableSpace = containerHeight - autocompletePosition - (isChannelScreen ? headerHeight : 0); const [animatedAutocompletePosition, animatedAutocompleteAvailableSpace] = useAutocompleteDefaultAnimatedValues(autocompletePosition, autocompleteAvailableSpace); @@ -136,26 +118,11 @@ function PostDraft({ /> ) : null; - if (Platform.OS === 'android') { - return ( - <> - {draftHandler} - {autoComplete} - - ); - } - return ( <> - - {draftHandler} - + {draftHandler} {autoComplete} + ); } diff --git a/app/components/post_draft/post_input/post_input.tsx b/app/components/post_draft/post_input/post_input.tsx index 756a05e7737..ea7208c9580 100644 --- a/app/components/post_draft/post_input/post_input.tsx +++ b/app/components/post_draft/post_input/post_input.tsx @@ -14,6 +14,7 @@ import { import {updateDraftMessage} from '@actions/local/draft'; import {userTyping} from '@actions/websocket/users'; import {Events, Screens} from '@constants'; +import {useExtraKeyboardContext} from '@context/extra_keyboard'; import {useServerUrl} from '@context/server'; import {useTheme} from '@context/theme'; import {useIsTablet} from '@hooks/device'; @@ -121,6 +122,7 @@ export default function PostInput({ const style = getStyleSheet(theme); const serverUrl = useServerUrl(); const managedConfig = useManagedConfig(); + const keyboardContext = useExtraKeyboardContext(); const [propagateValue, shouldProcessEvent] = useInputPropagation(); const lastTypingEventSent = useRef(0); @@ -145,13 +147,15 @@ export default function PostInput({ }; const onBlur = useCallback(() => { + keyboardContext?.registerTextInputBlur(); updateDraftMessage(serverUrl, channelId, rootId, value); setIsFocused(false); - }, [channelId, rootId, value, setIsFocused]); + }, [keyboardContext, serverUrl, channelId, rootId, value, setIsFocused]); const onFocus = useCallback(() => { + keyboardContext?.registerTextInputFocus(); setIsFocused(true); - }, [setIsFocused]); + }, [setIsFocused, keyboardContext]); const checkMessageLength = useCallback((newValue: string) => { const valueLength = newValue.trim().length; diff --git a/app/components/post_list/post/post.tsx b/app/components/post_list/post/post.tsx index cd86a79fd32..cf42e8794f6 100644 --- a/app/components/post_list/post/post.tsx +++ b/app/components/post_list/post/post.tsx @@ -1,7 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {type ReactNode, useEffect, useMemo, useRef, useState} from 'react'; +import React, {type ReactNode, useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {useIntl} from 'react-intl'; import {Keyboard, Platform, type StyleProp, View, type ViewStyle, TouchableHighlight} from 'react-native'; @@ -14,6 +14,7 @@ import SystemAvatar from '@components/system_avatar'; import SystemHeader from '@components/system_header'; import {POST_TIME_TO_FAIL} from '@constants/post'; import * as Screens from '@constants/screens'; +import {useHideExtraKeyboardIfNeeded} from '@context/extra_keyboard'; import {useServerUrl} from '@context/server'; import {useTheme} from '@context/theme'; import {useIsTablet} from '@hooks/device'; @@ -21,7 +22,6 @@ import PerformanceMetricsManager from '@managers/performance_metrics_manager'; import {openAsBottomSheet} from '@screens/navigation'; import {hasJumboEmojiOnly} from '@utils/emoji/helpers'; import {fromAutoResponder, isFromWebhook, isPostFailed, isPostPendingOrFailed, isSystemMessage} from '@utils/post'; -import {preventDoubleTap} from '@utils/tap'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; import Avatar from './avatar'; @@ -176,7 +176,7 @@ const Post = ({ return false; }, [customEmojiNames, post.message]); - const handlePostPress = () => { + const handlePostPress = useCallback(() => { if ([Screens.SAVED_MESSAGES, Screens.MENTIONS, Screens.SEARCH, Screens.PINNED_MESSAGES].includes(location)) { showPermalink(serverUrl, '', post.id); return; @@ -195,19 +195,20 @@ const Post = ({ setTimeout(() => { pressDetected.current = false; }, 300); - }; + }, [ + hasBeenDeleted, isAutoResponder, isEphemeral, + isPendingOrFailed, isSystemPost, location, serverUrl, post, + ]); - const handlePress = preventDoubleTap(() => { + const handlePress = useHideExtraKeyboardIfNeeded(() => { pressDetected.current = true; if (post) { - Keyboard.dismiss(); - setTimeout(handlePostPress, 300); } - }); + }, [handlePostPress, post]); - const showPostOptions = () => { + const showPostOptions = useHideExtraKeyboardIfNeeded(() => { if (!post) { return; } @@ -231,7 +232,11 @@ const Post = ({ title, props: passProps, }); - }; + }, [ + canDelete, hasBeenDeleted, intl, + isEphemeral, isPendingOrFailed, isTablet, isSystemPost, + location, post, serverUrl, showAddReaction, theme, + ]); const [, rerender] = useState(false); useEffect(() => { diff --git a/app/constants/post_draft.ts b/app/constants/post_draft.ts index 2b8b858a17d..9a601a8d239 100644 --- a/app/constants/post_draft.ts +++ b/app/constants/post_draft.ts @@ -5,13 +5,10 @@ export const MAX_MESSAGE_LENGTH_FALLBACK = 4000; export const DEFAULT_SERVER_MAX_FILE_SIZE = 50 * 1024 * 1024;// 50 Mb export const ICON_SIZE = 24; export const TYPING_HEIGHT = 16; -export const ACCESSORIES_CONTAINER_NATIVE_ID = 'channelAccessoriesContainer'; -export const THREAD_ACCESSORIES_CONTAINER_NATIVE_ID = 'threadAccessoriesContainer'; export const NOTIFY_ALL_MEMBERS = 5; export default { - ACCESSORIES_CONTAINER_NATIVE_ID, DEFAULT_SERVER_MAX_FILE_SIZE, ICON_SIZE, MAX_MESSAGE_LENGTH_FALLBACK, diff --git a/app/context/extra_keyboard/index.tsx b/app/context/extra_keyboard/index.tsx new file mode 100644 index 00000000000..cb14db6ccc6 --- /dev/null +++ b/app/context/extra_keyboard/index.tsx @@ -0,0 +1,183 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React, {createContext, useCallback, useContext, useEffect, useState} from 'react'; +import {Keyboard, Platform} from 'react-native'; +import Animated, {KeyboardState, useAnimatedKeyboard, useAnimatedStyle, useDerivedValue, withTiming} from 'react-native-reanimated'; +import {useSafeAreaInsets} from 'react-native-safe-area-context'; + +import {Screens} from '@constants'; +import {useIsTablet} from '@hooks/device'; +import NavigationStore from '@store/navigation_store'; +import {preventDoubleTap} from '@utils/tap'; + +import type {AvailableScreens} from '@typings/screens/navigation'; + +export type ExtraKeyboardContextProps = { + isExtraKeyboardVisible: boolean; + component: React.ReactElement|null; + showExtraKeyboard: (component: React.ReactElement|null) => void; + hideExtraKeyboard: () => void; + registerTextInputFocus: () => void; + registerTextInputBlur: () => void; +}; + +// This is based on the size of the tab bar +const KEYBOARD_OFFSET = -77; + +export const ExtraKeyboardContext = createContext(undefined); + +const useOffetForCurrentScreen = (): number => { + const [screen, setScreen] = useState(); + const [offset, setOffset] = useState(0); + const isTablet = useIsTablet(); + + useEffect(() => { + const sub = NavigationStore.getSubject(); + const s = sub.subscribe(setScreen); + + return () => s.unsubscribe(); + }, []); + + useEffect(() => { + if (isTablet && screen === Screens.HOME) { + setOffset(KEYBOARD_OFFSET); + } + }, [isTablet, screen]); + + return offset; +}; + +export const ExtraKeyboardProvider = (({children}: {children: React.ReactElement|React.ReactElement[]}) => { + const [isExtraKeyboardVisible, setExtraKeyboardVisible] = useState(false); + const [component, setComponent] = useState(null); + const [isTextInputFocused, setIsTextInputFocused] = useState(false); + + const showExtraKeyboard = useCallback((newComponent: React.ReactElement|null) => { + setExtraKeyboardVisible(true); + setComponent(newComponent); + if (Keyboard.isVisible()) { + Keyboard.dismiss(); + } + }, []); + + const hideExtraKeyboard = useCallback(() => { + setExtraKeyboardVisible(false); + setComponent(null); + if (Keyboard.isVisible()) { + Keyboard.dismiss(); + } + }, []); + + const registerTextInputFocus = useCallback(() => { + // If the extra keyboard is opened if we don't do this + // we get a glitch in the UI that will animate the extra keyboard down + // and immediately bring the keyboard, by doing this + // we delay hidding the extra keyboard, so that there is no animation glitch + setIsTextInputFocused(true); + setTimeout(() => { + setExtraKeyboardVisible(false); + }, 400); + }, []); + + const registerTextInputBlur = useCallback(() => { + setIsTextInputFocused(false); + }, []); + + useEffect(() => { + const keyboardHideListener = Keyboard.addListener('keyboardDidHide', () => { + if (isTextInputFocused) { + setExtraKeyboardVisible(false); + } + }); + + return () => keyboardHideListener.remove(); + }, [isTextInputFocused]); + + return ( + + {children} + + ); +}); + +export const useExtraKeyboardContext = (): ExtraKeyboardContextProps|undefined => { + const context = useContext(ExtraKeyboardContext); + if (!context) { + throw new Error('useExtraKeyboardContext must be used within a ExtraKeyboardProvider'); + } + return context; +}; + +export const useHideExtraKeyboardIfNeeded = (callback: (...args: any) => void, dependencies: React.DependencyList = []) => { + const keyboardContext = useExtraKeyboardContext(); + + return useCallback(preventDoubleTap((...args: any) => { + if (keyboardContext?.isExtraKeyboardVisible) { + keyboardContext.hideExtraKeyboard(); + + /* + /* At this point the early return is commented + /* Based on the UX we actually want to have + /* we can uncoment this and reaturn as early + /* as the custom keyboard is hidden + */ + // return; + } + + if (Keyboard.isVisible()) { + Keyboard.dismiss(); + } + + callback(...args); + }), [keyboardContext, ...dependencies]); +}; + +export const ExtraKeyboard = () => { + const keyb = useAnimatedKeyboard({isStatusBarTranslucentAndroid: true}); + const defaultKeyboardHeight = Platform.select({ios: 291, default: 240}); + const context = useExtraKeyboardContext(); + const insets = useSafeAreaInsets(); + const offset = useOffetForCurrentScreen(); + + const maxKeyboardHeight = useDerivedValue(() => { + if (keyb.state.value === KeyboardState.OPEN) { + const keyboardOffset = keyb.height.value < 70 ? 0 : offset; // When using a hw keyboard + return keyb.height.value + keyboardOffset; + } + + return defaultKeyboardHeight; + }); + + const animatedStyle = useAnimatedStyle(() => { + let height = keyb.height.value + offset; + if (keyb.height.value < 70) { + height = 0; // When using a hw keyboard + } + if (context?.isExtraKeyboardVisible) { + height = withTiming(maxKeyboardHeight.value, {duration: 250}); + } else if (keyb.state.value === KeyboardState.CLOSED || keyb.state.value === KeyboardState.UNKNOWN) { + height = withTiming(0, {duration: 250}); + } + + return { + height, + marginBottom: withTiming((keyb.state.value === KeyboardState.CLOSED || keyb.state.value === KeyboardState.CLOSING || keyb.state.value === KeyboardState.UNKNOWN) ? insets.bottom : 0, {duration: 250}), + }; + }, [context, insets.bottom, offset]); + + return ( + + {context?.isExtraKeyboardVisible && context.component} + + ); +}; diff --git a/app/hooks/device.ts b/app/hooks/device.ts index 72266b0b3a3..9eb98ffd821 100644 --- a/app/hooks/device.ts +++ b/app/hooks/device.ts @@ -3,12 +3,11 @@ import RNUtils, {type WindowDimensions} from '@mattermost/rnutils'; import React, {type RefObject, useEffect, useRef, useState, useContext} from 'react'; -import {AppState, DeviceEventEmitter, Keyboard, NativeEventEmitter, Platform, View} from 'react-native'; +import {AppState, Keyboard, NativeEventEmitter, Platform, View} from 'react-native'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import {DeviceContext} from '@context/device'; -import type {KeyboardTrackingViewRef, KeyboardWillShowEventData} from '@mattermost/keyboard-tracker'; import type {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view'; const utilsEmitter = new NativeEventEmitter(RNUtils); @@ -51,43 +50,14 @@ export function useIsTablet() { return isTablet && !isSplit; } -export function useKeyboardHeightWithDuration(keyboardTracker?: RefObject) { +export function useKeyboardHeightWithDuration() { const [keyboardHeight, setKeyboardHeight] = useState({height: 0, duration: 0}); const updateTimeout = useRef(null); const insets = useSafeAreaInsets(); - // This is a magic number. With tracking view, to properly get the final position, this had to be added. - const KEYBOARD_TRACKINGVIEW_SEPARATION = 4; - - const updateValue = (height: number, duration: number) => { - if (updateTimeout.current != null) { - clearTimeout(updateTimeout.current); - updateTimeout.current = null; - } - updateTimeout.current = setTimeout(() => { - setKeyboardHeight({height, duration}); - updateTimeout.current = null; - }, 200); - }; - useEffect(() => { const show = Keyboard.addListener(Platform.select({ios: 'keyboardWillShow', default: 'keyboardDidShow'}), async (event) => { - if (!keyboardTracker?.current) { - setKeyboardHeight({height: event.endCoordinates.height, duration: event.duration}); - } - }); - - const tracker = DeviceEventEmitter.addListener('MattermostKeyboardTrackerView', (event: KeyboardWillShowEventData) => { - const props = event.nativeEvent; - if (keyboardTracker?.current) { - if (props.keyboardHeight) { - updateValue((props.trackingViewHeight + props.keyboardHeight) - KEYBOARD_TRACKINGVIEW_SEPARATION, props.animationDuration); - } else { - updateValue((props.trackingViewHeight + insets.bottom) - KEYBOARD_TRACKINGVIEW_SEPARATION, props.animationDuration); - } - } else { - setKeyboardHeight({height: props.keyboardFrameEndHeight, duration: props.animationDuration}); - } + setKeyboardHeight({height: event.endCoordinates.height, duration: event.duration}); }); const hide = Keyboard.addListener(Platform.select({ios: 'keyboardWillHide', default: 'keyboardDidHide'}), (event) => { @@ -101,15 +71,14 @@ export function useKeyboardHeightWithDuration(keyboardTracker?: RefObject { show.remove(); hide.remove(); - tracker.remove(); }; - }, [keyboardTracker?.current && insets.bottom]); + }, [insets.bottom]); return keyboardHeight; } -export function useKeyboardHeight(keyboardTracker?: RefObject) { - const {height} = useKeyboardHeightWithDuration(keyboardTracker); +export function useKeyboardHeight() { + const {height} = useKeyboardHeightWithDuration(); return height; } @@ -126,7 +95,7 @@ export function useViewPosition(viewRef: RefObject, deps: React.Dependency } }); } - }, [...deps, isTablet, height]); + }, [...deps, isTablet, height, viewRef, modalPosition]); return modalPosition; } diff --git a/app/hooks/keyboard_tracking.ts b/app/hooks/keyboard_tracking.ts deleted file mode 100644 index 3f598da482b..00000000000 --- a/app/hooks/keyboard_tracking.ts +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import {type KeyboardTrackingViewRef} from '@mattermost/keyboard-tracker'; -import {type RefObject, useEffect, useRef} from 'react'; -import {Navigation} from 'react-native-navigation'; - -import NavigationStore from '@store/navigation_store'; - -export const useKeyboardTrackingPaused = (keyboardTrackingRef: RefObject, trackerId: string, screens: string[]) => { - const isPostDraftPaused = useRef(false); - - useEffect(() => { - if (keyboardTrackingRef.current) { - keyboardTrackingRef.current.resumeTracking(trackerId); - } - }, []); - - useEffect(() => { - const onCommandComplete = () => { - const id = NavigationStore.getVisibleScreen(); - if (screens.includes(id) && isPostDraftPaused.current) { - isPostDraftPaused.current = false; - keyboardTrackingRef.current?.resumeTracking(trackerId); - } - }; - - const commandListener = Navigation.events().registerCommandListener(() => { - setTimeout(() => { - const visibleScreen = NavigationStore.getVisibleScreen(); - if (!isPostDraftPaused.current && !screens.includes(visibleScreen)) { - isPostDraftPaused.current = true; - keyboardTrackingRef.current?.pauseTracking(trackerId); - } - }); - }); - - const commandCompletedListener = Navigation.events().registerCommandCompletedListener(() => { - onCommandComplete(); - }); - - const popListener = Navigation.events().registerScreenPoppedListener(() => { - onCommandComplete(); - }); - - return () => { - commandListener.remove(); - commandCompletedListener.remove(); - popListener.remove(); - }; - }, [trackerId]); -}; diff --git a/app/screens/channel/channel.tsx b/app/screens/channel/channel.tsx index 845d20e6bbf..4c4768c7ccc 100644 --- a/app/screens/channel/channel.tsx +++ b/app/screens/channel/channel.tsx @@ -1,22 +1,21 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {type KeyboardTrackingViewRef} from 'libraries/@mattermost/keyboard-tracker/src'; -import React, {useCallback, useEffect, useRef, useState} from 'react'; +import RNUtils from '@mattermost/rnutils'; +import React, {useCallback, useEffect, useState} from 'react'; import {type LayoutChangeEvent, StyleSheet, View} from 'react-native'; +import {Navigation} from 'react-native-navigation'; import {type Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'; import {storeLastViewedChannelIdAndServer, removeLastViewedChannelIdAndServer} from '@actions/app/global'; import FloatingCallContainer from '@calls/components/floating_call_container'; import FreezeScreen from '@components/freeze_screen'; import PostDraft from '@components/post_draft'; -import {Screens} from '@constants'; -import {ACCESSORIES_CONTAINER_NATIVE_ID} from '@constants/post_draft'; +import {ExtraKeyboardProvider} from '@context/extra_keyboard'; import useAndroidHardwareBackHandler from '@hooks/android_back_handler'; import {useChannelSwitch} from '@hooks/channel_switch'; import {useIsTablet} from '@hooks/device'; import {useDefaultHeaderHeight} from '@hooks/header'; -import {useKeyboardTrackingPaused} from '@hooks/keyboard_tracking'; import {useTeamSwitch} from '@hooks/team_switch'; import {popTopScreen} from '@screens/navigation'; import EphemeralStore from '@store/ephemeral_store'; @@ -45,7 +44,6 @@ type ChannelProps = { }; const edges: Edge[] = ['left', 'right']; -const trackKeyboardForScreens = [Screens.HOME, Screens.CHANNEL]; const styles = StyleSheet.create({ flex: { @@ -75,16 +73,28 @@ const Channel = ({ const switchingTeam = useTeamSwitch(); const switchingChannels = useChannelSwitch(); const defaultHeight = useDefaultHeaderHeight(); - const postDraftRef = useRef(null); const [containerHeight, setContainerHeight] = useState(0); const shouldRender = !switchingTeam && !switchingChannels && shouldRenderPosts && Boolean(channelId); const handleBack = useCallback(() => { popTopScreen(componentId); }, [componentId]); - useKeyboardTrackingPaused(postDraftRef, channelId, trackKeyboardForScreens); useAndroidHardwareBackHandler(componentId, handleBack); + useEffect(() => { + const listener = { + componentDidAppear: () => { + RNUtils.setSoftKeyboardToAdjustNothing(); + }, + componentDidDisappear: () => { + RNUtils.setSoftKeyboardToAdjustResize(); + }, + }; + const unsubscribe = Navigation.events().registerComponentListener(listener, componentId!); + + return () => unsubscribe.remove(); + }, []); + const marginTop = defaultHeight + (isTablet ? 0 : -insets.top); useEffect(() => { // This is done so that the header renders @@ -132,7 +142,7 @@ const Channel = ({ shouldRenderBookmarks={shouldRender} /> {shouldRender && - <> + - + } {showFloatingCallContainer && shouldRender && { } }; -export default function HomeScreen(props: HomeProps) { +export function HomeScreen(props: HomeProps) { const theme = useTheme(); const intl = useIntl(); const appState = useAppState(); @@ -82,7 +82,7 @@ export default function HomeScreen(props: HomeProps) { return () => { listener.remove(); }; - }, [intl.locale]); + }, [intl]); useEffect(() => { const leaveTeamListener = DeviceEventEmitter.addListener(Events.LEAVE_TEAM, (displayName: string) => { @@ -109,7 +109,7 @@ export default function HomeScreen(props: HomeProps) { archivedChannelListener.remove(); crtToggledListener.remove(); }; - }, [intl.locale]); + }, [intl]); useEffect(() => { if (appState === 'active') { @@ -191,3 +191,5 @@ export default function HomeScreen(props: HomeProps) { ); } + +export default HomeScreen; diff --git a/app/screens/home/recent_mentions/recent_mentions.tsx b/app/screens/home/recent_mentions/recent_mentions.tsx index 904f9a1dbd8..926766b1d68 100644 --- a/app/screens/home/recent_mentions/recent_mentions.tsx +++ b/app/screens/home/recent_mentions/recent_mentions.tsx @@ -14,6 +14,7 @@ import DateSeparator from '@components/post_list/date_separator'; import PostWithChannelInfo from '@components/post_with_channel_info'; import RoundedHeaderContext from '@components/rounded_header_context'; import {Events, Screens} from '@constants'; +import {ExtraKeyboardProvider} from '@context/extra_keyboard'; import {useServerUrl} from '@context/server'; import {useTheme} from '@context/theme'; import {useCollapsibleHeader} from '@hooks/header'; @@ -162,7 +163,7 @@ const RecentMentionsScreen = ({appsEnabled, customEmojiNames, mentions, currentT }, [appsEnabled, customEmojiNames]); return ( - <> + - + ); }; diff --git a/app/screens/home/saved_messages/saved_messages.tsx b/app/screens/home/saved_messages/saved_messages.tsx index 2ecbee96680..9fe96a59d1c 100644 --- a/app/screens/home/saved_messages/saved_messages.tsx +++ b/app/screens/home/saved_messages/saved_messages.tsx @@ -15,6 +15,7 @@ import DateSeparator from '@components/post_list/date_separator'; import PostWithChannelInfo from '@components/post_with_channel_info'; import RoundedHeaderContext from '@components/rounded_header_context'; import {Events, Screens} from '@constants'; +import {ExtraKeyboardProvider} from '@context/extra_keyboard'; import {useServerUrl} from '@context/server'; import {useTheme} from '@context/theme'; import {useCollapsibleHeader} from '@hooks/header'; @@ -164,7 +165,7 @@ function SavedMessages({appsEnabled, posts, currentTimezone, customEmojiNames}: }, [appsEnabled, currentTimezone, customEmojiNames, theme]); return ( - <> + - + ); } diff --git a/app/screens/home/search/results/post_results.tsx b/app/screens/home/search/results/post_results.tsx index 5b0ecd297f1..e4cd6f06eec 100644 --- a/app/screens/home/search/results/post_results.tsx +++ b/app/screens/home/search/results/post_results.tsx @@ -9,6 +9,7 @@ import NoResultsWithTerm from '@components/no_results_with_term'; import DateSeparator from '@components/post_list/date_separator'; import PostWithChannelInfo from '@components/post_with_channel_info'; import {Screens} from '@constants'; +import {ExtraKeyboardProvider} from '@context/extra_keyboard'; import {useTheme} from '@context/theme'; import {convertSearchTermToRegex, parseSearchTerms} from '@utils/markdown'; import {getDateForDateLine, selectOrderedPosts} from '@utils/post_list'; @@ -89,7 +90,7 @@ const PostResults = ({ default: return null; } - }, [appsEnabled, customEmojiNames, searchValue, matches]); + }, [currentTimezone, searchValue, matches, appsEnabled, customEmojiNames]); const noResults = useMemo(() => ( - } - ListEmptyComponent={noResults} - contentContainerStyle={containerStyle} - data={orderedPosts} - indicatorStyle='black' - initialNumToRender={5} + + + } + ListEmptyComponent={noResults} + contentContainerStyle={containerStyle} + data={orderedPosts} + indicatorStyle='black' + initialNumToRender={5} - //@ts-expect-error key not defined in types - listKey={'posts'} - maxToRenderPerBatch={5} - nestedScrollEnabled={true} - refreshing={false} - removeClippedSubviews={true} - renderItem={renderItem} - scrollEventThrottle={16} - scrollToOverflowEnabled={true} - showsVerticalScrollIndicator={true} - testID='search_results.post_list.flat_list' - /> + //@ts-expect-error key not defined in types + listKey={'posts'} + maxToRenderPerBatch={5} + nestedScrollEnabled={true} + refreshing={false} + removeClippedSubviews={true} + renderItem={renderItem} + scrollEventThrottle={16} + scrollToOverflowEnabled={true} + showsVerticalScrollIndicator={true} + testID='search_results.post_list.flat_list' + /> + ); }; diff --git a/app/screens/permalink/permalink.tsx b/app/screens/permalink/permalink.tsx index ff0c56b1803..22255dad634 100644 --- a/app/screens/permalink/permalink.tsx +++ b/app/screens/permalink/permalink.tsx @@ -15,6 +15,7 @@ import FormattedText from '@components/formatted_text'; import Loading from '@components/loading'; import PostList from '@components/post_list'; import {Screens} from '@constants'; +import {ExtraKeyboardProvider} from '@context/extra_keyboard'; import {useServerUrl} from '@context/server'; import {useTheme} from '@context/theme'; import DatabaseManager from '@database/manager'; @@ -315,7 +316,7 @@ function Permalink({ ); } else { content = ( - <> + - + ); } diff --git a/app/screens/pinned_messages/pinned_messages.tsx b/app/screens/pinned_messages/pinned_messages.tsx index 6cfadbf9bd4..36f142cb427 100644 --- a/app/screens/pinned_messages/pinned_messages.tsx +++ b/app/screens/pinned_messages/pinned_messages.tsx @@ -10,6 +10,7 @@ import Loading from '@components/loading'; import DateSeparator from '@components/post_list/date_separator'; import Post from '@components/post_list/post'; import {Events, Screens} from '@constants'; +import {ExtraKeyboardProvider} from '@context/extra_keyboard'; import {useServerUrl} from '@context/server'; import {useTheme} from '@context/theme'; import useAndroidHardwareBackHandler from '@hooks/android_back_handler'; @@ -152,17 +153,19 @@ function SavedMessages({ style={styles.flex} testID='pinned_messages.screen' > - + + + ); } diff --git a/app/screens/thread/thread.tsx b/app/screens/thread/thread.tsx index 8cb015b3dd9..435940f3853 100644 --- a/app/screens/thread/thread.tsx +++ b/app/screens/thread/thread.tsx @@ -1,9 +1,11 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import RNUtils from '@mattermost/rnutils'; import {uniqueId} from 'lodash'; -import React, {useCallback, useEffect, useRef, useState} from 'react'; +import React, {useCallback, useEffect, useState} from 'react'; import {type LayoutChangeEvent, StyleSheet, View} from 'react-native'; +import {Navigation} from 'react-native-navigation'; import {type Edge, SafeAreaView} from 'react-native-safe-area-context'; import {storeLastViewedThreadIdAndServer, removeLastViewedThreadIdAndServer} from '@actions/app/global'; @@ -12,17 +14,15 @@ import FreezeScreen from '@components/freeze_screen'; import PostDraft from '@components/post_draft'; import RoundedHeaderContext from '@components/rounded_header_context'; import {Screens} from '@constants'; -import {THREAD_ACCESSORIES_CONTAINER_NATIVE_ID} from '@constants/post_draft'; +import {ExtraKeyboardProvider} from '@context/extra_keyboard'; import useAndroidHardwareBackHandler from '@hooks/android_back_handler'; import useDidUpdate from '@hooks/did_update'; -import {useKeyboardTrackingPaused} from '@hooks/keyboard_tracking'; import {popTopScreen, setButtons} from '@screens/navigation'; import EphemeralStore from '@store/ephemeral_store'; import NavigationStore from '@store/navigation_store'; import ThreadPostList from './thread_post_list'; -import type {KeyboardTrackingViewRef} from '@mattermost/keyboard-tracker'; import type PostModel from '@typings/database/models/servers/post'; import type {AvailableScreens} from '@typings/screens/navigation'; @@ -37,7 +37,6 @@ type ThreadProps = { }; const edges: Edge[] = ['left', 'right']; -const trackKeyboardForScreens = [Screens.THREAD]; const styles = StyleSheet.create({ flex: {flex: 1}, @@ -52,16 +51,28 @@ const Thread = ({ isInACall, showIncomingCalls, }: ThreadProps) => { - const postDraftRef = useRef(null); const [containerHeight, setContainerHeight] = useState(0); const close = useCallback(() => { popTopScreen(componentId); }, [componentId]); - useKeyboardTrackingPaused(postDraftRef, rootId, trackKeyboardForScreens); useAndroidHardwareBackHandler(componentId, close); + useEffect(() => { + const listener = { + componentDidAppear: () => { + RNUtils.setSoftKeyboardToAdjustNothing(); + }, + componentDidDisappear: () => { + RNUtils.setSoftKeyboardToAdjustResize(); + }, + }; + const unsubscribe = Navigation.events().registerComponentListener(listener, componentId!); + + return () => unsubscribe.remove(); + }, []); + useEffect(() => { if (isCRTEnabled && rootId) { const id = `${componentId}-${rootId}-${uniqueId()}`; @@ -122,7 +133,7 @@ const Thread = ({ > {Boolean(rootPost) && - <> + - + } {showFloatingCallContainer && { const appState = useAppState(); - const isTablet = useIsTablet(); const serverUrl = useServerUrl(); const theme = useTheme(); const isFetchingThread = useFetchingThreadState(rootPost.id); @@ -87,7 +83,7 @@ const ThreadPostList = ({ oldPostsCount.current = posts.length; markThreadAsRead(serverUrl, teamId, rootPost.id, false); } - }, [isCRTEnabled, posts, rootPost, serverUrl, teamId, thread, appState === 'active']); + }, [isCRTEnabled, posts, rootPost, serverUrl, teamId, thread, appState]); const lastViewedAt = isCRTEnabled ? (thread?.viewedAt ?? 0) : channelLastViewedAt; @@ -116,18 +112,7 @@ const ThreadPostList = ({ /> ); - if (isTablet) { - return postList; - } - - return ( - - {postList} - - ); + return postList; }; export default ThreadPostList; diff --git a/app/store/navigation_store.ts b/app/store/navigation_store.ts index 0c0f815cad8..304718e7c12 100644 --- a/app/store/navigation_store.ts +++ b/app/store/navigation_store.ts @@ -1,6 +1,8 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import {BehaviorSubject} from 'rxjs'; + import type {AvailableScreens} from '@typings/screens/navigation'; class NavigationStore { @@ -9,11 +11,18 @@ class NavigationStore { private visibleTab = 'Home'; private tosOpen = false; + private subject: BehaviorSubject = new BehaviorSubject(undefined); + + getSubject = () => { + return this.subject; + }; + reset = () => { this.screensInStack = []; this.modalsInStack = []; this.visibleTab = 'Home'; this.tosOpen = false; + this.subject.next(undefined); }; addModalToStack = (modalId: AvailableScreens) => { @@ -25,10 +34,12 @@ class NavigationStore { addScreenToStack = (screenId: AvailableScreens) => { this.removeScreenFromStack(screenId); this.screensInStack.unshift(screenId); + this.subject.next(screenId); }; clearScreensFromStack = () => { this.screensInStack = []; + this.subject.next(undefined); }; getModalsInStack = () => this.modalsInStack; @@ -49,6 +60,7 @@ class NavigationStore { const index = this.screensInStack.indexOf(screenId); if (index > -1) { this.screensInStack.splice(0, index); + this.subject.next(screenId); } }; @@ -56,6 +68,7 @@ class NavigationStore { const index = this.screensInStack.indexOf(screenId); if (index > -1) { this.screensInStack.splice(index, 1); + this.subject.next(this.screensInStack[0]); } }; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 72a447e3af0..984bda232a0 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -94,27 +94,6 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - mattermost-keyboard-tracker (0.0.0): - - DoubleConversion - - glog - - hermes-engine - - RCT-Folly (= 2024.01.01.00) - - RCTRequired - - RCTTypeSafety - - React-Codegen - - React-Core - - React-debug - - React-Fabric - - React-featureflags - - React-graphics - - React-ImageManager - - React-NativeModulesApple - - React-RCTFabric - - React-rendererdebug - - React-utils - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - - Yoga - mattermost-react-native-turbo-log (0.4.0): - CocoaLumberjack (~> 3.8.5) - DoubleConversion @@ -1669,7 +1648,6 @@ DEPENDENCIES: - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - "mattermost-hardware-keyboard (from `../node_modules/@mattermost/hardware-keyboard`)" - - "mattermost-keyboard-tracker (from `../node_modules/@mattermost/keyboard-tracker`)" - "mattermost-react-native-turbo-log (from `../node_modules/@mattermost/react-native-turbo-log`)" - "mattermost-rnutils (from `../node_modules/@mattermost/rnutils`)" - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) @@ -1812,8 +1790,6 @@ EXTERNAL SOURCES: :tag: hermes-2024-06-28-RNv0.74.3-7bda0c267e76d11b68a585f84cfdd65000babf85 mattermost-hardware-keyboard: :path: "../node_modules/@mattermost/hardware-keyboard" - mattermost-keyboard-tracker: - :path: "../node_modules/@mattermost/keyboard-tracker" mattermost-react-native-turbo-log: :path: "../node_modules/@mattermost/react-native-turbo-log" mattermost-rnutils: @@ -2008,7 +1984,6 @@ SPEC CHECKSUMS: JitsiWebRTC: d0ae5fd6a81e771bfd82c2ee6c6bb542ebd65ee8 libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009 mattermost-hardware-keyboard: b916a168bb3add779bb226b3a62d6ac5ec225a79 - mattermost-keyboard-tracker: b48752a97e731fdae5e8259a4ea0e731e1a05094 mattermost-react-native-turbo-log: c446c7e8a39c131d6bafa6ae6f830c735030ed5e mattermost-rnutils: 01504fb26beb75594f4c6e2150668b27783112f5 RCT-Folly: 02617c592a293bd6d418e0a88ff4ee1f88329b47 diff --git a/libraries/@mattermost/keyboard-tracker/ios/Extensions/UIResponder+FirstResponder.h b/libraries/@mattermost/keyboard-tracker/ios/Extensions/UIResponder+FirstResponder.h deleted file mode 100644 index 0e8d253e820..00000000000 --- a/libraries/@mattermost/keyboard-tracker/ios/Extensions/UIResponder+FirstResponder.h +++ /dev/null @@ -1,6 +0,0 @@ -#import -#import - -@interface UIResponder (CurrentResponder) -+(id)currentFirstResponder; -@end diff --git a/libraries/@mattermost/keyboard-tracker/ios/Extensions/UIResponder+FirstResponder.m b/libraries/@mattermost/keyboard-tracker/ios/Extensions/UIResponder+FirstResponder.m deleted file mode 100644 index 2da036d29e0..00000000000 --- a/libraries/@mattermost/keyboard-tracker/ios/Extensions/UIResponder+FirstResponder.m +++ /dev/null @@ -1,17 +0,0 @@ -#import "UIResponder+FirstResponder.h" - -static __weak id currentFirstResponder; - -@implementation UIResponder (FirstResponder) - -+(id)currentFirstResponder { - currentFirstResponder = nil; - [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:nil forEvent:nil]; - return currentFirstResponder; -} - --(void)findFirstResponder:(id)sender { - currentFirstResponder = self; -} - -@end diff --git a/libraries/@mattermost/keyboard-tracker/ios/MattermostKeyboardTrackerView.h b/libraries/@mattermost/keyboard-tracker/ios/MattermostKeyboardTrackerView.h deleted file mode 100644 index 65ebeb4fb1c..00000000000 --- a/libraries/@mattermost/keyboard-tracker/ios/MattermostKeyboardTrackerView.h +++ /dev/null @@ -1,17 +0,0 @@ -// This guard prevent this file to be compiled in the old architecture. -#ifdef RCT_NEW_ARCH_ENABLED -#import -#import - -#ifndef MattermostKeyboardTrackerViewNativeComponent_h -#define MattermostKeyboardTrackerViewNativeComponent_h - -NS_ASSUME_NONNULL_BEGIN - -@interface MattermostKeyboardTrackerView : RCTViewComponentView -@end - -NS_ASSUME_NONNULL_END - -#endif /* MattermostKeyboardTrackerViewNativeComponent_h */ -#endif /* RCT_NEW_ARCH_ENABLED */ diff --git a/libraries/@mattermost/keyboard-tracker/ios/MattermostKeyboardTrackerView.mm b/libraries/@mattermost/keyboard-tracker/ios/MattermostKeyboardTrackerView.mm deleted file mode 100644 index f68571bc9d0..00000000000 --- a/libraries/@mattermost/keyboard-tracker/ios/MattermostKeyboardTrackerView.mm +++ /dev/null @@ -1,169 +0,0 @@ -#ifdef RCT_NEW_ARCH_ENABLED -#import "MattermostKeyboardTrackerView.h" -#import "KeyboardTrackingView.h" - -#import -#import -#import -#import - -#import "RCTFabricComponentsPlugins.h" -#import "RCTConversions.h" - -using namespace facebook::react; - -@interface MattermostKeyboardTrackerView () - -@end - -@implementation MattermostKeyboardTrackerView { - KeyboardTrackingView * _view; -} - -+ (ComponentDescriptorProvider)componentDescriptorProvider -{ - return concreteComponentDescriptorProvider(); -} - --(std::shared_ptr)getEventEmitter { - if (!self->_eventEmitter) { - return nullptr; - } - - assert(std::dynamic_pointer_cast(self->_eventEmitter)); - return std::dynamic_pointer_cast(self->_eventEmitter); -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - if (self = [super initWithFrame:frame]) { - static const auto defaultProps = std::make_shared(); - _props = defaultProps; - - _view = [[KeyboardTrackingView alloc] init]; - [self _setOnKeyboardWillShow]; - - self.contentView = _view; - } - - return self; -} - -- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps -{ - const auto &oldViewProps = *std::static_pointer_cast(_props); - const auto &newViewProps = *std::static_pointer_cast(props); - - if (oldViewProps.scrollBehavior != newViewProps.scrollBehavior) { - std::string behaviorString = toString(newViewProps.scrollBehavior); - KeyboardTrackingScrollBehavior scrollBehavior = KeyboardTrackingScrollBehaviorFromString([NSString stringWithUTF8String:behaviorString.c_str()]); - _view.scrollBehavior = scrollBehavior; - } - - if (oldViewProps.revealKeyboardInteractive != newViewProps.revealKeyboardInteractive) { - _view.revealKeyboardInteractive = newViewProps.revealKeyboardInteractive; - } - - if (oldViewProps.manageScrollView != newViewProps.manageScrollView) { - _view.manageScrollView = newViewProps.manageScrollView; - } - - if (oldViewProps.requiresSameParentToManageScrollView != newViewProps.requiresSameParentToManageScrollView) { - _view.requiresSameParentToManageScrollView = newViewProps.requiresSameParentToManageScrollView; - } - - if (oldViewProps.addBottomView != newViewProps.addBottomView) { - _view.addBottomView = newViewProps.addBottomView; - } - - if (oldViewProps.scrollToFocusedInput != newViewProps.scrollToFocusedInput) { - _view.scrollToFocusedInput = newViewProps.scrollToFocusedInput; - } - - if (oldViewProps.allowHitsOutsideBounds != newViewProps.allowHitsOutsideBounds) { - _view.allowHitsOutsideBounds = newViewProps.allowHitsOutsideBounds; - } - - if (oldViewProps.normalList != newViewProps.normalList) { - _view.normalList = newViewProps.normalList; - } - - if (oldViewProps.viewInitialOffsetY != newViewProps.viewInitialOffsetY) { - _view.viewInitialOffsetY = newViewProps.viewInitialOffsetY; - } - - if (oldViewProps.scrollViewNativeID != newViewProps.scrollViewNativeID) { - _view.scrollViewNativeID = RCTNSStringFromString(newViewProps.scrollViewNativeID); - } - - if (oldViewProps.accessoriesContainerID != newViewProps.accessoriesContainerID) { - _view.accessoriesContainerID = RCTNSStringFromString(newViewProps.accessoriesContainerID); - - } - - if (oldViewProps.backgroundColor != newViewProps.backgroundColor) { - [_view setBottomViewBackgroundColor:RCTUIColorFromSharedColor(newViewProps.backgroundColor)]; - } - - [super updateProps:props oldProps:oldProps]; -} - -- (void)handleCommand:(nonnull const NSString *)commandName args:(nonnull const NSArray *)args { - RCTMattermostKeyboardTrackerViewHandleCommand(self, commandName, args); -} - --(void)_setOnKeyboardWillShow{ - _view.onKeyboardWillShow = ^(NSDictionary *body) { - const auto eventEmitter = [self getEventEmitter]; - if (eventEmitter) { - eventEmitter->onKeyboardWillShow(MattermostKeyboardTrackerViewEventEmitter::OnKeyboardWillShow{ - .trackingViewHeight = [body[@"trackingViewHeight"] doubleValue], - .keyboardHeight = [body[@"keyboardHeight"] doubleValue], - .contentTopInset = [body[@"contentTopInset"] doubleValue], - .animationDuration = [body[@"animationDuration"] doubleValue], - .keyboardFrameEndHeight = (CGFloat)[body[@"keyboardFrameEndHeight"] doubleValue], - }); - } - }; -} - -Class MattermostKeyboardTrackerViewCls(void) -{ - return MattermostKeyboardTrackerView.class; -} - -- (void)pauseTracking:(nonnull NSString *)scrollViewNativeID { - [_view pauseTracking:scrollViewNativeID]; -} - -- (void)resetScrollView:(nonnull NSString *)scrollViewNativeID { - [_view resetScrollView:scrollViewNativeID]; -} - -- (void)resumeTracking:(nonnull NSString *)scrollViewNativeID { - [_view resumeTracking:scrollViewNativeID]; -} - -- (void)scrollToStart { - [_view scrollToStart]; -} - - -#pragma utils - -KeyboardTrackingScrollBehavior KeyboardTrackingScrollBehaviorFromString(NSString *string) { - if ([string isEqualToString:@"KeyboardTrackingScrollBehaviorNone"]) { - return KeyboardTrackingScrollBehaviorNone; - } else if ([string isEqualToString:@"KeyboardTrackingScrollBehaviorScrollToBottomInvertedOnly"]) { - return KeyboardTrackingScrollBehaviorScrollToBottomInvertedOnly; - } else if ([string isEqualToString:@"KeyboardTrackingScrollBehaviorFixedOffset"]) { - return KeyboardTrackingScrollBehaviorFixedOffset; - } else { - // Handle the case where the string doesn't match any known value - // You can choose to return a default value or raise an exception - return KeyboardTrackingScrollBehaviorNone; // Default value - } -} - -@end -#endif diff --git a/libraries/@mattermost/keyboard-tracker/ios/ViewManagers/MattermostKeyboardTrackerViewManager.mm b/libraries/@mattermost/keyboard-tracker/ios/ViewManagers/MattermostKeyboardTrackerViewManager.mm deleted file mode 100644 index bd2fc1954b9..00000000000 --- a/libraries/@mattermost/keyboard-tracker/ios/ViewManagers/MattermostKeyboardTrackerViewManager.mm +++ /dev/null @@ -1,127 +0,0 @@ -#import -#import -#import "RCTBridge.h" -#import "KeyboardTrackingView.h" - -@interface MattermostKeyboardTrackerViewManager : RCTViewManager -@property (nonatomic, nullable, strong) RCTDirectEventBlock keyboardWillShow; -@end - -@implementation RCTConvert (KeyboardTrackingScrollBehavior) -RCT_ENUM_CONVERTER(KeyboardTrackingScrollBehavior, (@{ @"KeyboardTrackingScrollBehaviorNone": @(KeyboardTrackingScrollBehaviorNone), - @"KeyboardTrackingScrollBehaviorScrollToBottomInvertedOnly": @(KeyboardTrackingScrollBehaviorScrollToBottomInvertedOnly), - @"KeyboardTrackingScrollBehaviorFixedOffset": @(KeyboardTrackingScrollBehaviorFixedOffset)}), - KeyboardTrackingScrollBehaviorNone, unsignedIntegerValue) -@end - -@implementation MattermostKeyboardTrackerViewManager - -RCT_EXPORT_MODULE(MattermostKeyboardTrackerView) - -#ifndef RCT_NEW_ARCH_ENABLED -- (UIView *)view -{ - return [[KeyboardTrackingView alloc] init]; -} -#endif - -RCT_CUSTOM_VIEW_PROPERTY(scrollBehavior, NSString, KeyboardTrackingView) { - KeyboardTrackingScrollBehavior behavior = [RCTConvert KeyboardTrackingScrollBehavior:json]; - [view setScrollBehavior:behavior]; -} - -RCT_CUSTOM_VIEW_PROPERTY(revealKeyboardInteractive, BOOL, KeyboardTrackingView) { - [view setRevealKeyboardInteractive:json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(manageScrollView, BOOL, KeyboardTrackingView) { - [view setManageScrollView:json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(requiresSameParentToManageScrollView, BOOL, KeyboardTrackingView) { - [view setRequiresSameParentToManageScrollView:json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(addBottomView, BOOL, KeyboardTrackingView) { - [view setAddBottomView:json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(scrollToFocusedInput, BOOL, KeyboardTrackingView) { - [view setScrollToFocusedInput:json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(allowHitsOutsideBounds, BOOL, KeyboardTrackingView) { - [view setAllowHitsOutsideBounds:json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(normalList, BOOL, KeyboardTrackingView) { - [view setNormalList:json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(viewInitialOffsetY, CGFloat, KeyboardTrackingView) { - [view setViewInitialOffsetY:[RCTConvert CGFloat: json]]; -} - -RCT_CUSTOM_VIEW_PROPERTY(scrollViewNativeID, NSString, KeyboardTrackingView) { - [view setScrollViewNativeID:json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(accessoriesContainerID, NSString, KeyboardTrackingView) { - [view setAccessoriesContainerID:json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(backgroundColor, NSString, KeyboardTrackingView) -{ - [view setBottomViewBackgroundColor:[RCTConvert UIColor:json]]; -} - -RCT_EXPORT_VIEW_PROPERTY(onKeyboardWillShow, RCTBubblingEventBlock) - -#pragma Commands - -RCT_EXPORT_METHOD(resetScrollView:(nonnull NSNumber *)reactTag scrollViewNativeID:(NSString *) scrollViewNativeID) { - [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { - KeyboardTrackingView *view = (KeyboardTrackingView *)viewRegistry[reactTag]; - if (!view || ![view isKindOfClass:[KeyboardTrackingView class]]) { - RCTLogError(@"Error: cannot find KeyboardTrackingView with tag #%@", reactTag); - return; - } - [view resetScrollView:scrollViewNativeID]; - }]; -} - -RCT_EXPORT_METHOD(pauseTracking:(nonnull NSNumber *)reactTag scrollViewNativeID:(NSString*)scrollViewNativeID) { - [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { - KeyboardTrackingView *view = (KeyboardTrackingView *)viewRegistry[reactTag]; - if (!view || ![view isKindOfClass:[KeyboardTrackingView class]]) { - RCTLogError(@"Error: cannot find KeyboardTrackingView with tag #%@", reactTag); - return; - } - [view pauseTracking:scrollViewNativeID]; - }]; -} - -RCT_EXPORT_METHOD(resumeTracking:(nonnull NSNumber *)reactTag scrollViewNativeID:(NSString*)scrollViewNativeID) { - [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { - KeyboardTrackingView *view = (KeyboardTrackingView *)viewRegistry[reactTag]; - if (!view || ![view isKindOfClass:[KeyboardTrackingView class]]) { - RCTLogError(@"Error: cannot find KeyboardTrackingView with tag #%@", reactTag); - return; - } - [view resumeTracking:scrollViewNativeID]; - }]; -} - -RCT_EXPORT_METHOD(scrollToStart:(nonnull NSNumber *)reactTag) -{ - [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { - KeyboardTrackingView *view = (KeyboardTrackingView *)viewRegistry[reactTag]; - if (!view || ![view isKindOfClass:[KeyboardTrackingView class]]) { - RCTLogError(@"Error: cannot find KeyboardTrackingView with tag #%@", reactTag); - return; - } - [view scrollToStart]; - }]; -} - -@end diff --git a/libraries/@mattermost/keyboard-tracker/ios/Views/KeyboardTrackingView.h b/libraries/@mattermost/keyboard-tracker/ios/Views/KeyboardTrackingView.h deleted file mode 100644 index 2c651f0b2d7..00000000000 --- a/libraries/@mattermost/keyboard-tracker/ios/Views/KeyboardTrackingView.h +++ /dev/null @@ -1,50 +0,0 @@ -#import -#import - -#import "ObservingInputAccessoryView.h" - -typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) { - KeyboardTrackingScrollBehaviorNone, - KeyboardTrackingScrollBehaviorScrollToBottomInvertedOnly, - KeyboardTrackingScrollBehaviorFixedOffset -}; - -@interface KeyboardTrackingView : UIView -{ - NSMapTable *_inputViewsMap; - ObservingInputAccessoryView *_observingInputAccessoryView; - UIView *_bottomView; - CGFloat _bottomViewHeight; -} - -@property (nonatomic) NSMutableDictionary* _Nullable rctScrollViewsArray; -@property (nonatomic, strong) UIScrollView * _Nullable scrollViewToManage; -@property (nonatomic) BOOL scrollIsInverted; -@property (nonatomic) BOOL revealKeyboardInteractive; -@property (nonatomic) BOOL isDraggingScrollView; -@property (nonatomic) BOOL manageScrollView; -@property (nonatomic) BOOL requiresSameParentToManageScrollView; -@property (nonatomic) NSUInteger deferedInitializeAccessoryViewsCount; -@property (nonatomic) CGFloat originalHeight; -@property (nonatomic) KeyboardTrackingScrollBehavior scrollBehavior; -@property (nonatomic) BOOL addBottomView; -@property (nonatomic) BOOL scrollToFocusedInput; -@property (nonatomic) BOOL allowHitsOutsideBounds; - -@property (nonatomic) BOOL normalList; -@property (nonatomic) NSString* _Nullable scrollViewNativeID; -@property (nonatomic) CGFloat initialOffsetY; -@property (nonatomic) CGFloat viewInitialOffsetY; -@property (nonatomic) BOOL initialOffsetIsSet; -@property (nonatomic) BOOL paused; -@property (nonatomic, strong) UIView* _Nullable accessoriesContainer; -@property (nonatomic) NSString* _Nullable accessoriesContainerID; -@property (nonatomic, copy, nullable) RCTDirectEventBlock onKeyboardWillShow; - --(void)setBottomViewBackgroundColor:(UIColor* _Nullable) color; --(void)resetScrollView:(NSString* _Nullable) scrollViewNativeID; --(void)pauseTracking:(NSString* _Nullable) scrollViewNativeID; --(void)resumeTracking:(NSString* _Nullable) scrollViewNativeID; --(void)scrollToStart; -@end - diff --git a/libraries/@mattermost/keyboard-tracker/ios/Views/KeyboardTrackingView.m b/libraries/@mattermost/keyboard-tracker/ios/Views/KeyboardTrackingView.m deleted file mode 100644 index ed6c062ef4c..00000000000 --- a/libraries/@mattermost/keyboard-tracker/ios/Views/KeyboardTrackingView.m +++ /dev/null @@ -1,622 +0,0 @@ -#import "KeyboardTrackingView.h" -#import -#import - -#import "UIResponder+FirstResponder.h" -#import "ObservingInputAccessoryView.h" - -#import - -NSUInteger const kInputViewKey = 101010; -NSUInteger const kMaxDeferedInitializeAccessoryViews = 15; -NSInteger const kTrackingViewNotFoundErrorCode = 1; -NSInteger const kBottomViewHeight = 34; - -@interface KeyboardTrackingView () -@end - -@implementation KeyboardTrackingView --(instancetype)init -{ - self = [super init]; - - if (self) - { - [self addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL]; - _inputViewsMap = [NSMapTable weakToWeakObjectsMapTable]; - _deferedInitializeAccessoryViewsCount = 0; - _rctScrollViewsArray = [[NSMutableDictionary alloc] init]; - - _observingInputAccessoryView = [ObservingInputAccessoryView new]; - _observingInputAccessoryView.delegate = self; - - _initialOffsetY = 0; - _initialOffsetIsSet = NO; - _viewInitialOffsetY = 0; - - _manageScrollView = YES; - _allowHitsOutsideBounds = NO; - _requiresSameParentToManageScrollView = YES; - - _bottomViewHeight = kBottomViewHeight; - - self.addBottomView = NO; - self.scrollToFocusedInput = NO; - self.paused = NO; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rctContentDidAppearNotification:) name:RCTContentDidAppearNotification object:nil]; - } - - return self; -} - --(RCTRootView*)getRootView -{ - UIView *view = self; - while (view.superview != nil) - { - view = view.superview; - if ([view isKindOfClass:[RCTRootView class]]) - break; - } - - if ([view isKindOfClass:[RCTRootView class]]) - { - return (RCTRootView*)view; - } - return nil; -} - -- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { - if (!_allowHitsOutsideBounds) { - return [super hitTest:point withEvent:event]; - } - - if (self.isHidden || self.alpha == 0 || self.clipsToBounds) { - return nil; - } - - UIView *subview = [super hitTest:point withEvent:event]; - if (subview == nil) { - NSArray* allSubviews = [self getBreadthFirstSubviewsForView:self]; - for (UIView *tmpSubview in allSubviews) { - CGPoint pointInSubview = [self convertPoint:point toView:tmpSubview]; - if ([tmpSubview pointInside:pointInSubview withEvent:event]) { - subview = tmpSubview; - break; - } - } - } - - return subview; -} - --(void)layoutSubviews -{ - [super layoutSubviews]; - [self updateBottomViewFrame]; -} - -- (void)initializeAccessoryViewsAndHandleInsets -{ - NSArray* allSubviews = [self getBreadthFirstSubviewsForView:[self getRootView]]; - - for (UIView* subview in allSubviews) - { - if(subview.nativeID) { - NSLog(@"self.accessoriesContainerID %@ %@", self.accessoriesContainerID, subview.nativeID); - } - - if (subview.nativeID && [subview.nativeID isEqualToString:self.accessoriesContainerID]) { - NSLog(@"SuperView ID: %@", subview.nativeID); - _accessoriesContainer = subview; - } - - if(_manageScrollView) - { - if(_scrollViewToManage == nil) - { - if([subview isKindOfClass:[RCTScrollView class]]) - { - RCTScrollView *scrollView = (RCTScrollView*)subview; - - if (subview.nativeID && [subview.nativeID isEqualToString:self.scrollViewNativeID]) { - [_rctScrollViewsArray setObject:scrollView forKey:subview.nativeID]; - _scrollViewToManage = scrollView.scrollView; - } - } - } - } - - if ([subview isKindOfClass:NSClassFromString(@"RCTTextField")]) - { - UITextField *textField = nil; - Ivar backedTextInputIvar = class_getInstanceVariable([subview class], "_backedTextInput"); - if (backedTextInputIvar != NULL) - { - textField = [subview valueForKey:@"_backedTextInput"]; - } - else if([subview isKindOfClass:[UITextField class]]) - { - textField = (UITextField*)subview; - } - [self setupTextField:textField]; - } - else if ([subview isKindOfClass:NSClassFromString(@"RCTUITextField")] && [subview isKindOfClass:[UITextField class]]) - { - [self setupTextField:(UITextField*)subview]; - } - else if ([subview isKindOfClass:NSClassFromString(@"RCTMultilineTextInputView")]) - { - [self setupTextView:[subview valueForKey:@"_backedTextInputView"]]; - } - else if ([subview isKindOfClass:NSClassFromString(@"RCTTextView")]) - { - UITextView *textView = nil; - Ivar backedTextInputIvar = class_getInstanceVariable([subview class], "_backedTextInput"); - if (backedTextInputIvar != NULL) - { - textView = [subview valueForKey:@"_backedTextInput"]; - } - else if([subview isKindOfClass:[UITextView class]]) - { - textView = (UITextView*)subview; - } - [self setupTextView:textView]; - } - else if ([subview isKindOfClass:NSClassFromString(@"RCTUITextView")] && [subview isKindOfClass:[UITextView class]]) - { - [self setupTextView:(UITextView*)subview]; - } - } - - for (RCTScrollView *scrollView in [_rctScrollViewsArray allValues]) - { - if(scrollView.scrollView == _scrollViewToManage) - { - [scrollView removeScrollListener:self]; - [scrollView addScrollListener:self]; - break; - } - } - -#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_10_3 - if (@available(iOS 11.0, *)) { - if (_scrollViewToManage != nil) { - _scrollViewToManage.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; - } - } -#endif - - [self _updateScrollViewInsets]; - - _originalHeight = _observingInputAccessoryView.height; - - [self addBottomViewIfNecessary]; -} - -- (void)resetScrollView:(NSString*) scrollViewNativeID { - for (RCTScrollView *scrollView in [_rctScrollViewsArray allValues]) - { - [scrollView removeScrollListener:self]; - } - [_rctScrollViewsArray removeAllObjects]; - _scrollViewToManage = nil; - _scrollViewNativeID = scrollViewNativeID; - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [self deferedInitializeAccessoryViewsAndHandleInsets]; - [self scrollToStart]; - }); -} - --(void)pauseTracking:(NSString*) scrollViewNativeID { - if ([self.scrollViewNativeID isEqualToString:scrollViewNativeID]) { - _observingInputAccessoryView.delegate = nil; - self.scrollViewToManage = nil; - self.accessoriesContainer = nil; - self.paused = YES; - } -} - --(void)resumeTracking:(NSString*) scrollViewNativeID { - if ([self.scrollViewNativeID isEqualToString:scrollViewNativeID]) { - self.paused = NO; - _observingInputAccessoryView.delegate = self; - [self deferedInitializeAccessoryViewsAndHandleInsets]; - } -} - -- (void)setupTextView:(UITextView*)textView -{ - if (textView != nil) - { - [textView setInputAccessoryView:_observingInputAccessoryView]; - [textView reloadInputViews]; - [_inputViewsMap setObject:textView forKey:@(kInputViewKey)]; - } -} - -- (void)setupTextField:(UITextField*)textField -{ - if (textField != nil) - { - [textField setInputAccessoryView:_observingInputAccessoryView]; - [textField reloadInputViews]; - [_inputViewsMap setObject:textField forKey:@(kInputViewKey)]; - } -} - --(void) deferedInitializeAccessoryViewsAndHandleInsets -{ - if(self.window == nil) - { - return; - } - - if (_observingInputAccessoryView.height == 0 && self.deferedInitializeAccessoryViewsCount < kMaxDeferedInitializeAccessoryViews) - { - self.deferedInitializeAccessoryViewsCount++; - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [self deferedInitializeAccessoryViewsAndHandleInsets]; - }); - } - else - { - dispatch_async(dispatch_get_main_queue(), ^{ - [self initializeAccessoryViewsAndHandleInsets]; - }); - } -} - -- (void)willMoveToWindow:(nullable UIWindow *)newWindow -{ - if (newWindow == nil && [ObservingInputAccessoryViewManager sharedInstance].activeObservingInputAccessoryView == _observingInputAccessoryView) - { - [ObservingInputAccessoryViewManager sharedInstance].activeObservingInputAccessoryView = nil; - } - else if (newWindow != nil) - { - [ObservingInputAccessoryViewManager sharedInstance].activeObservingInputAccessoryView = _observingInputAccessoryView; - } -} - --(void)didMoveToWindow -{ - [super didMoveToWindow]; - - self.deferedInitializeAccessoryViewsCount = 0; - - [self deferedInitializeAccessoryViewsAndHandleInsets]; -} - --(void)dealloc -{ - [self removeObserver:self forKeyPath:@"bounds"]; -} - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ - if (self.paused) { - return; - } - _observingInputAccessoryView.height = self.bounds.size.height; -} - -- (void)observingInputAccessoryViewKeyboardWillDisappear:(ObservingInputAccessoryView *)observingInputAccessoryView -{ - if (self.paused) { - return; - } - - _bottomViewHeight = [self getBottomSafeArea]; - [self updateBottomViewFrame]; -} - -- (NSArray*)getBreadthFirstSubviewsForView:(UIView*)view -{ - if(view == nil) - { - return nil; - } - - NSMutableArray *allSubviews = [NSMutableArray new]; - NSMutableArray *queue = [NSMutableArray new]; - - [allSubviews addObject:view]; - [queue addObject:view]; - - while ([queue count] > 0) { - UIView *current = [queue lastObject]; - [queue removeLastObject]; - - for (UIView *n in current.subviews) - { - [allSubviews addObject:n]; - [queue insertObject:n atIndex:0]; - } - } - return allSubviews; -} - -- (NSArray*)getAllReactSubviewsForView:(UIView*)view -{ - NSMutableArray *allSubviews = [NSMutableArray new]; - for (UIView *subview in view.reactSubviews) - { - [allSubviews addObject:subview]; - [allSubviews addObjectsFromArray:[self getAllReactSubviewsForView:subview]]; - } - return allSubviews; -} - -- (void)_updateScrollViewInsets -{ - if(self.scrollViewToManage != nil && !self.paused) - { - if (!_initialOffsetIsSet) { - self.initialOffsetY = self.scrollViewToManage.contentOffset.y; - _initialOffsetIsSet = YES; - } - - if (_observingInputAccessoryView.keyboardState != KeyboardStateWillHide && _observingInputAccessoryView.keyboardState != KeyboardStateHidden) { - [self.scrollViewToManage setContentOffset:CGPointMake(self.scrollViewToManage.contentOffset.x, self.initialOffsetY) animated:NO]; - } - - UIEdgeInsets insets = self.scrollViewToManage.contentInset; - CGFloat bottomSafeArea = [self getBottomSafeArea]; - CGFloat bottomInset = MAX(self.bounds.size.height, _observingInputAccessoryView.keyboardHeight + _observingInputAccessoryView.height); - - CGFloat originalBottomInset = self.scrollIsInverted ? insets.top : insets.bottom; - CGPoint originalOffset = self.scrollViewToManage.contentOffset; - CGFloat keyboardHeight = _observingInputAccessoryView.keyboardHeight; - - bottomInset += (keyboardHeight == 0 ? bottomSafeArea : 0); - if(self.scrollIsInverted) - { - insets.top = bottomInset; - } - else - { - insets.bottom = keyboardHeight; - } - self.scrollViewToManage.contentInset = insets; - - if(self.scrollBehavior == KeyboardTrackingScrollBehaviorScrollToBottomInvertedOnly && _scrollIsInverted) - { - BOOL firstTime = _observingInputAccessoryView.keyboardHeight == 0 && _observingInputAccessoryView.keyboardState == KeyboardStateHidden; - BOOL willOpen = _observingInputAccessoryView.keyboardHeight != 0 && _observingInputAccessoryView.keyboardState == KeyboardStateHidden; - BOOL isOpen = _observingInputAccessoryView.keyboardHeight != 0 && _observingInputAccessoryView.keyboardState == KeyboardStateShown; - if(firstTime || willOpen || (isOpen && !self.isDraggingScrollView)) - { - [self.scrollViewToManage setContentOffset:CGPointMake(self.scrollViewToManage.contentOffset.x, self.scrollViewToManage.contentOffset.y) animated:!firstTime]; - } - } - else if(self.scrollBehavior == KeyboardTrackingScrollBehaviorFixedOffset && !self.isDraggingScrollView) - { - CGFloat insetsDiff = (bottomInset - originalBottomInset) * (self.scrollIsInverted ? -1 : 1); - self.scrollViewToManage.contentOffset = CGPointMake(originalOffset.x, originalOffset.y + insetsDiff); - } - - CGFloat kHeight = _observingInputAccessoryView.keyboardHeight; - if (kHeight != 0 && (_observingInputAccessoryView.keyboardState == KeyboardStateShown || _observingInputAccessoryView.keyboardState == KeyboardStateWillShow)) { - kHeight -= (bottomSafeArea + _viewInitialOffsetY); - } - - CGFloat positionY = self.normalList ? 0 : kHeight; - CGRect frame = CGRectMake(self.scrollViewToManage.frame.origin.x, positionY, - self.scrollViewToManage.frame.size.width, self.scrollViewToManage.frame.size.height); - self.scrollViewToManage.frame = frame; - - if (self.accessoriesContainer) { - CGFloat containerPositionY = self.normalList ? 0 : kHeight; - self.accessoriesContainer.bounds = CGRectMake(self.accessoriesContainer.bounds.origin.x, containerPositionY, - self.accessoriesContainer.bounds.size.width, self.accessoriesContainer.bounds.size.height); - } - } -} - -#pragma mark - bottom view - --(void)setAddBottomView:(BOOL)addBottomView -{ - _addBottomView = addBottomView; - [self addBottomViewIfNecessary]; -} - --(void)addBottomViewIfNecessary -{ - if (self.addBottomView && _bottomView == nil) - { - _bottomView = [UIView new]; - [self addSubview:_bottomView]; - [self updateBottomViewFrame]; - } - else if (!self.addBottomView && _bottomView != nil) - { - [_bottomView removeFromSuperview]; - _bottomView = nil; - } -} - --(void)updateBottomViewFrame -{ - if (_bottomView != nil) - { - _bottomView.frame = CGRectMake(0, self.frame.size.height, self.frame.size.width, _bottomViewHeight); - } -} - --(void)setBottomViewBackgroundColor:(UIColor*) color { - if (_bottomView != nil) { - _bottomView.backgroundColor = color; - } -} - -#pragma mark - safe area - --(void)safeAreaInsetsDidChange -{ -#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_10_3 - if (@available(iOS 11.0, *)) { - [super safeAreaInsetsDidChange]; - } -#endif - [self updateTransformAndInsets]; -} - --(CGFloat)getBottomSafeArea -{ - CGFloat bottomSafeArea = 0; -#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_10_3 - if (@available(iOS 11.0, *)) { - bottomSafeArea = self.superview ? self.superview.safeAreaInsets.bottom : self.safeAreaInsets.bottom; - } -#endif - return bottomSafeArea; -} - -#pragma RCTRootView notifications - -- (void) rctContentDidAppearNotification:(NSNotification*)notification -{ - dispatch_async(dispatch_get_main_queue(), ^{ - if(notification.object == [self getRootView] && self->_manageScrollView && self->_scrollViewToManage == nil) - { - [self initializeAccessoryViewsAndHandleInsets]; - } - }); -} - -#pragma mark - ObservingInputAccessoryViewDelegate methods - --(void)updateTransformAndInsets -{ - if (self.paused) { - return; - } - - CGFloat bottomSafeArea = [self getBottomSafeArea]; - CGFloat accessoryTranslation = MIN(-bottomSafeArea, -(_observingInputAccessoryView.keyboardHeight - _viewInitialOffsetY)); - - if (_observingInputAccessoryView.keyboardHeight <= bottomSafeArea) { - _bottomViewHeight = [self getBottomSafeArea]; - } else if (_observingInputAccessoryView.keyboardState != KeyboardStateWillHide) { - _bottomViewHeight = 0; - } - [self updateBottomViewFrame]; - - self.transform = CGAffineTransformMakeTranslation(0, accessoryTranslation); - [self _updateScrollViewInsets]; -} - -- (void)performScrollToFocusedInput -{ - if (_scrollViewToManage != nil && self.scrollToFocusedInput) - { - UIResponder *currentFirstResponder = [UIResponder currentFirstResponder]; - if (currentFirstResponder != nil && [currentFirstResponder isKindOfClass:[UIView class]]) - { - UIView *reponderView = (UIView*)currentFirstResponder; - if ([reponderView isDescendantOfView:_scrollViewToManage]) - { - CGRect frame = [_scrollViewToManage convertRect:reponderView.frame fromView:reponderView]; - frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height + 20); - [_scrollViewToManage scrollRectToVisible:frame animated:NO]; - } - } - } -} - -- (void)observingInputAccessoryViewDidChangeFrame:(ObservingInputAccessoryView*)observingInputAccessoryView -{ - [self updateTransformAndInsets]; -} - --(void) observingInputAccessoryViewKeyboardWillAppear:(ObservingInputAccessoryView *)observingInputAccessoryView keyboardDelta:(CGFloat)keyboardDelta animationDuration:(double)animationDuration keyboardFrameEndHeight:(CGFloat)keyboardFrameEndHeight { - if (observingInputAccessoryView.keyboardHeight > 0) //prevent hiding the bottom view if an external keyboard is in use - { - _bottomViewHeight = 0; - [self updateBottomViewFrame]; - } - - [self performScrollToFocusedInput]; - _onKeyboardWillShow(@{ - @"trackingViewHeight": [NSNumber numberWithDouble:self.bounds.size.height], - @"keyboardHeight": [NSNumber numberWithDouble:[self getKeyboardHeight]], - @"contentTopInset": [NSNumber numberWithDouble:[self getScrollViewTopContentInset]], - @"animationDuration": [NSNumber numberWithDouble:animationDuration * 1000], - @"keyboardFrameEndHeight": [NSNumber numberWithDouble:keyboardFrameEndHeight], - }); -} - -#pragma mark - UIScrollViewDelegate methods - -- (void)scrollViewDidScroll:(UIScrollView *)scrollView -{ - if(_observingInputAccessoryView.keyboardState != KeyboardStateHidden || !self.revealKeyboardInteractive) - { - return; - } - - UIView *inputView = [_inputViewsMap objectForKey:@(kInputViewKey)]; - if (inputView != nil && scrollView.contentOffset.y * (self.scrollIsInverted ? -1 : 1) > (self.scrollIsInverted ? scrollView.contentInset.top : scrollView.contentInset.bottom) + 50 && ![inputView isFirstResponder]) - { - for (UIGestureRecognizer *gesture in scrollView.gestureRecognizers) - { - if([gesture isKindOfClass:[UIPanGestureRecognizer class]]) - { - gesture.enabled = NO; - gesture.enabled = YES; - } - } - - [inputView reactFocus]; - } -} - -- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView -{ - self.isDraggingScrollView = YES; - _initialOffsetIsSet = NO; - self.initialOffsetY = scrollView.contentOffset.y; -} - -- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset -{ - self.isDraggingScrollView = NO; -} - -- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate -{ - self.isDraggingScrollView = NO; - self.initialOffsetY = scrollView.contentOffset.y; -} - -- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { - self.initialOffsetY = scrollView.contentOffset.y; -} - -- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { - self.initialOffsetY = scrollView.contentOffset.y; -} - -- (CGFloat)getKeyboardHeight -{ - return _observingInputAccessoryView ? _observingInputAccessoryView.keyboardHeight : 0; -} - --(CGFloat)getScrollViewTopContentInset -{ - return (self.scrollViewToManage != nil) ? -self.scrollViewToManage.contentInset.top : 0; -} - --(void)scrollToStart -{ - if (self.scrollViewToManage != nil) - { - [self.scrollViewToManage setContentOffset:CGPointMake(self.scrollViewToManage.contentOffset.x, -self.scrollViewToManage.contentInset.top) animated:YES]; - } -} -@end diff --git a/libraries/@mattermost/keyboard-tracker/ios/Views/ObservingInputAccessoryView.h b/libraries/@mattermost/keyboard-tracker/ios/Views/ObservingInputAccessoryView.h deleted file mode 100644 index 08dd907bdfa..00000000000 --- a/libraries/@mattermost/keyboard-tracker/ios/Views/ObservingInputAccessoryView.h +++ /dev/null @@ -1,36 +0,0 @@ -#import - -typedef NS_ENUM(NSUInteger, KeyboardState) { - KeyboardStateHidden, - KeyboardStateWillShow, - KeyboardStateShown, - KeyboardStateWillHide -}; - -@class ObservingInputAccessoryView; - -@interface ObservingInputAccessoryViewManager : NSObject; -+(ObservingInputAccessoryViewManager*)sharedInstance; -@property (nonatomic, weak) ObservingInputAccessoryView *activeObservingInputAccessoryView; -@end - -@protocol ObservingInputAccessoryViewDelegate - -- (void)observingInputAccessoryViewDidChangeFrame:(ObservingInputAccessoryView*)observingInputAccessoryView; - -@optional - -- (void) observingInputAccessoryViewKeyboardWillAppear:(ObservingInputAccessoryView *)observingInputAccessoryView keyboardDelta:(CGFloat)keyboardDelta animationDuration:(double)animationDuration keyboardFrameEndHeight:(CGFloat)keyboardFrameEndHeight; -- (void)observingInputAccessoryViewKeyboardWillDisappear:(ObservingInputAccessoryView*)observingInputAccessoryView; - -@end - -@interface ObservingInputAccessoryView : UIView - -@property (nonatomic, weak) id delegate; - -@property (nonatomic) CGFloat height; -@property (nonatomic, readonly) CGFloat keyboardHeight; -@property (nonatomic, readonly) KeyboardState keyboardState; - -@end diff --git a/libraries/@mattermost/keyboard-tracker/ios/Views/ObservingInputAccessoryView.m b/libraries/@mattermost/keyboard-tracker/ios/Views/ObservingInputAccessoryView.m deleted file mode 100644 index 88be971db40..00000000000 --- a/libraries/@mattermost/keyboard-tracker/ios/Views/ObservingInputAccessoryView.m +++ /dev/null @@ -1,172 +0,0 @@ -#import "ObservingInputAccessoryView.h" - -@implementation ObservingInputAccessoryViewManager - -+(ObservingInputAccessoryViewManager*)sharedInstance -{ - static ObservingInputAccessoryViewManager *instance = nil; - static dispatch_once_t observingInputAccessoryViewManagerOnceToken = 0; - - dispatch_once(&observingInputAccessoryViewManagerOnceToken,^ - { - if (instance == nil) - { - instance = [ObservingInputAccessoryViewManager new]; - } - }); - - return instance; -} - -@end - -@implementation ObservingInputAccessoryView -{ - CGFloat _previousKeyboardHeight; -} - -- (instancetype)init -{ - self = [super init]; - - if(self) - { - self.userInteractionEnabled = NO; - self.translatesAutoresizingMaskIntoConstraints = NO; - self.autoresizingMask = UIViewAutoresizingFlexibleHeight; - - [self registerForKeyboardNotifications]; - } - - return self; -} - -- (void) registerForKeyboardNotifications -{ - NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; - [notificationCenter addObserver:self selector:@selector(_keyboardWillShowNotification:) name:UIKeyboardWillShowNotification object:nil]; - [notificationCenter addObserver:self selector:@selector(_keyboardDidShowNotification:) name:UIKeyboardDidShowNotification object:nil]; - [notificationCenter addObserver:self selector:@selector(_keyboardWillHideNotification:) name:UIKeyboardWillHideNotification object:nil]; - [notificationCenter addObserver:self selector:@selector(_keyboardDidHideNotification:) name:UIKeyboardDidHideNotification object:nil]; - [notificationCenter addObserver:self selector:@selector(_keyboardWillChangeFrameNotification:) name:UIKeyboardWillChangeFrameNotification object:nil]; -} - -- (void)willMoveToSuperview:(UIView *)newSuperview -{ - if (self.superview) - { - [self.superview removeObserver:self forKeyPath:@"center"]; - } - - if (newSuperview != nil) - { - [newSuperview addObserver:self forKeyPath:@"center" options:NSKeyValueObservingOptionNew context:nil]; - } - - [super willMoveToSuperview:newSuperview]; -} - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ - if ((object == self.superview) && ([keyPath isEqualToString:@"center"])) - { - CGFloat centerY = self.superview.center.y; - - if([keyPath isEqualToString:@"center"]) - { - centerY = [change[NSKeyValueChangeNewKey] CGPointValue].y; - } - - CGFloat boundsH = self.superview.bounds.size.height; - - _previousKeyboardHeight = _keyboardHeight; - _keyboardHeight = MAX(0, self.window.bounds.size.height - (centerY - boundsH / 2) - self.intrinsicContentSize.height); - - [_delegate observingInputAccessoryViewDidChangeFrame:self]; - } -} - --(void)dealloc -{ - [self.superview removeObserver:self forKeyPath:@"center"]; - - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (CGSize)intrinsicContentSize -{ - return CGSizeMake(self.bounds.size.width, _keyboardState == KeyboardStateWillShow || _keyboardState == KeyboardStateWillHide ? 0 : _height); -} - -- (void)setHeight:(CGFloat)height -{ - _height = height; - - [self invalidateIntrinsicContentSize]; -} - -- (void)_keyboardWillShowNotification:(NSNotification*)notification -{ - if (_keyboardState != KeyboardStateShown) { - _keyboardState = KeyboardStateWillShow; - - [self invalidateIntrinsicContentSize]; - - if([_delegate respondsToSelector:@selector(observingInputAccessoryViewKeyboardWillAppear:keyboardDelta:animationDuration:keyboardFrameEndHeight:)]) - { - NSDictionary *userInfo = notification.userInfo; - CGFloat delta = _keyboardHeight - _previousKeyboardHeight; - NSValue *frameEndValue = userInfo[UIKeyboardFrameEndUserInfoKey]; - CGFloat keyboardFrameEnd = [frameEndValue CGRectValue].size.height; - NSNumber *animationDurationValue = userInfo[UIKeyboardAnimationDurationUserInfoKey]; - NSTimeInterval animationDuration = [animationDurationValue doubleValue]; - - [_delegate observingInputAccessoryViewKeyboardWillAppear:self keyboardDelta:delta animationDuration:animationDuration keyboardFrameEndHeight:keyboardFrameEnd]; - } - } -} - -- (void)_keyboardDidShowNotification:(NSNotification*)notification -{ - if (_keyboardState != KeyboardStateShown) { - _keyboardState = KeyboardStateShown; - - [self invalidateIntrinsicContentSize]; - } -} - -- (void)_keyboardWillHideNotification:(NSNotification*)notification -{ - _keyboardState = KeyboardStateWillHide; - - [self invalidateIntrinsicContentSize]; - - if([_delegate respondsToSelector:@selector(observingInputAccessoryViewKeyboardWillDisappear:)]) - { - [_delegate observingInputAccessoryViewKeyboardWillDisappear:self]; - } -} - -- (void)_keyboardDidHideNotification:(NSNotification*)notification -{ - _keyboardState = KeyboardStateHidden; - - [self invalidateIntrinsicContentSize]; -} - -- (void)_keyboardWillChangeFrameNotification:(NSNotification*)notification -{ - if(self.window) - { - return; - } - - CGRect endFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; - _keyboardHeight = [UIScreen mainScreen].bounds.size.height - endFrame.origin.y; - - [_delegate observingInputAccessoryViewDidChangeFrame:self]; - - [self invalidateIntrinsicContentSize]; -} - -@end diff --git a/libraries/@mattermost/keyboard-tracker/mattermost-keyboard-tracker.podspec b/libraries/@mattermost/keyboard-tracker/mattermost-keyboard-tracker.podspec deleted file mode 100644 index 30c5b07cbbf..00000000000 --- a/libraries/@mattermost/keyboard-tracker/mattermost-keyboard-tracker.podspec +++ /dev/null @@ -1,23 +0,0 @@ -require "json" - -package = JSON.parse(File.read(File.join(__dir__, "package.json"))) - -Pod::Spec.new do |s| - s.name = "mattermost-keyboard-tracker" - s.version = package["version"] - s.summary = package["description"] - s.homepage = package["homepage"] - s.license = package["license"] - s.authors = package["author"] - - s.platforms = { :ios => min_ios_version_supported } - s.source = { :git => ".git", :tag => "#{s.version}" } - - s.source_files = "ios/**/*.{h,m,mm}" - - install_modules_dependencies(s) - - s.pod_target_xcconfig = { - "CLANG_CXX_LANGUAGE_STANDARD" => "c++20", - } -end diff --git a/libraries/@mattermost/keyboard-tracker/package.json b/libraries/@mattermost/keyboard-tracker/package.json deleted file mode 100644 index 3b2286f7aed..00000000000 --- a/libraries/@mattermost/keyboard-tracker/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "@mattermost/keyboard-tracker", - "version": "0.0.0", - "description": "component to track the keyboard", - "main": "src/index", - "codegenConfig": { - "name": "MattermostKeyboardTrackerSpec", - "type": "all", - "jsSrcsDir": "src", - "platforms": ["ios"] - }, - "author": "Mattermost, Inc.", - "license": "Apache 2.0", - "private": true, - "homepage": "#readme" -} diff --git a/libraries/@mattermost/keyboard-tracker/src/MattermostKeyboardTrackerViewNativeComponent.ts b/libraries/@mattermost/keyboard-tracker/src/MattermostKeyboardTrackerViewNativeComponent.ts deleted file mode 100644 index 167ad7c1f5e..00000000000 --- a/libraries/@mattermost/keyboard-tracker/src/MattermostKeyboardTrackerViewNativeComponent.ts +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands'; -import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; - -import type {ColorValue, HostComponent, ViewProps} from 'react-native'; -import type {BubblingEventHandler, Double, Float, WithDefault} from 'react-native/Libraries/Types/CodegenTypes'; - -type ScrollBehavior = 'KeyboardTrackingScrollBehaviorNone' | 'KeyboardTrackingScrollBehaviorScrollToBottomInvertedOnly' | 'KeyboardTrackingScrollBehaviorFixedOffset' - -export type NativeKeyboardTrackerProps = Readonly<{ - trackingViewHeight: Double; - keyboardHeight: Double; - contentTopInset: Double; - animationDuration: Double; - keyboardFrameEndHeight: Float; -}> - -export type KeyboardWillShowEventData = { - nativeEvent: { - trackingViewHeight: number; - keyboardHeight: number; - contentTopInset: number; - animationDuration: number; - keyboardFrameEndHeight: number; - }; -} - -export interface NativeProps extends ViewProps { - scrollBehavior?: WithDefault; - revealKeyboardInteractive?: boolean; - manageScrollView?: WithDefault; - requiresSameParentToManageScrollView?: WithDefault; - addBottomView?: boolean; - scrollToFocusedInput?: boolean; - allowHitsOutsideBounds?: boolean; - normalList?: boolean; - viewInitialOffsetY?: WithDefault; - scrollViewNativeID?: string; - accessoriesContainerID?: string; - backgroundColor?: ColorValue; - onKeyboardWillShow?: BubblingEventHandler; -} - -export type MattermostKeyboardTrackerNativeComponentType = HostComponent; - -interface NativeCommands { - readonly resetScrollView: ( - viewRef: React.ElementRef, - scrollViewNativeID: string, - ) => void; - readonly pauseTracking: ( - viewRef: React.ElementRef, - scrollViewNativeID: string, - ) => void; - readonly resumeTracking: ( - viewRef: React.ElementRef, - scrollViewNativeID: string, - ) => void; - readonly scrollToStart: ( - viewRef: React.ElementRef, - ) => void; -} - -export const Commands: NativeCommands = codegenNativeCommands({ - supportedCommands: ['resetScrollView', 'pauseTracking', 'resumeTracking', 'scrollToStart'], -}); - -export default codegenNativeComponent('MattermostKeyboardTrackerView'); diff --git a/libraries/@mattermost/keyboard-tracker/src/index.tsx b/libraries/@mattermost/keyboard-tracker/src/index.tsx deleted file mode 100644 index 88784a4ccde..00000000000 --- a/libraries/@mattermost/keyboard-tracker/src/index.tsx +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import React, {forwardRef, useCallback, useImperativeHandle, useRef} from 'react'; -import {DeviceEventEmitter} from 'react-native'; - -import MattermostKeyboardTrackerView, {Commands, type KeyboardWillShowEventData, type NativeProps} from './MattermostKeyboardTrackerViewNativeComponent'; - -export * from './MattermostKeyboardTrackerViewNativeComponent'; - -export type KeyboardTrackingViewRef = { - resetScrollView: (scrollViewNativeID: string) => void; - pauseTracking: (scrollViewNativeID: string) => void; - resumeTracking: (scrollViewNativeID: string) => void; - scrollToStart: () => void; -}; - -type Props = NativeProps & { - onKeyboardWillShow?: (e: KeyboardWillShowEventData) => void; -} - -const KeyboardTrackingView = forwardRef((props, ref) => { - const viewRef = useRef(null); - - useImperativeHandle(ref, () => ({ - resetScrollView(scrollViewNativeID: string) { - if (viewRef.current) { - Commands.resumeTracking(viewRef.current, scrollViewNativeID); - } - }, - pauseTracking(scrollViewNativeID: string) { - if (viewRef.current) { - Commands.pauseTracking(viewRef.current, scrollViewNativeID); - } - }, - resumeTracking(scrollViewNativeID: string) { - if (viewRef.current) { - Commands.resumeTracking(viewRef.current, scrollViewNativeID); - } - }, - scrollToStart() { - if (viewRef.current) { - Commands.scrollToStart(viewRef.current); - } - }, - })); - - const _onKeyboardShow = useCallback((e: KeyboardWillShowEventData) => { - DeviceEventEmitter.emit('MattermostKeyboardTrackerView', e); - props.onKeyboardWillShow?.(e); - }, [props.onKeyboardWillShow]); - - return ( - - ); -}); - -KeyboardTrackingView.displayName = 'KeyboardTrackingView'; - -export default KeyboardTrackingView; diff --git a/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt b/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt index d79ae9bef68..60c2921e7bd 100644 --- a/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt +++ b/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt @@ -2,6 +2,8 @@ package com.mattermost.rnutils import android.app.Activity import android.net.Uri +import android.view.WindowManager +import androidx.core.view.OnApplyWindowInsetsListener import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext @@ -13,6 +15,8 @@ import com.mattermost.rnutils.helpers.SaveDataTask import com.mattermost.rnutils.helpers.SplitView class RNUtilsModuleImpl(private val reactContext: ReactApplicationContext) { + private var customInsetsListener: OnApplyWindowInsetsListener? = null + companion object { const val NAME = "RNUtils" @@ -121,4 +125,20 @@ class RNUtilsModuleImpl(private val reactContext: ReactApplicationContext) { fun removeServerNotifications(serverUrl: String?) { serverUrl?.let { Notifications.removeServerNotifications(it) } } + + fun setSoftKeyboardToAdjustNothing() { + val currentActivity: Activity = reactContext.currentActivity ?: return + + currentActivity.runOnUiThread { + currentActivity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING) + } + } + + fun setSoftKeyboardToAdjustResize() { + val currentActivity: Activity = reactContext.currentActivity ?: return + + currentActivity.runOnUiThread { + currentActivity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) + } + } } diff --git a/libraries/@mattermost/rnutils/android/src/newarch/RNUtilsModule.kt b/libraries/@mattermost/rnutils/android/src/newarch/RNUtilsModule.kt index a5f8c369c26..20f3562693b 100644 --- a/libraries/@mattermost/rnutils/android/src/newarch/RNUtilsModule.kt +++ b/libraries/@mattermost/rnutils/android/src/newarch/RNUtilsModule.kt @@ -67,4 +67,12 @@ class RNUtilsModule(val reactContext: ReactApplicationContext) : NativeRNUtilsSp override fun removeServerNotifications(serverUrl: String?) { implementation.removeServerNotifications(serverUrl) } + + override fun setSoftKeyboardToAdjustResize() { + implementation.setSoftKeyboardToAdjustResize() + } + + override fun setSoftKeyboardToAdjustNothing() { + implementation.setSoftKeyboardToAdjustNothing() + } } diff --git a/libraries/@mattermost/rnutils/android/src/oldarch/RNUtilsModule.kt b/libraries/@mattermost/rnutils/android/src/oldarch/RNUtilsModule.kt index e28b0ba95b1..08558b78edc 100644 --- a/libraries/@mattermost/rnutils/android/src/oldarch/RNUtilsModule.kt +++ b/libraries/@mattermost/rnutils/android/src/oldarch/RNUtilsModule.kt @@ -98,4 +98,14 @@ class RNUtilsModule(context: ReactApplicationContext) : fun removeServerNotifications(serverUrl: String?) { implementation.removeServerNotifications(serverUrl) } + + @ReactMethod + fun setSoftKeyboardToAdjustResize() { + implementation.setSoftKeyboardToAdjustResize() + } + + @ReactMethod + fun setSoftKeyboardToAdjustNothing() { + implementation.setSoftKeyboardToAdjustNothing() + } } diff --git a/libraries/@mattermost/rnutils/ios/RNUtils.mm b/libraries/@mattermost/rnutils/ios/RNUtils.mm index 489d5f56756..9bec52197d6 100644 --- a/libraries/@mattermost/rnutils/ios/RNUtils.mm +++ b/libraries/@mattermost/rnutils/ios/RNUtils.mm @@ -123,6 +123,14 @@ - (NSDictionary *)constantsToExport { [self saveFile:filePath resolve:resolve reject:reject]; } +RCT_REMAP_METHOD(setSoftKeyboardToAdjustResize, setAdjustResize) { + [self setSoftKeyboardToAdjustResize]; +} + +RCT_REMAP_METHOD(setSoftKeyboardToAdjustNothing, setAdjustNothing) { + [self setSoftKeyboardToAdjustNothing]; +} + // Don't compile this code when we build for the old architecture. #ifdef RCT_NEW_ARCH_ENABLED - (std::shared_ptr)getTurboModule: @@ -216,6 +224,14 @@ - (void)saveFile:(NSString *)filePath resolve:(RCTPromiseResolveBlock)resolve re resolve(@""); } +-(void)setSoftKeyboardToAdjustResize { + // Do nothing as it does not apply to iOS +} + +-(void)setSoftKeyboardToAdjustNothing { + // Do nothing as it does not apply to iOS +} + #pragma helpers -(void)getNotifications:(RCTPromiseResolveBlock)resolve { [[NotificationManager shared] getDeliveredNotificationsWithCompletionHandler:^(NSArray * _Nonnull notifications) { diff --git a/libraries/@mattermost/rnutils/src/NativeRNUtils.ts b/libraries/@mattermost/rnutils/src/NativeRNUtils.ts index 7ab46c89ce2..c39f8dd234f 100644 --- a/libraries/@mattermost/rnutils/src/NativeRNUtils.ts +++ b/libraries/@mattermost/rnutils/src/NativeRNUtils.ts @@ -70,6 +70,9 @@ export interface Spec extends TurboModule { removeChannelNotifications(serverUrl: string, channelId: string): void; removeThreadNotifications(serverUrl: string, threadId: string): void; removeServerNotifications(serverUrl: string): void; + + setSoftKeyboardToAdjustResize(): void; + setSoftKeyboardToAdjustNothing(): void; } export default TurboModuleRegistry.getEnforcing('RNUtils'); diff --git a/package-lock.json b/package-lock.json index 616f26d4736..9e778ef840e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "mattermost-mobile", - "version": "2.22.0", + "version": "2.23.0", "hasInstallScript": true, "license": "Apache 2.0", "dependencies": { @@ -20,7 +20,6 @@ "@mattermost/calls": "github:mattermost/calls-common#030ff7c0a37ee9b0ccc5fae0b2ea9c0e1c08473f", "@mattermost/compass-icons": "0.1.45", "@mattermost/hardware-keyboard": "file:./libraries/@mattermost/hardware-keyboard", - "@mattermost/keyboard-tracker": "file:./libraries/@mattermost/keyboard-tracker", "@mattermost/react-native-emm": "1.5.0", "@mattermost/react-native-network-client": "1.7.3", "@mattermost/react-native-paste-input": "0.8.0", @@ -176,6 +175,7 @@ }, "libraries/@mattermost/keyboard-tracker": { "version": "0.0.0", + "extraneous": true, "license": "Apache 2.0" }, "libraries/@mattermost/rnshare": { @@ -5880,10 +5880,6 @@ "resolved": "libraries/@mattermost/hardware-keyboard", "link": true }, - "node_modules/@mattermost/keyboard-tracker": { - "resolved": "libraries/@mattermost/keyboard-tracker", - "link": true - }, "node_modules/@mattermost/react-native-emm": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@mattermost/react-native-emm/-/react-native-emm-1.5.0.tgz", diff --git a/package.json b/package.json index 4ecea74abe6..f57375c7598 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,6 @@ "@mattermost/calls": "github:mattermost/calls-common#030ff7c0a37ee9b0ccc5fae0b2ea9c0e1c08473f", "@mattermost/compass-icons": "0.1.45", "@mattermost/hardware-keyboard": "file:./libraries/@mattermost/hardware-keyboard", - "@mattermost/keyboard-tracker": "file:./libraries/@mattermost/keyboard-tracker", "@mattermost/react-native-emm": "1.5.0", "@mattermost/react-native-network-client": "1.7.3", "@mattermost/react-native-paste-input": "0.8.0", diff --git a/patches/react-native-navigation+7.40.1.patch b/patches/react-native-navigation+7.40.1.patch index 9d32075b3cf..9a4f8342325 100644 --- a/patches/react-native-navigation+7.40.1.patch +++ b/patches/react-native-navigation+7.40.1.patch @@ -296,6 +296,37 @@ index 834d734..3fc00c3 100644 want |= Typeface.ITALIC; } +diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java +index 3acc41d..ebc8d18 100644 +--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java ++++ b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java +@@ -7,6 +7,7 @@ import android.util.Log; + import android.view.View; + import android.view.ViewGroup; + import android.view.WindowInsets; ++import android.view.WindowManager; + + import com.reactnativenavigation.options.Options; + import com.reactnativenavigation.utils.LogKt; +@@ -100,6 +101,18 @@ public abstract class ChildController extends ViewControlle + } + + protected WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) { ++ Activity activity = getActivity(); ++ Insets ime = insets.getInsets(WindowInsetsCompat.Type.ime()); ++ if (activity != null) { ++ int softInputMode = activity.getWindow().getAttributes().softInputMode; ++ if (softInputMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING && !isRoot()) { ++ view.setPadding(ime.left, ime.top, ime.right, 0); ++ return WindowInsetsCompat.CONSUMED; ++ } ++ } ++ if (!isRoot()) { ++ view.setPadding(0, 0, 0, 0); ++ } + return insets; + } + diff --git a/node_modules/react-native-navigation/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/ReactGateway.java b/node_modules/react-native-navigation/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/ReactGateway.java index 035ec31..630b8d4 100644 --- a/node_modules/react-native-navigation/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/ReactGateway.java diff --git a/test/intl-test-helper.tsx b/test/intl-test-helper.tsx index 159295c14ca..e39cc111643 100644 --- a/test/intl-test-helper.tsx +++ b/test/intl-test-helper.tsx @@ -7,6 +7,7 @@ import React, {type ReactElement} from 'react'; import {IntlProvider} from 'react-intl'; import {SafeAreaProvider} from 'react-native-safe-area-context'; +import {ExtraKeyboardProvider} from '@context/extra_keyboard'; import ServerUrlProvider from '@context/server'; import {ThemeContext, getDefaultThemeByAppearance} from '@context/theme'; import {getTranslations} from '@i18n'; @@ -63,7 +64,9 @@ export function renderWithEverything(ui: ReactElement, {locale = 'en', database, > - {children} + + {children} + From 7cb2ee75b364c8073a0d84039d7067c2ec593781 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Fri, 29 Nov 2024 12:50:09 +0800 Subject: [PATCH 23/36] Fix bottomSheet bottom insets (#8331) * Fix bottomSheet bottom insets * fix search team picker on android * ux review * fix footer padding for message priority modal on iPad --- .../announcement_banner/announcement_banner.tsx | 5 +---- .../channel_bookmarks/add_bookmark.tsx | 15 +++++++++------ .../channel_bookmark/channel_bookmark.tsx | 6 ++---- .../channel_bookmarks/channel_bookmarks.tsx | 5 +++-- .../file_options/mobile_options.tsx | 5 +---- app/components/files_search/file_results.tsx | 1 - .../markdown/at_mention/at_mention.tsx | 6 ++---- .../markdown/markdown_code_block/index.tsx | 6 ++---- .../markdown/markdown_image/index.tsx | 6 ++---- .../markdown/markdown_latex_block/index.tsx | 6 ++---- .../markdown/markdown_link/markdown_link.tsx | 6 ++---- .../quick_actions/camera_quick_action/index.tsx | 6 ++---- .../post_priority_action/index.tsx | 2 +- .../body/acknowledgements/acknowledgements.tsx | 10 ++++++---- .../users_list/user_list_item.tsx | 2 +- .../post_list/post/body/failed/index.tsx | 6 ++---- .../post_list/post/body/reactions/reactions.tsx | 2 +- app/components/post_list/post/footer/footer.tsx | 2 +- app/components/selected_users/index.tsx | 15 +++++++-------- app/components/team_list/index.tsx | 1 + app/components/user_avatars_stack/index.tsx | 14 +++++++++----- app/components/user_list/index.tsx | 6 +++--- .../calls/components/audio_device_button.tsx | 4 +--- app/products/calls/hooks.ts | 4 ++-- .../calls/screens/call_screen/call_screen.tsx | 8 +++----- .../screens/host_controls/host_controls.tsx | 8 +++----- .../participants_list/participants_list.tsx | 5 +---- app/screens/bottom_sheet/button.tsx | 2 +- app/screens/bottom_sheet/index.tsx | 5 +++++ .../browse_channels/channel_dropdown.tsx | 4 +--- .../intro/direct_channel/member/member.tsx | 2 +- app/screens/channel/header/bookmarks.tsx | 2 +- app/screens/channel/header/header.tsx | 12 +++++++----- .../components/bookmark_detail.tsx | 2 +- app/screens/channel_files/header.tsx | 5 +---- app/screens/channel_info/extra/extra.tsx | 14 +++----------- .../title/public_private/public_private.tsx | 12 ++---------- .../create_direct_message.tsx | 13 ++++++------- app/screens/custom_status/custom_status.tsx | 2 +- .../components/profile_image_picker.tsx | 6 ++---- .../emoji_picker/picker/footer/index.tsx | 4 ++-- .../components/options/user_presence/index.tsx | 6 ++---- .../categories_list/header/header.tsx | 6 ++---- app/screens/home/channel_list/servers/index.tsx | 6 ++---- app/screens/home/search/results/header.tsx | 5 +---- app/screens/home/search/team_picker_icon.tsx | 6 ++---- .../manage_channel_members.tsx | 2 +- app/screens/post_options/post_options.tsx | 6 ++---- .../post_options/reaction_bar/reaction_bar.tsx | 2 +- app/screens/post_priority_picker/footer.tsx | 4 ++-- .../post_priority_picker.tsx | 16 +++++++--------- app/screens/thread_options/thread_options.tsx | 4 +--- app/screens/user_profile/user_profile.tsx | 12 +++++++----- app/utils/helpers.test.ts | 5 ++--- app/utils/helpers.ts | 5 ++--- patches/@gorhom+bottom-sheet+4.6.4.patch | 17 +++++++++++++++++ 56 files changed, 155 insertions(+), 194 deletions(-) create mode 100644 patches/@gorhom+bottom-sheet+4.6.4.patch diff --git a/app/components/announcement_banner/announcement_banner.tsx b/app/components/announcement_banner/announcement_banner.tsx index 70fbd87bcf2..242a803a6ab 100644 --- a/app/components/announcement_banner/announcement_banner.tsx +++ b/app/components/announcement_banner/announcement_banner.tsx @@ -9,7 +9,6 @@ import { View, } from 'react-native'; import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; -import {useSafeAreaInsets} from 'react-native-safe-area-context'; import {dismissAnnouncement} from '@actions/local/systems'; import CompassIcon from '@components/compass_icon'; @@ -85,7 +84,6 @@ const AnnouncementBanner = ({ const intl = useIntl(); const serverUrl = useServerUrl(); const height = useSharedValue(0); - const {bottom} = useSafeAreaInsets(); const theme = useTheme(); const [visible, setVisible] = useState(false); const style = getStyle(theme); @@ -107,7 +105,6 @@ const AnnouncementBanner = ({ const snapPoint = bottomSheetSnapPoint( 1, SNAP_POINT_WITHOUT_DISMISS + (allowDismissal ? DISMISS_BUTTON_HEIGHT : 0), - bottom, ); bottomSheet({ @@ -117,7 +114,7 @@ const AnnouncementBanner = ({ snapPoints: [1, snapPoint], theme, }); - }, [theme.sidebarHeaderTextColor, intl.locale, renderContent, allowDismissal, bottom]); + }, [theme.sidebarHeaderTextColor, intl.locale, renderContent, allowDismissal]); const handleDismiss = useCallback(() => { dismissAnnouncement(serverUrl, bannerText); diff --git a/app/components/channel_bookmarks/add_bookmark.tsx b/app/components/channel_bookmarks/add_bookmark.tsx index 2a71f4a6895..32bc929579c 100644 --- a/app/components/channel_bookmarks/add_bookmark.tsx +++ b/app/components/channel_bookmarks/add_bookmark.tsx @@ -3,14 +3,13 @@ import React, {useCallback} from 'react'; import {useIntl} from 'react-intl'; -import {Alert, View, type Insets} from 'react-native'; -import {useSafeAreaInsets} from 'react-native-safe-area-context'; +import {Alert, Platform, View, type Insets} from 'react-native'; import Button from '@components/button'; import {ITEM_HEIGHT} from '@components/option_item'; import {Screens} from '@constants'; import {useTheme} from '@context/theme'; -import {TITLE_HEIGHT} from '@screens/bottom_sheet'; +import {BOTTOM_SHEET_ANDROID_OFFSET, TITLE_HEIGHT} from '@screens/bottom_sheet'; import {bottomSheet, showModal} from '@screens/navigation'; import {bottomSheetSnapPoint} from '@utils/helpers'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; @@ -81,7 +80,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => ({ const AddBookmark = ({bookmarksCount, channelId, currentUserId, canUploadFiles, showLarge}: Props) => { const theme = useTheme(); const {formatMessage} = useIntl(); - const {bottom} = useSafeAreaInsets(); const styles = getStyleSheet(theme); const onPress = useCallback(() => { @@ -126,14 +124,19 @@ const AddBookmark = ({bookmarksCount, channelId, currentUserId, canUploadFiles, /> ); + let height = bottomSheetSnapPoint(1, (2 * ITEM_HEIGHT)) + TITLE_HEIGHT; + if (Platform.OS === 'android') { + height += BOTTOM_SHEET_ANDROID_OFFSET; + } + bottomSheet({ title: formatMessage({id: 'channel_info.add_bookmark', defaultMessage: 'Add a bookmark'}), renderContent, - snapPoints: [1, bottomSheetSnapPoint(1, (2 * ITEM_HEIGHT), bottom) + TITLE_HEIGHT], + snapPoints: [1, height], theme, closeButtonId: 'close-channel-quick-actions', }); - }, [bottom, bookmarksCount, canUploadFiles, currentUserId, channelId, theme]); + }, [bookmarksCount, canUploadFiles, formatMessage, theme, channelId, currentUserId]); const button = (