From 75e04ce1adbf64f734a9ea42b2a31e08c7be3673 Mon Sep 17 00:00:00 2001 From: Nick Mallory Date: Fri, 24 Jul 2020 15:11:03 -0400 Subject: [PATCH 001/140] use TouchableNativeFeedback for external link buttons --- src/components/ButtonSingleLine.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/ButtonSingleLine.tsx b/src/components/ButtonSingleLine.tsx index d46bab286..2b4340b1d 100644 --- a/src/components/ButtonSingleLine.tsx +++ b/src/components/ButtonSingleLine.tsx @@ -16,6 +16,7 @@ import {Box} from './Box'; import {Icon, IconName} from './Icon'; import {Text} from './Text'; import {Ripple} from './Ripple'; +import {TouchableNativeFeedback} from 'react-native-gesture-handler'; export interface ButtonSingleLineProps { text?: string; @@ -67,7 +68,7 @@ export const ButtonSingleLine = ({ justifyContent="center" // eslint-disable-next-line react-native/no-inline-styles style={{ - backgroundColor: Platform.OS === 'ios' ? color : 'transparent', + backgroundColor: Platform.OS === 'ios' || externalLink ? color : 'transparent', minHeight: height, borderWidth, borderColor: buttonColor, @@ -120,7 +121,11 @@ export const ButtonSingleLine = ({ }; if (Platform.OS === 'android') { - return ( + return externalLink ? ( + + {content} + + ) : ( Date: Fri, 24 Jul 2020 15:27:15 -0400 Subject: [PATCH 002/140] Use TouchableOpacity for external links --- src/components/ButtonSingleLine.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/ButtonSingleLine.tsx b/src/components/ButtonSingleLine.tsx index 2b4340b1d..4b1856db2 100644 --- a/src/components/ButtonSingleLine.tsx +++ b/src/components/ButtonSingleLine.tsx @@ -11,12 +11,10 @@ import { } from 'react-native'; import {Theme, palette} from 'shared/theme'; import {useI18n} from 'locale'; - import {Box} from './Box'; import {Icon, IconName} from './Icon'; import {Text} from './Text'; import {Ripple} from './Ripple'; -import {TouchableNativeFeedback} from 'react-native-gesture-handler'; export interface ButtonSingleLineProps { text?: string; @@ -122,9 +120,15 @@ export const ButtonSingleLine = ({ if (Platform.OS === 'android') { return externalLink ? ( - + {content} - + ) : ( Date: Fri, 24 Jul 2020 15:30:55 -0400 Subject: [PATCH 003/140] lint --- src/components/ButtonSingleLine.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ButtonSingleLine.tsx b/src/components/ButtonSingleLine.tsx index 4b1856db2..ec0b04ccd 100644 --- a/src/components/ButtonSingleLine.tsx +++ b/src/components/ButtonSingleLine.tsx @@ -11,6 +11,7 @@ import { } from 'react-native'; import {Theme, palette} from 'shared/theme'; import {useI18n} from 'locale'; + import {Box} from './Box'; import {Icon, IconName} from './Icon'; import {Text} from './Text'; From 24dfc6a0032704b3d7278d96431bcb33c837e03d Mon Sep 17 00:00:00 2001 From: Piotr Isajew Date: Sun, 26 Jul 2020 12:04:44 +0200 Subject: [PATCH 004/140] Set flags on BRProcessingTask requests submitted by TSBackgroundFetch This will ensure that exposure-notification background processing tasks will be submitted as requiring network connectivity and not needing external power. --- ios/CovidShield/AppDelegate.m | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/ios/CovidShield/AppDelegate.m b/ios/CovidShield/AppDelegate.m index 0e81cfb80..7b2f8e5f4 100644 --- a/ios/CovidShield/AppDelegate.m +++ b/ios/CovidShield/AppDelegate.m @@ -8,6 +8,8 @@ #import #import +#import +#import #if DEBUG #import @@ -28,6 +30,8 @@ static void InitializeFlipper(UIApplication *application) { } #endif +static void patchBGTaskSubmission(); + @implementation AppDelegate // Required to register for notifications @@ -99,6 +103,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( } // [REQUIRED] Register BackgroundFetch + patchBGTaskSubmission(); [[TSBackgroundFetch sharedInstance] didFinishLaunching]; // Define UNUserNotificationCenter @@ -124,3 +129,25 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge } @end +#pragma mark Patch for BackgroundTask submission +static IMP _BGTaskScheduler_submitTaskRequest_orig = NULL; + +static BOOL preSubmitTaskHook(id me, SEL selector, BGTaskRequest *req, NSError **perr) { + if([req isKindOfClass: [BGProcessingTaskRequest class]] && + [req.identifier isEqualToString: @"app.covidshield.exposure-notification"]) { + ((BGProcessingTaskRequest*)req).requiresNetworkConnectivity = YES; + ((BGProcessingTaskRequest*)req).requiresExternalPower = NO; + } + + return ((BOOL (*)(id, SEL, BGTaskRequest*, NSError**))*_BGTaskScheduler_submitTaskRequest_orig)(me, selector, req, perr); +} + + +static void patchBGTaskSubmission() { + SEL submitSelector = @selector(submitTaskRequest:error:); + Class schedulerClass = objc_getClass("BGTaskScheduler"); + if(schedulerClass == nil) return; + + _BGTaskScheduler_submitTaskRequest_orig = class_replaceMethod(schedulerClass, submitSelector, (IMP)preSubmitTaskHook, "B@:@@"); +} + From ef6de3d2fde469b1ef0a607b809b2d4a4eb06d2e Mon Sep 17 00:00:00 2001 From: Tim Arney Date: Mon, 27 Jul 2020 13:43:01 -0400 Subject: [PATCH 005/140] package update --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 08d19a92f..d21600916 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "react-native-markdown-display": "^6.1.0", "react-native-permissions": "^2.1.4", "react-native-reanimated": "^1.8.0", - "react-native-safe-area-context": "^3.0.2", + "react-native-safe-area-context": "^3.1.1", "react-native-screens": "^2.7.0", "react-native-secure-key-store": "^2.0.7", "react-native-snap-carousel": "^3.9.0", diff --git a/yarn.lock b/yarn.lock index 59fa951cf..adf255bd4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7231,10 +7231,10 @@ react-native-reanimated@^1.8.0: dependencies: fbjs "^1.0.0" -react-native-safe-area-context@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-3.0.2.tgz#95dd7e56bc89bcc4f3f7bb5fada30c98420328b2" - integrity sha512-x3yVMsxwe9GyvIkv0Q5jy2CWYN7VO0/CJTFGG5kSiMo8FFTQJbWtuWGANFqxDzEH5NEV7/SfK+qTgAh931KyUw== +react-native-safe-area-context@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-3.1.1.tgz#9b04d1154766e6c1132030aca8f4b0336f561ccd" + integrity sha512-Iqb41OT5+QxFn0tpTbbHgz8+3VU/F9OH2fTeeoU7oZCzojOXQbC6sp6mN7BlsAoTKhngWoJLMcSosL58uRaLWQ== react-native-screens@^2.7.0: version "2.7.0" From adea3ef396e5423d2fde5937ff5feff8cdedcd51 Mon Sep 17 00:00:00 2001 From: Tim Arney Date: Mon, 27 Jul 2020 13:52:06 -0400 Subject: [PATCH 006/140] pod update --- ios/Podfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 634d52800..23d049276 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -243,7 +243,7 @@ PODS: - React - react-native-netinfo (5.9.5): - React - - react-native-safe-area-context (3.0.2): + - react-native-safe-area-context (3.1.1): - React - react-native-splash-screen (3.2.0): - React @@ -545,7 +545,7 @@ SPEC CHECKSUMS: React-jsinspector: 512e560d0e985d0e8c479a54a4e5c147a9c83493 react-native-config: 313a1306066289211579b9655eb81d9a565462d0 react-native-netinfo: a53b00d949b6456913aaf507d9dba90c4008c611 - react-native-safe-area-context: b11a34881faac509cad5578726c98161ad4d275c + react-native-safe-area-context: 344b969c45af3d8464d36e8dea264942992ef033 react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 React-RCTActionSheet: f41ea8a811aac770e0cc6e0ad6b270c644ea8b7c React-RCTAnimation: 49ab98b1c1ff4445148b72a3d61554138565bad0 From ce1eb2bde8b188646b81bac728a0786d04543db0 Mon Sep 17 00:00:00 2001 From: James Eberhardt Date: Mon, 27 Jul 2020 15:30:08 -0400 Subject: [PATCH 007/140] Patch `async-storage` to mark every file with `NSURLIsExcludedFromBackupKey` attribute. --- package.json | 2 +- ...native-community+async-storage+1.9.0.patch | 33 +++++++++++++++++++ yarn.lock | 2 +- 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 patches/@react-native-community+async-storage+1.9.0.patch diff --git a/package.json b/package.json index 08d19a92f..205fe739d 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "fastlane:android:local": "bundle exec fastlane android local" }, "dependencies": { - "@react-native-community/async-storage": "^1.9.0", + "@react-native-community/async-storage": "1.9.0", "@react-native-community/masked-view": "^0.1.10", "@react-native-community/netinfo": "^5.9.5", "@react-native-community/push-notification-ios": "^1.3.0", diff --git a/patches/@react-native-community+async-storage+1.9.0.patch b/patches/@react-native-community+async-storage+1.9.0.patch new file mode 100644 index 000000000..ea10a08cb --- /dev/null +++ b/patches/@react-native-community+async-storage+1.9.0.patch @@ -0,0 +1,33 @@ +diff --git a/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m b/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m +index 2d72ac7..c4de715 100644 +--- a/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m ++++ b/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m +@@ -417,6 +417,14 @@ - (NSDictionary *)_writeManifest:(NSMutableArray **)errors + NSError *error; + NSString *serialized = RCTJSONStringify(_manifest, &error); + [serialized writeToFile:RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()) atomically:YES encoding:NSUTF8StringEncoding error:&error]; ++ ++ // Added by COVID Alert: Ensure all files are excluded from iCloud Backup. ++ if (!error){ ++ NSString *filePath = RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()); ++ NSURL *fileURL = [NSURL fileURLWithPath:filePath]; ++ [fileURL setResourceValue:[NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; ++ } ++ + NSDictionary *errorOut; + if (error) { + errorOut = RCTMakeError(@"Failed to write manifest file.", error, nil); +@@ -481,6 +489,13 @@ - (NSDictionary *)_writeEntry:(NSArray *)entry changedManifest:(BOOL + return nil; + } + [value writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error]; ++ ++ // Added by COVID Alert: Ensure all files are excluded from iCloud Backup. ++ if (!error){ ++ NSURL *fileURL = [NSURL URLWithString:filePath]; ++ [fileURL setResourceValue:[NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; ++ } ++ + [RCTGetCache() setObject:value forKey:key cost:value.length]; + if (error) { + errorOut = RCTMakeError(@"Failed to write value.", error, @{@"key": key}); diff --git a/yarn.lock b/yarn.lock index 59fa951cf..ae9302f12 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1043,7 +1043,7 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= -"@react-native-community/async-storage@^1.9.0": +"@react-native-community/async-storage@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/async-storage/-/async-storage-1.9.0.tgz#af26a8879bd2987970fbbe81a9623851d29a56f1" integrity sha512-TlGMr02JcmY4huH1P7Mt7p6wJecosPpW+09+CwCFLn875IhpRqU2XiVA+BQppZOYfQdHUfUzIKyCBeXOlCEbEg== From 5469d163eb855243fba236b9b4d0f8fb253f3795 Mon Sep 17 00:00:00 2001 From: Henry Tao Date: Mon, 27 Jul 2020 15:37:06 -0400 Subject: [PATCH 008/140] Add code coverage --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 08d19a92f..704987273 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "run-android": "react-native run-android --variant debug", "run-ios": "react-native run-ios", "start": "react-native start --reset-cache", - "test": "jest", + "test": "jest --coverage", "tsc": "tsc", "fastlane:ios:beta": "bundle exec fastlane ios beta", "fastlane:ios:local": "bundle exec fastlane ios local", From 06ac0c77cc176b478bfc2f2aff7faa62d32b46a7 Mon Sep 17 00:00:00 2001 From: James Eberhardt Date: Mon, 27 Jul 2020 16:15:03 -0400 Subject: [PATCH 009/140] A cleaner implementation in the `_writeManifest` function. --- ...native-community+async-storage+1.9.0.patch | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/patches/@react-native-community+async-storage+1.9.0.patch b/patches/@react-native-community+async-storage+1.9.0.patch index ea10a08cb..f50421255 100644 --- a/patches/@react-native-community+async-storage+1.9.0.patch +++ b/patches/@react-native-community+async-storage+1.9.0.patch @@ -1,23 +1,25 @@ diff --git a/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m b/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m -index 2d72ac7..c4de715 100644 +index 2d72ac7..bf72515 100644 --- a/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m +++ b/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m -@@ -417,6 +417,14 @@ - (NSDictionary *)_writeManifest:(NSMutableArray **)errors +@@ -417,10 +417,16 @@ - (NSDictionary *)_writeManifest:(NSMutableArray **)errors NSError *error; NSString *serialized = RCTJSONStringify(_manifest, &error); [serialized writeToFile:RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()) atomically:YES encoding:NSUTF8StringEncoding error:&error]; -+ -+ // Added by COVID Alert: Ensure all files are excluded from iCloud Backup. -+ if (!error){ -+ NSString *filePath = RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()); -+ NSURL *fileURL = [NSURL fileURLWithPath:filePath]; -+ [fileURL setResourceValue:[NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; -+ } + NSDictionary *errorOut; if (error) { errorOut = RCTMakeError(@"Failed to write manifest file.", error, nil); -@@ -481,6 +489,13 @@ - (NSDictionary *)_writeEntry:(NSArray *)entry changedManifest:(BOOL + RCTAppendError(errorOut, errors); ++ } else { ++ // Added by COVID Alert: Ensure all files are excluded from iCloud Backup. ++ NSString *filePath = RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()); ++ NSURL *fileURL = [NSURL fileURLWithPath:filePath]; ++ [fileURL setResourceValue:[NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; + } + return errorOut; + } +@@ -481,6 +487,13 @@ - (NSDictionary *)_writeEntry:(NSArray *)entry changedManifest:(BOOL return nil; } [value writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error]; From f30867e5dd975d83fad32e267d8c5b06cbb85a80 Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Mon, 27 Jul 2020 15:26:05 -0600 Subject: [PATCH 010/140] updated content on error screen ios 14 users will see --- src/locale/translations/en.json | 1 + src/locale/translations/fr.json | 1 + src/locale/translations/index.js | 2 +- src/screens/home/views/UnknownProblemView.tsx | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/locale/translations/en.json b/src/locale/translations/en.json index c007d9a31..df084ec28 100644 --- a/src/locale/translations/en.json +++ b/src/locale/translations/en.json @@ -82,6 +82,7 @@ }, "UnknownProblem": { "Title": "Something went wrong", + "Body": "It looks like your phone cannot support COVID Alert.", "CTA": "Get Help" }, "NoConnectivity": "COVID Alert is offline", diff --git a/src/locale/translations/fr.json b/src/locale/translations/fr.json index 8072f8991..19c597afc 100644 --- a/src/locale/translations/fr.json +++ b/src/locale/translations/fr.json @@ -173,6 +173,7 @@ "TurnOnBluetooth": "Activez Bluetooth", "UnknownProblem": { "Title": "Une erreur s’est produite", + "Body": "Il semble que votre téléphone ne puisse pas prendre en charge Alerte COVID.", "CTA": "Trouver de l’aide" } }, diff --git a/src/locale/translations/index.js b/src/locale/translations/index.js index 897881de8..3d78842d9 100644 --- a/src/locale/translations/index.js +++ b/src/locale/translations/index.js @@ -1 +1 @@ -export default JSON.parse("{\"en\":{\"Home\":{\"NoExposureDetected\":{\"AllSetTitle\":\"You're all set\",\"RegionCovered\":{\"Title\":\"No exposure detected\",\"Body\":\"You have not been near anyone who reported a COVID-19 diagnosis through this app.\",\"GuidanceUrl\":\"https://www.canada.ca/en/public-health/services/publications/diseases-conditions/covid-19-how-to-isolate-at-home.html\",\"AllSetBody\":\"Your phone is now running Bluetooth to collect codes from nearby phones.\"},\"NoRegion\":{\"Title\":\"No exposure detected\",\"Body\":\"You have not been near anyone who reported a COVID-19 diagnosis through this app.\\n\\nHowever, in some provinces and territories, people cannot yet report COVID-19 diagnoses through this app.\",\"AllSetBody\":\"We’ll let you know as soon as people outside Ontario can report a diagnosis through COVID Alert.\\n\\nIt’s still helpful to keep COVID Alert on.\\n\\nThat way, when people are able to report a diagnosis, you’ll find out if you were near them.\"},\"RegionNotCovered\":{\"Title\":\"No reporting yet in your area\",\"Body\":\"People in your province or territory are not yet able to report a COVID-19 diagnosis through this app.\\n\\nIt’s still helpful to turn COVID Alert on. That way, when people are able to report a diagnosis, you’ll be notified if you were near them.\",\"GuidanceUrl\":\"https://www.canada.ca/en/public-health/services/publications/diseases-conditions/covid-19-how-to-isolate-at-home.html\",\"AllSetBody\":\"We’ll let you know as soon as people in your area can report a diagnosis through COVID Alert.\\n\\nIt’s still helpful to keep COVID Alert on.\\n\\nThat way, when people are able to report a diagnosis, you’ll find out if you were near them.\"}},\"ExposureDetected\":{\"CA\":{\"Title\":\"You’ve been exposed in the last 14 days\",\"Title2\":\"What now?\",\"Body1\":\"Someone you’ve been near has reported a COVID-19 diagnosis through the app. You were close to them for 15 minutes or more.\",\"Body2\":\"You’re at risk of being infected. Watch yourself carefully for symptoms, and \",\"Body3\":\"consider self-isolating for 14 days.\",\"HowToIsolateCTA\":\"How to self-isolate\"},\"ON\":{\"Title\":\"You’ve been exposed in the last 14 days\",\"Title2\":\"What now?\",\"Body1\":\"Someone you’ve been near has reported a COVID-19 diagnosis through the app. You were close to them for 15 minutes or more.\",\"Body2\":\"You’re at risk of being infected.\",\"HowToIsolateCTA\":\"How to self-isolate\"}},\"ChooseRegionCTA\":\"Choose province or territory\",\"How\":\"Diagnosed with COVID-19?\",\"CTA\":\"What to do next\",\"HowUrl\":\"https://www.canada.ca/\",\"DiagnosedView\":{\"Title\":\"Thanks for helping fight COVID-19\",\"Body1\":{\"One\":\"Tomorrow, you’ll get your last notification asking permission to upload any new random codes your phone sent out.\",\"Other\":\"For the next {number} days, you’ll get a daily notification asking permission to upload any new random codes your phone sent out.\"},\"Body2\":\"You do not have to agree, even if you agreed the day before.\",\"Body3\":\"If you’re worried about your symptoms, get medical care as soon as you can. Take care of yourself and your family during this time.\",\"TipTitle\":\"TIP: \",\"TipBody\":\"You can prepare for your call from Public Health through the test results website. \",\"TipLinkText\":\"Test results website\",\"TipURL\":\"https://covid19results.ehealthontario.ca:4443/login\"},\"SymptomTrackerUrl\":\"https://ca.thrive.health/covid19app/action/88a5e9a7-db9e-487b-bc87-ce35035f8e5c?from=/home&navigateTo=/tracker/complete\",\"DiagnosedShareView\":{\"Title\":\"Upload random codes\",\"Body1\":\"Thanks for helping slow the spread!\",\"Body2\":\"Reminder: \",\"Body3\":\"To help keep people safe, you need to upload your random codes every day, especially if you have to leave your home.\",\"ButtonCTA\":\"Upload your random codes\"},\"BluetoothDisabled\":\"Bluetooth is off\",\"EnableBluetoothCTA\":\"You need to turn on Bluetooth in your phone’s settings so COVID Alert can work.\",\"TurnOnBluetooth\":\"Turn on Bluetooth\",\"EnDisabled\":{\"Title\":\"COVID Alert is off\",\"Body1\":\"You did not enable COVID Alert. The app needs your permission to work.\",\"CTA\":\"Enable COVID Alert\",\"AndroidTitle2\":\"Not sure about turning on Location?\",\"AndroidBody1\":\"You need to have Location turned on for COVID Alert to work. To use Bluetooth scanning, Android phones need Location setting on for all apps.\",\"AndroidBody2a\":\"Despite that, COVID Alert has \",\"AndroidBody2b\":\"no way of knowing where you are. \",\"AndroidBody2c\":\"You can check the app’s permissions in your phone’s settings. You’ll see it does not have permission for location services.\"},\"FrameworkUnavailable\":{\"Title\":\"Something went wrong\",\"Body\":\"COVID Alert is not supported by your phone’s operating system.\\n\\nMake sure your operating system is up to date.\\n\\nIf you have an Android phone, try updating your Google Play Services.\",\"CTA\":\"Get Help\"},\"UnknownProblem\":{\"Title\":\"Something went wrong\",\"CTA\":\"Get Help\"},\"NoConnectivity\":\"COVID Alert is offline\",\"NoConnectivityDetailed\":\"COVID Alert only checks for exposure if your phone is connected to the Internet.\",\"AppName\":\"COVID Alert\",\"ExternalLinkHint\":\"Opens in a new window\",\"LastCheckedMinutes\":{\"One\":\"Last checked {number} minute ago\",\"Other\":\"Last checked {number} minutes ago\"},\"LastCheckedHours\":{\"One\":\"Last checked {number} hour ago\",\"Other\":\"Last checked {number} hours ago\"},\"LastCheckedDays\":{\"One\":\"Last checked {number} day ago\",\"Other\":\"Last checked {number} days ago\"}},\"OverlayClosed\":{\"SystemStatus\":\"COVID Alert is \",\"SystemStatusOn\":\"active\",\"SystemStatusOff\":\"off\",\"NotificationStatus\":\"Notifications are \",\"NotificationStatusOff\":\"off\",\"TapPrompt\":\"Tap for menu\"},\"OverlayOpen\":{\"BluetoothCardBody\":\"You need to turn on Bluetooth in your phone’s settings so COVID Alert can work.\",\"BluetoothCardAction\":\"Turn on Bluetooth\",\"EnterCodeCardTitle\":\"Diagnosed with COVID-19?\",\"EnterCodeCardBody\":\"You need a one-time key to let people know they’ve been exposed.\",\"EnterCodeCardAction\":\"Enter your one-time key\",\"EnterCodeCardTitleDiagnosed\":\"You’re helping stop COVID-19\",\"EnterCodeCardBodyDiagnosed\":\"Thank you for doing your part to slow the spread. \",\"EnterCodeCardDiagnosedCountdown\":{\"One\":\"{number} day left!\",\"Other\":\"{number} days left!\"},\"NotificationCardStatus\":\"Notifications are off\",\"NotificationCardStatusOff\":\"OFF\",\"NotificationCardBody\":\"You will not receive notifications if you've been near anyone who has reported a COVID-19 diagnosis. Finding out potential exposures right away is essential to slowing the spread of COVID-19.\",\"NotificationCardAction\":\"Turn on notifications\",\"ExposureNotificationCardStatus\":\"Exposure notifications are \",\"ExposureNotificationCardBody\":\"COVID Alert cannot notify you as soon as it learns of a possible exposure. Finding out right away is essential to slowing the spread of COVID-19.\",\"ExposureNotificationCardAction\":\"Turn on exposure notifications\",\"NoConnectivityCardAction\":\"COVID Alert is offline\",\"NoConnectivityCardBody\":\"Connect to the Internet to notify people or check for exposures.\"},\"Info\":{\"CheckSymptoms\":\"Check symptoms\",\"SymptomsUrl\":\"https://ca.thrive.health/covid19/en\",\"TellAFriend\":\"Share app\",\"LearnMore\":\"How it works\",\"Help\":\"Help\",\"HelpUrl\":\"https://www.canada.ca/en/public-health/services/diseases/coronavirus-disease-covid-19/covid-alert/help.html\",\"GetCode\":\"Get a one-time key\",\"ChangeLanguage\":\"Change language\",\"ChangeRegion\":\"Change province or territory\",\"Privacy\":\"How it protects your privacy\",\"SettingsTitle\":\"Settings\",\"InformationTitle\":\"About COVID Alert\"},\"Landing\":{\"En\":\"English\",\"Fr\":\"Français\",\"AltText\":\"Illustration of 8 people enjoying a public space. There’s a person with a walking cane, a person in a wheelchair, a person wearing a hijab, several people of colour, and a representation of gender diversity.\",\"CanadaAltText\":\"Symbol of the Government of Canada\"},\"LanguageSelect\":{\"Title\":\"Language\",\"En\":\"English (Canada)\",\"Fr\":\"Français (Canada)\",\"PtBR\":\"Portuguese (Brazil)\",\"EnShort\":\"English\",\"FrShort\":\"Français\",\"PtBRShort\":\"Portuguese (Brazil)\",\"Close\":\"Close\"},\"Tutorial\":{\"step-1Title\":\"How COVID Alert works\",\"step-1AltText\":\"A hand-drawn illustration of a mobile phone in a pocket, sending and receiving signals.\",\"step-1\":\"The app runs in the background and will not interrupt your activities.\\n\\nWhenever you’re near someone else with COVID Alert, both phones exchange random codes every 5 minutes.\\n\\nThe random codes change often and cannot be used to identify you. \",\"step-2Title\":\"What’s an exposure?\",\"step-2AltText\":\"A hand-drawn illustration of 2 mobile phones side-by-side with a timer clock connecting both phones.\",\"step-2\":\"The app estimates how near people are by the strength of Bluetooth signals.\\n\\nIf you’re closer than 2 metres for more than 15 minutes, the app will record an exposure.\",\"step-3Title\":\"Getting a positive test\",\"step-3AltText\":\"A hand-drawn illustration of a mobile phone uploading a numeric code to a cloud.\",\"step-3\":\"If someone with the app is diagnosed with COVID-19, they can choose to upload the random codes their phone sent. The codes go into a central server.\\n\\nThe server only gets the codes. It does not get any information about the person.\",\"step-4Title\":\"Looking for exposures\",\"step-4AltText\":\"A hand-drawn illustration of a mobile phone uploading a numeric code to a cloud.\",\"step-4\":\"Every day, whenever it has an Internet connection, your phone will get a list of the random codes from people who reported a diagnosis.\\n\\nIf it finds codes that match, the app notifies you that you've been exposed and explains what to do next.\",\"ActionBack\":\"Back\",\"ActionNext\":\"Next\",\"ActionEnd\":\"Done\",\"Close\":\"Close\"},\"Sharing\":{\"Title\":\"Tell your friends about COVID Alert\",\"SubTitle\":\"Every person using COVID Alert helps to slow the spread of COVID-19. Sharing this app will not share any of your personal information.\",\"Platform-messages\":\"Share to Messages\",\"Platform-instagram\":\"Share to Instagram\",\"More\":\"More apps\",\"Message\":\"Join me in helping to slow the spread of COVID-19. Download the COVID Alert app: https://covidshield.app\",\"InstagramImageUrl\":\"https://user-images.githubusercontent.com/5274722/84658989-b9ba6b00-aee4-11ea-84d4-d840527467b4.png\",\"Close\":\"Close\"},\"Onboarding\":{\"Step\":\"Step\",\"Of\":\"of\",\"ActionNext\":\"Next\",\"ActionEndSkip\":\"Skip\",\"ActionEnd\":\"Done\",\"ActionBack\":\"Back\",\"Start\":{\"Title\":\"Together, let’s stop the spread of COVID-19\",\"ImageAltText\":\"A hand-drawn illustration with lots of different people in it. Dotted lines show their paths crossing and leading to a smartphone below.\",\"Body1\":\"COVID Alert helps us break the cycle of infection. The app can let people know of possible exposures before any symptoms appear. \",\"Body2\":\"That way, we can take care of ourselves and protect our communities.\"},\"WhatItsNot\":{\"Title\":\"What COVID Alert does not do\",\"ImageAltText\":\"A hand-drawn illustration with many houses and a high-rise building on a curving street. Small message bubbles appear above each home.\",\"Body1\":\"The app will not tell you in the moment if you’re currently near someone who’s been diagnosed.\",\"Body2\":\"It will not tell you about outbreaks in your community.\"},\"Anonymous\":{\"Title\":\"Your privacy is protected\",\"ImageAltText\":\"A hand-drawn illustration of shaded glasses and hat to go incognito. Above the hat, a location pin icon is crossed out.\",\"Body1\":\"COVID Alert **does not use GPS** or track your location.\",\"Body2\":\"It has **no way of knowing**:\",\"Bullet1\":\"Your location.\",\"Bullet2\":\"Your name or address.\",\"Bullet3\":\"Your phone's contacts.\",\"Bullet4\":\"Your health information.\",\"Bullet5\":\"The health information of anyone you’re near.\"},\"HowItWorks\":{\"Title\":\"How it works\",\"ImageAltText\":\"A hand-drawn illustration of 3 mobile phones sending out random codes via bluetooth.\",\"Body1\":\"The app uses Bluetooth to exchange random codes with nearby phones.\",\"Body2\":\"Every day, it checks a list of random codes from people who tell the app they tested positive.\",\"Body3\":\"If you’ve had close contact with one of those people in the past 14 days, you’ll get a notification.\",\"HowItWorksCTA\":\"Learn more about how it works\"},\"PartOf\":{\"Title\":\"One part of public health\",\"ImageAltText\":\"A hand-drawn illustration of different ways of fighting COVID-19, including hand sanitizer, handwashing, face mask and the COVID Alert app.\",\"Body1\":\"COVID Alert is just one part of the public health effort to stop the spread of COVID-19.\",\"Body2\":\"Follow all public health guidelines in your area.\",\"Body3\":\"COVID Alert does not replace medical advice. If you get sick, contact your doctor or other healthcare provider.\"},\"Permissions\":{\"Title\":\"The app will now ask your permission\",\"ImageAltText\":\"A hand-drawn illustration of a mobile phone displaying a dialogue box with a red X and a green check mark on the screen.\",\"Body1\":\"**Allow the app** to start logging random codes or “random IDs” when you’re near other phones. The app will access the date, duration and signal strength related to the random codes, but they never leave your phone.\",\"Body2\":\"You’ll also need to **let the app send you notifications**.\",\"PrivacyButtonCTA\":\"Learn more about privacy\"}},\"Privacy\":{\"Title\":\"Privacy policy\",\"Close\":\"Close\"},\"ThankYou\":{\"Title\":\"Thank you for helping\",\"Body\":\"Exposure notifications are on. You will receive a message if COVID Alert detects that you've been near someone who has reported a COVID-19 diagnosis.\",\"Dismiss\":\"Dismiss\"},\"DataUpload\":{\"Cancel\":\"Cancel\",\"InfoSmall\":\"Your random codes will not be uploaded unless you give permission in the next step.\",\"ShareToast\":\"Random codes uploaded successfully\",\"Step1\":{\"Title\":\"Let people know they may have been exposed\",\"Body1a\":\"Step 1. \",\"Body1b\":\"Enter the one-time key you got when you were diagnosed.\",\"Body2a\":\"Step 2. \",\"Body2b\":\"Agree that COVID Alert can let people know they were exposed.\",\"Body3a\":\"Step 3. \",\"Body3b\":\"Allow your phone to share your random codes.\",\"Body4a\":\"Nobody will get any information about you \",\"Body4b\":\"or the time you were near them.\",\"CTA\":\"Next\",\"NoCode\":\"Need a one-time key?\"},\"FormView\":{\"Title\":\"Enter your one-time key\",\"Body\":\"Enter the key you got when you were diagnosed.\",\"Action\":\"Submit\",\"InputLabel\":\"COVID Alert key\",\"ErrorTitle\":\"One-time key not recognized\",\"ErrorBody\":\"Your key could not be recognized. Please try again.\",\"ErrorAction\":\"OK\"},\"ConsentView\":{\"Title\":\"Now you can upload your codes\",\"Body1\":\"Your phone will ask your permission to upload your random codes or “random IDs” from the past 14 days.\",\"Body2a\":\"Nobody will get any information about you \",\"Body2b\":\"or the time you were near them.\",\"Body3\":\"You can help slow the spread of COVID-19 if you agree.\",\"Action\":\"Agree\",\"ErrorTitle\":\"Random codes could not be uploaded\",\"ErrorBody\":\"You did not give permission.\",\"ErrorAction\":\"OK\"},\"NoCode\":{\"NoRegion\":{\"Title\":\"You skipped choosing province or territory\",\"Body\":\"In some provinces and territories, people cannot yet report a COVID-19 diagnosis through this app.\\n\\nTo find out if you can get a one-time key, you need to choose your area.\",\"ChooseRegionCTA\":\"Choose province or territory\"},\"RegionCovered\":{\"ON\":{\"Title\":\"Get a one-time key\",\"Body\":\"If you’ve tested positive in Ontario:\",\"Body2\":\"Go to the COVID-19 Test Results Website and enter your details.\",\"Body3\":\"Review your test results.\",\"Body4\":\"Get the one-time key.\",\"Body5\":\"Come back here and enter the key.\",\"CTA\":\"Go to COVID-19 Test Results Website\",\"Link\":\"https://covid19results.ehealthontario.ca:4443/\"}},\"RegionNotCovered\":{\"Title\":\"No reporting yet in your area\",\"Body\":\"People in your area cannot yet get a one-time key.\\n\\nYou will not be able to let people know they were exposed. But you can still self-isolate for 14 days, and:\",\"Body2\":\"Keep your community safe.\",\"Body3\":\"Protect people and pets you live with.\",\"Body4\":\"Take care of yourself.\"}}},\"Notification\":{\"ExposedMessageTitle\":\"You’ve been exposed\",\"ExposedMessageBody\":\"You’ve had close contact with someone who reported a COVID-19 diagnosis through the app. Learn more about what to do next.\",\"OffMessageTitle\":\"COVID Alert is off\",\"OffMessageBody\":\"Turn on COVID Alert to get notified if you've been near someone who has reported a COVID-19 diagnosis.\",\"DailyUploadNotificationTitle\":\"Upload new random codes\",\"DailyUploadNotificationBody\":\"Help slow the spread of COVID-19 and upload your new random codes.\"},\"Partners\":{\"Label\":\"Developed in partnership with\"},\"BottomSheet\":{\"Collapse\":\"Close\",\"OnStatus\":\"COVID Alert is on, Tap for more information\",\"OffStatus\":\"COVID Alert is off, Tap for more information\"},\"RegionLanding\":{\"Title\":\"Choose your province or territory\",\"Body1\":\"Provincial and territorial governments are working to support COVID Alert across Canada.\",\"Body2\":\"In some places, people cannot yet report a COVID-19 diagnosis through this app.\",\"RegionSelectBtn\":\"Choose province or territory\"},\"RegionPicker\":{\"Title\":\"Where do you live? (optional)\",\"SettingsTitle\":\"Province or territory\",\"Close\":\"Close\",\"Body\":\"Choose your region to check if you can report a diagnosis through this app.\\n\\nYour region will never be shared with anyone.\",\"Skip\":\"Skip\",\"GetStarted\":\"Get started\",\"Optional\":\"* Optional\",\"AB\":\"Alberta\",\"BC\":\"British Columbia\",\"MB\":\"Manitoba\",\"NB\":\"New Brunswick\",\"NL\":\"Newfoundland and Labrador\",\"NT\":\"Northwest Territories\",\"NS\":\"Nova Scotia\",\"NU\":\"Nunavut\",\"ON\":\"Ontario\",\"PE\":\"Prince Edward Island\",\"QC\":\"Quebec\",\"SK\":\"Saskatchewan\",\"YT\":\"Yukon\",\"None\":\"Prefer not to say\"},\"RegionalGuidance\":{\"CA\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://ca.thrive.health/covid19/en\"},\"AB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://myhealth.alberta.ca/Journey/COVID-19/Pages/PubAsympIsolate.aspx\"},\"BC\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://bc.thrive.health/covid19/en\"},\"MB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://sharedhealthmb.ca/covid19/screening-tool/\"},\"NB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www2.gnb.ca/content/gnb/en/departments/ocmoh/cdc/content/respiratory_diseases/coronavirus/coronavirusexposure.html#/app/symptom-checker/guides/399/what-to-do\"},\"NL\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://nl.thrive.health/covid19/en\"},\"NT\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.gov.nt.ca/covid-19/en/services/nwt-online-covid-19-self-assessment-tool\"},\"NS\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://novascotia.ca/coronavirus/when-to-seek-help/#if-exposed\"},\"NU\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://nu.thrive.health/covid19/en\"},\"ON\":{\"CTA\":\"Find out what to do next\",\"URL\":\"https://ontario.ca/covidalert-exposed\"},\"PE\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.princeedwardisland.ca/en/information/health-and-wellness/covid-19-self-isolation\"},\"QC\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.quebec.ca/en/health/health-issues/a-z/2019-coronavirus/instructions-for-people-who-have-been-in-contact-with-a-confirmed-case-of-covid-19/\"},\"SK\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.saskatchewan.ca/government/health-care-administration-and-provider-resources/treatment-procedures-and-guidelines/emerging-public-health-issues/2019-novel-coronavirus/covid-19-self-assessment\"},\"YT\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://service.yukon.ca/en/covid-19-self-assessment/\"}},\"HowToIsolate\":{\"Title\":\"How to self-isolate\",\"Intro\":\"Try your best to:\",\"Body1\":\"Stay home unless it’s to get medical care.\",\"Body2\":\"Avoid public transportation like buses or taxis.\",\"Body3\":\"Ask for help to get groceries and supplies dropped off at your door.\",\"Body4\":\"Stay in a separate room and use a separate bathroom from others in your home, if possible.\",\"Body5\":\"Wear a mask safely any time you cannot take the above actions.\"},\"A11yList\":{\"Start\":\"List start\",\"End\":\"List end\",\"Bullet\":\"Bullet\"}},\"fr\":{\"Home\":{\"NoExposureDetected\":{\"AllSetTitle\":\"Vous voilà prêt!\",\"RegionCovered\":{\"Title\":\"Aucune exposition détectée\",\"Body\":\"Vous n’avez été près d’aucune personne ayant signalé un diagnostic de COVID-19 avec cette application.\",\"GuidanceUrl\":\"https://www.canada.ca/fr/sante-publique/services/publications/maladies-et-affections/covid-19-comment-isoler-chez-soi.html\",\"AllSetBody\":\"Votre téléphone utilise maintenant Bluetooth pour collecter les codes provenant des téléphones voisins.\"},\"NoRegion\":{\"Title\":\"Aucune exposition détectée\",\"Body\":\"Vous n’avez été près d’aucune personne ayant signalé un diagnostic de COVID-19 avec cette application.\\n\\nToutefois, dans certaines provinces et certains territoires, on ne peut pas encore signaler de diagnostics de COVID-19 avec cette application.\",\"AllSetBody\":\"Nous vous informerons dès que les personnes en dehors de l’Ontario peuvent signaler des diagnostics avec Alerte COVID.\\n\\nIl est tout de même utile de garder Alerte COVID activée.\\n\\nDe cette façon, vous pourrez être avisé dès que les personnes dont vous avez été près signalent un diagnostic.\"},\"RegionNotCovered\":{\"Title\":\"Pas encore de signalement dans votre région\",\"Body\":\"Les personnes de votre province ou territoire ne peuvent pas encore signaler de diagnostics de COVID-19 avec cette application.\\n\\nIl est tout de même utile d’activer Alerte COVID. Quand les personnes pourront signaler un diagnostic, vous serez ainsi avisé si jamais vous avez été près d’elles.\",\"GuidanceUrl\":\"https://www.canada.ca/fr/sante-publique/services/publications/maladies-et-affections/covid-19-comment-isoler-chez-soi.html\",\"AllSetBody\":\"Nous vous informerons dès que les personnes de votre région peuvent signaler un diagnostic avec Alerte COVID.\\n\\nIl est tout de même utile de garder Alerte COVID activée.\\n\\nDe cette façon, vous pourrez être avisé dès que les personnes dont vous avez été près signalent un diagnostic.\"}},\"ExposureDetected\":{\"CA\":{\"Title\":\"Vous avez été exposé au cours des 14 derniers jours\",\"Title2\":\"Que faire maintenant?\",\"Body1\":\"Vous avez été près d’une personne qui a signalé un diagnostic de COVID-19 avec l’application. Votre proximité a duré 15 minutes ou plus.\",\"Body2\":\"Vous êtes à risque d’être infecté. Surveillez attentivement vos symptômes et \",\"Body3\":\"pensez à vous isoler pendant 14 jours.\",\"HowToIsolateCTA\":\"Comment vous isoler\"},\"ON\":{\"Title\":\"Vous avez été exposé au cours des 14 derniers jours\",\"Title2\":\"Que faire maintenant?\",\"Body1\":\"Vous avez été près d’une personne qui a signalé un diagnostic de COVID-19 avec l’application. Votre proximité a duré 15 minutes ou plus.\",\"Body2\":\"Vous êtes à risque d’être infecté.\",\"HowToIsolateCTA\":\"Comment vous isoler\"}},\"ChooseRegionCTA\":\"Sélectionnez une province ou un territoire\",\"How\":\"Diagnosed with COVID-19?\",\"CTA\":\"Prochaines étapes\",\"HowUrl\":\"https://www.canada.ca/\",\"DiagnosedView\":{\"Title\":\"Merci d’aider à lutter contre la COVID\",\"Body1\":{\"One\":\"Tomorrow, you’ll get your last notification asking permission to upload any new random codes your phone sent out.\",\"Other\":\"Au cours des {number} prochains jours, vous recevrez une notification quotidienne vous demandant l’autorisation de téléverser tout nouveau code aléatoire émis par votre téléphone.\"},\"Body2\":\"Vous n’êtes pas tenu d’accepter, même si vous avez accepté le jour d’avant.\",\"Body3\":\"Si vos symptômes vous inquiètent, cherchez à obtenir des soins médicaux dès que vous le pouvez. Prenez soin de vous et de votre famille pendant ce temps.\",\"TipTitle\":\"CONSEIL : \",\"TipBody\":\"Vous pouvez vous préparer pour l’appel de la Santé publique sur le site Web des résultats du test.\",\"TipLinkText\":\"Site des résultats du test\",\"TipURL\":\"https://covid19results.ehealthontario.ca:4443/login\"},\"SymptomTrackerUrl\":\"https://ca.thrive.health/covid19app/action/88a5e9a7-db9e-487b-bc87-ce35035f8e5c?from=/home&navigateTo=/tracker/complete\",\"DiagnosedShareView\":{\"Title\":\"Téléverser les codes aléatoires\",\"Body1\":\"Merci d’aider à ralentir la propagation de la COVID-19!\",\"Body2\":\"Rappel : \",\"Body3\":\"Pour contribuer à la sécurité des autres, vous devez téléverser vos codes aléatoires tous les jours, surtout si vous avez à sortir de la maison.\",\"ButtonCTA\":\"Téléverser vos codes aléatoires\"},\"BluetoothDisabled\":\"Bluetooth désactivé\",\"EnableBluetoothCTA\":\"Vous devez activer la fonction Bluetooth dans les paramètres de votre téléphone pour qu’Alerte COVID fonctionne.\",\"TurnOnBluetooth\":\"Activez Bluetooth\",\"EnDisabled\":{\"Title\":\"Alerte COVID est désactivée\",\"Body1\":\"Vous n’avez pas activé Alerte COVID. L’application a besoin de votre autorisation pour fonctionner.\",\"CTA\":\"Activer Alerte COVID\",\"AndroidTitle2\":\"Vous hésitez à activer la localisation?\",\"AndroidBody1\":\"Il faut activer la localisation pour qu’Alerte COVID fonctionne. Avec Android, la recherche Bluetooth n’est possible que si la localisation est activée pour toutes les applications.\",\"AndroidBody2a\":\"Malgré cela, Alerte COVID \",\"AndroidBody2b\":\"ne peut pas savoir où vous êtes. \",\"AndroidBody2c\":\"Vous pouvez vous en assurer en vérifiant les autorisations d’Alerte COVID dans les paramètres de votre téléphone. La localisation n’est pas autorisée.\"},\"FrameworkUnavailable\":{\"Title\":\"Une erreur s’est produite\",\"Body\":\"Alerte COVID n’est pas prise en charge par le système d’exploitation de votre téléphone.\\n\\nVérifiez que votre système d’exploitation est à jour.\\n\\nSi vous avez un téléphone Android, pensez à mettre les services Google Play à jour.\",\"CTA\":\"Trouver de l’aide\"},\"UnknownProblem\":{\"Title\":\"Une erreur s’est produite\",\"CTA\":\"Trouver de l’aide\"},\"NoConnectivity\":\"Alerte COVID est hors ligne\",\"NoConnectivityDetailed\":\"Alerte COVID vérifie s’il y a des expositions seulement quand votre téléphone est connecté à Internet.\",\"AppName\":\"Alerte COVID\",\"ExternalLinkHint\":\"Ouvre dans une nouvelle fenêtre\",\"LastCheckedMinutes\":{\"One\":\"Dernière vérification il y a {number} minute\",\"Other\":\"Dernière vérification il y a {number} minutes\"},\"LastCheckedHours\":{\"One\":\"Dernière vérification il y a {number} heure\",\"Other\":\"Dernière vérification il y a {number} heures\"},\"LastCheckedDays\":{\"One\":\"Dernière vérification il y a {number} jour\",\"Other\":\"Dernière vérification il y a {number} jours\"}},\"OverlayClosed\":{\"SystemStatus\":\"Alerte COVID est \",\"SystemStatusOn\":\"activée\",\"SystemStatusOff\":\"désactivée\",\"NotificationStatus\":\"Notifications \",\"NotificationStatusOff\":\"désactivées\",\"TapPrompt\":\"Appuyez pour voir le menu\"},\"OverlayOpen\":{\"BluetoothCardBody\":\"Vous devez l’activer dans les paramètres de votre téléphone pour qu’Alerte COVID fonctionne.\",\"BluetoothCardAction\":\"Activez Bluetooth\",\"EnterCodeCardTitle\":\"Vous avez la COVID-19?\",\"EnterCodeCardBody\":\"Vous avez besoin d’une clé à usage unique pour aviser les autres personnes d’une exposition.\",\"EnterCodeCardAction\":\"Entrer votre clé\",\"EnterCodeCardTitleDiagnosed\":\"Vous contribuez à freiner la COVID\",\"EnterCodeCardBodyDiagnosed\":\"Merci de faire votre part pour freiner la propagation de la COVID-19. \",\"EnterCodeCardDiagnosedCountdown\":{\"One\":\"Il vous reste {number} jour!\",\"Other\":\"Il vous reste {number} jours!\"},\"NotificationCardStatus\":\"Les notifications sont désactivées\",\"NotificationCardStatusOff\":\"DÉSACTIVÉES\",\"NotificationCardBody\":\"Alerte COVID ne peut pas vous aviser dès qu’il découvre une exposition potentielle. Le fait d’être notifié rapidement est essentiel pour ralentir la propagation de la COVID-19.\",\"NotificationCardAction\":\"Activer les notifications\",\"ExposureNotificationCardStatus\":\"Les notifications d’exposition à la COVID-19 sont \",\"ExposureNotificationCardBody\":\"Alerte COVID ne peut pas vous aviser de la découverte d’une exposition potentielle. Le fait d’être notifié rapidement est essentiel pour ralentir la propagation de la COVID-19.\",\"ExposureNotificationCardAction\":\"Activez les notifications d'exposition\",\"NoConnectivityCardAction\":\"Alerte COVID est hors ligne\",\"NoConnectivityCardBody\":\"Connectez-vous à Internet pour aviser les autres personnes ou pour vérifier si vous avez été exposé.\"},\"Info\":{\"CheckSymptoms\":\"Vérifier vos symptômes\",\"SymptomsUrl\":\"https://ca.thrive.health/covid19/fr\",\"TellAFriend\":\"Partager l’application\",\"LearnMore\":\"Fonctionnement\",\"Help\":\"Aide\",\"HelpUrl\":\"https://www.canada.ca/fr/sante-publique/services/maladies/maladie-coronavirus-covid-19/alerte-covid/aide.html\",\"GetCode\":\"Obtenir une clé à usage unique\",\"ChangeLanguage\":\"Modifier la langue\",\"ChangeRegion\":\"Modifier la province ou le territoire\",\"Privacy\":\"Protection de votre vie privée\",\"SettingsTitle\":\"Paramètres\",\"InformationTitle\":\"À propos d’Alerte COVID\"},\"Landing\":{\"En\":\"English\",\"Fr\":\"Français\",\"AltText\":\"Illustration de 8 personnes profitant de l’espace public. Il y a une personne avec une canne blanche, une autre en fauteuil roulant, une autre avec un hijab, plusieurs personnes de couleur, et une représentation de la diversité de genre.\",\"CanadaAltText\":\"Symbole du gouvernement du Canada\"},\"LanguageSelect\":{\"Title\":\"Langue\",\"En\":\"English (Canada)\",\"Fr\":\"Français (Canada)\",\"PtBR\":\"Portugais (Brésil)\",\"EnShort\":\"English\",\"FrShort\":\"Français\",\"PtBRShort\":\"Portugais (Brésil)\",\"Close\":\"Fermer\"},\"Tutorial\":{\"step-1Title\":\"Fonctionnement d’Alerte COVID\",\"step-1AltText\":\"Dessin à la main d’un téléphone mobile dans une poche, qui envoie et reçoit des signaux.\",\"step-1\":\"L’application s’exécute en arrière-plan sans interrompre vos activités.\\n\\nQuand vous serez près d’une personne ayant Alerte COVID, vos téléphones s’échangeront des codes aléatoires toutes les 5 minutes.\\n\\nCes codes changent souvent et ne peuvent pas servir à vous identifier.\",\"step-2Title\":\"Qu’est-ce qu’une exposition?\",\"step-2AltText\":\"Dessin à la main de 2 téléphones mobiles côte à côte avec un chronomètre qui relie les deux téléphones.\",\"step-2\":\"L’application estime la distance entre vous et d’autres personnes grâce à la puissance des signaux Bluetooth.\\n\\nSi vous êtes à une distance de moins de 2 mètres pendant plus de 15 minutes, l’application enregistre une exposition.\",\"step-3Title\":\"Quand une personne reçoit un test positif\",\"step-3AltText\":\"Dessin à la main d’un téléphone mobile téléversant un code chiffré vers un nuage.\",\"step-3\":\"Si une personne ayant l’application a un diagnostic de COVID-19, elle peut décider de téléverser tous les codes aléatoires émis par son téléphone vers un serveur central.\\n\\nLe serveur ne reçoit que les codes. Il ne reçoit aucune information personnelle.\",\"step-4Title\":\"Découverte des expositions\",\"step-4AltText\":\"Dessin à la main d’un téléphone mobile émettant une liste de codes chiffrés. L’icône de la loupe de recherche met en évidence l’un des codes de la liste.\",\"step-4\":\"Chaque jour, quand votre téléphone a une connexion Internet, il obtient une liste de codes aléatoires émis par les personnes qui ont signalé un diagnostic.\\n\\nSi l’application reconnaît des codes dans cette liste, elle vous dira que vous avez été exposé et vous expliquera quoi faire ensuite.\",\"ActionBack\":\"Précédent\",\"ActionNext\":\"Suivant\",\"ActionEnd\":\"Terminé\",\"Close\":\"Fermer\"},\"Sharing\":{\"Title\":\"Partager l’application\",\"SubTitle\":\"Chaque personne utilisant Alerte COVID aide à ralentir la transmission de la COVID-19. Partager cette application ne partage aucune donnée privée.\",\"Platform-messages\":\"Partager avec Messages\",\"Platform-instagram\":\"Partager avec Instagram\",\"More\":\"Plus d'applications\",\"Message\":\"Joignez-vous à moi pour aider à ralentir la transmission de la COVID-19. Téléchargez l'application Alerte COVID : https://covidshield.app\",\"InstagramImageUrl\":\"https://user-images.githubusercontent.com/5274722/84658989-b9ba6b00-aee4-11ea-84d4-d840527467b4.png\",\"Close\":\"Fermer\"},\"Onboarding\":{\"Step\":\"Étape\",\"Of\":\"de\",\"ActionNext\":\"Suivant\",\"ActionEndSkip\":\"Ignorer\",\"ActionEnd\":\"Terminé\",\"ActionBack\":\"Précédent\",\"Start\":{\"Title\":\"Unissons-nous pour freiner la propagation de la COVID-19\",\"ImageAltText\":\"Dessin à la main avec plusieurs personnes différentes dedans. Leurs chemins en lignes pointillées se croisent et mènent à un téléphone intelligent plus bas.\",\"Body1\":\"Alerte COVID nous aide à briser le cycle d’infection. L’application permet d’aviser les personnes en cas d’exposition potentielle avant même que des symptômes apparaissent. \",\"Body2\":\"Nous pouvons ainsi prendre soin de nous et protéger nos communautés.\"},\"WhatItsNot\":{\"Title\":\"Ce qu’Alerte COVID ne fait pas\",\"ImageAltText\":\"Dessin à la main d’une rue sinueuse avec plusieurs maisons et un immeuble en hauteur. De petites infobulles apparaissent au-dessus de chaque bâtiment.\",\"Body1\":\"L’application ne vous dira pas sur-le-champ que vous êtes près d’une personne ayant eu un diagnostic.\",\"Body2\":\"Elle ne vous renseignera pas sur les éclosions de COVID-19 dans votre collectivité.\"},\"Anonymous\":{\"Title\":\"Votre vie privée est protégée\",\"ImageAltText\":\"Dessin à la main d’une paire de lunettes de soleil et d’un chapeau pour passer incognito. Au-dessus du chapeau, une icône de marqueur de géolocalisation est biffée.\",\"Body1\":\"Alerte COVID **n’utilise pas le GPS** et ne suit pas votre emplacement.\",\"Body2\":\"L’application **n’a aucun moyen** de connaître :\",\"Bullet1\":\"Votre emplacement.\",\"Bullet2\":\"Votre nom ou votre adresse.\",\"Bullet3\":\"Les contacts de votre téléphone.\",\"Bullet4\":\"Vos informations de santé.\",\"Bullet5\":\"Les informations de santé des personnes à proximité.\"},\"HowItWorks\":{\"Title\":\"Fonctionnement\",\"ImageAltText\":\"Dessin à la main de 3 téléphones mobiles émettant des codes aléatoires en utilisant Bluetooth.\",\"Body1\":\"L’application utilise Bluetooth pour échanger des codes aléatoires avec les téléphones à proximité.\",\"Body2\":\"Chaque jour, elle vérifie une liste de codes aléatoires provenant des personnes ayant signalé un test positif à l’application.\",\"Body3\":\"Si vous avez eu un contact étroit avec l’une de ces personnes au cours des 14 derniers jours, vous recevrez une notification.\",\"HowItWorksCTA\":\"En savoir plus sur le fonctionnement\"},\"PartOf\":{\"Title\":\"L’un des efforts de santé publique\",\"ImageAltText\":\"Dessin à la main de divers moyens de lutter contre la COVID-19, dont un désinfectant pour les mains, un couvre-visage, des mains avec du savon et l’application Alerte COIVID.\",\"Body1\":\"Alerte COVID n’est qu’une partie des efforts de santé publique visant à freiner la propagation de la COVID-19.\",\"Body2\":\"Continuez à suivre les recommandations de santé publique de votre région.\",\"Body3\":\"Alerte COVID ne remplace pas un avis médical. Si vous tombez malade, contactez votre médecin ou un professionnel de la santé.\"},\"Permissions\":{\"Title\":\"L’application demandera votre autorisation\",\"ImageAltText\":\"Dessin à la main d’un téléphone mobile dont l’écran affiche une fenêtre de dialogue avec un X rouge et un crochet vert.\",\"Body1\":\"**Permettez à l’application** de collecter des codes aléatoires quand vous êtes près d’autres téléphones. L’application connaîtra la date, la durée et la puissance de signal associées à ces codes, mais ces données resteront sur votre téléphone. \",\"Body2\":\"Vous devrez aussi **lui permettre de vous envoyer des notifications**.\",\"PrivacyButtonCTA\":\"En savoir plus sur la confidentialité\"}},\"Privacy\":{\"Title\":\"Politique de confidentialité\",\"Close\":\"Fermer\"},\"ThankYou\":{\"Title\":\"Merci d'aider\",\"Body\":\"Les notifications d’exposition sont activées. Si Alerte COVID détecte que vous avez possiblement été exposé(e) à la COVID-19, vous recevrez une notification.\",\"Dismiss\":\"OK\"},\"DataUpload\":{\"Cancel\":\"Annuler\",\"InfoSmall\":\"Vos identifiants aléatoires ne seront pas partagés, à moins que vous donniez votre permission à l'étape suivante.\",\"ShareToast\":\"Identifiants aléatoires partagés avec succès\",\"Step1\":{\"Title\":\"Aviser les autres personnes d’une exposition potentielle\",\"Body1a\":\"Étape 1 : \",\"Body1b\":\"Vous entrez la clé à usage unique reçue lors de votre diagnostic.\",\"Body2a\":\"Étape 2 : \",\"Body2b\":\"Vous acceptez qu’Alerte COVID avise les personnes qu’elles ont été exposées.\",\"Body3a\":\"Étape 3 : \",\"Body3b\":\"Vous autorisez votre téléphone à partager vos codes aléatoires.\",\"Body4a\":\"Personne ne recevra d’information sur vous \",\"Body4b\":\"ou sur le moment de votre proximité.\",\"CTA\":\"Suivant\",\"NoCode\":\"Vous n’avez pas de clé à usage unique?\"},\"FormView\":{\"Title\":\"Entrez votre clé à usage unique\",\"Body\":\"Entrez la clé que vous avez reçue lors de votre diagnostic.\",\"Action\":\"Envoyer\",\"InputLabel\":\"code Alerte COVID\",\"ErrorTitle\":\"Clé à usage unique non reconnue\",\"ErrorBody\":\"Votre clé n’a pas pu être reconnue. Veuillez essayer à nouveau.\",\"ErrorAction\":\"OK\"},\"ConsentView\":{\"Title\":\"Vous pouvez maintenant téléverser vos codes\",\"Body1\":\"Votre téléphone vous demandera l’autorisation de téléverser vos codes ou « identifiants » aléatoires des 14 derniers jours.\",\"Body2a\":\"Personne ne recevra d’information sur vous \",\"Body2b\":\"ou sur le moment de votre proximité.\",\"Body3\":\"Vous pouvez aider à ralentir la propagation de la COVID-19 si vous acceptez.\",\"Action\":\"Accepter\",\"ErrorTitle\":\"Les codes aléatoires n’ont pas pu être téléversés\",\"ErrorBody\":\"Vous n’avez pas donné votre autorisation.\",\"ErrorAction\":\"OK\"},\"NoCode\":{\"NoRegion\":{\"Title\":\"Vous n’avez pas choisi de province ou de territoire\",\"Body\":\"Dans certaines provinces et certains territoires, on ne peut pas encore signaler de diagnostics de COVID-19 avec cette application.\\n\\nPour savoir si vous pouvez obtenir une clé à usage unique, vous devez sélectionner votre région.\",\"ChooseRegionCTA\":\"Sélectionner une province ou un territoire\"},\"RegionCovered\":{\"ON\":{\"Title\":\"Obtenir une clé à usage unique\",\"Body\":\"Si vous avez reçu un test positif en Ontario :\",\"Body2\":\"Allez sur le site Web des Résultats du test de diagnostic de la COVID-19 puis entrez vos informations.\",\"Body3\":\"Consultez les résultats de votre test.\",\"Body4\":\"Notez la clé à usage unique.\",\"Body5\":\"Revenez ici et entrez la clé.\",\"CTA\":\"Aller sur le site des Résultats du test pour la COVID-19\",\"Link\":\"https://covid19results.ehealthontario.ca:4443/login\"}},\"RegionNotCovered\":{\"Title\":\"Pas encore de signalement dans votre région\",\"Body\":\"Les personnes de votre région ne peuvent pas encore obtenir de clé à usage unique.\\n\\nVous ne pourrez pas aviser les personnes d’une exposition. Mais vous pouvez tout de même vous isoler pendant 14 jours, et ainsi :\",\"Body2\":\"Assurer la sécurité de votre communauté.\",\"Body3\":\"Protéger les personnes et les animaux vivant avec vous.\",\"Body4\":\"Prendre soin de vous.\"}}},\"Notification\":{\"ExposedMessageTitle\":\"Vous avez été exposé\",\"ExposedMessageBody\":\"Vous avez eu un contact étroit avec une personne qui a signalé un diagnostic de COVID-19 au moyen de l’application. Informez-vous sur les étapes à suivre.\",\"OffMessageTitle\":\"Alerte COVID est désactivée\",\"OffMessageBody\":\"Activez Alerte COVID pour être avisé en cas d’exposition potentielle à la COVID-19.\",\"DailyUploadNotificationTitle\":\"Téléversez vos nouveaux codes aléatoires\",\"DailyUploadNotificationBody\":\"Aidez à ralentir la propagation de la COVID-19 en téléversant vos nouveaux codes aléatoires.\"},\"Partners\":{\"Label\":\"Conçu en partenariat avec\"},\"BottomSheet\":{\"Collapse\":\"Fermer\",\"OnStatus\":\"Alerte COVID est ACTIVÉE, Appuyez pour voir le menu\",\"OffStatus\":\"Alerte COVID est DÉSACTIVÉE, Appuyez pour voir le menu\"},\"RegionLanding\":{\"Title\":\"Sélectionnez votre province ou territoire\",\"Body1\":\"Les gouvernements provinciaux et territoriaux s’efforcent de rendre Alerte COVID utilisable partout au Canada.\",\"Body2\":\"Dans certains endroits, on ne peut pas encore signaler de diagnostics de COVID-19 avec cette application.\",\"RegionSelectBtn\":\"Sélectionnez une province ou un territoire\"},\"RegionPicker\":{\"Title\":\"Où habitez-vous? (facultatif)\",\"SettingsTitle\":\"Province ou territoire\",\"Close\":\"Fermer\",\"Body\":\"Sélectionnez votre région pour savoir si vous pouvez signaler un diagnostic à l’aide de l’application.\\n\\nLa région où vous habitez ne sera jamais transmise à personne.\",\"Skip\":\"Ignorer\",\"GetStarted\":\"Commencer\",\"Optional\":\"* Facultatif\",\"AB\":\"Alberta\",\"BC\":\"Colombie-Britannique\",\"MB\":\"Manitoba\",\"NB\":\"Nouveau-Brunswick\",\"NL\":\"Terre-Neuve-et-Labrador\",\"NT\":\"Territoires du Nord-Ouest\",\"NS\":\"Nouvelle-Écosse\",\"NU\":\"Nunavut\",\"ON\":\"Ontario\",\"PE\":\"Île-du-Prince-Édouard\",\"QC\":\"Québec\",\"SK\":\"Saskatchewan\",\"YT\":\"Yukon\",\"None\":\"Ne rien sélectionner\"},\"RegionalGuidance\":{\"CA\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://ca.thrive.health/covid19/fr\"},\"AB\":{\"CTA\":\"Découvrez si vous devriez vous faire tester (lien en anglais seulement)\",\"URL\":\"https://myhealth.alberta.ca/Journey/COVID-19/Pages/PubAsympIsolate.aspx\"},\"BC\":{\"CTA\":\"Découvrez si vous devriez vous faire tester (lien en anglais seulement)\",\"URL\":\"https://bc.thrive.health/covid19/en\"},\"MB\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://covid19.soinscommunsmb.ca/covid19/outil-de-depistage/\"},\"NB\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://www2.gnb.ca/content/gnb/fr/ministeres/bmhc/maladies_transmissibles/content/maladies_respiratoires/coronavirus/expositionaucoronavirus.html#/app/symptom-checker/guides/399/what-to-do\"},\"NL\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://www.811healthline.ca/fr/autoevaluation-pour-la-covid-19/\"},\"NT\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://www.gov.nt.ca/covid-19/fr/services/outil-d%E2%80%99auto-%C3%A9valuation-en-ligne-pour-la-covid-19-aux-tno\"},\"NS\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://novascotia.ca/coronavirus/when-to-seek-help/fr/#if-exposed\"},\"NU\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://nu.thrive.health/covid19/fr\"},\"ON\":{\"CTA\":\"Lisez les étapes à suivre\",\"URL\":\"https://ontario.ca/covidalerte-expose\"},\"PE\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://www.princeedwardisland.ca/fr/information/sante-et-mieux-etre/auto-isolement-pour-lutter-contre-la-covid-19\"},\"QC\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://www.quebec.ca/sante/problemes-de-sante/a-z/coronavirus-2019/consignes-isolement-personne-en-contact-covid-19/\"},\"SK\":{\"CTA\":\"Découvrez si vous devriez vous faire tester (lien en anglais seulement)\",\"URL\":\"https://www.saskatchewan.ca/government/health-care-administration-and-provider-resources/treatment-procedures-and-guidelines/emerging-public-health-issues/2019-novel-coronavirus/covid-19-self-assessment\"},\"YT\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://service.yukon.ca/fr/covid-19-auto-evaluation/\"}},\"HowToIsolate\":{\"Title\":\"Comment vous isoler\",\"Intro\":\"Faites votre possible pour :\",\"Body1\":\"Rester à la maison, sauf si vous avez besoin de soins médicaux.\",\"Body2\":\"Éviter les transports publics comme les autobus et les taxis.\",\"Body3\":\"Demander de l’aide pour recevoir votre épicerie et vos provisions à votre porte.\",\"Body4\":\"Utiliser une pièce et une salle de bain séparées des autres de votre maison, si possible.\",\"Body5\":\"Porter un masque de façon sécuritaire dès que vous ne pouvez pas suivre les mesures ci-dessus.\"},\"A11yList\":{\"Start\":\"Début de liste\",\"End\":\"Fin de liste\",\"Bullet\":\"Puce\"},\"YourData\":{\"Body1\":\"votre identité\",\"Body2\":\"vos contacts\",\"Body3\":\"toute précision sur vous ou sur les personnes à proximité\",\"Body4\":\"vos informations de santé\",\"Body5\":\"\",\"Intro\":\"Alerte COVID n’a aucun moyen de connaître :\",\"Title\":\"Complètement anonyme\"}},\"pt-BR\":{\"Home\":{\"NoExposureDetected\":\"Nenhuma exposição detectada\",\"ExposureDetected\":\"Você possivelmente foi exposto ao COVID-19\",\"ChooseRegionCTA\":\"Choose province or territory\",\"How\":\"Diagnosed with COVID-19?\",\"CTA\":\"What to do next\",\"HowUrl\":\"https://www.canada.ca/\",\"DiagnosedView\":{\"Title\":\"Thanks for helping fight COVID-19\",\"Body1\":{\"One\":\"Tomorrow, you’ll get your last notification asking permission to upload any new random codes your phone sent out.\",\"Other\":\"For the next {number} days, you’ll get a daily notification asking permission to upload any new random codes your phone sent out.\"},\"Body2\":\"You do not have to agree, even if you agreed the day before.\",\"Body3\":\"If you’re worried about your symptoms, get medical care as soon as you can. Take care of yourself and your family during this time.\",\"TipTitle\":\"TIP: \",\"TipBody\":\"You can prepare for your call from Public Health through the test results website. \",\"TipLinkText\":\"Test results website\",\"TipURL\":\"https://covid19results.ehealthontario.ca:4443/login\"},\"SymptomTrackerUrl\":\"https://ca.thrive.health/covid19app/action/88a5e9a7-db9e-487b-bc87-ce35035f8e5c?from=/home&navigateTo=/tracker/complete\",\"DiagnosedShareView\":{\"Title\":\"Upload random codes\",\"Body1\":\"Thanks for helping slow the spread!\",\"Body2\":\"Reminder: \",\"Body3\":\"To help keep people safe, you need to upload your random codes every day, especially if you have to leave your home.\",\"ButtonCTA\":\"Upload your random codes\"},\"BluetoothDisabled\":\"Bluetooth desligado\",\"EnableBluetoothCTA\":\"O Bluetooth é usado para coletar e compartilhar IDs aleatórios necessários para o COVID Alert funcionar.\",\"TurnOnBluetooth\":\"Ligar o Bluetooth\",\"EnDisabled\":{\"Title\":\"COVID Alert is off\",\"Body1\":\"You did not enable COVID Alert. The app needs your permission to work.\",\"CTA\":\"Enable COVID Alert\",\"AndroidTitle2\":\"Not sure about turning on Location?\",\"AndroidBody1\":\"You need to have Location turned on for COVID Alert to work. To use Bluetooth scanning, Android phones need Location setting on for all apps.\",\"AndroidBody2a\":\"Despite that, COVID Alert has \",\"AndroidBody2b\":\"no way of knowing where you are. \",\"AndroidBody2c\":\"You can check the app’s permissions in your phone’s settings. You’ll see it does not have permission for location services.\"},\"FrameworkUnavailable\":{\"Title\":\"Something went wrong\",\"Body\":\"COVID Alert is not supported by your phone’s operating system.\\n\\nMake sure your operating system is up to date.\\n\\nIf you have an Android phone, try updating your Google Play Services.\",\"CTA\":\"Get Help\"},\"UnknownProblem\":{\"Title\":\"Something went wrong\",\"CTA\":\"Get Help\"},\"NoConnectivity\":\"Sem conexão à internet\",\"NoConnectivityDetailed\":\"O COVID Alert precisa de acesso à Internet para continuar verificando à potenciais exposições.\",\"AppName\":\"COVID Alert\",\"ExternalLinkHint\":\"Opens in a new window\",\"LastCheckedMinutes\":{\"One\":\"Última verificação há {number} minuto\",\"Other\":\"Última verificação há {number} minutos\"},\"LastCheckedHours\":{\"One\":\"Última verificação há {number} hora\",\"Other\":\"Última verificação há {number} horas\"},\"LastCheckedDays\":{\"One\":\"Última verificação há {number} dia\",\"Other\":\"Última verificação há {number} dias\"},\"NoExposureDetectedDetailed\":\"Com base em seus IDs aleatórios, você não esteve perto de alguém nos últimos 14 dias que testou positivo para COVID-19.\",\"ExposureDetectedDetailed\":\"Com base nos seus IDs aleatórios, você esteve perto de alguém nos últimos 14 dias que testou positivo para COVID-19.\",\"SeeGuidance\":\"Leia a orientação do Canadá sobre COVID-19\",\"GuidanceUrl\":\"https://www.canada.ca/en/public-health/services/publications/diseases-conditions/covid-19-how-to-isolate-at-home.html\",\"SignalDataShared\":\"Obrigado por ajudar a diminuir a propagação\",\"SignalDataSharedDetailed\":{\"One\":\"Você receberá uma notificação solicitando que compartilhe seus IDs aleatórios todos os dias pelo próximo {number} dia.\",\"Other\":\"Você receberá uma notificação solicitando que compartilhe seus IDs aleatórios todos os dias pelos próximos {number} dias.\"},\"SignalDataSharedCTA\":\"Acompanhe seus sintomas\",\"DailyShare\":\"Compartilhe seus novos IDs aleatórios\",\"DailyShareDetailed\":\"Compartilhar seus dados ajuda outras pessoas a saber se elas foram expostas ao COVID-19.\",\"ShareRandomIDsCTA\":\"Compartilhe seus IDs aleatórios\",\"ExposureNotificationsDisabled\":\"As notificações de exposição estão desligadas\",\"ExposureNotificationsDisabledDetailed\":\"São necessárias notificações de exposição para que o COVID Alert funcione.\",\"EnableExposureNotificationsCTA\":\"Ligar notificações de exposição\"},\"OverlayClosed\":{\"SystemStatus\":\"COVID Alert está \",\"SystemStatusOn\":\"LIGADO\",\"SystemStatusOff\":\"DESLIGADO\",\"NotificationStatus\":\"As notificações estão \",\"NotificationStatusOff\":\"DESLIGADAS\",\"TapPrompt\":\"Toque para mais informações\"},\"OverlayOpen\":{\"BluetoothCardBody\":\"O Bluetooth é usado para coletar e compartilhar IDs aleatórios necessários para o COVID Alert funcionar.\",\"BluetoothCardAction\":\"Ligar o Bluetooth\",\"EnterCodeCardTitle\":\"Código do COVID Alert\",\"EnterCodeCardBody\":\"Um profissional de saúde pediu para você inserir um código COVID Alert?\",\"EnterCodeCardAction\":\"Insira o código\",\"EnterCodeCardTitleDiagnosed\":\"You’re helping stop COVID-19\",\"EnterCodeCardBodyDiagnosed\":\"Thank you for doing your part to slow the spread. \",\"EnterCodeCardDiagnosedCountdown\":{\"One\":\"{number} day left!\",\"Other\":\"{number} days left!\"},\"NotificationCardStatus\":\"As notificações estão \",\"NotificationCardStatusOff\":\"DESLIGADAS\",\"NotificationCardBody\":\"Você não receberá notificações se tiver sido exposto ao COVID-19. A notificação de potencial exposição é importante para ajudar a diminuir a propagação do COVID-19.\",\"NotificationCardAction\":\"Ligar notificações\",\"ExposureNotificationCardStatus\":\"As notificações de exposição estão \",\"ExposureNotificationCardBody\":\"São necessárias notificações de exposição para que o COVID Alert funcione.\",\"ExposureNotificationCardAction\":\"Ligar notificações de exposição\",\"NoConnectivityCardAction\":\"COVID Alert is offline\",\"NoConnectivityCardBody\":\"Connect to the Internet to notify people or check for exposures.\",\"BluetoothCardStatus\":\"Bluetooth está \",\"BluetoothCardStatusOff\":\"DESLIGADO\",\"ExposureNotificationCardStatusOff\":\"DESLIGADAS\"},\"Info\":{\"CheckSymptoms\":\"Verifique os sintomas\",\"SymptomsUrl\":\"https://ca.thrive.health/covid19/en\",\"TellAFriend\":\"Compartilhe o aplicativo\",\"LearnMore\":\"Como o COVID Alert funciona\",\"Help\":\"Help\",\"HelpUrl\":\"https://www.canada.ca/en/public-health/services/diseases/coronavirus-disease-covid-19/covid-alert/help.html\",\"GetCode\":\"Get a one-time key\",\"ChangeLanguage\":\"Mudar idioma\",\"ChangeRegion\":\"Change province or territory\",\"Privacy\":\"Leia a política de privacidade\",\"SettingsTitle\":\"Settings\",\"InformationTitle\":\"About COVID Alert\"},\"Landing\":{\"En\":\"English\",\"Fr\":\"Français\",\"AltText\":\"Illustration of 8 people enjoying a public space. There’s a person with a walking cane, a person in a wheelchair, a person wearing a hijab, several people of colour, and a representation of gender diversity.\",\"CanadaAltText\":\"Symbol of the Government of Canada\"},\"LanguageSelect\":{\"Title\":\"Idioma\",\"En\":\"Inglês (Canadá)\",\"Fr\":\"Francês (Canadá)\",\"PtBR\":\"Português (Brasil)\",\"EnShort\":\"Inglês\",\"FrShort\":\"Francês\",\"PtBRShort\":\"Português (Brasil)\",\"Close\":\"Voltar\"},\"Tutorial\":{\"step-1Title\":\"Como o COVID Alert funciona\",\"step-1AltText\":\"A hand-drawn illustration of a mobile phone in a pocket, sending and receiving signals.\",\"step-1\":\"Seu telefone usa o Bluetooth para coletar e compartilhar IDs aleatórios com telefones próximos a você com o COVID Alert instalado. Esses IDs são armazenados com segurança em cada telefone.\",\"step-2Title\":\"Se você foi potencialmente exposto ao COVID-19\",\"step-2AltText\":\"A hand-drawn illustration of 2 mobile phones side-by-side with a timer clock connecting both phones.\",\"step-2\":\"Você receberá uma notificação se esteve próximo de alguém nos últimos 14 dias que testou positivo para COVID-19.\",\"step-3Title\":\"Se você testar positivo para COVID-19\",\"step-3AltText\":\"A hand-drawn illustration of a mobile phone uploading a numeric code to a cloud.\",\"step-3\":\"Notifique anonimamente as pessoas que estiveram perto de você nos últimos 14 dias de que elas possivelmente foram expostas.\",\"step-4Title\":\"Looking for exposures\",\"step-4AltText\":\"A hand-drawn illustration of a mobile phone uploading a numeric code to a cloud.\",\"step-4\":\"Every day, whenever it has an Internet connection, your phone will get a list of the random codes from people who reported a diagnosis.\\n\\nIf it finds codes that match, the app notifies you that you've been exposed and explains what to do next.\",\"ActionBack\":\"Voltar\",\"ActionNext\":\"Próximo\",\"ActionEnd\":\"Concluir\",\"Close\":\"Fechar\"},\"Sharing\":{\"Title\":\"Compartilhe o aplicativo\",\"SubTitle\":\"Todas as pessoas que usam o COVID Alert ajudam a diminuir a propagação do COVID-19. Compartilhando este aplicativo não compartilhará dados pessoais.\",\"Platform-messages\":\"Compartilhar em Mensagens\",\"Platform-instagram\":\"Compartilhar no Instagram\",\"More\":\"Mais aplicativos\",\"Message\":\"Junte-se a mim e ajude a diminuir a propagação do COVID-19. Baixe o aplicativo COVID Shield: https://covidshield.app\",\"InstagramImageUrl\":\"https://user-images.githubusercontent.com/5274722/84658989-b9ba6b00-aee4-11ea-84d4-d840527467b4.png\",\"Close\":\"Fechar\"},\"Onboarding\":{\"Step\":\"Step\",\"Of\":\"of\",\"ActionNext\":\"Próximo\",\"ActionEndSkip\":\"Skip\",\"ActionEnd\":\"Concluir\",\"ActionBack\":\"Voltar\",\"Start\":{\"Title\":\"Together, let’s stop the spread of COVID-19\",\"ImageAltText\":\"A hand-drawn illustration with lots of different people in it. Dotted lines show their paths crossing and leading to a smartphone below.\",\"Body1\":\"COVID Alert helps us break the cycle of infection. The app can let people know of possible exposures before any symptoms appear. \",\"Body2\":\"That way, we can take care of ourselves and protect our communities.\"},\"WhatItsNot\":{\"Title\":\"What COVID Alert does not do\",\"ImageAltText\":\"A hand-drawn illustration with many houses and a high-rise building on a curving street. Small message bubbles appear above each home.\",\"Body1\":\"The app will not tell you in the moment if you’re currently near someone who’s been diagnosed.\",\"Body2\":\"It will not tell you about outbreaks in your community.\"},\"Anonymous\":{\"Title\":\"Your privacy is protected\",\"ImageAltText\":\"A hand-drawn illustration of shaded glasses and hat to go incognito. Above the hat, a location pin icon is crossed out.\",\"Body1\":\"COVID Alert **does not use GPS** or track your location.\",\"Body2\":\"It has **no way of knowing**:\",\"Bullet1\":\"Your location.\",\"Bullet2\":\"Your name or address.\",\"Bullet3\":\"Your phone's contacts.\",\"Bullet4\":\"Your health information.\",\"Bullet5\":\"The health information of anyone you’re near.\"},\"HowItWorks\":{\"Title\":\"How it works\",\"ImageAltText\":\"A hand-drawn illustration of 3 mobile phones sending out random codes via bluetooth.\",\"Body1\":\"The app uses Bluetooth to exchange random codes with nearby phones.\",\"Body2\":\"Every day, it checks a list of random codes from people who tell the app they tested positive.\",\"Body3\":\"If you’ve had close contact with one of those people in the past 14 days, you’ll get a notification.\",\"HowItWorksCTA\":\"Learn more about how it works\"},\"PartOf\":{\"Title\":\"One part of public health\",\"ImageAltText\":\"A hand-drawn illustration of different ways of fighting COVID-19, including hand sanitizer, handwashing, face mask and the COVID Alert app.\",\"Body1\":\"COVID Alert is just one part of the public health effort to stop the spread of COVID-19.\",\"Body2\":\"Follow all public health guidelines in your area.\",\"Body3\":\"COVID Alert does not replace medical advice. If you get sick, contact your doctor or other healthcare provider.\"},\"Permissions\":{\"Title\":\"The app will now ask your permission\",\"ImageAltText\":\"A hand-drawn illustration of a mobile phone displaying a dialogue box with a red X and a green check mark on the screen.\",\"Body1\":\"**Allow the app** to start logging random codes or “random IDs” when you’re near other phones. The app will access the date, duration and signal strength related to the random codes, but they never leave your phone.\",\"Body2\":\"You’ll also need to **let the app send you notifications**.\",\"PrivacyButtonCTA\":\"Learn more about privacy\"}},\"Privacy\":{\"Title\":\"Política de privacidade\",\"Close\":\"Fechar\"},\"ThankYou\":{\"Title\":\"Obrigado por ajudar\",\"Body\":\"As notificações de exposição estão ativadas. Você receberá uma notificação se o COVID Alert detectar que você foi exposto ao COVID-19.\",\"Dismiss\":\"Dispensar\"},\"DataUpload\":{\"Cancel\":\"Cancelar\",\"InfoSmall\":\"Seus IDs aleatórios não serão compartilhados, a menos que você permita na próxima etapa.\",\"ShareToast\":\"IDs aleatórios compartilhados com sucesso\",\"Step1\":{\"Title\":\"Let people know they may have been exposed\",\"Body1a\":\"Step 1. \",\"Body1b\":\"Enter the one-time key you got when you were diagnosed.\",\"Body2a\":\"Step 2. \",\"Body2b\":\"Agree that COVID Alert can let people know they were exposed.\",\"Body3a\":\"Step 3. \",\"Body3b\":\"Allow your phone to share your random codes.\",\"Body4a\":\"Nobody will get any information about you \",\"Body4b\":\"or the time you were near them.\",\"CTA\":\"Next\",\"NoCode\":\"Need a one-time key?\"},\"FormView\":{\"Title\":\"Enter your one-time key\",\"Body\":\"Enter the key you got when you were diagnosed.\",\"Action\":\"Submit\",\"InputLabel\":\"COVID Alert key\",\"ErrorTitle\":\"One-time key not recognized\",\"ErrorBody\":\"Your key could not be recognized. Please try again.\",\"ErrorAction\":\"OK\"},\"ConsentView\":{\"Title\":\"Now you can upload your codes\",\"Body1\":\"Your phone will ask your permission to upload your random codes or “random IDs” from the past 14 days.\",\"Body2a\":\"Nobody will get any information about you \",\"Body2b\":\"or the time you were near them.\",\"Body3\":\"You can help slow the spread of COVID-19 if you agree.\",\"Action\":\"Agree\",\"ErrorTitle\":\"Random codes could not be uploaded\",\"ErrorBody\":\"You did not give permission.\",\"ErrorAction\":\"OK\"},\"NoCode\":{\"NoRegion\":{\"Title\":\"You skipped choosing province or territory\",\"Body\":\"In some provinces and territories, people cannot yet report a COVID-19 diagnosis through this app.\\n\\nTo find out if you can get a one-time key, you need to choose your area.\",\"ChooseRegionCTA\":\"Choose province or territory\"},\"RegionCovered\":{\"ON\":{\"Title\":\"Get a one-time key\",\"Body\":\"If you’ve tested positive in Ontario:\",\"Body2\":\"Go to the COVID-19 Test Results Website and enter your details.\",\"Body3\":\"Review your test results.\",\"Body4\":\"Get the one-time key.\",\"Body5\":\"Come back here and enter the key.\",\"CTA\":\"Go to COVID-19 Test Results Website\",\"Link\":\"https://covid19results.ehealthontario.ca:4443/\"}},\"RegionNotCovered\":{\"Title\":\"No reporting yet in your area\",\"Body\":\"People in your area cannot yet get a one-time key.\\n\\nYou will not be able to let people know they were exposed. But you can still self-isolate for 14 days, and:\",\"Body2\":\"Keep your community safe.\",\"Body3\":\"Protect people and pets you live with.\",\"Body4\":\"Take care of yourself.\"}},\"FormIntro\":\"Digite seu código COVID Alert de 8 dígitos.\",\"Action\":\"Enviar código\",\"ConsentTitle\":\"Compartilhe seus IDs aleatórios\",\"ConsentBody\":\"Você recebeu acesso de um profissional de saúde para compartilhar os IDs aleatórios armazenados no seu telefone.\",\"ConsentBody2\":\"Se você compartilhar seus IDs aleatórios, outras pessoas com a COVID Alert que estiveram perto de você nos últimos 14 dias receberão uma notificação de que elas possivelmente foram expostas. Esta notificação não incluirá nenhuma informação sobre você.\",\"ConsentBody3\":\"Você será notificado uma vez por dia quando novos IDs aleatórios estiverem disponíveis para serem compartilhados. Você deve conceder permissão cada vez para que os IDs aleatórios sejam compartilhados. Compartilhar é voluntário.\",\"PrivacyPolicyLink\":\"Ver política de privacidade\",\"ConsentAction\":\"Concordo\",\"ErrorTitle\":\"Código não reconhecido\",\"ErrorBody\":\"Não foi possível reconhecer seu código COVID Alert. Por favor, tente novamente.\",\"ErrorAction\":\"OK\"},\"Notification\":{\"ExposedMessageTitle\":\"Você possivelmente foi exposto ao COVID-19\",\"ExposedMessageBody\":\"Com base nos seus IDs aleatórios, você esteve perto de alguém nos últimos 14 dias que testou positivo para COVID-19.\",\"OffMessageTitle\":\"O COVID Alert está desligado\",\"OffMessageBody\":\"Ligue o COVID Alert para ser notificado se você tiver sido potencialmente exposto ao COVID-19.\",\"DailyUploadNotificationTitle\":\"Compartilhe seus novos IDs aleatórios\",\"DailyUploadNotificationBody\":\"Compartilhar seus dados ajuda outras pessoas a saber se elas foram expostas ao COVID-19.\"},\"Partners\":{\"Label\":\"Desenvolvido em parceria com\"},\"BottomSheet\":{\"Collapse\":\"Ocultar\",\"OnStatus\":\"COVID Alert is on, Tap for more information\",\"OffStatus\":\"COVID Alert is off, Tap for more information\"},\"RegionLanding\":{\"Title\":\"Choose your province or territory\",\"Body1\":\"Provincial and territorial governments are working to support COVID Alert across Canada.\",\"Body2\":\"In some places, people cannot yet report a COVID-19 diagnosis through this app.\",\"RegionSelectBtn\":\"Choose province or territory\"},\"RegionPicker\":{\"Title\":\"Where do you live? (optional)\",\"SettingsTitle\":\"Province or territory\",\"Close\":\"Close\",\"Body\":\"Choose your region to check if you can report a diagnosis through this app.\\n\\nYour region will never be shared with anyone.\",\"Skip\":\"Skip\",\"GetStarted\":\"Get started\",\"Optional\":\"* Optional\",\"AB\":\"Alberta\",\"BC\":\"British Columbia\",\"MB\":\"Manitoba\",\"NB\":\"New Brunswick\",\"NL\":\"Newfoundland and Labrador\",\"NT\":\"Northwest Territories\",\"NS\":\"Nova Scotia\",\"NU\":\"Nunavut\",\"ON\":\"Ontario\",\"PE\":\"Prince Edward Island\",\"QC\":\"Quebec\",\"SK\":\"Saskatchewan\",\"YT\":\"Yukon\",\"None\":\"Prefer not to say\"},\"RegionalGuidance\":{\"CA\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://ca.thrive.health/covid19/en\"},\"AB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://myhealth.alberta.ca/Journey/COVID-19/Pages/PubAsympIsolate.aspx\"},\"BC\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://bc.thrive.health/covid19/en\"},\"MB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://sharedhealthmb.ca/covid19/screening-tool/\"},\"NB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www2.gnb.ca/content/gnb/en/departments/ocmoh/cdc/content/respiratory_diseases/coronavirus/coronavirusexposure.html#/app/symptom-checker/guides/399/what-to-do\"},\"NL\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://nl.thrive.health/covid19/en\"},\"NT\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.gov.nt.ca/covid-19/en/services/nwt-online-covid-19-self-assessment-tool\"},\"NS\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://novascotia.ca/coronavirus/when-to-seek-help/#if-exposed\"},\"NU\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://nu.thrive.health/covid19/en\"},\"ON\":{\"CTA\":\"Find out what to do next\",\"URL\":\"https://ontario.ca/covidalert-exposed\"},\"PE\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.princeedwardisland.ca/en/information/health-and-wellness/covid-19-self-isolation\"},\"QC\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.quebec.ca/en/health/health-issues/a-z/2019-coronavirus/instructions-for-people-who-have-been-in-contact-with-a-confirmed-case-of-covid-19/\"},\"SK\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.saskatchewan.ca/government/health-care-administration-and-provider-resources/treatment-procedures-and-guidelines/emerging-public-health-issues/2019-novel-coronavirus/covid-19-self-assessment\"},\"YT\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://service.yukon.ca/en/covid-19-self-assessment/\"}},\"HowToIsolate\":{\"Title\":\"How to self-isolate\",\"Intro\":\"Try your best to:\",\"Body1\":\"Stay home unless it’s to get medical care.\",\"Body2\":\"Avoid public transportation like buses or taxis.\",\"Body3\":\"Ask for help to get groceries and supplies dropped off at your door.\",\"Body4\":\"Stay in a separate room and use a separate bathroom from others in your home, if possible.\",\"Body5\":\"Wear a mask safely any time you cannot take the above actions.\"},\"A11yList\":{\"Start\":\"List start\",\"End\":\"List end\",\"Bullet\":\"Bullet\"},\"OnboardingPermissions\":{\"Title\":\"Seus dados são privados\",\"Body\":\"O COVID Alert adota uma abordagem de privacidade em primeiro lugar na notificação de exposição.\",\"Body2\":\"Seus IDs aleatórios são armazenados exclusivamente em seu telefone, a menos que você os compartilhe.\",\"Body3\":\"O uso do COVID Alert é voluntário. Você pode excluir seus IDs aleatórios a qualquer momento.\"},\"OnboardingStart\":{\"Title\":\"Mantenha você e os outros seguros\",\"Body1\":\"Seja notificado se você foi potencialmente exposto ao COVID-19.\",\"Body2\":\"Se você testar positivo para COVID-19, poderá compartilhar seus dados anonimamente para que outras pessoas possam ser notificadas sobre uma possível exposição.\",\"TutorialAction\":\"Saiba como o COVID Alert funciona\"}}}") \ No newline at end of file +export default JSON.parse("{\"en\":{\"Home\":{\"NoExposureDetected\":{\"AllSetTitle\":\"You're all set\",\"RegionCovered\":{\"Title\":\"No exposure detected\",\"Body\":\"You have not been near anyone who reported a COVID-19 diagnosis through this app.\",\"GuidanceUrl\":\"https://www.canada.ca/en/public-health/services/publications/diseases-conditions/covid-19-how-to-isolate-at-home.html\",\"AllSetBody\":\"Your phone is now running Bluetooth to collect codes from nearby phones.\"},\"NoRegion\":{\"Title\":\"No exposure detected\",\"Body\":\"You have not been near anyone who reported a COVID-19 diagnosis through this app.\\n\\nHowever, in some provinces and territories, people cannot yet report COVID-19 diagnoses through this app.\",\"AllSetBody\":\"We’ll let you know as soon as people outside Ontario can report a diagnosis through COVID Alert.\\n\\nIt’s still helpful to keep COVID Alert on.\\n\\nThat way, when people are able to report a diagnosis, you’ll find out if you were near them.\"},\"RegionNotCovered\":{\"Title\":\"No reporting yet in your area\",\"Body\":\"People in your province or territory are not yet able to report a COVID-19 diagnosis through this app.\\n\\nIt’s still helpful to turn COVID Alert on. That way, when people are able to report a diagnosis, you’ll be notified if you were near them.\",\"GuidanceUrl\":\"https://www.canada.ca/en/public-health/services/publications/diseases-conditions/covid-19-how-to-isolate-at-home.html\",\"AllSetBody\":\"We’ll let you know as soon as people in your area can report a diagnosis through COVID Alert.\\n\\nIt’s still helpful to keep COVID Alert on.\\n\\nThat way, when people are able to report a diagnosis, you’ll find out if you were near them.\"}},\"ExposureDetected\":{\"CA\":{\"Title\":\"You’ve been exposed in the last 14 days\",\"Title2\":\"What now?\",\"Body1\":\"Someone you’ve been near has reported a COVID-19 diagnosis through the app. You were close to them for 15 minutes or more.\",\"Body2\":\"You’re at risk of being infected. Watch yourself carefully for symptoms, and \",\"Body3\":\"consider self-isolating for 14 days.\",\"HowToIsolateCTA\":\"How to self-isolate\"},\"ON\":{\"Title\":\"You’ve been exposed in the last 14 days\",\"Title2\":\"What now?\",\"Body1\":\"Someone you’ve been near has reported a COVID-19 diagnosis through the app. You were close to them for 15 minutes or more.\",\"Body2\":\"You’re at risk of being infected.\",\"HowToIsolateCTA\":\"How to self-isolate\"}},\"ChooseRegionCTA\":\"Choose province or territory\",\"How\":\"Diagnosed with COVID-19?\",\"CTA\":\"What to do next\",\"HowUrl\":\"https://www.canada.ca/\",\"DiagnosedView\":{\"Title\":\"Thanks for helping fight COVID-19\",\"Body1\":{\"One\":\"Tomorrow, you’ll get your last notification asking permission to upload any new random codes your phone sent out.\",\"Other\":\"For the next {number} days, you’ll get a daily notification asking permission to upload any new random codes your phone sent out.\"},\"Body2\":\"You do not have to agree, even if you agreed the day before.\",\"Body3\":\"If you’re worried about your symptoms, get medical care as soon as you can. Take care of yourself and your family during this time.\",\"TipTitle\":\"TIP: \",\"TipBody\":\"You can prepare for your call from Public Health through the test results website. \",\"TipLinkText\":\"Test results website\",\"TipURL\":\"https://covid19results.ehealthontario.ca:4443/login\"},\"SymptomTrackerUrl\":\"https://ca.thrive.health/covid19app/action/88a5e9a7-db9e-487b-bc87-ce35035f8e5c?from=/home&navigateTo=/tracker/complete\",\"DiagnosedShareView\":{\"Title\":\"Upload random codes\",\"Body1\":\"Thanks for helping slow the spread!\",\"Body2\":\"Reminder: \",\"Body3\":\"To help keep people safe, you need to upload your random codes every day, especially if you have to leave your home.\",\"ButtonCTA\":\"Upload your random codes\"},\"BluetoothDisabled\":\"Bluetooth is off\",\"EnableBluetoothCTA\":\"You need to turn on Bluetooth in your phone’s settings so COVID Alert can work.\",\"TurnOnBluetooth\":\"Turn on Bluetooth\",\"EnDisabled\":{\"Title\":\"COVID Alert is off\",\"Body1\":\"You did not enable COVID Alert. The app needs your permission to work.\",\"CTA\":\"Enable COVID Alert\",\"AndroidTitle2\":\"Not sure about turning on Location?\",\"AndroidBody1\":\"You need to have Location turned on for COVID Alert to work. To use Bluetooth scanning, Android phones need Location setting on for all apps.\",\"AndroidBody2a\":\"Despite that, COVID Alert has \",\"AndroidBody2b\":\"no way of knowing where you are. \",\"AndroidBody2c\":\"You can check the app’s permissions in your phone’s settings. You’ll see it does not have permission for location services.\"},\"FrameworkUnavailable\":{\"Title\":\"Something went wrong\",\"Body\":\"COVID Alert is not supported by your phone’s operating system.\\n\\nMake sure your operating system is up to date.\\n\\nIf you have an Android phone, try updating your Google Play Services.\",\"CTA\":\"Get Help\"},\"UnknownProblem\":{\"Title\":\"Something went wrong\",\"Body\":\"It looks like your phone cannot support COVID Alert.\",\"CTA\":\"Get Help\"},\"NoConnectivity\":\"COVID Alert is offline\",\"NoConnectivityDetailed\":\"COVID Alert only checks for exposure if your phone is connected to the Internet.\",\"AppName\":\"COVID Alert\",\"ExternalLinkHint\":\"Opens in a new window\",\"LastCheckedMinutes\":{\"One\":\"Last checked {number} minute ago\",\"Other\":\"Last checked {number} minutes ago\"},\"LastCheckedHours\":{\"One\":\"Last checked {number} hour ago\",\"Other\":\"Last checked {number} hours ago\"},\"LastCheckedDays\":{\"One\":\"Last checked {number} day ago\",\"Other\":\"Last checked {number} days ago\"}},\"OverlayClosed\":{\"SystemStatus\":\"COVID Alert is \",\"SystemStatusOn\":\"active\",\"SystemStatusOff\":\"off\",\"NotificationStatus\":\"Notifications are \",\"NotificationStatusOff\":\"off\",\"TapPrompt\":\"Tap for menu\"},\"OverlayOpen\":{\"BluetoothCardBody\":\"You need to turn on Bluetooth in your phone’s settings so COVID Alert can work.\",\"BluetoothCardAction\":\"Turn on Bluetooth\",\"EnterCodeCardTitle\":\"Diagnosed with COVID-19?\",\"EnterCodeCardBody\":\"You need a one-time key to let people know they’ve been exposed.\",\"EnterCodeCardAction\":\"Enter your one-time key\",\"EnterCodeCardTitleDiagnosed\":\"You’re helping stop COVID-19\",\"EnterCodeCardBodyDiagnosed\":\"Thank you for doing your part to slow the spread. \",\"EnterCodeCardDiagnosedCountdown\":{\"One\":\"{number} day left!\",\"Other\":\"{number} days left!\"},\"NotificationCardStatus\":\"Notifications are off\",\"NotificationCardStatusOff\":\"OFF\",\"NotificationCardBody\":\"You will not receive notifications if you've been near anyone who has reported a COVID-19 diagnosis. Finding out potential exposures right away is essential to slowing the spread of COVID-19.\",\"NotificationCardAction\":\"Turn on notifications\",\"ExposureNotificationCardStatus\":\"Exposure notifications are \",\"ExposureNotificationCardBody\":\"COVID Alert cannot notify you as soon as it learns of a possible exposure. Finding out right away is essential to slowing the spread of COVID-19.\",\"ExposureNotificationCardAction\":\"Turn on exposure notifications\",\"NoConnectivityCardAction\":\"COVID Alert is offline\",\"NoConnectivityCardBody\":\"Connect to the Internet to notify people or check for exposures.\"},\"Info\":{\"CheckSymptoms\":\"Check symptoms\",\"SymptomsUrl\":\"https://ca.thrive.health/covid19/en\",\"TellAFriend\":\"Share app\",\"LearnMore\":\"How it works\",\"Help\":\"Help\",\"HelpUrl\":\"https://www.canada.ca/en/public-health/services/diseases/coronavirus-disease-covid-19/covid-alert/help.html\",\"GetCode\":\"Get a one-time key\",\"ChangeLanguage\":\"Change language\",\"ChangeRegion\":\"Change province or territory\",\"Privacy\":\"How it protects your privacy\",\"SettingsTitle\":\"Settings\",\"InformationTitle\":\"About COVID Alert\"},\"Landing\":{\"En\":\"English\",\"Fr\":\"Français\",\"AltText\":\"Illustration of 8 people enjoying a public space. There’s a person with a walking cane, a person in a wheelchair, a person wearing a hijab, several people of colour, and a representation of gender diversity.\",\"CanadaAltText\":\"Symbol of the Government of Canada\"},\"LanguageSelect\":{\"Title\":\"Language\",\"En\":\"English (Canada)\",\"Fr\":\"Français (Canada)\",\"PtBR\":\"Portuguese (Brazil)\",\"EnShort\":\"English\",\"FrShort\":\"Français\",\"PtBRShort\":\"Portuguese (Brazil)\",\"Close\":\"Close\"},\"Tutorial\":{\"step-1Title\":\"How COVID Alert works\",\"step-1AltText\":\"A hand-drawn illustration of a mobile phone in a pocket, sending and receiving signals.\",\"step-1\":\"The app runs in the background and will not interrupt your activities.\\n\\nWhenever you’re near someone else with COVID Alert, both phones exchange random codes every 5 minutes.\\n\\nThe random codes change often and cannot be used to identify you. \",\"step-2Title\":\"What’s an exposure?\",\"step-2AltText\":\"A hand-drawn illustration of 2 mobile phones side-by-side with a timer clock connecting both phones.\",\"step-2\":\"The app estimates how near people are by the strength of Bluetooth signals.\\n\\nIf you’re closer than 2 metres for more than 15 minutes, the app will record an exposure.\",\"step-3Title\":\"Getting a positive test\",\"step-3AltText\":\"A hand-drawn illustration of a mobile phone uploading a numeric code to a cloud.\",\"step-3\":\"If someone with the app is diagnosed with COVID-19, they can choose to upload the random codes their phone sent. The codes go into a central server.\\n\\nThe server only gets the codes. It does not get any information about the person.\",\"step-4Title\":\"Looking for exposures\",\"step-4AltText\":\"A hand-drawn illustration of a mobile phone uploading a numeric code to a cloud.\",\"step-4\":\"Every day, whenever it has an Internet connection, your phone will get a list of the random codes from people who reported a diagnosis.\\n\\nIf it finds codes that match, the app notifies you that you've been exposed and explains what to do next.\",\"ActionBack\":\"Back\",\"ActionNext\":\"Next\",\"ActionEnd\":\"Done\",\"Close\":\"Close\"},\"Sharing\":{\"Title\":\"Tell your friends about COVID Alert\",\"SubTitle\":\"Every person using COVID Alert helps to slow the spread of COVID-19. Sharing this app will not share any of your personal information.\",\"Platform-messages\":\"Share to Messages\",\"Platform-instagram\":\"Share to Instagram\",\"More\":\"More apps\",\"Message\":\"Join me in helping to slow the spread of COVID-19. Download the COVID Alert app: https://covidshield.app\",\"InstagramImageUrl\":\"https://user-images.githubusercontent.com/5274722/84658989-b9ba6b00-aee4-11ea-84d4-d840527467b4.png\",\"Close\":\"Close\"},\"Onboarding\":{\"Step\":\"Step\",\"Of\":\"of\",\"ActionNext\":\"Next\",\"ActionEndSkip\":\"Skip\",\"ActionEnd\":\"Done\",\"ActionBack\":\"Back\",\"Start\":{\"Title\":\"Together, let’s stop the spread of COVID-19\",\"ImageAltText\":\"A hand-drawn illustration with lots of different people in it. Dotted lines show their paths crossing and leading to a smartphone below.\",\"Body1\":\"COVID Alert helps us break the cycle of infection. The app can let people know of possible exposures before any symptoms appear. \",\"Body2\":\"That way, we can take care of ourselves and protect our communities.\"},\"WhatItsNot\":{\"Title\":\"What COVID Alert does not do\",\"ImageAltText\":\"A hand-drawn illustration with many houses and a high-rise building on a curving street. Small message bubbles appear above each home.\",\"Body1\":\"The app will not tell you in the moment if you’re currently near someone who’s been diagnosed.\",\"Body2\":\"It will not tell you about outbreaks in your community.\"},\"Anonymous\":{\"Title\":\"Your privacy is protected\",\"ImageAltText\":\"A hand-drawn illustration of shaded glasses and hat to go incognito. Above the hat, a location pin icon is crossed out.\",\"Body1\":\"COVID Alert **does not use GPS** or track your location.\",\"Body2\":\"It has **no way of knowing**:\",\"Bullet1\":\"Your location.\",\"Bullet2\":\"Your name or address.\",\"Bullet3\":\"Your phone's contacts.\",\"Bullet4\":\"Your health information.\",\"Bullet5\":\"The health information of anyone you’re near.\"},\"HowItWorks\":{\"Title\":\"How it works\",\"ImageAltText\":\"A hand-drawn illustration of 3 mobile phones sending out random codes via bluetooth.\",\"Body1\":\"The app uses Bluetooth to exchange random codes with nearby phones.\",\"Body2\":\"Every day, it checks a list of random codes from people who tell the app they tested positive.\",\"Body3\":\"If you’ve had close contact with one of those people in the past 14 days, you’ll get a notification.\",\"HowItWorksCTA\":\"Learn more about how it works\"},\"PartOf\":{\"Title\":\"One part of public health\",\"ImageAltText\":\"A hand-drawn illustration of different ways of fighting COVID-19, including hand sanitizer, handwashing, face mask and the COVID Alert app.\",\"Body1\":\"COVID Alert is just one part of the public health effort to stop the spread of COVID-19.\",\"Body2\":\"Follow all public health guidelines in your area.\",\"Body3\":\"COVID Alert does not replace medical advice. If you get sick, contact your doctor or other healthcare provider.\"},\"Permissions\":{\"Title\":\"The app will now ask your permission\",\"ImageAltText\":\"A hand-drawn illustration of a mobile phone displaying a dialogue box with a red X and a green check mark on the screen.\",\"Body1\":\"**Allow the app** to start logging random codes or “random IDs” when you’re near other phones. The app will access the date, duration and signal strength related to the random codes, but they never leave your phone.\",\"Body2\":\"You’ll also need to **let the app send you notifications**.\",\"PrivacyButtonCTA\":\"Learn more about privacy\"}},\"Privacy\":{\"Title\":\"Privacy policy\",\"Close\":\"Close\"},\"ThankYou\":{\"Title\":\"Thank you for helping\",\"Body\":\"Exposure notifications are on. You will receive a message if COVID Alert detects that you've been near someone who has reported a COVID-19 diagnosis.\",\"Dismiss\":\"Dismiss\"},\"DataUpload\":{\"Cancel\":\"Cancel\",\"InfoSmall\":\"Your random codes will not be uploaded unless you give permission in the next step.\",\"ShareToast\":\"Random codes uploaded successfully\",\"Step1\":{\"Title\":\"Let people know they may have been exposed\",\"Body1a\":\"Step 1. \",\"Body1b\":\"Enter the one-time key you got when you were diagnosed.\",\"Body2a\":\"Step 2. \",\"Body2b\":\"Agree that COVID Alert can let people know they were exposed.\",\"Body3a\":\"Step 3. \",\"Body3b\":\"Allow your phone to share your random codes.\",\"Body4a\":\"Nobody will get any information about you \",\"Body4b\":\"or the time you were near them.\",\"CTA\":\"Next\",\"NoCode\":\"Need a one-time key?\"},\"FormView\":{\"Title\":\"Enter your one-time key\",\"Body\":\"Enter the key you got when you were diagnosed.\",\"Action\":\"Submit\",\"InputLabel\":\"COVID Alert key\",\"ErrorTitle\":\"One-time key not recognized\",\"ErrorBody\":\"Your key could not be recognized. Please try again.\",\"ErrorAction\":\"OK\"},\"ConsentView\":{\"Title\":\"Now you can upload your codes\",\"Body1\":\"Your phone will ask your permission to upload your random codes or “random IDs” from the past 14 days.\",\"Body2a\":\"Nobody will get any information about you \",\"Body2b\":\"or the time you were near them.\",\"Body3\":\"You can help slow the spread of COVID-19 if you agree.\",\"Action\":\"Agree\",\"ErrorTitle\":\"Random codes could not be uploaded\",\"ErrorBody\":\"You did not give permission.\",\"ErrorAction\":\"OK\"},\"NoCode\":{\"NoRegion\":{\"Title\":\"You skipped choosing province or territory\",\"Body\":\"In some provinces and territories, people cannot yet report a COVID-19 diagnosis through this app.\\n\\nTo find out if you can get a one-time key, you need to choose your area.\",\"ChooseRegionCTA\":\"Choose province or territory\"},\"RegionCovered\":{\"ON\":{\"Title\":\"Get a one-time key\",\"Body\":\"If you’ve tested positive in Ontario:\",\"Body2\":\"Go to the COVID-19 Test Results Website and enter your details.\",\"Body3\":\"Review your test results.\",\"Body4\":\"Get the one-time key.\",\"Body5\":\"Come back here and enter the key.\",\"CTA\":\"Go to COVID-19 Test Results Website\",\"Link\":\"https://covid19results.ehealthontario.ca:4443/\"}},\"RegionNotCovered\":{\"Title\":\"No reporting yet in your area\",\"Body\":\"People in your area cannot yet get a one-time key.\\n\\nYou will not be able to let people know they were exposed. But you can still self-isolate for 14 days, and:\",\"Body2\":\"Keep your community safe.\",\"Body3\":\"Protect people and pets you live with.\",\"Body4\":\"Take care of yourself.\"}}},\"Notification\":{\"ExposedMessageTitle\":\"You’ve been exposed\",\"ExposedMessageBody\":\"You’ve had close contact with someone who reported a COVID-19 diagnosis through the app. Learn more about what to do next.\",\"OffMessageTitle\":\"COVID Alert is off\",\"OffMessageBody\":\"Turn on COVID Alert to get notified if you've been near someone who has reported a COVID-19 diagnosis.\",\"DailyUploadNotificationTitle\":\"Upload new random codes\",\"DailyUploadNotificationBody\":\"Help slow the spread of COVID-19 and upload your new random codes.\"},\"Partners\":{\"Label\":\"Developed in partnership with\"},\"BottomSheet\":{\"Collapse\":\"Close\",\"OnStatus\":\"COVID Alert is on, Tap for more information\",\"OffStatus\":\"COVID Alert is off, Tap for more information\"},\"RegionLanding\":{\"Title\":\"Choose your province or territory\",\"Body1\":\"Provincial and territorial governments are working to support COVID Alert across Canada.\",\"Body2\":\"In some places, people cannot yet report a COVID-19 diagnosis through this app.\",\"RegionSelectBtn\":\"Choose province or territory\"},\"RegionPicker\":{\"Title\":\"Where do you live? (optional)\",\"SettingsTitle\":\"Province or territory\",\"Close\":\"Close\",\"Body\":\"Choose your region to check if you can report a diagnosis through this app.\\n\\nYour region will never be shared with anyone.\",\"Skip\":\"Skip\",\"GetStarted\":\"Get started\",\"Optional\":\"* Optional\",\"AB\":\"Alberta\",\"BC\":\"British Columbia\",\"MB\":\"Manitoba\",\"NB\":\"New Brunswick\",\"NL\":\"Newfoundland and Labrador\",\"NT\":\"Northwest Territories\",\"NS\":\"Nova Scotia\",\"NU\":\"Nunavut\",\"ON\":\"Ontario\",\"PE\":\"Prince Edward Island\",\"QC\":\"Quebec\",\"SK\":\"Saskatchewan\",\"YT\":\"Yukon\",\"None\":\"Prefer not to say\"},\"RegionalGuidance\":{\"CA\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://ca.thrive.health/covid19/en\"},\"AB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://myhealth.alberta.ca/Journey/COVID-19/Pages/PubAsympIsolate.aspx\"},\"BC\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://bc.thrive.health/covid19/en\"},\"MB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://sharedhealthmb.ca/covid19/screening-tool/\"},\"NB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www2.gnb.ca/content/gnb/en/departments/ocmoh/cdc/content/respiratory_diseases/coronavirus/coronavirusexposure.html#/app/symptom-checker/guides/399/what-to-do\"},\"NL\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://nl.thrive.health/covid19/en\"},\"NT\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.gov.nt.ca/covid-19/en/services/nwt-online-covid-19-self-assessment-tool\"},\"NS\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://novascotia.ca/coronavirus/when-to-seek-help/#if-exposed\"},\"NU\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://nu.thrive.health/covid19/en\"},\"ON\":{\"CTA\":\"Find out what to do next\",\"URL\":\"https://ontario.ca/covidalert-exposed\"},\"PE\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.princeedwardisland.ca/en/information/health-and-wellness/covid-19-self-isolation\"},\"QC\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.quebec.ca/en/health/health-issues/a-z/2019-coronavirus/instructions-for-people-who-have-been-in-contact-with-a-confirmed-case-of-covid-19/\"},\"SK\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.saskatchewan.ca/government/health-care-administration-and-provider-resources/treatment-procedures-and-guidelines/emerging-public-health-issues/2019-novel-coronavirus/covid-19-self-assessment\"},\"YT\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://service.yukon.ca/en/covid-19-self-assessment/\"}},\"HowToIsolate\":{\"Title\":\"How to self-isolate\",\"Intro\":\"Try your best to:\",\"Body1\":\"Stay home unless it’s to get medical care.\",\"Body2\":\"Avoid public transportation like buses or taxis.\",\"Body3\":\"Ask for help to get groceries and supplies dropped off at your door.\",\"Body4\":\"Stay in a separate room and use a separate bathroom from others in your home, if possible.\",\"Body5\":\"Wear a mask safely any time you cannot take the above actions.\"},\"A11yList\":{\"Start\":\"List start\",\"End\":\"List end\",\"Bullet\":\"Bullet\"}},\"fr\":{\"Home\":{\"NoExposureDetected\":{\"AllSetTitle\":\"Vous voilà prêt!\",\"RegionCovered\":{\"Title\":\"Aucune exposition détectée\",\"Body\":\"Vous n’avez été près d’aucune personne ayant signalé un diagnostic de COVID-19 avec cette application.\",\"GuidanceUrl\":\"https://www.canada.ca/fr/sante-publique/services/publications/maladies-et-affections/covid-19-comment-isoler-chez-soi.html\",\"AllSetBody\":\"Votre téléphone utilise maintenant Bluetooth pour collecter les codes provenant des téléphones voisins.\"},\"NoRegion\":{\"Title\":\"Aucune exposition détectée\",\"Body\":\"Vous n’avez été près d’aucune personne ayant signalé un diagnostic de COVID-19 avec cette application.\\n\\nToutefois, dans certaines provinces et certains territoires, on ne peut pas encore signaler de diagnostics de COVID-19 avec cette application.\",\"AllSetBody\":\"Nous vous informerons dès que les personnes en dehors de l’Ontario peuvent signaler des diagnostics avec Alerte COVID.\\n\\nIl est tout de même utile de garder Alerte COVID activée.\\n\\nDe cette façon, vous pourrez être avisé dès que les personnes dont vous avez été près signalent un diagnostic.\"},\"RegionNotCovered\":{\"Title\":\"Pas encore de signalement dans votre région\",\"Body\":\"Les personnes de votre province ou territoire ne peuvent pas encore signaler de diagnostics de COVID-19 avec cette application.\\n\\nIl est tout de même utile d’activer Alerte COVID. Quand les personnes pourront signaler un diagnostic, vous serez ainsi avisé si jamais vous avez été près d’elles.\",\"GuidanceUrl\":\"https://www.canada.ca/fr/sante-publique/services/publications/maladies-et-affections/covid-19-comment-isoler-chez-soi.html\",\"AllSetBody\":\"Nous vous informerons dès que les personnes de votre région peuvent signaler un diagnostic avec Alerte COVID.\\n\\nIl est tout de même utile de garder Alerte COVID activée.\\n\\nDe cette façon, vous pourrez être avisé dès que les personnes dont vous avez été près signalent un diagnostic.\"}},\"ExposureDetected\":{\"CA\":{\"Title\":\"Vous avez été exposé au cours des 14 derniers jours\",\"Title2\":\"Que faire maintenant?\",\"Body1\":\"Vous avez été près d’une personne qui a signalé un diagnostic de COVID-19 avec l’application. Votre proximité a duré 15 minutes ou plus.\",\"Body2\":\"Vous êtes à risque d’être infecté. Surveillez attentivement vos symptômes et \",\"Body3\":\"pensez à vous isoler pendant 14 jours.\",\"HowToIsolateCTA\":\"Comment vous isoler\"},\"ON\":{\"Title\":\"Vous avez été exposé au cours des 14 derniers jours\",\"Title2\":\"Que faire maintenant?\",\"Body1\":\"Vous avez été près d’une personne qui a signalé un diagnostic de COVID-19 avec l’application. Votre proximité a duré 15 minutes ou plus.\",\"Body2\":\"Vous êtes à risque d’être infecté.\",\"HowToIsolateCTA\":\"Comment vous isoler\"}},\"ChooseRegionCTA\":\"Sélectionnez une province ou un territoire\",\"How\":\"Diagnosed with COVID-19?\",\"CTA\":\"Prochaines étapes\",\"HowUrl\":\"https://www.canada.ca/\",\"DiagnosedView\":{\"Title\":\"Merci d’aider à lutter contre la COVID\",\"Body1\":{\"One\":\"Tomorrow, you’ll get your last notification asking permission to upload any new random codes your phone sent out.\",\"Other\":\"Au cours des {number} prochains jours, vous recevrez une notification quotidienne vous demandant l’autorisation de téléverser tout nouveau code aléatoire émis par votre téléphone.\"},\"Body2\":\"Vous n’êtes pas tenu d’accepter, même si vous avez accepté le jour d’avant.\",\"Body3\":\"Si vos symptômes vous inquiètent, cherchez à obtenir des soins médicaux dès que vous le pouvez. Prenez soin de vous et de votre famille pendant ce temps.\",\"TipTitle\":\"CONSEIL : \",\"TipBody\":\"Vous pouvez vous préparer pour l’appel de la Santé publique sur le site Web des résultats du test.\",\"TipLinkText\":\"Site des résultats du test\",\"TipURL\":\"https://covid19results.ehealthontario.ca:4443/login\"},\"SymptomTrackerUrl\":\"https://ca.thrive.health/covid19app/action/88a5e9a7-db9e-487b-bc87-ce35035f8e5c?from=/home&navigateTo=/tracker/complete\",\"DiagnosedShareView\":{\"Title\":\"Téléverser les codes aléatoires\",\"Body1\":\"Merci d’aider à ralentir la propagation de la COVID-19!\",\"Body2\":\"Rappel : \",\"Body3\":\"Pour contribuer à la sécurité des autres, vous devez téléverser vos codes aléatoires tous les jours, surtout si vous avez à sortir de la maison.\",\"ButtonCTA\":\"Téléverser vos codes aléatoires\"},\"BluetoothDisabled\":\"Bluetooth désactivé\",\"EnableBluetoothCTA\":\"Vous devez activer la fonction Bluetooth dans les paramètres de votre téléphone pour qu’Alerte COVID fonctionne.\",\"TurnOnBluetooth\":\"Activez Bluetooth\",\"EnDisabled\":{\"Title\":\"Alerte COVID est désactivée\",\"Body1\":\"Vous n’avez pas activé Alerte COVID. L’application a besoin de votre autorisation pour fonctionner.\",\"CTA\":\"Activer Alerte COVID\",\"AndroidTitle2\":\"Vous hésitez à activer la localisation?\",\"AndroidBody1\":\"Il faut activer la localisation pour qu’Alerte COVID fonctionne. Avec Android, la recherche Bluetooth n’est possible que si la localisation est activée pour toutes les applications.\",\"AndroidBody2a\":\"Malgré cela, Alerte COVID \",\"AndroidBody2b\":\"ne peut pas savoir où vous êtes. \",\"AndroidBody2c\":\"Vous pouvez vous en assurer en vérifiant les autorisations d’Alerte COVID dans les paramètres de votre téléphone. La localisation n’est pas autorisée.\"},\"FrameworkUnavailable\":{\"Title\":\"Une erreur s’est produite\",\"Body\":\"Alerte COVID n’est pas prise en charge par le système d’exploitation de votre téléphone.\\n\\nVérifiez que votre système d’exploitation est à jour.\\n\\nSi vous avez un téléphone Android, pensez à mettre les services Google Play à jour.\",\"CTA\":\"Trouver de l’aide\"},\"UnknownProblem\":{\"Title\":\"Une erreur s’est produite\",\"Body\":\"Il semble que votre téléphone ne puisse pas prendre en charge Alerte COVID.\",\"CTA\":\"Trouver de l’aide\"},\"NoConnectivity\":\"Alerte COVID est hors ligne\",\"NoConnectivityDetailed\":\"Alerte COVID vérifie s’il y a des expositions seulement quand votre téléphone est connecté à Internet.\",\"AppName\":\"Alerte COVID\",\"ExternalLinkHint\":\"Ouvre dans une nouvelle fenêtre\",\"LastCheckedMinutes\":{\"One\":\"Dernière vérification il y a {number} minute\",\"Other\":\"Dernière vérification il y a {number} minutes\"},\"LastCheckedHours\":{\"One\":\"Dernière vérification il y a {number} heure\",\"Other\":\"Dernière vérification il y a {number} heures\"},\"LastCheckedDays\":{\"One\":\"Dernière vérification il y a {number} jour\",\"Other\":\"Dernière vérification il y a {number} jours\"}},\"OverlayClosed\":{\"SystemStatus\":\"Alerte COVID est \",\"SystemStatusOn\":\"activée\",\"SystemStatusOff\":\"désactivée\",\"NotificationStatus\":\"Notifications \",\"NotificationStatusOff\":\"désactivées\",\"TapPrompt\":\"Appuyez pour voir le menu\"},\"OverlayOpen\":{\"BluetoothCardBody\":\"Vous devez l’activer dans les paramètres de votre téléphone pour qu’Alerte COVID fonctionne.\",\"BluetoothCardAction\":\"Activez Bluetooth\",\"EnterCodeCardTitle\":\"Vous avez la COVID-19?\",\"EnterCodeCardBody\":\"Vous avez besoin d’une clé à usage unique pour aviser les autres personnes d’une exposition.\",\"EnterCodeCardAction\":\"Entrer votre clé\",\"EnterCodeCardTitleDiagnosed\":\"Vous contribuez à freiner la COVID\",\"EnterCodeCardBodyDiagnosed\":\"Merci de faire votre part pour freiner la propagation de la COVID-19. \",\"EnterCodeCardDiagnosedCountdown\":{\"One\":\"Il vous reste {number} jour!\",\"Other\":\"Il vous reste {number} jours!\"},\"NotificationCardStatus\":\"Les notifications sont désactivées\",\"NotificationCardStatusOff\":\"DÉSACTIVÉES\",\"NotificationCardBody\":\"Alerte COVID ne peut pas vous aviser dès qu’il découvre une exposition potentielle. Le fait d’être notifié rapidement est essentiel pour ralentir la propagation de la COVID-19.\",\"NotificationCardAction\":\"Activer les notifications\",\"ExposureNotificationCardStatus\":\"Les notifications d’exposition à la COVID-19 sont \",\"ExposureNotificationCardBody\":\"Alerte COVID ne peut pas vous aviser de la découverte d’une exposition potentielle. Le fait d’être notifié rapidement est essentiel pour ralentir la propagation de la COVID-19.\",\"ExposureNotificationCardAction\":\"Activez les notifications d'exposition\",\"NoConnectivityCardAction\":\"Alerte COVID est hors ligne\",\"NoConnectivityCardBody\":\"Connectez-vous à Internet pour aviser les autres personnes ou pour vérifier si vous avez été exposé.\"},\"Info\":{\"CheckSymptoms\":\"Vérifier vos symptômes\",\"SymptomsUrl\":\"https://ca.thrive.health/covid19/fr\",\"TellAFriend\":\"Partager l’application\",\"LearnMore\":\"Fonctionnement\",\"Help\":\"Aide\",\"HelpUrl\":\"https://www.canada.ca/fr/sante-publique/services/maladies/maladie-coronavirus-covid-19/alerte-covid/aide.html\",\"GetCode\":\"Obtenir une clé à usage unique\",\"ChangeLanguage\":\"Modifier la langue\",\"ChangeRegion\":\"Modifier la province ou le territoire\",\"Privacy\":\"Protection de votre vie privée\",\"SettingsTitle\":\"Paramètres\",\"InformationTitle\":\"À propos d’Alerte COVID\"},\"Landing\":{\"En\":\"English\",\"Fr\":\"Français\",\"AltText\":\"Illustration de 8 personnes profitant de l’espace public. Il y a une personne avec une canne blanche, une autre en fauteuil roulant, une autre avec un hijab, plusieurs personnes de couleur, et une représentation de la diversité de genre.\",\"CanadaAltText\":\"Symbole du gouvernement du Canada\"},\"LanguageSelect\":{\"Title\":\"Langue\",\"En\":\"English (Canada)\",\"Fr\":\"Français (Canada)\",\"PtBR\":\"Portugais (Brésil)\",\"EnShort\":\"English\",\"FrShort\":\"Français\",\"PtBRShort\":\"Portugais (Brésil)\",\"Close\":\"Fermer\"},\"Tutorial\":{\"step-1Title\":\"Fonctionnement d’Alerte COVID\",\"step-1AltText\":\"Dessin à la main d’un téléphone mobile dans une poche, qui envoie et reçoit des signaux.\",\"step-1\":\"L’application s’exécute en arrière-plan sans interrompre vos activités.\\n\\nQuand vous serez près d’une personne ayant Alerte COVID, vos téléphones s’échangeront des codes aléatoires toutes les 5 minutes.\\n\\nCes codes changent souvent et ne peuvent pas servir à vous identifier.\",\"step-2Title\":\"Qu’est-ce qu’une exposition?\",\"step-2AltText\":\"Dessin à la main de 2 téléphones mobiles côte à côte avec un chronomètre qui relie les deux téléphones.\",\"step-2\":\"L’application estime la distance entre vous et d’autres personnes grâce à la puissance des signaux Bluetooth.\\n\\nSi vous êtes à une distance de moins de 2 mètres pendant plus de 15 minutes, l’application enregistre une exposition.\",\"step-3Title\":\"Quand une personne reçoit un test positif\",\"step-3AltText\":\"Dessin à la main d’un téléphone mobile téléversant un code chiffré vers un nuage.\",\"step-3\":\"Si une personne ayant l’application a un diagnostic de COVID-19, elle peut décider de téléverser tous les codes aléatoires émis par son téléphone vers un serveur central.\\n\\nLe serveur ne reçoit que les codes. Il ne reçoit aucune information personnelle.\",\"step-4Title\":\"Découverte des expositions\",\"step-4AltText\":\"Dessin à la main d’un téléphone mobile émettant une liste de codes chiffrés. L’icône de la loupe de recherche met en évidence l’un des codes de la liste.\",\"step-4\":\"Chaque jour, quand votre téléphone a une connexion Internet, il obtient une liste de codes aléatoires émis par les personnes qui ont signalé un diagnostic.\\n\\nSi l’application reconnaît des codes dans cette liste, elle vous dira que vous avez été exposé et vous expliquera quoi faire ensuite.\",\"ActionBack\":\"Précédent\",\"ActionNext\":\"Suivant\",\"ActionEnd\":\"Terminé\",\"Close\":\"Fermer\"},\"Sharing\":{\"Title\":\"Partager l’application\",\"SubTitle\":\"Chaque personne utilisant Alerte COVID aide à ralentir la transmission de la COVID-19. Partager cette application ne partage aucune donnée privée.\",\"Platform-messages\":\"Partager avec Messages\",\"Platform-instagram\":\"Partager avec Instagram\",\"More\":\"Plus d'applications\",\"Message\":\"Joignez-vous à moi pour aider à ralentir la transmission de la COVID-19. Téléchargez l'application Alerte COVID : https://covidshield.app\",\"InstagramImageUrl\":\"https://user-images.githubusercontent.com/5274722/84658989-b9ba6b00-aee4-11ea-84d4-d840527467b4.png\",\"Close\":\"Fermer\"},\"Onboarding\":{\"Step\":\"Étape\",\"Of\":\"de\",\"ActionNext\":\"Suivant\",\"ActionEndSkip\":\"Ignorer\",\"ActionEnd\":\"Terminé\",\"ActionBack\":\"Précédent\",\"Start\":{\"Title\":\"Unissons-nous pour freiner la propagation de la COVID-19\",\"ImageAltText\":\"Dessin à la main avec plusieurs personnes différentes dedans. Leurs chemins en lignes pointillées se croisent et mènent à un téléphone intelligent plus bas.\",\"Body1\":\"Alerte COVID nous aide à briser le cycle d’infection. L’application permet d’aviser les personnes en cas d’exposition potentielle avant même que des symptômes apparaissent. \",\"Body2\":\"Nous pouvons ainsi prendre soin de nous et protéger nos communautés.\"},\"WhatItsNot\":{\"Title\":\"Ce qu’Alerte COVID ne fait pas\",\"ImageAltText\":\"Dessin à la main d’une rue sinueuse avec plusieurs maisons et un immeuble en hauteur. De petites infobulles apparaissent au-dessus de chaque bâtiment.\",\"Body1\":\"L’application ne vous dira pas sur-le-champ que vous êtes près d’une personne ayant eu un diagnostic.\",\"Body2\":\"Elle ne vous renseignera pas sur les éclosions de COVID-19 dans votre collectivité.\"},\"Anonymous\":{\"Title\":\"Votre vie privée est protégée\",\"ImageAltText\":\"Dessin à la main d’une paire de lunettes de soleil et d’un chapeau pour passer incognito. Au-dessus du chapeau, une icône de marqueur de géolocalisation est biffée.\",\"Body1\":\"Alerte COVID **n’utilise pas le GPS** et ne suit pas votre emplacement.\",\"Body2\":\"L’application **n’a aucun moyen** de connaître :\",\"Bullet1\":\"Votre emplacement.\",\"Bullet2\":\"Votre nom ou votre adresse.\",\"Bullet3\":\"Les contacts de votre téléphone.\",\"Bullet4\":\"Vos informations de santé.\",\"Bullet5\":\"Les informations de santé des personnes à proximité.\"},\"HowItWorks\":{\"Title\":\"Fonctionnement\",\"ImageAltText\":\"Dessin à la main de 3 téléphones mobiles émettant des codes aléatoires en utilisant Bluetooth.\",\"Body1\":\"L’application utilise Bluetooth pour échanger des codes aléatoires avec les téléphones à proximité.\",\"Body2\":\"Chaque jour, elle vérifie une liste de codes aléatoires provenant des personnes ayant signalé un test positif à l’application.\",\"Body3\":\"Si vous avez eu un contact étroit avec l’une de ces personnes au cours des 14 derniers jours, vous recevrez une notification.\",\"HowItWorksCTA\":\"En savoir plus sur le fonctionnement\"},\"PartOf\":{\"Title\":\"L’un des efforts de santé publique\",\"ImageAltText\":\"Dessin à la main de divers moyens de lutter contre la COVID-19, dont un désinfectant pour les mains, un couvre-visage, des mains avec du savon et l’application Alerte COIVID.\",\"Body1\":\"Alerte COVID n’est qu’une partie des efforts de santé publique visant à freiner la propagation de la COVID-19.\",\"Body2\":\"Continuez à suivre les recommandations de santé publique de votre région.\",\"Body3\":\"Alerte COVID ne remplace pas un avis médical. Si vous tombez malade, contactez votre médecin ou un professionnel de la santé.\"},\"Permissions\":{\"Title\":\"L’application demandera votre autorisation\",\"ImageAltText\":\"Dessin à la main d’un téléphone mobile dont l’écran affiche une fenêtre de dialogue avec un X rouge et un crochet vert.\",\"Body1\":\"**Permettez à l’application** de collecter des codes aléatoires quand vous êtes près d’autres téléphones. L’application connaîtra la date, la durée et la puissance de signal associées à ces codes, mais ces données resteront sur votre téléphone. \",\"Body2\":\"Vous devrez aussi **lui permettre de vous envoyer des notifications**.\",\"PrivacyButtonCTA\":\"En savoir plus sur la confidentialité\"}},\"Privacy\":{\"Title\":\"Politique de confidentialité\",\"Close\":\"Fermer\"},\"ThankYou\":{\"Title\":\"Merci d'aider\",\"Body\":\"Les notifications d’exposition sont activées. Si Alerte COVID détecte que vous avez possiblement été exposé(e) à la COVID-19, vous recevrez une notification.\",\"Dismiss\":\"OK\"},\"DataUpload\":{\"Cancel\":\"Annuler\",\"InfoSmall\":\"Vos identifiants aléatoires ne seront pas partagés, à moins que vous donniez votre permission à l'étape suivante.\",\"ShareToast\":\"Identifiants aléatoires partagés avec succès\",\"Step1\":{\"Title\":\"Aviser les autres personnes d’une exposition potentielle\",\"Body1a\":\"Étape 1 : \",\"Body1b\":\"Vous entrez la clé à usage unique reçue lors de votre diagnostic.\",\"Body2a\":\"Étape 2 : \",\"Body2b\":\"Vous acceptez qu’Alerte COVID avise les personnes qu’elles ont été exposées.\",\"Body3a\":\"Étape 3 : \",\"Body3b\":\"Vous autorisez votre téléphone à partager vos codes aléatoires.\",\"Body4a\":\"Personne ne recevra d’information sur vous \",\"Body4b\":\"ou sur le moment de votre proximité.\",\"CTA\":\"Suivant\",\"NoCode\":\"Vous n’avez pas de clé à usage unique?\"},\"FormView\":{\"Title\":\"Entrez votre clé à usage unique\",\"Body\":\"Entrez la clé que vous avez reçue lors de votre diagnostic.\",\"Action\":\"Envoyer\",\"InputLabel\":\"code Alerte COVID\",\"ErrorTitle\":\"Clé à usage unique non reconnue\",\"ErrorBody\":\"Votre clé n’a pas pu être reconnue. Veuillez essayer à nouveau.\",\"ErrorAction\":\"OK\"},\"ConsentView\":{\"Title\":\"Vous pouvez maintenant téléverser vos codes\",\"Body1\":\"Votre téléphone vous demandera l’autorisation de téléverser vos codes ou « identifiants » aléatoires des 14 derniers jours.\",\"Body2a\":\"Personne ne recevra d’information sur vous \",\"Body2b\":\"ou sur le moment de votre proximité.\",\"Body3\":\"Vous pouvez aider à ralentir la propagation de la COVID-19 si vous acceptez.\",\"Action\":\"Accepter\",\"ErrorTitle\":\"Les codes aléatoires n’ont pas pu être téléversés\",\"ErrorBody\":\"Vous n’avez pas donné votre autorisation.\",\"ErrorAction\":\"OK\"},\"NoCode\":{\"NoRegion\":{\"Title\":\"Vous n’avez pas choisi de province ou de territoire\",\"Body\":\"Dans certaines provinces et certains territoires, on ne peut pas encore signaler de diagnostics de COVID-19 avec cette application.\\n\\nPour savoir si vous pouvez obtenir une clé à usage unique, vous devez sélectionner votre région.\",\"ChooseRegionCTA\":\"Sélectionner une province ou un territoire\"},\"RegionCovered\":{\"ON\":{\"Title\":\"Obtenir une clé à usage unique\",\"Body\":\"Si vous avez reçu un test positif en Ontario :\",\"Body2\":\"Allez sur le site Web des Résultats du test de diagnostic de la COVID-19 puis entrez vos informations.\",\"Body3\":\"Consultez les résultats de votre test.\",\"Body4\":\"Notez la clé à usage unique.\",\"Body5\":\"Revenez ici et entrez la clé.\",\"CTA\":\"Aller sur le site des Résultats du test pour la COVID-19\",\"Link\":\"https://covid19results.ehealthontario.ca:4443/login\"}},\"RegionNotCovered\":{\"Title\":\"Pas encore de signalement dans votre région\",\"Body\":\"Les personnes de votre région ne peuvent pas encore obtenir de clé à usage unique.\\n\\nVous ne pourrez pas aviser les personnes d’une exposition. Mais vous pouvez tout de même vous isoler pendant 14 jours, et ainsi :\",\"Body2\":\"Assurer la sécurité de votre communauté.\",\"Body3\":\"Protéger les personnes et les animaux vivant avec vous.\",\"Body4\":\"Prendre soin de vous.\"}}},\"Notification\":{\"ExposedMessageTitle\":\"Vous avez été exposé\",\"ExposedMessageBody\":\"Vous avez eu un contact étroit avec une personne qui a signalé un diagnostic de COVID-19 au moyen de l’application. Informez-vous sur les étapes à suivre.\",\"OffMessageTitle\":\"Alerte COVID est désactivée\",\"OffMessageBody\":\"Activez Alerte COVID pour être avisé en cas d’exposition potentielle à la COVID-19.\",\"DailyUploadNotificationTitle\":\"Téléversez vos nouveaux codes aléatoires\",\"DailyUploadNotificationBody\":\"Aidez à ralentir la propagation de la COVID-19 en téléversant vos nouveaux codes aléatoires.\"},\"Partners\":{\"Label\":\"Conçu en partenariat avec\"},\"BottomSheet\":{\"Collapse\":\"Fermer\",\"OnStatus\":\"Alerte COVID est ACTIVÉE, Appuyez pour voir le menu\",\"OffStatus\":\"Alerte COVID est DÉSACTIVÉE, Appuyez pour voir le menu\"},\"RegionLanding\":{\"Title\":\"Sélectionnez votre province ou territoire\",\"Body1\":\"Les gouvernements provinciaux et territoriaux s’efforcent de rendre Alerte COVID utilisable partout au Canada.\",\"Body2\":\"Dans certains endroits, on ne peut pas encore signaler de diagnostics de COVID-19 avec cette application.\",\"RegionSelectBtn\":\"Sélectionnez une province ou un territoire\"},\"RegionPicker\":{\"Title\":\"Où habitez-vous? (facultatif)\",\"SettingsTitle\":\"Province ou territoire\",\"Close\":\"Fermer\",\"Body\":\"Sélectionnez votre région pour savoir si vous pouvez signaler un diagnostic à l’aide de l’application.\\n\\nLa région où vous habitez ne sera jamais transmise à personne.\",\"Skip\":\"Ignorer\",\"GetStarted\":\"Commencer\",\"Optional\":\"* Facultatif\",\"AB\":\"Alberta\",\"BC\":\"Colombie-Britannique\",\"MB\":\"Manitoba\",\"NB\":\"Nouveau-Brunswick\",\"NL\":\"Terre-Neuve-et-Labrador\",\"NT\":\"Territoires du Nord-Ouest\",\"NS\":\"Nouvelle-Écosse\",\"NU\":\"Nunavut\",\"ON\":\"Ontario\",\"PE\":\"Île-du-Prince-Édouard\",\"QC\":\"Québec\",\"SK\":\"Saskatchewan\",\"YT\":\"Yukon\",\"None\":\"Ne rien sélectionner\"},\"RegionalGuidance\":{\"CA\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://ca.thrive.health/covid19/fr\"},\"AB\":{\"CTA\":\"Découvrez si vous devriez vous faire tester (lien en anglais seulement)\",\"URL\":\"https://myhealth.alberta.ca/Journey/COVID-19/Pages/PubAsympIsolate.aspx\"},\"BC\":{\"CTA\":\"Découvrez si vous devriez vous faire tester (lien en anglais seulement)\",\"URL\":\"https://bc.thrive.health/covid19/en\"},\"MB\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://covid19.soinscommunsmb.ca/covid19/outil-de-depistage/\"},\"NB\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://www2.gnb.ca/content/gnb/fr/ministeres/bmhc/maladies_transmissibles/content/maladies_respiratoires/coronavirus/expositionaucoronavirus.html#/app/symptom-checker/guides/399/what-to-do\"},\"NL\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://www.811healthline.ca/fr/autoevaluation-pour-la-covid-19/\"},\"NT\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://www.gov.nt.ca/covid-19/fr/services/outil-d%E2%80%99auto-%C3%A9valuation-en-ligne-pour-la-covid-19-aux-tno\"},\"NS\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://novascotia.ca/coronavirus/when-to-seek-help/fr/#if-exposed\"},\"NU\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://nu.thrive.health/covid19/fr\"},\"ON\":{\"CTA\":\"Lisez les étapes à suivre\",\"URL\":\"https://ontario.ca/covidalerte-expose\"},\"PE\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://www.princeedwardisland.ca/fr/information/sante-et-mieux-etre/auto-isolement-pour-lutter-contre-la-covid-19\"},\"QC\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://www.quebec.ca/sante/problemes-de-sante/a-z/coronavirus-2019/consignes-isolement-personne-en-contact-covid-19/\"},\"SK\":{\"CTA\":\"Découvrez si vous devriez vous faire tester (lien en anglais seulement)\",\"URL\":\"https://www.saskatchewan.ca/government/health-care-administration-and-provider-resources/treatment-procedures-and-guidelines/emerging-public-health-issues/2019-novel-coronavirus/covid-19-self-assessment\"},\"YT\":{\"CTA\":\"Découvrez si vous devriez vous faire tester\",\"URL\":\"https://service.yukon.ca/fr/covid-19-auto-evaluation/\"}},\"HowToIsolate\":{\"Title\":\"Comment vous isoler\",\"Intro\":\"Faites votre possible pour :\",\"Body1\":\"Rester à la maison, sauf si vous avez besoin de soins médicaux.\",\"Body2\":\"Éviter les transports publics comme les autobus et les taxis.\",\"Body3\":\"Demander de l’aide pour recevoir votre épicerie et vos provisions à votre porte.\",\"Body4\":\"Utiliser une pièce et une salle de bain séparées des autres de votre maison, si possible.\",\"Body5\":\"Porter un masque de façon sécuritaire dès que vous ne pouvez pas suivre les mesures ci-dessus.\"},\"A11yList\":{\"Start\":\"Début de liste\",\"End\":\"Fin de liste\",\"Bullet\":\"Puce\"},\"YourData\":{\"Body1\":\"votre identité\",\"Body2\":\"vos contacts\",\"Body3\":\"toute précision sur vous ou sur les personnes à proximité\",\"Body4\":\"vos informations de santé\",\"Body5\":\"\",\"Intro\":\"Alerte COVID n’a aucun moyen de connaître :\",\"Title\":\"Complètement anonyme\"}},\"pt-BR\":{\"Home\":{\"NoExposureDetected\":\"Nenhuma exposição detectada\",\"ExposureDetected\":\"Você possivelmente foi exposto ao COVID-19\",\"ChooseRegionCTA\":\"Choose province or territory\",\"How\":\"Diagnosed with COVID-19?\",\"CTA\":\"What to do next\",\"HowUrl\":\"https://www.canada.ca/\",\"DiagnosedView\":{\"Title\":\"Thanks for helping fight COVID-19\",\"Body1\":{\"One\":\"Tomorrow, you’ll get your last notification asking permission to upload any new random codes your phone sent out.\",\"Other\":\"For the next {number} days, you’ll get a daily notification asking permission to upload any new random codes your phone sent out.\"},\"Body2\":\"You do not have to agree, even if you agreed the day before.\",\"Body3\":\"If you’re worried about your symptoms, get medical care as soon as you can. Take care of yourself and your family during this time.\",\"TipTitle\":\"TIP: \",\"TipBody\":\"You can prepare for your call from Public Health through the test results website. \",\"TipLinkText\":\"Test results website\",\"TipURL\":\"https://covid19results.ehealthontario.ca:4443/login\"},\"SymptomTrackerUrl\":\"https://ca.thrive.health/covid19app/action/88a5e9a7-db9e-487b-bc87-ce35035f8e5c?from=/home&navigateTo=/tracker/complete\",\"DiagnosedShareView\":{\"Title\":\"Upload random codes\",\"Body1\":\"Thanks for helping slow the spread!\",\"Body2\":\"Reminder: \",\"Body3\":\"To help keep people safe, you need to upload your random codes every day, especially if you have to leave your home.\",\"ButtonCTA\":\"Upload your random codes\"},\"BluetoothDisabled\":\"Bluetooth desligado\",\"EnableBluetoothCTA\":\"O Bluetooth é usado para coletar e compartilhar IDs aleatórios necessários para o COVID Alert funcionar.\",\"TurnOnBluetooth\":\"Ligar o Bluetooth\",\"EnDisabled\":{\"Title\":\"COVID Alert is off\",\"Body1\":\"You did not enable COVID Alert. The app needs your permission to work.\",\"CTA\":\"Enable COVID Alert\",\"AndroidTitle2\":\"Not sure about turning on Location?\",\"AndroidBody1\":\"You need to have Location turned on for COVID Alert to work. To use Bluetooth scanning, Android phones need Location setting on for all apps.\",\"AndroidBody2a\":\"Despite that, COVID Alert has \",\"AndroidBody2b\":\"no way of knowing where you are. \",\"AndroidBody2c\":\"You can check the app’s permissions in your phone’s settings. You’ll see it does not have permission for location services.\"},\"FrameworkUnavailable\":{\"Title\":\"Something went wrong\",\"Body\":\"COVID Alert is not supported by your phone’s operating system.\\n\\nMake sure your operating system is up to date.\\n\\nIf you have an Android phone, try updating your Google Play Services.\",\"CTA\":\"Get Help\"},\"UnknownProblem\":{\"Title\":\"Something went wrong\",\"Body\":\"It looks like your phone cannot support COVID Alert.\",\"CTA\":\"Get Help\"},\"NoConnectivity\":\"Sem conexão à internet\",\"NoConnectivityDetailed\":\"O COVID Alert precisa de acesso à Internet para continuar verificando à potenciais exposições.\",\"AppName\":\"COVID Alert\",\"ExternalLinkHint\":\"Opens in a new window\",\"LastCheckedMinutes\":{\"One\":\"Última verificação há {number} minuto\",\"Other\":\"Última verificação há {number} minutos\"},\"LastCheckedHours\":{\"One\":\"Última verificação há {number} hora\",\"Other\":\"Última verificação há {number} horas\"},\"LastCheckedDays\":{\"One\":\"Última verificação há {number} dia\",\"Other\":\"Última verificação há {number} dias\"},\"NoExposureDetectedDetailed\":\"Com base em seus IDs aleatórios, você não esteve perto de alguém nos últimos 14 dias que testou positivo para COVID-19.\",\"ExposureDetectedDetailed\":\"Com base nos seus IDs aleatórios, você esteve perto de alguém nos últimos 14 dias que testou positivo para COVID-19.\",\"SeeGuidance\":\"Leia a orientação do Canadá sobre COVID-19\",\"GuidanceUrl\":\"https://www.canada.ca/en/public-health/services/publications/diseases-conditions/covid-19-how-to-isolate-at-home.html\",\"SignalDataShared\":\"Obrigado por ajudar a diminuir a propagação\",\"SignalDataSharedDetailed\":{\"One\":\"Você receberá uma notificação solicitando que compartilhe seus IDs aleatórios todos os dias pelo próximo {number} dia.\",\"Other\":\"Você receberá uma notificação solicitando que compartilhe seus IDs aleatórios todos os dias pelos próximos {number} dias.\"},\"SignalDataSharedCTA\":\"Acompanhe seus sintomas\",\"DailyShare\":\"Compartilhe seus novos IDs aleatórios\",\"DailyShareDetailed\":\"Compartilhar seus dados ajuda outras pessoas a saber se elas foram expostas ao COVID-19.\",\"ShareRandomIDsCTA\":\"Compartilhe seus IDs aleatórios\",\"ExposureNotificationsDisabled\":\"As notificações de exposição estão desligadas\",\"ExposureNotificationsDisabledDetailed\":\"São necessárias notificações de exposição para que o COVID Alert funcione.\",\"EnableExposureNotificationsCTA\":\"Ligar notificações de exposição\"},\"OverlayClosed\":{\"SystemStatus\":\"COVID Alert está \",\"SystemStatusOn\":\"LIGADO\",\"SystemStatusOff\":\"DESLIGADO\",\"NotificationStatus\":\"As notificações estão \",\"NotificationStatusOff\":\"DESLIGADAS\",\"TapPrompt\":\"Toque para mais informações\"},\"OverlayOpen\":{\"BluetoothCardBody\":\"O Bluetooth é usado para coletar e compartilhar IDs aleatórios necessários para o COVID Alert funcionar.\",\"BluetoothCardAction\":\"Ligar o Bluetooth\",\"EnterCodeCardTitle\":\"Código do COVID Alert\",\"EnterCodeCardBody\":\"Um profissional de saúde pediu para você inserir um código COVID Alert?\",\"EnterCodeCardAction\":\"Insira o código\",\"EnterCodeCardTitleDiagnosed\":\"You’re helping stop COVID-19\",\"EnterCodeCardBodyDiagnosed\":\"Thank you for doing your part to slow the spread. \",\"EnterCodeCardDiagnosedCountdown\":{\"One\":\"{number} day left!\",\"Other\":\"{number} days left!\"},\"NotificationCardStatus\":\"As notificações estão \",\"NotificationCardStatusOff\":\"DESLIGADAS\",\"NotificationCardBody\":\"Você não receberá notificações se tiver sido exposto ao COVID-19. A notificação de potencial exposição é importante para ajudar a diminuir a propagação do COVID-19.\",\"NotificationCardAction\":\"Ligar notificações\",\"ExposureNotificationCardStatus\":\"As notificações de exposição estão \",\"ExposureNotificationCardBody\":\"São necessárias notificações de exposição para que o COVID Alert funcione.\",\"ExposureNotificationCardAction\":\"Ligar notificações de exposição\",\"NoConnectivityCardAction\":\"COVID Alert is offline\",\"NoConnectivityCardBody\":\"Connect to the Internet to notify people or check for exposures.\",\"BluetoothCardStatus\":\"Bluetooth está \",\"BluetoothCardStatusOff\":\"DESLIGADO\",\"ExposureNotificationCardStatusOff\":\"DESLIGADAS\"},\"Info\":{\"CheckSymptoms\":\"Verifique os sintomas\",\"SymptomsUrl\":\"https://ca.thrive.health/covid19/en\",\"TellAFriend\":\"Compartilhe o aplicativo\",\"LearnMore\":\"Como o COVID Alert funciona\",\"Help\":\"Help\",\"HelpUrl\":\"https://www.canada.ca/en/public-health/services/diseases/coronavirus-disease-covid-19/covid-alert/help.html\",\"GetCode\":\"Get a one-time key\",\"ChangeLanguage\":\"Mudar idioma\",\"ChangeRegion\":\"Change province or territory\",\"Privacy\":\"Leia a política de privacidade\",\"SettingsTitle\":\"Settings\",\"InformationTitle\":\"About COVID Alert\"},\"Landing\":{\"En\":\"English\",\"Fr\":\"Français\",\"AltText\":\"Illustration of 8 people enjoying a public space. There’s a person with a walking cane, a person in a wheelchair, a person wearing a hijab, several people of colour, and a representation of gender diversity.\",\"CanadaAltText\":\"Symbol of the Government of Canada\"},\"LanguageSelect\":{\"Title\":\"Idioma\",\"En\":\"Inglês (Canadá)\",\"Fr\":\"Francês (Canadá)\",\"PtBR\":\"Português (Brasil)\",\"EnShort\":\"Inglês\",\"FrShort\":\"Francês\",\"PtBRShort\":\"Português (Brasil)\",\"Close\":\"Voltar\"},\"Tutorial\":{\"step-1Title\":\"Como o COVID Alert funciona\",\"step-1AltText\":\"A hand-drawn illustration of a mobile phone in a pocket, sending and receiving signals.\",\"step-1\":\"Seu telefone usa o Bluetooth para coletar e compartilhar IDs aleatórios com telefones próximos a você com o COVID Alert instalado. Esses IDs são armazenados com segurança em cada telefone.\",\"step-2Title\":\"Se você foi potencialmente exposto ao COVID-19\",\"step-2AltText\":\"A hand-drawn illustration of 2 mobile phones side-by-side with a timer clock connecting both phones.\",\"step-2\":\"Você receberá uma notificação se esteve próximo de alguém nos últimos 14 dias que testou positivo para COVID-19.\",\"step-3Title\":\"Se você testar positivo para COVID-19\",\"step-3AltText\":\"A hand-drawn illustration of a mobile phone uploading a numeric code to a cloud.\",\"step-3\":\"Notifique anonimamente as pessoas que estiveram perto de você nos últimos 14 dias de que elas possivelmente foram expostas.\",\"step-4Title\":\"Looking for exposures\",\"step-4AltText\":\"A hand-drawn illustration of a mobile phone uploading a numeric code to a cloud.\",\"step-4\":\"Every day, whenever it has an Internet connection, your phone will get a list of the random codes from people who reported a diagnosis.\\n\\nIf it finds codes that match, the app notifies you that you've been exposed and explains what to do next.\",\"ActionBack\":\"Voltar\",\"ActionNext\":\"Próximo\",\"ActionEnd\":\"Concluir\",\"Close\":\"Fechar\"},\"Sharing\":{\"Title\":\"Compartilhe o aplicativo\",\"SubTitle\":\"Todas as pessoas que usam o COVID Alert ajudam a diminuir a propagação do COVID-19. Compartilhando este aplicativo não compartilhará dados pessoais.\",\"Platform-messages\":\"Compartilhar em Mensagens\",\"Platform-instagram\":\"Compartilhar no Instagram\",\"More\":\"Mais aplicativos\",\"Message\":\"Junte-se a mim e ajude a diminuir a propagação do COVID-19. Baixe o aplicativo COVID Shield: https://covidshield.app\",\"InstagramImageUrl\":\"https://user-images.githubusercontent.com/5274722/84658989-b9ba6b00-aee4-11ea-84d4-d840527467b4.png\",\"Close\":\"Fechar\"},\"Onboarding\":{\"Step\":\"Step\",\"Of\":\"of\",\"ActionNext\":\"Próximo\",\"ActionEndSkip\":\"Skip\",\"ActionEnd\":\"Concluir\",\"ActionBack\":\"Voltar\",\"Start\":{\"Title\":\"Together, let’s stop the spread of COVID-19\",\"ImageAltText\":\"A hand-drawn illustration with lots of different people in it. Dotted lines show their paths crossing and leading to a smartphone below.\",\"Body1\":\"COVID Alert helps us break the cycle of infection. The app can let people know of possible exposures before any symptoms appear. \",\"Body2\":\"That way, we can take care of ourselves and protect our communities.\"},\"WhatItsNot\":{\"Title\":\"What COVID Alert does not do\",\"ImageAltText\":\"A hand-drawn illustration with many houses and a high-rise building on a curving street. Small message bubbles appear above each home.\",\"Body1\":\"The app will not tell you in the moment if you’re currently near someone who’s been diagnosed.\",\"Body2\":\"It will not tell you about outbreaks in your community.\"},\"Anonymous\":{\"Title\":\"Your privacy is protected\",\"ImageAltText\":\"A hand-drawn illustration of shaded glasses and hat to go incognito. Above the hat, a location pin icon is crossed out.\",\"Body1\":\"COVID Alert **does not use GPS** or track your location.\",\"Body2\":\"It has **no way of knowing**:\",\"Bullet1\":\"Your location.\",\"Bullet2\":\"Your name or address.\",\"Bullet3\":\"Your phone's contacts.\",\"Bullet4\":\"Your health information.\",\"Bullet5\":\"The health information of anyone you’re near.\"},\"HowItWorks\":{\"Title\":\"How it works\",\"ImageAltText\":\"A hand-drawn illustration of 3 mobile phones sending out random codes via bluetooth.\",\"Body1\":\"The app uses Bluetooth to exchange random codes with nearby phones.\",\"Body2\":\"Every day, it checks a list of random codes from people who tell the app they tested positive.\",\"Body3\":\"If you’ve had close contact with one of those people in the past 14 days, you’ll get a notification.\",\"HowItWorksCTA\":\"Learn more about how it works\"},\"PartOf\":{\"Title\":\"One part of public health\",\"ImageAltText\":\"A hand-drawn illustration of different ways of fighting COVID-19, including hand sanitizer, handwashing, face mask and the COVID Alert app.\",\"Body1\":\"COVID Alert is just one part of the public health effort to stop the spread of COVID-19.\",\"Body2\":\"Follow all public health guidelines in your area.\",\"Body3\":\"COVID Alert does not replace medical advice. If you get sick, contact your doctor or other healthcare provider.\"},\"Permissions\":{\"Title\":\"The app will now ask your permission\",\"ImageAltText\":\"A hand-drawn illustration of a mobile phone displaying a dialogue box with a red X and a green check mark on the screen.\",\"Body1\":\"**Allow the app** to start logging random codes or “random IDs” when you’re near other phones. The app will access the date, duration and signal strength related to the random codes, but they never leave your phone.\",\"Body2\":\"You’ll also need to **let the app send you notifications**.\",\"PrivacyButtonCTA\":\"Learn more about privacy\"}},\"Privacy\":{\"Title\":\"Política de privacidade\",\"Close\":\"Fechar\"},\"ThankYou\":{\"Title\":\"Obrigado por ajudar\",\"Body\":\"As notificações de exposição estão ativadas. Você receberá uma notificação se o COVID Alert detectar que você foi exposto ao COVID-19.\",\"Dismiss\":\"Dispensar\"},\"DataUpload\":{\"Cancel\":\"Cancelar\",\"InfoSmall\":\"Seus IDs aleatórios não serão compartilhados, a menos que você permita na próxima etapa.\",\"ShareToast\":\"IDs aleatórios compartilhados com sucesso\",\"Step1\":{\"Title\":\"Let people know they may have been exposed\",\"Body1a\":\"Step 1. \",\"Body1b\":\"Enter the one-time key you got when you were diagnosed.\",\"Body2a\":\"Step 2. \",\"Body2b\":\"Agree that COVID Alert can let people know they were exposed.\",\"Body3a\":\"Step 3. \",\"Body3b\":\"Allow your phone to share your random codes.\",\"Body4a\":\"Nobody will get any information about you \",\"Body4b\":\"or the time you were near them.\",\"CTA\":\"Next\",\"NoCode\":\"Need a one-time key?\"},\"FormView\":{\"Title\":\"Enter your one-time key\",\"Body\":\"Enter the key you got when you were diagnosed.\",\"Action\":\"Submit\",\"InputLabel\":\"COVID Alert key\",\"ErrorTitle\":\"One-time key not recognized\",\"ErrorBody\":\"Your key could not be recognized. Please try again.\",\"ErrorAction\":\"OK\"},\"ConsentView\":{\"Title\":\"Now you can upload your codes\",\"Body1\":\"Your phone will ask your permission to upload your random codes or “random IDs” from the past 14 days.\",\"Body2a\":\"Nobody will get any information about you \",\"Body2b\":\"or the time you were near them.\",\"Body3\":\"You can help slow the spread of COVID-19 if you agree.\",\"Action\":\"Agree\",\"ErrorTitle\":\"Random codes could not be uploaded\",\"ErrorBody\":\"You did not give permission.\",\"ErrorAction\":\"OK\"},\"NoCode\":{\"NoRegion\":{\"Title\":\"You skipped choosing province or territory\",\"Body\":\"In some provinces and territories, people cannot yet report a COVID-19 diagnosis through this app.\\n\\nTo find out if you can get a one-time key, you need to choose your area.\",\"ChooseRegionCTA\":\"Choose province or territory\"},\"RegionCovered\":{\"ON\":{\"Title\":\"Get a one-time key\",\"Body\":\"If you’ve tested positive in Ontario:\",\"Body2\":\"Go to the COVID-19 Test Results Website and enter your details.\",\"Body3\":\"Review your test results.\",\"Body4\":\"Get the one-time key.\",\"Body5\":\"Come back here and enter the key.\",\"CTA\":\"Go to COVID-19 Test Results Website\",\"Link\":\"https://covid19results.ehealthontario.ca:4443/\"}},\"RegionNotCovered\":{\"Title\":\"No reporting yet in your area\",\"Body\":\"People in your area cannot yet get a one-time key.\\n\\nYou will not be able to let people know they were exposed. But you can still self-isolate for 14 days, and:\",\"Body2\":\"Keep your community safe.\",\"Body3\":\"Protect people and pets you live with.\",\"Body4\":\"Take care of yourself.\"}},\"FormIntro\":\"Digite seu código COVID Alert de 8 dígitos.\",\"Action\":\"Enviar código\",\"ConsentTitle\":\"Compartilhe seus IDs aleatórios\",\"ConsentBody\":\"Você recebeu acesso de um profissional de saúde para compartilhar os IDs aleatórios armazenados no seu telefone.\",\"ConsentBody2\":\"Se você compartilhar seus IDs aleatórios, outras pessoas com a COVID Alert que estiveram perto de você nos últimos 14 dias receberão uma notificação de que elas possivelmente foram expostas. Esta notificação não incluirá nenhuma informação sobre você.\",\"ConsentBody3\":\"Você será notificado uma vez por dia quando novos IDs aleatórios estiverem disponíveis para serem compartilhados. Você deve conceder permissão cada vez para que os IDs aleatórios sejam compartilhados. Compartilhar é voluntário.\",\"PrivacyPolicyLink\":\"Ver política de privacidade\",\"ConsentAction\":\"Concordo\",\"ErrorTitle\":\"Código não reconhecido\",\"ErrorBody\":\"Não foi possível reconhecer seu código COVID Alert. Por favor, tente novamente.\",\"ErrorAction\":\"OK\"},\"Notification\":{\"ExposedMessageTitle\":\"Você possivelmente foi exposto ao COVID-19\",\"ExposedMessageBody\":\"Com base nos seus IDs aleatórios, você esteve perto de alguém nos últimos 14 dias que testou positivo para COVID-19.\",\"OffMessageTitle\":\"O COVID Alert está desligado\",\"OffMessageBody\":\"Ligue o COVID Alert para ser notificado se você tiver sido potencialmente exposto ao COVID-19.\",\"DailyUploadNotificationTitle\":\"Compartilhe seus novos IDs aleatórios\",\"DailyUploadNotificationBody\":\"Compartilhar seus dados ajuda outras pessoas a saber se elas foram expostas ao COVID-19.\"},\"Partners\":{\"Label\":\"Desenvolvido em parceria com\"},\"BottomSheet\":{\"Collapse\":\"Ocultar\",\"OnStatus\":\"COVID Alert is on, Tap for more information\",\"OffStatus\":\"COVID Alert is off, Tap for more information\"},\"RegionLanding\":{\"Title\":\"Choose your province or territory\",\"Body1\":\"Provincial and territorial governments are working to support COVID Alert across Canada.\",\"Body2\":\"In some places, people cannot yet report a COVID-19 diagnosis through this app.\",\"RegionSelectBtn\":\"Choose province or territory\"},\"RegionPicker\":{\"Title\":\"Where do you live? (optional)\",\"SettingsTitle\":\"Province or territory\",\"Close\":\"Close\",\"Body\":\"Choose your region to check if you can report a diagnosis through this app.\\n\\nYour region will never be shared with anyone.\",\"Skip\":\"Skip\",\"GetStarted\":\"Get started\",\"Optional\":\"* Optional\",\"AB\":\"Alberta\",\"BC\":\"British Columbia\",\"MB\":\"Manitoba\",\"NB\":\"New Brunswick\",\"NL\":\"Newfoundland and Labrador\",\"NT\":\"Northwest Territories\",\"NS\":\"Nova Scotia\",\"NU\":\"Nunavut\",\"ON\":\"Ontario\",\"PE\":\"Prince Edward Island\",\"QC\":\"Quebec\",\"SK\":\"Saskatchewan\",\"YT\":\"Yukon\",\"None\":\"Prefer not to say\"},\"RegionalGuidance\":{\"CA\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://ca.thrive.health/covid19/en\"},\"AB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://myhealth.alberta.ca/Journey/COVID-19/Pages/PubAsympIsolate.aspx\"},\"BC\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://bc.thrive.health/covid19/en\"},\"MB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://sharedhealthmb.ca/covid19/screening-tool/\"},\"NB\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www2.gnb.ca/content/gnb/en/departments/ocmoh/cdc/content/respiratory_diseases/coronavirus/coronavirusexposure.html#/app/symptom-checker/guides/399/what-to-do\"},\"NL\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://nl.thrive.health/covid19/en\"},\"NT\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.gov.nt.ca/covid-19/en/services/nwt-online-covid-19-self-assessment-tool\"},\"NS\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://novascotia.ca/coronavirus/when-to-seek-help/#if-exposed\"},\"NU\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://nu.thrive.health/covid19/en\"},\"ON\":{\"CTA\":\"Find out what to do next\",\"URL\":\"https://ontario.ca/covidalert-exposed\"},\"PE\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.princeedwardisland.ca/en/information/health-and-wellness/covid-19-self-isolation\"},\"QC\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.quebec.ca/en/health/health-issues/a-z/2019-coronavirus/instructions-for-people-who-have-been-in-contact-with-a-confirmed-case-of-covid-19/\"},\"SK\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://www.saskatchewan.ca/government/health-care-administration-and-provider-resources/treatment-procedures-and-guidelines/emerging-public-health-issues/2019-novel-coronavirus/covid-19-self-assessment\"},\"YT\":{\"CTA\":\"Find out if you need to be tested\",\"URL\":\"https://service.yukon.ca/en/covid-19-self-assessment/\"}},\"HowToIsolate\":{\"Title\":\"How to self-isolate\",\"Intro\":\"Try your best to:\",\"Body1\":\"Stay home unless it’s to get medical care.\",\"Body2\":\"Avoid public transportation like buses or taxis.\",\"Body3\":\"Ask for help to get groceries and supplies dropped off at your door.\",\"Body4\":\"Stay in a separate room and use a separate bathroom from others in your home, if possible.\",\"Body5\":\"Wear a mask safely any time you cannot take the above actions.\"},\"A11yList\":{\"Start\":\"List start\",\"End\":\"List end\",\"Bullet\":\"Bullet\"},\"OnboardingPermissions\":{\"Title\":\"Seus dados são privados\",\"Body\":\"O COVID Alert adota uma abordagem de privacidade em primeiro lugar na notificação de exposição.\",\"Body2\":\"Seus IDs aleatórios são armazenados exclusivamente em seu telefone, a menos que você os compartilhe.\",\"Body3\":\"O uso do COVID Alert é voluntário. Você pode excluir seus IDs aleatórios a qualquer momento.\"},\"OnboardingStart\":{\"Title\":\"Mantenha você e os outros seguros\",\"Body1\":\"Seja notificado se você foi potencialmente exposto ao COVID-19.\",\"Body2\":\"Se você testar positivo para COVID-19, poderá compartilhar seus dados anonimamente para que outras pessoas possam ser notificadas sobre uma possível exposição.\",\"TutorialAction\":\"Saiba como o COVID Alert funciona\"}}}") \ No newline at end of file diff --git a/src/screens/home/views/UnknownProblemView.tsx b/src/screens/home/views/UnknownProblemView.tsx index ddf0d9b50..77dbdfbfe 100644 --- a/src/screens/home/views/UnknownProblemView.tsx +++ b/src/screens/home/views/UnknownProblemView.tsx @@ -19,6 +19,7 @@ export const UnknownProblemView = ({isBottomSheetExpanded}: {isBottomSheetExpand {i18n.translate('Home.UnknownProblem.Title')} + {i18n.translate('Home.UnknownProblem.Body')} Date: Mon, 27 Jul 2020 18:07:55 -0400 Subject: [PATCH 011/140] Updating patch to delete data file if unable to apply `NSURLIsExcludedFromBackupKey` attribute. --- ...native-community+async-storage+1.9.0.patch | 69 +++++++++++++++---- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/patches/@react-native-community+async-storage+1.9.0.patch b/patches/@react-native-community+async-storage+1.9.0.patch index f50421255..9efca30c1 100644 --- a/patches/@react-native-community+async-storage+1.9.0.patch +++ b/patches/@react-native-community+async-storage+1.9.0.patch @@ -1,33 +1,72 @@ diff --git a/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m b/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m -index 2d72ac7..bf72515 100644 +index 2d72ac7..1a0531e 100644 --- a/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m +++ b/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m -@@ -417,10 +417,16 @@ - (NSDictionary *)_writeManifest:(NSMutableArray **)errors +@@ -414,14 +414,38 @@ - (NSDictionary *)_ensureSetup + + - (NSDictionary *)_writeManifest:(NSMutableArray **)errors + { ++ NSDictionary *errorOut; NSError *error; - NSString *serialized = RCTJSONStringify(_manifest, &error); - [serialized writeToFile:RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()) atomically:YES encoding:NSUTF8StringEncoding error:&error]; ++ BOOL success; + - NSDictionary *errorOut; + NSString *serialized = RCTJSONStringify(_manifest, &error); +- [serialized writeToFile:RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()) atomically:YES encoding:NSUTF8StringEncoding error:&error]; +- NSDictionary *errorOut; if (error) { - errorOut = RCTMakeError(@"Failed to write manifest file.", error, nil); - RCTAppendError(errorOut, errors); -+ } else { -+ // Added by COVID Alert: Ensure all files are excluded from iCloud Backup. -+ NSString *filePath = RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()); -+ NSURL *fileURL = [NSURL fileURLWithPath:filePath]; -+ [fileURL setResourceValue:[NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; +- errorOut = RCTMakeError(@"Failed to write manifest file.", error, nil); +- RCTAppendError(errorOut, errors); ++ return RCTMakeError(@"Unable to parse manifest file.", error, nil); ++ } ++ ++ success = [serialized writeToFile:RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()) atomically:YES encoding:NSUTF8StringEncoding error:&error]; ++ if (!success) { ++ return RCTMakeError(@"Failed to write manifest file.", error, nil); ++ } ++ ++ // Added by COVID Alert: Ensure all files are excluded from iCloud Backup. ++ NSString *filePath = RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()); ++ NSURL *fileURL = [NSURL fileURLWithPath:filePath]; ++ success = [fileURL setResourceValue:[NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; ++ if (!success) { ++ if ([[NSFileManager defaultManager] isDeletableFileAtPath:filePath]) { ++ NSError *removeFileError; ++ BOOL removeFileSuccess = [[NSFileManager defaultManager] removeItemAtPath:filePath error:&removeFileError]; ++ if (!removeFileSuccess) { ++ return RCTMakeError(@"Error removing file at path.", removeFileError, nil); ++ } else { ++ return RCTMakeError(@"Unable to exclude file from backup.", error, nil); ++ } ++ } else { ++ return RCTMakeError(@"Unable to delete file.", nil, nil); ++ } } ++ return errorOut; } -@@ -481,6 +487,13 @@ - (NSDictionary *)_writeEntry:(NSArray *)entry changedManifest:(BOOL + +@@ -481,6 +505,26 @@ - (NSDictionary *)_writeEntry:(NSArray *)entry changedManifest:(BOOL return nil; } [value writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error]; + + // Added by COVID Alert: Ensure all files are excluded from iCloud Backup. + if (!error){ -+ NSURL *fileURL = [NSURL URLWithString:filePath]; -+ [fileURL setResourceValue:[NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; ++ NSURL *fileURL = [NSURL fileURLWithPath:filePath]; ++ BOOL success = [fileURL setResourceValue:[NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; ++ if (!success) { ++ if ([[NSFileManager defaultManager] isDeletableFileAtPath:filePath]) { ++ NSError *removeFileError; ++ BOOL removeFileSuccess = [[NSFileManager defaultManager] removeItemAtPath:filePath error:&removeFileError]; ++ if (!removeFileSuccess) { ++ return RCTMakeError(@"Error removing file at path.", removeFileError, nil); ++ } else { ++ return RCTMakeError(@"Unable to exclude file from backup.", error, nil); ++ } ++ } else { ++ return RCTMakeError(@"Unable to delete file.", nil, nil); ++ } ++ } + } + [RCTGetCache() setObject:value forKey:key cost:value.length]; From c53a9bd3e786f1c7f570c8528dccfd65d9778a21 Mon Sep 17 00:00:00 2001 From: James Eberhardt Date: Mon, 27 Jul 2020 18:36:22 -0400 Subject: [PATCH 012/140] Adjusting use of `error` and `success`. --- ...native-community+async-storage+1.9.0.patch | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/patches/@react-native-community+async-storage+1.9.0.patch b/patches/@react-native-community+async-storage+1.9.0.patch index 9efca30c1..25badcab9 100644 --- a/patches/@react-native-community+async-storage+1.9.0.patch +++ b/patches/@react-native-community+async-storage+1.9.0.patch @@ -1,5 +1,5 @@ diff --git a/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m b/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m -index 2d72ac7..1a0531e 100644 +index 2d72ac7..2937091 100644 --- a/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m +++ b/node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.m @@ -414,14 +414,38 @@ - (NSDictionary *)_ensureSetup @@ -45,27 +45,32 @@ index 2d72ac7..1a0531e 100644 return errorOut; } -@@ -481,6 +505,26 @@ - (NSDictionary *)_writeEntry:(NSArray *)entry changedManifest:(BOOL +@@ -480,7 +504,30 @@ - (NSDictionary *)_writeEntry:(NSArray *)entry changedManifest:(BOOL + _manifest[key] = value; return nil; } - [value writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error]; -+ +- [value writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error]; ++ + // Added by COVID Alert: Ensure all files are excluded from iCloud Backup. -+ if (!error){ -+ NSURL *fileURL = [NSURL fileURLWithPath:filePath]; -+ BOOL success = [fileURL setResourceValue:[NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; -+ if (!success) { -+ if ([[NSFileManager defaultManager] isDeletableFileAtPath:filePath]) { -+ NSError *removeFileError; -+ BOOL removeFileSuccess = [[NSFileManager defaultManager] removeItemAtPath:filePath error:&removeFileError]; -+ if (!removeFileSuccess) { -+ return RCTMakeError(@"Error removing file at path.", removeFileError, nil); -+ } else { -+ return RCTMakeError(@"Unable to exclude file from backup.", error, nil); -+ } ++ BOOL success; ++ success = [value writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error]; ++ if (!success) { ++ return RCTMakeError(@"Failed to write file.", error, nil); ++ } ++ ++ NSURL *fileURL = [NSURL fileURLWithPath:filePath]; ++ success = [fileURL setResourceValue:[NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; ++ if (!success) { ++ if ([[NSFileManager defaultManager] isDeletableFileAtPath:filePath]) { ++ NSError *removeFileError; ++ BOOL removeFileSuccess = [[NSFileManager defaultManager] removeItemAtPath:filePath error:&removeFileError]; ++ if (!removeFileSuccess) { ++ return RCTMakeError(@"Error removing file at path.", removeFileError, nil); + } else { -+ return RCTMakeError(@"Unable to delete file.", nil, nil); ++ return RCTMakeError(@"Unable to exclude file from backup.", error, nil); + } ++ } else { ++ return RCTMakeError(@"Unable to delete file.", nil, nil); + } + } + From f09631d4a6f5a97fb6be31ffa65665042653103b Mon Sep 17 00:00:00 2001 From: Henry Tao Date: Tue, 28 Jul 2020 09:46:04 -0400 Subject: [PATCH 013/140] Add test for cancelablePromise --- package.json | 3 +- src/shared/cancellablePromise.spec.ts | 57 +++++++++++++++++++++++++++ yarn.lock | 5 +++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/shared/cancellablePromise.spec.ts diff --git a/package.json b/package.json index 16f722036..b796f6a84 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "react-test-renderer": "16.11.0", "reactotron-react-native": "^3.2.1", "ts-jest": "25.2.1", - "typescript": "^3.8.3" + "typescript": "^3.8.3", + "wait-for-expect": "^3.0.2" } } diff --git a/src/shared/cancellablePromise.spec.ts b/src/shared/cancellablePromise.spec.ts new file mode 100644 index 000000000..bcc0a2bf1 --- /dev/null +++ b/src/shared/cancellablePromise.spec.ts @@ -0,0 +1,57 @@ +import waitForExpect from 'wait-for-expect'; + +import {createCancellableCallbackPromise} from './cancellablePromise'; + +describe('createCancellableCallbackPromise', () => { + it('calls callback if the promise has not been canceled', async () => { + const mockPromise = jest.fn(); + const mockCallback = jest.fn(); + mockPromise.mockImplementation(() => Promise.resolve(true)); + + const {callable} = createCancellableCallbackPromise(mockPromise, mockCallback); + callable(); + + await waitForExpect(() => { + expect(mockPromise).toHaveBeenCalled(); + }); + + expect(mockCallback).toHaveBeenCalledWith(true); + }); + + it('does not call callback if the promise has been canceled', async () => { + const mockPromise = jest.fn(); + const mockCallback = jest.fn(); + mockPromise.mockImplementation(() => Promise.resolve(true)); + + const {callable, cancelable} = createCancellableCallbackPromise(mockPromise, mockCallback); + callable(); + cancelable(); + + await waitForExpect(() => { + expect(mockPromise).toHaveBeenCalled(); + }); + + expect(mockCallback).not.toHaveBeenCalled(); + }); + + it('does not call callback if the promise has been canceled before being called', async () => { + const mockPromise = jest.fn(); + const mockCallback = jest.fn(); + mockPromise.mockImplementation(() => Promise.resolve(true)); + + const {callable, cancelable} = createCancellableCallbackPromise(mockPromise, mockCallback); + cancelable(); + callable(); + + let isTimeout = false; + setTimeout(() => { + isTimeout = true; + }, 1000); + await waitForExpect(() => { + expect(isTimeout).toStrictEqual(true); + }); + + expect(mockPromise).not.toHaveBeenCalled(); + expect(mockCallback).not.toHaveBeenCalled(); + }); +}); diff --git a/yarn.lock b/yarn.lock index d26fb0074..1e8b44ced 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8880,6 +8880,11 @@ w3c-xmlserializer@^1.1.2: webidl-conversions "^4.0.2" xml-name-validator "^3.0.0" +wait-for-expect@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-3.0.2.tgz#d2f14b2f7b778c9b82144109c8fa89ceaadaa463" + integrity sha512-cfS1+DZxuav1aBYbaO/kE06EOS8yRw7qOFoD3XtjTkYvCvh3zUvNST8DXK/nPaeqIzIv3P3kL3lRJn8iwOiSag== + walker@^1.0.7, walker@~1.0.5: version "1.0.7" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" From 8478375419fece9041c301355b9b9ce964748950 Mon Sep 17 00:00:00 2001 From: Nick Mallory Date: Tue, 28 Jul 2020 12:05:40 -0400 Subject: [PATCH 014/140] setup detox --- .detoxrc.json | 22 + e2e/config.json | 8 + e2e/environment.js | 23 + e2e/firstTest.e2e.js | 19 + ios/CovidShield.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/WorkspaceSettings.xcsettings | 8 + package.json | 4 +- yarn.lock | 1443 +++++++++++------ 8 files changed, 1029 insertions(+), 500 deletions(-) create mode 100644 .detoxrc.json create mode 100644 e2e/config.json create mode 100644 e2e/environment.js create mode 100644 e2e/firstTest.e2e.js create mode 100644 ios/CovidShield.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/.detoxrc.json b/.detoxrc.json new file mode 100644 index 000000000..c5ec61d37 --- /dev/null +++ b/.detoxrc.json @@ -0,0 +1,22 @@ +{ + "testRunner": "jest", + "runnerConfig": "e2e/config.json", + "configurations": { + "ios": { + "type": "ios.simulator", + "binaryPath": "./ios/build/Build/Products/Debug-iphonesimulator/CovidShield.app", + "build": "xcodebuild -workspace ios/CovidShield.xcworkspace -scheme CovidShield -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", + "device": { + "type": "iPhone 11" + } + }, + "android": { + "type": "android.emulator", + "binaryPath": "./android/app/build/outputs/apk/debug/app-debug.apk", + "build": "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..", + "device": { + "avdName": "Pixel_3_API_29" + } + } + } +} diff --git a/e2e/config.json b/e2e/config.json new file mode 100644 index 000000000..5f638d1aa --- /dev/null +++ b/e2e/config.json @@ -0,0 +1,8 @@ +{ + "testEnvironment": "./environment", + "testRunner": "jest-circus/runner", + "testTimeout": 120000, + "testRegex": "\\.e2e\\.ts$", + "reporters": ["detox/runners/jest/streamlineReporter"], + "verbose": true +} diff --git a/e2e/environment.js b/e2e/environment.js new file mode 100644 index 000000000..ad46bec5f --- /dev/null +++ b/e2e/environment.js @@ -0,0 +1,23 @@ +const { + DetoxCircusEnvironment, + SpecReporter, + WorkerAssignReporter, +} = require('detox/runners/jest-circus'); + +class CustomDetoxEnvironment extends DetoxCircusEnvironment { + constructor(config) { + super(config); + + // Can be safely removed, if you are content with the default value (=300000ms) + this.initTimeout = 300000; + + // This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level. + // This is strictly optional. + this.registerListeners({ + SpecReporter, + WorkerAssignReporter, + }); + } +} + +module.exports = CustomDetoxEnvironment; diff --git a/e2e/firstTest.e2e.js b/e2e/firstTest.e2e.js new file mode 100644 index 000000000..9b7e4bd56 --- /dev/null +++ b/e2e/firstTest.e2e.js @@ -0,0 +1,19 @@ +describe('Example', () => { + beforeEach(async () => { + await device.reloadReactNative(); + }); + + it('should have welcome screen', async () => { + await expect(element(by.id('welcome'))).toBeVisible(); + }); + + it('should show hello screen after tap', async () => { + await element(by.id('hello_button')).tap(); + await expect(element(by.text('Hello!!!'))).toBeVisible(); + }); + + it('should show world screen after tap', async () => { + await element(by.id('world_button')).tap(); + await expect(element(by.text('World!!!'))).toBeVisible(); + }); +}); diff --git a/ios/CovidShield.xcodeproj/project.pbxproj b/ios/CovidShield.xcodeproj/project.pbxproj index a3a10e85d..ce667a436 100644 --- a/ios/CovidShield.xcodeproj/project.pbxproj +++ b/ios/CovidShield.xcodeproj/project.pbxproj @@ -521,7 +521,7 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "ca.gc.hcsc.canada.stopcovid"; + PRODUCT_BUNDLE_IDENTIFIER = ca.gc.hcsc.canada.stopcovid; PRODUCT_NAME = CovidShield; PROVISIONING_PROFILE_SPECIFIER = "Stop COVID Development Profile"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; diff --git a/ios/CovidShield.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/CovidShield.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/ios/CovidShield.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/package.json b/package.json index 5964e017a..881ae6f03 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,9 @@ "add": "^2.0.6", "buffer": "^5.6.0", "crypto-js": "^3.0.0", + "detox": "^17.3.1", "intl": "^1.2.5", + "jest-circus": "^26.1.0", "jsonschema": "^1.2.6", "react": "16.11.0", "react-native": "0.62.2", @@ -78,7 +80,7 @@ "eslint": "^6.5.1", "eslint-plugin-jest": "^23.8.2", "eslint-plugin-prettier": "^3.1.3", - "jest": "25.1.0", + "jest": "^26.1.0", "jest-when": "^2.7.1", "metro-react-native-babel-preset": "^0.58.0", "patch-package": "^6.2.2", diff --git a/yarn.lock b/yarn.lock index d26fb0074..90b9f078d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -776,59 +776,58 @@ chalk "^2.0.1" slash "^2.0.0" -"@jest/console@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.5.0.tgz#770800799d510f37329c508a9edd0b7b447d9abb" - integrity sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw== - dependencies: - "@jest/types" "^25.5.0" - chalk "^3.0.0" - jest-message-util "^25.5.0" - jest-util "^25.5.0" +"@jest/console@^26.1.0": + version "26.1.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.1.0.tgz#f67c89e4f4d04dbcf7b052aed5ab9c74f915b954" + integrity sha512-+0lpTHMd/8pJp+Nd4lyip+/Iyf2dZJvcCqrlkeZQoQid+JlThA4M9vxHtheyrQ99jJTMQam+es4BcvZ5W5cC3A== + dependencies: + "@jest/types" "^26.1.0" + chalk "^4.0.0" + jest-message-util "^26.1.0" + jest-util "^26.1.0" slash "^3.0.0" -"@jest/core@^25.1.0", "@jest/core@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.5.0.tgz#e71ddcac282e965081688cac5e9f100b237a7b32" - integrity sha512-YQPhBtPQa8QJCMpseg1b/DqJE0iG16uhUQOAOdRX2dbIzgZeobNQn4Cmigr1va6IC3RTnGPTUF7QmWOzsiJtbQ== +"@jest/core@^26.1.0": + version "26.1.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.1.0.tgz#4580555b522de412a7998b3938c851e4f9da1c18" + integrity sha512-zyizYmDJOOVke4OO/De//aiv8b07OwZzL2cfsvWF3q9YssfpcKfcnZAwDY8f+A76xXSMMYe8i/f/LPocLlByfw== dependencies: - "@jest/console" "^25.5.0" - "@jest/reporters" "^25.5.0" - "@jest/test-result" "^25.5.0" - "@jest/transform" "^25.5.0" - "@jest/types" "^25.5.0" + "@jest/console" "^26.1.0" + "@jest/reporters" "^26.1.0" + "@jest/test-result" "^26.1.0" + "@jest/transform" "^26.1.0" + "@jest/types" "^26.1.0" ansi-escapes "^4.2.1" - chalk "^3.0.0" + chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" - jest-changed-files "^25.5.0" - jest-config "^25.5.0" - jest-haste-map "^25.5.0" - jest-message-util "^25.5.0" - jest-regex-util "^25.2.6" - jest-resolve "^25.5.0" - jest-resolve-dependencies "^25.5.0" - jest-runner "^25.5.0" - jest-runtime "^25.5.0" - jest-snapshot "^25.5.0" - jest-util "^25.5.0" - jest-validate "^25.5.0" - jest-watcher "^25.5.0" + jest-changed-files "^26.1.0" + jest-config "^26.1.0" + jest-haste-map "^26.1.0" + jest-message-util "^26.1.0" + jest-regex-util "^26.0.0" + jest-resolve "^26.1.0" + jest-resolve-dependencies "^26.1.0" + jest-runner "^26.1.0" + jest-runtime "^26.1.0" + jest-snapshot "^26.1.0" + jest-util "^26.1.0" + jest-validate "^26.1.0" + jest-watcher "^26.1.0" micromatch "^4.0.2" p-each-series "^2.1.0" - realpath-native "^2.0.0" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.5.0.tgz#aa33b0c21a716c65686638e7ef816c0e3a0c7b37" - integrity sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA== +"@jest/environment@^26.1.0": + version "26.1.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.1.0.tgz#378853bcdd1c2443b4555ab908cfbabb851e96da" + integrity sha512-86+DNcGongbX7ai/KE/S3/NcUVZfrwvFzOOWX/W+OOTvTds7j07LtC+MgGydH5c8Ri3uIrvdmVgd1xFD5zt/xA== dependencies: - "@jest/fake-timers" "^25.5.0" - "@jest/types" "^25.5.0" - jest-mock "^25.5.0" + "@jest/fake-timers" "^26.1.0" + "@jest/types" "^26.1.0" + jest-mock "^26.1.0" "@jest/fake-timers@^24.9.0": version "24.9.0" @@ -839,57 +838,57 @@ jest-message-util "^24.9.0" jest-mock "^24.9.0" -"@jest/fake-timers@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.5.0.tgz#46352e00533c024c90c2bc2ad9f2959f7f114185" - integrity sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ== +"@jest/fake-timers@^26.1.0": + version "26.1.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.1.0.tgz#9a76b7a94c351cdbc0ad53e5a748789f819a65fe" + integrity sha512-Y5F3kBVWxhau3TJ825iuWy++BAuQzK/xEa+wD9vDH3RytW9f2DbMVodfUQC54rZDX3POqdxCgcKdgcOL0rYUpA== dependencies: - "@jest/types" "^25.5.0" - jest-message-util "^25.5.0" - jest-mock "^25.5.0" - jest-util "^25.5.0" - lolex "^5.0.0" + "@jest/types" "^26.1.0" + "@sinonjs/fake-timers" "^6.0.1" + jest-message-util "^26.1.0" + jest-mock "^26.1.0" + jest-util "^26.1.0" -"@jest/globals@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-25.5.0.tgz#2e36037e0e96d34870f99a024d4dc1485bcbd775" - integrity sha512-yC+WlD1ytYPZvTSbmSeZM+BNbkFXtkTBBjtmoFDYxjznwugl2Qv2KW7csxL7nTxJOxyjkffy6ngLZ6YMqAe7MA== +"@jest/globals@^26.1.0": + version "26.1.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.1.0.tgz#6cc5d7cbb79b76b120f2403d7d755693cf063ab1" + integrity sha512-MKiHPNaT+ZoG85oMaYUmGHEqu98y3WO2yeIDJrs2sJqHhYOy3Z6F7F/luzFomRQ8SQ1wEkmahFAz2291Iv8EAw== dependencies: - "@jest/environment" "^25.5.0" - "@jest/types" "^25.5.0" - expect "^25.5.0" + "@jest/environment" "^26.1.0" + "@jest/types" "^26.1.0" + expect "^26.1.0" -"@jest/reporters@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.5.0.tgz#749e035119ec22c76af9bb587108a27c15dfe40d" - integrity sha512-CnrfHhrxGgMI2Va/w0e406CRmf+P1ZBAahgM4aaETWy8IQ5n3aGEDNE+tuh7vexIFCfZ1QFsVMYzvcVT4o9XOQ== +"@jest/reporters@^26.1.0": + version "26.1.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.1.0.tgz#08952e90c90282e14ff49e927bdf1873617dae78" + integrity sha512-SVAysur9FOIojJbF4wLP0TybmqwDkdnFxHSPzHMMIYyBtldCW9gG+Q5xWjpMFyErDiwlRuPyMSJSU64A67Pazg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^25.5.0" - "@jest/test-result" "^25.5.0" - "@jest/transform" "^25.5.0" - "@jest/types" "^25.5.0" - chalk "^3.0.0" + "@jest/console" "^26.1.0" + "@jest/test-result" "^26.1.0" + "@jest/transform" "^26.1.0" + "@jest/types" "^26.1.0" + chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.2" graceful-fs "^4.2.4" istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^4.0.0" + istanbul-lib-instrument "^4.0.3" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.2" - jest-haste-map "^25.5.0" - jest-resolve "^25.5.0" - jest-util "^25.5.0" - jest-worker "^25.5.0" + jest-haste-map "^26.1.0" + jest-resolve "^26.1.0" + jest-util "^26.1.0" + jest-worker "^26.1.0" slash "^3.0.0" source-map "^0.6.0" - string-length "^3.1.0" + string-length "^4.0.1" terminal-link "^2.0.0" v8-to-istanbul "^4.1.3" optionalDependencies: - node-notifier "^6.0.0" + node-notifier "^7.0.0" "@jest/source-map@^24.9.0": version "24.9.0" @@ -900,10 +899,10 @@ graceful-fs "^4.1.15" source-map "^0.6.0" -"@jest/source-map@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.5.0.tgz#df5c20d6050aa292c2c6d3f0d2c7606af315bd1b" - integrity sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ== +"@jest/source-map@^26.1.0": + version "26.1.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.1.0.tgz#a6a020d00e7d9478f4b690167c5e8b77e63adb26" + integrity sha512-XYRPYx4eEVX15cMT9mstnO7hkHP3krNtKfxUYd8L7gbtia8JvZZ6bMzSwa6IQJENbudTwKMw5R1BePRD+bkEmA== dependencies: callsites "^3.0.0" graceful-fs "^4.2.4" @@ -918,28 +917,28 @@ "@jest/types" "^24.9.0" "@types/istanbul-lib-coverage" "^2.0.0" -"@jest/test-result@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.5.0.tgz#139a043230cdeffe9ba2d8341b27f2efc77ce87c" - integrity sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A== +"@jest/test-result@^26.1.0": + version "26.1.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.1.0.tgz#a93fa15b21ad3c7ceb21c2b4c35be2e407d8e971" + integrity sha512-Xz44mhXph93EYMA8aYDz+75mFbarTV/d/x0yMdI3tfSRs/vh4CqSxgzVmCps1fPkHDCtn0tU8IH9iCKgGeGpfw== dependencies: - "@jest/console" "^25.5.0" - "@jest/types" "^25.5.0" + "@jest/console" "^26.1.0" + "@jest/types" "^26.1.0" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.5.0.tgz#edc249d26f73804172dbf30a140d04b494a9dc38" - integrity sha512-c9Go3EK4+5erD2HKibIyt8JqImV23iGTWfaqMKdtD3aish8CDcXlq1X+L/CMFPOORJDV63quN4obR6iHpARapg== +"@jest/test-sequencer@^26.1.0": + version "26.1.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.1.0.tgz#41a6fc8b850c3f33f48288ea9ea517c047e7f14e" + integrity sha512-Z/hcK+rTq56E6sBwMoQhSRDVjqrGtj1y14e2bIgcowARaIE1SgOanwx6gvY4Q9gTKMoZQXbXvptji+q5GYxa6Q== dependencies: - "@jest/test-result" "^25.5.0" + "@jest/test-result" "^26.1.0" graceful-fs "^4.2.4" - jest-haste-map "^25.5.0" - jest-runner "^25.5.0" - jest-runtime "^25.5.0" + jest-haste-map "^26.1.0" + jest-runner "^26.1.0" + jest-runtime "^26.1.0" -"@jest/transform@^25.1.0", "@jest/transform@^25.5.0": +"@jest/transform@^25.1.0": version "25.5.0" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.5.0.tgz#a0f3719a1e158be442a99988d3134d577cb1c1be" integrity sha512-yqxpmosig2JWKHVbyEl8I7btXCinLIL8b3ENJYMvl9TqzZ9KulnV2t08wp4Wbv/pFKYqTd5NWyEzi4xCpcQ3mg== @@ -961,6 +960,27 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/transform@^26.1.0": + version "26.1.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.1.0.tgz#697f48898c2a2787c9b4cb71d09d7e617464e509" + integrity sha512-ICPm6sUXmZJieq45ix28k0s+d/z2E8CHDsq+WwtWI6kW8m7I8kPqarSEcUN86entHQ570ZBRci5OWaKL0wlAWw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^26.1.0" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^26.1.0" + jest-regex-util "^26.0.0" + jest-util "^26.1.0" + micromatch "^4.0.2" + pirates "^4.0.1" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + "@jest/types@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" @@ -990,6 +1010,16 @@ "@types/yargs" "^15.0.0" chalk "^3.0.0" +"@jest/types@^26.1.0": + version "26.1.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.1.0.tgz#f8afaaaeeb23b5cad49dd1f7779689941dcb6057" + integrity sha512-GXigDDsp6ZlNMhXQDeuy/iYCDsRIHJabWtDzvnn36+aqFfG14JmFV0e/iXxY4SP9vbXSiPNOWdehU5MeqrYHBQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -1353,6 +1383,13 @@ dependencies: type-detect "4.0.8" +"@sinonjs/fake-timers@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" + integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@svgr/babel-plugin-add-jsx-attribute@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1" @@ -1442,6 +1479,17 @@ merge-deep "^3.0.2" svgo "^1.2.2" +"@types/babel__core@^7.0.0": + version "7.1.9" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.9.tgz#77e59d438522a6fb898fa43dc3455c6e72f3963d" + integrity sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + "@types/babel__core@^7.1.0", "@types/babel__core@^7.1.7": version "7.1.7" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.7.tgz#1dacad8840364a57c98d0dd4855c6dd3752c6b89" @@ -1490,6 +1538,13 @@ resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== +"@types/graceful-fs@^4.1.2": + version "4.1.3" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.3.tgz#039af35fe26bec35003e8d86d2ee9c586354348f" + integrity sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ== + dependencies: + "@types/node" "*" + "@types/hammerjs@^2.0.36": version "2.0.36" resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.36.tgz#17ce0a235e9ffbcdcdf5095646b374c2bf615a4c" @@ -1555,6 +1610,11 @@ resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== +"@types/node@*": + version "14.0.26" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.26.tgz#22a3b8a46510da8944b67bfc27df02c34a35331c" + integrity sha512-W+fpe5s91FBGE0pEa0lnqGLL4USgpLgs4nokw16SrBBco/gQxuua7KnArSEOd5iaMqbbSHV10vUDkJYJJqpXKA== + "@types/node@^13.7.0": version "13.13.4" resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.4.tgz#1581d6c16e3d4803eb079c87d4ac893ee7501c2c" @@ -1565,10 +1625,10 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== -"@types/prettier@^1.19.0": - version "1.19.1" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f" - integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ== +"@types/prettier@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.0.2.tgz#5bb52ee68d0f8efa9cc0099920e56be6cc4e37f3" + integrity sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA== "@types/prop-types@*": version "15.7.3" @@ -1716,7 +1776,7 @@ resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== -abab@^2.0.0: +abab@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== @@ -1741,13 +1801,13 @@ accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" -acorn-globals@^4.3.2: - version "4.3.4" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" - integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" + acorn "^7.1.1" + acorn-walk "^7.1.1" acorn-jsx@^3.0.0: version "3.0.1" @@ -1761,10 +1821,10 @@ acorn-jsx@^5.0.0, acorn-jsx@^5.2.0: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== -acorn-walk@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" - integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== acorn@^3.0.4: version "3.3.0" @@ -1776,12 +1836,12 @@ acorn@^5.5.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== -acorn@^6.0.1, acorn@^6.0.7: +acorn@^6.0.7: version "6.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== -acorn@^7.1.0, acorn@^7.1.1: +acorn@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== @@ -1959,11 +2019,6 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= - array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" @@ -2038,6 +2093,11 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + async@^2.4.0: version "2.6.3" resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" @@ -2107,17 +2167,17 @@ babel-jest@25.1.0: chalk "^3.0.0" slash "^3.0.0" -babel-jest@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.5.0.tgz#a310e74f76585cf24d526ed477e56ee83bce86c4" - integrity sha512-8AfVNU7MEMsa+MjbY/CmwrGuQdplZ/+GkeWJDpRPm4C4wJZf937Pd9KgWU3NbnWEcYvIiqR15wy0U6C028kTWw== +babel-jest@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.1.0.tgz#b20751185fc7569a0f135730584044d1cb934328" + integrity sha512-Nkqgtfe7j6PxLO6TnCQQlkMm8wdTdnIF8xrdpooHCuD5hXRzVEPbPneTJKknH5Dsv3L8ip9unHDAp48YQ54Dkg== dependencies: - "@jest/transform" "^25.5.0" - "@jest/types" "^25.5.0" + "@jest/transform" "^26.1.0" + "@jest/types" "^26.1.0" "@types/babel__core" "^7.1.7" babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^25.5.0" - chalk "^3.0.0" + babel-preset-jest "^26.1.0" + chalk "^4.0.0" graceful-fs "^4.2.4" slash "^3.0.0" @@ -2148,6 +2208,16 @@ babel-plugin-jest-hoist@^25.5.0: "@babel/types" "^7.3.3" "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.1.0.tgz#c6a774da08247a28285620a64dfadbd05dd5233a" + integrity sha512-qhqLVkkSlqmC83bdMhM8WW4Z9tB+JkjqAqlbbohS9sJLT5Ha2vfzuKqg5yenXrAjOPG2YC0WiXdH3a9PvB+YYw== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + babel-plugin-module-resolver@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.0.0.tgz#8f3a3d9d48287dc1d3b0d5595113adabd36a847f" @@ -2213,7 +2283,7 @@ babel-preset-fbjs@^3.2.0, babel-preset-fbjs@^3.3.0: "@babel/plugin-transform-template-literals" "^7.0.0" babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" -babel-preset-jest@^25.1.0, babel-preset-jest@^25.5.0: +babel-preset-jest@^25.1.0: version "25.5.0" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz#c1d7f191829487a907764c65307faa0e66590b49" integrity sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw== @@ -2221,6 +2291,14 @@ babel-preset-jest@^25.1.0, babel-preset-jest@^25.5.0: babel-plugin-jest-hoist "^25.5.0" babel-preset-current-node-syntax "^0.1.2" +babel-preset-jest@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.1.0.tgz#612f714e5b457394acfd863793c564cbcdb7d1c1" + integrity sha512-na9qCqFksknlEj5iSdw1ehMVR06LCCTkZLGKeEtxDDdhg8xpUF09m29Kvh1pRbZ07h7AQ5ttLYUwpXL4tO6w7w== + dependencies: + babel-plugin-jest-hoist "^26.1.0" + babel-preset-current-node-syntax "^0.1.2" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -2263,6 +2341,11 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" +bluebird@^3.5.4: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -2318,13 +2401,6 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browser-resolve@^1.11.3: - version "1.11.3" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" - integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== - dependencies: - resolve "1.1.7" - bs-logger@0.x: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" @@ -2357,6 +2433,14 @@ buffer@^5.6.0: base64-js "^1.0.2" ieee754 "^1.1.4" +bunyan-debug-stream@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/bunyan-debug-stream/-/bunyan-debug-stream-1.1.1.tgz#4740a00b7d5c2d9d1b714925ab0802516040813e" + integrity sha512-jJbQ1gXUL6vMmZVdbaTFK1v1sGa7axLrSQQwkB6HU9HCPTzsw2HsKcPHm1vgXZlEck/4IvEuRwg/9+083YelCg== + dependencies: + colors "^1.0.3" + exception-formatter "^1.0.4" + bunyan@^1.8.12: version "1.8.12" resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797" @@ -2432,6 +2516,11 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +camelcase@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.0.0.tgz#5259f7c30e35e278f1bdc2a4d91230b37cad981e" + integrity sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w== + camelize@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" @@ -2486,6 +2575,14 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + change-case@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.1.0.tgz#0e611b7edc9952df2e8513b27b42de72647dd17e" @@ -2528,6 +2625,11 @@ change-case@^4.0.1: snake-case "^3.0.3" tslib "^1.10.0" +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" @@ -2538,6 +2640,15 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +child-process-promise@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074" + integrity sha1-RzChHvYQ+tRQuPIjx50x172tgHQ= + dependencies: + cross-spawn "^4.0.2" + node-version "^1.0.0" + promise-polyfill "^6.0.1" + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -2688,6 +2799,11 @@ colorette@^1.0.7: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.1.0.tgz#1f943e5a357fac10b4e0f5aaef3b14cdc1af6ec7" integrity sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg== +colors@^1.0.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -2856,6 +2972,14 @@ cross-fetch@2.2.2: node-fetch "2.1.2" whatwg-fetch "2.0.4" +cross-spawn@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -2947,7 +3071,7 @@ csso@^4.0.2: dependencies: css-tree "1.0.0-alpha.39" -cssom@^0.4.1: +cssom@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== @@ -2957,10 +3081,10 @@ cssom@~0.3.6: resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== -cssstyle@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.2.0.tgz#e4c44debccd6b7911ed617a4395e5754bba59992" - integrity sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA== +cssstyle@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== dependencies: cssom "~0.3.6" @@ -2981,14 +3105,14 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-urls@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" dayjs@^1.8.15: version "1.8.25" @@ -3021,11 +3145,21 @@ decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +decimal.js@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.0.tgz#39466113a9e036111d02f82489b5fd6b0b5ed231" + integrity sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw== + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + deep-assign@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/deep-assign/-/deep-assign-3.0.0.tgz#c8e4c4d401cba25550a2f0f486a2e75bc5f219a2" @@ -3109,6 +3243,34 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +detox@^17.3.1: + version "17.3.1" + resolved "https://registry.yarnpkg.com/detox/-/detox-17.3.1.tgz#508a1358c3c0c56670d520b2ab7480dddbfc486f" + integrity sha512-UFhHxsjfaOdO0tf6tIMXYCEIClfhgHHfjU/XZmrLavL2GKSfS3udGu+EcQ/Iqt57C1GYCHfnxMi2pgghjASmRQ== + dependencies: + bunyan "^1.8.12" + bunyan-debug-stream "^1.1.0" + chalk "^2.4.2" + child-process-promise "^2.2.0" + find-up "^4.1.0" + fs-extra "^4.0.2" + funpermaproxy "^1.0.1" + get-port "^2.1.0" + ini "^1.3.4" + lodash "^4.17.5" + minimist "^1.2.0" + proper-lockfile "^3.0.2" + sanitize-filename "^1.6.1" + shell-utils "^1.0.9" + signal-exit "^3.0.3" + tail "^2.0.0" + telnet-client "1.2.8" + tempfile "^2.0.0" + which "^1.3.1" + ws "^3.3.1" + yargs "^13.0.0" + yargs-parser "^13.0.0" + diff-sequences@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" @@ -3119,6 +3281,11 @@ diff-sequences@^25.2.6: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== +diff-sequences@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.0.0.tgz#0760059a5c287637b842bd7085311db7060e88a6" + integrity sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg== + dlv@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" @@ -3164,12 +3331,12 @@ domelementtype@^2.0.1: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== dependencies: - webidl-conversions "^4.0.2" + webidl-conversions "^5.0.0" domutils@^1.7.0: version "1.7.0" @@ -3309,15 +3476,20 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -escodegen@^1.11.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457" - integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ== +escodegen@^1.14.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== dependencies: esprima "^4.0.1" estraverse "^4.2.0" @@ -3773,6 +3945,13 @@ eventemitter3@^3.0.0: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== +exception-formatter@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/exception-formatter/-/exception-formatter-1.0.7.tgz#3291616b86fceabefa97aee6a4708032c6e3b96d" + integrity sha512-zV45vEsjytJrwfGq6X9qd1Ll56cW4NC2mhCO6lqwMk4ZpA1fZ6C3UiaQM/X7if+7wZFmCgss3ahp9B/uVFuLRw== + dependencies: + colors "^1.0.3" + exec-sh@^0.3.2: version "0.3.4" resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" @@ -3791,10 +3970,10 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^3.2.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" - integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== +execa@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.0.3.tgz#0a34dabbad6d66100bd6f2c576c8669403f317f2" + integrity sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A== dependencies: cross-spawn "^7.0.0" get-stream "^5.0.0" @@ -3803,7 +3982,6 @@ execa@^3.2.0: merge-stream "^2.0.0" npm-run-path "^4.0.0" onetime "^5.1.0" - p-finally "^2.0.0" signal-exit "^3.0.2" strip-final-newline "^2.0.0" @@ -3837,17 +4015,17 @@ expect@^24.8.0: jest-message-util "^24.9.0" jest-regex-util "^24.9.0" -expect@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-25.5.0.tgz#f07f848712a2813bb59167da3fb828ca21f58bba" - integrity sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA== +expect@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-26.1.0.tgz#8c62e31d0f8d5a8ebb186ee81473d15dd2fbf7c8" + integrity sha512-QbH4LZXDsno9AACrN9eM0zfnby9G+OsdNgZUohjg/P0mLy1O+/bzTAJGT6VSIjVCe8yKM6SzEl/ckEOFBT7Vnw== dependencies: - "@jest/types" "^25.5.0" + "@jest/types" "^26.1.0" ansi-styles "^4.0.0" - jest-get-type "^25.2.6" - jest-matcher-utils "^25.5.0" - jest-message-util "^25.5.0" - jest-regex-util "^25.2.6" + jest-get-type "^26.0.0" + jest-matcher-utils "^26.1.0" + jest-message-util "^26.1.0" + jest-regex-util "^26.0.0" extend-shallow@^1.1.2: version "1.1.4" @@ -4177,7 +4355,7 @@ fs-extra@^1.0.0: jsonfile "^2.1.0" klaw "^1.0.0" -fs-extra@^4.0.3: +fs-extra@^4.0.2, fs-extra@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== @@ -4232,6 +4410,11 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +funpermaproxy@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/funpermaproxy/-/funpermaproxy-1.0.1.tgz#4650e69b7c334d9717c06beba9b339cc08ac3335" + integrity sha512-9pEzs5vnNtR7ZGihly98w/mQ7blsvl68Wj30ZCDAXy7qDN4CWLLjdfjtH/P2m6whsnaJkw15hysCNHMXue+wdA== + gensync@^1.0.0-beta.1: version "1.0.0-beta.1" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" @@ -4242,6 +4425,13 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-port@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-2.1.0.tgz#8783f9dcebd1eea495a334e1a6a251e78887ab1a" + integrity sha1-h4P53OvR7qSVozThpqJR54iHqxo= + dependencies: + pinkie-promise "^2.0.0" + get-stdin@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" @@ -4469,12 +4659,12 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== -html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== dependencies: - whatwg-encoding "^1.0.1" + whatwg-encoding "^1.0.5" html-escaper@^2.0.0: version "2.0.2" @@ -4580,6 +4770,11 @@ inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + inquirer@^3.0.6: version "3.3.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" @@ -4747,6 +4942,11 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= +is-docker@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b" + integrity sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ== + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -4817,6 +5017,11 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-potential-custom-element-name@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" + integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= + is-regex@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" @@ -4868,10 +5073,12 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= -is-wsl@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d" - integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog== +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" @@ -4926,6 +5133,16 @@ istanbul-lib-instrument@^4.0.0: istanbul-lib-coverage "^3.0.0" semver "^6.3.0" +istanbul-lib-instrument@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== + dependencies: + "@babel/core" "^7.7.5" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" + istanbul-lib-report@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" @@ -4957,59 +5174,81 @@ iterall@^1.2.2: resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== -jest-changed-files@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.5.0.tgz#141cc23567ceb3f534526f8614ba39421383634c" - integrity sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw== +jest-changed-files@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.1.0.tgz#de66b0f30453bca2aff98e9400f75905da495305" + integrity sha512-HS5MIJp3B8t0NRKGMCZkcDUZo36mVRvrDETl81aqljT1S9tqiHRSpyoOvWg9ZilzZG9TDisDNaN1IXm54fLRZw== dependencies: - "@jest/types" "^25.5.0" - execa "^3.2.0" + "@jest/types" "^26.1.0" + execa "^4.0.0" throat "^5.0.0" -jest-cli@^25.1.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.5.0.tgz#91d96af92804ffedd5c159a7adb01321ee778049" - integrity sha512-zcUtEL1wD7BO7ehhwb7KodGS//B5dqgEIrmO3zY4xOjMnS7MMs06yzndvlDqzJqMylIkeOr1A3ToGYWFbBNSmQ== +jest-circus@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-26.1.0.tgz#3c6ef8669eb3b7a83eac27b6b7bec874d697b15f" + integrity sha512-V5h5XJLPf0XXwP92GIOx8n0Q6vdPDcFPBuEVQ9/OPzpsx3gquL8fdxaJGZ5TsvkU3zWM7mDWULAKYJMRkA2e+g== dependencies: - "@jest/core" "^25.5.0" - "@jest/test-result" "^25.5.0" - "@jest/types" "^25.5.0" - chalk "^3.0.0" + "@babel/traverse" "^7.1.0" + "@jest/environment" "^26.1.0" + "@jest/test-result" "^26.1.0" + "@jest/types" "^26.1.0" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^26.1.0" + is-generator-fn "^2.0.0" + jest-each "^26.1.0" + jest-matcher-utils "^26.1.0" + jest-message-util "^26.1.0" + jest-runtime "^26.1.0" + jest-snapshot "^26.1.0" + jest-util "^26.1.0" + pretty-format "^26.1.0" + stack-utils "^2.0.2" + throat "^5.0.0" + +jest-cli@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.1.0.tgz#eb9ec8a18cf3b6aa556d9deaa9e24be12b43ad87" + integrity sha512-Imumvjgi3rU7stq6SJ1JUEMaV5aAgJYXIs0jPqdUnF47N/Tk83EXfmtvNKQ+SnFVI6t6mDOvfM3aA9Sg6kQPSw== + dependencies: + "@jest/core" "^26.1.0" + "@jest/test-result" "^26.1.0" + "@jest/types" "^26.1.0" + chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^25.5.0" - jest-util "^25.5.0" - jest-validate "^25.5.0" + jest-config "^26.1.0" + jest-util "^26.1.0" + jest-validate "^26.1.0" prompts "^2.0.1" - realpath-native "^2.0.0" yargs "^15.3.1" -jest-config@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.5.0.tgz#6cc56bb8a72a1c1f36ed2d78668e810c844d7af5" - integrity sha512-ucmAX+AdcQAQCOnXOsefYygtFCdfkU7/pUdO+etV0JSgvO6WWnu/bWQLbff3SMw/gZLGl/t3S5Ts7Ct7Pejlwg== +jest-config@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.1.0.tgz#9074f7539acc185e0113ad6d22ed589c16a37a73" + integrity sha512-ONTGeoMbAwGCdq4WuKkMcdMoyfs5CLzHEkzFOlVvcDXufZSaIWh/OXMLa2fwKXiOaFcqEw8qFr4VOKJQfn4CVw== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^25.5.0" - "@jest/types" "^25.5.0" - babel-jest "^25.5.0" - chalk "^3.0.0" + "@jest/test-sequencer" "^26.1.0" + "@jest/types" "^26.1.0" + babel-jest "^26.1.0" + chalk "^4.0.0" deepmerge "^4.2.2" glob "^7.1.1" graceful-fs "^4.2.4" - jest-environment-jsdom "^25.5.0" - jest-environment-node "^25.5.0" - jest-get-type "^25.2.6" - jest-jasmine2 "^25.5.0" - jest-regex-util "^25.2.6" - jest-resolve "^25.5.0" - jest-util "^25.5.0" - jest-validate "^25.5.0" + jest-environment-jsdom "^26.1.0" + jest-environment-node "^26.1.0" + jest-get-type "^26.0.0" + jest-jasmine2 "^26.1.0" + jest-regex-util "^26.0.0" + jest-resolve "^26.1.0" + jest-util "^26.1.0" + jest-validate "^26.1.0" micromatch "^4.0.2" - pretty-format "^25.5.0" - realpath-native "^2.0.0" + pretty-format "^26.1.0" jest-diff@^24.3.0, jest-diff@^24.9.0: version "24.9.0" @@ -5021,7 +5260,7 @@ jest-diff@^24.3.0, jest-diff@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" -jest-diff@^25.2.1, jest-diff@^25.5.0: +jest-diff@^25.2.1: version "25.5.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9" integrity sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A== @@ -5031,47 +5270,56 @@ jest-diff@^25.2.1, jest-diff@^25.5.0: jest-get-type "^25.2.6" pretty-format "^25.5.0" -jest-docblock@^25.3.0: - version "25.3.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.3.0.tgz#8b777a27e3477cd77a168c05290c471a575623ef" - integrity sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg== +jest-diff@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.1.0.tgz#00a549bdc936c9691eb4dc25d1fbd78bf456abb2" + integrity sha512-GZpIcom339y0OXznsEKjtkfKxNdg7bVbEofK8Q6MnevTIiR1jNhDWKhRX6X0SDXJlwn3dy59nZ1z55fLkAqPWg== dependencies: - detect-newline "^3.0.0" + chalk "^4.0.0" + diff-sequences "^26.0.0" + jest-get-type "^26.0.0" + pretty-format "^26.1.0" -jest-each@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.5.0.tgz#0c3c2797e8225cb7bec7e4d249dcd96b934be516" - integrity sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA== +jest-docblock@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5" + integrity sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w== dependencies: - "@jest/types" "^25.5.0" - chalk "^3.0.0" - jest-get-type "^25.2.6" - jest-util "^25.5.0" - pretty-format "^25.5.0" + detect-newline "^3.0.0" -jest-environment-jsdom@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz#dcbe4da2ea997707997040ecf6e2560aec4e9834" - integrity sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A== - dependencies: - "@jest/environment" "^25.5.0" - "@jest/fake-timers" "^25.5.0" - "@jest/types" "^25.5.0" - jest-mock "^25.5.0" - jest-util "^25.5.0" - jsdom "^15.2.1" - -jest-environment-node@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.5.0.tgz#0f55270d94804902988e64adca37c6ce0f7d07a1" - integrity sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA== - dependencies: - "@jest/environment" "^25.5.0" - "@jest/fake-timers" "^25.5.0" - "@jest/types" "^25.5.0" - jest-mock "^25.5.0" - jest-util "^25.5.0" - semver "^6.3.0" +jest-each@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.1.0.tgz#e35449875009a22d74d1bda183b306db20f286f7" + integrity sha512-lYiSo4Igr81q6QRsVQq9LIkJW0hZcKxkIkHzNeTMPENYYDw/W/Raq28iJ0sLlNFYz2qxxeLnc5K2gQoFYlu2bA== + dependencies: + "@jest/types" "^26.1.0" + chalk "^4.0.0" + jest-get-type "^26.0.0" + jest-util "^26.1.0" + pretty-format "^26.1.0" + +jest-environment-jsdom@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.1.0.tgz#9dc7313ffe1b59761dad1fedb76e2503e5d37c5b" + integrity sha512-dWfiJ+spunVAwzXbdVqPH1LbuJW/kDL+FyqgA5YzquisHqTi0g9hquKif9xKm7c1bKBj6wbmJuDkeMCnxZEpUw== + dependencies: + "@jest/environment" "^26.1.0" + "@jest/fake-timers" "^26.1.0" + "@jest/types" "^26.1.0" + jest-mock "^26.1.0" + jest-util "^26.1.0" + jsdom "^16.2.2" + +jest-environment-node@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.1.0.tgz#8bb387b3eefb132eab7826f9a808e4e05618960b" + integrity sha512-DNm5x1aQH0iRAe9UYAkZenuzuJ69VKzDCAYISFHQ5i9e+2Tbeu2ONGY7YStubCLH8a1wdKBgqScYw85+ySxqxg== + dependencies: + "@jest/environment" "^26.1.0" + "@jest/fake-timers" "^26.1.0" + "@jest/types" "^26.1.0" + jest-mock "^26.1.0" + jest-util "^26.1.0" jest-get-type@^24.9.0: version "24.9.0" @@ -5083,6 +5331,11 @@ jest-get-type@^25.2.6: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== +jest-get-type@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.0.0.tgz#381e986a718998dbfafcd5ec05934be538db4039" + integrity sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg== + jest-haste-map@^24.7.1: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" @@ -5121,36 +5374,56 @@ jest-haste-map@^25.5.0: optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.5.0.tgz#55f5a0a264a200bc8b9fa21a5e909dbc2befd084" - integrity sha512-e66pVthiFQairNJddx7xoENQV9q3H8pNFj4SlCRb2/hi/ztVeO7RY3h41jpL/OZ5R4ewar36quJebL16jNoliQ== +jest-haste-map@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.1.0.tgz#ef31209be73f09b0d9445e7d213e1b53d0d1476a" + integrity sha512-WeBS54xCIz9twzkEdm6+vJBXgRBQfdbbXD0dk8lJh7gLihopABlJmIQFdWSDDtuDe4PRiObsjZSUjbJ1uhWEpA== + dependencies: + "@jest/types" "^26.1.0" + "@types/graceful-fs" "^4.1.2" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-serializer "^26.1.0" + jest-util "^26.1.0" + jest-worker "^26.1.0" + micromatch "^4.0.2" + sane "^4.0.3" + walker "^1.0.7" + which "^2.0.2" + optionalDependencies: + fsevents "^2.1.2" + +jest-jasmine2@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.1.0.tgz#4dfe349b2b2d3c6b3a27c024fd4cb57ac0ed4b6f" + integrity sha512-1IPtoDKOAG+MeBrKvvuxxGPJb35MTTRSDglNdWWCndCB3TIVzbLThRBkwH9P081vXLgiJHZY8Bz3yzFS803xqQ== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^25.5.0" - "@jest/source-map" "^25.5.0" - "@jest/test-result" "^25.5.0" - "@jest/types" "^25.5.0" - chalk "^3.0.0" + "@jest/environment" "^26.1.0" + "@jest/source-map" "^26.1.0" + "@jest/test-result" "^26.1.0" + "@jest/types" "^26.1.0" + chalk "^4.0.0" co "^4.6.0" - expect "^25.5.0" + expect "^26.1.0" is-generator-fn "^2.0.0" - jest-each "^25.5.0" - jest-matcher-utils "^25.5.0" - jest-message-util "^25.5.0" - jest-runtime "^25.5.0" - jest-snapshot "^25.5.0" - jest-util "^25.5.0" - pretty-format "^25.5.0" + jest-each "^26.1.0" + jest-matcher-utils "^26.1.0" + jest-message-util "^26.1.0" + jest-runtime "^26.1.0" + jest-snapshot "^26.1.0" + jest-util "^26.1.0" + pretty-format "^26.1.0" throat "^5.0.0" -jest-leak-detector@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz#2291c6294b0ce404241bb56fe60e2d0c3e34f0bb" - integrity sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA== +jest-leak-detector@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.1.0.tgz#039c3a07ebcd8adfa984b6ac015752c35792e0a6" + integrity sha512-dsMnKF+4BVOZwvQDlgn3MG+Ns4JuLv8jNvXH56bgqrrboyCbI1rQg6EI5rs+8IYagVcfVP2yZFKfWNZy0rK0Hw== dependencies: - jest-get-type "^25.2.6" - pretty-format "^25.5.0" + jest-get-type "^26.0.0" + pretty-format "^26.1.0" jest-matcher-utils@^24.9.0: version "24.9.0" @@ -5162,15 +5435,15 @@ jest-matcher-utils@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" -jest-matcher-utils@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz#fbc98a12d730e5d2453d7f1ed4a4d948e34b7867" - integrity sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw== +jest-matcher-utils@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.1.0.tgz#cf75a41bd413dda784f022de5a65a2a5c73a5c92" + integrity sha512-PW9JtItbYvES/xLn5mYxjMd+Rk+/kIt88EfH3N7w9KeOrHWaHrdYPnVHndGbsFGRJ2d5gKtwggCvkqbFDoouQA== dependencies: - chalk "^3.0.0" - jest-diff "^25.5.0" - jest-get-type "^25.2.6" - pretty-format "^25.5.0" + chalk "^4.0.0" + jest-diff "^26.1.0" + jest-get-type "^26.0.0" + pretty-format "^26.1.0" jest-message-util@^24.9.0: version "24.9.0" @@ -5186,19 +5459,19 @@ jest-message-util@^24.9.0: slash "^2.0.0" stack-utils "^1.0.1" -jest-message-util@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.5.0.tgz#ea11d93204cc7ae97456e1d8716251185b8880ea" - integrity sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA== +jest-message-util@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.1.0.tgz#52573fbb8f5cea443c4d1747804d7a238a3e233c" + integrity sha512-dY0+UlldiAJwNDJ08SF0HdF32g9PkbF2NRK/+2iMPU40O6q+iSn1lgog/u0UH8ksWoPv0+gNq8cjhYO2MFtT0g== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/types" "^25.5.0" + "@jest/types" "^26.1.0" "@types/stack-utils" "^1.0.1" - chalk "^3.0.0" + chalk "^4.0.0" graceful-fs "^4.2.4" micromatch "^4.0.2" slash "^3.0.0" - stack-utils "^1.0.1" + stack-utils "^2.0.2" jest-mock@^24.9.0: version "24.9.0" @@ -5207,12 +5480,12 @@ jest-mock@^24.9.0: dependencies: "@jest/types" "^24.9.0" -jest-mock@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.5.0.tgz#a91a54dabd14e37ecd61665d6b6e06360a55387a" - integrity sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA== +jest-mock@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.1.0.tgz#80d8286da1f05a345fbad1bfd6fa49a899465d3d" + integrity sha512-1Rm8EIJ3ZFA8yCIie92UbxZWj9SuVmUGcyhLHyAhY6WI3NIct38nVcfOPWhJteqSn8V8e3xOMha9Ojfazfpovw== dependencies: - "@jest/types" "^25.5.0" + "@jest/types" "^26.1.0" jest-pnp-resolver@^1.2.1: version "1.2.1" @@ -5229,83 +5502,87 @@ jest-regex-util@^25.2.6: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.6.tgz#d847d38ba15d2118d3b06390056028d0f2fd3964" integrity sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw== -jest-resolve-dependencies@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.5.0.tgz#d5e6ea2984aea22121f85a8cf5bcbdea35ae1d96" - integrity sha512-TXTYxNSfB9EBl1/bPUyC4gPCy+WI/DhTtePfWckvS9qworAhq9HJI1OBSoHFP5X2WeO/mx4rCfU3atWo+OH7IQ== +jest-regex-util@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" + integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== + +jest-resolve-dependencies@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.1.0.tgz#1ce36472f864a5dadf7dc82fa158e1c77955691b" + integrity sha512-fQVEPHHQ1JjHRDxzlLU/buuQ9om+hqW6Vo928aa4b4yvq4ZHBtRSDsLdKQLuCqn5CkTVpYZ7ARh2fbA8WkRE6g== dependencies: - "@jest/types" "^25.5.0" - jest-regex-util "^25.2.6" - jest-snapshot "^25.5.0" + "@jest/types" "^26.1.0" + jest-regex-util "^26.0.0" + jest-snapshot "^26.1.0" -jest-resolve@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.5.0.tgz#0099a09857a68565429b17c973cfa4227f765015" - integrity sha512-quY4fdl64UwIGZhrbWgHCORC4xPgrM+UUzucYW0Oy1PjIUHgazVTji+XtW1iQRbsrJEpfs974L2oXX3QHaYBaA== +jest-resolve@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.1.0.tgz#a530eaa302b1f6fa0479079d1561dd69abc00e68" + integrity sha512-KsY1JV9FeVgEmwIISbZZN83RNGJ1CC+XUCikf/ZWJBX/tO4a4NvA21YixokhdR9UnmPKKAC4LafVixJBrwlmfg== dependencies: - "@jest/types" "^25.5.0" - browser-resolve "^1.11.3" - chalk "^3.0.0" + "@jest/types" "^26.1.0" + chalk "^4.0.0" graceful-fs "^4.2.4" jest-pnp-resolver "^1.2.1" + jest-util "^26.1.0" read-pkg-up "^7.0.1" - realpath-native "^2.0.0" resolve "^1.17.0" slash "^3.0.0" -jest-runner@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.5.0.tgz#a32546675cbcf4e32086138f6c56c8423add6234" - integrity sha512-BJRbtZGe9V19Cv3ARFrpAfMHoHObUYLXNBKS4LTYBd85OJEp8DyFpxCG5g3AobrtmuMIvIbcNg4MvWlTtN3ODQ== +jest-runner@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.1.0.tgz#457f7fc522afe46ca6db1dccf19f87f500b3288d" + integrity sha512-elvP7y0fVDREnfqit0zAxiXkDRSw6dgCkzPCf1XvIMnSDZ8yogmSKJf192dpOgnUVykmQXwYYJnCx641uLTgcw== dependencies: - "@jest/console" "^25.5.0" - "@jest/environment" "^25.5.0" - "@jest/test-result" "^25.5.0" - "@jest/types" "^25.5.0" - chalk "^3.0.0" + "@jest/console" "^26.1.0" + "@jest/environment" "^26.1.0" + "@jest/test-result" "^26.1.0" + "@jest/types" "^26.1.0" + chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" - jest-config "^25.5.0" - jest-docblock "^25.3.0" - jest-haste-map "^25.5.0" - jest-jasmine2 "^25.5.0" - jest-leak-detector "^25.5.0" - jest-message-util "^25.5.0" - jest-resolve "^25.5.0" - jest-runtime "^25.5.0" - jest-util "^25.5.0" - jest-worker "^25.5.0" + jest-config "^26.1.0" + jest-docblock "^26.0.0" + jest-haste-map "^26.1.0" + jest-jasmine2 "^26.1.0" + jest-leak-detector "^26.1.0" + jest-message-util "^26.1.0" + jest-resolve "^26.1.0" + jest-runtime "^26.1.0" + jest-util "^26.1.0" + jest-worker "^26.1.0" source-map-support "^0.5.6" throat "^5.0.0" -jest-runtime@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.5.0.tgz#d1df2c601710974001f7095ab25c865ce5882cbc" - integrity sha512-s7TqawKRjaNaE82PjXxDYVhjrMQqjTiiY63N1jFcYtX2xtg05xsgCBk0ls6NMR3fy3AtvbPIQjD3FpssH01l6A== - dependencies: - "@jest/console" "^25.5.0" - "@jest/environment" "^25.5.0" - "@jest/globals" "^25.5.0" - "@jest/source-map" "^25.5.0" - "@jest/test-result" "^25.5.0" - "@jest/transform" "^25.5.0" - "@jest/types" "^25.5.0" +jest-runtime@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.1.0.tgz#45a37af42115f123ed5c51f126c05502da2469cb" + integrity sha512-1qiYN+EZLmG1QV2wdEBRf+Ci8i3VSfIYLF02U18PiUDrMbhfpN/EAMMkJtT02jgJUoaEOpHAIXG6zS3QRMzRmA== + dependencies: + "@jest/console" "^26.1.0" + "@jest/environment" "^26.1.0" + "@jest/fake-timers" "^26.1.0" + "@jest/globals" "^26.1.0" + "@jest/source-map" "^26.1.0" + "@jest/test-result" "^26.1.0" + "@jest/transform" "^26.1.0" + "@jest/types" "^26.1.0" "@types/yargs" "^15.0.0" - chalk "^3.0.0" + chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.4" - jest-config "^25.5.0" - jest-haste-map "^25.5.0" - jest-message-util "^25.5.0" - jest-mock "^25.5.0" - jest-regex-util "^25.2.6" - jest-resolve "^25.5.0" - jest-snapshot "^25.5.0" - jest-util "^25.5.0" - jest-validate "^25.5.0" - realpath-native "^2.0.0" + jest-config "^26.1.0" + jest-haste-map "^26.1.0" + jest-message-util "^26.1.0" + jest-mock "^26.1.0" + jest-regex-util "^26.0.0" + jest-resolve "^26.1.0" + jest-snapshot "^26.1.0" + jest-util "^26.1.0" + jest-validate "^26.1.0" slash "^3.0.0" strip-bom "^4.0.0" yargs "^15.3.1" @@ -5322,26 +5599,33 @@ jest-serializer@^25.5.0: dependencies: graceful-fs "^4.2.4" -jest-snapshot@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.5.0.tgz#0344dc1b8a949aeffefa45075508bb6277ee07d1" - integrity sha512-DveG7ZRn6HEmpDxpZXXR/U5x/aKG5N88tdaB+CH0d5jpb9tuvLMZn8rGZeBiLPS0RCO5VIlu8HL/WtY6wMk0QA== +jest-serializer@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.1.0.tgz#72a394531fc9b08e173dc7d297440ac610d95022" + integrity sha512-eqZOQG/0+MHmr25b2Z86g7+Kzd5dG9dhCiUoyUNJPgiqi38DqbDEOlHcNijyfZoj74soGBohKBZuJFS18YTJ5w== + dependencies: + graceful-fs "^4.2.4" + +jest-snapshot@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.1.0.tgz#c36ed1e0334bd7bd2fe5ad07e93a364ead7e1349" + integrity sha512-YhSbU7eMTVQO/iRbNs8j0mKRxGp4plo7sJ3GzOQ0IYjvsBiwg0T1o0zGQAYepza7lYHuPTrG5J2yDd0CE2YxSw== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^25.5.0" - "@types/prettier" "^1.19.0" - chalk "^3.0.0" - expect "^25.5.0" + "@jest/types" "^26.1.0" + "@types/prettier" "^2.0.0" + chalk "^4.0.0" + expect "^26.1.0" graceful-fs "^4.2.4" - jest-diff "^25.5.0" - jest-get-type "^25.2.6" - jest-matcher-utils "^25.5.0" - jest-message-util "^25.5.0" - jest-resolve "^25.5.0" - make-dir "^3.0.0" + jest-diff "^26.1.0" + jest-get-type "^26.0.0" + jest-haste-map "^26.1.0" + jest-matcher-utils "^26.1.0" + jest-message-util "^26.1.0" + jest-resolve "^26.1.0" natural-compare "^1.4.0" - pretty-format "^25.5.0" - semver "^6.3.0" + pretty-format "^26.1.0" + semver "^7.3.2" jest-util@^24.9.0: version "24.9.0" @@ -5372,6 +5656,17 @@ jest-util@^25.5.0: is-ci "^2.0.0" make-dir "^3.0.0" +jest-util@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.1.0.tgz#80e85d4ba820decacf41a691c2042d5276e5d8d8" + integrity sha512-rNMOwFQevljfNGvbzNQAxdmXQ+NawW/J72dmddsK0E8vgxXCMtwQ/EH0BiWEIxh0hhMcTsxwAxINt7Lh46Uzbg== + dependencies: + "@jest/types" "^26.1.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + is-ci "^2.0.0" + micromatch "^4.0.2" + jest-validate@^24.7.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" @@ -5384,29 +5679,29 @@ jest-validate@^24.7.0: leven "^3.1.0" pretty-format "^24.9.0" -jest-validate@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.5.0.tgz#fb4c93f332c2e4cf70151a628e58a35e459a413a" - integrity sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ== +jest-validate@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.1.0.tgz#942c85ad3d60f78250c488a7f85d8f11a29788e7" + integrity sha512-WPApOOnXsiwhZtmkDsxnpye+XLb/tUISP+H6cHjfUIXvlG+eKwP+isnivsxlHCPaO9Q5wvbhloIBkdF3qUn+Nw== dependencies: - "@jest/types" "^25.5.0" - camelcase "^5.3.1" - chalk "^3.0.0" - jest-get-type "^25.2.6" + "@jest/types" "^26.1.0" + camelcase "^6.0.0" + chalk "^4.0.0" + jest-get-type "^26.0.0" leven "^3.1.0" - pretty-format "^25.5.0" + pretty-format "^26.1.0" -jest-watcher@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.5.0.tgz#d6110d101df98badebe435003956fd4a465e8456" - integrity sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q== +jest-watcher@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.1.0.tgz#99812a0cd931f0cb3d153180426135ab83e4d8f2" + integrity sha512-ffEOhJl2EvAIki613oPsSG11usqnGUzIiK7MMX6hE4422aXOcVEG3ySCTDFLn1+LZNXGPE8tuJxhp8OBJ1pgzQ== dependencies: - "@jest/test-result" "^25.5.0" - "@jest/types" "^25.5.0" + "@jest/test-result" "^26.1.0" + "@jest/types" "^26.1.0" ansi-escapes "^4.2.1" - chalk "^3.0.0" - jest-util "^25.5.0" - string-length "^3.1.0" + chalk "^4.0.0" + jest-util "^26.1.0" + string-length "^4.0.1" jest-when@^2.7.1: version "2.7.1" @@ -5432,14 +5727,22 @@ jest-worker@^25.5.0: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-25.1.0.tgz#b85ef1ddba2fdb00d295deebbd13567106d35be9" - integrity sha512-FV6jEruneBhokkt9MQk0WUFoNTwnF76CLXtwNMfsc0um0TlB/LG2yxUd0KqaFjEJ9laQmVWQWS0sG/t2GsuI0w== +jest-worker@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.1.0.tgz#65d5641af74e08ccd561c240e7db61284f82f33d" + integrity sha512-Z9P5pZ6UC+kakMbNJn+tA2RdVdNX5WH1x+5UCBZ9MxIK24pjYtFt96fK+UwBTrjLYm232g1xz0L3eTh51OW+yQ== + dependencies: + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-26.1.0.tgz#2f3aa7bcffb9bfd025473f83bbbf46a3af026263" + integrity sha512-LIti8jppw5BcQvmNJe4w2g1N/3V68HUfAv9zDVm7v+VAtQulGhH0LnmmiVkbNE4M4I43Bj2fXPiBGKt26k9tHw== dependencies: - "@jest/core" "^25.1.0" + "@jest/core" "^26.1.0" import-local "^3.0.2" - jest-cli "^25.1.0" + jest-cli "^26.1.0" jetifier@^1.6.2: version "1.6.5" @@ -5469,36 +5772,36 @@ jsc-android@^245459.0.0: resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9" integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg== -jsdom@^15.2.1: - version "15.2.1" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-15.2.1.tgz#d2feb1aef7183f86be521b8c6833ff5296d07ec5" - integrity sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g== - dependencies: - abab "^2.0.0" - acorn "^7.1.0" - acorn-globals "^4.3.2" - array-equal "^1.0.0" - cssom "^0.4.1" - cssstyle "^2.0.0" - data-urls "^1.1.0" - domexception "^1.0.1" - escodegen "^1.11.1" - html-encoding-sniffer "^1.0.2" +jsdom@^16.2.2: + version "16.3.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.3.0.tgz#75690b7dac36c67be49c336dcd7219bbbed0810c" + integrity sha512-zggeX5UuEknpdZzv15+MS1dPYG0J/TftiiNunOeNxSl3qr8Z6cIlQpN0IdJa44z9aFxZRIVqRncvEhQ7X5DtZg== + dependencies: + abab "^2.0.3" + acorn "^7.1.1" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.2.0" + data-urls "^2.0.0" + decimal.js "^10.2.0" + domexception "^2.0.1" + escodegen "^1.14.1" + html-encoding-sniffer "^2.0.1" + is-potential-custom-element-name "^1.0.0" nwsapi "^2.2.0" - parse5 "5.1.0" - pn "^1.1.0" - request "^2.88.0" - request-promise-native "^1.0.7" - saxes "^3.1.9" - symbol-tree "^3.2.2" + parse5 "5.1.1" + request "^2.88.2" + request-promise-native "^1.0.8" + saxes "^5.0.0" + symbol-tree "^3.2.4" tough-cookie "^3.0.1" - w3c-hr-time "^1.0.1" - w3c-xmlserializer "^1.1.2" - webidl-conversions "^4.0.2" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" - whatwg-url "^7.0.0" - ws "^7.0.0" + whatwg-url "^8.0.0" + ws "^7.2.3" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -5750,6 +6053,11 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= +lodash@4.x.x, lodash@^4.17.19, lodash@^4.17.5: + version "4.17.19" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" + integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== + lodash@^4.11.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.3.0: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" @@ -5784,13 +6092,6 @@ loglevel@^1.4.1: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171" integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA== -lolex@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" - integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== - dependencies: - "@sinonjs/commons" "^1.7.0" - long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" @@ -6382,22 +6683,28 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-notifier@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-6.0.0.tgz#cea319e06baa16deec8ce5cd7f133c4a46b68e12" - integrity sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw== +node-notifier@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-7.0.2.tgz#3a70b1b70aca5e919d0b1b022530697466d9c675" + integrity sha512-ux+n4hPVETuTL8+daJXTOC6uKLgMsl1RYfFv7DKRzyvzBapqco0rZZ9g72ZN8VS6V+gvNYHYa/ofcCY8fkJWsA== dependencies: growly "^1.3.0" - is-wsl "^2.1.1" - semver "^6.3.0" + is-wsl "^2.2.0" + semver "^7.3.2" shellwords "^0.1.1" - which "^1.3.1" + uuid "^8.2.0" + which "^2.0.2" node-stream-zip@^1.9.1: version "1.9.2" resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.9.2.tgz#ef35da90a03627f275b3c7ead4cea1218f1f5a6a" integrity sha512-X9gnhFH8Egchv+CJwtiGYFtiRotf/gDL+MB3pV7KGFNbeYDo0NqAYocdQEU2czXj6npta9SbPj4bow1yQtoffA== +node-version@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.2.0.tgz#34fde3ffa8e1149bd323983479dda620e1b5060d" + integrity sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ== + normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -6631,11 +6938,6 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-finally@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" - integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== - p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -6733,10 +7035,10 @@ parse-node-version@^1.0.0: resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== -parse5@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" - integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== +parse5@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== parseurl@~1.3.3: version "1.3.3" @@ -6864,6 +7166,18 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + pirates@^4.0.0, pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" @@ -6924,11 +7238,6 @@ pluralize@^8.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== - posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -7018,6 +7327,16 @@ pretty-format@^25.2.0: ansi-styles "^4.0.0" react-is "^16.12.0" +pretty-format@^26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.1.0.tgz#272b9cd1f1a924ab5d443dc224899d7a65cb96ec" + integrity sha512-GmeO1PEYdM+non4BKCj+XsPJjFOJIPnsLewqhDVoqY1xo0yNmDas7tC2XwpMrRAHR3MaE2hPo37deX5OisJ2Wg== + dependencies: + "@jest/types" "^26.1.0" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^16.12.0" + private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -7033,6 +7352,11 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +promise-polyfill@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-6.1.0.tgz#dfa96943ea9c121fca4de9b5868cb39d3472e057" + integrity sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc= + promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -7057,6 +7381,15 @@ prop-types@^15.5.10, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" +proper-lockfile@^3.0.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-3.2.0.tgz#89ca420eea1d55d38ca552578851460067bcda66" + integrity sha512-iMghHHXv2bsxl6NchhEaFck8tvX3F9cknEEh1SUpguUOBjN7PAAW9BLzmbc1g/mCD1gY3EE2EABBHPJfFdHFmA== + dependencies: + graceful-fs "^4.1.11" + retry "^0.12.0" + signal-exit "^3.0.2" + protobufjs@^6.9.0: version "6.9.0" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.9.0.tgz#c08b2bf636682598e6fabbf0edb0b1256ff090bd" @@ -7512,23 +7845,23 @@ repeat-string@^1.6.1: resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -request-promise-core@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" - integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== +request-promise-core@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" + integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== dependencies: - lodash "^4.17.15" + lodash "^4.17.19" -request-promise-native@^1.0.7: - version "1.0.8" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" - integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== +request-promise-native@^1.0.8: + version "1.0.9" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" + integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== dependencies: - request-promise-core "1.1.3" + request-promise-core "1.1.4" stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.88.0: +request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -7606,11 +7939,6 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= - resolve@1.x, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1: version "1.17.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" @@ -7639,6 +7967,11 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -7760,17 +8093,24 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" +sanitize-filename@^1.6.1: + version "1.6.3" + resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz#755ebd752045931977e30b2025d340d7c9090378" + integrity sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg== + dependencies: + truncate-utf8-bytes "^1.0.0" + sax@^1.2.1, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -saxes@^3.1.9: - version "3.1.11" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" - integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== +saxes@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== dependencies: - xmlchars "^2.1.1" + xmlchars "^2.2.0" scheduler@0.17.0, scheduler@^0.17.0: version "0.17.0" @@ -7795,6 +8135,11 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -7920,6 +8265,13 @@ shell-quote@^1.6.1: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== +shell-utils@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/shell-utils/-/shell-utils-1.0.10.tgz#7fe7b8084f5d6d21323d941267013bc38aed063e" + integrity sha512-p1xuqhj3jgcXiV8wGoF1eL/NOvapN9tyGDoObqKwvZTUZn7fIzK75swLTEHfGa7sObeN9vxFplHw/zgYUYRTsg== + dependencies: + lodash "4.x.x" + shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" @@ -7933,7 +8285,7 @@ side-channel@^1.0.2: es-abstract "^1.17.0-next.1" object-inspect "^1.7.0" -signal-exit@^3.0.0, signal-exit@^3.0.2: +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== @@ -8135,6 +8487,13 @@ stack-utils@^1.0.1: resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== +stack-utils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.2.tgz#5cf48b4557becb4638d0bc4f21d23f5d19586593" + integrity sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg== + dependencies: + escape-string-regexp "^2.0.0" + stacktrace-parser@^0.1.3: version "0.1.9" resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.9.tgz#11e6d61d42e8cfc87293143d0766408b7a87b00f" @@ -8175,13 +8534,13 @@ string-hash@^1.1.3: resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= -string-length@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" - integrity sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA== +string-length@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1" + integrity sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw== dependencies: - astral-regex "^1.0.0" - strip-ansi "^5.2.0" + char-regex "^1.0.2" + strip-ansi "^6.0.0" string-width@^2.1.0: version "2.1.1" @@ -8396,7 +8755,7 @@ symbol-observable@1.0.1: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ= -symbol-tree@^3.2.2: +symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== @@ -8411,6 +8770,23 @@ table@^5.2.3: slice-ansi "^2.1.0" string-width "^3.0.0" +tail@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.4.tgz#4824de583004df17606d04854aa3cc3491b17010" + integrity sha512-xHkZdNWIzO++g+V/rHGqVoHd2LRxz+8t8bj6FGelfb8FHBjg5yjkX7Su/8sQSBo5alIspYkRp/fU0A2SM5h+5A== + +telnet-client@1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/telnet-client/-/telnet-client-1.2.8.tgz#946c0dadc8daa3f19bb40a3e898cb870403a4ca4" + integrity sha512-W+w4k3QAmULVNhBVT2Fei369kGZCh/TH25M7caJAXW+hLxwoQRuw0di3cX4l0S9fgH3Mvq7u+IFMoBDpEw/eIg== + dependencies: + bluebird "^3.5.4" + +temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= + temp@0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" @@ -8419,6 +8795,14 @@ temp@0.8.3: os-tmpdir "^1.0.0" rimraf "~2.2.6" +tempfile@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265" + integrity sha1-awRGhWqbERTRhW/8vlCczLCXcmU= + dependencies: + temp-dir "^1.0.0" + uuid "^3.0.1" + terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -8548,12 +8932,19 @@ tough-cookie@^3.0.1: psl "^1.1.28" punycode "^2.1.1" -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= +tr46@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" + integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== dependencies: - punycode "^2.1.0" + punycode "^2.1.1" + +truncate-utf8-bytes@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" + integrity sha1-QFkjkJWS1W94pYGENLC3hInKXys= + dependencies: + utf8-byte-length "^1.0.1" ts-jest@25.2.1: version "25.2.1" @@ -8672,6 +9063,11 @@ ultron@1.0.x: resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" integrity sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po= +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -8786,6 +9182,11 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +utf8-byte-length@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" + integrity sha1-9F8VDExm7uloGGUFq5P8u4rWv2E= + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -8806,11 +9207,16 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.3.2: +uuid@^3.0.1, uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +uuid@^8.2.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea" + integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ== + v8-compile-cache@^2.0.3: version "2.1.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" @@ -8864,20 +9270,18 @@ vue-eslint-parser@^2.0.2: esquery "^1.0.0" lodash "^4.17.4" -w3c-hr-time@^1.0.1: +w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== dependencies: browser-process-hrtime "^1.0.0" -w3c-xmlserializer@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" - integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== dependencies: - domexception "^1.0.1" - webidl-conversions "^4.0.2" xml-name-validator "^3.0.0" walker@^1.0.7, walker@~1.0.5: @@ -8894,12 +9298,17 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== @@ -8916,19 +9325,19 @@ whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0: resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== -whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: +whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== +whatwg-url@^8.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.1.0.tgz#c628acdcf45b82274ce7281ee31dd3c839791771" + integrity sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw== dependencies: lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" + tr46 "^2.0.2" + webidl-conversions "^5.0.0" which-module@^2.0.0: version "2.0.0" @@ -9016,11 +9425,25 @@ ws@^1.1.0, ws@^1.1.5: options ">=0.0.5" ultron "1.0.x" -ws@^7, ws@^7.0.0: +ws@^3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +ws@^7: version "7.2.5" resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.5.tgz#abb1370d4626a5a9cd79d8de404aa18b3465d10d" integrity sha512-C34cIU4+DB2vMyAbmEKossWq2ZQDr6QEyuuCzWrM9zfw1sGc0mYiJ0UnG9zzNykt49C2Fi34hvr2vssFQRS6EA== +ws@^7.2.3: + version "7.3.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" + integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== + xcode@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/xcode/-/xcode-2.1.0.tgz#bab64a7e954bb50ca8d19da7e09531c65a43ecfe" @@ -9039,7 +9462,7 @@ xmlbuilder@^9.0.7: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= -xmlchars@^2.1.1: +xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== @@ -9083,6 +9506,14 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= +yargs-parser@^13.0.0, yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs-parser@^15.0.1: version "15.0.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.1.tgz#54786af40b820dcb2fb8025b11b4d659d76323b3" @@ -9107,6 +9538,22 @@ yargs-parser@^18.1.1: camelcase "^5.0.0" decamelize "^1.2.0" +yargs@^13.0.0: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + yargs@^14.2.0: version "14.2.3" resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414" From 979be4901de1ef86695c6f72ce4cd06bdf5b01e2 Mon Sep 17 00:00:00 2001 From: Nick Mallory Date: Tue, 28 Jul 2020 12:06:29 -0400 Subject: [PATCH 015/140] use js tests --- e2e/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/config.json b/e2e/config.json index 5f638d1aa..c556f806b 100644 --- a/e2e/config.json +++ b/e2e/config.json @@ -2,7 +2,7 @@ "testEnvironment": "./environment", "testRunner": "jest-circus/runner", "testTimeout": 120000, - "testRegex": "\\.e2e\\.ts$", + "testRegex": "\\.e2e\\.js$", "reporters": ["detox/runners/jest/streamlineReporter"], "verbose": true } From 651782d61aa298022da00714079fc4652b1a2900 Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Tue, 28 Jul 2020 10:22:51 -0600 Subject: [PATCH 016/140] moved new dependencies to dev, updated detox build for ios --- .detoxrc.json | 2 +- e2e/environment.js | 6 +----- package.json | 4 ++-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.detoxrc.json b/.detoxrc.json index c5ec61d37..283e42fa2 100644 --- a/.detoxrc.json +++ b/.detoxrc.json @@ -5,7 +5,7 @@ "ios": { "type": "ios.simulator", "binaryPath": "./ios/build/Build/Products/Debug-iphonesimulator/CovidShield.app", - "build": "xcodebuild -workspace ios/CovidShield.xcworkspace -scheme CovidShield -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", + "build": "yarn bundle-ios", "device": { "type": "iPhone 11" } diff --git a/e2e/environment.js b/e2e/environment.js index ad46bec5f..b030fa340 100644 --- a/e2e/environment.js +++ b/e2e/environment.js @@ -1,8 +1,4 @@ -const { - DetoxCircusEnvironment, - SpecReporter, - WorkerAssignReporter, -} = require('detox/runners/jest-circus'); +const {DetoxCircusEnvironment, SpecReporter, WorkerAssignReporter} = require('detox/runners/jest-circus'); class CustomDetoxEnvironment extends DetoxCircusEnvironment { constructor(config) { diff --git a/package.json b/package.json index 881ae6f03..02263b1ed 100644 --- a/package.json +++ b/package.json @@ -34,9 +34,7 @@ "add": "^2.0.6", "buffer": "^5.6.0", "crypto-js": "^3.0.0", - "detox": "^17.3.1", "intl": "^1.2.5", - "jest-circus": "^26.1.0", "jsonschema": "^1.2.6", "react": "16.11.0", "react-native": "0.62.2", @@ -77,10 +75,12 @@ "@typescript-eslint/parser": "^2.27.0", "babel-jest": "25.1.0", "babel-plugin-module-resolver": "^4.0.0", + "detox": "^17.3.1", "eslint": "^6.5.1", "eslint-plugin-jest": "^23.8.2", "eslint-plugin-prettier": "^3.1.3", "jest": "^26.1.0", + "jest-circus": "^26.1.0", "jest-when": "^2.7.1", "metro-react-native-babel-preset": "^0.58.0", "patch-package": "^6.2.2", From b70a8a3e156d1f139846acb74cac9e596297cb8c Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Tue, 28 Jul 2020 11:13:49 -0600 Subject: [PATCH 017/140] added some yarn scripts from the irish repo --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 02263b1ed..4f5b7ae24 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,10 @@ "run-ios": "react-native run-ios", "start": "react-native start --reset-cache", "test": "jest", + "test:ios": "detox test --configuration=ios", + "test:android": "detox test --configuration=ios", + "pre:test:ios": "detox build --configuration=ios", + "pre:test:android": "detox build --configuration=ios", "tsc": "tsc", "fastlane:ios:beta": "bundle exec fastlane ios beta", "fastlane:ios:local": "bundle exec fastlane ios local", From b705b4177923e3989fa28841652d776d46346490 Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Tue, 28 Jul 2020 11:27:38 -0600 Subject: [PATCH 018/140] reverted my change to the ios build command --- .detoxrc.json | 2 +- ios/CovidShield/Info.plist | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.detoxrc.json b/.detoxrc.json index 283e42fa2..c5ec61d37 100644 --- a/.detoxrc.json +++ b/.detoxrc.json @@ -5,7 +5,7 @@ "ios": { "type": "ios.simulator", "binaryPath": "./ios/build/Build/Products/Debug-iphonesimulator/CovidShield.app", - "build": "yarn bundle-ios", + "build": "xcodebuild -workspace ios/CovidShield.xcworkspace -scheme CovidShield -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", "device": { "type": "iPhone 11" } diff --git a/ios/CovidShield/Info.plist b/ios/CovidShield/Info.plist index ef31ce0a7..1d60943da 100644 --- a/ios/CovidShield/Info.plist +++ b/ios/CovidShield/Info.plist @@ -59,5 +59,12 @@ UIViewControllerBasedStatusBarAppearance + NSAppTransportSecurity + + NSAllowsLocalNetworking + + NSAllowsArbitraryLoads + + From 2ea568ed4c8a0832fd5b1ffa1509e0745dbbbc95 Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Tue, 28 Jul 2020 11:35:26 -0600 Subject: [PATCH 019/140] test that the word English is displayed on the first screen --- e2e/firstTest.e2e.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/e2e/firstTest.e2e.js b/e2e/firstTest.e2e.js index 9b7e4bd56..ab7c03bf7 100644 --- a/e2e/firstTest.e2e.js +++ b/e2e/firstTest.e2e.js @@ -3,17 +3,17 @@ describe('Example', () => { await device.reloadReactNative(); }); - it('should have welcome screen', async () => { - await expect(element(by.id('welcome'))).toBeVisible(); + it('should have landing screen', async () => { + await expect(element(by.text('English'))).toBeVisible(); }); - it('should show hello screen after tap', async () => { - await element(by.id('hello_button')).tap(); - await expect(element(by.text('Hello!!!'))).toBeVisible(); - }); + // it('should show hello screen after tap', async () => { + // await element(by.id('hello_button')).tap(); + // await expect(element(by.text('Hello!!!'))).toBeVisible(); + // }); - it('should show world screen after tap', async () => { - await element(by.id('world_button')).tap(); - await expect(element(by.text('World!!!'))).toBeVisible(); - }); + // it('should show world screen after tap', async () => { + // await element(by.id('world_button')).tap(); + // await expect(element(by.text('World!!!'))).toBeVisible(); + // }); }); From f0497a325f7dbf5111930fda9cffac8d48d45c53 Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Tue, 28 Jul 2020 12:34:37 -0600 Subject: [PATCH 020/140] wip --- src/screens/home/components/AllSetView.tsx | 4 ++-- .../views/NoExposureCoveredRegionView.tsx | 12 ++++++----- .../home/views/NoExposureNoRegionView.tsx | 12 ++++++----- .../views/NoExposureUncoveredRegionView.tsx | 20 ++++++++++--------- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/screens/home/components/AllSetView.tsx b/src/screens/home/components/AllSetView.tsx index 03cc325d3..7dd66b2e3 100644 --- a/src/screens/home/components/AllSetView.tsx +++ b/src/screens/home/components/AllSetView.tsx @@ -15,11 +15,11 @@ export const AllSetView = ({ }) => { const autoFocusRef = useAccessibilityAutoFocus(!isBottomSheetExpanded); return ( - + <> {titleText} - + ); }; diff --git a/src/screens/home/views/NoExposureCoveredRegionView.tsx b/src/screens/home/views/NoExposureCoveredRegionView.tsx index a77d1e3ef..260a64cfa 100644 --- a/src/screens/home/views/NoExposureCoveredRegionView.tsx +++ b/src/screens/home/views/NoExposureCoveredRegionView.tsx @@ -15,11 +15,13 @@ export const NoExposureCoveredRegionView = ({isBottomSheetExpanded}: {isBottomSh if (!skipAllSet && onboardedDatetime && hoursFromNow(onboardedDatetime) < 24) { return ( - + + + ); } return ( diff --git a/src/screens/home/views/NoExposureNoRegionView.tsx b/src/screens/home/views/NoExposureNoRegionView.tsx index 4187aad07..5a99cff61 100644 --- a/src/screens/home/views/NoExposureNoRegionView.tsx +++ b/src/screens/home/views/NoExposureNoRegionView.tsx @@ -16,11 +16,13 @@ export const NoExposureNoRegionView = ({isBottomSheetExpanded}: {isBottomSheetEx if (!skipAllSet && onboardedDatetime && hoursFromNow(onboardedDatetime) < 24) { return ( - + + + ); } diff --git a/src/screens/home/views/NoExposureUncoveredRegionView.tsx b/src/screens/home/views/NoExposureUncoveredRegionView.tsx index 3586ae7e8..3ed074e0c 100644 --- a/src/screens/home/views/NoExposureUncoveredRegionView.tsx +++ b/src/screens/home/views/NoExposureUncoveredRegionView.tsx @@ -13,15 +13,17 @@ export const NoExposureUncoveredRegionView = ({isBottomSheetExpanded}: {isBottom const {onboardedDatetime, skipAllSet} = useStorage(); const autoFocusRef = useAccessibilityAutoFocus(!isBottomSheetExpanded); - if (!skipAllSet && onboardedDatetime && hoursFromNow(onboardedDatetime) < 24) { - return ( - - ); - } + // if (!skipAllSet && onboardedDatetime && hoursFromNow(onboardedDatetime) < 24) { + // return ( + // + // + // + // ); + // } return ( // note you can add an icon i.e. From 061dcf0f7e2c4e2ea0c019460dcaeda4d239bf30 Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Tue, 28 Jul 2020 13:15:01 -0600 Subject: [PATCH 021/140] fixed bug in yarn scripts --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4f5b7ae24..9216dc9d5 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,9 @@ "start": "react-native start --reset-cache", "test": "jest", "test:ios": "detox test --configuration=ios", - "test:android": "detox test --configuration=ios", + "test:android": "detox test --configuration=android", "pre:test:ios": "detox build --configuration=ios", - "pre:test:android": "detox build --configuration=ios", + "pre:test:android": "detox build --configuration=android", "tsc": "tsc", "fastlane:ios:beta": "bundle exec fastlane ios beta", "fastlane:ios:local": "bundle exec fastlane ios local", From de5788253ab17fd3775f431b8ed5661e0a5e20e4 Mon Sep 17 00:00:00 2001 From: Piotr Isajew Date: Tue, 28 Jul 2020 21:30:01 +0200 Subject: [PATCH 022/140] Add unit tests for Storage Service --- .../StorageService/StorageService.spec.ts | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 src/services/StorageService/StorageService.spec.ts diff --git a/src/services/StorageService/StorageService.spec.ts b/src/services/StorageService/StorageService.spec.ts new file mode 100644 index 000000000..6154f0515 --- /dev/null +++ b/src/services/StorageService/StorageService.spec.ts @@ -0,0 +1,155 @@ +import AsyncStorage from '@react-native-community/async-storage'; + +import {StorageService, Key, createStorageService} from './StorageService'; + +jest.mock('react-native-localize', () => ({ + getLocales: () => [{countryCode: 'US', languageTag: 'en-US', langaugeCode: 'en', isRTL: false}], +})); + +describe('StorageService', () => { + let storageService; + + beforeEach(async () => { + jest.clearAllMocks(); + jest.resetAllMocks(); + storageService = await createStorageService(); + }); + + describe('createStorageService', () => { + it('initializes onboarding status from persistent storage', async () => { + expect(AsyncStorage.getItem).toHaveBeenCalledWith(Key.IsOnboarded); + }); + + it('initializes locale from persistent storage', async () => { + expect(AsyncStorage.getItem).toHaveBeenCalledWith(Key.Locale); + }); + + it('initalizes region from persistent storage', async () => { + expect(AsyncStorage.getItem).toHaveBeenCalledWith(Key.Region); + }); + + it('initializes onboardedDateTime from persistent storage', async () => { + expect(AsyncStorage.getItem).toHaveBeenCalledWith(Key.OnboardedDatetime); + }); + + it('initializes forceScreen from persistent storage', async () => { + expect(AsyncStorage.getItem).toHaveBeenCalledWith(Key.ForceScreen); + }); + + it('initializes skipAllSet from persistent storage', async () => { + expect(AsyncStorage.getItem).toHaveBeenCalledWith(Key.SkipAllSet); + }); + }); + + describe('setOnboarded', () => { + it('stores the onboarded status to permanent storage', async () => { + await storageService.setOnboarded(true); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.IsOnboarded, '1'); + + await storageService.setOnboarded(false); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.IsOnboarded, '0'); + }); + + it('exposes set value as StorageService attribute', async () => { + await storageService.setOnboarded(true); + expect(storageService.isOnboarding.get()).toStrictEqual(false); + + await storageService.setOnboarded(false); + expect(storageService.isOnboarding.get()).toStrictEqual(true); + }); + }); + + describe('setLocale', () => { + it('stores the locale to permanent storage', async () => { + await storageService.setLocale('en'); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.Locale, 'en'); + + await storageService.setLocale('fr_CA'); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.Locale, 'fr_CA'); + }); + + it('exposes set value as StorageService attribute', async () => { + await storageService.setLocale('en_US'); + expect(storageService.locale.get()).toStrictEqual('en_US'); + + await storageService.setLocale('fr'); + expect(storageService.locale.get()).toStrictEqual('fr'); + }); + }); + + describe('setRegion', () => { + it('stores the region to permanent storage', async () => { + await storageService.setRegion('ABC'); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.Region, 'ABC'); + + await storageService.setRegion('asd'); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.Region, 'asd'); + }); + + it('exposes set value as StorageService attribute', async () => { + await storageService.setRegion('qwe'); + expect(storageService.region.get()).toStrictEqual('qwe'); + + await storageService.setRegion('fddd'); + expect(storageService.region.get()).toStrictEqual('fddd'); + }); + }); + + describe('setOnboardedDatetime', () => { + it('stores the onboarded date to permanent storage', async () => { + const d1 = new Date(); + await storageService.setOnboardedDatetime(d1); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.OnboardedDatetime, d1.toISOString()); + + const d2 = new Date(); + await storageService.setOnboardedDatetime(d2); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.OnboardedDatetime, d2.toISOString()); + }); + + it('exposes set value as StorageService attribute', async () => { + const d1 = new Date(); + await storageService.setOnboardedDatetime(d1); + expect(storageService.onboardedDatetime.get()).toStrictEqual(d1); + + const d2 = new Date(); + await storageService.setOnboardedDatetime(d2); + expect(storageService.onboardedDatetime.get()).toStrictEqual(d2); + }); + }); + + describe('setForceScreen', () => { + it('stores the forceScreen flag to permanent storage', async () => { + await storageService.setForceScreen('testing'); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.ForceScreen, 'testing'); + + await storageService.setForceScreen('xaz'); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.ForceScreen, 'xaz'); + }); + + it('exposes set value as StorageService attribute', async () => { + await storageService.setForceScreen('testing'); + expect(storageService.forceScreen.get()).toStrictEqual('testing'); + + await storageService.setForceScreen('xaz'); + expect(storageService.forceScreen.get()).toStrictEqual('xaz'); + }); + }); + + describe('setSkipAllSet', () => { + it('stores the SkipAllSet flag to permanent storage', async () => { + await storageService.setSkipAllSet(true); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.SkipAllSet, '1'); + + await storageService.setSkipAllSet(false); + expect(AsyncStorage.setItem).toHaveBeenCalledWith(Key.SkipAllSet, '0'); + }); + + it('exposes set value as StorageService attribute', async () => { + await storageService.setSkipAllSet(false); + expect(storageService.skipAllSet.get()).toStrictEqual(false); + + await storageService.setSkipAllSet(true); + expect(storageService.skipAllSet.get()).toStrictEqual(true); + }); + }); +}); From 551a04b6a25fdf890a17b24370281205505012a9 Mon Sep 17 00:00:00 2001 From: Piotr Isajew Date: Tue, 28 Jul 2020 21:36:58 +0200 Subject: [PATCH 023/140] added async storage mock --- __mocks__/@react-native-community/async-storage.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 __mocks__/@react-native-community/async-storage.ts diff --git a/__mocks__/@react-native-community/async-storage.ts b/__mocks__/@react-native-community/async-storage.ts new file mode 100644 index 000000000..dc59da3da --- /dev/null +++ b/__mocks__/@react-native-community/async-storage.ts @@ -0,0 +1 @@ +export {default} from '@react-native-community/async-storage/jest/async-storage-mock'; From 4ead22eeff29b9274661bb45ad957980ed12fb10 Mon Sep 17 00:00:00 2001 From: James Eberhardt Date: Tue, 28 Jul 2020 16:12:56 -0400 Subject: [PATCH 024/140] Remove direct access to `console` commands. --- src/navigation/DevPersistedNavigationContainer.tsx | 9 +++++---- src/screens/home/views/ExposureView.tsx | 3 ++- src/screens/home/views/FrameworkUnavailableView.tsx | 3 ++- src/screens/home/views/InfoShareView.tsx | 3 ++- src/screens/home/views/UnknownProblemView.tsx | 3 ++- src/screens/nocode/NoCode.tsx | 3 ++- src/services/BackendService/BackendService.ts | 2 +- .../ExposureConfigurationValidator.ts | 4 ++-- .../ExposureNotificationService.ts | 3 +-- src/shared/useReduceMotionPreference.ts | 4 +++- 10 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/navigation/DevPersistedNavigationContainer.tsx b/src/navigation/DevPersistedNavigationContainer.tsx index b133b4344..b7812d4a1 100644 --- a/src/navigation/DevPersistedNavigationContainer.tsx +++ b/src/navigation/DevPersistedNavigationContainer.tsx @@ -2,6 +2,7 @@ import {InitialState, NavigationContainerRef, NavigationContainer} from '@react- import AsyncStorage from '@react-native-community/async-storage'; import * as React from 'react'; import {InteractionManager} from 'react-native'; +import {captureException} from 'shared/log'; interface DevPersistedNavigationContainerProps extends React.ComponentProps { persistKey: string; @@ -20,8 +21,8 @@ function DevPersistedNavigationContainerImpl( persistInteractionRef.current = null; try { await AsyncStorage.setItem(persistKey, JSON.stringify(state)); - } catch (ex) { - console.warn(`Failed to persist state. ${ex.message}`); + } catch (error) { + captureException(`Failed to persist state.`, error); } }; @@ -48,8 +49,8 @@ function DevPersistedNavigationContainerImpl( setInitialState(JSON.parse(jsonString)); } setIsReady(true); - } catch (ex) { - console.warn(`Failed to load state. ${ex.message}`); + } catch (error) { + captureException(`Failed to load state.`, error); setIsReady(true); } }; diff --git a/src/screens/home/views/ExposureView.tsx b/src/screens/home/views/ExposureView.tsx index 5633056ae..fcd8468d2 100644 --- a/src/screens/home/views/ExposureView.tsx +++ b/src/screens/home/views/ExposureView.tsx @@ -5,6 +5,7 @@ import {useI18n} from 'locale'; import {Text, Box, ButtonSingleLine} from 'components'; import {useStorage} from 'services/StorageService'; import {useAccessibilityAutoFocus} from 'shared/useAccessibilityAutoFocus'; +import {captureException} from 'shared/log'; import {BaseHomeView} from '../components/BaseHomeView'; @@ -27,7 +28,7 @@ export const ExposureView = ({isBottomSheetExpanded}: {isBottomSheetExpanded: bo }, [i18n, region]); const onActionGuidance = useCallback(() => { - Linking.openURL(getGuidanceURL()).catch(err => console.error('An error occurred', err)); + Linking.openURL(getGuidanceURL()).catch(error => captureException('An error occurred', error)); }, [getGuidanceURL]); const onHowToIsolate = useCallback(() => navigation.navigate('HowToIsolate'), [navigation]); const autoFocusRef = useAccessibilityAutoFocus(!isBottomSheetExpanded); diff --git a/src/screens/home/views/FrameworkUnavailableView.tsx b/src/screens/home/views/FrameworkUnavailableView.tsx index d0d477659..8843c6632 100644 --- a/src/screens/home/views/FrameworkUnavailableView.tsx +++ b/src/screens/home/views/FrameworkUnavailableView.tsx @@ -2,6 +2,7 @@ import {useI18n} from 'locale'; import {Box, ButtonSingleLine, Text, TextMultiline} from 'components'; import React, {useCallback} from 'react'; import {useAccessibilityAutoFocus} from 'shared/useAccessibilityAutoFocus'; +import {captureException} from 'shared/log'; import {Linking} from 'react-native'; import {BaseHomeView} from '../components/BaseHomeView'; @@ -10,7 +11,7 @@ export const FrameworkUnavailableView = ({isBottomSheetExpanded}: {isBottomSheet const i18n = useI18n(); const onHelp = useCallback(() => { - Linking.openURL(i18n.translate('Info.HelpUrl')).catch(err => console.error('An error occurred', err)); + Linking.openURL(i18n.translate('Info.HelpUrl')).catch(error => captureException('An error occurred', error)); }, [i18n]); const autoFocusRef = useAccessibilityAutoFocus(!isBottomSheetExpanded); diff --git a/src/screens/home/views/InfoShareView.tsx b/src/screens/home/views/InfoShareView.tsx index d74b475a9..9c6102611 100644 --- a/src/screens/home/views/InfoShareView.tsx +++ b/src/screens/home/views/InfoShareView.tsx @@ -3,6 +3,7 @@ import {TouchableOpacity, TouchableOpacityProps, Linking} from 'react-native'; import {Box, Text, Icon, IconProps} from 'components'; import {useNavigation} from '@react-navigation/native'; import {useI18n} from 'locale'; +import {captureException} from 'shared/log'; interface InfoShareItemProps extends TouchableOpacityProps { onPress: () => void; @@ -47,7 +48,7 @@ export const InfoShareView = () => { const onLanguage = useCallback(() => navigation.navigate('LanguageSelect'), [navigation]); const onRegion = useCallback(() => navigation.navigate('RegionSelect'), [navigation]); const onHelp = useCallback(() => { - Linking.openURL(i18n.translate('Info.HelpUrl')).catch(err => console.error('An error occurred', err)); + Linking.openURL(i18n.translate('Info.HelpUrl')).catch(error => captureException('An error occurred', error)); }, [i18n]); return ( diff --git a/src/screens/home/views/UnknownProblemView.tsx b/src/screens/home/views/UnknownProblemView.tsx index 77dbdfbfe..e85054125 100644 --- a/src/screens/home/views/UnknownProblemView.tsx +++ b/src/screens/home/views/UnknownProblemView.tsx @@ -2,6 +2,7 @@ import {useI18n} from 'locale'; import {Box, ButtonSingleLine, Text} from 'components'; import React, {useCallback} from 'react'; import {useAccessibilityAutoFocus} from 'shared/useAccessibilityAutoFocus'; +import {captureException} from 'shared/log'; import {Linking} from 'react-native'; import {BaseHomeView} from '../components/BaseHomeView'; @@ -10,7 +11,7 @@ export const UnknownProblemView = ({isBottomSheetExpanded}: {isBottomSheetExpand const i18n = useI18n(); const onHelp = useCallback(() => { - Linking.openURL(i18n.translate('Info.HelpUrl')).catch(err => console.error('An error occurred', err)); + Linking.openURL(i18n.translate('Info.HelpUrl')).catch(error => captureException('An error occurred', error)); }, [i18n]); const autoFocusRef = useAccessibilityAutoFocus(!isBottomSheetExpanded); diff --git a/src/screens/nocode/NoCode.tsx b/src/screens/nocode/NoCode.tsx index 000dd3fe2..24a152c1a 100644 --- a/src/screens/nocode/NoCode.tsx +++ b/src/screens/nocode/NoCode.tsx @@ -9,6 +9,7 @@ import {BulletPoint} from 'components/BulletPoint'; import {BulletPointOrdered} from 'components/BulletPointOrdered'; import {SafeAreaView} from 'react-native-safe-area-context'; import {useAccessibilityAutoFocus} from 'shared/useAccessibilityAutoFocus'; +import {captureException} from 'shared/log'; interface ContentProps { title: string; @@ -26,7 +27,7 @@ const Content = ({title, body, notCoveredList, coveredList, externalLinkText, ex Linking.openURL(externalLinkCTA).catch(err => console.error('An error occurred', err))} + onPress={() => Linking.openURL(externalLinkCTA).catch(error => captureException('An error occurred', error))} externalLink /> ) : null; diff --git a/src/services/BackendService/BackendService.ts b/src/services/BackendService/BackendService.ts index 583a9f1be..45f15a509 100644 --- a/src/services/BackendService/BackendService.ts +++ b/src/services/BackendService/BackendService.ts @@ -64,7 +64,7 @@ export class BackendService implements BackendInterface { try { randomBytes = await getRandomBytes(32); } catch (error) { - console.error('getRandomBytes()', error); + captureException('getRandomBytes()', error); throw new Error(error); } nacl.setPRNG(buff => { diff --git a/src/services/ExposureNotificationService/ExposureConfigurationValidator.ts b/src/services/ExposureNotificationService/ExposureConfigurationValidator.ts index e5c7815d5..f47519239 100644 --- a/src/services/ExposureNotificationService/ExposureConfigurationValidator.ts +++ b/src/services/ExposureNotificationService/ExposureConfigurationValidator.ts @@ -1,4 +1,5 @@ import {Schema, Validator, ValidatorResult} from 'jsonschema'; +import {captureException} from 'shared/log'; import {ExposureConfiguration} from '../../bridge/ExposureNotification'; @@ -14,8 +15,7 @@ export class ExposureConfigurationValidator { const validator = new Validator(); const validatorResult = validator.validate(exposureConfiguration, schema); if (!validatorResult.valid) { - console.log('invalid json'); - console.log(validatorResult.errors.toString()); + captureException('invalid json', null); throw new ExposureConfigurationValidationError( `Invalid Exposure Configuration JSON. ${validatorResult.errors.toString()}`, ); diff --git a/src/services/ExposureNotificationService/ExposureNotificationService.ts b/src/services/ExposureNotificationService/ExposureNotificationService.ts index dc072df48..36e72200a 100644 --- a/src/services/ExposureNotificationService/ExposureNotificationService.ts +++ b/src/services/ExposureNotificationService/ExposureNotificationService.ts @@ -164,11 +164,10 @@ export class ExposureNotificationService { async startKeysSubmission(oneTimeCode: string): Promise { const keys = await this.backendInterface.claimOneTimeCode(oneTimeCode); const serialized = JSON.stringify(keys); - console.log(serialized); try { await this.secureStorage.set(SUBMISSION_AUTH_KEYS, serialized, {}); } catch (error) { - console.error(error); + captureException('Unable to store SUBMISSION_AUTH_KEYS', error); } const cycleStartsAt = getCurrentDate(); this.exposureStatus.append({ diff --git a/src/shared/useReduceMotionPreference.ts b/src/shared/useReduceMotionPreference.ts index 496d0b370..8f3497a32 100644 --- a/src/shared/useReduceMotionPreference.ts +++ b/src/shared/useReduceMotionPreference.ts @@ -1,6 +1,8 @@ import {useEffect, useState} from 'react'; import {AccessibilityInfo, AccessibilityEvent} from 'react-native'; +import {captureException} from './log'; + export function useReduceMotionPreference() { const [prefersReducedMotion, setPreference] = useState(false); useEffect(() => { @@ -10,7 +12,7 @@ export function useReduceMotionPreference() { AccessibilityInfo.isReduceMotionEnabled() .then(handleChange) .catch(error => { - console.warn('AccessibilityInfo.isReduceMotionEnabled promise failed', error); + captureException('AccessibilityInfo.isReduceMotionEnabled promise failed', error); }); AccessibilityInfo.addEventListener('reduceMotionChanged', handleChange); return () => { From 39ca496aacc1fccfdb7f7739d32450ef5e7c0844 Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Tue, 28 Jul 2020 14:48:59 -0600 Subject: [PATCH 025/140] removed comments, reverted changes to Info.plist --- e2e/firstTest.e2e.js | 10 ---------- ios/CovidShield/Info.plist | 7 ------- 2 files changed, 17 deletions(-) diff --git a/e2e/firstTest.e2e.js b/e2e/firstTest.e2e.js index ab7c03bf7..0044adf4c 100644 --- a/e2e/firstTest.e2e.js +++ b/e2e/firstTest.e2e.js @@ -6,14 +6,4 @@ describe('Example', () => { it('should have landing screen', async () => { await expect(element(by.text('English'))).toBeVisible(); }); - - // it('should show hello screen after tap', async () => { - // await element(by.id('hello_button')).tap(); - // await expect(element(by.text('Hello!!!'))).toBeVisible(); - // }); - - // it('should show world screen after tap', async () => { - // await element(by.id('world_button')).tap(); - // await expect(element(by.text('World!!!'))).toBeVisible(); - // }); }); diff --git a/ios/CovidShield/Info.plist b/ios/CovidShield/Info.plist index 1d60943da..ef31ce0a7 100644 --- a/ios/CovidShield/Info.plist +++ b/ios/CovidShield/Info.plist @@ -59,12 +59,5 @@ UIViewControllerBasedStatusBarAppearance - NSAppTransportSecurity - - NSAllowsLocalNetworking - - NSAllowsArbitraryLoads - - From 8766826286ea55725cf069e2fda5c7aea7848ebf Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Tue, 28 Jul 2020 14:50:45 -0600 Subject: [PATCH 026/140] reverted change to ios/CovidShield.xcodeproj/project.pbxproj --- ios/CovidShield.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/CovidShield.xcodeproj/project.pbxproj b/ios/CovidShield.xcodeproj/project.pbxproj index ce667a436..a3a10e85d 100644 --- a/ios/CovidShield.xcodeproj/project.pbxproj +++ b/ios/CovidShield.xcodeproj/project.pbxproj @@ -521,7 +521,7 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = ca.gc.hcsc.canada.stopcovid; + PRODUCT_BUNDLE_IDENTIFIER = "ca.gc.hcsc.canada.stopcovid"; PRODUCT_NAME = CovidShield; PROVISIONING_PROFILE_SPECIFIER = "Stop COVID Development Profile"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; From b678ce07a92994d11851a98b3ba6b6d2950b3a09 Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Tue, 28 Jul 2020 14:51:55 -0600 Subject: [PATCH 027/140] lint --- e2e/firstTest.e2e.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/e2e/firstTest.e2e.js b/e2e/firstTest.e2e.js index 0044adf4c..301d89a13 100644 --- a/e2e/firstTest.e2e.js +++ b/e2e/firstTest.e2e.js @@ -1,9 +1,10 @@ +/* eslint-disable no-undef */ describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); }); - it('should have landing screen', async () => { + it('has landing screen', async () => { await expect(element(by.text('English'))).toBeVisible(); }); }); From 99d1d24ec57c3b78d7fda1974d6b81473d16055e Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Tue, 28 Jul 2020 15:11:15 -0600 Subject: [PATCH 028/140] added thumbs up to the no province monitoring screen --- .../home/views/NoExposureNoRegionView.tsx | 2 +- .../views/NoExposureUncoveredRegionView.tsx | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/screens/home/views/NoExposureNoRegionView.tsx b/src/screens/home/views/NoExposureNoRegionView.tsx index 5a99cff61..f6fb6f6d2 100644 --- a/src/screens/home/views/NoExposureNoRegionView.tsx +++ b/src/screens/home/views/NoExposureNoRegionView.tsx @@ -28,7 +28,7 @@ export const NoExposureNoRegionView = ({isBottomSheetExpanded}: {isBottomSheetEx return ( // note you can add an icon i.e. {i18n.translate('Home.NoExposureDetected.NoRegion.Title')} diff --git a/src/screens/home/views/NoExposureUncoveredRegionView.tsx b/src/screens/home/views/NoExposureUncoveredRegionView.tsx index 3ed074e0c..e0d752d26 100644 --- a/src/screens/home/views/NoExposureUncoveredRegionView.tsx +++ b/src/screens/home/views/NoExposureUncoveredRegionView.tsx @@ -13,17 +13,17 @@ export const NoExposureUncoveredRegionView = ({isBottomSheetExpanded}: {isBottom const {onboardedDatetime, skipAllSet} = useStorage(); const autoFocusRef = useAccessibilityAutoFocus(!isBottomSheetExpanded); - // if (!skipAllSet && onboardedDatetime && hoursFromNow(onboardedDatetime) < 24) { - // return ( - // - // - // - // ); - // } + if (!skipAllSet && onboardedDatetime && hoursFromNow(onboardedDatetime) < 24) { + return ( + + + + ); + } return ( // note you can add an icon i.e. From 9eb729dcf8c180c364e4769479f3efc9466d1e7f Mon Sep 17 00:00:00 2001 From: James Eberhardt Date: Tue, 28 Jul 2020 17:24:15 -0400 Subject: [PATCH 029/140] Remove debugging code. --- .../ExposureNotificationService/ExposureNotificationService.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/services/ExposureNotificationService/ExposureNotificationService.ts b/src/services/ExposureNotificationService/ExposureNotificationService.ts index dc072df48..f9bb512d4 100644 --- a/src/services/ExposureNotificationService/ExposureNotificationService.ts +++ b/src/services/ExposureNotificationService/ExposureNotificationService.ts @@ -164,7 +164,6 @@ export class ExposureNotificationService { async startKeysSubmission(oneTimeCode: string): Promise { const keys = await this.backendInterface.claimOneTimeCode(oneTimeCode); const serialized = JSON.stringify(keys); - console.log(serialized); try { await this.secureStorage.set(SUBMISSION_AUTH_KEYS, serialized, {}); } catch (error) { From 3306da1fa522d54ca116e2650f8fe2d4377f419a Mon Sep 17 00:00:00 2001 From: smcmurtry Date: Tue, 28 Jul 2020 15:24:39 -0600 Subject: [PATCH 030/140] lint --- src/screens/home/components/AllSetView.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/screens/home/components/AllSetView.tsx b/src/screens/home/components/AllSetView.tsx index 7dd66b2e3..dbe31b043 100644 --- a/src/screens/home/components/AllSetView.tsx +++ b/src/screens/home/components/AllSetView.tsx @@ -2,8 +2,6 @@ import React from 'react'; import {Text, TextMultiline} from 'components'; import {useAccessibilityAutoFocus} from 'shared/useAccessibilityAutoFocus'; -import {BaseHomeView} from './BaseHomeView'; - export const AllSetView = ({ isBottomSheetExpanded, titleText, From 43870de969624ee99843b99b34d8d67d370f7bd9 Mon Sep 17 00:00:00 2001 From: James Eberhardt Date: Tue, 28 Jul 2020 16:12:56 -0400 Subject: [PATCH 031/140] Remove direct access to `console` commands. --- src/navigation/DevPersistedNavigationContainer.tsx | 9 +++++---- src/screens/home/views/ExposureView.tsx | 3 ++- src/screens/home/views/FrameworkUnavailableView.tsx | 3 ++- src/screens/home/views/InfoShareView.tsx | 3 ++- src/screens/home/views/UnknownProblemView.tsx | 3 ++- src/screens/nocode/NoCode.tsx | 3 ++- src/services/BackendService/BackendService.ts | 2 +- .../ExposureConfigurationValidator.ts | 4 ++-- .../ExposureNotificationService.ts | 2 +- src/shared/useReduceMotionPreference.ts | 4 +++- 10 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/navigation/DevPersistedNavigationContainer.tsx b/src/navigation/DevPersistedNavigationContainer.tsx index b133b4344..b7812d4a1 100644 --- a/src/navigation/DevPersistedNavigationContainer.tsx +++ b/src/navigation/DevPersistedNavigationContainer.tsx @@ -2,6 +2,7 @@ import {InitialState, NavigationContainerRef, NavigationContainer} from '@react- import AsyncStorage from '@react-native-community/async-storage'; import * as React from 'react'; import {InteractionManager} from 'react-native'; +import {captureException} from 'shared/log'; interface DevPersistedNavigationContainerProps extends React.ComponentProps { persistKey: string; @@ -20,8 +21,8 @@ function DevPersistedNavigationContainerImpl( persistInteractionRef.current = null; try { await AsyncStorage.setItem(persistKey, JSON.stringify(state)); - } catch (ex) { - console.warn(`Failed to persist state. ${ex.message}`); + } catch (error) { + captureException(`Failed to persist state.`, error); } }; @@ -48,8 +49,8 @@ function DevPersistedNavigationContainerImpl( setInitialState(JSON.parse(jsonString)); } setIsReady(true); - } catch (ex) { - console.warn(`Failed to load state. ${ex.message}`); + } catch (error) { + captureException(`Failed to load state.`, error); setIsReady(true); } }; diff --git a/src/screens/home/views/ExposureView.tsx b/src/screens/home/views/ExposureView.tsx index 5633056ae..fcd8468d2 100644 --- a/src/screens/home/views/ExposureView.tsx +++ b/src/screens/home/views/ExposureView.tsx @@ -5,6 +5,7 @@ import {useI18n} from 'locale'; import {Text, Box, ButtonSingleLine} from 'components'; import {useStorage} from 'services/StorageService'; import {useAccessibilityAutoFocus} from 'shared/useAccessibilityAutoFocus'; +import {captureException} from 'shared/log'; import {BaseHomeView} from '../components/BaseHomeView'; @@ -27,7 +28,7 @@ export const ExposureView = ({isBottomSheetExpanded}: {isBottomSheetExpanded: bo }, [i18n, region]); const onActionGuidance = useCallback(() => { - Linking.openURL(getGuidanceURL()).catch(err => console.error('An error occurred', err)); + Linking.openURL(getGuidanceURL()).catch(error => captureException('An error occurred', error)); }, [getGuidanceURL]); const onHowToIsolate = useCallback(() => navigation.navigate('HowToIsolate'), [navigation]); const autoFocusRef = useAccessibilityAutoFocus(!isBottomSheetExpanded); diff --git a/src/screens/home/views/FrameworkUnavailableView.tsx b/src/screens/home/views/FrameworkUnavailableView.tsx index d0d477659..8843c6632 100644 --- a/src/screens/home/views/FrameworkUnavailableView.tsx +++ b/src/screens/home/views/FrameworkUnavailableView.tsx @@ -2,6 +2,7 @@ import {useI18n} from 'locale'; import {Box, ButtonSingleLine, Text, TextMultiline} from 'components'; import React, {useCallback} from 'react'; import {useAccessibilityAutoFocus} from 'shared/useAccessibilityAutoFocus'; +import {captureException} from 'shared/log'; import {Linking} from 'react-native'; import {BaseHomeView} from '../components/BaseHomeView'; @@ -10,7 +11,7 @@ export const FrameworkUnavailableView = ({isBottomSheetExpanded}: {isBottomSheet const i18n = useI18n(); const onHelp = useCallback(() => { - Linking.openURL(i18n.translate('Info.HelpUrl')).catch(err => console.error('An error occurred', err)); + Linking.openURL(i18n.translate('Info.HelpUrl')).catch(error => captureException('An error occurred', error)); }, [i18n]); const autoFocusRef = useAccessibilityAutoFocus(!isBottomSheetExpanded); diff --git a/src/screens/home/views/InfoShareView.tsx b/src/screens/home/views/InfoShareView.tsx index d74b475a9..9c6102611 100644 --- a/src/screens/home/views/InfoShareView.tsx +++ b/src/screens/home/views/InfoShareView.tsx @@ -3,6 +3,7 @@ import {TouchableOpacity, TouchableOpacityProps, Linking} from 'react-native'; import {Box, Text, Icon, IconProps} from 'components'; import {useNavigation} from '@react-navigation/native'; import {useI18n} from 'locale'; +import {captureException} from 'shared/log'; interface InfoShareItemProps extends TouchableOpacityProps { onPress: () => void; @@ -47,7 +48,7 @@ export const InfoShareView = () => { const onLanguage = useCallback(() => navigation.navigate('LanguageSelect'), [navigation]); const onRegion = useCallback(() => navigation.navigate('RegionSelect'), [navigation]); const onHelp = useCallback(() => { - Linking.openURL(i18n.translate('Info.HelpUrl')).catch(err => console.error('An error occurred', err)); + Linking.openURL(i18n.translate('Info.HelpUrl')).catch(error => captureException('An error occurred', error)); }, [i18n]); return ( diff --git a/src/screens/home/views/UnknownProblemView.tsx b/src/screens/home/views/UnknownProblemView.tsx index 77dbdfbfe..e85054125 100644 --- a/src/screens/home/views/UnknownProblemView.tsx +++ b/src/screens/home/views/UnknownProblemView.tsx @@ -2,6 +2,7 @@ import {useI18n} from 'locale'; import {Box, ButtonSingleLine, Text} from 'components'; import React, {useCallback} from 'react'; import {useAccessibilityAutoFocus} from 'shared/useAccessibilityAutoFocus'; +import {captureException} from 'shared/log'; import {Linking} from 'react-native'; import {BaseHomeView} from '../components/BaseHomeView'; @@ -10,7 +11,7 @@ export const UnknownProblemView = ({isBottomSheetExpanded}: {isBottomSheetExpand const i18n = useI18n(); const onHelp = useCallback(() => { - Linking.openURL(i18n.translate('Info.HelpUrl')).catch(err => console.error('An error occurred', err)); + Linking.openURL(i18n.translate('Info.HelpUrl')).catch(error => captureException('An error occurred', error)); }, [i18n]); const autoFocusRef = useAccessibilityAutoFocus(!isBottomSheetExpanded); diff --git a/src/screens/nocode/NoCode.tsx b/src/screens/nocode/NoCode.tsx index 000dd3fe2..24a152c1a 100644 --- a/src/screens/nocode/NoCode.tsx +++ b/src/screens/nocode/NoCode.tsx @@ -9,6 +9,7 @@ import {BulletPoint} from 'components/BulletPoint'; import {BulletPointOrdered} from 'components/BulletPointOrdered'; import {SafeAreaView} from 'react-native-safe-area-context'; import {useAccessibilityAutoFocus} from 'shared/useAccessibilityAutoFocus'; +import {captureException} from 'shared/log'; interface ContentProps { title: string; @@ -26,7 +27,7 @@ const Content = ({title, body, notCoveredList, coveredList, externalLinkText, ex Linking.openURL(externalLinkCTA).catch(err => console.error('An error occurred', err))} + onPress={() => Linking.openURL(externalLinkCTA).catch(error => captureException('An error occurred', error))} externalLink /> ) : null; diff --git a/src/services/BackendService/BackendService.ts b/src/services/BackendService/BackendService.ts index 583a9f1be..45f15a509 100644 --- a/src/services/BackendService/BackendService.ts +++ b/src/services/BackendService/BackendService.ts @@ -64,7 +64,7 @@ export class BackendService implements BackendInterface { try { randomBytes = await getRandomBytes(32); } catch (error) { - console.error('getRandomBytes()', error); + captureException('getRandomBytes()', error); throw new Error(error); } nacl.setPRNG(buff => { diff --git a/src/services/ExposureNotificationService/ExposureConfigurationValidator.ts b/src/services/ExposureNotificationService/ExposureConfigurationValidator.ts index e5c7815d5..f47519239 100644 --- a/src/services/ExposureNotificationService/ExposureConfigurationValidator.ts +++ b/src/services/ExposureNotificationService/ExposureConfigurationValidator.ts @@ -1,4 +1,5 @@ import {Schema, Validator, ValidatorResult} from 'jsonschema'; +import {captureException} from 'shared/log'; import {ExposureConfiguration} from '../../bridge/ExposureNotification'; @@ -14,8 +15,7 @@ export class ExposureConfigurationValidator { const validator = new Validator(); const validatorResult = validator.validate(exposureConfiguration, schema); if (!validatorResult.valid) { - console.log('invalid json'); - console.log(validatorResult.errors.toString()); + captureException('invalid json', null); throw new ExposureConfigurationValidationError( `Invalid Exposure Configuration JSON. ${validatorResult.errors.toString()}`, ); diff --git a/src/services/ExposureNotificationService/ExposureNotificationService.ts b/src/services/ExposureNotificationService/ExposureNotificationService.ts index f9bb512d4..36e72200a 100644 --- a/src/services/ExposureNotificationService/ExposureNotificationService.ts +++ b/src/services/ExposureNotificationService/ExposureNotificationService.ts @@ -167,7 +167,7 @@ export class ExposureNotificationService { try { await this.secureStorage.set(SUBMISSION_AUTH_KEYS, serialized, {}); } catch (error) { - console.error(error); + captureException('Unable to store SUBMISSION_AUTH_KEYS', error); } const cycleStartsAt = getCurrentDate(); this.exposureStatus.append({ diff --git a/src/shared/useReduceMotionPreference.ts b/src/shared/useReduceMotionPreference.ts index 496d0b370..8f3497a32 100644 --- a/src/shared/useReduceMotionPreference.ts +++ b/src/shared/useReduceMotionPreference.ts @@ -1,6 +1,8 @@ import {useEffect, useState} from 'react'; import {AccessibilityInfo, AccessibilityEvent} from 'react-native'; +import {captureException} from './log'; + export function useReduceMotionPreference() { const [prefersReducedMotion, setPreference] = useState(false); useEffect(() => { @@ -10,7 +12,7 @@ export function useReduceMotionPreference() { AccessibilityInfo.isReduceMotionEnabled() .then(handleChange) .catch(error => { - console.warn('AccessibilityInfo.isReduceMotionEnabled promise failed', error); + captureException('AccessibilityInfo.isReduceMotionEnabled promise failed', error); }); AccessibilityInfo.addEventListener('reduceMotionChanged', handleChange); return () => { From e080aff79557c880e5d79f3a3410839ee8c15fe8 Mon Sep 17 00:00:00 2001 From: James Eberhardt Date: Tue, 28 Jul 2020 18:26:50 -0400 Subject: [PATCH 032/140] Force return on `captureMessage` and `captureException` --- src/shared/log.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/shared/log.ts b/src/shared/log.ts index 2878a309d..7360e5dbf 100644 --- a/src/shared/log.ts +++ b/src/shared/log.ts @@ -1,6 +1,10 @@ export const captureMessage = async (message: string, params: {[key in string]: any} = {}) => { + // force return for production + return; + const finalMessage = message; const finalParams = params; + if (!__DEV__) { return; } @@ -8,6 +12,9 @@ export const captureMessage = async (message: string, params: {[key in string]: }; export const captureException = async (message: string, error: any, params: {[key in string]: any} = {}) => { + // force return for production + return; + const finalMessage = `Error: ${message}`; const finalParams = { ...params, From e749ed4ce6a9cbab9cd44f9471f962d31b4d6768 Mon Sep 17 00:00:00 2001 From: Piotr Isajew Date: Wed, 29 Jul 2020 06:59:10 +0200 Subject: [PATCH 033/140] Increasing test coverage for date-fns --- src/shared/date-fns.spec.ts | 145 +++++++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 1 deletion(-) diff --git a/src/shared/date-fns.spec.ts b/src/shared/date-fns.spec.ts index af382ec9b..c06392efb 100644 --- a/src/shared/date-fns.spec.ts +++ b/src/shared/date-fns.spec.ts @@ -1,4 +1,12 @@ -import {daysBetweenUTC} from './date-fns'; +import { + daysBetweenUTC, + addDays, + hoursSinceEpoch, + daysFromNow, + hoursFromNow, + minutesFromNow, + minutesBetween, +} from './date-fns'; /** * These tests have to run in non UTC timezone. @@ -29,6 +37,141 @@ describe('date-fns', () => { }); }); + describe('addDays', () => { + const now = new Date(); + + it('returns date 1 day from now if 1 day was added', () => { + expect(addDays(now, 1).getTime() - now.getTime()).toStrictEqual(86400 * 1000); + }); + + it('returns the same date if 0 days was added', () => { + expect(addDays(now, 0)).toStrictEqual(now); + }); + }); + + describe('hoursSinceEpoch', () => { + it('returns 1 for date which is 1 hour since the epoch', () => { + expect(hoursSinceEpoch(new Date('1970-01-01 01:00:00 GMT+0000'))).toStrictEqual(1); + }); + + it('returns 0 for the epoch', () => { + expect(hoursSinceEpoch(new Date('1970-01-01 00:00:00 GMT+0000'))).toStrictEqual(0); + }); + + it('returns 25.5 for 1:30 first day after epoch', () => { + expect(hoursSinceEpoch(new Date('1970-01-02 01:30:00 GMT+0000'))).toStrictEqual(25.5); + }); + }); + + describe('daysFromNow', () => { + let now; + + beforeEach(() => { + now = jest.spyOn(Date, 'now').mockImplementation(() => new Date('2020-07-07 00:01:00 GMT+0200')); + }); + + afterEach(() => { + now.mockReset(); + }); + + it('returns 1 if the date is within 24h in past', () => { + const date = new Date('2020-07-06 00:01:01 GMT+0200'); + expect(daysFromNow(date)).toStrictEqual(1); + }); + + it('returns -1 if the date is within 24h in future', () => { + const date = new Date('2020-07-07 23:59:59 GMT+0200'); + expect(daysFromNow(date)).toStrictEqual(-1); + }); + + it('returns 0 if the date is exactly the current time', () => { + expect(daysFromNow(now())).toStrictEqual(0); + }); + }); + + describe('hoursFromNow', () => { + let now; + + beforeEach(() => { + now = jest.spyOn(Date, 'now').mockImplementation(() => new Date('2020-07-07 00:01:00 GMT+0200')); + }); + + afterEach(() => { + now.mockReset(); + }); + + it('returns 1 if the date is between 60 and 120 minutes in past', () => { + const date = new Date('2020-07-06 22:32:00 GMT+0200'); + expect(hoursFromNow(date)).toStrictEqual(1); + }); + + it('returns -1 if the date is within 60 minutes in future', () => { + const date = new Date('2020-07-07 00:59:59 GMT+0200'); + expect(hoursFromNow(date)).toStrictEqual(-1); + }); + + it('returns 0 if the date is exactly the current time', () => { + expect(hoursFromNow(now())).toStrictEqual(0); + }); + }); + + describe('minutesFromNow', () => { + let now; + + beforeEach(() => { + now = jest.spyOn(Date, 'now').mockImplementation(() => new Date('2020-07-07 00:01:00 GMT+0200')); + }); + + afterEach(() => { + now.mockReset(); + }); + + it('returns 1 if the date is within 60 seconds in past', () => { + const date = new Date('2020-07-07 00:00:00 GMT+0200'); + expect(minutesFromNow(date)).toStrictEqual(1); + }); + + it('returns 2 if the date is 100 seconds in past', () => { + const date = new Date('2020-07-06 23:59:20 GMT+0200'); + expect(minutesFromNow(date)).toStrictEqual(2); + }); + + it('returns -3 if the date is 3 minutes in future', () => { + const date = new Date('2020-07-07 00:04:00 GMT+0200'); + expect(minutesFromNow(date)).toStrictEqual(-3); + }); + + it('returns 0 if the date is exactly the current time', () => { + expect(minutesFromNow(now())).toStrictEqual(0); + }); + }); + + describe('minutesBetween', () => { + it('returns 0 when comparing the same dates', () => { + const d1 = new Date('2020-07-06 00:00:01 GMT+0600'); + const d2 = new Date('2020-07-06 00:00:01 GMT+0600'); + expect(minutesBetween(d1, d2)).toStrictEqual(0); + }); + + it('returns 2 if second argument is exactly 2 minutes later than first', () => { + const d1 = new Date('2020-07-06 00:00:01 GMT+0600'); + const d2 = new Date('2020-07-06 00:02:01 GMT+0600'); + expect(minutesBetween(d1, d2)).toStrictEqual(2); + }); + + it('returns -60 if second argument is exactly 1 hour earlier than first', () => { + const d1 = new Date('2020-07-06 00:00:01 GMT+0600'); + const d2 = new Date('2020-07-05 23:00:01 GMT+0600'); + expect(minutesBetween(d1, d2)).toStrictEqual(-60); + }); + + it('returns timezone offset difference for the same time in different timezones', () => { + const d1 = new Date('2020-07-06 00:00:01 GMT+0600'); + const d2 = new Date('2020-07-06 00:00:01 GMT+0500'); + expect(minutesBetween(d1, d2)).toStrictEqual(60); + }); + }); + // eslint-disable-next-line jest/no-commented-out-tests // it('returns 1 missing day for keys upload', () => { // const today = new Date('Wed Jul 28 2020 00:00:00 GMT-0400'); From 5c75d02e2bdf530c61c398ff33cc3e1b09bd4653 Mon Sep 17 00:00:00 2001 From: Nick Mallory Date: Wed, 29 Jul 2020 08:39:39 -0400 Subject: [PATCH 034/140] Android setup for Detox --- android/app/build.gradle | 7 ++++++ .../java/app/covidshield/DetoxTest.java | 23 +++++++++++++++++++ android/build.gradle | 4 ++++ 3 files changed, 34 insertions(+) create mode 100644 android/app/src/androidTest/java/app/covidshield/DetoxTest.java diff --git a/android/app/build.gradle b/android/app/build.gradle index 87e018e0b..92807eff1 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -144,6 +144,8 @@ android { versionCode project.env.get("APP_VERSION_CODE") as Integer versionName project.env.get("APP_VERSION_NAME") resValue "string", "build_config_package", "app.covidshield" + testBuildType System.getProperty('testBuildType', 'debug') + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } splits { abi { @@ -179,6 +181,7 @@ android { minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" signingConfig signingConfigs.release + proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro" } } @@ -243,6 +246,10 @@ dependencies { } else { implementation jscFlavor } + + androidTestImplementation('com.wix:detox:+') { transitive = true } + androidTestImplementation 'junit:junit:4.12' + implementation "androidx.annotation:annotation:1.1.0" } // Run this once to be able to run the application with BUCK diff --git a/android/app/src/androidTest/java/app/covidshield/DetoxTest.java b/android/app/src/androidTest/java/app/covidshield/DetoxTest.java new file mode 100644 index 000000000..79bf2070c --- /dev/null +++ b/android/app/src/androidTest/java/app/covidshield/DetoxTest.java @@ -0,0 +1,23 @@ +package app.covidshield; + +import com.wix.detox.Detox; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.LargeTest; +import androidx.test.rule.ActivityTestRule; + +@RunWith(AndroidJUnit4.class) +@LargeTest +public class DetoxTest { + @Rule + public ActivityTestRule mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false); + + @Test + public void runDetoxTests() { + Detox.runTests(mActivityRule); + } +} diff --git a/android/build.gradle b/android/build.gradle index baa012b0c..620666769 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -52,6 +52,10 @@ allprojects { google() jcenter() maven { url 'https://www.jitpack.io' } + maven { + // All of Detox' artifacts are provided via the npm module + url "$rootDir/../node_modules/detox/Detox-android" + } } } From f78805c9cf3323f4068e90ccecb02164a5021320 Mon Sep 17 00:00:00 2001 From: nickmly Date: Wed, 29 Jul 2020 09:25:40 -0400 Subject: [PATCH 035/140] Added testID prop to Buttons for LandingScreen --- src/components/Button.tsx | 4 ++++ src/screens/landing/LandingScreen.tsx | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 98a77ed96..4561cd1cd 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -28,6 +28,7 @@ export interface ButtonProps { internalLink?: boolean; backButton?: boolean; iconName?: IconName; + testID?: string; } export const Button = ({ @@ -41,6 +42,7 @@ export const Button = ({ internalLink, backButton, iconName, + testID, }: ButtonProps) => { const i18n = useI18n(); const theme = useTheme(); @@ -122,6 +124,7 @@ export const Button = ({ onPress={onPressHandler} backgroundColor={color} borderRadius={borderRadius} + testID={testID} {...accessibilityProps} > {content} @@ -134,6 +137,7 @@ export const Button = ({ onPress={onPressHandler} style={styles.stretch} disabled={disabled} + testID={testID} {...accessibilityProps} > {content} diff --git a/src/screens/landing/LandingScreen.tsx b/src/screens/landing/LandingScreen.tsx index 7106de0d5..70e4bdab6 100644 --- a/src/screens/landing/LandingScreen.tsx +++ b/src/screens/landing/LandingScreen.tsx @@ -34,10 +34,10 @@ export const LandingScreen = () => { -