From 5ab9ed97974d7fd41d21ed40e2a3fb35e312b483 Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Wed, 16 Oct 2024 09:22:50 -0400 Subject: [PATCH 01/99] WIP --- shared/todo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/todo.txt b/shared/todo.txt index bb5734ef987d..44268f83db35 100644 --- a/shared/todo.txt +++ b/shared/todo.txt @@ -1,3 +1,3 @@ Some short term todos: swipeable2 slow -mem leak +mem leak (mergedown) From 3db47eb97b0f25703a6ca42714ec95dc8cb3f24f Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Wed, 16 Oct 2024 09:25:06 -0400 Subject: [PATCH 02/99] WIP: expo 51 (#26844) --- .../android/build.gradle | 87 +- .../com/reactnativedropview/DropViewView.java | 25 - .../com/reactnativedropview/DropViewView.kt | 12 + .../DropViewViewManager.java | 25 - .../DropViewViewManager.kt | 23 + .../DropViewViewPackage.java | 24 - .../DropViewViewPackage.kt | 20 + .../src/newarch/DropViewViewManagerSpec.java | 31 - .../src/newarch/DropViewViewManagerSpec.kt | 22 + .../src/oldarch/DropViewViewManagerSpec.java | 9 - .../src/oldarch/DropViewViewManagerSpec.kt | 7 + .../ios/DropViewView.mm | 27 +- rnmodules/react-native-drop-view/yarn.lock | 1717 ++-- .../react-native-kb/android/build.gradle | 11 +- .../react-native-kb/android/cpp-adapter.cpp | 20 +- .../react-native-kb/android/gradle.properties | 10 +- .../com/reactnativekb/DarkModePrefHelper.java | 14 - .../com/reactnativekb/DarkModePrefHelper.kt | 13 + .../com/reactnativekb/DarkModePreference.java | 6 - .../com/reactnativekb/DarkModePreference.kt | 9 + .../java/com/reactnativekb/GuiConfig.java | 44 - .../main/java/com/reactnativekb/GuiConfig.kt | 42 + .../main/java/com/reactnativekb/KbModule.java | 719 -- .../main/java/com/reactnativekb/KbModule.kt | 731 ++ .../java/com/reactnativekb/KbPackage.java | 45 - .../main/java/com/reactnativekb/KbPackage.kt | 40 + .../java/com/reactnativekb/NativeLogger.java | 59 - .../java/com/reactnativekb/NativeLogger.kt | 56 + .../java/com/reactnativekb/PathResolver.java | 224 - .../java/com/reactnativekb/PathResolver.kt | 208 + .../com/reactnativekb/ReadFileAsString.java | 39 - .../com/reactnativekb/ReadFileAsString.kt | 38 + .../android/src/newarch/KbSpec.java | 10 - .../android/src/newarch/KbSpec.kt | 5 + .../android/src/oldarch/KbSpec.java | 40 - .../android/src/oldarch/KbSpec.kt | 36 + .../react-native-kb/ios/KBJSScheduler.cpp | 34 + rnmodules/react-native-kb/ios/KBJSScheduler.h | 39 + rnmodules/react-native-kb/ios/Kb.h | 4 +- rnmodules/react-native-kb/ios/Kb.mm | 165 +- .../lib/module/NativeKb.js.map | 2 +- .../lib/typescript/NativeKb.d.ts | 4 +- .../react-native-kb/lib/typescript/index.d.ts | 2 +- .../react-native-kb/react-native-kb.podspec | 2 +- rnmodules/react-native-kb/src/NativeKb.ts | 5 +- rnmodules/react-native-kb/yarn.lock | 1738 ++-- shared/.eslintignore | 18 - shared/.eslintrc.js | 318 - shared/.gitignore | 1 + shared/Gemfile | 4 +- shared/actions/engine-gen-gen.tsx | 1642 ++-- shared/android/app/build.gradle | 52 +- .../keybase/ossifrage/MainActivityTest.java | 28 - .../android/app/src/debug/AndroidManifest.xml | 8 +- .../keybase/ossifrage/ReactNativeFlipper.java | 77 - .../android/app/src/main/AndroidManifest.xml | 5 +- .../ossifrage/ChatBroadcastReceiver.java | 91 - .../ossifrage/ChatBroadcastReceiver.kt | 89 + ...CustomBitmapMemoryCacheParamsSupplier.java | 56 - .../CustomBitmapMemoryCacheParamsSupplier.kt | 54 + .../ossifrage/KBInstallReferrerListener.java | 110 - .../ossifrage/KBInstallReferrerListener.kt | 97 + .../io/keybase/ossifrage/KBPushNotifier.java | 275 - .../io/keybase/ossifrage/KBPushNotifier.kt | 229 + .../io/keybase/ossifrage/KBReactPackage.java | 24 - .../io/keybase/ossifrage/KBReactPackage.kt | 17 + .../java/io/keybase/ossifrage/KeyStore.java | 241 - .../java/io/keybase/ossifrage/KeyStore.kt | 207 + ...eybasePushNotificationListenerService.java | 318 - .../KeybasePushNotificationListenerService.kt | 303 + .../io/keybase/ossifrage/MainActivity.java | 528 -- .../java/io/keybase/ossifrage/MainActivity.kt | 441 + .../io/keybase/ossifrage/MainApplication.java | 154 - .../io/keybase/ossifrage/MainApplication.kt | 104 + .../ossifrage/keystore/KeyStoreHelper.java | 64 - .../ossifrage/keystore/KeyStoreHelper.kt | 52 + .../modules/BackgroundSyncWorker.java | 28 - .../ossifrage/modules/BackgroundSyncWorker.kt | 22 + .../ossifrage/modules/KillableModule.java | 5 - .../ossifrage/modules/KillableModule.kt | 5 + .../ossifrage/modules/NativeLogger.java | 58 - .../keybase/ossifrage/modules/NativeLogger.kt | 48 + .../ossifrage/modules/StorybookConstants.java | 28 - .../ossifrage/modules/StorybookConstants.kt | 18 + .../keybase/ossifrage/util/DNSNSFetcher.java | 29 - .../io/keybase/ossifrage/util/DNSNSFetcher.kt | 27 + .../ossifrage/util/DeviceLockType.java | 115 - .../keybase/ossifrage/util/DeviceLockType.kt | 108 + .../ossifrage/util/SharedFileProvider.java | 6 - .../ossifrage/util/SharedFileProvider.kt | 5 + .../keybase/ossifrage/util/VideoHelper.java | 41 - .../io/keybase/ossifrage/util/VideoHelper.kt | 37 + .../keybase/ossifrage/ReactNativeFlipper.java | 18 - .../keybase/ossifrage/ReactNativeFlipper.java | 19 - shared/android/build.gradle | 42 +- shared/android/gradle.properties | 12 - .../android/gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 43453 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 +- shared/android/gradlew | 204 +- shared/android/gradlew.bat | 20 +- shared/android/settings.gradle | 14 +- shared/app/global-errors/hook.tsx | 14 +- shared/app/global-errors/index.d.ts | 1 - shared/app/globals.native.tsx | 14 +- shared/app/index.native.tsx | 38 +- shared/app/runtime-stats.tsx | 171 +- shared/babel.config.js | 26 +- shared/chat/audio/audio-player.tsx | 9 +- shared/chat/audio/audio-recorder.native.tsx | 45 +- shared/chat/audio/audio-send.native.tsx | 3 +- shared/chat/audio/audio-video.d.ts | 1 - shared/chat/audio/audio-video.desktop.tsx | 25 +- shared/chat/audio/audio-video.native.tsx | 20 +- .../attachment-fullscreen/index.desktop.tsx | 14 +- .../attachment-fullscreen/index.native.tsx | 26 +- .../attachment-get-titles/index.tsx | 2 +- .../conversation/command-status/container.tsx | 2 +- .../conversation/header-area/index.native.tsx | 13 +- .../conversation/info-panel/add-people.tsx | 51 +- .../conversation/info-panel/attachments.tsx | 19 +- shared/chat/conversation/info-panel/bot.tsx | 17 +- shared/chat/conversation/info-panel/index.tsx | 6 + .../chat/conversation/info-panel/members.tsx | 23 +- .../info-panel/menu/container.tsx | 23 +- .../conversation/input-area/container.tsx | 2 +- .../index.tsx} | 4 +- .../page.tsx} | 2 +- .../conversation/input-area/normal/index.tsx | 256 - .../conversation/input-area/normal2/index.tsx | 303 + .../max-input-area-context.tsx | 0 .../{normal => normal2}/moremenu-popup.tsx | 0 .../{normal => normal2}/platform-input.d.ts | 6 +- .../platform-input.desktop.tsx | 81 +- .../platform-input.native.tsx | 135 +- .../normal2}/set-explode-popup/container.tsx | 6 +- .../normal2}/set-explode-popup/index.d.ts | 0 .../set-explode-popup/index.desktop.tsx | 0 .../set-explode-popup/index.native.tsx | 0 .../typing/index.tsx => normal2/typing.tsx} | 13 +- .../input-area/suggestors/channels.tsx | 9 +- .../input-area/suggestors/commands.tsx | 9 +- .../input-area/suggestors/common.tsx | 56 +- .../input-area/suggestors/emoji.tsx | 14 +- .../input-area/suggestors/index.tsx | 42 +- .../{normal => suggestors}/shared.tsx | 0 .../suggestors/suggestion-list.desktop.tsx | 2 +- .../suggestors/suggestion-list.native.tsx | 2 +- .../input-area/suggestors/users.tsx | 42 +- .../conversation/list-area/index.desktop.tsx | 475 +- .../conversation/list-area/index.native.tsx | 54 +- .../list-area/use-intersection-observer.tsx | 157 + .../list-area/use-resize-observer.tsx | 91 + .../pending-background/index.d.ts | 10 - .../pending-background/index.desktop.tsx | 34 - .../pending-background/index.native.tsx | 54 - .../pending-background/pending-background.css | 21 - .../messages/attachment/file/index.tsx | 7 +- .../messages/attachment/image2/imageimpl.d.ts | 3 +- .../messages/attachment/shared.tsx | 32 +- .../conversation/messages/cards/hello-bot.tsx | 4 +- .../messages/react-button/index.tsx | 5 +- .../chat/conversation/messages/separator.tsx | 53 +- .../messages/special-top-message.tsx | 25 +- .../messages/text/coinflip/index.tsx | 6 +- .../text/unfurl/unfurl-list/map-popup.tsx | 4 +- .../messages/text/unfurl/unfurl-list/map.tsx | 2 +- .../conversation/messages/text/wrapper.tsx | 16 +- .../index.desktop.tsx | 6 +- .../messages/wrapper/exploding-meta/index.tsx | 10 +- .../wrapper/long-pressable/index.native.tsx | 49 +- .../messages/wrapper/send-indicator/index.tsx | 113 +- .../conversation/messages/wrapper/sent.tsx | 40 +- .../conversation/messages/wrapper/wrapper.tsx | 26 +- shared/chat/conversation/normal/container.tsx | 108 +- shared/chat/conversation/normal/context.tsx | 22 +- .../conversation/normal/index.desktop.tsx | 4 +- .../chat/conversation/normal/index.native.tsx | 10 +- .../conversation/pinned-message/index.tsx | 16 +- shared/chat/emoji-picker/container.tsx | 15 +- shared/chat/emoji-picker/index.tsx | 4 +- shared/chat/inbox-and-conversation-2.tsx | 18 +- shared/chat/inbox-and-conversation-header.tsx | 44 +- shared/chat/inbox/container.tsx | 103 +- shared/chat/inbox/defer-loading.tsx | 21 +- shared/chat/inbox/filter-row.tsx | 16 +- shared/chat/inbox/index.desktop.tsx | 28 +- shared/chat/inbox/index.native.tsx | 28 +- shared/chat/inbox/row/big-team-channel.tsx | 175 +- shared/chat/inbox/row/index.tsx | 6 +- shared/chat/inbox/row/small-team/index.tsx | 102 +- .../small-team/swipe-conv-actions/index.d.ts | 4 +- .../swipe-conv-actions/index.desktop.tsx | 6 +- .../swipe-conv-actions/index.native.tsx | 137 +- shared/chat/inbox/row/teams-divider.tsx | 24 +- shared/chat/routes.tsx | 2 +- shared/common-adapters/animation.native.tsx | 22 +- shared/common-adapters/avatar.tsx | 5 +- .../background-repeat-box/index.desktop.tsx | 3 +- shared/common-adapters/badge.tsx | 12 +- shared/common-adapters/box.native.tsx | 18 +- .../common-adapters/drag-and-drop.desktop.tsx | 7 +- shared/common-adapters/dropdown.tsx | 194 +- .../common-adapters/floating-box/index.d.ts | 1 + .../floating-box/index.desktop.tsx | 95 +- .../relative-floating-box.desktop.tsx | 310 +- .../common-adapters/floating-menu/index.tsx | 18 +- shared/common-adapters/header-hoc/index.d.ts | 7 +- .../header-hoc/index.desktop.tsx | 13 +- .../header-hoc/index.native.tsx | 260 +- shared/common-adapters/icon.d.ts | 2 +- shared/common-adapters/icon.desktop.tsx | 22 +- shared/common-adapters/icon.shared.tsx | 8 +- shared/common-adapters/index-impl.d.ts | 2 +- shared/common-adapters/index-impl.js | 3 + shared/common-adapters/index.d.ts | 1 + shared/common-adapters/input2.d.ts | 56 + shared/common-adapters/input2.desktop.tsx | 240 + shared/common-adapters/input2.native.tsx | 125 + shared/common-adapters/list2.d.ts | 2 +- shared/common-adapters/loading-line.d.ts | 3 +- shared/common-adapters/markdown/index.tsx | 48 +- shared/common-adapters/markdown/react.tsx | 112 +- shared/common-adapters/markdown/spoiler.tsx | 12 +- shared/common-adapters/plain-input.d.ts | 2 +- shared/common-adapters/plain-input.native.tsx | 9 +- .../common-adapters/popup-dialog.desktop.tsx | 1 + shared/common-adapters/profile-card.tsx | 144 +- shared/common-adapters/qr-scanner.native.tsx | 39 +- shared/common-adapters/reanimated.tsx | 4 +- shared/common-adapters/reload.tsx | 147 +- shared/common-adapters/safe-react-list.tsx | 2 +- shared/common-adapters/scroll-view.d.ts | 2 +- shared/common-adapters/section-list.d.ts | 4 +- .../common-adapters/section-list.desktop.tsx | 50 +- .../common-adapters/section-list.native.tsx | 25 +- shared/common-adapters/swipeable.native.tsx | 366 - shared/common-adapters/switch.tsx | 68 +- shared/common-adapters/text.css | 2 + shared/common-adapters/toast.desktop.tsx | 4 + shared/common-adapters/toast.native.tsx | 30 +- shared/common-adapters/use-popup.tsx | 12 +- shared/common-adapters/use-timers.tsx | 5 +- shared/common-adapters/usernames.tsx | 6 +- shared/common-adapters/video.desktop.tsx | 47 +- shared/common-adapters/wave-button.tsx | 4 +- .../common-adapters/zoomable-box.android.tsx | 11 +- shared/common-adapters/zoomable-box.ios.tsx | 69 +- shared/constants/active.tsx | 2 +- shared/constants/archive.tsx | 2 +- shared/constants/autoreset.tsx | 2 +- shared/constants/bots.tsx | 2 +- shared/constants/chat2/convostate.tsx | 459 +- shared/constants/chat2/debug.tsx | 2 +- shared/constants/chat2/index.tsx | 110 +- shared/constants/chat2/message.tsx | 15 +- shared/constants/config.tsx | 13 +- shared/constants/crypto.tsx | 4 +- shared/constants/current-user.tsx | 2 +- shared/constants/daemon.tsx | 5 +- shared/constants/darkmode.tsx | 2 +- shared/constants/deeplinks.tsx | 26 +- shared/constants/devices.tsx | 10 +- shared/constants/engine.tsx | 4 +- shared/constants/followers.tsx | 2 +- shared/constants/{fs.tsx => fs/index.tsx} | 24 +- shared/constants/git.tsx | 2 +- shared/constants/immer.tsx | 2 +- shared/constants/index.tsx | 99 +- shared/constants/logout.tsx | 2 +- shared/constants/notifications.tsx | 4 +- shared/constants/people.tsx | 4 +- shared/constants/pinentry.tsx | 2 +- .../platform-specific/index.native.tsx | 1 + .../platform-specific/kbfs-notifications.tsx | 33 +- .../platform-specific/push.native.tsx | 4 +- shared/constants/profile.tsx | 2 +- shared/constants/provision.tsx | 14 +- shared/constants/push.d.ts | 2 +- shared/constants/push.desktop.tsx | 2 +- shared/constants/push.native.tsx | 2 +- shared/constants/react.tsx | 36 +- shared/constants/recover-password.tsx | 2 +- shared/constants/router2.tsx | 11 +- shared/constants/settings-chat.tsx | 2 +- shared/constants/settings-contacts.d.ts | 2 +- .../constants/settings-contacts.desktop.tsx | 2 +- shared/constants/settings-contacts.native.tsx | 2 +- shared/constants/settings-email.tsx | 2 +- shared/constants/settings-invites.tsx | 30 +- shared/constants/settings-notifications.tsx | 2 +- shared/constants/settings-password.tsx | 2 +- shared/constants/settings-phone.tsx | 2 +- shared/constants/settings.tsx | 2 +- shared/constants/signup.tsx | 2 +- shared/constants/team-building.tsx | 12 +- shared/constants/teams.tsx | 10 +- shared/constants/tracker2.tsx | 2 +- shared/constants/types/chat2/index.tsx | 4 +- shared/constants/types/index.tsx | 18 +- shared/constants/types/more.tsx | 3 +- shared/constants/types/users.tsx | 2 +- shared/constants/unlock-folders.tsx | 2 +- shared/constants/users.tsx | 2 +- shared/constants/waiting.tsx | 8 +- shared/constants/wallets.tsx | 2 +- shared/constants/whats-new.tsx | 10 +- shared/crypto/sub-nav/index.desktop.tsx | 27 +- shared/crypto/sub-nav/index.native.tsx | 2 +- shared/desktop/app/installer.desktop.tsx | 3 + shared/desktop/app/menu-bar.desktop.tsx | 1 + shared/desktop/app/menu-helper.desktop.tsx | 8 +- shared/desktop/app/node2.desktop.tsx | 7 +- shared/desktop/electron-sums.tsx | 12 +- shared/desktop/package.desktop.tsx | 2 +- .../remote/component-loader.desktop.tsx | 38 +- .../remote/use-serialize-props.desktop.tsx | 2 +- shared/desktop/renderer/main.desktop.tsx | 2 +- shared/desktop/renderer/main2.desktop.tsx | 23 +- shared/desktop/renderer/preload.desktop.tsx | 39 +- shared/desktop/webpack.config.babel.js | 22 +- .../yarn-helper/action-creator-creator.tsx | 17 +- shared/desktop/yarn-helper/build.tsx | 2 +- shared/desktop/yarn-helper/electron.tsx | 9 +- shared/desktop/yarn-helper/font.tsx | 2 +- shared/desktop/yarn-helper/index.tsx | 12 +- shared/desktop/yarn-helper/log-to-trace.tsx | 4 +- shared/devices/add-device.tsx | 18 +- shared/devices/index.tsx | 10 +- shared/devices/paper-key.tsx | 2 +- shared/engine/index-impl.tsx | 6 +- shared/engine/local-console.tsx | 2 +- shared/engine/request.tsx | 4 +- shared/engine/session-impl.tsx | 2 +- shared/engine/stats.tsx | 2 +- shared/engine/transport-shared.tsx | 6 +- shared/eslint.config.mjs | 395 + shared/fs/common/hooks.tsx | 2 +- shared/fs/common/pie-slice.tsx | 4 +- shared/fs/top-bar/sync-toggle.tsx | 10 +- shared/git/new-repo.tsx | 91 +- shared/globals.d.ts | 2 +- shared/ignored-modules.js | 1 + shared/incoming-share/index.tsx | 2 +- shared/index.android.js | 6 +- shared/index.ios.js | 51 +- shared/ios/Keybase.xcodeproj/project.pbxproj | 90 +- .../xcschemes/KeybaseShare.xcscheme | 1 - shared/ios/Keybase/AppDelegate.mm | 11 +- shared/ios/Keybase/Info.plist | 13 +- shared/ios/Keybase/MediaUtils.m | 2 +- shared/ios/Podfile | 48 +- shared/ios/Podfile.lock | 2289 ++++- shared/ios/PrivacyInfo.xcprivacy | 48 + shared/local-debug.native.tsx | 2 +- shared/logger/ring-logger.tsx | 2 +- shared/menubar/chat-container.desktop.tsx | 4 + shared/menubar/index.desktop.tsx | 16 +- shared/menubar/remote-proxy.desktop.tsx | 69 +- shared/metro.config.js | 54 +- shared/null-module.js | 2 + shared/override-d.ts/misc/index.d.ts | 19 +- shared/package.json | 190 +- .../patches/@gorhom+bottom-sheet+4.5.1.patch | 13 - ...@khanacademy+simple-markdown+0.13.3.patch} | 72 +- ...> @react-native-picker+picker+2.8.1.patch} | 4 +- ...react-navigation+native-stack+6.9.17.patch | 55 - ...e-software+why-did-you-render+8.0.3.patch} | 4 +- shared/patches/expo-camera+15.0.16.patch | 12 + shared/patches/expo-constants+16.0.2.patch | 13 + ...0.patch => expo-image-picker+15.0.7.patch} | 6 +- ...estsmallesttextencoderdecoder+1.0.22.patch | 468 + shared/patches/immer+10.0.3.patch | 13 - ...enubar+9.4.0.patch => menubar+9.5.1.patch} | 4 +- shared/patches/qrcode-generator+1.4.4.patch | 29 + shared/patches/react-list+0.8.17.patch | 12 + shared/patches/react-native+0.72.7.patch | 72 - shared/patches/react-native+0.75.2.patch | 41 + ...react-native-hw-keyboard-event+0.0.4.patch | 10 + .../react-native-reanimated+3.6.1.patch | 12 - ...react-native-safe-area-context+4.8.2.patch | 9 - .../patches/react-native-screens+3.34.0.patch | 41 + shared/people/container.tsx | 6 +- shared/pinentry/main.desktop.tsx | 2 +- shared/profile/edit-avatar/index.desktop.tsx | 25 +- shared/profile/generic/shared.tsx | 4 +- shared/profile/pgp/choice/index.d.ts | 3 +- shared/profile/pgp/finished/index.d.ts | 3 +- shared/profile/pgp/generate/index.d.ts | 3 +- shared/profile/pgp/import/index.d.ts | 3 +- shared/profile/pgp/info/index.d.ts | 3 +- shared/profile/user/actions/index.tsx | 2 +- shared/profile/user/measure/index.desktop.tsx | 5 +- shared/profile/user/page.tsx | 14 +- shared/provision/code-page/index.tsx | 149 +- shared/provision/code-page/qr-image.tsx | 3 +- shared/react-native.config.js | 6 +- shared/react-native/gobuild.sh | 85 +- shared/rn-transformer.js | 2 +- shared/router-v2/common.d.ts | 2 +- shared/router-v2/common.desktop.tsx | 28 +- shared/router-v2/common.native.tsx | 18 +- shared/router-v2/header/index.desktop.tsx | 42 +- .../router-v2/left-tab-navigator.desktop.tsx | 25 +- shared/router-v2/router-linking.native.tsx | 132 +- shared/router-v2/router.d.ts | 3 +- shared/router-v2/router.desktop.tsx | 15 +- shared/router-v2/router.native.tsx | 162 +- shared/router-v2/router.shared.tsx | 16 +- shared/router-v2/shim.desktop.tsx | 10 + shared/router-v2/tab-bar.css | 10 - shared/router-v2/tab-bar.desktop.tsx | 2 +- shared/settings/advanced.tsx | 158 +- shared/settings/archive/modal.tsx | 20 +- .../delete-confirm/check-passphrase.d.ts | 3 +- shared/settings/invites/index.desktop.tsx | 6 +- shared/settings/root-desktop-tablet.tsx | 19 +- shared/settings/root-phone.tsx | 2 +- shared/settings/screenprotector.d.ts | 5 +- shared/settings/screenprotector.desktop.tsx | 26 +- shared/settings/sub-nav/left-nav.tsx | 2 +- shared/signup/common.tsx | 4 +- shared/signup/device-name.tsx | 24 +- shared/styles/colors.tsx | 8 +- shared/styles/css.d.ts | 15 +- shared/styles/dark-mode.tsx | 2 +- shared/styles/index.d.ts | 8 +- shared/styles/index.desktop.tsx | 6 +- shared/styles/index.native.tsx | 4 +- shared/styles/shared.tsx | 2 +- shared/styles/style-sheet-proxy.tsx | 2 +- shared/team-building/index.tsx | 4 +- .../team-building/service-tab-bar.desktop.tsx | 2 +- .../add-members-wizard/add-contacts.d.ts | 3 +- shared/teams/channel/index.tsx | 94 +- shared/teams/channel/rows/member-row.tsx | 64 +- shared/teams/common/index.tsx | 34 +- shared/teams/common/selection-popup.tsx | 5 +- .../really-leave-team/index.tsx | 91 +- shared/teams/emojis/add-emoji.tsx | 8 +- .../teams/new-team/wizard/create-channels.tsx | 65 +- .../teams/new-team/wizard/create-subteams.tsx | 13 +- shared/teams/page.tsx | 2 +- shared/teams/team/rows/index.tsx | 17 +- .../test/setupTestFrameworkScriptFile-rn.js | 1 - shared/test/setupTestFrameworkScriptFile.js | 1 - shared/todo.txt | 21 +- shared/tracker2/assertion/container.tsx | 20 +- shared/tracker2/index.desktop.tsx | 14 +- shared/tsconfig.json | 1 + shared/unlock-folders/main.desktop.tsx | 2 +- .../remote-container.desktop.tsx | 21 +- shared/util/clipboard.desktop.tsx | 1 + shared/util/container.tsx | 14 +- shared/util/electron.d.ts | 1 + shared/util/electron.desktop.tsx | 1 + shared/util/emoji.tsx | 5 +- shared/util/notify-popup.desktop.tsx | 12 +- shared/util/safe-submit.tsx | 6 +- shared/util/shared-timers.tsx | 10 +- shared/util/use-safe-callback.tsx | 41 - shared/util/why-did-you-render.tsx | 1 + shared/util/zustand.tsx | 5 +- shared/whats-new/container.tsx | 7 +- shared/whats-new/icon/index.tsx | 131 +- shared/whats-new/icon/popup.desktop.tsx | 2 +- shared/whats-new/index.tsx | 69 +- shared/yarn.lock | 8252 +++++++++-------- 467 files changed, 18866 insertions(+), 16264 deletions(-) delete mode 100644 rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewView.java create mode 100644 rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewView.kt delete mode 100644 rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewManager.java create mode 100644 rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewManager.kt delete mode 100644 rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewPackage.java create mode 100644 rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewPackage.kt delete mode 100644 rnmodules/react-native-drop-view/android/src/newarch/DropViewViewManagerSpec.java create mode 100644 rnmodules/react-native-drop-view/android/src/newarch/DropViewViewManagerSpec.kt delete mode 100644 rnmodules/react-native-drop-view/android/src/oldarch/DropViewViewManagerSpec.java create mode 100644 rnmodules/react-native-drop-view/android/src/oldarch/DropViewViewManagerSpec.kt delete mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePrefHelper.java create mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePrefHelper.kt delete mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePreference.java create mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePreference.kt delete mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/GuiConfig.java create mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/GuiConfig.kt delete mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbModule.java create mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbModule.kt delete mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbPackage.java create mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbPackage.kt delete mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/NativeLogger.java create mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/NativeLogger.kt delete mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/PathResolver.java create mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/PathResolver.kt delete mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/ReadFileAsString.java create mode 100644 rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/ReadFileAsString.kt delete mode 100644 rnmodules/react-native-kb/android/src/newarch/KbSpec.java create mode 100644 rnmodules/react-native-kb/android/src/newarch/KbSpec.kt delete mode 100644 rnmodules/react-native-kb/android/src/oldarch/KbSpec.java create mode 100644 rnmodules/react-native-kb/android/src/oldarch/KbSpec.kt create mode 100644 rnmodules/react-native-kb/ios/KBJSScheduler.cpp create mode 100644 rnmodules/react-native-kb/ios/KBJSScheduler.h delete mode 100644 shared/.eslintignore delete mode 100644 shared/.eslintrc.js delete mode 100644 shared/android/app/src/androidTest/java/io/keybase/ossifrage/MainActivityTest.java delete mode 100644 shared/android/app/src/debug/java/io/keybase/ossifrage/ReactNativeFlipper.java delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/ChatBroadcastReceiver.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/ChatBroadcastReceiver.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/CustomBitmapMemoryCacheParamsSupplier.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/CustomBitmapMemoryCacheParamsSupplier.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/KBInstallReferrerListener.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/KBInstallReferrerListener.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/KBPushNotifier.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/KBPushNotifier.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/KBReactPackage.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/KBReactPackage.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/KeyStore.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/KeyStore.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/KeybasePushNotificationListenerService.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/KeybasePushNotificationListenerService.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/MainActivity.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/MainActivity.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/MainApplication.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/MainApplication.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/keystore/KeyStoreHelper.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/keystore/KeyStoreHelper.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/modules/BackgroundSyncWorker.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/modules/BackgroundSyncWorker.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/modules/KillableModule.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/modules/KillableModule.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/modules/NativeLogger.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/modules/NativeLogger.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/modules/StorybookConstants.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/modules/StorybookConstants.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/util/DNSNSFetcher.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/util/DNSNSFetcher.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/util/DeviceLockType.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/util/DeviceLockType.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/util/SharedFileProvider.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/util/SharedFileProvider.kt delete mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/util/VideoHelper.java create mode 100644 shared/android/app/src/main/java/io/keybase/ossifrage/util/VideoHelper.kt delete mode 100644 shared/android/app/src/release/java/io/keybase/ossifrage/ReactNativeFlipper.java delete mode 100644 shared/android/app/src/releaseUnsigned/java/io/keybase/ossifrage/ReactNativeFlipper.java rename shared/chat/conversation/input-area/{normal/location-popup.tsx => location-popup/index.tsx} (97%) rename shared/chat/conversation/input-area/{normal/location-popup.page.tsx => location-popup/page.tsx} (85%) delete mode 100644 shared/chat/conversation/input-area/normal/index.tsx create mode 100644 shared/chat/conversation/input-area/normal2/index.tsx rename shared/chat/conversation/input-area/{normal => normal2}/max-input-area-context.tsx (100%) rename shared/chat/conversation/input-area/{normal => normal2}/moremenu-popup.tsx (100%) rename shared/chat/conversation/input-area/{normal => normal2}/platform-input.d.ts (80%) rename shared/chat/conversation/input-area/{normal => normal2}/platform-input.desktop.tsx (87%) rename shared/chat/conversation/input-area/{normal => normal2}/platform-input.native.tsx (86%) rename shared/chat/conversation/{messages => input-area/normal2}/set-explode-popup/container.tsx (86%) rename shared/chat/conversation/{messages => input-area/normal2}/set-explode-popup/index.d.ts (100%) rename shared/chat/conversation/{messages => input-area/normal2}/set-explode-popup/index.desktop.tsx (100%) rename shared/chat/conversation/{messages => input-area/normal2}/set-explode-popup/index.native.tsx (100%) rename shared/chat/conversation/input-area/{normal/typing/index.tsx => normal2/typing.tsx} (89%) rename shared/chat/conversation/input-area/{normal => suggestors}/shared.tsx (100%) create mode 100644 shared/chat/conversation/list-area/use-intersection-observer.tsx create mode 100644 shared/chat/conversation/list-area/use-resize-observer.tsx delete mode 100644 shared/chat/conversation/messages/account-payment/pending-background/index.d.ts delete mode 100644 shared/chat/conversation/messages/account-payment/pending-background/index.desktop.tsx delete mode 100644 shared/chat/conversation/messages/account-payment/pending-background/index.native.tsx delete mode 100644 shared/chat/conversation/messages/account-payment/pending-background/pending-background.css create mode 100644 shared/common-adapters/input2.d.ts create mode 100644 shared/common-adapters/input2.desktop.tsx create mode 100644 shared/common-adapters/input2.native.tsx delete mode 100644 shared/common-adapters/swipeable.native.tsx rename shared/constants/{fs.tsx => fs/index.tsx} (99%) create mode 100644 shared/eslint.config.mjs create mode 100644 shared/ignored-modules.js create mode 100644 shared/ios/PrivacyInfo.xcprivacy create mode 100644 shared/null-module.js delete mode 100644 shared/patches/@gorhom+bottom-sheet+4.5.1.patch rename shared/patches/{@khanacademy+simple-markdown+0.11.2.patch => @khanacademy+simple-markdown+0.13.3.patch} (56%) rename shared/patches/{@react-native-picker+picker+2.6.1.patch => @react-native-picker+picker+2.8.1.patch} (84%) delete mode 100644 shared/patches/@react-navigation+native-stack+6.9.17.patch rename shared/patches/{@welldone-software+why-did-you-render+8.0.1.patch => @welldone-software+why-did-you-render+8.0.3.patch} (96%) create mode 100644 shared/patches/expo-camera+15.0.16.patch create mode 100644 shared/patches/expo-constants+16.0.2.patch rename shared/patches/{expo-image-picker+14.5.0.patch => expo-image-picker+15.0.7.patch} (79%) create mode 100644 shared/patches/fastestsmallesttextencoderdecoder+1.0.22.patch delete mode 100644 shared/patches/immer+10.0.3.patch rename shared/patches/{menubar+9.4.0.patch => menubar+9.5.1.patch} (90%) create mode 100644 shared/patches/qrcode-generator+1.4.4.patch create mode 100644 shared/patches/react-list+0.8.17.patch delete mode 100644 shared/patches/react-native+0.72.7.patch create mode 100644 shared/patches/react-native+0.75.2.patch delete mode 100644 shared/patches/react-native-reanimated+3.6.1.patch delete mode 100644 shared/patches/react-native-safe-area-context+4.8.2.patch create mode 100644 shared/patches/react-native-screens+3.34.0.patch delete mode 100644 shared/util/use-safe-callback.tsx diff --git a/rnmodules/react-native-drop-view/android/build.gradle b/rnmodules/react-native-drop-view/android/build.gradle index 416e517f83cc..cc52a86bc569 100644 --- a/rnmodules/react-native-drop-view/android/build.gradle +++ b/rnmodules/react-native-drop-view/android/build.gradle @@ -1,4 +1,7 @@ buildscript { + // Buildscript is evaluated before everything else so we can't use getExtOrDefault + def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["DropView_kotlinVersion"] + repositories { google() mavenCentral() @@ -6,6 +9,8 @@ buildscript { dependencies { classpath "com.android.tools.build:gradle:7.2.1" + // noinspection DifferentKotlinGradleVersion + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -14,29 +19,7 @@ def isNewArchitectureEnabled() { } apply plugin: "com.android.library" - -import groovy.json.JsonSlurper - -// https://github.com/callstack/react-native-builder-bob/discussions/359 -def registrationCompat = { - def reactNativeManifest = file("$projectDir/../node_modules/react-native/package.json").exists() - ? file("$projectDir/../node_modules/react-native/package.json") // developer mode, to run example app - : file("$projectDir/../../react-native/package.json") - def reactNativeVersion = new JsonSlurper().parseText(reactNativeManifest.text).version as String - // Fabric was introduced at react-native@0.68, full CMake support were introduced at react-native@0.71 - // Use Android.mk for compatibility with react-native@0.68/0.69 - reactNativeVersion.matches('(0.68.*|0.69.*)') -}() - -def codegenViewLibraryName = "DropViewView" -def codegenViewModuleName = { - // Autolink for Fabric uses codegenConfig.name in package.json since react-native@0.70 - // Use codegenViewLibraryName for compatibility with react-native@0.68/0.69 - def libraryManifestJson = new JsonSlurper().parseText(file("$projectDir/../package.json").text) - registrationCompat ? codegenViewLibraryName : libraryManifestJson.codegenConfig.name -}() - -def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') } +apply plugin: "kotlin-android" if (isNewArchitectureEnabled()) { apply plugin: "com.facebook.react" @@ -50,42 +33,39 @@ def getExtOrIntegerDefault(name) { return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["DropView_" + name]).toInteger() } +def supportsNamespace() { + def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.') + def major = parsed[0].toInteger() + def minor = parsed[1].toInteger() + + // Namespace support was added in 7.3.0 + return (major == 7 && minor >= 3) || major >= 8 +} + android { - ndkVersion getExtOrDefault("ndkVersion") + if (supportsNamespace()) { + namespace "io.keybase.dropview" + + sourceSets { + main { + manifest.srcFile "src/main/AndroidManifestNew.xml" + } + } + } + compileSdkVersion getExtOrIntegerDefault("compileSdkVersion") defaultConfig { minSdkVersion getExtOrIntegerDefault("minSdkVersion") targetSdkVersion getExtOrIntegerDefault("targetSdkVersion") buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() - buildConfigField "String", "CODEGEN_MODULE_REGISTRATION", (isNewArchitectureEnabled() && registrationCompat ? "\"${codegenViewModuleName}_registration\"" : "null") - if (isNewArchitectureEnabled() && registrationCompat) { - def reactAndroidProject = project(':ReactAndroid') - externalNativeBuild { - ndkBuild { - arguments "APP_PLATFORM=android-21", - "APP_STL=c++_shared", - "NDK_TOOLCHAIN_VERSION=clang", - "GENERATED_SRC_DIR=$buildDir/generated/source", // for react_codegen_* in this library's codegen/jni - "PROJECT_BUILD_DIR=${appProject.buildDir}", // for REACT_NDK_EXPORT_DIR in ReactAndroid's Android-prebuilt.mk - "REACT_ANDROID_DIR=${reactAndroidProject.projectDir}", - "REACT_ANDROID_BUILD_DIR=${reactAndroidProject.buildDir}", - "CODEGEN_MODULE_NAME=$codegenViewModuleName" - cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1" - cppFlags "-std=c++17" - targets "${codegenViewModuleName}_registration" - } - } - } + } - if (isNewArchitectureEnabled() && registrationCompat) { - // We configure the NDK build only if you decide to opt-in for the New Architecture. - externalNativeBuild { - ndkBuild { - path "Android.mk" - } - } + + buildFeatures { + buildConfig true } + buildTypes { release { minifyEnabled false @@ -121,19 +101,20 @@ repositories { google() } +def kotlin_version = getExtOrDefault("kotlinVersion") dependencies { // For < 0.71, this will be from the local maven repo // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:+" + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" } if (isNewArchitectureEnabled()) { react { jsRootDir = file("../src/") - - libraryName = codegenViewLibraryName - codegenJavaPackageName = "com.dropview" + libraryName = "DropViewView" + codegenJavaPackageName = "io.keybase.dropview" } } diff --git a/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewView.java b/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewView.java deleted file mode 100644 index 97cb7554038c..000000000000 --- a/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewView.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.reactnativedropview; - -import androidx.annotation.Nullable; -import android.widget.FrameLayout; -import androidx.annotation.NonNull; -import android.content.Context; -import android.util.AttributeSet; -import com.facebook.react.uimanager.ViewGroupManager; -import com.facebook.react.uimanager.ThemedReactContext; -import android.view.View; - -public class DropViewView extends FrameLayout { - public DropViewView(Context context) { - super(context); - } - - public DropViewView(Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - } - - public DropViewView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - -} diff --git a/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewView.kt b/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewView.kt new file mode 100644 index 000000000000..43f3dc5c1eea --- /dev/null +++ b/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewView.kt @@ -0,0 +1,12 @@ +package com.reactnativedropview + +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import androidx.annotation.Nullable + +class DropViewView @JvmOverloads constructor( + context: Context, + @Nullable attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : FrameLayout(context, attrs, defStyleAttr) diff --git a/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewManager.java b/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewManager.java deleted file mode 100644 index d9774e5c1710..000000000000 --- a/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewManager.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.reactnativedropview; - -import android.graphics.Color; - -import androidx.annotation.Nullable; - -import com.facebook.react.module.annotations.ReactModule; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.annotations.ReactProp; - -@ReactModule(name = DropViewViewManager.NAME) -public class DropViewViewManager extends DropViewViewManagerSpec { - - public static final String NAME = "DropViewView"; - - @Override - public String getName() { - return NAME; - } - - @Override - public DropViewView createViewInstance(ThemedReactContext context) { - return new DropViewView(context); - } -} diff --git a/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewManager.kt b/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewManager.kt new file mode 100644 index 000000000000..e5d3c7375281 --- /dev/null +++ b/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewManager.kt @@ -0,0 +1,23 @@ +package com.reactnativedropview + +import com.facebook.react.module.annotations.ReactModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.uimanager.ThemedReactContext +import com.facebook.react.uimanager.annotations.ReactProp + +@ReactModule(name = DropViewViewManager.NAME) +class DropViewViewManager : + DropViewViewManagerSpec() { + override fun getName(): String { + return NAME + } + + public override fun createViewInstance(context: ThemedReactContext): DropViewView { + return DropViewView(context) + } + + companion object { + const val NAME = "DropViewView" + } +} + diff --git a/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewPackage.java b/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewPackage.java deleted file mode 100644 index addf0cee9f1c..000000000000 --- a/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewPackage.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.reactnativedropview; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class DropViewViewPackage implements ReactPackage { - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - List viewManagers = new ArrayList<>(); - viewManagers.add(new DropViewViewManager()); - return viewManagers; - } - - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewPackage.kt b/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewPackage.kt new file mode 100644 index 000000000000..a16bff84a680 --- /dev/null +++ b/rnmodules/react-native-drop-view/android/src/main/java/com/reactnativedropview/DropViewViewPackage.kt @@ -0,0 +1,20 @@ +package com.reactnativedropview + +import com.facebook.react.ReactPackage +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.uimanager.ViewManager +import java.util.ArrayList + +class DropViewViewPackage : ReactPackage { + override fun createViewManagers(reactContext: ReactApplicationContext): List> { + val viewManagers: MutableList> = ArrayList() + viewManagers.add(DropViewViewManager()) + return viewManagers + } + + override fun createNativeModules(reactContext: ReactApplicationContext): List { + return emptyList() + } +} + diff --git a/rnmodules/react-native-drop-view/android/src/newarch/DropViewViewManagerSpec.java b/rnmodules/react-native-drop-view/android/src/newarch/DropViewViewManagerSpec.java deleted file mode 100644 index 268be73c66a6..000000000000 --- a/rnmodules/react-native-drop-view/android/src/newarch/DropViewViewManagerSpec.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.reactnativedropview; - -import android.view.View; - -import androidx.annotation.Nullable; -import android.widget.FrameLayout; -import com.facebook.react.uimanager.ViewManagerDelegate; -import com.facebook.react.viewmanagers.DropViewViewManagerDelegate; -import com.facebook.react.viewmanagers.DropViewViewManagerInterface; -import com.facebook.react.uimanager.ViewGroupManager; -import com.facebook.soloader.SoLoader; - -public abstract class DropViewViewManagerSpec extends ViewGroupManager implements DropViewViewManagerInterface { - static { - if (BuildConfig.CODEGEN_MODULE_REGISTRATION != null) { - SoLoader.loadLibrary(BuildConfig.CODEGEN_MODULE_REGISTRATION); - } - } - - private final ViewManagerDelegate mDelegate; - - public DropViewViewManagerSpec() { - mDelegate = new DropViewViewManagerDelegate(this); - } - - @Nullable - @Override - protected ViewManagerDelegate getDelegate() { - return mDelegate; - } -} diff --git a/rnmodules/react-native-drop-view/android/src/newarch/DropViewViewManagerSpec.kt b/rnmodules/react-native-drop-view/android/src/newarch/DropViewViewManagerSpec.kt new file mode 100644 index 000000000000..5039d99cba81 --- /dev/null +++ b/rnmodules/react-native-drop-view/android/src/newarch/DropViewViewManagerSpec.kt @@ -0,0 +1,22 @@ +package com.reactnativedropview + +import android.view.View +import android.widget.FrameLayout +import com.facebook.react.uimanager.ViewManagerDelegate +import com.facebook.react.viewmanagers.DropViewViewManagerDelegate +import com.facebook.react.viewmanagers.DropViewViewManagerInterface +import com.facebook.react.uimanager.ViewGroupManager +import com.facebook.soloader.SoLoader + +abstract class DropViewViewManagerSpec : ViewGroupManager(), DropViewViewManagerInterface { + private val mDelegate: ViewManagerDelegate + + init { + mDelegate = DropViewViewManagerDelegate(this) + } + + override fun getDelegate(): ViewManagerDelegate? { + return mDelegate + } + +} diff --git a/rnmodules/react-native-drop-view/android/src/oldarch/DropViewViewManagerSpec.java b/rnmodules/react-native-drop-view/android/src/oldarch/DropViewViewManagerSpec.java deleted file mode 100644 index 3cfcca1077a2..000000000000 --- a/rnmodules/react-native-drop-view/android/src/oldarch/DropViewViewManagerSpec.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.reactnativedropview; - -import android.view.View; -import com.facebook.react.uimanager.ViewGroupManager; -import android.widget.FrameLayout; - -public abstract class DropViewViewManagerSpec extends ViewGroupManager { -} - diff --git a/rnmodules/react-native-drop-view/android/src/oldarch/DropViewViewManagerSpec.kt b/rnmodules/react-native-drop-view/android/src/oldarch/DropViewViewManagerSpec.kt new file mode 100644 index 000000000000..e73d12078dd0 --- /dev/null +++ b/rnmodules/react-native-drop-view/android/src/oldarch/DropViewViewManagerSpec.kt @@ -0,0 +1,7 @@ +package com.reactnativedropview + +import android.view.View +import com.facebook.react.uimanager.ViewGroupManager +import android.widget.FrameLayout + +abstract class DropViewViewManagerSpec : ViewGroupManager() diff --git a/rnmodules/react-native-drop-view/ios/DropViewView.mm b/rnmodules/react-native-drop-view/ios/DropViewView.mm index f9c346ce4c11..952030b3a127 100644 --- a/rnmodules/react-native-drop-view/ios/DropViewView.mm +++ b/rnmodules/react-native-drop-view/ios/DropViewView.mm @@ -23,18 +23,14 @@ + (ComponentDescriptorProvider)componentDescriptorProvider return concreteComponentDescriptorProvider(); } -- (instancetype)initWithFrame:(CGRect)frame +- (instancetype)init { - if (self = [super initWithFrame:frame]) { + if (self = [super init]) { +#ifdef RCT_NEW_ARCH_ENABLED static const auto defaultProps = std::make_shared(); _props = defaultProps; - - DropView *dv = [[DropView alloc] init]; - _view = dv; - - self.contentView = _view; +#endif } - return self; } @@ -48,5 +44,20 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const & return DropViewView.class; } +- (void)layoutSubviews +{ + [super layoutSubviews]; +} + +- (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index +{ + [super mountChildComponentView:childComponentView index:index]; +} + +- (UIView *)view +{ + return [[DropView alloc] init]; +} + @end #endif diff --git a/rnmodules/react-native-drop-view/yarn.lock b/rnmodules/react-native-drop-view/yarn.lock index 97bf2c2f7f1d..519493bfad66 100644 --- a/rnmodules/react-native-drop-view/yarn.lock +++ b/rnmodules/react-native-drop-view/yarn.lock @@ -18,11 +18,32 @@ "@babel/highlight" "^7.22.10" chalk "^2.4.2" -"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": +"@babel/code-frame@^7.23.5": + version "7.24.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" + integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== + dependencies: + "@babel/highlight" "^7.24.2" + picocolors "^1.0.0" + +"@babel/code-frame@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== + dependencies: + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" + +"@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== +"@babel/compat-data@^7.25.2": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.4.tgz#7d2a80ce229890edcf4cc259d4d696cb4dae2fcb" + integrity sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ== + "@babel/core@^7.13.16", "@babel/core@^7.18.5", "@babel/core@^7.20.0": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.10.tgz#aad442c7bcd1582252cb4576747ace35bc122f35" @@ -54,6 +75,16 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" +"@babel/generator@^7.25.4": + version "7.25.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.5.tgz#b31cf05b3fe8c32d206b6dad03bb0aacbde73450" + integrity sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w== + dependencies: + "@babel/types" "^7.25.4" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" @@ -61,6 +92,13 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-annotate-as-pure@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" + integrity sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg== + dependencies: + "@babel/types" "^7.24.7" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.10.tgz#573e735937e99ea75ea30788b57eb52fab7468c9" @@ -68,7 +106,7 @@ dependencies: "@babel/types" "^7.22.10" -"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.10", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": +"@babel/helper-compilation-targets@^7.22.10", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz#01d648bbc25dd88f513d862ee0df27b7d4e67024" integrity sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q== @@ -79,6 +117,17 @@ lru-cache "^5.1.1" semver "^6.3.1" +"@babel/helper-compilation-targets@^7.24.7": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz#e1d9410a90974a3a5a66e84ff55ef62e3c02d06c" + integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw== + dependencies: + "@babel/compat-data" "^7.25.2" + "@babel/helper-validator-option" "^7.24.8" + browserslist "^4.23.1" + lru-cache "^5.1.1" + semver "^6.3.1" + "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.10", "@babel/helper-create-class-features-plugin@^7.22.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.10.tgz#dd2612d59eac45588021ac3d6fa976d08f4e95a3" @@ -94,6 +143,34 @@ "@babel/helper-split-export-declaration" "^7.22.6" semver "^6.3.1" +"@babel/helper-create-class-features-plugin@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz#7d19da92c7e0cd8d11c09af2ce1b8e7512a6e723" + integrity sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.24.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.24.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.24.5" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.25.4": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz#57eaf1af38be4224a9d9dd01ddde05b741f50e14" + integrity sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-member-expression-to-functions" "^7.24.8" + "@babel/helper-optimise-call-expression" "^7.24.7" + "@babel/helper-replace-supers" "^7.25.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/traverse" "^7.25.4" + semver "^6.3.1" + "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" @@ -114,7 +191,12 @@ lodash.debounce "^4.0.8" resolve "^1.14.2" -"@babel/helper-environment-visitor@^7.18.9", "@babel/helper-environment-visitor@^7.22.5": +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-environment-visitor@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== @@ -127,6 +209,14 @@ "@babel/template" "^7.22.5" "@babel/types" "^7.22.5" +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + "@babel/helper-hoist-variables@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" @@ -141,6 +231,21 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-member-expression-to-functions@^7.23.0", "@babel/helper-member-expression-to-functions@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz#5981e131d5c7003c7d1fa1ad49e86c9b097ec475" + integrity sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA== + dependencies: + "@babel/types" "^7.24.5" + +"@babel/helper-member-expression-to-functions@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz#6155e079c913357d24a4c20480db7c712a5c3fb6" + integrity sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA== + dependencies: + "@babel/traverse" "^7.24.8" + "@babel/types" "^7.24.8" + "@babel/helper-module-imports@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" @@ -166,12 +271,29 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-optimise-call-expression@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz#8b0a0456c92f6b323d27cfd00d1d664e76692a0f" + integrity sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A== + dependencies: + "@babel/types" "^7.24.7" + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== -"@babel/helper-remap-async-to-generator@^7.18.9", "@babel/helper-remap-async-to-generator@^7.22.5", "@babel/helper-remap-async-to-generator@^7.22.9": +"@babel/helper-plugin-utils@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz#a924607dd254a65695e5bd209b98b902b3b2f11a" + integrity sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ== + +"@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" + integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== + +"@babel/helper-remap-async-to-generator@^7.22.5", "@babel/helper-remap-async-to-generator@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz#53a25b7484e722d7efb9c350c75c032d4628de82" integrity sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ== @@ -180,6 +302,15 @@ "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-wrap-function" "^7.22.9" +"@babel/helper-remap-async-to-generator@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz#d2f0fbba059a42d68e5e378feaf181ef6055365e" + integrity sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-wrap-function" "^7.25.0" + "@babel/traverse" "^7.25.0" + "@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz#cbdc27d6d8d18cd22c81ae4293765a5d9afd0779" @@ -189,6 +320,24 @@ "@babel/helper-member-expression-to-functions" "^7.22.5" "@babel/helper-optimise-call-expression" "^7.22.5" +"@babel/helper-replace-supers@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz#7085bd19d4a0b7ed8f405c1ed73ccb70f323abc1" + integrity sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + +"@babel/helper-replace-supers@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz#ff44deac1c9f619523fe2ca1fd650773792000a9" + integrity sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.24.8" + "@babel/helper-optimise-call-expression" "^7.24.7" + "@babel/traverse" "^7.25.0" + "@babel/helper-simple-access@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" @@ -203,6 +352,14 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-skip-transparent-expression-wrappers@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz#5f8fa83b69ed5c27adc56044f8be2b3ea96669d9" + integrity sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + "@babel/helper-split-export-declaration@^7.22.6": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" @@ -210,21 +367,53 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-split-export-declaration@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz#b9a67f06a46b0b339323617c8c6213b9055a78b6" + integrity sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q== + dependencies: + "@babel/types" "^7.24.5" + "@babel/helper-string-parser@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== +"@babel/helper-string-parser@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" + integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== + +"@babel/helper-string-parser@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" + integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== + "@babel/helper-validator-identifier@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== +"@babel/helper-validator-identifier@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" + integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== + +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + "@babel/helper-validator-option@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== +"@babel/helper-validator-option@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" + integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== + "@babel/helper-wrap-function@^7.22.9": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.10.tgz#d845e043880ed0b8c18bd194a12005cb16d2f614" @@ -234,6 +423,15 @@ "@babel/template" "^7.22.5" "@babel/types" "^7.22.10" +"@babel/helper-wrap-function@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz#dab12f0f593d6ca48c0062c28bcfb14ebe812f81" + integrity sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ== + dependencies: + "@babel/template" "^7.25.0" + "@babel/traverse" "^7.25.0" + "@babel/types" "^7.25.0" + "@babel/helpers@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.10.tgz#ae6005c539dfbcb5cd71fb51bfc8a52ba63bc37a" @@ -252,11 +450,43 @@ chalk "^2.4.2" js-tokens "^4.0.0" +"@babel/highlight@^7.24.2": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.5.tgz#bc0613f98e1dd0720e99b2a9ee3760194a704b6e" + integrity sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.5" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + "@babel/parser@^7.13.16", "@babel/parser@^7.20.0", "@babel/parser@^7.22.10", "@babel/parser@^7.22.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.10.tgz#e37634f9a12a1716136c44624ef54283cabd3f55" integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== +"@babel/parser@^7.24.0": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" + integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== + +"@babel/parser@^7.25.0", "@babel/parser@^7.25.4": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.4.tgz#af4f2df7d02440286b7de57b1c21acfb2a6f257a" + integrity sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA== + dependencies: + "@babel/types" "^7.25.4" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e" @@ -273,17 +503,7 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/plugin-transform-optional-chaining" "^7.22.5" -"@babel/plugin-proposal-async-generator-functions@^7.0.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz#bfb7276d2d573cb67ba379984a2334e262ba5326" - integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-remap-async-to-generator" "^7.18.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.13.0", "@babel/plugin-proposal-class-properties@^7.17.12", "@babel/plugin-proposal-class-properties@^7.18.0": +"@babel/plugin-proposal-class-properties@^7.13.0", "@babel/plugin-proposal-class-properties@^7.17.12": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== @@ -299,7 +519,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-export-default-from" "^7.22.5" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.0": +"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== @@ -307,34 +527,7 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" - integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.20.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" - integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== - dependencies: - "@babel/compat-data" "^7.20.5" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.20.7" - -"@babel/plugin-proposal-optional-catch-binding@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" - integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.20.0": +"@babel/plugin-proposal-optional-chaining@^7.13.12": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== @@ -355,7 +548,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.0.0", "@babel/plugin-syntax-class-properties@^7.12.13": +"@babel/plugin-syntax-class-properties@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== @@ -390,7 +583,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.12.1", "@babel/plugin-syntax-flow@^7.18.0", "@babel/plugin-syntax-flow@^7.22.5": +"@babel/plugin-syntax-flow@^7.12.1", "@babel/plugin-syntax-flow@^7.18.0", "@babel/plugin-syntax-flow@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz#163b820b9e7696ce134df3ee716d9c0c98035859" integrity sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ== @@ -425,7 +618,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.22.5": +"@babel/plugin-syntax-jsx@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== @@ -453,7 +646,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== @@ -520,6 +713,16 @@ "@babel/helper-remap-async-to-generator" "^7.22.9" "@babel/plugin-syntax-async-generators" "^7.8.4" +"@babel/plugin-transform-async-generator-functions@^7.24.3": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz#2afd4e639e2d055776c9f091b6c0c180ed8cf083" + integrity sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-remap-async-to-generator" "^7.25.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/traverse" "^7.25.4" + "@babel/plugin-transform-async-to-generator@^7.20.0", "@babel/plugin-transform-async-to-generator@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" @@ -529,7 +732,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-remap-async-to-generator" "^7.22.5" -"@babel/plugin-transform-block-scoped-functions@^7.0.0", "@babel/plugin-transform-block-scoped-functions@^7.22.5": +"@babel/plugin-transform-block-scoped-functions@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== @@ -551,6 +754,14 @@ "@babel/helper-create-class-features-plugin" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-class-properties@^7.24.1": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz#bae7dbfcdcc2e8667355cd1fb5eda298f05189fd" + integrity sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.25.4" + "@babel/helper-plugin-utils" "^7.24.8" + "@babel/plugin-transform-class-static-block@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz#3e40c46f048403472d6f4183116d5e46b1bff5ba" @@ -583,7 +794,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/template" "^7.22.5" -"@babel/plugin-transform-destructuring@^7.0.0", "@babel/plugin-transform-destructuring@^7.20.0", "@babel/plugin-transform-destructuring@^7.22.10": +"@babel/plugin-transform-destructuring@^7.20.0", "@babel/plugin-transform-destructuring@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.10.tgz#38e2273814a58c810b6c34ea293be4973c4eb5e2" integrity sha512-dPJrL0VOyxqLM9sritNbMSGx/teueHF/htMKrPT7DNxccXxRDPYqlgPFFdr8u+F+qUZOkZoXue/6rL5O5GduEw== @@ -629,7 +840,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.20.0", "@babel/plugin-transform-flow-strip-types@^7.22.5": +"@babel/plugin-transform-flow-strip-types@^7.20.0", "@babel/plugin-transform-flow-strip-types@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz#0bb17110c7bf5b35a60754b2f00c58302381dee2" integrity sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA== @@ -637,7 +848,15 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-flow" "^7.22.5" -"@babel/plugin-transform-for-of@^7.0.0", "@babel/plugin-transform-for-of@^7.22.5": +"@babel/plugin-transform-for-of@^7.0.0": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz#f25b33f72df1d8be76399e1b8f3f9d366eb5bc70" + integrity sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + +"@babel/plugin-transform-for-of@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz#ab1b8a200a8f990137aff9a084f8de4099ab173f" integrity sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A== @@ -676,7 +895,15 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.0.0", "@babel/plugin-transform-member-expression-literals@^7.22.5": +"@babel/plugin-transform-logical-assignment-operators@^7.24.1": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz#a58fb6eda16c9dc8f9ff1c7b1ba6deb7f4694cb0" + integrity sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== @@ -741,6 +968,14 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" +"@babel/plugin-transform-nullish-coalescing-operator@^7.24.1": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz#1de4534c590af9596f53d67f52a92f12db984120" + integrity sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-transform-numeric-separator@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz#57226a2ed9e512b9b446517ab6fa2d17abb83f58" @@ -749,6 +984,14 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" +"@babel/plugin-transform-numeric-separator@^7.24.1": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz#bea62b538c80605d8a0fac9b40f48e97efa7de63" + integrity sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-transform-object-rest-spread@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz#9686dc3447df4753b0b2a2fae7e8bc33cdc1f2e1" @@ -760,7 +1003,17 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.22.5" -"@babel/plugin-transform-object-super@^7.0.0", "@babel/plugin-transform-object-super@^7.22.5": +"@babel/plugin-transform-object-rest-spread@^7.24.5": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz#d13a2b93435aeb8a197e115221cab266ba6e55d6" + integrity sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q== + dependencies: + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.24.7" + +"@babel/plugin-transform-object-super@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== @@ -776,6 +1029,14 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" +"@babel/plugin-transform-optional-catch-binding@^7.24.1": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz#00eabd883d0dd6a60c1c557548785919b6e717b4" + integrity sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-transform-optional-chaining@^7.22.10", "@babel/plugin-transform-optional-chaining@^7.22.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.10.tgz#076d28a7e074392e840d4ae587d83445bac0372a" @@ -785,13 +1046,29 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.22.5": +"@babel/plugin-transform-optional-chaining@^7.24.5": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz#bb02a67b60ff0406085c13d104c99a835cdf365d" + integrity sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz#c3542dd3c39b42c8069936e48717a8d179d63a18" integrity sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-parameters@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz#5881f0ae21018400e320fc7eb817e529d1254b68" + integrity sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-transform-private-methods@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" @@ -800,6 +1077,16 @@ "@babel/helper-create-class-features-plugin" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-private-property-in-object@^7.22.11": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz#f5d1fcad36e30c960134cb479f1ca98a5b06eda5" + integrity sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.24.5" + "@babel/helper-plugin-utils" "^7.24.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-transform-private-property-in-object@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz#07a77f28cbb251546a43d175a1dda4cf3ef83e32" @@ -810,7 +1097,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-transform-property-literals@^7.0.0", "@babel/plugin-transform-property-literals@^7.22.5": +"@babel/plugin-transform-property-literals@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== @@ -864,6 +1151,14 @@ "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-regenerator@^7.20.0": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz#021562de4534d8b4b1851759fd7af4e05d2c47f8" + integrity sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + regenerator-transform "^0.15.2" + "@babel/plugin-transform-regenerator@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca" @@ -913,7 +1208,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-template-literals@^7.0.0", "@babel/plugin-transform-template-literals@^7.22.5": +"@babel/plugin-transform-template-literals@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== @@ -1127,6 +1422,24 @@ "@babel/parser" "^7.22.5" "@babel/types" "^7.22.5" +"@babel/template@^7.22.15": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" + integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/parser" "^7.24.0" + "@babel/types" "^7.24.0" + +"@babel/template@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a" + integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/parser" "^7.25.0" + "@babel/types" "^7.25.0" + "@babel/traverse@^7.20.0", "@babel/traverse@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.10.tgz#20252acb240e746d27c2e82b4484f199cf8141aa" @@ -1143,6 +1456,19 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.4": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.4.tgz#648678046990f2957407e3086e97044f13c3e18e" + integrity sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.25.4" + "@babel/parser" "^7.25.4" + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.4" + debug "^4.3.1" + globals "^11.1.0" + "@babel/types@^7.20.0", "@babel/types@^7.22.10", "@babel/types@^7.22.5", "@babel/types@^7.4.4": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" @@ -1152,6 +1478,24 @@ "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" +"@babel/types@^7.23.0", "@babel/types@^7.24.0", "@babel/types@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.5.tgz#7661930afc638a5383eb0c4aee59b74f38db84d7" + integrity sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ== + dependencies: + "@babel/helper-string-parser" "^7.24.1" + "@babel/helper-validator-identifier" "^7.24.5" + to-fast-properties "^2.0.0" + +"@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.25.0", "@babel/types@^7.25.4": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.4.tgz#6bcb46c72fdf1012a209d016c07f769e10adcb5f" + integrity sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ== + dependencies: + "@babel/helper-string-parser" "^7.24.8" + "@babel/helper-validator-identifier" "^7.24.7" + to-fast-properties "^2.0.0" + "@hapi/hoek@^9.0.0": version "9.3.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" @@ -1164,39 +1508,44 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@jest/create-cache-key-function@^29.2.1": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.6.2.tgz#b6b74fb741a7b7d9aa399c179694db8272283527" - integrity sha512-oGVRMr8na9h1vUiem1E/Uoxb/NR9BdfKb7IBZ+pNWxJQmTYSbDF0dsVBAGqNU7MBQwYJDyRx0H7H/0itiqAgQg== +"@isaacs/ttlcache@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz#21fb23db34e9b6220c6ba023a0118a2dd3461ea2" + integrity sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA== + +"@jest/create-cache-key-function@^29.6.3": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz#793be38148fab78e65f40ae30c36785f4ad859f0" + integrity sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" -"@jest/environment@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.6.2.tgz#794c0f769d85e7553439d107d3f43186dc6874a9" - integrity sha512-AEcW43C7huGd/vogTddNNTDRpO6vQ2zaQNrttvWV18ArBx9Z56h7BIsXkNFJVOO4/kblWEQz30ckw0+L3izc+Q== +"@jest/environment@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" + integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== dependencies: - "@jest/fake-timers" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" - jest-mock "^29.6.2" + jest-mock "^29.7.0" -"@jest/fake-timers@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.6.2.tgz#fe9d43c5e4b1b901168fe6f46f861b3e652a2df4" - integrity sha512-euZDmIlWjm1Z0lJ1D0f7a0/y5Kh/koLFMUBE5SUYWrmy8oNhJpbTBDAP6CxKnadcMLDoDf4waRYCe35cH6G6PA== +"@jest/fake-timers@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^29.6.2" - jest-mock "^29.6.2" - jest-util "^29.6.2" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" -"@jest/schemas@^29.6.0": - version "29.6.0" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040" - integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ== +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== dependencies: "@sinclair/typebox" "^0.27.8" @@ -1211,23 +1560,12 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@jest/types@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" - integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - -"@jest/types@^29.6.1": - version "29.6.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.1.tgz#ae79080278acff0a6af5eb49d063385aaa897bf2" - integrity sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw== +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== dependencies: - "@jest/schemas" "^29.6.0" + "@jest/schemas" "^29.6.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" @@ -1243,6 +1581,15 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@^3.1.0": version "3.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" @@ -1253,6 +1600,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + "@jridgewell/source-map@^0.3.3": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" @@ -1274,6 +1626,14 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1295,204 +1655,294 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@react-native-community/cli-clean@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-11.3.10.tgz#70d14dd998ce8ad532266b36a0e5cafe22d300ac" - integrity sha512-g6QjW+DSqoWRHzmIQW3AH22k1AnynWuOdy2YPwYEGgPddTeXZtJphIpEVwDOiC0L4mZv2VmiX33/cGNUwO0cIA== +"@react-native-community/cli-clean@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-14.1.0.tgz#fee1a178fa58c84dfe18e23ee79fd3110d974971" + integrity sha512-/C4j1yntLo6faztNgZnsDtgpGqa6j0+GYrxOY8LqaKAN03OCnoeUUKO6w78dycbYSGglc1xjJg2RZI/M2oF2AA== dependencies: - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-tools" "14.1.0" chalk "^4.1.2" execa "^5.0.0" - prompts "^2.4.0" + fast-glob "^3.3.2" -"@react-native-community/cli-config@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-11.3.10.tgz#753510a80a98b136fec852e1ea5fa655c13dbd17" - integrity sha512-YYu14nm1JYLS6mDRBz78+zDdSFudLBFpPkhkOoj4LuBhNForQBIqFFHzQbd9/gcguJxfW3vlYSnudfaUI7oGLg== +"@react-native-community/cli-config@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-14.1.0.tgz#8cdebb890eeb3c25d6c117ee56c952e96ea2afbf" + integrity sha512-P3FK2rPUJBD1fmQHLgTqpHxsc111pnMdEEFR7KeqprCNz+Qr2QpPxfNy0V7s15tGL5rAv+wpbOGcioIV50EbxA== dependencies: - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-tools" "14.1.0" chalk "^4.1.2" - cosmiconfig "^5.1.0" + cosmiconfig "^9.0.0" deepmerge "^4.3.0" - glob "^7.1.3" + fast-glob "^3.3.2" joi "^17.2.1" -"@react-native-community/cli-debugger-ui@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-11.3.10.tgz#b16ebf770ba3cc76bf46580f101d00dacf919824" - integrity sha512-kyitGV3RsjlXIioq9lsuawha2GUBPCTAyXV6EBlm3qlyF3dMniB3twEvz+fIOid/e1ZeucH3Tzy5G3qcP8yWoA== +"@react-native-community/cli-debugger-ui@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-14.1.0.tgz#0008039ad2c386730c415d9dfc6884d68fda2c93" + integrity sha512-+YbeCL0wLcBcqDwraJFGsqzcXu9S+bwTVrfImne/4mT6itfe3Oa93yrOVJgNbstrt5pJHuwpU76ZXfXoiuncsg== dependencies: serve-static "^1.13.1" -"@react-native-community/cli-doctor@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-11.3.10.tgz#161b8fd1b485cd52f7a19b2025696070b9d2b6a1" - integrity sha512-DpMsfCWKZ15L9nFK/SyDvpl5v6MjV+arMHMC1i8kR+DOmf2xWmp/pgMywKk0/u50yGB9GwxBHt3i/S/IMK5Ylg== +"@react-native-community/cli-doctor@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-14.1.0.tgz#129b25a7792f7bb0ed1218d17665ce74bb995d08" + integrity sha512-xIf0oQDRKt7lufUenRwcLYdINGc0x1FSXHaHjd7lQDGT5FJnCEYlIkYEDDgAl5tnVJSvM/IL2c6O+mffkNEPzQ== dependencies: - "@react-native-community/cli-config" "11.3.10" - "@react-native-community/cli-platform-android" "11.3.10" - "@react-native-community/cli-platform-ios" "11.3.10" - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-config" "14.1.0" + "@react-native-community/cli-platform-android" "14.1.0" + "@react-native-community/cli-platform-apple" "14.1.0" + "@react-native-community/cli-platform-ios" "14.1.0" + "@react-native-community/cli-tools" "14.1.0" chalk "^4.1.2" command-exists "^1.2.8" - envinfo "^7.7.2" + deepmerge "^4.3.0" + envinfo "^7.13.0" execa "^5.0.0" - hermes-profile-transformer "^0.0.6" - ip "^1.1.5" node-stream-zip "^1.9.1" ora "^5.4.1" - prompts "^2.4.0" semver "^7.5.2" strip-ansi "^5.2.0" - sudo-prompt "^9.0.0" wcwidth "^1.0.1" yaml "^2.2.1" -"@react-native-community/cli-hermes@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-11.3.10.tgz#f3d4f069ca472b1d8b4e8132cf9c44097a58ca19" - integrity sha512-vqINuzAlcHS9ImNwJtT43N7kfBQ7ro9A8O1Gpc5TQ0A8V36yGG8eoCHeauayklVVgMZpZL6f6mcoLLr9IOgBZQ== +"@react-native-community/cli-platform-android@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-14.1.0.tgz#3545347a810d209bba24941f62f802fdc09e252f" + integrity sha512-4JnXkAV+ca8XdUhZ7xjgDhXAMwTVjQs8JqiwP7FTYVrayShXy2cBXm/C3HNDoe+oQOF5tPT2SqsDAF2vYTnKiQ== dependencies: - "@react-native-community/cli-platform-android" "11.3.10" - "@react-native-community/cli-tools" "11.3.10" - chalk "^4.1.2" - hermes-profile-transformer "^0.0.6" - ip "^1.1.5" - -"@react-native-community/cli-platform-android@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-11.3.10.tgz#756dd73ad78bf2f20c678683dfc48cb764b1b590" - integrity sha512-RGu9KuDIXnrcNkacSHj5ETTQtp/D/835L6veE2jMigO21p//gnKAjw3AVLCysGr8YXYfThF8OSOALrwNc94puQ== - dependencies: - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-tools" "14.1.0" chalk "^4.1.2" execa "^5.0.0" - glob "^7.1.3" + fast-glob "^3.3.2" + fast-xml-parser "^4.4.1" logkitty "^0.7.1" -"@react-native-community/cli-platform-ios@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-11.3.10.tgz#f8a9bca1181802f12ed15714d5a496e60096cbed" - integrity sha512-JjduMrBM567/j4Hvjsff77dGSLMA0+p9rr0nShlgnKPcc+0J4TDy0hgWpUceM7OG00AdDjpetAPupz0kkAh4cQ== +"@react-native-community/cli-platform-apple@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-apple/-/cli-platform-apple-14.1.0.tgz#d232cd0fc1ec0bccd165e40dd7d8a3c4bec5f571" + integrity sha512-DExd+pZ7hHxXt8I6BBmckeYUxxq7PQ+o4YSmGIeQx0xUpi+f82obBct2WNC3VWU72Jw6obwfoN6Fwe6F7Wxp5Q== dependencies: - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-tools" "14.1.0" chalk "^4.1.2" execa "^5.0.0" - fast-xml-parser "^4.0.12" - glob "^7.1.3" + fast-glob "^3.3.2" + fast-xml-parser "^4.4.1" ora "^5.4.1" -"@react-native-community/cli-plugin-metro@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-11.3.10.tgz#6ed67dda2518d3dabae20f3b38f66a0a9bd8e962" - integrity sha512-ZYAc5Hc+QVqJgj1XFbpKnIPbSJ9xKcBnfQrRhR+jFyt2DWx85u4bbzY1GSVc/USs0UbSUXv4dqPbnmOJz52EYQ== +"@react-native-community/cli-platform-ios@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-14.1.0.tgz#e3b7ae8a97b69da4c7c89d9767ea58fb90c9c05f" + integrity sha512-ah/ZTiJXUdCVHujyRJ4OmCL5nTq8OWcURcE3UXa1z0sIIiA8io06n+v5n299T9rtPKMwRtVJlQjtO/nbODABPQ== dependencies: - "@react-native-community/cli-server-api" "11.3.10" - "@react-native-community/cli-tools" "11.3.10" - chalk "^4.1.2" - execa "^5.0.0" - metro "0.76.8" - metro-config "0.76.8" - metro-core "0.76.8" - metro-react-native-babel-transformer "0.76.8" - metro-resolver "0.76.8" - metro-runtime "0.76.8" - readline "^1.3.0" + "@react-native-community/cli-platform-apple" "14.1.0" -"@react-native-community/cli-server-api@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-11.3.10.tgz#2c4940d921711f2c78f0b61f126e8dbbbef6277c" - integrity sha512-WEwHWIpqx3gA6Da+lrmq8+z78E1XbxxjBlvHAXevhjJj42N4SO417eZiiUVrFzEFVVJSUee9n9aRa0kUR+0/2w== +"@react-native-community/cli-server-api@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-14.1.0.tgz#b658f96014f6d725ddb50da69833eacdbb8263c8" + integrity sha512-1k2LBQaYsy9RDWFIfKVne3frOye73O33MV6eYMoRPff7wqxHCrsX1CYJQkmwpgVigZHxYwalHj+Axtu3gpomCA== dependencies: - "@react-native-community/cli-debugger-ui" "11.3.10" - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-debugger-ui" "14.1.0" + "@react-native-community/cli-tools" "14.1.0" compression "^1.7.1" connect "^3.6.5" errorhandler "^1.5.1" nocache "^3.0.1" pretty-format "^26.6.2" serve-static "^1.13.1" - ws "^7.5.1" + ws "^6.2.3" -"@react-native-community/cli-tools@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-11.3.10.tgz#d7bbe3fd8b338004f996f03f53a5373d9caab91c" - integrity sha512-4kCuCwVcGagSrNg9vxMNVhynwpByuC/J5UnKGEet3HuqmoDhQW15m18fJXiehA8J+u9WBvHduefy9nZxO0C06Q== +"@react-native-community/cli-tools@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-14.1.0.tgz#fbbd40e9ccd93842992c8e45c10dfd8eeb56ff4a" + integrity sha512-r1KxSu2+OSuhWFoE//1UR7aSTXMLww/UYWQprEw4bSo/kvutGX//4r9ywgXSWp+39udpNN4jQpNTHuWhGZd/Bg== dependencies: appdirsjs "^1.2.4" chalk "^4.1.2" + execa "^5.0.0" find-up "^5.0.0" mime "^2.4.1" - node-fetch "^2.6.0" open "^6.2.0" ora "^5.4.1" semver "^7.5.2" shell-quote "^1.7.3" + sudo-prompt "^9.0.0" -"@react-native-community/cli-types@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-11.3.10.tgz#cb02186cd247108bcea5ff93c4c97bb3c8dd8f22" - integrity sha512-0FHK/JE7bTn0x1y8Lk5m3RISDHIBQqWLltO2Mf7YQ6cAeKs8iNOJOeKaHJEY+ohjsOyCziw+XSC4cY57dQrwNA== +"@react-native-community/cli-types@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-14.1.0.tgz#0ea5dad716f30cd49d2edd5d9fdea8e552cb44e8" + integrity sha512-aJwZI9mGRx3HdP8U4CGhqjt3S4r8GmeOqv4kRagC1UHDk4QNMC+bZ8JgPA4W7FrGiPey+lJQHMDPAXOo51SOUw== dependencies: joi "^17.2.1" -"@react-native-community/cli@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-11.3.10.tgz#ea88d20982cfc9ed7a5170d04aeedd2abf092348" - integrity sha512-bIx0t5s9ewH1PlcEcuQUD+UnVrCjPGAfjhVR5Gew565X60nE+GTIHRn70nMv9G4he/amBF+Z+vf5t8SNZEWMwg== - dependencies: - "@react-native-community/cli-clean" "11.3.10" - "@react-native-community/cli-config" "11.3.10" - "@react-native-community/cli-debugger-ui" "11.3.10" - "@react-native-community/cli-doctor" "11.3.10" - "@react-native-community/cli-hermes" "11.3.10" - "@react-native-community/cli-plugin-metro" "11.3.10" - "@react-native-community/cli-server-api" "11.3.10" - "@react-native-community/cli-tools" "11.3.10" - "@react-native-community/cli-types" "11.3.10" +"@react-native-community/cli@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-14.1.0.tgz#bbcc14e9b7ee54589e645c7cd42da0cc79307f41" + integrity sha512-k7aTdKNZIec7WMSqMJn9bDVLWPPOaYmshXcnjWy6t5ItsJnREju9p2azMTR5tXY5uIeynose3cxettbhk2Tbnw== + dependencies: + "@react-native-community/cli-clean" "14.1.0" + "@react-native-community/cli-config" "14.1.0" + "@react-native-community/cli-debugger-ui" "14.1.0" + "@react-native-community/cli-doctor" "14.1.0" + "@react-native-community/cli-server-api" "14.1.0" + "@react-native-community/cli-tools" "14.1.0" + "@react-native-community/cli-types" "14.1.0" chalk "^4.1.2" commander "^9.4.1" + deepmerge "^4.3.0" execa "^5.0.0" - find-up "^4.1.0" + find-up "^5.0.0" fs-extra "^8.1.0" graceful-fs "^4.1.3" - prompts "^2.4.0" + prompts "^2.4.2" semver "^7.5.2" -"@react-native/assets-registry@^0.72.0": - version "0.72.0" - resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.72.0.tgz#c82a76a1d86ec0c3907be76f7faf97a32bbed05d" - integrity sha512-Im93xRJuHHxb1wniGhBMsxLwcfzdYreSZVQGDoMJgkd6+Iky61LInGEHnQCTN0fKNYF1Dvcofb4uMmE1RQHXHQ== +"@react-native/assets-registry@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.75.4.tgz#d48b8765e030f8d305f34659d4ce50ebb82ccb34" + integrity sha512-WX6/LNHwyjislSFM+h3qQjBiPaXXPJW5ZV4TdgNKb6QOPO0g1KGYRQj44cI2xSpZ3fcWrvQFZfQgSMbVK9Sg7A== + +"@react-native/babel-plugin-codegen@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.75.4.tgz#c9916d1c2c043a0b777fe0134fe4aaee6a82ae6c" + integrity sha512-gu5ZRIdr7+ufi09DJROhfDtbF4biTnCDJqtqcmtsku4cXOXPHE36QbC/vAmKEZ0PMPURBI8lwF2wfaeHLn7gig== + dependencies: + "@react-native/codegen" "0.75.4" -"@react-native/codegen@^0.72.7": - version "0.72.7" - resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.72.7.tgz#b6832ce631ac63143024ea094a6b5480a780e589" - integrity sha512-O7xNcGeXGbY+VoqBGNlZ3O05gxfATlwE1Q1qQf5E38dK+tXn5BY4u0jaQ9DPjfE8pBba8g/BYI1N44lynidMtg== +"@react-native/babel-preset@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.75.4.tgz#6e49a73dbbe70e2765686a67088c67fe83085e97" + integrity sha512-UtyYCDJ3rZIeggyFEfh/q5t/FZ5a1h9F8EI37Nbrwyk/OKPH+1XS4PbHROHJzBARlJwOAfmT75+ovYUO0eakJA== + dependencies: + "@babel/core" "^7.20.0" + "@babel/plugin-proposal-export-default-from" "^7.0.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-default-from" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.18.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-syntax-optional-chaining" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-async-generator-functions" "^7.24.3" + "@babel/plugin-transform-async-to-generator" "^7.20.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-class-properties" "^7.24.1" + "@babel/plugin-transform-classes" "^7.0.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.20.0" + "@babel/plugin-transform-flow-strip-types" "^7.20.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.0.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-logical-assignment-operators" "^7.24.1" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.1" + "@babel/plugin-transform-numeric-separator" "^7.24.1" + "@babel/plugin-transform-object-rest-spread" "^7.24.5" + "@babel/plugin-transform-optional-catch-binding" "^7.24.1" + "@babel/plugin-transform-optional-chaining" "^7.24.5" + "@babel/plugin-transform-parameters" "^7.0.0" + "@babel/plugin-transform-private-methods" "^7.22.5" + "@babel/plugin-transform-private-property-in-object" "^7.22.11" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-react-jsx-self" "^7.0.0" + "@babel/plugin-transform-react-jsx-source" "^7.0.0" + "@babel/plugin-transform-regenerator" "^7.20.0" + "@babel/plugin-transform-runtime" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-sticky-regex" "^7.0.0" + "@babel/plugin-transform-typescript" "^7.5.0" + "@babel/plugin-transform-unicode-regex" "^7.0.0" + "@babel/template" "^7.0.0" + "@react-native/babel-plugin-codegen" "0.75.4" + babel-plugin-transform-flow-enums "^0.0.2" + react-refresh "^0.14.0" + +"@react-native/codegen@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.75.4.tgz#2eae0800fbddfd2f3946d9f2a229cae21feacd45" + integrity sha512-0FplNAD/S5FUvm8YIn6uyarOcP4jdJPqWz17K4a/Gp2KSsG/JJKEskX3aj5wpePzVfNQl3WyvBJ0whODdCocIA== dependencies: "@babel/parser" "^7.20.0" - flow-parser "^0.206.0" + glob "^7.1.1" + hermes-parser "0.22.0" + invariant "^2.2.4" jscodeshift "^0.14.0" + mkdirp "^0.5.1" nullthrows "^1.1.1" + yargs "^17.6.2" -"@react-native/gradle-plugin@^0.72.11": - version "0.72.11" - resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.72.11.tgz#c063ef12778706611de7a1e42b74b14d9405fb9f" - integrity sha512-P9iRnxiR2w7EHcZ0mJ+fmbPzMby77ZzV6y9sJI3lVLJzF7TLSdbwcQyD3lwMsiL+q5lKUHoZJS4sYmih+P2HXw== +"@react-native/community-cli-plugin@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.75.4.tgz#aaaebeaf3d39c9c3e39b5b2fc8779119be51c87e" + integrity sha512-k/hevYPjEpW0MNVVyb3v9PJosOP+FzenS7+oqYNLXdEmgTnGHrAtYX9ABrJJgzeJt7I6g8g+RDvm8PSE+tnM5w== + dependencies: + "@react-native-community/cli-server-api" "14.1.0" + "@react-native-community/cli-tools" "14.1.0" + "@react-native/dev-middleware" "0.75.4" + "@react-native/metro-babel-transformer" "0.75.4" + chalk "^4.0.0" + execa "^5.1.1" + metro "^0.80.3" + metro-config "^0.80.3" + metro-core "^0.80.3" + node-fetch "^2.2.0" + readline "^1.3.0" -"@react-native/js-polyfills@^0.72.1": - version "0.72.1" - resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.72.1.tgz#905343ef0c51256f128256330fccbdb35b922291" - integrity sha512-cRPZh2rBswFnGt5X5EUEPs0r+pAsXxYsifv/fgy9ZLQokuT52bPH+9xjDR+7TafRua5CttGW83wP4TntRcWNDA== +"@react-native/debugger-frontend@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.75.4.tgz#81b0aa239d171a41a7b14333bd45b3aa5e77072a" + integrity sha512-QfGurR5hV6bhMPn/6VxS2RomYrPRFGwA03jJr+zKyWHnxDAu5jOqYVyKAktIIbhYe5sPp78QVl1ZYuhcnsRbEw== -"@react-native/normalize-colors@<0.73.0", "@react-native/normalize-colors@^0.72.0": - version "0.72.0" - resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.72.0.tgz#14294b7ed3c1d92176d2a00df48456e8d7d62212" - integrity sha512-285lfdqSXaqKuBbbtP9qL2tDrfxdOFtIMvkKadtleRQkdOxx+uzGvFr82KHmc/sSiMtfXGp7JnFYWVh4sFl7Yw== +"@react-native/dev-middleware@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.75.4.tgz#fee908bbafb9cb4fe20a3add755aadb16c440a60" + integrity sha512-UhyBeQOG2wNcvrUGw3+IBrHBk/lIu7hHGmWt4j8W9Aqv9BwktHKkPyko+5A1yoUeO1O/VDnHWYqWeOejcA9wpQ== + dependencies: + "@isaacs/ttlcache" "^1.4.1" + "@react-native/debugger-frontend" "0.75.4" + chrome-launcher "^0.15.2" + chromium-edge-launcher "^0.2.0" + connect "^3.6.5" + debug "^2.2.0" + node-fetch "^2.2.0" + nullthrows "^1.1.1" + open "^7.0.3" + selfsigned "^2.4.1" + serve-static "^1.13.1" + ws "^6.2.2" + +"@react-native/gradle-plugin@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.75.4.tgz#357d7d4c22059393113d44b077bb8e904aa1cd2c" + integrity sha512-kKTmw7cF7p1raT30DC0L6N+xiVXN7dlRy0J+hYPiCRRVHplwgvyS7pszjxfzwXmHFqOxwpxQVI3du8opsma1Mg== + +"@react-native/js-polyfills@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.75.4.tgz#de895d0728a14126d7b3c04fe17c0da7e806d994" + integrity sha512-NF5ID5FjcVHBYk1LQ4JMRjPmxBWEo4yoqW1m6vGOQZPT8D5Qs9afgx3f7gQatxbn3ivMh0FVbLW0zBx6LyxEzA== -"@react-native/virtualized-lists@^0.72.8": - version "0.72.8" - resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.72.8.tgz#a2c6a91ea0f1d40eb5a122fb063daedb92ed1dc3" - integrity sha512-J3Q4Bkuo99k7mu+jPS9gSUSgq+lLRSI/+ahXNwV92XgJ/8UgOTxu2LPwhJnBk/sQKxq7E8WkZBnBiozukQMqrw== +"@react-native/metro-babel-transformer@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.75.4.tgz#9283418536db31db8e39a879c8497483cfc736dc" + integrity sha512-O0WMW/K8Ny/MAAeRebqGEQhrbzcioxcPHZtos+EH2hWeBTEKHQV8fMYYxfYDabpr392qdhSBwg3LlXUD4U3PXQ== + dependencies: + "@babel/core" "^7.20.0" + "@react-native/babel-preset" "0.75.4" + hermes-parser "0.22.0" + nullthrows "^1.1.1" + +"@react-native/normalize-colors@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.75.4.tgz#e5eb01ee4309f2895c2d3aaf1b6449a5439c0176" + integrity sha512-90QrQDLg0/k9xqYesaKuIkayOSjD+FKa0hsHollbwT5h3kuGMY+lU7UZxnb8tU55Y1PKdvjYxqQsYWI/ql79zA== + +"@react-native/virtualized-lists@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.75.4.tgz#9c6603d916c165ad2730a54b66104c990a860347" + integrity sha512-iEauRiXjvWG/iOH8bV+9MfepCS+72cuL5rhkrenYZS0NUnDcNjF+wtaoS9+Gx5z1UJOfEXxSmyXRtQJZne8SnA== dependencies: invariant "^2.2.4" nullthrows "^1.1.1" @@ -1552,6 +2002,13 @@ dependencies: "@types/istanbul-lib-report" "*" +"@types/node-forge@^1.3.0": + version "1.3.11" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" + integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ== + dependencies: + "@types/node" "*" + "@types/node@*": version "20.5.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.1.tgz#178d58ee7e4834152b0e8b4d30cbfab578b9bb30" @@ -1577,10 +2034,9 @@ csstype "^3.0.2" "@types/react@file:../../shared/node_modules/@types/react": - version "18.2.39" + version "18.3.11" dependencies: "@types/prop-types" "*" - "@types/scheduler" "*" csstype "^3.0.2" "@types/scheduler@*": @@ -1605,13 +2061,6 @@ dependencies: "@types/yargs-parser" "*" -"@types/yargs@^16.0.0": - version "16.0.5" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3" - integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== - dependencies: - "@types/yargs-parser" "*" - "@types/yargs@^17.0.8": version "17.0.24" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" @@ -1715,6 +2164,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1742,11 +2196,6 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== -async@^3.2.2: - version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== - at-least-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" @@ -1781,11 +2230,6 @@ babel-plugin-polyfill-regenerator@^0.5.2: dependencies: "@babel/helper-define-polyfill-provider" "^0.4.2" -babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: - version "7.0.0-beta.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf" - integrity sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ== - babel-plugin-transform-flow-enums@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz#d1d0cc9bdc799c850ca110d0ddc9f21b9ec3ef25" @@ -1793,45 +2237,12 @@ babel-plugin-transform-flow-enums@^0.0.2: dependencies: "@babel/plugin-syntax-flow" "^7.12.1" -babel-preset-fbjs@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz#38a14e5a7a3b285a3f3a86552d650dca5cf6111c" - integrity sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-syntax-class-properties" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoped-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-member-expression-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-super" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-property-literals" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.1.2, base64-js@^1.3.1: +base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -1877,6 +2288,16 @@ browserslist@^4.20.4, browserslist@^4.21.10, browserslist@^4.21.9: node-releases "^2.0.13" update-browserslist-db "^1.0.11" +browserslist@^4.23.1: + version "4.23.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" + integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== + dependencies: + caniuse-lite "^1.0.30001646" + electron-to-chromium "^1.5.4" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -1941,6 +2362,11 @@ caniuse-lite@^1.0.30001517: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz#44b87a406c901269adcdb834713e23582dd71856" integrity sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg== +caniuse-lite@^1.0.30001646: + version "1.0.30001653" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz#b8af452f8f33b1c77f122780a4aecebea0caca56" + integrity sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw== + chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -1958,6 +2384,28 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +chrome-launcher@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/chrome-launcher/-/chrome-launcher-0.15.2.tgz#4e6404e32200095fdce7f6a1e1004f9bd36fa5da" + integrity sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ== + dependencies: + "@types/node" "*" + escape-string-regexp "^4.0.0" + is-wsl "^2.2.0" + lighthouse-logger "^1.0.0" + +chromium-edge-launcher@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/chromium-edge-launcher/-/chromium-edge-launcher-0.2.0.tgz#0c378f28c99aefc360705fa155de0113997f62fc" + integrity sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg== + dependencies: + "@types/node" "*" + escape-string-regexp "^4.0.0" + is-wsl "^2.2.0" + lighthouse-logger "^1.0.0" + mkdirp "^1.0.4" + rimraf "^3.0.2" + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -2061,11 +2509,6 @@ commander@^9.4.1: resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== -commander@~2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" - integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -2123,7 +2566,7 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig@^5.0.5, cosmiconfig@^5.1.0: +cosmiconfig@^5.0.5: version "5.2.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== @@ -2144,6 +2587,16 @@ cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" +cosmiconfig@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz#34c3fc58287b915f3ae905ab6dc3de258b55ad9d" + integrity sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg== + dependencies: + env-paths "^2.2.1" + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -2163,7 +2616,7 @@ dayjs@^1.8.15: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a" integrity sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA== -debug@2.6.9, debug@^2.2.0: +debug@2.6.9, debug@^2.2.0, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -2177,6 +2630,13 @@ debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" +debug@^4.3.1: + version "4.3.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" + integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + dependencies: + ms "2.1.2" + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -2223,15 +2683,6 @@ depd@2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -deprecated-react-native-prop-types@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-4.2.3.tgz#0ef845c1a80ef1636bd09060e4cdf70f9727e5ad" - integrity sha512-2rLTiMKidIFFYpIVM69UnQKngLqQfL6I11Ch8wGSBftS18FUXda+o2we2950X+1dmbgps28niI3qwyH4eX3Z1g== - dependencies: - "@react-native/normalize-colors" "<0.73.0" - invariant "^2.2.4" - prop-types "^15.8.1" - destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -2254,6 +2705,11 @@ electron-to-chromium@^1.4.477: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.496.tgz#a57534b70d2bdee7e1ad7dbd4c91e560cbd08db1" integrity sha512-qeXC3Zbykq44RCrBa4kr8v/dWzYJA8rAwpyh9Qd+NKWoJfjG5vvJqy9XOJ9H4P/lqulZBCgUWAYi+FeK5AuJ8g== +electron-to-chromium@^1.5.4: + version "1.5.13" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz#1abf0410c5344b2b829b7247e031f02810d442e6" + integrity sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -2271,10 +2727,15 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -envinfo@^7.7.2: - version "7.10.0" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13" - integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw== +env-paths@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +envinfo@^7.13.0: + version "7.13.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.13.0.tgz#81fbb81e5da35d74e814941aeab7c325a606fb31" + integrity sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q== error-ex@^1.3.1: version "1.3.2" @@ -2303,6 +2764,11 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2318,6 +2784,11 @@ escape-string-regexp@^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== + esprima@^4.0.0, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -2353,7 +2824,7 @@ execa@^4.0.3: signal-exit "^3.0.2" strip-final-newline "^2.0.0" -execa@^5.0.0: +execa@^5.0.0, execa@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -2379,10 +2850,21 @@ fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" -fast-xml-parser@^4.0.12: - version "4.2.7" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.7.tgz#871f2ca299dc4334b29f8da3658c164e68395167" - integrity sha512-J8r6BriSLO1uj2miOk1NW0YVm8AGOOu3Si2HQp/cSmo6EA4m3fcwu2WKjJ4RK9wMLBtg69y1kS8baDiQBR41Ig== +fast-glob@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-xml-parser@^4.4.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz#2882b7d01a6825dfdf909638f2de0256351def37" + integrity sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg== dependencies: strnum "^1.0.5" @@ -2459,21 +2941,16 @@ find-yarn-workspace-root@^2.0.0: dependencies: micromatch "^4.0.2" -flow-enums-runtime@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/flow-enums-runtime/-/flow-enums-runtime-0.0.5.tgz#95884bfcc82edaf27eef7e1dd09732331cfbafbc" - integrity sha512-PSZF9ZuaZD03sT9YaIs0FrGJ7lSUw7rHZIex+73UYVXg46eL/wxN5PaVcPJFudE2cJu5f0fezitV5aBkLHPUOQ== +flow-enums-runtime@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz#5bb0cd1b0a3e471330f4d109039b7eba5cb3e787" + integrity sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw== flow-parser@0.*: version "0.214.0" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.214.0.tgz#455efc841ec015c62f6dec022cf6c61480f231a2" integrity sha512-RW1Dh6BuT14DA7+gtNRKzgzvG3GTPdrceHCi4ddZ9VFGQ9HtO5L8wzxMGsor7XtInIrbWZZCSak0oxnBF7tApw== -flow-parser@^0.206.0: - version "0.206.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.206.0.tgz#f4f794f8026535278393308e01ea72f31000bfef" - integrity sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w== - fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -2551,7 +3028,7 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" -glob@^7.1.3: +glob@^7.1.1, glob@^7.1.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -2613,24 +3090,29 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hermes-estree@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.12.0.tgz#8a289f9aee854854422345e6995a48613bac2ca8" - integrity sha512-+e8xR6SCen0wyAKrMT3UD0ZCCLymKhRgjEB5sS28rKiFir/fXgLoeRilRUssFCILmGHb+OvHDUlhxs0+IEyvQw== +hermes-estree@0.20.1: + version "0.20.1" + resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.20.1.tgz#0b9a544cf883a779a8e1444b915fa365bef7f72d" + integrity sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg== + +hermes-estree@0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.22.0.tgz#38559502b119f728901d2cfe2ef422f277802a1d" + integrity sha512-FLBt5X9OfA8BERUdc6aZS36Xz3rRuB0Y/mfocSADWEJfomc1xfene33GdyAmtTkKTBXTN/EgAy+rjTKkkZJHlw== -hermes-parser@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.12.0.tgz#114dc26697cfb41a6302c215b859b74224383773" - integrity sha512-d4PHnwq6SnDLhYl3LHNHvOg7nQ6rcI7QVil418REYksv0Mh3cEkHDcuhGxNQ3vgnLSLl4QSvDrFCwQNYdpWlzw== +hermes-parser@0.20.1: + version "0.20.1" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.20.1.tgz#ad10597b99f718b91e283f81cbe636c50c3cff92" + integrity sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA== dependencies: - hermes-estree "0.12.0" + hermes-estree "0.20.1" -hermes-profile-transformer@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/hermes-profile-transformer/-/hermes-profile-transformer-0.0.6.tgz#bd0f5ecceda80dd0ddaae443469ab26fb38fc27b" - integrity sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ== +hermes-parser@0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.22.0.tgz#fc8e0e6c7bfa8db85b04c9f9544a102c4fcb4040" + integrity sha512-gn5RfZiEXCsIWsFGsKiykekktUoh0PdFWYocXsUdZIyWSckT6UIyPcyyUIPSR3kpnELWeK3n3ztAse7Mat6PSA== dependencies: - source-map "^0.7.3" + hermes-estree "0.22.0" http-errors@2.0.0: version "2.0.0" @@ -2678,7 +3160,7 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.2.1: +import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -2716,11 +3198,6 @@ invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -ip@^1.1.5: - version "1.1.8" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" - integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== - is-absolute@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" @@ -2850,7 +3327,7 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== -is-wsl@^2.1.1: +is-wsl@^2.1.1, 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== @@ -2872,94 +3349,78 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -jest-environment-node@^29.2.1: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.6.2.tgz#a9ea2cabff39b08eca14ccb32c8ceb924c8bb1ad" - integrity sha512-YGdFeZ3T9a+/612c5mTQIllvWkddPbYcN2v95ZH24oWMbGA4GGS2XdIF92QMhUhvrjjuQWYgUGW2zawOyH63MQ== +jest-environment-node@^29.6.3: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== dependencies: - "@jest/environment" "^29.6.2" - "@jest/fake-timers" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" - jest-mock "^29.6.2" - jest-util "^29.6.2" + jest-mock "^29.7.0" + jest-util "^29.7.0" -jest-get-type@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" - integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== -jest-message-util@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.2.tgz#af7adc2209c552f3f5ae31e77cf0a261f23dc2bb" - integrity sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ== +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.6.2" + pretty-format "^29.7.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.6.2.tgz#ef9c9b4d38c34a2ad61010a021866dad41ce5e00" - integrity sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg== - dependencies: - "@jest/types" "^29.6.1" - "@types/node" "*" - jest-util "^29.6.2" - -jest-regex-util@^27.0.6: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" - integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== - -jest-util@^27.2.0: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" - integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== +jest-mock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" + integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== dependencies: - "@jest/types" "^27.5.1" + "@jest/types" "^29.6.3" "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" + jest-util "^29.7.0" -jest-util@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.2.tgz#8a052df8fff2eebe446769fd88814521a517664d" - integrity sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w== +jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^29.2.1: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.6.2.tgz#25d972af35b2415b83b1373baf1a47bb266c1082" - integrity sha512-vGz0yMN5fUFRRbpJDPwxMpgSXW1LDKROHfBopAvDcmD6s+B/s8WJrwi+4bfH4SdInBA5C3P3BI19dBtKzx1Arg== +jest-validate@^29.6.3: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^29.4.3" + jest-get-type "^29.6.3" leven "^3.1.0" - pretty-format "^29.6.2" + pretty-format "^29.7.0" -jest-worker@^27.2.0: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== +jest-worker@^29.6.3: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== dependencies: "@types/node" "*" + jest-util "^29.7.0" merge-stream "^2.0.0" supports-color "^8.0.0" @@ -2992,6 +3453,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsc-android@^250231.0.0: version "250231.0.0" resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-250231.0.0.tgz#91720f8df382a108872fa4b3f558f33ba5e95262" @@ -3107,6 +3575,14 @@ leven@^3.1.0: resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== +lighthouse-logger@^1.0.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz#aef90f9e97cd81db367c7634292ee22079280aaa" + integrity sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g== + dependencies: + debug "^2.6.9" + marky "^1.2.2" + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -3161,7 +3637,7 @@ logkitty@^0.7.1: dayjs "^1.8.15" yargs "^15.1.0" -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -3197,6 +3673,11 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" +marky@^1.2.2: + version "1.2.5" + resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.5.tgz#55796b688cbd72390d2d399eaaf1832c9413e3c0" + integrity sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q== + memoize-one@^5.0.0: version "5.2.1" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" @@ -3212,62 +3693,60 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -metro-babel-transformer@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.76.8.tgz#5efd1027353b36b73706164ef09c290dceac096a" - integrity sha512-Hh6PW34Ug/nShlBGxkwQJSgPGAzSJ9FwQXhUImkzdsDgVu6zj5bx258J8cJVSandjNoQ8nbaHK6CaHlnbZKbyA== +metro-babel-transformer@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.80.9.tgz#7051ba377b7d2140abd23f4846bbbb1e81fea99b" + integrity sha512-d76BSm64KZam1nifRZlNJmtwIgAeZhZG3fi3K+EmPOlrR8rDtBxQHDSN3fSGeNB9CirdTyabTMQCkCup6BXFSQ== dependencies: "@babel/core" "^7.20.0" - hermes-parser "0.12.0" + hermes-parser "0.20.1" nullthrows "^1.1.1" -metro-cache-key@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.76.8.tgz#8a0a5e991c06f56fcc584acadacb313c312bdc16" - integrity sha512-buKQ5xentPig9G6T37Ww/R/bC+/V1MA5xU/D8zjnhlelsrPG6w6LtHUS61ID3zZcMZqYaELWk5UIadIdDsaaLw== +metro-cache-key@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.80.9.tgz#a04cbb0a7828509bb10dde9789ef761c0c60bc3d" + integrity sha512-hRcYGhEiWIdM87hU0fBlcGr+tHDEAT+7LYNCW89p5JhErFt/QaAkVx4fb5bW3YtXGv5BTV7AspWPERoIb99CXg== -metro-cache@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.76.8.tgz#296c1c189db2053b89735a8f33dbe82575f53661" - integrity sha512-QBJSJIVNH7Hc/Yo6br/U/qQDUpiUdRgZ2ZBJmvAbmAKp2XDzsapnMwK/3BGj8JNWJF7OLrqrYHsRsukSbUBpvQ== +metro-cache@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.80.9.tgz#b914318a90dbcd51b4c27836184519c441ba5123" + integrity sha512-ujEdSI43QwI+Dj2xuNax8LMo8UgKuXJEdxJkzGPU6iIx42nYa1byQ+aADv/iPh5sh5a//h5FopraW5voXSgm2w== dependencies: - metro-core "0.76.8" + metro-core "0.80.9" rimraf "^3.0.2" -metro-config@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.76.8.tgz#20bd5397fcc6096f98d2a813a7cecb38b8af062d" - integrity sha512-SL1lfKB0qGHALcAk2zBqVgQZpazDYvYFGwCK1ikz0S6Y/CM2i2/HwuZN31kpX6z3mqjv/6KvlzaKoTb1otuSAA== +metro-config@0.80.9, metro-config@^0.80.3: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.80.9.tgz#4eb6948b0ddc7c38d9d4ba8ddf22a67ca1c2bc06" + integrity sha512-28wW7CqS3eJrunRGnsibWldqgwRP9ywBEf7kg+uzUHkSFJNKPM1K3UNSngHmH0EZjomizqQA2Zi6/y6VdZMolg== dependencies: connect "^3.6.5" cosmiconfig "^5.0.5" - jest-validate "^29.2.1" - metro "0.76.8" - metro-cache "0.76.8" - metro-core "0.76.8" - metro-runtime "0.76.8" + jest-validate "^29.6.3" + metro "0.80.9" + metro-cache "0.80.9" + metro-core "0.80.9" + metro-runtime "0.80.9" -metro-core@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.76.8.tgz#917c8157c63406cb223522835abb8e7c6291dcad" - integrity sha512-sl2QLFI3d1b1XUUGxwzw/KbaXXU/bvFYrSKz6Sg19AdYGWFyzsgZ1VISRIDf+HWm4R/TJXluhWMEkEtZuqi3qA== +metro-core@0.80.9, metro-core@^0.80.3: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.80.9.tgz#3af21d0b09d71ec9c0840f028bffb36bc3619727" + integrity sha512-tbltWQn+XTdULkGdzHIxlxk4SdnKxttvQQV3wpqqFbHDteR4gwCyTR2RyYJvxgU7HELfHtrVbqgqAdlPByUSbg== dependencies: lodash.throttle "^4.1.1" - metro-resolver "0.76.8" + metro-resolver "0.80.9" -metro-file-map@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.76.8.tgz#a1db1185b6c316904ba6b53d628e5d1323991d79" - integrity sha512-A/xP1YNEVwO1SUV9/YYo6/Y1MmzhL4ZnVgcJC3VmHp/BYVOXVStzgVbWv2wILe56IIMkfXU+jpXrGKKYhFyHVw== +metro-file-map@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.80.9.tgz#ed8783f6e35dfc005794344c2a9fcd6e914885aa" + integrity sha512-sBUjVtQMHagItJH/wGU9sn3k2u0nrCl0CdR4SFMO1tksXLKbkigyQx4cbpcyPVOAmGTVuy3jyvBlELaGCAhplQ== dependencies: anymatch "^3.0.3" debug "^2.2.0" fb-watchman "^2.0.0" graceful-fs "^4.2.4" invariant "^2.2.4" - jest-regex-util "^27.0.6" - jest-util "^27.2.0" - jest-worker "^27.2.0" + jest-worker "^29.6.3" micromatch "^4.0.4" node-abort-controller "^3.1.1" nullthrows "^1.1.1" @@ -3275,130 +3754,55 @@ metro-file-map@0.76.8: optionalDependencies: fsevents "^2.3.2" -metro-inspector-proxy@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.76.8.tgz#6b8678a7461b0b42f913a7881cc9319b4d3cddff" - integrity sha512-Us5o5UEd4Smgn1+TfHX4LvVPoWVo9VsVMn4Ldbk0g5CQx3Gu0ygc/ei2AKPGTwsOZmKxJeACj7yMH2kgxQP/iw== - dependencies: - connect "^3.6.5" - debug "^2.2.0" - node-fetch "^2.2.0" - ws "^7.5.1" - yargs "^17.6.2" - -metro-minify-terser@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.76.8.tgz#915ab4d1419257fc6a0b9fa15827b83fe69814bf" - integrity sha512-Orbvg18qXHCrSj1KbaeSDVYRy/gkro2PC7Fy2tDSH1c9RB4aH8tuMOIXnKJE+1SXxBtjWmQ5Yirwkth2DyyEZA== +metro-minify-terser@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.80.9.tgz#2b7798cba2bd4bd69cc5ce05a45bf66291542f83" + integrity sha512-FEeCeFbkvvPuhjixZ1FYrXtO0araTpV6UbcnGgDUpH7s7eR5FG/PiJz3TsuuPP/HwCK19cZtQydcA2QrCw446A== dependencies: terser "^5.15.0" -metro-minify-uglify@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.76.8.tgz#74745045ea2dd29f8783db483b2fce58385ba695" - integrity sha512-6l8/bEvtVaTSuhG1FqS0+Mc8lZ3Bl4RI8SeRIifVLC21eeSDp4CEBUWSGjpFyUDfi6R5dXzYaFnSgMNyfxADiQ== - dependencies: - uglify-es "^3.1.9" - -metro-react-native-babel-preset@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.76.8.tgz#7476efae14363cbdfeeec403b4f01d7348e6c048" - integrity sha512-Ptza08GgqzxEdK8apYsjTx2S8WDUlS2ilBlu9DR1CUcHmg4g3kOkFylZroogVAUKtpYQNYwAvdsjmrSdDNtiAg== - dependencies: - "@babel/core" "^7.20.0" - "@babel/plugin-proposal-async-generator-functions" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.18.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.0" - "@babel/plugin-proposal-numeric-separator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.20.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.20.0" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.18.0" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-syntax-optional-chaining" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.20.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.20.0" - "@babel/plugin-transform-flow-strip-types" "^7.20.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-self" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.5.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - babel-plugin-transform-flow-enums "^0.0.2" - react-refresh "^0.4.0" - -metro-react-native-babel-transformer@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.76.8.tgz#c3a98e1f4cd5faf1e21eba8e004b94a90c4db69b" - integrity sha512-3h+LfS1WG1PAzhq8QF0kfXjxuXetbY/lgz8vYMQhgrMMp17WM1DNJD0gjx8tOGYbpbBC1qesJ45KMS4o5TA73A== - dependencies: - "@babel/core" "^7.20.0" - babel-preset-fbjs "^3.4.0" - hermes-parser "0.12.0" - metro-react-native-babel-preset "0.76.8" - nullthrows "^1.1.1" - -metro-resolver@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.76.8.tgz#0862755b9b84e26853978322464fb37c6fdad76d" - integrity sha512-KccOqc10vrzS7ZhG2NSnL2dh3uVydarB7nOhjreQ7C4zyWuiW9XpLC4h47KtGQv3Rnv/NDLJYeDqaJ4/+140HQ== +metro-resolver@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.80.9.tgz#bae9120a0553e0cb59da6429e83a7e97465cc1a8" + integrity sha512-wAPIjkN59BQN6gocVsAvvpZ1+LQkkqUaswlT++cJafE/e54GoVkMNCmrR4BsgQHr9DknZ5Um/nKueeN7kaEz9w== -metro-runtime@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.76.8.tgz#74b2d301a2be5f3bbde91b8f1312106f8ffe50c3" - integrity sha512-XKahvB+iuYJSCr3QqCpROli4B4zASAYpkK+j3a0CJmokxCDNbgyI4Fp88uIL6rNaZfN0Mv35S0b99SdFXIfHjg== +metro-runtime@0.80.9, metro-runtime@^0.80.3: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.80.9.tgz#665312bd4e4d38fea921b3153d6ab47846eb4f08" + integrity sha512-8PTVIgrVcyU+X/rVCy/9yxNlvXsBCk5JwwkbAm/Dm+Abo6NBGtNjWF0M1Xo/NWCb4phamNWcD7cHdR91HhbJvg== dependencies: "@babel/runtime" "^7.0.0" - react-refresh "^0.4.0" -metro-source-map@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.76.8.tgz#f085800152a6ba0b41ca26833874d31ec36c5a53" - integrity sha512-Hh0ncPsHPVf6wXQSqJqB3K9Zbudht4aUtNpNXYXSxH+pteWqGAXnjtPsRAnCsCWl38wL0jYF0rJDdMajUI3BDw== +metro-source-map@0.80.9, metro-source-map@^0.80.3: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.80.9.tgz#df8f673137548f37ab9f9dcfa771b354a452cfab" + integrity sha512-RMn+XS4VTJIwMPOUSj61xlxgBvPeY4G6s5uIn6kt6HB6A/k9ekhr65UkkDD7WzHYs3a9o869qU8tvOZvqeQzgw== dependencies: "@babel/traverse" "^7.20.0" "@babel/types" "^7.20.0" invariant "^2.2.4" - metro-symbolicate "0.76.8" + metro-symbolicate "0.80.9" nullthrows "^1.1.1" - ob1 "0.76.8" + ob1 "0.80.9" source-map "^0.5.6" vlq "^1.0.0" -metro-symbolicate@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.76.8.tgz#f102ac1a306d51597ecc8fdf961c0a88bddbca03" - integrity sha512-LrRL3uy2VkzrIXVlxoPtqb40J6Bf1mlPNmUQewipc3qfKKFgtPHBackqDy1YL0njDsWopCKcfGtFYLn0PTUn3w== +metro-symbolicate@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.80.9.tgz#8d1d19d26ebb36b9d13dbd29814fdd71d6009db7" + integrity sha512-Ykae12rdqSs98hg41RKEToojuIW85wNdmSe/eHUgMkzbvCFNVgcC0w3dKZEhSsqQOXapXRlLtHkaHLil0UD/EA== dependencies: invariant "^2.2.4" - metro-source-map "0.76.8" + metro-source-map "0.80.9" nullthrows "^1.1.1" source-map "^0.5.6" through2 "^2.0.1" vlq "^1.0.0" -metro-transform-plugins@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.76.8.tgz#d77c28a6547a8e3b72250f740fcfbd7f5408f8ba" - integrity sha512-PlkGTQNqS51Bx4vuufSQCdSn2R2rt7korzngo+b5GCkeX5pjinPjnO2kNhQ8l+5bO0iUD/WZ9nsM2PGGKIkWFA== +metro-transform-plugins@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.80.9.tgz#473a2c0a9e48043210547abe61cdeedb77725422" + integrity sha512-UlDk/uc8UdfLNJhPbF3tvwajyuuygBcyp+yBuS/q0z3QSuN/EbLllY3rK8OTD9n4h00qZ/qgxGv/lMFJkwP4vg== dependencies: "@babel/core" "^7.20.0" "@babel/generator" "^7.20.0" @@ -3406,28 +3810,28 @@ metro-transform-plugins@0.76.8: "@babel/traverse" "^7.20.0" nullthrows "^1.1.1" -metro-transform-worker@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.76.8.tgz#b9012a196cee205170d0c899b8b175b9305acdea" - integrity sha512-mE1fxVAnJKmwwJyDtThildxxos9+DGs9+vTrx2ktSFMEVTtXS/bIv2W6hux1pqivqAfyJpTeACXHk5u2DgGvIQ== +metro-transform-worker@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.80.9.tgz#f1d8ef4f77228bb7e1d20d3c06934166e8ee3b28" + integrity sha512-c/IrzMUVnI0hSVVit4TXzt3A1GiUltGVlzCmLJWxNrBGHGrJhvgePj38+GXl1Xf4Fd4vx6qLUkKMQ3ux73bFLQ== dependencies: "@babel/core" "^7.20.0" "@babel/generator" "^7.20.0" "@babel/parser" "^7.20.0" "@babel/types" "^7.20.0" - babel-preset-fbjs "^3.4.0" - metro "0.76.8" - metro-babel-transformer "0.76.8" - metro-cache "0.76.8" - metro-cache-key "0.76.8" - metro-source-map "0.76.8" - metro-transform-plugins "0.76.8" + metro "0.80.9" + metro-babel-transformer "0.80.9" + metro-cache "0.80.9" + metro-cache-key "0.80.9" + metro-minify-terser "0.80.9" + metro-source-map "0.80.9" + metro-transform-plugins "0.80.9" nullthrows "^1.1.1" -metro@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.76.8.tgz#ba526808b99977ca3f9ac5a7432fd02a340d13a6" - integrity sha512-oQA3gLzrrYv3qKtuWArMgHPbHu8odZOD9AoavrqSFllkPgOtmkBvNNDLCELqv5SjBfqjISNffypg+5UGG3y0pg== +metro@0.80.9, metro@^0.80.3: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.80.9.tgz#de3c2011df62036520d51d040d2dde0d015aecb6" + integrity sha512-Bc57Xf3GO2Xe4UWQsBj/oW6YfLPABEu8jfDVDiNmJvoQW4CO34oDPuYKe4KlXzXhcuNsqOtSxpbjCRRVjhhREg== dependencies: "@babel/code-frame" "^7.0.0" "@babel/core" "^7.20.0" @@ -3437,7 +3841,6 @@ metro@0.76.8: "@babel/traverse" "^7.20.0" "@babel/types" "^7.20.0" accepts "^1.3.7" - async "^3.2.2" chalk "^4.0.0" ci-info "^2.0.0" connect "^3.6.5" @@ -3445,28 +3848,24 @@ metro@0.76.8: denodeify "^1.2.1" error-stack-parser "^2.0.6" graceful-fs "^4.2.4" - hermes-parser "0.12.0" + hermes-parser "0.20.1" image-size "^1.0.2" invariant "^2.2.4" - jest-worker "^27.2.0" + jest-worker "^29.6.3" jsc-safe-url "^0.2.2" lodash.throttle "^4.1.1" - metro-babel-transformer "0.76.8" - metro-cache "0.76.8" - metro-cache-key "0.76.8" - metro-config "0.76.8" - metro-core "0.76.8" - metro-file-map "0.76.8" - metro-inspector-proxy "0.76.8" - metro-minify-terser "0.76.8" - metro-minify-uglify "0.76.8" - metro-react-native-babel-preset "0.76.8" - metro-resolver "0.76.8" - metro-runtime "0.76.8" - metro-source-map "0.76.8" - metro-symbolicate "0.76.8" - metro-transform-plugins "0.76.8" - metro-transform-worker "0.76.8" + metro-babel-transformer "0.80.9" + metro-cache "0.80.9" + metro-cache-key "0.80.9" + metro-config "0.80.9" + metro-core "0.80.9" + metro-file-map "0.80.9" + metro-resolver "0.80.9" + metro-runtime "0.80.9" + metro-source-map "0.80.9" + metro-symbolicate "0.80.9" + metro-transform-plugins "0.80.9" + metro-transform-worker "0.80.9" mime-types "^2.1.27" node-fetch "^2.2.0" nullthrows "^1.1.1" @@ -3539,6 +3938,11 @@ mkdirp@^0.5.1: dependencies: minimist "^1.2.6" +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -3581,13 +3985,18 @@ node-dir@^0.1.17: dependencies: minimatch "^3.0.2" -node-fetch@^2.2.0, node-fetch@^2.6.0: +node-fetch@^2.2.0: version "2.6.13" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.13.tgz#a20acbbec73c2e09f9007de5cda17104122e0010" integrity sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA== dependencies: whatwg-url "^5.0.0" +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -3598,6 +4007,11 @@ node-releases@^2.0.13: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== + node-stream-zip@^1.9.1: version "1.15.0" resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.15.0.tgz#158adb88ed8004c6c49a396b50a6a5de3bca33ea" @@ -3620,15 +4034,10 @@ nullthrows@^1.1.1: resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== -ob1@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.76.8.tgz#ac4c459465b1c0e2c29aaa527e09fc463d3ffec8" - integrity sha512-dlBkJJV5M/msj9KYA9upc+nUWVwuOFFTbu28X6kZeGwcuW+JxaHSBZ70SYQnk5M+j5JbNLR6yKHmgW4M5E7X5g== - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== +ob1@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.80.9.tgz#4ae3edd807536097674ff943509089f5d4e0649f" + integrity sha512-v9yOxowkZbxWhKOaaTyLjIm1aLy4ebMNcSn4NYJKOAI/Qv+SkfEfszpLr2GIxsccmb2Y2HA9qtsqiIJ80ucpVA== on-finished@2.4.1: version "2.4.1" @@ -3670,7 +4079,7 @@ open@^6.2.0: dependencies: is-wsl "^1.1.0" -open@^7.4.2: +open@^7.0.3, open@^7.4.2: version "7.4.2" resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== @@ -3760,7 +4169,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -3829,6 +4238,11 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== + picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -3861,12 +4275,12 @@ pretty-format@^26.5.2, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" -pretty-format@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.2.tgz#3d5829261a8a4d89d8b9769064b29c50ed486a47" - integrity sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg== +pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== dependencies: - "@jest/schemas" "^29.6.0" + "@jest/schemas" "^29.6.3" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -3882,7 +4296,7 @@ promise@^8.3.0: dependencies: asap "~2.0.6" -prompts@^2.4.0, prompts@^2.4.2: +prompts@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== @@ -3890,15 +4304,6 @@ prompts@^2.4.0, prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.8.1: - version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -3924,29 +4329,24 @@ range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -react-devtools-core@^4.27.2: - version "4.28.0" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.28.0.tgz#3fa18709b24414adddadac33b6b9cea96db60f2f" - integrity sha512-E3C3X1skWBdBzwpOUbmXG8SgH6BtsluSMe+s6rRcujNKG1DGi8uIfhdhszkgDpAsMoE55hwqRUzeXCmETDBpTg== +react-devtools-core@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-5.3.1.tgz#d57f5b8f74f16e622bd6a7bc270161e4ba162666" + integrity sha512-7FSb9meX0btdBQLwdFOwt6bGqvRPabmVMMslv8fgoSPqXyuGpgQe36kx8gR86XPw7aV1yVouTp6fyZ0EH+NfUw== dependencies: shell-quote "^1.6.1" ws "^7" -"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - -react-is@^16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + react-native-builder-bob@^0.20.4: version "0.20.4" resolved "https://registry.yarnpkg.com/react-native-builder-bob/-/react-native-builder-bob-0.20.4.tgz#02df01b8dc02f1bb2d566f820e33c5d42bfb9c99" @@ -3975,60 +4375,55 @@ react-native-builder-bob@^0.20.4: jetifier "^2.0.0" "react-native@file:../../shared/node_modules/react-native": - version "0.72.7" - dependencies: - "@jest/create-cache-key-function" "^29.2.1" - "@react-native-community/cli" "11.3.10" - "@react-native-community/cli-platform-android" "11.3.10" - "@react-native-community/cli-platform-ios" "11.3.10" - "@react-native/assets-registry" "^0.72.0" - "@react-native/codegen" "^0.72.7" - "@react-native/gradle-plugin" "^0.72.11" - "@react-native/js-polyfills" "^0.72.1" - "@react-native/normalize-colors" "^0.72.0" - "@react-native/virtualized-lists" "^0.72.8" + version "0.75.4" + dependencies: + "@jest/create-cache-key-function" "^29.6.3" + "@react-native-community/cli" "14.1.0" + "@react-native-community/cli-platform-android" "14.1.0" + "@react-native-community/cli-platform-ios" "14.1.0" + "@react-native/assets-registry" "0.75.4" + "@react-native/codegen" "0.75.4" + "@react-native/community-cli-plugin" "0.75.4" + "@react-native/gradle-plugin" "0.75.4" + "@react-native/js-polyfills" "0.75.4" + "@react-native/normalize-colors" "0.75.4" + "@react-native/virtualized-lists" "0.75.4" abort-controller "^3.0.0" anser "^1.4.9" - base64-js "^1.1.2" - deprecated-react-native-prop-types "^4.2.3" + ansi-regex "^5.0.0" + base64-js "^1.5.1" + chalk "^4.0.0" + commander "^9.4.1" event-target-shim "^5.0.1" - flow-enums-runtime "^0.0.5" + flow-enums-runtime "^0.0.6" + glob "^7.1.1" invariant "^2.2.4" - jest-environment-node "^29.2.1" + jest-environment-node "^29.6.3" jsc-android "^250231.0.0" memoize-one "^5.0.0" - metro-runtime "0.76.8" - metro-source-map "0.76.8" + metro-runtime "^0.80.3" + metro-source-map "^0.80.3" mkdirp "^0.5.1" nullthrows "^1.1.1" pretty-format "^26.5.2" promise "^8.3.0" - react-devtools-core "^4.27.2" - react-refresh "^0.4.0" - react-shallow-renderer "^16.15.0" + react-devtools-core "^5.3.1" + react-refresh "^0.14.0" regenerator-runtime "^0.13.2" scheduler "0.24.0-canary-efb381bbf-20230505" + semver "^7.1.3" stacktrace-parser "^0.1.10" - use-sync-external-store "^1.0.0" whatwg-fetch "^3.0.0" ws "^6.2.2" yargs "^17.6.2" -react-refresh@^0.4.0: - version "0.4.3" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.3.tgz#966f1750c191672e76e16c2efa569150cc73ab53" - integrity sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA== - -react-shallow-renderer@^16.15.0: - version "16.15.0" - resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457" - integrity sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA== - dependencies: - object-assign "^4.1.1" - react-is "^16.12.0 || ^17.0.0 || ^18.0.0" +react-refresh@^0.14.0: + version "0.14.2" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" + integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== "react@file:../../shared/node_modules/react": - version "18.2.0" + version "18.3.1" dependencies: loose-envify "^1.1.0" @@ -4204,6 +4599,14 @@ scheduler@0.24.0-canary-efb381bbf-20230505: dependencies: loose-envify "^1.1.0" +selfsigned@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== + dependencies: + "@types/node-forge" "^1.3.0" + node-forge "^1" + semver@^5.6.0: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" @@ -4214,6 +4617,11 @@ semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.1.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + semver@^7.5.2, semver@^7.5.3: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" @@ -4336,11 +4744,6 @@ source-map@^0.6.0, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3: - version "0.7.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -4533,15 +4936,7 @@ type-fest@^0.7.1: integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== "typescript@file:../../shared/node_modules/typescript": - version "5.3.2" - -uglify-es@^3.1.9: - version "3.3.9" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" - integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ== - dependencies: - commander "~2.13.0" - source-map "~0.6.1" + version "5.6.3" unc-path-regex@^0.1.2: version "0.1.2" @@ -4594,10 +4989,13 @@ update-browserslist-db@^1.0.11: escalade "^3.1.1" picocolors "^1.0.0" -use-sync-external-store@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" - integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" @@ -4702,6 +5100,13 @@ ws@^6.2.2: dependencies: async-limiter "~1.0.0" +ws@^6.2.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.3.tgz#ccc96e4add5fd6fedbc491903075c85c5a11d9ee" + integrity sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA== + dependencies: + async-limiter "~1.0.0" + ws@^7, ws@^7.5.1: version "7.5.9" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" diff --git a/rnmodules/react-native-kb/android/build.gradle b/rnmodules/react-native-kb/android/build.gradle index a08caf35df2a..3b8914061158 100644 --- a/rnmodules/react-native-kb/android/build.gradle +++ b/rnmodules/react-native-kb/android/build.gradle @@ -1,4 +1,7 @@ buildscript { + // Buildscript is evaluated before everything else so we can't use getExtOrDefault + def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["DropView_kotlinVersion"] + repositories { google() mavenCentral() @@ -6,6 +9,8 @@ buildscript { dependencies { classpath "com.android.tools.build:gradle:7.2.1" + // noinspection DifferentKotlinGradleVersion + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -21,7 +26,7 @@ def isNewArchitectureEnabled() { } apply plugin: "com.android.library" - +apply plugin: "kotlin-android" def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') } @@ -126,13 +131,15 @@ repositories { google() } +def kotlin_version = getExtOrDefault("kotlinVersion") dependencies { // For < 0.71, this will be from the local maven repo // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:+" - implementation "com.google.firebase:firebase-messaging:22.0.0" + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation "com.google.firebase:firebase-messaging:24.0.1" implementation "me.leolin:ShortcutBadger:1.1.22@aar" implementation project(':keybaselib') } diff --git a/rnmodules/react-native-kb/android/cpp-adapter.cpp b/rnmodules/react-native-kb/android/cpp-adapter.cpp index b422eb7c9129..f7ed9c8da652 100644 --- a/rnmodules/react-native-kb/android/cpp-adapter.cpp +++ b/rnmodules/react-native-kb/android/cpp-adapter.cpp @@ -42,6 +42,7 @@ void DeferThreadDetach(JNIEnv *env) { } return 0; }(); + static_cast(run_once); // For the callback to actually be executed when a thread exits // we need to associate a non-NULL value with the key on that thread. @@ -109,9 +110,7 @@ void install(facebook::jsi::Runtime &jsiRuntime) { jsiRuntime.global().setProperty(jsiRuntime, "rpcOnGo", std::move(rpcOnGo)); } -extern "C" JNIEXPORT void JNICALL -Java_com_reactnativekb_KbModule_nativeInstallJSI(JNIEnv *env, jobject thiz, - jlong jsi) { +extern "C" JNIEXPORT void JNICALL installJSI(JNIEnv *env, jobject thiz, jlong jsi) { auto runtime = reinterpret_cast(jsi); if (runtime) { install(*runtime); @@ -120,9 +119,7 @@ Java_com_reactnativekb_KbModule_nativeInstallJSI(JNIEnv *env, jobject thiz, java_object = env->NewGlobalRef(thiz); } -extern "C" JNIEXPORT void JNICALL Java_com_reactnativekb_KbModule_nativeEmit( - JNIEnv *env, jclass clazz, jlong jsi, jobject boxedCallInvokerHolder, - jbyteArray data) { +extern "C" JNIEXPORT void JNICALL emit(JNIEnv *env, jclass clazz, jlong jsi, jobject boxedCallInvokerHolder, jbyteArray data) { auto rPtr = reinterpret_cast(jsi); auto &runtime = *rPtr; auto boxedCallInvokerRef = jni::make_local(boxedCallInvokerHolder); @@ -148,3 +145,14 @@ extern "C" JNIEXPORT void JNICALL Java_com_reactnativekb_KbModule_nativeEmit( }); }); } + +static JNINativeMethod methods[] = { + {"installJSI", "(J)V", (void *)&installJSI}, + {"emit", "(JLcom/facebook/react/turbomodule/core/CallInvokerHolderImpl;[B)V", (void *)&emit}, +}; + + +extern "C" JNIEXPORT void JNICALL Java_com_reactnativekb_KbModule_registerNatives(JNIEnv *env, jobject thiz, jlong jsi) { + jclass clazz = env->FindClass("com/reactnativekb/KbModule"); + env->RegisterNatives(clazz, methods, sizeof(methods)/sizeof(methods[0])); +} diff --git a/rnmodules/react-native-kb/android/gradle.properties b/rnmodules/react-native-kb/android/gradle.properties index 1a8feb4a016e..1e3c7fd3193d 100644 --- a/rnmodules/react-native-kb/android/gradle.properties +++ b/rnmodules/react-native-kb/android/gradle.properties @@ -1,5 +1,5 @@ -Kb_kotlinVersion=1.7.0 -Kb_minSdkVersion=21 -Kb_targetSdkVersion=31 -Kb_compileSdkVersion=31 -Kb_ndkversion=21.4.7075529 +Kb_kotlinVersion=1.9.24 +Kb_minSdkVersion=23 +Kb_targetSdkVersion=34 +Kb_compileSdkVersion=34 +Kb_ndkversion=26.1.10909125 diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePrefHelper.java b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePrefHelper.java deleted file mode 100644 index 975a89a883f4..000000000000 --- a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePrefHelper.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.reactnativekb; - -public class DarkModePrefHelper { - public static DarkModePreference fromString(String prefString) { - switch (prefString) { - case "alwaysDark": - return DarkModePreference.AlwaysDark; - case "alwaysLight": - return DarkModePreference.AlwaysLight; - default: - return DarkModePreference.System; - } - } -} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePrefHelper.kt b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePrefHelper.kt new file mode 100644 index 000000000000..192bc517d23a --- /dev/null +++ b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePrefHelper.kt @@ -0,0 +1,13 @@ +package com.reactnativekb + +import kotlin.Throws + +object DarkModePrefHelper { + fun fromString(prefString: String): DarkModePreference { + return when (prefString) { + "alwaysDark" -> DarkModePreference.AlwaysDark + "alwaysLight" -> DarkModePreference.AlwaysLight + else -> DarkModePreference.System + } + } +} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePreference.java b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePreference.java deleted file mode 100644 index 439e756b1fb9..000000000000 --- a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePreference.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.reactnativekb; - -public enum DarkModePreference { - System, AlwaysDark, AlwaysLight; -} - diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePreference.kt b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePreference.kt new file mode 100644 index 000000000000..b62b89766471 --- /dev/null +++ b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/DarkModePreference.kt @@ -0,0 +1,9 @@ +package com.reactnativekb + +import kotlin.Throws + +enum class DarkModePreference { + System, + AlwaysDark, + AlwaysLight +} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/GuiConfig.java b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/GuiConfig.java deleted file mode 100644 index ef326e0261d1..000000000000 --- a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/GuiConfig.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.reactnativekb; - -import androidx.annotation.Nullable; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.File; - -public class GuiConfig { - private static GuiConfig singletonInstance = null; - - private File filesDir; - - private GuiConfig(File filesDir) { - this.filesDir = filesDir; - } - - public static GuiConfig getInstance(File filesDir) { - if (singletonInstance == null) { - singletonInstance = new GuiConfig(filesDir); - } - return singletonInstance; - } - - - public String asString() { - File filePath = new File(this.filesDir, "/.config/keybase/gui_config.json"); - return ReadFileAsString.read(filePath.getAbsolutePath()); - } - - public DarkModePreference getDarkMode() { - try { - JSONObject jsonObject = new JSONObject(this.asString()); - JSONObject jsonObjectUI = jsonObject.getJSONObject("ui"); - - String darkModeString = jsonObjectUI.getString("darkMode"); - return DarkModePrefHelper.fromString(darkModeString); - } catch (JSONException e) { - return DarkModePreference.System; - } - } -} - diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/GuiConfig.kt b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/GuiConfig.kt new file mode 100644 index 000000000000..c78a5fd2ebcb --- /dev/null +++ b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/GuiConfig.kt @@ -0,0 +1,42 @@ +package com.reactnativekb + +import androidx.annotation.Nullable + +import org.json.JSONException +import org.json.JSONObject + +import java.io.File + +class GuiConfig private constructor(filesDir: File?) { + private val filesDir: File? + + init { + this.filesDir = filesDir + } + + fun asString(): String? { + val filePath = File(filesDir, "/.config/keybase/gui_config.json") + return ReadFileAsString.read(filePath.getAbsolutePath()) + } + + fun getDarkMode(): DarkModePreference { + return try { + val jsonObject = JSONObject(asString()) + val jsonObjectUI: JSONObject = jsonObject.getJSONObject("ui") + val darkModeString: String = jsonObjectUI.getString("darkMode") + DarkModePrefHelper.fromString(darkModeString) + } catch (e: JSONException) { + DarkModePreference.System + } + } + + companion object { + private var singletonInstance: GuiConfig? = null + fun getInstance(filesDir: File?): GuiConfig? { + if (singletonInstance == null) { + singletonInstance = GuiConfig(filesDir) + } + return singletonInstance + } + } +} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbModule.java b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbModule.java deleted file mode 100644 index b2ca5c8aa64f..000000000000 --- a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbModule.java +++ /dev/null @@ -1,719 +0,0 @@ -package com.reactnativekb; - -import android.app.Activity; -import android.app.DownloadManager; -import android.app.KeyguardManager; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.AssetFileDescriptor; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.provider.Settings; -import android.telephony.TelephonyManager; -import android.text.format.DateFormat; -import android.util.Log; -import android.view.Window; -import android.view.WindowManager; -import androidx.annotation.NonNull; -import androidx.core.app.NotificationManagerCompat; -import androidx.core.content.FileProvider; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.LifecycleEventListener; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.module.annotations.ReactModule; -import com.facebook.react.modules.core.DeviceEventManagerModule; -import com.facebook.react.turbomodule.core.CallInvokerHolderImpl; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.messaging.FirebaseMessagingService; -import com.google.firebase.messaging.FirebaseMessaging; -import com.google.firebase.FirebaseApp; -import com.google.firebase.FirebaseOptions; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import keybase.Keybase; -import me.leolin.shortcutbadger.ShortcutBadger; -import static keybase.Keybase.readArr; -import static keybase.Keybase.version; -import static keybase.Keybase.writeArr; - -public class KbModule extends KbSpec { - public static final String NAME = "Kb"; - private static final String RN_NAME = "ReactNativeJS"; - private static final String RPC_META_EVENT_NAME = "kb-meta-engine-event"; - private static final String RPC_META_EVENT_ENGINE_RESET = "kb-engine-reset"; - private static final int MAX_TEXT_FILE_SIZE = 100 * 1024; // 100 kiB - private static final String LINE_SEPARATOR = System.getProperty("line.separator"); - private Boolean started = false; - private boolean misTestDevice; - private HashMap initialIntent; - private final ReactApplicationContext reactContext; - - private native void nativeInstallJSI(long jsiPtr); - private native void nativeEmit(long jsiPtr, CallInvokerHolderImpl jsInvoker, byte[] data); - private ExecutorService executor; - private Boolean jsiInstalled = false; - - KbModule(ReactApplicationContext reactContext) { - super(reactContext); - this.reactContext = reactContext; - this.misTestDevice = isTestDevice(reactContext); - this.setSecureFlag(); - - reactContext.addLifecycleEventListener(new LifecycleEventListener() { - @Override - public void onHostResume() { - setSecureFlag(); - } - - @Override - public void onHostPause() { } - - @Override - public void onHostDestroy() { } - }); - } - - @Override - @NonNull - public String getName() { - return NAME; - } - - @ReactMethod - public void addListener(String eventName) { } - - @ReactMethod - public void removeListeners(Integer count) { - } - - // Is this a robot controlled test device? (i.e. pre-launch report?) - private static boolean isTestDevice(ReactApplicationContext context) { - String testLabSetting = Settings.System.getString(context.getContentResolver(), "firebase.test.lab"); - return "true".equals(testLabSetting); - } - - /** - * Gets a field from the project's BuildConfig. This is useful when, for example, flavors - * are used at the project level to set custom fields. - * @param context Used to find the correct file - * @param fieldName The name of the field-to-access - * @return The value of the field, or {@code null} if the field is not found. - */ - private Object getBuildConfigValue(String fieldName) { - try { - Class clazz = Class.forName(this.reactContext.getPackageName() + ".BuildConfig"); - Field field = clazz.getField(fieldName); - return field.get(null); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (NoSuchFieldException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - return null; - } - - - private String readGuiConfig() { - return GuiConfig.getInstance(this.reactContext.getFilesDir()).asString(); - } - - // newarch @Override - protected Map getTypedExportedConstants() { - String versionCode = String.valueOf(getBuildConfigValue("VERSION_CODE")); - String versionName = String.valueOf(getBuildConfigValue("VERSION_NAME")); - boolean isDeviceSecure = false; - - try { - final KeyguardManager keyguardManager = (KeyguardManager) this.reactContext.getSystemService(Context.KEYGUARD_SERVICE); - isDeviceSecure = keyguardManager.isKeyguardSecure(); - } catch (Exception e) { - NativeLogger.warn(": Error reading keyguard secure state", e); - } - - String serverConfig = ""; - try { - serverConfig = ReadFileAsString.read(this.reactContext.getCacheDir().getAbsolutePath() + "/Keybase/keybase.app.serverConfig"); - } catch (Exception e) { - NativeLogger.warn(": Error reading server config", e); - } - - String cacheDir = ""; - { - File dir = this.reactContext.getCacheDir(); - if (dir != null) { - cacheDir = dir.getAbsolutePath(); - } - } - - String downloadDir = ""; - { - File dir = this.reactContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); - if (dir != null) { - downloadDir = dir.getAbsolutePath(); - } - } - - final Map constants = new HashMap<>(); - constants.put("androidIsDeviceSecure", isDeviceSecure); - constants.put("androidIsTestDevice", misTestDevice); - constants.put("appVersionCode", versionCode); - constants.put("appVersionName", versionName); - constants.put("darkModeSupported", false); - constants.put("fsCacheDir", cacheDir); - constants.put("fsDownloadDir", downloadDir); - constants.put("guiConfig", readGuiConfig()); - constants.put("serverConfig", serverConfig); - constants.put("uses24HourClock", DateFormat.is24HourFormat(this.reactContext)); - constants.put("version", version()); - return constants; - } - - // country code - @ReactMethod - public void getDefaultCountryCode(Promise promise) { - try { - TelephonyManager tm = (TelephonyManager) this.reactContext.getSystemService(Context.TELEPHONY_SERVICE); - String countryCode = tm.getNetworkCountryIso(); - promise.resolve(countryCode); - } catch (Exception e) { - promise.reject(e); - } - } - - // Logging - @ReactMethod - public void logSend(String status, String feedback, boolean sendLogs, boolean sendMaxBytes, String traceDir, String cpuProfileDir, Promise promise) { - if (misTestDevice) { - return; - } - try { - final String logID = Keybase.logSend(status, feedback, sendLogs, sendMaxBytes, traceDir, cpuProfileDir); - promise.resolve(logID); - } catch (Exception e) { - promise.reject(e); - } - } - - // Settings - @ReactMethod - public void androidOpenSettings() { - Intent intent = new Intent(); - intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); - Uri uri = Uri.fromParts("package", reactContext.getPackageName(), null); - intent.setData(uri); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - reactContext.startActivity(intent); - } - - // Screen protector - @ReactMethod - public void androidSetSecureFlagSetting(boolean setSecure, Promise promise) { - final SharedPreferences prefs = reactContext.getSharedPreferences("SecureFlag", Context.MODE_PRIVATE); - final boolean success = prefs.edit().putBoolean("setSecure", setSecure).commit(); - promise.resolve(success); - setSecureFlag(); - } - - @ReactMethod - public void androidGetSecureFlagSetting(Promise promise) { - final SharedPreferences prefs = this.reactContext.getSharedPreferences("SecureFlag", Context.MODE_PRIVATE); - final boolean setSecure = prefs.getBoolean("setSecure", !misTestDevice); - promise.resolve(setSecure); - } - - private void setSecureFlag() { - final SharedPreferences prefs = this.reactContext.getSharedPreferences("SecureFlag", Context.MODE_PRIVATE); - final boolean setSecure = prefs.getBoolean("setSecure", !misTestDevice); - final Activity activity = this.reactContext.getCurrentActivity(); - if (activity != null) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - final Window window = activity.getWindow(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && setSecure) { - window.addFlags(WindowManager.LayoutParams.FLAG_SECURE); - } else { - window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE); - } - } - }); - } - } - - // Sharing - @ReactMethod - public void androidShare(String uriPath, String mimeType, Promise promise) { - File file = new File(uriPath); - Intent intent = new Intent(Intent.ACTION_SEND).setType(mimeType); - if (mimeType.startsWith("text/")) { - handleTextFileSharing(file, intent, promise); - } else { - handleNonTextFileSharing(file, intent, promise); - } - } - private void handleTextFileSharing(File file, Intent intent, Promise promise) { - try (BufferedReader br = new BufferedReader(new FileReader(file))) { - StringBuilder textBuilder = new StringBuilder(); - String text; - boolean isFirst = true; - - while (textBuilder.length() < MAX_TEXT_FILE_SIZE && (text = br.readLine()) != null) { - if (!isFirst) { - textBuilder.append(LINE_SEPARATOR); - } - textBuilder.append(text); - isFirst = false; - } - intent.putExtra(Intent.EXTRA_TEXT, textBuilder.toString()); - } catch (FileNotFoundException ex) { - promise.reject(new Exception("File not found")); - return; - } catch (IOException ex) { - promise.reject(new Exception("Error reading the file")); - return; - } - startSharing(intent, promise); - } - - private void handleNonTextFileSharing(File file, Intent intent, Promise promise) { - Uri fileUri = FileProvider.getUriForFile(reactContext, reactContext.getPackageName() + ".fileprovider", file); - intent.putExtra(Intent.EXTRA_STREAM, fileUri); - startSharing(intent, promise); - } - - private void startSharing(Intent intent, Promise promise) { - if (intent.resolveActivity(reactContext.getPackageManager()) != null) { - Intent chooser = Intent.createChooser(intent, "Send to"); - // Android 5.1.1 fails `startActivity` below without this flag in the Intent. - chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - reactContext.startActivity(chooser); - promise.resolve(true); - } else { - promise.reject(new Exception("Invalid chooser")); - } - } - - @ReactMethod - public void androidShareText(String text, String mimeType, Promise promise) { - Intent intent = new Intent(Intent.ACTION_SEND).setType(mimeType); - intent.putExtra(Intent.EXTRA_TEXT, text); - - if (intent.resolveActivity(reactContext.getPackageManager()) != null) { - Intent chooser = Intent.createChooser(intent, "Send to"); - // Android 5.1.1 fails `startActivity` below without this flag in the Intent. - chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - reactContext.startActivity(chooser); - promise.resolve(true); - } else { - promise.reject(new Exception("Invalid chooser")); - } - } - - // Push - - @ReactMethod - public void androidCheckPushPermissions(Promise promise) { - NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this.reactContext); - promise.resolve(managerCompat.areNotificationsEnabled()); - } - - @ReactMethod - public void androidRequestPushPermissions(Promise promise) { - this.ensureFirebase(); - androidCheckPushPermissions(promise); - } - - private void ensureFirebase() { - boolean firebaseInitialized = FirebaseApp.getApps(this.reactContext).size() == 1; - if (!firebaseInitialized) { - FirebaseApp.initializeApp(this.reactContext, - new FirebaseOptions.Builder() - .setApplicationId(String.valueOf(getBuildConfigValue("APPLICATION_ID"))) - .setProjectId("keybase-c30fb") - .setGcmSenderId("9603251415") - .build() - ); - } - } - - @ReactMethod - public void androidGetRegistrationToken(Promise promise) { - this.ensureFirebase(); - FirebaseMessaging.getInstance().getToken() - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@NonNull Task task) { - if (!task.isSuccessful()) { - NativeLogger.info("Fetching FCM registration token failed " + task.getException()); - promise.reject(task.getException()); - return; - } - - // Get new FCM registration token - String token = task.getResult(); - NativeLogger.info("Got token: " + token); - promise.resolve(token); - } - }); - } - - // Unlink - - private void deleteRecursive(File fileOrDirectory) throws IOException { - if (fileOrDirectory.isDirectory()) { - File[] files = fileOrDirectory.listFiles(); - if (files == null) { - throw new NullPointerException("Received null trying to list files of directory '" + fileOrDirectory + "'"); - } else { - for (File child : files) { - deleteRecursive(child); - } - } - } - boolean result = fileOrDirectory.delete(); - if (!result) { - throw new IOException("Failed to delete '" + fileOrDirectory + "'"); - } - } - - private static final String FILE_PREFIX_BUNDLE_ASSET = "bundle-assets://"; - - private boolean isAsset(String path) { - return path != null && path.startsWith(FILE_PREFIX_BUNDLE_ASSET); - } - - private String normalizePath(String path) { - if (path == null) - return null; - if (!path.matches("\\w+\\:.*")) - return path; - if (path.startsWith("file://")) { - return path.replace("file://", ""); - } - - Uri uri = Uri.parse(path); - if (path.startsWith(FILE_PREFIX_BUNDLE_ASSET)) { - return path; - } else - return PathResolver.getRealPathFromURI(this.reactContext, uri); - } - - @ReactMethod - public void androidUnlink(String path, Promise promise) { - try { - String normalizedPath = this.normalizePath(path); - this.deleteRecursive(new File(normalizedPath)); - promise.resolve(true); - } catch (Exception err) { - promise.reject("EUNSPECIFIED", err.getLocalizedMessage()); - } - } - - // download - - private WritableMap statFile(String path) { - try { - path = this.normalizePath(path); - WritableMap stat = Arguments.createMap(); - if (this.isAsset(path)) { - String name = path.replace(FILE_PREFIX_BUNDLE_ASSET, ""); - AssetFileDescriptor fd = this.reactContext.getAssets().openFd(name); - stat.putString("filename", name); - stat.putString("path", path); - stat.putString("type", "asset"); - stat.putString("size", String.valueOf(fd.getLength())); - stat.putInt("lastModified", 0); - } else { - File target = new File(path); - if (!target.exists()) { - return null; - } - stat.putString("filename", target.getName()); - stat.putString("path", target.getPath()); - stat.putString("type", target.isDirectory() ? "directory" : "file"); - stat.putString("size", String.valueOf(target.length())); - String lastModified = String.valueOf(target.lastModified()); - stat.putString("lastModified", lastModified); - - } - return stat; - } catch (Exception err) { - return null; - } - } - - @ReactMethod - public void androidAddCompleteDownload(ReadableMap config, Promise promise) { - DownloadManager dm = (DownloadManager) this.reactContext.getSystemService(this.reactContext.DOWNLOAD_SERVICE); - if (config == null || !config.hasKey("path")) { - promise.reject("EINVAL", "addCompleteDownload config or path missing."); - return; - } - String path = this.normalizePath(config.getString("path")); - if (path == null) { - promise.reject("EINVAL", "addCompleteDownload can not resolve URI:" + config.getString("path")); - return; - } - try { - WritableMap stat = statFile(path); - dm.addCompletedDownload( - config.hasKey("title") ? config.getString("title") : "", - config.hasKey("description") ? config.getString("description") : "", - true, - config.hasKey("mime") ? config.getString("mime") : null, - path, - Long.valueOf(stat.getString("size")), - config.hasKey("showNotification") && config.getBoolean("showNotification") - ); - promise.resolve(null); - } catch (Exception ex) { - promise.reject("EUNSPECIFIED", ex.getLocalizedMessage()); - } - } - - // Dark mode - // Same type as DarkModePreference: 'system' | 'alwaysDark' | 'alwaysLight' - @ReactMethod - public void androidAppColorSchemeChanged(String prefString) { - try { - final Activity activity = this.reactContext.getCurrentActivity(); - if (activity != null) { - Method m = activity.getClass().getMethod("setBackgroundColor", DarkModePreference.class); - final DarkModePreference pref = DarkModePrefHelper.fromString(prefString); - m.invoke(activity, pref); - } - } catch (Exception ex) { - } - } - - // Badging - - @ReactMethod - public void androidSetApplicationIconBadgeNumber(double badge) { - ShortcutBadger.applyCount(this.reactContext, (int)badge); - } - - - // init bundles - // This isn't related to the Go Engine, but it's a small thing that wouldn't be worth putting in - // its own react module. That's because starting up a react module is a bit expensive and we - // wouldn't be able to lazy load this because we need it on startup. - @ReactMethod - public void androidGetInitialBundleFromNotification(Promise promise) { - try { - final Activity activity = this.reactContext.getCurrentActivity(); - if (activity != null) { - Method m = activity.getClass().getMethod("getInitialBundleFromNotification"); - Bundle initialBundleFromNotification = (Bundle)(m.invoke(activity)); - if (initialBundleFromNotification != null) { - WritableMap map = Arguments.fromBundle(initialBundleFromNotification); - promise.resolve(map); - return; - } - } - } catch (Exception ex){ } - - promise.resolve(null); - } - - @ReactMethod - public void androidGetInitialShareFileUrls(Promise promise) { - try { - final Activity activity = this.reactContext.getCurrentActivity(); - if (activity != null) { - Method m = activity.getClass().getMethod("getInitialShareFileUrls"); - Object o = m.invoke(activity); - if (o != null && o instanceof String[]) { - String[] us = (String[]) o; - WritableArray writableArray = Arguments.createArray(); - for (String str : us) { - writableArray.pushString(str); - } - promise.resolve(writableArray); - return; - } - } - } catch (Exception ex){ - Log.d("androidGetInitialShareFileUrl exception", ex.toString()); - } - promise.resolve(""); - } - - @ReactMethod - public void androidGetInitialShareText(Promise promise) { - try { - final Activity activity = this.reactContext.getCurrentActivity(); - if (activity != null) { - Method m = activity.getClass().getMethod("getInitialShareText"); - Object shareText = m.invoke(activity); - if (shareText != null) { - promise.resolve(String.valueOf(shareText)); - return; - } - } - } catch (Exception ex){} - promise.resolve(""); - } - - // engine - private static void relayReset(ReactApplicationContext reactContext) { - if (!reactContext.hasActiveCatalystInstance()) { - NativeLogger.info(NAME + ": JS Bridge is dead, Can't send EOF message"); - } else { - reactContext - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) - .emit(RPC_META_EVENT_NAME, RPC_META_EVENT_ENGINE_RESET); - } - } - - @ReactMethod(isBlockingSynchronousMethod = true) - public void install() { - try { - System.loadLibrary("cpp"); - jsiInstalled = true; - this.nativeInstallJSI(this.reactContext.getJavaScriptContextHolder().get()); - } catch (Exception exception) { - NativeLogger.error("Exception in installJSI", exception); - } - } - - @ReactMethod - public void engineReset() { - try { - Keybase.reset(); - relayReset(reactContext); - } catch (Exception e) { - NativeLogger.error("Exception in engineReset", e); - } - } - - @ReactMethod - public void engineStart() { - NativeLogger.info("KeybaseEngine started"); - try { - started = true; - if (executor == null) { - executor = Executors.newSingleThreadExecutor(); - executor.execute(new ReadFromKBLib(this.reactContext)); - } - } catch (Exception e) { - NativeLogger.error("Exception in engineStart", e); - } - } - -// JSI - private class ReadFromKBLib implements Runnable { - private final ReactApplicationContext reactContext; - - public ReadFromKBLib(ReactApplicationContext reactContext) { - this.reactContext = reactContext; - - reactContext.addLifecycleEventListener(new LifecycleEventListener() { - @Override - public void onHostResume() { - if (executor == null) { - executor = Executors.newSingleThreadExecutor(); - executor.execute(new ReadFromKBLib(reactContext)); - } - } - - @Override - public void onHostPause() { - } - - @Override - public void onHostDestroy() { - destroy(); - } - }); - } - - @Override - public void run() { - do { - try { - - Thread.currentThread().setName("ReadFromKBLib"); - final byte[] data = readArr(); - - if (!reactContext.hasActiveCatalystInstance()) { - NativeLogger.info(NAME + ": JS Bridge is dead, dropping engine message: " + data); - } - - CallInvokerHolderImpl callInvoker = (CallInvokerHolderImpl) reactContext.getCatalystInstance().getJSCallInvokerHolder(); - nativeEmit(reactContext.getJavaScriptContextHolder().get(), callInvoker, data); - } catch (Exception e) { - if (e.getMessage() != null && e.getMessage().equals("Read error: EOF")) { - NativeLogger.info("Got EOF from read. Likely because of reset."); - } else { - NativeLogger.error("Exception in ReadFromKBLib.run", e); - } - } - } while (!Thread.currentThread().isInterrupted() && reactContext.hasActiveCatalystInstance()); - } - } - - public void destroy() { - try { - Keybase.reset(); - relayReset(reactContext); - } catch (Exception e) { - NativeLogger.error("Exception in KeybaseEngine.destroy", e); - } - - try { - if (executor != null) { - executor.shutdownNow(); - } - - // We often hit this timeout during app resume, e.g. hit the back - // button to go to home screen and then tap Keybase app icon again. - if (executor != null && !executor.awaitTermination(3, TimeUnit.SECONDS)) { - NativeLogger.warn(NAME + ": Executor pool didn't shut down cleanly"); - } - executor = null; - } catch (Exception e) { - NativeLogger.error("Exception in JSI.destroy", e); - } - } - - @ReactMethod - public void rpcOnGo(byte[] arr) { - try { - writeArr(arr); - } catch (Exception e) { - NativeLogger.error("Exception in GoJSIBridge.rpcOnGo", e); - } - } - - - @ReactMethod - public void iosGetHasShownPushPrompt(Promise promise) { - promise.reject(new Exception("wrong platform")); - } -} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbModule.kt b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbModule.kt new file mode 100644 index 000000000000..a8edcde27faa --- /dev/null +++ b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbModule.kt @@ -0,0 +1,731 @@ +package com.reactnativekb + +import android.app.Activity +import android.app.DownloadManager +import android.app.KeyguardManager +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.content.res.AssetFileDescriptor +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.os.Environment +import android.provider.Settings +import android.telephony.TelephonyManager +import android.text.format.DateFormat +import android.util.Log +import android.view.Window +import android.view.WindowManager +import androidx.core.app.NotificationManagerCompat +import androidx.core.content.FileProvider +import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.LifecycleEventListener +import com.facebook.react.bridge.Promise +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReactContextBaseJavaModule +import com.facebook.react.bridge.ReactContext +import com.facebook.react.bridge.ReactMethod +import com.facebook.react.bridge.ReadableMap +import com.facebook.react.bridge.WritableArray +import com.facebook.react.bridge.WritableMap +import com.facebook.react.module.annotations.ReactModule +import com.facebook.react.modules.core.DeviceEventManagerModule +import com.facebook.react.turbomodule.core.CallInvokerHolderImpl +import com.google.android.gms.tasks.OnCompleteListener +import com.google.android.gms.tasks.Task +import com.google.firebase.messaging.FirebaseMessagingService +import com.google.firebase.messaging.FirebaseMessaging +import com.google.firebase.FirebaseApp +import com.google.firebase.FirebaseOptions +import java.io.BufferedReader +import java.io.File +import java.io.FileNotFoundException +import java.io.FileReader +import java.io.IOException +import java.io.InputStreamReader +import java.lang.reflect.Field +import java.lang.reflect.Method +import java.util.HashMap +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit +import java.util.regex.Matcher +import java.util.regex.Pattern +import keybase.Keybase +import me.leolin.shortcutbadger.ShortcutBadger +import keybase.Keybase.readArr +import keybase.Keybase.version +import keybase.Keybase.writeArr +import com.facebook.react.common.annotations.FrameworkAPI + +@OptIn(FrameworkAPI::class) +internal class KbModule(reactContext: ReactApplicationContext?) : KbSpec(reactContext) { + private var started: Boolean? = false + private val misTestDevice: Boolean + private val initialIntent: HashMap? = null + private val reactContext: ReactApplicationContext + private external fun registerNatives(jsiPtr: Long) + private external fun installJSI(jsiPtr: Long) + private external fun emit(jsiPtr: Long, jsInvoker: CallInvokerHolderImpl?, data: ByteArray?) + private var executor: ExecutorService? = null + private var jsiInstalled: Boolean? = false + + override fun getName(): String { + return NAME + } + + @ReactMethod + override fun addListener(eventName: String) { + } + + @ReactMethod + override fun removeListeners(count: Double) { + } + + /** + * Gets a field from the project's BuildConfig. This is useful when, for example, flavors + * are used at the project level to set custom fields. + * @param context Used to find the correct file + * @param fieldName The name of the field-to-access + * @return The value of the field, or `null` if the field is not found. + */ + private fun getBuildConfigValue(fieldName: String): Any? { + try { + val clazz: Class<*> = Class.forName(reactContext.getPackageName() + ".BuildConfig") + val field = clazz.getField(fieldName) + return field.get(null) + } catch (e: ClassNotFoundException) { + e.printStackTrace() + } catch (e: NoSuchFieldException) { + e.printStackTrace() + } catch (e: IllegalAccessException) { + e.printStackTrace() + } + return null + } + + private fun readGuiConfig(): String? { + return GuiConfig.getInstance(reactContext.getFilesDir())?.asString() + } + + + // only old arch, uncomment +// override fun getConstants(): MutableMap? { +// return getTypedExportedConstants() +// } + + // newarch @Override + override fun getTypedExportedConstants(): MutableMap { + val versionCode: String = getBuildConfigValue("VERSION_CODE").toString() + val versionName: String = getBuildConfigValue("VERSION_NAME").toString() + var isDeviceSecure = false + try { + val keyguardManager: KeyguardManager = reactContext.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager + isDeviceSecure = keyguardManager.isKeyguardSecure() + } catch (e: Exception) { + NativeLogger.warn(": Error reading keyguard secure state", e) + } + var serverConfig = "" + try { + serverConfig = ReadFileAsString.read(reactContext.getCacheDir().getAbsolutePath() + "/Keybase/keybase.app.serverConfig") + } catch (e: Exception) { + NativeLogger.warn(": Error reading server config", e) + } + var cacheDir = "" + run { + val dir: File? = reactContext.getCacheDir() + if (dir != null) { + cacheDir = dir.getAbsolutePath() + } + } + var downloadDir = "" + run { + val dir: File? = reactContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + if (dir != null) { + downloadDir = dir.getAbsolutePath() + } + } + val constants: MutableMap = HashMap() + constants.put("androidIsDeviceSecure", isDeviceSecure) + constants.put("androidIsTestDevice", misTestDevice) + constants.put("appVersionCode", versionCode) + constants.put("appVersionName", versionName) + constants.put("darkModeSupported", false) + constants.put("fsCacheDir", cacheDir) + constants.put("fsDownloadDir", downloadDir) + constants.put("guiConfig", readGuiConfig() as Any) + constants.put("serverConfig", serverConfig) + constants.put("uses24HourClock", DateFormat.is24HourFormat(reactContext)) + constants.put("version", version()) + return constants + } + + // country code + @ReactMethod + override fun getDefaultCountryCode(promise: Promise) { + try { + val tm: TelephonyManager = reactContext.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager + val countryCode: String = tm.getNetworkCountryIso() + promise.resolve(countryCode) + } catch (e: Exception) { + promise.reject(e) + } + } + + // Logging + @ReactMethod + override fun logSend(status: String, feedback: String, sendLogs: Boolean, sendMaxBytes: Boolean, traceDir: String, cpuProfileDir: String, promise: Promise) { + if (misTestDevice) { + return + } + try { + val logID: String = Keybase.logSend(status, feedback, sendLogs, sendMaxBytes, traceDir, cpuProfileDir) + promise.resolve(logID) + } catch (e: Exception) { + promise.reject(e) + } + } + + // Settings + @ReactMethod + override fun androidOpenSettings() { + val intent = Intent() + intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + val uri: Uri = Uri.fromParts("package", reactContext.getPackageName(), null) + intent.setData(uri) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + reactContext.startActivity(intent) + } + + // Screen protector + @ReactMethod + override fun androidSetSecureFlagSetting(setSecure: Boolean, promise: Promise) { + val prefs: SharedPreferences = reactContext.getSharedPreferences("SecureFlag", Context.MODE_PRIVATE) + val success: Boolean = prefs.edit().putBoolean("setSecure", setSecure).commit() + promise.resolve(success) + setSecureFlag() + } + + @ReactMethod + override fun androidGetSecureFlagSetting(promise: Promise) { + val prefs: SharedPreferences = reactContext.getSharedPreferences("SecureFlag", Context.MODE_PRIVATE) + val setSecure: Boolean = prefs.getBoolean("setSecure", !misTestDevice) + promise.resolve(setSecure) + } + + private fun setSecureFlag() { + val prefs: SharedPreferences = reactContext.getSharedPreferences("SecureFlag", Context.MODE_PRIVATE) + val setSecure: Boolean = prefs.getBoolean("setSecure", !misTestDevice) + val activity: Activity? = reactContext.getCurrentActivity() + if (activity != null) { + activity.runOnUiThread(object : Runnable { + @Override + override fun run() { + val window: Window = activity.getWindow() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && setSecure) { + window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) + } else { + window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) + } + } + }) + } + } + + // Sharing + @ReactMethod + override fun androidShare(uriPath: String, mimeType: String, promise: Promise) { + val file = File(uriPath) + val intent: Intent = Intent(Intent.ACTION_SEND).setType(mimeType) + if (mimeType.startsWith("text/")) { + handleTextFileSharing(file, intent, promise) + } else { + handleNonTextFileSharing(file, intent, promise) + } + } + + private fun handleTextFileSharing(file: File, intent: Intent, promise: Promise) { + try { + BufferedReader(FileReader(file)).use { br -> + val textBuilder = StringBuilder() + var text: String? = null + var isFirst = true + while (textBuilder.length < MAX_TEXT_FILE_SIZE && br.readLine().also { text = it } != null) { + if (!isFirst) { + textBuilder.append(LINE_SEPARATOR) + } + textBuilder.append(text) + isFirst = false + } + intent.putExtra(Intent.EXTRA_TEXT, textBuilder.toString()) + } + } catch (ex: FileNotFoundException) { + promise.reject(Exception("File not found")) + return + } catch (ex: IOException) { + promise.reject(Exception("Error reading the file")) + return + } + startSharing(intent, promise) + } + + private fun handleNonTextFileSharing(file: File, intent: Intent, promise: Promise) { + val fileUri: Uri = FileProvider.getUriForFile(reactContext, reactContext.getPackageName() + ".fileprovider", file) + intent.putExtra(Intent.EXTRA_STREAM, fileUri) + startSharing(intent, promise) + } + + private fun startSharing(intent: Intent, promise: Promise) { + if (intent.resolveActivity(reactContext.getPackageManager()) != null) { + val chooser: Intent = Intent.createChooser(intent, "Send to") + // Android 5.1.1 fails `startActivity` below without this flag in the Intent. + chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + reactContext.startActivity(chooser) + promise.resolve(true) + } else { + promise.reject(Exception("Invalid chooser")) + } + } + + @ReactMethod + override fun androidShareText(text: String, mimeType: String, promise: Promise) { + val intent: Intent = Intent(Intent.ACTION_SEND).setType(mimeType) + intent.putExtra(Intent.EXTRA_TEXT, text) + if (intent.resolveActivity(reactContext.getPackageManager()) != null) { + val chooser: Intent = Intent.createChooser(intent, "Send to") + // Android 5.1.1 fails `startActivity` below without this flag in the Intent. + chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + reactContext.startActivity(chooser) + promise.resolve(true) + } else { + promise.reject(Exception("Invalid chooser")) + } + } + + // Push + @ReactMethod + override fun androidCheckPushPermissions(promise: Promise) { + val managerCompat: NotificationManagerCompat = NotificationManagerCompat.from(reactContext) + promise.resolve(managerCompat.areNotificationsEnabled()) + } + + @ReactMethod + override fun androidRequestPushPermissions(promise: Promise) { + ensureFirebase() + androidCheckPushPermissions(promise) + } + + private fun ensureFirebase() { + val firebaseInitialized = FirebaseApp.getApps(reactContext).size == 1 + if (!firebaseInitialized) { + FirebaseApp.initializeApp(reactContext, + FirebaseOptions.Builder() + .setApplicationId(getBuildConfigValue("APPLICATION_ID").toString()) + .setProjectId("keybase-c30fb") + .setGcmSenderId("9603251415") + .build() + ) + } + } + + @ReactMethod + override fun androidGetRegistrationToken(promise: Promise) { + ensureFirebase() + FirebaseMessaging.getInstance().getToken() + .addOnCompleteListener(OnCompleteListener { task -> + if (!task.isSuccessful()) { + NativeLogger.info("Fetching FCM registration token failed " + task.getException()) + promise.reject(task.getException()) + return@OnCompleteListener + } + + // Get new FCM registration token + val token: String? = task.result + if (token == null) { + promise.reject(task.getException()) + return@OnCompleteListener + } + NativeLogger.info("Got token: $token") + promise.resolve(token) + }) + } + + // Unlink + @Throws(IOException::class) + private fun deleteRecursive(fileOrDirectory: File) { + if (fileOrDirectory.isDirectory()) { + val files = fileOrDirectory.listFiles() + if (files == null) { + throw NullPointerException("Received null trying to list files of directory '$fileOrDirectory'") + } else { + for (child in files) { + deleteRecursive(child) + } + } + } + val result: Boolean = fileOrDirectory.delete() + if (!result) { + throw IOException("Failed to delete '$fileOrDirectory'") + } + } + + init { + this.reactContext = reactContext!! + misTestDevice = isTestDevice(reactContext) + setSecureFlag() + reactContext.addLifecycleEventListener(object : LifecycleEventListener { + @Override + override fun onHostResume() { + setSecureFlag() + } + + @Override + override fun onHostPause() { + } + + @Override + override fun onHostDestroy() { + } + }) + } + + private fun isAsset(path: String): Boolean { + return path.startsWith(FILE_PREFIX_BUNDLE_ASSET) + } + + private fun normalizePath(path: String): String { + if (!Regex("""\w+\:.*""").matches(path)) + if (path.startsWith("file://")) { + return path.replace("file://", "") + } + val uri: Uri = Uri.parse(path) + return if (path.startsWith(FILE_PREFIX_BUNDLE_ASSET)) { + path + } else PathResolver.getRealPathFromURI(reactContext, uri) ?: "" + } + + @ReactMethod + override fun androidUnlink(path: String, promise: Promise) { + try { + val normalizedPath = normalizePath(path) + deleteRecursive(File(normalizedPath)) + promise.resolve(true) + } catch (err: Exception) { + promise.reject("EUNSPECIFIED", err.getLocalizedMessage()) + } + } + + // download + private fun statFile(_path: String): WritableMap? { + var path = _path + return try { + path = normalizePath(path) + val stat: WritableMap = Arguments.createMap() + if (isAsset(path)) { + val name: String = path.replace(FILE_PREFIX_BUNDLE_ASSET, "") + val fd: AssetFileDescriptor = reactContext.getAssets().openFd(name) + stat.putString("filename", name) + stat.putString("path", path) + stat.putString("type", "asset") + stat.putString("size", fd.getLength().toString()) + stat.putInt("lastModified", 0) + } else { + val target = File(path) + if (!target.exists()) { + return null + } + stat.putString("filename", target.getName()) + stat.putString("path", target.getPath()) + stat.putString("type", if (target.isDirectory()) "directory" else "file") + stat.putString("size", target.length().toString()) + val lastModified: String = target.lastModified().toString() + stat.putString("lastModified", lastModified) + } + stat + } catch (err: Exception) { + null + } + } + + @ReactMethod + override fun androidAddCompleteDownload(config: ReadableMap, promise: Promise) { + val dm: DownloadManager = reactContext.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager + if (!config.hasKey("path")) { + promise.reject("EINVAL", "addCompleteDownload config or path missing.") + return + } + val path = normalizePath(config.getString("path") ?: "") + if (path == "") { + promise.reject("EINVAL", "addCompleteDownload can not resolve URI:" + config.getString("path")) + return + } + try { + val stat: WritableMap? = statFile(path) + var size = 0L + if (stat != null) { + val sizeStr = stat.getString("size") + if (sizeStr != null) { + size = sizeStr.toLong() + } + } + dm.addCompletedDownload( + if (config.hasKey("title")) config.getString("title") else "", + if (config.hasKey("description")) config.getString("description") else "", + true, + if (config.hasKey("mime")) config.getString("mime") else null, + path, + size, + config.hasKey("showNotification") && config.getBoolean("showNotification") + ) + promise.resolve(null) + } catch (ex: Exception) { + promise.reject("EUNSPECIFIED", ex.getLocalizedMessage()) + } + } + + // Dark mode + // Same type as DarkModePreference: 'system' | 'alwaysDark' | 'alwaysLight' + @ReactMethod + override fun androidAppColorSchemeChanged(prefString: String) { + try { + val activity: Activity? = reactContext.getCurrentActivity() + if (activity != null) { + val m: Method = activity.javaClass.getMethod("setBackgroundColor", DarkModePreference::class.java) + val pref: DarkModePreference = DarkModePrefHelper.fromString(prefString) + m.invoke(activity, pref) + } + } catch (ex: Exception) { + } + } + + // Badging + @ReactMethod + override fun androidSetApplicationIconBadgeNumber(badge: Double) { + ShortcutBadger.applyCount(reactContext, badge.toInt()) + } + + // init bundles + // This isn't related to the Go Engine, but it's a small thing that wouldn't be worth putting in + // its own react module. That's because starting up a react module is a bit expensive and we + // wouldn't be able to lazy load this because we need it on startup. + @ReactMethod + override fun androidGetInitialBundleFromNotification(promise: Promise) { + try { + val activity: Activity? = reactContext.getCurrentActivity() + if (activity != null) { + val m: Method = activity.javaClass.getMethod("getInitialBundleFromNotification") + val initialBundleFromNotification = m.invoke(activity) as Bundle? + if (initialBundleFromNotification != null) { + val map: WritableMap = Arguments.fromBundle(initialBundleFromNotification) + promise.resolve(map) + return + } + } + } catch (ex: Exception) { + } + promise.resolve(null) + } + + @ReactMethod + override fun androidGetInitialShareFileUrls(promise: Promise) { + try { + val activity: Activity? = reactContext.getCurrentActivity() + if (activity != null) { + val m: Method = activity.javaClass.getMethod("getInitialShareFileUrls") + val o = m.invoke(activity) + if (o != null && o is Array<*>) { + val us = o.filterIsInstance() + val writableArray: WritableArray = Arguments.createArray() + for (str in us) { + writableArray.pushString(str) + } + promise.resolve(writableArray) + return + } + } + } catch (ex: Exception) { + Log.d("ossifrageShare", "androidGetInitialShareFileUrl exception" + ex.toString()) + } + promise.resolve("") + } + + @ReactMethod + override fun androidGetInitialShareText(promise: Promise) { + try { + val activity: Activity? = reactContext.getCurrentActivity() + if (activity != null) { + val m: Method = activity.javaClass.getMethod("getInitialShareText") + val shareText = m.invoke(activity) + if (shareText != null) { + promise.resolve(shareText.toString()) + return + } + } + } catch (ex: Exception) { + } + promise.resolve("") + } + + @ReactMethod(isBlockingSynchronousMethod = true) + override fun install(): Boolean { + try { + System.loadLibrary("cpp") + jsiInstalled = true + val jsi = reactContext.javaScriptContextHolder?.get() + if (jsi != null) { + registerNatives(jsi) + installJSI(jsi) + } else { + throw Exception("No context holder") + } + } catch (exception: Exception) { + NativeLogger.error("Exception in installJSI", exception) + } + return true; + } + + @ReactMethod + override fun engineReset() { + try { + Keybase.reset() + relayReset(reactContext) + } catch (e: Exception) { + NativeLogger.error("Exception in engineReset", e) + } + } + + @ReactMethod + override fun engineStart() { + NativeLogger.info("KeybaseEngine started") + try { + started = true + if (executor == null) { + val ex = Executors.newSingleThreadExecutor() + executor = ex + ex.execute(ReadFromKBLib(reactContext)) + } + } catch (e: Exception) { + NativeLogger.error("Exception in engineStart", e) + } + } + + // JSI + private inner class ReadFromKBLib(reactContext: ReactApplicationContext) : Runnable { + private val reactContext: ReactApplicationContext + + init { + this.reactContext = reactContext + reactContext.addLifecycleEventListener(object : LifecycleEventListener { + @Override + override fun onHostResume() { + if (executor == null) { + val ex = Executors.newSingleThreadExecutor() + executor = ex + ex.execute(ReadFromKBLib(reactContext)) + } + } + + @Override + override fun onHostPause() { + } + + @Override + override fun onHostDestroy() { + destroy() + } + }) + } + + @Override + override fun run() { + do { + try { + Thread.currentThread().setName("ReadFromKBLib") + val data: ByteArray = readArr() + if (!reactContext.hasActiveCatalystInstance()) { + NativeLogger.info(NAME.toString() + ": JS Bridge is dead, dropping engine message: " + data) + + } + + val callInvoker: CallInvokerHolderImpl = reactContext.getJSCallInvokerHolder() as CallInvokerHolderImpl + val jsi = reactContext.javaScriptContextHolder?.get() + if (jsi != null) { + emit(jsi, callInvoker, data) + } else { + throw Exception("No context holder") + } + } catch (e: Exception) { + if (e.message != null && e.message.equals("Read error: EOF")) { + NativeLogger.info("Got EOF from read. Likely because of reset.") + } else { + NativeLogger.error("Exception in ReadFromKBLib.run", e) + } + } + } while (!Thread.currentThread().isInterrupted() && reactContext.hasActiveCatalystInstance()) + } + } + + fun destroy() { + try { + Keybase.reset() + relayReset(reactContext) + } catch (e: Exception) { + NativeLogger.error("Exception in KeybaseEngine.destroy", e) + } + try { + executor?.shutdownNow() + + // We often hit this timeout during app resume, e.g. hit the back + // button to go to home screen and then tap Keybase app icon again. + if (executor?.awaitTermination(3, TimeUnit.SECONDS)== false) { + NativeLogger.warn(NAME.toString() + ": Executor pool didn't shut down cleanly") + } + executor = null + } catch (e: Exception) { + NativeLogger.error("Exception in JSI.destroy", e) + } + } + + @ReactMethod + fun rpcOnGo(arr: ByteArray) { + try { + writeArr(arr) + } catch (e: Exception) { + NativeLogger.error("Exception in GoJSIBridge.rpcOnGo", e) + } + } + + @ReactMethod + override fun iosGetHasShownPushPrompt(promise: Promise) { + promise.reject(Exception("wrong platform")) + } + + companion object { + val NAME: String = "Kb" + private val RN_NAME: String = "ReactNativeJS" + private val RPC_META_EVENT_NAME: String = "kb-meta-engine-event" + private val RPC_META_EVENT_ENGINE_RESET: String = "kb-engine-reset" + private const val MAX_TEXT_FILE_SIZE = 100 * 1024 // 100 kiB + private val LINE_SEPARATOR: String? = System.getProperty("line.separator") + + // Is this a robot controlled test device? (i.e. pre-launch report?) + private fun isTestDevice(context: ReactApplicationContext): Boolean { + val testLabSetting: String? = Settings.System.getString(context.contentResolver, "firebase.test.lab") + return "true".equals(testLabSetting) + } + + private val FILE_PREFIX_BUNDLE_ASSET: String = "bundle-assets://" + + // engine + private fun relayReset(reactContext: ReactApplicationContext) { + if (!reactContext.hasActiveCatalystInstance()) { + NativeLogger.info(NAME.toString() + ": JS Bridge is dead, Can't send EOF message") + } else { + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) + .emit(RPC_META_EVENT_NAME, RPC_META_EVENT_ENGINE_RESET) + } + } + } +} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbPackage.java b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbPackage.java deleted file mode 100644 index d241efe8bd55..000000000000 --- a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbPackage.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.reactnativekb; - -import androidx.annotation.Nullable; - -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.module.model.ReactModuleInfo; -import com.facebook.react.module.model.ReactModuleInfoProvider; -import com.facebook.react.TurboReactPackage; - -import java.util.HashMap; -import java.util.Map; - -public class KbPackage extends TurboReactPackage { - - @Nullable - @Override - public NativeModule getModule(String name, ReactApplicationContext reactContext) { - if (name.equals(KbModule.NAME)) { - return new KbModule(reactContext); - } else { - return null; - } - } - - @Override - public ReactModuleInfoProvider getReactModuleInfoProvider() { - return () -> { - final Map moduleInfos = new HashMap<>(); - boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; - moduleInfos.put( - KbModule.NAME, - new ReactModuleInfo( - KbModule.NAME, - KbModule.NAME, - false, // canOverrideExistingModule - false, // needsEagerInit - true, // hasConstants - false, // isCxxModule - isTurboModule // isTurboModule - )); - return moduleInfos; - }; - } -} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbPackage.kt b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbPackage.kt new file mode 100644 index 000000000000..b2bedca9a217 --- /dev/null +++ b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/KbPackage.kt @@ -0,0 +1,40 @@ +package com.reactnativekb + +import androidx.annotation.Nullable + +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.module.model.ReactModuleInfo +import com.facebook.react.module.model.ReactModuleInfoProvider +import com.facebook.react.TurboReactPackage + +import java.util.HashMap +import java.util.Map + +class KbPackage : TurboReactPackage() { + @Nullable + override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? { + return if (name == KbModule.NAME) { + KbModule(reactContext) + } else { + null + } + } + + override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { + return ReactModuleInfoProvider { + val moduleInfos: MutableMap = HashMap() + val isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED + moduleInfos[KbModule.NAME] = ReactModuleInfo( + KbModule.NAME, + KbModule.NAME, + false, // canOverrideExistingModule + false, // needsEagerInit + true, // hasConstants + false, // isCxxModule + isTurboModule // isTurboModule + ) + moduleInfos + } + } +} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/NativeLogger.java b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/NativeLogger.java deleted file mode 100644 index 524aa9df7403..000000000000 --- a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/NativeLogger.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.reactnativekb; - -import android.util.Log; -import keybase.Keybase; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.WritableArray; - -public class NativeLogger extends ReactContextBaseJavaModule { - private static final String NAME = "NativeLogger"; - private static final String RN_NAME = "ReactNativeJS"; - - public static void rawLog(String tag, String jsonLog) { - Log.i(tag + NAME, jsonLog); - } - - private static String formatLine(String tagPrefix, String toLog) { - // Copies the Style JS outputs in native/logger.native.tsx - return tagPrefix + NAME + ": [" + System.currentTimeMillis() + ",\"" + toLog + "\"]"; - } - - public static void error(String log) { - Keybase.logToService(formatLine("e", log)); - } - - public static void error(String log, Throwable tr) { - Keybase.logToService(formatLine("e", log + Log.getStackTraceString(tr))); - } - - public static void info(String log) { - Keybase.logToService(formatLine("i", log)); - } - - public static void info(String log, Throwable tr) { - Keybase.logToService(formatLine("i", log + Log.getStackTraceString(tr))); - } - - public static void warn(String log) { - Keybase.logToService(formatLine("w", log)); - } - - public static void warn(String log, Throwable tr) { - Keybase.logToService(formatLine("w", log + Log.getStackTraceString(tr))); - } - - public NativeLogger(final ReactApplicationContext reactContext) { - super(reactContext); - } - - @Override - public String getName() { - return NAME; - } -} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/NativeLogger.kt b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/NativeLogger.kt new file mode 100644 index 000000000000..17852364de2d --- /dev/null +++ b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/NativeLogger.kt @@ -0,0 +1,56 @@ +package com.reactnativekb + +import android.util.Log +import keybase.Keybase + +import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.Promise +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReactContextBaseJavaModule +import com.facebook.react.bridge.ReactMethod +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.bridge.WritableArray + +class NativeLogger(reactContext: ReactApplicationContext?) : ReactContextBaseJavaModule(reactContext) { + @Override + override fun getName(): String { + return NAME + } + + companion object { + private val NAME: String = "NativeLogger" + private val RN_NAME: String = "ReactNativeJS" + fun rawLog(tag: String, jsonLog: String) { + Log.i(tag + NAME, jsonLog) + } + + private fun formatLine(tagPrefix: String, toLog: String): String { + // Copies the Style JS outputs in native/logger.native.tsx + return tagPrefix + NAME + ": [" + System.currentTimeMillis() + ",\"" + toLog + "\"]" + } + + fun error(log: String) { + Keybase.logToService(formatLine("e", log)) + } + + fun error(log: String, tr: Throwable?) { + Keybase.logToService(formatLine("e", log + Log.getStackTraceString(tr))) + } + + fun info(log: String) { + Keybase.logToService(formatLine("i", log)) + } + + fun info(log: String, tr: Throwable?) { + Keybase.logToService(formatLine("i", log + Log.getStackTraceString(tr))) + } + + fun warn(log: String) { + Keybase.logToService(formatLine("w", log)) + } + + fun warn(log: String, tr: Throwable) { + Keybase.logToService(formatLine("w", log + Log.getStackTraceString(tr))) + } + } +} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/PathResolver.java b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/PathResolver.java deleted file mode 100644 index 09921a7658d0..000000000000 --- a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/PathResolver.java +++ /dev/null @@ -1,224 +0,0 @@ -package com.reactnativekb; - -// part of https://raw.githubusercontent.com/RonRadtke/react-native-blob-util/master/android/src/main/java/com/ReactNativeBlobUtil/Utils/PathResolver.java - -import android.annotation.TargetApi; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.os.Build; -import android.provider.DocumentsContract; -import android.provider.MediaStore; -import android.content.ContentUris; -import android.content.ContentResolver; - -import java.io.File; -import java.io.InputStream; -import java.io.FileOutputStream; - -public class PathResolver { - @TargetApi(19) - public static String getRealPathFromURI(final Context context, final Uri uri) { - - final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; - - // DocumentProvider - if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { - // ExternalStorageProvider - if (isExternalStorageDocument(uri)) { - final String docId = DocumentsContract.getDocumentId(uri); - final String[] split = docId.split(":"); - final String type = split[0]; - - if ("primary".equalsIgnoreCase(type)) { - File dir = context.getExternalFilesDir(null); - if (dir != null) return dir + "/" + split[1]; - return ""; - } - - // TODO handle non-primary volumes - } - // DownloadsProvider - else if (isDownloadsDocument(uri)) { - try { - final String id = DocumentsContract.getDocumentId(uri); - //Starting with Android O, this "id" is not necessarily a long (row number), - //but might also be a "raw:/some/file/path" URL - if (id != null && id.startsWith("raw:/")) { - Uri rawuri = Uri.parse(id); - String path = rawuri.getPath(); - return path; - } - - Long docId = null; - //Since Android 10, uri can start with msf scheme like "msf:12345" - if (id != null && id.startsWith("msf:")) { - final String[] split = id.split(":"); - docId = Long.valueOf(split[1]); - } else { - docId = Long.valueOf(id); - } - - final Uri contentUri = ContentUris.withAppendedId( - Uri.parse("content://downloads/public_downloads"), docId); - return getDataColumn(context, contentUri, null, null); - } catch (Exception ex) { - //something went wrong, but android should still be able to handle the original uri by returning null here (see readFile(...)) - return null; - } - - } - // MediaProvider - else if (isMediaDocument(uri)) { - final String docId = DocumentsContract.getDocumentId(uri); - final String[] split = docId.split(":"); - final String type = split[0]; - - Uri contentUri = null; - if ("image".equals(type)) { - contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; - } else if ("video".equals(type)) { - contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; - } else if ("audio".equals(type)) { - contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; - } - - final String selection = "_id=?"; - final String[] selectionArgs = new String[]{ - split[1] - }; - - return getDataColumn(context, contentUri, selection, selectionArgs); - } else if ("content".equalsIgnoreCase(uri.getScheme())) { - - // Return the remote address - if (isGooglePhotosUri(uri)) - return uri.getLastPathSegment(); - - return getDataColumn(context, uri, null, null); - } - // Other Providers - else { - try { - InputStream attachment = context.getContentResolver().openInputStream(uri); - if (attachment != null) { - String filename = getContentName(context.getContentResolver(), uri); - if (filename != null) { - File file = new File(context.getCacheDir(), filename); - FileOutputStream tmp = new FileOutputStream(file); - byte[] buffer = new byte[1024]; - while (attachment.read(buffer) > 0) { - tmp.write(buffer); - } - tmp.close(); - attachment.close(); - return file.getAbsolutePath(); - } - } - } catch (Exception e) { - // ReactNativeBlobUtilUtils.emitWarningEvent(e.toString()); - return null; - } - } - } - // MediaStore (and general) - else if ("content".equalsIgnoreCase(uri.getScheme())) { - - // Return the remote address - if (isGooglePhotosUri(uri)) - return uri.getLastPathSegment(); - - return getDataColumn(context, uri, null, null); - } - // File - else if ("file".equalsIgnoreCase(uri.getScheme())) { - return uri.getPath(); - } - - return null; - } - - private static String getContentName(ContentResolver resolver, Uri uri) { - Cursor cursor = resolver.query(uri, null, null, null, null); - if (cursor == null) return null; - cursor.moveToFirst(); - int nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME); - if (nameIndex >= 0) { - String name = cursor.getString(nameIndex); - cursor.close(); - return name; - } - return null; - } - - /** - * Get the value of the data column for this Uri. This is useful for - * MediaStore Uris, and other file-based ContentProviders. - * - * @param context The context. - * @param uri The Uri to query. - * @param selection (Optional) Filter used in the query. - * @param selectionArgs (Optional) Selection arguments used in the query. - * @return The value of the _data column, which is typically a file path. - */ - public static String getDataColumn(Context context, Uri uri, String selection, - String[] selectionArgs) { - - Cursor cursor = null; - String result = null; - final String column = "_data"; - final String[] projection = { - column - }; - - try { - cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, - null); - if (cursor != null && cursor.moveToFirst()) { - final int index = cursor.getColumnIndexOrThrow(column); - result = cursor.getString(index); - } - } catch (Exception ex) { - ex.printStackTrace(); - return null; - } finally { - if (cursor != null) - cursor.close(); - } - return result; - } - - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is ExternalStorageProvider. - */ - public static boolean isExternalStorageDocument(Uri uri) { - return "com.android.externalstorage.documents".equals(uri.getAuthority()); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is DownloadsProvider. - */ - public static boolean isDownloadsDocument(Uri uri) { - return "com.android.providers.downloads.documents".equals(uri.getAuthority()); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is MediaProvider. - */ - public static boolean isMediaDocument(Uri uri) { - return "com.android.providers.media.documents".equals(uri.getAuthority()); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is Google Photos. - */ - public static boolean isGooglePhotosUri(Uri uri) { - return "com.google.android.apps.photos.content".equals(uri.getAuthority()); - } - -} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/PathResolver.kt b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/PathResolver.kt new file mode 100644 index 000000000000..1c907d246b15 --- /dev/null +++ b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/PathResolver.kt @@ -0,0 +1,208 @@ +package com.reactnativekb +// part of https://raw.githubusercontent.com/RonRadtke/react-native-blob-util/master/android/src/main/java/com/ReactNativeBlobUtil/Utils/PathResolver.java +import android.annotation.TargetApi +import android.content.Context +import android.database.Cursor +import android.net.Uri +import android.os.Build +import android.provider.DocumentsContract +import android.provider.MediaStore +import android.content.ContentUris +import android.content.ContentResolver + +import java.io.File; +import java.io.InputStream; +import java.io.FileOutputStream; +object PathResolver { + @TargetApi(19) + fun getRealPathFromURI(context: Context?, uri: Uri?): String? { + if (context == null || uri == null) { + return null + } + val isKitKat: Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT + + // DocumentProvider + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if (isExternalStorageDocument(uri)) { + val docId: String = DocumentsContract.getDocumentId(uri) + val split: List = docId.split(":") + val type = split[0] + if ("primary".equals(type, ignoreCase = true) && context != null) { + val dir: File? = context.getExternalFilesDir(null) + return if (dir != null) dir.toString() + "/" + split[1] else "" + } + + // TODO handle non-primary volumes + } else if (isDownloadsDocument(uri)) { + return try { + val id: String = DocumentsContract.getDocumentId(uri) + //Starting with Android O, this "id" is not necessarily a long (row number), + //but might also be a "raw:/some/file/path" URL + if (id != null && id.startsWith("raw:/")) { + val rawuri: Uri = Uri.parse(id) + return rawuri.getPath() + } + var docId: Long? = null + //Since Android 10, uri can start with msf scheme like "msf:12345" + if (id != null && id.startsWith("msf:")) { + val split: List = id.split(":") + val v = split[1] + if (v != null) { + docId = v.toLong() + } + } else { + docId = id.toLong() + } + if (docId == null) { + return null + } + val contentUri: Uri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), docId) + getDataColumn(context, contentUri, null, null) + } catch (ex: Exception) { + //something went wrong, but android should still be able to handle the original uri by returning null here (see readFile(...)) + null + } + } else if (isMediaDocument(uri)) { + val docId: String = DocumentsContract.getDocumentId(uri) + val split: List = docId.split(":") + val type = split[0] + var contentUri: Uri? = null + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + } + val selection = "_id=?" + val selectionArgs = arrayOf( + split[1] + ) + return getDataColumn(context, contentUri, selection, selectionArgs) + } else if ("content".equals(uri.getScheme(), ignoreCase = true)) { + // Return the remote address + return if (isGooglePhotosUri(uri)) uri.getLastPathSegment() else getDataColumn(context, uri, null, null) + } else { + try { + val cr = context.getContentResolver() + if (cr != null) { + val attachment: InputStream? = cr.openInputStream(uri) + if (attachment != null) { + val filename = getContentName(context.getContentResolver(), uri) + if (filename != null) { + val file = File(context.getCacheDir(), filename) + val tmp = FileOutputStream(file) + val buffer = ByteArray(1024) + while (attachment.read(buffer) > 0) { + tmp.write(buffer) + } + tmp.close() + attachment.close() + return file.getAbsolutePath() + } + } + } + } catch (e: Exception) { + // ReactNativeBlobUtilUtils.emitWarningEvent(e.toString()); + return null + } + } + } else if ("content".equals(uri.getScheme(), ignoreCase = true)) { + + // Return the remote address + return if (isGooglePhotosUri(uri)) uri.getLastPathSegment() else getDataColumn(context, uri, null, null) + } else if ("file".equals(uri.getScheme(), ignoreCase = true)) { + return uri.getPath() + } + return null + } + + private fun getContentName(resolver: ContentResolver?, uri: Uri?): String? { + if (resolver == null || uri == null) { + return null + } + val cursor: Cursor? = resolver.query(uri, null, null, null, null) + if (cursor == null) { + return null + } + cursor.moveToFirst() + val nameIndex: Int = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME) + if (nameIndex >= 0) { + val name: String = cursor.getString(nameIndex) + cursor.close() + return name + } + return null + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + */ + fun getDataColumn(context: Context?, uri: Uri?, selection: String?, + selectionArgs: Array?): String? { + if (context == null || uri == null) { + return null + } + var cursor: Cursor? = null + var result: String? = null + val column = "_data" + val projection = arrayOf( + column + ) + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, + null) + if (cursor != null && cursor.moveToFirst()) { + val index: Int = cursor.getColumnIndexOrThrow(column) + result = cursor.getString(index) + } + } catch (ex: Exception) { + ex.printStackTrace() + return null + } finally { + if (cursor != null) cursor.close() + } + return result + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + fun isExternalStorageDocument(uri: Uri): Boolean { + return "com.android.externalstorage.documents".equals(uri.getAuthority()) + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + fun isDownloadsDocument(uri: Uri): Boolean { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()) + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + fun isMediaDocument(uri: Uri): Boolean { + return "com.android.providers.media.documents".equals(uri.getAuthority()) + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is Google Photos. + */ + fun isGooglePhotosUri(uri: Uri): Boolean { + return "com.google.android.apps.photos.content".equals(uri.getAuthority()) + } +} diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/ReadFileAsString.java b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/ReadFileAsString.java deleted file mode 100644 index de6e012ae1a7..000000000000 --- a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/ReadFileAsString.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.reactnativekb; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; - -public class ReadFileAsString { - public static String read(String path) { - String ret = ""; - - try { - FileInputStream inputStream = new FileInputStream(new File(path)); - - if (inputStream != null) { - InputStreamReader inputStreamReader = new InputStreamReader(inputStream); - BufferedReader bufferedReader = new BufferedReader(inputStreamReader); - String receiveString = ""; - StringBuilder stringBuilder = new StringBuilder(); - - while ((receiveString = bufferedReader.readLine()) != null) { - stringBuilder.append(receiveString); - } - - inputStream.close(); - ret = stringBuilder.toString(); - } - } catch (FileNotFoundException e) { - // ignore - } catch (IOException e) { - // ignore - } - - return ret; - } -} - diff --git a/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/ReadFileAsString.kt b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/ReadFileAsString.kt new file mode 100644 index 000000000000..cecd14f8c4fd --- /dev/null +++ b/rnmodules/react-native-kb/android/src/main/java/com/reactnativekb/ReadFileAsString.kt @@ -0,0 +1,38 @@ +package com.reactnativekb + +import java.io.BufferedReader +import java.io.File +import java.io.FileInputStream +import java.io.FileNotFoundException +import java.io.IOException +import java.io.InputStreamReader + +object ReadFileAsString { + fun read(path: String): String { + var ret = "" + + try { + val inputStream = FileInputStream(File(path)) + + inputStream.use { + val inputStreamReader = InputStreamReader(it) + val bufferedReader = BufferedReader(inputStreamReader) + val stringBuilder = StringBuilder() + + var receiveString: String? + + while (bufferedReader.readLine().also { receiveString = it } != null) { + stringBuilder.append(receiveString) + } + + ret = stringBuilder.toString() + } + } catch (e: FileNotFoundException) { + // ignore + } catch (e: IOException) { + // ignore + } + + return ret + } +} diff --git a/rnmodules/react-native-kb/android/src/newarch/KbSpec.java b/rnmodules/react-native-kb/android/src/newarch/KbSpec.java deleted file mode 100644 index 528317341944..000000000000 --- a/rnmodules/react-native-kb/android/src/newarch/KbSpec.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.reactnativekb; - -import com.facebook.react.bridge.ReactApplicationContext; - -abstract class KbSpec extends NativeKbSpec { - KbSpec(ReactApplicationContext context) { - super(context); - } -} - diff --git a/rnmodules/react-native-kb/android/src/newarch/KbSpec.kt b/rnmodules/react-native-kb/android/src/newarch/KbSpec.kt new file mode 100644 index 000000000000..29f32004bcf1 --- /dev/null +++ b/rnmodules/react-native-kb/android/src/newarch/KbSpec.kt @@ -0,0 +1,5 @@ +package com.reactnativekb + +import com.facebook.react.bridge.ReactApplicationContext + +internal abstract class KbSpec(context: ReactApplicationContext?) : NativeKbSpec(context) diff --git a/rnmodules/react-native-kb/android/src/oldarch/KbSpec.java b/rnmodules/react-native-kb/android/src/oldarch/KbSpec.java deleted file mode 100644 index 6f5a6bb8cb67..000000000000 --- a/rnmodules/react-native-kb/android/src/oldarch/KbSpec.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.reactnativekb; - -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReadableMap; -import java.util.Map; - -abstract class KbSpec extends ReactContextBaseJavaModule { - KbSpec(ReactApplicationContext context) { - super(context); - } - protected abstract Map getTypedExportedConstants(); - - public Map getConstants() { - return this.getTypedExportedConstants(); - } - - public abstract void install(); - public abstract void getDefaultCountryCode(Promise promise); - public abstract void logSend(String status, String feedback, boolean sendLogs, boolean sendMaxBytes, String traceDir, String cpuProfileDir, Promise promise); - public abstract void androidOpenSettings(); - public abstract void androidSetSecureFlagSetting(boolean setSecure, Promise promise); - public abstract void androidGetSecureFlagSetting(Promise promise); - public abstract void androidShare(String uriPath, String mimeType, Promise promise); - public abstract void androidShareText(String text, String mimeType, Promise promise); - public abstract void androidCheckPushPermissions(Promise promise); - public abstract void androidRequestPushPermissions(Promise promise); - public abstract void androidGetRegistrationToken(Promise promise); - public abstract void androidUnlink(String path, Promise promise); - public abstract void androidAddCompleteDownload(ReadableMap config, Promise promise); - public abstract void androidAppColorSchemeChanged(String prefString); - public abstract void androidSetApplicationIconBadgeNumber(double badge); - public abstract void androidGetInitialBundleFromNotification(Promise promise); - public abstract void androidGetInitialShareFileUrls(Promise promise); - public abstract void androidGetInitialShareText(Promise promise); - public abstract void engineReset(); - public abstract void engineStart(); - public abstract void rpcOnGo(byte[] arr); -} diff --git a/rnmodules/react-native-kb/android/src/oldarch/KbSpec.kt b/rnmodules/react-native-kb/android/src/oldarch/KbSpec.kt new file mode 100644 index 000000000000..e877681c1e9b --- /dev/null +++ b/rnmodules/react-native-kb/android/src/oldarch/KbSpec.kt @@ -0,0 +1,36 @@ +package com.reactnativekb + +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReactContextBaseJavaModule +import com.facebook.react.bridge.Promise +import com.facebook.react.bridge.ReadableMap +import java.util.Map + +abstract class KbSpec(context: ReactApplicationContext?) : ReactContextBaseJavaModule(context) { + + abstract fun getTypedExportedConstants(): MutableMap + abstract fun install(): Boolean + abstract fun getDefaultCountryCode(promise: Promise) + abstract fun logSend(status: String, feedback: String, sendLogs: Boolean, sendMaxBytes: Boolean, traceDir: String, cpuProfileDir: String, promise: Promise) + abstract fun androidOpenSettings() + abstract fun androidSetSecureFlagSetting(setSecure: Boolean, promise: Promise) + abstract fun androidGetSecureFlagSetting(promise: Promise) + abstract fun androidShare(uriPath: String, mimeType: String, promise: Promise) + abstract fun androidShareText(text: String, mimeType: String, promise: Promise) + abstract fun androidCheckPushPermissions(promise: Promise) + abstract fun androidRequestPushPermissions(promise: Promise) + abstract fun androidGetRegistrationToken(promise: Promise) + abstract fun androidUnlink(path: String, promise: Promise) + abstract fun androidAddCompleteDownload(config: ReadableMap, promise: Promise) + abstract fun androidAppColorSchemeChanged(prefString: String) + abstract fun androidSetApplicationIconBadgeNumber(badge: Double) + abstract fun androidGetInitialBundleFromNotification(promise: Promise) + abstract fun androidGetInitialShareFileUrls(promise: Promise) + abstract fun androidGetInitialShareText(promise: Promise) + abstract fun engineReset() + abstract fun engineStart() + abstract fun addListener(eventType: String) + abstract fun removeListeners(count: Double) + abstract fun iosGetHasShownPushPrompt(promise: Promise) + +} diff --git a/rnmodules/react-native-kb/ios/KBJSScheduler.cpp b/rnmodules/react-native-kb/ios/KBJSScheduler.cpp new file mode 100644 index 000000000000..104cbfbc2a10 --- /dev/null +++ b/rnmodules/react-native-kb/ios/KBJSScheduler.cpp @@ -0,0 +1,34 @@ +// https://github.com/software-mansion/react-native-reanimated/blob/main/Common/cpp/Tools/ +#include "./KBJSScheduler.h" +using namespace facebook; +using namespace react; + +KBJSScheduler::KBJSScheduler( + jsi::Runtime &rnRuntime, + const std::shared_ptr &jsCallInvoker) + : scheduleOnJS([&](KBJob job) { + jsCallInvoker_->invokeAsync( + [job = std::move(job), &rt = rnRuntime_] { job(rt); }); + }), + rnRuntime_(rnRuntime), + jsCallInvoker_(jsCallInvoker) {} + +#if defined(RCT_NEW_ARCH_ENABLED) +// With `runtimeExecutor`. +KBJSScheduler::KBJSScheduler( + jsi::Runtime &rnRuntime, + RuntimeExecutor runtimeExecutor) + : scheduleOnJS([&](KBJob job) { + runtimeExecutor_( + [job = std::move(job)](jsi::Runtime &runtime) { job(runtime); }); + }), + rnRuntime_(rnRuntime), + runtimeExecutor_(runtimeExecutor) {} +#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED + +const std::shared_ptr KBJSScheduler::getJSCallInvoker() const { + assert( + jsCallInvoker_ != nullptr && + "[Reanimated] Expected jsCallInvoker, got nullptr instead."); + return jsCallInvoker_; +} diff --git a/rnmodules/react-native-kb/ios/KBJSScheduler.h b/rnmodules/react-native-kb/ios/KBJSScheduler.h new file mode 100644 index 000000000000..56da10d3a237 --- /dev/null +++ b/rnmodules/react-native-kb/ios/KBJSScheduler.h @@ -0,0 +1,39 @@ +// https://github.com/software-mansion/react-native-reanimated/blob/main/Common/cpp/Tools/ +#pragma once + +#include +#include +#include + +#include +#include + +using namespace facebook; +using namespace react; + +using KBJob = std::function; + +class KBJSScheduler { + public: + // With `jsCallInvoker`. + explicit KBJSScheduler( + jsi::Runtime &rnRuntime, + const std::shared_ptr &jsCallInvoker); + +#if defined(RCT_NEW_ARCH_ENABLED) + // With `runtimeExecutor`. + explicit KBJSScheduler( + jsi::Runtime &rnRuntime, + RuntimeExecutor runtimeExecutor); +#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED + + const std::function scheduleOnJS = nullptr; + const std::shared_ptr getJSCallInvoker() const; + + protected: + jsi::Runtime &rnRuntime_; +#if defined(RCT_NEW_ARCH_ENABLED) + RuntimeExecutor runtimeExecutor_ = nullptr; +#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED + const std::shared_ptr jsCallInvoker_ = nullptr; +}; diff --git a/rnmodules/react-native-kb/ios/Kb.h b/rnmodules/react-native-kb/ios/Kb.h index 9b382bb6b941..4ff3eb48f245 100644 --- a/rnmodules/react-native-kb/ios/Kb.h +++ b/rnmodules/react-native-kb/ios/Kb.h @@ -6,8 +6,10 @@ #import #import #import +#import +#import -@interface Kb : RCTEventEmitter +@interface Kb : RCTEventEmitter #else #import #import diff --git a/rnmodules/react-native-kb/ios/Kb.mm b/rnmodules/react-native-kb/ios/Kb.mm index 50f2fb1c23f6..db5f195ac2fe 100644 --- a/rnmodules/react-native-kb/ios/Kb.mm +++ b/rnmodules/react-native-kb/ios/Kb.mm @@ -12,6 +12,7 @@ #import #import #import +#import "./KBJSScheduler.h" #ifdef RCT_NEW_ARCH_ENABLED #import "RNKbSpec.h" @@ -69,13 +70,19 @@ - (void)dealloc { static NSString *const metaEventName = @"kb-meta-engine-event"; static NSString *const metaEventEngineReset = @"kb-engine-reset"; -@interface RCTBridge () +@interface RCTBridge (JSIRuntime) +- (void *)runtime; +@end + +@interface RCTBridge (RCTTurboModule) +- (std::shared_ptr)jsCallInvoker; +- (void)_tryAndHandleError:(dispatch_block_t)block; +@end +@interface RCTBridge () - (JSGlobalContextRef)jsContextRef; - (void *)runtime; - (void)dispatchBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue; -- (std::shared_ptr)jsCallInvoker; - @end @interface Kb () @@ -84,13 +91,16 @@ @interface Kb () @implementation Kb +jsi::Runtime *_jsRuntime; +std::shared_ptr jsScheduler; + // sanity check the runtime isn't out of sync due to reload etc void *currentRuntime = nil; RCT_EXPORT_MODULE() + (BOOL)requiresMainQueueSetup { - return NO; + return YES; } - (instancetype)init { @@ -102,6 +112,7 @@ - (instancetype)init { - (void)invalidate { currentRuntime = nil; + _jsRuntime = nil; [super invalidate]; Teardown(); self.bridge = nil; @@ -124,14 +135,8 @@ - (void)invalidate { - (void)sendToJS:(NSData *)data { __weak __typeof__(self) weakSelf = self; - auto invoker = self.bridge.jsCallInvoker; - - if (!invoker) { - NSLog(@"Failed to find invoker in sendToJS!!!"); - return; - } - invoker->invokeAsync([data, weakSelf]() { + jsScheduler->scheduleOnJS([data, weakSelf](jsi::Runtime &jsiRuntime) { __typeof__(self) strongSelf = weakSelf; if (!strongSelf) { NSLog(@"Failed to find self in sendToJS invokeAsync!!!"); @@ -144,7 +149,6 @@ - (void)sendToJS:(NSData *)data { } int size = (int)[data length]; - auto &jsiRuntime = *jsRuntimePtr; auto values = PrepRpcOnJS(jsiRuntime, (uint8_t *)[data bytes], size); RpcOnJS(jsiRuntime, values, [](const std::string &err) { @@ -157,59 +161,7 @@ - (void)sendToJS:(NSData *)data { } - (jsi::Runtime *)javaScriptRuntimePointer { - if ([self.bridge respondsToSelector:@selector(runtime)]) { - auto runtime = reinterpret_cast(self.bridge.runtime); - if (runtime == currentRuntime) { - return runtime; - } - return nil; - } else { - return nil; - } -} - -- (void)installJsiBindings { - // stash the current runtime to keep in sync - currentRuntime = self.bridge.runtime; - auto rpcOnGoWrap = [](Runtime &runtime, const Value &thisValue, - const Value *arguments, size_t count) -> Value { - return RpcOnGo(runtime, thisValue, arguments, count, - [](void *ptr, size_t size) { - NSData *result = [NSData dataWithBytesNoCopy:ptr - length:size - freeWhenDone:NO]; - NSError *error = nil; - KeybaseWriteArr(result, &error); - if (error) { - NSLog(@"Error writing data: %@", error); - } - }); - }; - - auto jsRuntimePtr = [self javaScriptRuntimePointer]; - if (!jsRuntimePtr) { - NSLog(@"Failed to install jsi!!!"); - return; - } - - KeybaseLogToService( - [NSString stringWithFormat:@"dNativeLogger: [%f,\"jsi install success\"]", - [[NSDate date] timeIntervalSince1970] * 1000]); - - auto &jsiRuntime = *jsRuntimePtr; - // register the global JS uses to call go - jsiRuntime.global().setProperty( - jsiRuntime, "rpcOnGo", - Function::createFromHostFunction( - jsiRuntime, PropNameID::forAscii(jsiRuntime, "rpcOnGo"), 1, - std::move(rpcOnGoWrap))); - - // register a global so we get notified when the runtime is killed so we can - // cleanup - jsiRuntime.global().setProperty( - jsiRuntime, "kbTeardown", - jsi::Object::createFromHostObject(jsiRuntime, - std::make_shared())); + return _jsRuntime; } // from react-native-localize @@ -350,8 +302,70 @@ - (NSDictionary *)constantsToExport { }); } -RCT_EXPORT_METHOD(install) { - [self installJsiBindings]; +BOOL isBridgeless = false; // SYNC with AppDelegate.mm + +#if defined(RCT_NEW_ARCH_ENABLED) +@synthesize runtimeExecutor = _runtimeExecutor; +#endif + +RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) { + if (isBridgeless) { +#if defined(RCT_NEW_ARCH_ENABLED) + RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge; + _jsRuntime = (jsi::Runtime *)cxxBridge.runtime; + auto &rnRuntime = *(jsi::Runtime *)cxxBridge.runtime; + auto executorFunction = ([executor = _runtimeExecutor](std::function &&callback) { + // Convert to Objective-C block so it can be captured properly. + __block auto callbackBlock = callback; + + [executor execute:^(jsi::Runtime &runtime) { + callbackBlock(runtime); + }]; + }); + jsScheduler = std::make_shared(rnRuntime, executorFunction); +#else // (RCT_NEW_ARCH_ENABLED) + [NSException raise:@"Missing bridge" format:@"Failed to obtain the bridge."]; +#endif + } else { + _jsRuntime = [self.bridge respondsToSelector:@selector(runtime)] + ? reinterpret_cast(self.bridge.runtime) + : nullptr; + jsScheduler = std::make_shared(*_jsRuntime, self.bridge.jsCallInvoker); + } + + // stash the current runtime to keep in sync + auto rpcOnGoWrap = [](Runtime &runtime, const Value &thisValue, + const Value *arguments, size_t count) -> Value { + return RpcOnGo(runtime, thisValue, arguments, count, + [](void *ptr, size_t size) { + NSData *result = [NSData dataWithBytesNoCopy:ptr + length:size + freeWhenDone:NO]; + NSError *error = nil; + KeybaseWriteArr(result, &error); + if (error) { + NSLog(@"Error writing data: %@", error); + } + }); + }; + + KeybaseLogToService( + [NSString stringWithFormat:@"dNativeLogger: [%f,\"jsi install success\"]", + [[NSDate date] timeIntervalSince1970] * 1000]); + + _jsRuntime->global().setProperty( + *_jsRuntime, "rpcOnGo", + Function::createFromHostFunction( + *_jsRuntime, PropNameID::forAscii(*_jsRuntime, "rpcOnGo"), 1, + std::move(rpcOnGoWrap))); + + // register a global so we get notified when the runtime is killed so we can + // cleanup + _jsRuntime->global().setProperty( + *_jsRuntime, "kbTeardown", + jsi::Object::createFromHostObject(*_jsRuntime, + std::make_shared())); + return @YES; } RCT_EXPORT_METHOD(getDefaultCountryCode @@ -390,32 +404,31 @@ - (NSDictionary *)constantsToExport { }]; } -- (void)androidAddCompleteDownload:(/*JS::NativeKb::SpecAndroidAddCompleteDownloadO &*/ id)o {} -- (void)androidAppColorSchemeChanged:(NSString *)mode {} - (NSNumber *)androidCheckPushPermissions {return @-1;} +- (NSNumber *)androidGetSecureFlagSetting {return @-1;} +- (NSNumber *)androidRequestPushPermissions {return @-1;} +- (NSNumber *)androidSetSecureFlagSetting:(BOOL)s {return @-1;} +- (NSNumber *)androidShare:(NSString *)text mimeType:(NSString *)mimeType {return @-1;} +- (NSNumber *)androidShareText:(NSString *)text mimeType:(NSString *)mimeType {return @-1;} - (NSString *)androidGetInitialBundleFromNotification {return @"";} - (NSString *)androidGetInitialShareFileUrl {return @"";} - (NSString *)androidGetInitialShareText {return @"";} - (NSString *)androidGetRegistrationToken {return @"";} -- (NSNumber *)androidGetSecureFlagSetting {return @-1;} -- (void)androidOpenSettings {} -- (NSNumber *)androidRequestPushPermissions {return @-1;} -- (void)androidSetApplicationIconBadgeNumber:(double)n {} - (void)androidAddCompleteDownload:(/*JS::NativeKb::SpecAndroidAddCompleteDownloadO &*/id)o resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {} +- (void)androidAppColorSchemeChanged:(NSString *)mode {} - (void)androidCheckPushPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {} - (void)androidGetInitialBundleFromNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {} - (void)androidGetInitialShareFileUrls:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {} - (void)androidGetInitialShareText:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {} - (void)androidGetRegistrationToken:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {} - (void)androidGetSecureFlagSetting:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {} +- (void)androidOpenSettings {} - (void)androidRequestPushPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject{} +- (void)androidSetApplicationIconBadgeNumber:(double)n {} - (void)androidSetSecureFlagSetting:(BOOL)s resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {} - (void)androidShare:(NSString *)text mimeType:(NSString *)mimeType resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {} - (void)androidShareText:(NSString *)text mimeType:(NSString *)mimeType resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {} - (void)androidUnlink:(NSString *)path resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {} -- (NSNumber *)androidSetSecureFlagSetting:(BOOL)s {return @-1;} -- (NSNumber *)androidShare:(NSString *)text mimeType:(NSString *)mimeType {return @-1;} -- (NSNumber *)androidShareText:(NSString *)text mimeType:(NSString *)mimeType {return @-1;} - (void)androidUnlink:(NSString *)path {} @end diff --git a/rnmodules/react-native-kb/lib/module/NativeKb.js.map b/rnmodules/react-native-kb/lib/module/NativeKb.js.map index 642e96c19f4c..f8d853824a47 100644 --- a/rnmodules/react-native-kb/lib/module/NativeKb.js.map +++ b/rnmodules/react-native-kb/lib/module/NativeKb.js.map @@ -1 +1 @@ -{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeKb.ts"],"mappings":"AACA,SAAQA,mBAAmB,QAAO,cAAc;AAsDhD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,IAAI,CAAC"} \ No newline at end of file +{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeKb.ts"],"mappings":"AAAA,SAAQA,mBAAmB,QAAyB,cAAc;AAsDlE,eAAeA,mBAAmB,CAACC,YAAY,CAAO,IAAI,CAAC"} \ No newline at end of file diff --git a/rnmodules/react-native-kb/lib/typescript/NativeKb.d.ts b/rnmodules/react-native-kb/lib/typescript/NativeKb.d.ts index f2d3d3a3ae0a..3b1f7f9ca87d 100644 --- a/rnmodules/react-native-kb/lib/typescript/NativeKb.d.ts +++ b/rnmodules/react-native-kb/lib/typescript/NativeKb.d.ts @@ -1,6 +1,6 @@ -import type { TurboModule } from 'react-native'; +import { type TurboModule } from 'react-native'; export interface Spec extends TurboModule { - install: () => void; + install: () => boolean; addListener: (eventType: string) => void; removeListeners: (count: number) => void; getConstants(): { diff --git a/rnmodules/react-native-kb/lib/typescript/index.d.ts b/rnmodules/react-native-kb/lib/typescript/index.d.ts index 8935d598a083..422a457a64ec 100644 --- a/rnmodules/react-native-kb/lib/typescript/index.d.ts +++ b/rnmodules/react-native-kb/lib/typescript/index.d.ts @@ -19,7 +19,7 @@ export declare const androidAddCompleteDownload: (o: { showNotification: boolean; title: string; }) => Promise; -export declare const androidAppColorSchemeChanged: (mode: 'system' | 'alwaysDark' | 'alwaysLight' | '') => void; +export declare const androidAppColorSchemeChanged: (mode: "system" | "alwaysDark" | "alwaysLight" | "") => void; export declare const androidSetApplicationIconBadgeNumber: (n: number) => void; export declare const androidGetInitialBundleFromNotification: () => Promise; export declare const androidGetInitialShareFileUrls: () => Promise>; diff --git a/rnmodules/react-native-kb/react-native-kb.podspec b/rnmodules/react-native-kb/react-native-kb.podspec index 5f5cbf3eee0c..73ba60ac2836 100644 --- a/rnmodules/react-native-kb/react-native-kb.podspec +++ b/rnmodules/react-native-kb/react-native-kb.podspec @@ -15,7 +15,7 @@ Pod::Spec.new do |s| s.source = { :git => "https://github.com/keybase/client/react-native-kb.git", :tag => "#{s.version}" } s.source_files = [ - "ios/**/*.{h,m,mm}", + "ios/**/*.{h,m,mm,cpp}", "cpp/**/*.{h,cpp}", "cpp/*.{h,cpp}" ] diff --git a/rnmodules/react-native-kb/src/NativeKb.ts b/rnmodules/react-native-kb/src/NativeKb.ts index 457b6d52d970..985f01e02557 100644 --- a/rnmodules/react-native-kb/src/NativeKb.ts +++ b/rnmodules/react-native-kb/src/NativeKb.ts @@ -1,8 +1,7 @@ -import type {TurboModule} from 'react-native' -import {TurboModuleRegistry} from 'react-native' +import {TurboModuleRegistry, type TurboModule} from 'react-native' export interface Spec extends TurboModule { - install: () => void + install: () => boolean addListener: (eventType: string) => void removeListeners: (count: number) => void getConstants(): { diff --git a/rnmodules/react-native-kb/yarn.lock b/rnmodules/react-native-kb/yarn.lock index 4b00b43d30cb..a1f7f518c25e 100644 --- a/rnmodules/react-native-kb/yarn.lock +++ b/rnmodules/react-native-kb/yarn.lock @@ -18,11 +18,32 @@ "@babel/highlight" "^7.22.10" chalk "^2.4.2" -"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": +"@babel/code-frame@^7.23.5": + version "7.24.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" + integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== + dependencies: + "@babel/highlight" "^7.24.2" + picocolors "^1.0.0" + +"@babel/code-frame@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== + dependencies: + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" + +"@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== +"@babel/compat-data@^7.25.2": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.4.tgz#7d2a80ce229890edcf4cc259d4d696cb4dae2fcb" + integrity sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ== + "@babel/core@^7.13.16", "@babel/core@^7.18.5", "@babel/core@^7.20.0": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.10.tgz#aad442c7bcd1582252cb4576747ace35bc122f35" @@ -54,6 +75,16 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" +"@babel/generator@^7.25.4": + version "7.25.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.5.tgz#b31cf05b3fe8c32d206b6dad03bb0aacbde73450" + integrity sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w== + dependencies: + "@babel/types" "^7.25.4" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" @@ -61,6 +92,13 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-annotate-as-pure@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" + integrity sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg== + dependencies: + "@babel/types" "^7.24.7" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.10.tgz#573e735937e99ea75ea30788b57eb52fab7468c9" @@ -68,7 +106,7 @@ dependencies: "@babel/types" "^7.22.10" -"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.10", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": +"@babel/helper-compilation-targets@^7.22.10", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz#01d648bbc25dd88f513d862ee0df27b7d4e67024" integrity sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q== @@ -79,6 +117,17 @@ lru-cache "^5.1.1" semver "^6.3.1" +"@babel/helper-compilation-targets@^7.24.7": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz#e1d9410a90974a3a5a66e84ff55ef62e3c02d06c" + integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw== + dependencies: + "@babel/compat-data" "^7.25.2" + "@babel/helper-validator-option" "^7.24.8" + browserslist "^4.23.1" + lru-cache "^5.1.1" + semver "^6.3.1" + "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.10", "@babel/helper-create-class-features-plugin@^7.22.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.10.tgz#dd2612d59eac45588021ac3d6fa976d08f4e95a3" @@ -94,6 +143,34 @@ "@babel/helper-split-export-declaration" "^7.22.6" semver "^6.3.1" +"@babel/helper-create-class-features-plugin@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz#7d19da92c7e0cd8d11c09af2ce1b8e7512a6e723" + integrity sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.24.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.24.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.24.5" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.25.4": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz#57eaf1af38be4224a9d9dd01ddde05b741f50e14" + integrity sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-member-expression-to-functions" "^7.24.8" + "@babel/helper-optimise-call-expression" "^7.24.7" + "@babel/helper-replace-supers" "^7.25.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/traverse" "^7.25.4" + semver "^6.3.1" + "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" @@ -114,7 +191,12 @@ lodash.debounce "^4.0.8" resolve "^1.14.2" -"@babel/helper-environment-visitor@^7.18.9", "@babel/helper-environment-visitor@^7.22.5": +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-environment-visitor@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== @@ -127,6 +209,14 @@ "@babel/template" "^7.22.5" "@babel/types" "^7.22.5" +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + "@babel/helper-hoist-variables@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" @@ -141,6 +231,21 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-member-expression-to-functions@^7.23.0", "@babel/helper-member-expression-to-functions@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz#5981e131d5c7003c7d1fa1ad49e86c9b097ec475" + integrity sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA== + dependencies: + "@babel/types" "^7.24.5" + +"@babel/helper-member-expression-to-functions@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz#6155e079c913357d24a4c20480db7c712a5c3fb6" + integrity sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA== + dependencies: + "@babel/traverse" "^7.24.8" + "@babel/types" "^7.24.8" + "@babel/helper-module-imports@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" @@ -166,12 +271,29 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-optimise-call-expression@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz#8b0a0456c92f6b323d27cfd00d1d664e76692a0f" + integrity sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A== + dependencies: + "@babel/types" "^7.24.7" + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== -"@babel/helper-remap-async-to-generator@^7.18.9", "@babel/helper-remap-async-to-generator@^7.22.5", "@babel/helper-remap-async-to-generator@^7.22.9": +"@babel/helper-plugin-utils@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz#a924607dd254a65695e5bd209b98b902b3b2f11a" + integrity sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ== + +"@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" + integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== + +"@babel/helper-remap-async-to-generator@^7.22.5", "@babel/helper-remap-async-to-generator@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz#53a25b7484e722d7efb9c350c75c032d4628de82" integrity sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ== @@ -180,6 +302,15 @@ "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-wrap-function" "^7.22.9" +"@babel/helper-remap-async-to-generator@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz#d2f0fbba059a42d68e5e378feaf181ef6055365e" + integrity sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-wrap-function" "^7.25.0" + "@babel/traverse" "^7.25.0" + "@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz#cbdc27d6d8d18cd22c81ae4293765a5d9afd0779" @@ -189,6 +320,24 @@ "@babel/helper-member-expression-to-functions" "^7.22.5" "@babel/helper-optimise-call-expression" "^7.22.5" +"@babel/helper-replace-supers@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz#7085bd19d4a0b7ed8f405c1ed73ccb70f323abc1" + integrity sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + +"@babel/helper-replace-supers@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz#ff44deac1c9f619523fe2ca1fd650773792000a9" + integrity sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.24.8" + "@babel/helper-optimise-call-expression" "^7.24.7" + "@babel/traverse" "^7.25.0" + "@babel/helper-simple-access@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" @@ -203,6 +352,14 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-skip-transparent-expression-wrappers@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz#5f8fa83b69ed5c27adc56044f8be2b3ea96669d9" + integrity sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + "@babel/helper-split-export-declaration@^7.22.6": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" @@ -210,21 +367,53 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-split-export-declaration@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz#b9a67f06a46b0b339323617c8c6213b9055a78b6" + integrity sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q== + dependencies: + "@babel/types" "^7.24.5" + "@babel/helper-string-parser@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== +"@babel/helper-string-parser@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" + integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== + +"@babel/helper-string-parser@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" + integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== + "@babel/helper-validator-identifier@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== +"@babel/helper-validator-identifier@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" + integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== + +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + "@babel/helper-validator-option@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== +"@babel/helper-validator-option@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" + integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== + "@babel/helper-wrap-function@^7.22.9": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.10.tgz#d845e043880ed0b8c18bd194a12005cb16d2f614" @@ -234,6 +423,15 @@ "@babel/template" "^7.22.5" "@babel/types" "^7.22.10" +"@babel/helper-wrap-function@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz#dab12f0f593d6ca48c0062c28bcfb14ebe812f81" + integrity sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ== + dependencies: + "@babel/template" "^7.25.0" + "@babel/traverse" "^7.25.0" + "@babel/types" "^7.25.0" + "@babel/helpers@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.10.tgz#ae6005c539dfbcb5cd71fb51bfc8a52ba63bc37a" @@ -252,11 +450,43 @@ chalk "^2.4.2" js-tokens "^4.0.0" +"@babel/highlight@^7.24.2": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.5.tgz#bc0613f98e1dd0720e99b2a9ee3760194a704b6e" + integrity sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.5" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + "@babel/parser@^7.13.16", "@babel/parser@^7.20.0", "@babel/parser@^7.22.10", "@babel/parser@^7.22.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.10.tgz#e37634f9a12a1716136c44624ef54283cabd3f55" integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== +"@babel/parser@^7.24.0": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" + integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== + +"@babel/parser@^7.25.0", "@babel/parser@^7.25.4": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.4.tgz#af4f2df7d02440286b7de57b1c21acfb2a6f257a" + integrity sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA== + dependencies: + "@babel/types" "^7.25.4" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e" @@ -273,17 +503,7 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/plugin-transform-optional-chaining" "^7.22.5" -"@babel/plugin-proposal-async-generator-functions@^7.0.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz#bfb7276d2d573cb67ba379984a2334e262ba5326" - integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-remap-async-to-generator" "^7.18.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.13.0", "@babel/plugin-proposal-class-properties@^7.17.12", "@babel/plugin-proposal-class-properties@^7.18.0": +"@babel/plugin-proposal-class-properties@^7.13.0", "@babel/plugin-proposal-class-properties@^7.17.12": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== @@ -299,7 +519,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-export-default-from" "^7.22.5" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.0": +"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== @@ -307,34 +527,7 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" - integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.20.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" - integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== - dependencies: - "@babel/compat-data" "^7.20.5" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.20.7" - -"@babel/plugin-proposal-optional-catch-binding@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" - integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.20.0": +"@babel/plugin-proposal-optional-chaining@^7.13.12": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== @@ -355,7 +548,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.0.0", "@babel/plugin-syntax-class-properties@^7.12.13": +"@babel/plugin-syntax-class-properties@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== @@ -390,7 +583,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.12.1", "@babel/plugin-syntax-flow@^7.18.0", "@babel/plugin-syntax-flow@^7.22.5": +"@babel/plugin-syntax-flow@^7.12.1", "@babel/plugin-syntax-flow@^7.18.0", "@babel/plugin-syntax-flow@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz#163b820b9e7696ce134df3ee716d9c0c98035859" integrity sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ== @@ -425,7 +618,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.22.5": +"@babel/plugin-syntax-jsx@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== @@ -453,7 +646,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== @@ -520,6 +713,16 @@ "@babel/helper-remap-async-to-generator" "^7.22.9" "@babel/plugin-syntax-async-generators" "^7.8.4" +"@babel/plugin-transform-async-generator-functions@^7.24.3": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz#2afd4e639e2d055776c9f091b6c0c180ed8cf083" + integrity sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-remap-async-to-generator" "^7.25.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/traverse" "^7.25.4" + "@babel/plugin-transform-async-to-generator@^7.20.0", "@babel/plugin-transform-async-to-generator@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" @@ -529,7 +732,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-remap-async-to-generator" "^7.22.5" -"@babel/plugin-transform-block-scoped-functions@^7.0.0", "@babel/plugin-transform-block-scoped-functions@^7.22.5": +"@babel/plugin-transform-block-scoped-functions@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== @@ -551,6 +754,14 @@ "@babel/helper-create-class-features-plugin" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-class-properties@^7.24.1": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz#bae7dbfcdcc2e8667355cd1fb5eda298f05189fd" + integrity sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.25.4" + "@babel/helper-plugin-utils" "^7.24.8" + "@babel/plugin-transform-class-static-block@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz#3e40c46f048403472d6f4183116d5e46b1bff5ba" @@ -583,7 +794,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/template" "^7.22.5" -"@babel/plugin-transform-destructuring@^7.0.0", "@babel/plugin-transform-destructuring@^7.20.0", "@babel/plugin-transform-destructuring@^7.22.10": +"@babel/plugin-transform-destructuring@^7.20.0", "@babel/plugin-transform-destructuring@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.10.tgz#38e2273814a58c810b6c34ea293be4973c4eb5e2" integrity sha512-dPJrL0VOyxqLM9sritNbMSGx/teueHF/htMKrPT7DNxccXxRDPYqlgPFFdr8u+F+qUZOkZoXue/6rL5O5GduEw== @@ -629,7 +840,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.20.0", "@babel/plugin-transform-flow-strip-types@^7.22.5": +"@babel/plugin-transform-flow-strip-types@^7.20.0", "@babel/plugin-transform-flow-strip-types@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz#0bb17110c7bf5b35a60754b2f00c58302381dee2" integrity sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA== @@ -637,7 +848,15 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-flow" "^7.22.5" -"@babel/plugin-transform-for-of@^7.0.0", "@babel/plugin-transform-for-of@^7.22.5": +"@babel/plugin-transform-for-of@^7.0.0": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz#f25b33f72df1d8be76399e1b8f3f9d366eb5bc70" + integrity sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + +"@babel/plugin-transform-for-of@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz#ab1b8a200a8f990137aff9a084f8de4099ab173f" integrity sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A== @@ -676,7 +895,15 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.0.0", "@babel/plugin-transform-member-expression-literals@^7.22.5": +"@babel/plugin-transform-logical-assignment-operators@^7.24.1": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz#a58fb6eda16c9dc8f9ff1c7b1ba6deb7f4694cb0" + integrity sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== @@ -741,6 +968,14 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" +"@babel/plugin-transform-nullish-coalescing-operator@^7.24.1": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz#1de4534c590af9596f53d67f52a92f12db984120" + integrity sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-transform-numeric-separator@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz#57226a2ed9e512b9b446517ab6fa2d17abb83f58" @@ -749,6 +984,14 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" +"@babel/plugin-transform-numeric-separator@^7.24.1": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz#bea62b538c80605d8a0fac9b40f48e97efa7de63" + integrity sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-transform-object-rest-spread@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz#9686dc3447df4753b0b2a2fae7e8bc33cdc1f2e1" @@ -760,7 +1003,17 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.22.5" -"@babel/plugin-transform-object-super@^7.0.0", "@babel/plugin-transform-object-super@^7.22.5": +"@babel/plugin-transform-object-rest-spread@^7.24.5": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz#d13a2b93435aeb8a197e115221cab266ba6e55d6" + integrity sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q== + dependencies: + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.24.7" + +"@babel/plugin-transform-object-super@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== @@ -776,6 +1029,14 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" +"@babel/plugin-transform-optional-catch-binding@^7.24.1": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz#00eabd883d0dd6a60c1c557548785919b6e717b4" + integrity sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-transform-optional-chaining@^7.22.10", "@babel/plugin-transform-optional-chaining@^7.22.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.10.tgz#076d28a7e074392e840d4ae587d83445bac0372a" @@ -785,13 +1046,29 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.22.5": +"@babel/plugin-transform-optional-chaining@^7.24.5": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz#bb02a67b60ff0406085c13d104c99a835cdf365d" + integrity sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz#c3542dd3c39b42c8069936e48717a8d179d63a18" integrity sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-parameters@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz#5881f0ae21018400e320fc7eb817e529d1254b68" + integrity sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-transform-private-methods@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" @@ -800,6 +1077,16 @@ "@babel/helper-create-class-features-plugin" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-private-property-in-object@^7.22.11": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz#f5d1fcad36e30c960134cb479f1ca98a5b06eda5" + integrity sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.24.5" + "@babel/helper-plugin-utils" "^7.24.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-transform-private-property-in-object@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz#07a77f28cbb251546a43d175a1dda4cf3ef83e32" @@ -810,7 +1097,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-transform-property-literals@^7.0.0", "@babel/plugin-transform-property-literals@^7.22.5": +"@babel/plugin-transform-property-literals@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== @@ -864,6 +1151,14 @@ "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-regenerator@^7.20.0": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz#021562de4534d8b4b1851759fd7af4e05d2c47f8" + integrity sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + regenerator-transform "^0.15.2" + "@babel/plugin-transform-regenerator@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca" @@ -913,7 +1208,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-template-literals@^7.0.0", "@babel/plugin-transform-template-literals@^7.22.5": +"@babel/plugin-transform-template-literals@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== @@ -1127,6 +1422,24 @@ "@babel/parser" "^7.22.5" "@babel/types" "^7.22.5" +"@babel/template@^7.22.15": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" + integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/parser" "^7.24.0" + "@babel/types" "^7.24.0" + +"@babel/template@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a" + integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/parser" "^7.25.0" + "@babel/types" "^7.25.0" + "@babel/traverse@^7.20.0", "@babel/traverse@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.10.tgz#20252acb240e746d27c2e82b4484f199cf8141aa" @@ -1143,6 +1456,19 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.4": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.4.tgz#648678046990f2957407e3086e97044f13c3e18e" + integrity sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.25.4" + "@babel/parser" "^7.25.4" + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.4" + debug "^4.3.1" + globals "^11.1.0" + "@babel/types@^7.20.0", "@babel/types@^7.22.10", "@babel/types@^7.22.5", "@babel/types@^7.4.4": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" @@ -1152,6 +1478,24 @@ "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" +"@babel/types@^7.23.0", "@babel/types@^7.24.0", "@babel/types@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.5.tgz#7661930afc638a5383eb0c4aee59b74f38db84d7" + integrity sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ== + dependencies: + "@babel/helper-string-parser" "^7.24.1" + "@babel/helper-validator-identifier" "^7.24.5" + to-fast-properties "^2.0.0" + +"@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.25.0", "@babel/types@^7.25.4": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.4.tgz#6bcb46c72fdf1012a209d016c07f769e10adcb5f" + integrity sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ== + dependencies: + "@babel/helper-string-parser" "^7.24.8" + "@babel/helper-validator-identifier" "^7.24.7" + to-fast-properties "^2.0.0" + "@hapi/hoek@^9.0.0": version "9.3.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" @@ -1164,39 +1508,44 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@jest/create-cache-key-function@^29.2.1": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.6.2.tgz#b6b74fb741a7b7d9aa399c179694db8272283527" - integrity sha512-oGVRMr8na9h1vUiem1E/Uoxb/NR9BdfKb7IBZ+pNWxJQmTYSbDF0dsVBAGqNU7MBQwYJDyRx0H7H/0itiqAgQg== +"@isaacs/ttlcache@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz#21fb23db34e9b6220c6ba023a0118a2dd3461ea2" + integrity sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA== + +"@jest/create-cache-key-function@^29.6.3": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz#793be38148fab78e65f40ae30c36785f4ad859f0" + integrity sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" -"@jest/environment@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.6.2.tgz#794c0f769d85e7553439d107d3f43186dc6874a9" - integrity sha512-AEcW43C7huGd/vogTddNNTDRpO6vQ2zaQNrttvWV18ArBx9Z56h7BIsXkNFJVOO4/kblWEQz30ckw0+L3izc+Q== +"@jest/environment@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" + integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== dependencies: - "@jest/fake-timers" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" - jest-mock "^29.6.2" + jest-mock "^29.7.0" -"@jest/fake-timers@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.6.2.tgz#fe9d43c5e4b1b901168fe6f46f861b3e652a2df4" - integrity sha512-euZDmIlWjm1Z0lJ1D0f7a0/y5Kh/koLFMUBE5SUYWrmy8oNhJpbTBDAP6CxKnadcMLDoDf4waRYCe35cH6G6PA== +"@jest/fake-timers@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^29.6.2" - jest-mock "^29.6.2" - jest-util "^29.6.2" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" -"@jest/schemas@^29.6.0": - version "29.6.0" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040" - integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ== +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== dependencies: "@sinclair/typebox" "^0.27.8" @@ -1211,23 +1560,12 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@jest/types@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" - integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - -"@jest/types@^29.6.1": - version "29.6.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.1.tgz#ae79080278acff0a6af5eb49d063385aaa897bf2" - integrity sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw== +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== dependencies: - "@jest/schemas" "^29.6.0" + "@jest/schemas" "^29.6.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" @@ -1243,6 +1581,15 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@^3.1.0": version "3.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" @@ -1253,6 +1600,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + "@jridgewell/source-map@^0.3.3": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" @@ -1274,6 +1626,14 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1295,204 +1655,294 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@react-native-community/cli-clean@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-11.3.10.tgz#70d14dd998ce8ad532266b36a0e5cafe22d300ac" - integrity sha512-g6QjW+DSqoWRHzmIQW3AH22k1AnynWuOdy2YPwYEGgPddTeXZtJphIpEVwDOiC0L4mZv2VmiX33/cGNUwO0cIA== +"@react-native-community/cli-clean@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-14.1.0.tgz#fee1a178fa58c84dfe18e23ee79fd3110d974971" + integrity sha512-/C4j1yntLo6faztNgZnsDtgpGqa6j0+GYrxOY8LqaKAN03OCnoeUUKO6w78dycbYSGglc1xjJg2RZI/M2oF2AA== dependencies: - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-tools" "14.1.0" chalk "^4.1.2" execa "^5.0.0" - prompts "^2.4.0" + fast-glob "^3.3.2" -"@react-native-community/cli-config@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-11.3.10.tgz#753510a80a98b136fec852e1ea5fa655c13dbd17" - integrity sha512-YYu14nm1JYLS6mDRBz78+zDdSFudLBFpPkhkOoj4LuBhNForQBIqFFHzQbd9/gcguJxfW3vlYSnudfaUI7oGLg== +"@react-native-community/cli-config@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-14.1.0.tgz#8cdebb890eeb3c25d6c117ee56c952e96ea2afbf" + integrity sha512-P3FK2rPUJBD1fmQHLgTqpHxsc111pnMdEEFR7KeqprCNz+Qr2QpPxfNy0V7s15tGL5rAv+wpbOGcioIV50EbxA== dependencies: - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-tools" "14.1.0" chalk "^4.1.2" - cosmiconfig "^5.1.0" + cosmiconfig "^9.0.0" deepmerge "^4.3.0" - glob "^7.1.3" + fast-glob "^3.3.2" joi "^17.2.1" -"@react-native-community/cli-debugger-ui@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-11.3.10.tgz#b16ebf770ba3cc76bf46580f101d00dacf919824" - integrity sha512-kyitGV3RsjlXIioq9lsuawha2GUBPCTAyXV6EBlm3qlyF3dMniB3twEvz+fIOid/e1ZeucH3Tzy5G3qcP8yWoA== +"@react-native-community/cli-debugger-ui@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-14.1.0.tgz#0008039ad2c386730c415d9dfc6884d68fda2c93" + integrity sha512-+YbeCL0wLcBcqDwraJFGsqzcXu9S+bwTVrfImne/4mT6itfe3Oa93yrOVJgNbstrt5pJHuwpU76ZXfXoiuncsg== dependencies: serve-static "^1.13.1" -"@react-native-community/cli-doctor@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-11.3.10.tgz#161b8fd1b485cd52f7a19b2025696070b9d2b6a1" - integrity sha512-DpMsfCWKZ15L9nFK/SyDvpl5v6MjV+arMHMC1i8kR+DOmf2xWmp/pgMywKk0/u50yGB9GwxBHt3i/S/IMK5Ylg== +"@react-native-community/cli-doctor@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-14.1.0.tgz#129b25a7792f7bb0ed1218d17665ce74bb995d08" + integrity sha512-xIf0oQDRKt7lufUenRwcLYdINGc0x1FSXHaHjd7lQDGT5FJnCEYlIkYEDDgAl5tnVJSvM/IL2c6O+mffkNEPzQ== dependencies: - "@react-native-community/cli-config" "11.3.10" - "@react-native-community/cli-platform-android" "11.3.10" - "@react-native-community/cli-platform-ios" "11.3.10" - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-config" "14.1.0" + "@react-native-community/cli-platform-android" "14.1.0" + "@react-native-community/cli-platform-apple" "14.1.0" + "@react-native-community/cli-platform-ios" "14.1.0" + "@react-native-community/cli-tools" "14.1.0" chalk "^4.1.2" command-exists "^1.2.8" - envinfo "^7.7.2" + deepmerge "^4.3.0" + envinfo "^7.13.0" execa "^5.0.0" - hermes-profile-transformer "^0.0.6" - ip "^1.1.5" node-stream-zip "^1.9.1" ora "^5.4.1" - prompts "^2.4.0" semver "^7.5.2" strip-ansi "^5.2.0" - sudo-prompt "^9.0.0" wcwidth "^1.0.1" yaml "^2.2.1" -"@react-native-community/cli-hermes@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-11.3.10.tgz#f3d4f069ca472b1d8b4e8132cf9c44097a58ca19" - integrity sha512-vqINuzAlcHS9ImNwJtT43N7kfBQ7ro9A8O1Gpc5TQ0A8V36yGG8eoCHeauayklVVgMZpZL6f6mcoLLr9IOgBZQ== - dependencies: - "@react-native-community/cli-platform-android" "11.3.10" - "@react-native-community/cli-tools" "11.3.10" - chalk "^4.1.2" - hermes-profile-transformer "^0.0.6" - ip "^1.1.5" - -"@react-native-community/cli-platform-android@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-11.3.10.tgz#756dd73ad78bf2f20c678683dfc48cb764b1b590" - integrity sha512-RGu9KuDIXnrcNkacSHj5ETTQtp/D/835L6veE2jMigO21p//gnKAjw3AVLCysGr8YXYfThF8OSOALrwNc94puQ== +"@react-native-community/cli-platform-android@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-14.1.0.tgz#3545347a810d209bba24941f62f802fdc09e252f" + integrity sha512-4JnXkAV+ca8XdUhZ7xjgDhXAMwTVjQs8JqiwP7FTYVrayShXy2cBXm/C3HNDoe+oQOF5tPT2SqsDAF2vYTnKiQ== dependencies: - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-tools" "14.1.0" chalk "^4.1.2" execa "^5.0.0" - glob "^7.1.3" + fast-glob "^3.3.2" + fast-xml-parser "^4.4.1" logkitty "^0.7.1" -"@react-native-community/cli-platform-ios@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-11.3.10.tgz#f8a9bca1181802f12ed15714d5a496e60096cbed" - integrity sha512-JjduMrBM567/j4Hvjsff77dGSLMA0+p9rr0nShlgnKPcc+0J4TDy0hgWpUceM7OG00AdDjpetAPupz0kkAh4cQ== +"@react-native-community/cli-platform-apple@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-apple/-/cli-platform-apple-14.1.0.tgz#d232cd0fc1ec0bccd165e40dd7d8a3c4bec5f571" + integrity sha512-DExd+pZ7hHxXt8I6BBmckeYUxxq7PQ+o4YSmGIeQx0xUpi+f82obBct2WNC3VWU72Jw6obwfoN6Fwe6F7Wxp5Q== dependencies: - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-tools" "14.1.0" chalk "^4.1.2" execa "^5.0.0" - fast-xml-parser "^4.0.12" - glob "^7.1.3" + fast-glob "^3.3.2" + fast-xml-parser "^4.4.1" ora "^5.4.1" -"@react-native-community/cli-plugin-metro@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-11.3.10.tgz#6ed67dda2518d3dabae20f3b38f66a0a9bd8e962" - integrity sha512-ZYAc5Hc+QVqJgj1XFbpKnIPbSJ9xKcBnfQrRhR+jFyt2DWx85u4bbzY1GSVc/USs0UbSUXv4dqPbnmOJz52EYQ== +"@react-native-community/cli-platform-ios@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-14.1.0.tgz#e3b7ae8a97b69da4c7c89d9767ea58fb90c9c05f" + integrity sha512-ah/ZTiJXUdCVHujyRJ4OmCL5nTq8OWcURcE3UXa1z0sIIiA8io06n+v5n299T9rtPKMwRtVJlQjtO/nbODABPQ== dependencies: - "@react-native-community/cli-server-api" "11.3.10" - "@react-native-community/cli-tools" "11.3.10" - chalk "^4.1.2" - execa "^5.0.0" - metro "0.76.8" - metro-config "0.76.8" - metro-core "0.76.8" - metro-react-native-babel-transformer "0.76.8" - metro-resolver "0.76.8" - metro-runtime "0.76.8" - readline "^1.3.0" + "@react-native-community/cli-platform-apple" "14.1.0" -"@react-native-community/cli-server-api@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-11.3.10.tgz#2c4940d921711f2c78f0b61f126e8dbbbef6277c" - integrity sha512-WEwHWIpqx3gA6Da+lrmq8+z78E1XbxxjBlvHAXevhjJj42N4SO417eZiiUVrFzEFVVJSUee9n9aRa0kUR+0/2w== +"@react-native-community/cli-server-api@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-14.1.0.tgz#b658f96014f6d725ddb50da69833eacdbb8263c8" + integrity sha512-1k2LBQaYsy9RDWFIfKVne3frOye73O33MV6eYMoRPff7wqxHCrsX1CYJQkmwpgVigZHxYwalHj+Axtu3gpomCA== dependencies: - "@react-native-community/cli-debugger-ui" "11.3.10" - "@react-native-community/cli-tools" "11.3.10" + "@react-native-community/cli-debugger-ui" "14.1.0" + "@react-native-community/cli-tools" "14.1.0" compression "^1.7.1" connect "^3.6.5" errorhandler "^1.5.1" nocache "^3.0.1" pretty-format "^26.6.2" serve-static "^1.13.1" - ws "^7.5.1" + ws "^6.2.3" -"@react-native-community/cli-tools@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-11.3.10.tgz#d7bbe3fd8b338004f996f03f53a5373d9caab91c" - integrity sha512-4kCuCwVcGagSrNg9vxMNVhynwpByuC/J5UnKGEet3HuqmoDhQW15m18fJXiehA8J+u9WBvHduefy9nZxO0C06Q== +"@react-native-community/cli-tools@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-14.1.0.tgz#fbbd40e9ccd93842992c8e45c10dfd8eeb56ff4a" + integrity sha512-r1KxSu2+OSuhWFoE//1UR7aSTXMLww/UYWQprEw4bSo/kvutGX//4r9ywgXSWp+39udpNN4jQpNTHuWhGZd/Bg== dependencies: appdirsjs "^1.2.4" chalk "^4.1.2" + execa "^5.0.0" find-up "^5.0.0" mime "^2.4.1" - node-fetch "^2.6.0" open "^6.2.0" ora "^5.4.1" semver "^7.5.2" shell-quote "^1.7.3" + sudo-prompt "^9.0.0" -"@react-native-community/cli-types@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-11.3.10.tgz#cb02186cd247108bcea5ff93c4c97bb3c8dd8f22" - integrity sha512-0FHK/JE7bTn0x1y8Lk5m3RISDHIBQqWLltO2Mf7YQ6cAeKs8iNOJOeKaHJEY+ohjsOyCziw+XSC4cY57dQrwNA== +"@react-native-community/cli-types@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-14.1.0.tgz#0ea5dad716f30cd49d2edd5d9fdea8e552cb44e8" + integrity sha512-aJwZI9mGRx3HdP8U4CGhqjt3S4r8GmeOqv4kRagC1UHDk4QNMC+bZ8JgPA4W7FrGiPey+lJQHMDPAXOo51SOUw== dependencies: joi "^17.2.1" -"@react-native-community/cli@11.3.10": - version "11.3.10" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-11.3.10.tgz#ea88d20982cfc9ed7a5170d04aeedd2abf092348" - integrity sha512-bIx0t5s9ewH1PlcEcuQUD+UnVrCjPGAfjhVR5Gew565X60nE+GTIHRn70nMv9G4he/amBF+Z+vf5t8SNZEWMwg== - dependencies: - "@react-native-community/cli-clean" "11.3.10" - "@react-native-community/cli-config" "11.3.10" - "@react-native-community/cli-debugger-ui" "11.3.10" - "@react-native-community/cli-doctor" "11.3.10" - "@react-native-community/cli-hermes" "11.3.10" - "@react-native-community/cli-plugin-metro" "11.3.10" - "@react-native-community/cli-server-api" "11.3.10" - "@react-native-community/cli-tools" "11.3.10" - "@react-native-community/cli-types" "11.3.10" +"@react-native-community/cli@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-14.1.0.tgz#bbcc14e9b7ee54589e645c7cd42da0cc79307f41" + integrity sha512-k7aTdKNZIec7WMSqMJn9bDVLWPPOaYmshXcnjWy6t5ItsJnREju9p2azMTR5tXY5uIeynose3cxettbhk2Tbnw== + dependencies: + "@react-native-community/cli-clean" "14.1.0" + "@react-native-community/cli-config" "14.1.0" + "@react-native-community/cli-debugger-ui" "14.1.0" + "@react-native-community/cli-doctor" "14.1.0" + "@react-native-community/cli-server-api" "14.1.0" + "@react-native-community/cli-tools" "14.1.0" + "@react-native-community/cli-types" "14.1.0" chalk "^4.1.2" commander "^9.4.1" + deepmerge "^4.3.0" execa "^5.0.0" - find-up "^4.1.0" + find-up "^5.0.0" fs-extra "^8.1.0" graceful-fs "^4.1.3" - prompts "^2.4.0" + prompts "^2.4.2" semver "^7.5.2" -"@react-native/assets-registry@^0.72.0": - version "0.72.0" - resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.72.0.tgz#c82a76a1d86ec0c3907be76f7faf97a32bbed05d" - integrity sha512-Im93xRJuHHxb1wniGhBMsxLwcfzdYreSZVQGDoMJgkd6+Iky61LInGEHnQCTN0fKNYF1Dvcofb4uMmE1RQHXHQ== +"@react-native/assets-registry@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.75.4.tgz#d48b8765e030f8d305f34659d4ce50ebb82ccb34" + integrity sha512-WX6/LNHwyjislSFM+h3qQjBiPaXXPJW5ZV4TdgNKb6QOPO0g1KGYRQj44cI2xSpZ3fcWrvQFZfQgSMbVK9Sg7A== + +"@react-native/babel-plugin-codegen@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.75.4.tgz#c9916d1c2c043a0b777fe0134fe4aaee6a82ae6c" + integrity sha512-gu5ZRIdr7+ufi09DJROhfDtbF4biTnCDJqtqcmtsku4cXOXPHE36QbC/vAmKEZ0PMPURBI8lwF2wfaeHLn7gig== + dependencies: + "@react-native/codegen" "0.75.4" + +"@react-native/babel-preset@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.75.4.tgz#6e49a73dbbe70e2765686a67088c67fe83085e97" + integrity sha512-UtyYCDJ3rZIeggyFEfh/q5t/FZ5a1h9F8EI37Nbrwyk/OKPH+1XS4PbHROHJzBARlJwOAfmT75+ovYUO0eakJA== + dependencies: + "@babel/core" "^7.20.0" + "@babel/plugin-proposal-export-default-from" "^7.0.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-default-from" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.18.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-syntax-optional-chaining" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-async-generator-functions" "^7.24.3" + "@babel/plugin-transform-async-to-generator" "^7.20.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-class-properties" "^7.24.1" + "@babel/plugin-transform-classes" "^7.0.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.20.0" + "@babel/plugin-transform-flow-strip-types" "^7.20.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.0.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-logical-assignment-operators" "^7.24.1" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.1" + "@babel/plugin-transform-numeric-separator" "^7.24.1" + "@babel/plugin-transform-object-rest-spread" "^7.24.5" + "@babel/plugin-transform-optional-catch-binding" "^7.24.1" + "@babel/plugin-transform-optional-chaining" "^7.24.5" + "@babel/plugin-transform-parameters" "^7.0.0" + "@babel/plugin-transform-private-methods" "^7.22.5" + "@babel/plugin-transform-private-property-in-object" "^7.22.11" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-react-jsx-self" "^7.0.0" + "@babel/plugin-transform-react-jsx-source" "^7.0.0" + "@babel/plugin-transform-regenerator" "^7.20.0" + "@babel/plugin-transform-runtime" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-sticky-regex" "^7.0.0" + "@babel/plugin-transform-typescript" "^7.5.0" + "@babel/plugin-transform-unicode-regex" "^7.0.0" + "@babel/template" "^7.0.0" + "@react-native/babel-plugin-codegen" "0.75.4" + babel-plugin-transform-flow-enums "^0.0.2" + react-refresh "^0.14.0" -"@react-native/codegen@^0.72.7": - version "0.72.7" - resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.72.7.tgz#b6832ce631ac63143024ea094a6b5480a780e589" - integrity sha512-O7xNcGeXGbY+VoqBGNlZ3O05gxfATlwE1Q1qQf5E38dK+tXn5BY4u0jaQ9DPjfE8pBba8g/BYI1N44lynidMtg== +"@react-native/codegen@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.75.4.tgz#2eae0800fbddfd2f3946d9f2a229cae21feacd45" + integrity sha512-0FplNAD/S5FUvm8YIn6uyarOcP4jdJPqWz17K4a/Gp2KSsG/JJKEskX3aj5wpePzVfNQl3WyvBJ0whODdCocIA== dependencies: "@babel/parser" "^7.20.0" - flow-parser "^0.206.0" + glob "^7.1.1" + hermes-parser "0.22.0" + invariant "^2.2.4" jscodeshift "^0.14.0" + mkdirp "^0.5.1" nullthrows "^1.1.1" + yargs "^17.6.2" -"@react-native/gradle-plugin@^0.72.11": - version "0.72.11" - resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.72.11.tgz#c063ef12778706611de7a1e42b74b14d9405fb9f" - integrity sha512-P9iRnxiR2w7EHcZ0mJ+fmbPzMby77ZzV6y9sJI3lVLJzF7TLSdbwcQyD3lwMsiL+q5lKUHoZJS4sYmih+P2HXw== +"@react-native/community-cli-plugin@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.75.4.tgz#aaaebeaf3d39c9c3e39b5b2fc8779119be51c87e" + integrity sha512-k/hevYPjEpW0MNVVyb3v9PJosOP+FzenS7+oqYNLXdEmgTnGHrAtYX9ABrJJgzeJt7I6g8g+RDvm8PSE+tnM5w== + dependencies: + "@react-native-community/cli-server-api" "14.1.0" + "@react-native-community/cli-tools" "14.1.0" + "@react-native/dev-middleware" "0.75.4" + "@react-native/metro-babel-transformer" "0.75.4" + chalk "^4.0.0" + execa "^5.1.1" + metro "^0.80.3" + metro-config "^0.80.3" + metro-core "^0.80.3" + node-fetch "^2.2.0" + readline "^1.3.0" -"@react-native/js-polyfills@^0.72.1": - version "0.72.1" - resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.72.1.tgz#905343ef0c51256f128256330fccbdb35b922291" - integrity sha512-cRPZh2rBswFnGt5X5EUEPs0r+pAsXxYsifv/fgy9ZLQokuT52bPH+9xjDR+7TafRua5CttGW83wP4TntRcWNDA== +"@react-native/debugger-frontend@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.75.4.tgz#81b0aa239d171a41a7b14333bd45b3aa5e77072a" + integrity sha512-QfGurR5hV6bhMPn/6VxS2RomYrPRFGwA03jJr+zKyWHnxDAu5jOqYVyKAktIIbhYe5sPp78QVl1ZYuhcnsRbEw== -"@react-native/normalize-colors@<0.73.0", "@react-native/normalize-colors@^0.72.0": - version "0.72.0" - resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.72.0.tgz#14294b7ed3c1d92176d2a00df48456e8d7d62212" - integrity sha512-285lfdqSXaqKuBbbtP9qL2tDrfxdOFtIMvkKadtleRQkdOxx+uzGvFr82KHmc/sSiMtfXGp7JnFYWVh4sFl7Yw== +"@react-native/dev-middleware@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.75.4.tgz#fee908bbafb9cb4fe20a3add755aadb16c440a60" + integrity sha512-UhyBeQOG2wNcvrUGw3+IBrHBk/lIu7hHGmWt4j8W9Aqv9BwktHKkPyko+5A1yoUeO1O/VDnHWYqWeOejcA9wpQ== + dependencies: + "@isaacs/ttlcache" "^1.4.1" + "@react-native/debugger-frontend" "0.75.4" + chrome-launcher "^0.15.2" + chromium-edge-launcher "^0.2.0" + connect "^3.6.5" + debug "^2.2.0" + node-fetch "^2.2.0" + nullthrows "^1.1.1" + open "^7.0.3" + selfsigned "^2.4.1" + serve-static "^1.13.1" + ws "^6.2.2" + +"@react-native/gradle-plugin@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.75.4.tgz#357d7d4c22059393113d44b077bb8e904aa1cd2c" + integrity sha512-kKTmw7cF7p1raT30DC0L6N+xiVXN7dlRy0J+hYPiCRRVHplwgvyS7pszjxfzwXmHFqOxwpxQVI3du8opsma1Mg== + +"@react-native/js-polyfills@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.75.4.tgz#de895d0728a14126d7b3c04fe17c0da7e806d994" + integrity sha512-NF5ID5FjcVHBYk1LQ4JMRjPmxBWEo4yoqW1m6vGOQZPT8D5Qs9afgx3f7gQatxbn3ivMh0FVbLW0zBx6LyxEzA== -"@react-native/virtualized-lists@^0.72.8": - version "0.72.8" - resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.72.8.tgz#a2c6a91ea0f1d40eb5a122fb063daedb92ed1dc3" - integrity sha512-J3Q4Bkuo99k7mu+jPS9gSUSgq+lLRSI/+ahXNwV92XgJ/8UgOTxu2LPwhJnBk/sQKxq7E8WkZBnBiozukQMqrw== +"@react-native/metro-babel-transformer@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.75.4.tgz#9283418536db31db8e39a879c8497483cfc736dc" + integrity sha512-O0WMW/K8Ny/MAAeRebqGEQhrbzcioxcPHZtos+EH2hWeBTEKHQV8fMYYxfYDabpr392qdhSBwg3LlXUD4U3PXQ== + dependencies: + "@babel/core" "^7.20.0" + "@react-native/babel-preset" "0.75.4" + hermes-parser "0.22.0" + nullthrows "^1.1.1" + +"@react-native/normalize-colors@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.75.4.tgz#e5eb01ee4309f2895c2d3aaf1b6449a5439c0176" + integrity sha512-90QrQDLg0/k9xqYesaKuIkayOSjD+FKa0hsHollbwT5h3kuGMY+lU7UZxnb8tU55Y1PKdvjYxqQsYWI/ql79zA== + +"@react-native/virtualized-lists@0.75.4": + version "0.75.4" + resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.75.4.tgz#9c6603d916c165ad2730a54b66104c990a860347" + integrity sha512-iEauRiXjvWG/iOH8bV+9MfepCS+72cuL5rhkrenYZS0NUnDcNjF+wtaoS9+Gx5z1UJOfEXxSmyXRtQJZne8SnA== dependencies: invariant "^2.2.4" nullthrows "^1.1.1" @@ -1552,6 +2002,13 @@ dependencies: "@types/istanbul-lib-report" "*" +"@types/node-forge@^1.3.0": + version "1.3.11" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" + integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ== + dependencies: + "@types/node" "*" + "@types/node@*": version "20.5.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.1.tgz#178d58ee7e4834152b0e8b4d30cbfab578b9bb30" @@ -1568,17 +2025,11 @@ integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== "@types/react@file:../../shared/node_modules/@types/react": - version "18.2.39" + version "18.3.11" dependencies: "@types/prop-types" "*" - "@types/scheduler" "*" csstype "^3.0.2" -"@types/scheduler@*": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" - integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== - "@types/stack-utils@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" @@ -1596,13 +2047,6 @@ dependencies: "@types/yargs-parser" "*" -"@types/yargs@^16.0.0": - version "16.0.5" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3" - integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== - dependencies: - "@types/yargs-parser" "*" - "@types/yargs@^17.0.8": version "17.0.24" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" @@ -1701,6 +2145,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1728,11 +2177,6 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== -async@^3.2.2: - version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== - babel-core@^7.0.0-bridge.0: version "7.0.0-bridge.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" @@ -1762,11 +2206,6 @@ babel-plugin-polyfill-regenerator@^0.5.2: dependencies: "@babel/helper-define-polyfill-provider" "^0.4.2" -babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: - version "7.0.0-beta.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf" - integrity sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ== - babel-plugin-transform-flow-enums@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz#d1d0cc9bdc799c850ca110d0ddc9f21b9ec3ef25" @@ -1774,45 +2213,12 @@ babel-plugin-transform-flow-enums@^0.0.2: dependencies: "@babel/plugin-syntax-flow" "^7.12.1" -babel-preset-fbjs@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz#38a14e5a7a3b285a3f3a86552d650dca5cf6111c" - integrity sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-syntax-class-properties" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoped-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-member-expression-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-super" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-property-literals" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.1.2, base64-js@^1.3.1: +base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -1858,6 +2264,16 @@ browserslist@^4.20.4, browserslist@^4.21.10, browserslist@^4.21.9: node-releases "^2.0.13" update-browserslist-db "^1.0.11" +browserslist@^4.23.1: + version "4.23.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" + integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== + dependencies: + caniuse-lite "^1.0.30001646" + electron-to-chromium "^1.5.4" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -1922,6 +2338,11 @@ caniuse-lite@^1.0.30001517: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz#44b87a406c901269adcdb834713e23582dd71856" integrity sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg== +caniuse-lite@^1.0.30001646: + version "1.0.30001653" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz#b8af452f8f33b1c77f122780a4aecebea0caca56" + integrity sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw== + chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -1939,6 +2360,28 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +chrome-launcher@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/chrome-launcher/-/chrome-launcher-0.15.2.tgz#4e6404e32200095fdce7f6a1e1004f9bd36fa5da" + integrity sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ== + dependencies: + "@types/node" "*" + escape-string-regexp "^4.0.0" + is-wsl "^2.2.0" + lighthouse-logger "^1.0.0" + +chromium-edge-launcher@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/chromium-edge-launcher/-/chromium-edge-launcher-0.2.0.tgz#0c378f28c99aefc360705fa155de0113997f62fc" + integrity sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg== + dependencies: + "@types/node" "*" + escape-string-regexp "^4.0.0" + is-wsl "^2.2.0" + lighthouse-logger "^1.0.0" + mkdirp "^1.0.4" + rimraf "^3.0.2" + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -2042,11 +2485,6 @@ commander@^9.4.1: resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== -commander@~2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" - integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -2104,7 +2542,7 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig@^5.0.5, cosmiconfig@^5.1.0: +cosmiconfig@^5.0.5: version "5.2.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== @@ -2125,6 +2563,16 @@ cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" +cosmiconfig@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz#34c3fc58287b915f3ae905ab6dc3de258b55ad9d" + integrity sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg== + dependencies: + env-paths "^2.2.1" + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -2144,7 +2592,7 @@ dayjs@^1.8.15: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a" integrity sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA== -debug@2.6.9, debug@^2.2.0: +debug@2.6.9, debug@^2.2.0, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -2158,6 +2606,13 @@ debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" +debug@^4.3.1: + version "4.3.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" + integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + dependencies: + ms "2.1.2" + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -2204,15 +2659,6 @@ depd@2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -deprecated-react-native-prop-types@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-4.2.3.tgz#0ef845c1a80ef1636bd09060e4cdf70f9727e5ad" - integrity sha512-2rLTiMKidIFFYpIVM69UnQKngLqQfL6I11Ch8wGSBftS18FUXda+o2we2950X+1dmbgps28niI3qwyH4eX3Z1g== - dependencies: - "@react-native/normalize-colors" "<0.73.0" - invariant "^2.2.4" - prop-types "^15.8.1" - destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -2235,6 +2681,11 @@ electron-to-chromium@^1.4.477: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.496.tgz#a57534b70d2bdee7e1ad7dbd4c91e560cbd08db1" integrity sha512-qeXC3Zbykq44RCrBa4kr8v/dWzYJA8rAwpyh9Qd+NKWoJfjG5vvJqy9XOJ9H4P/lqulZBCgUWAYi+FeK5AuJ8g== +electron-to-chromium@^1.5.4: + version "1.5.13" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz#1abf0410c5344b2b829b7247e031f02810d442e6" + integrity sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -2252,10 +2703,15 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -envinfo@^7.7.2: - version "7.10.0" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13" - integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw== +env-paths@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +envinfo@^7.13.0: + version "7.13.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.13.0.tgz#81fbb81e5da35d74e814941aeab7c325a606fb31" + integrity sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q== error-ex@^1.3.1: version "1.3.2" @@ -2284,6 +2740,11 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2299,6 +2760,11 @@ escape-string-regexp@^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== + esprima@^4.0.0, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -2334,7 +2800,7 @@ execa@^4.0.3: signal-exit "^3.0.2" strip-final-newline "^2.0.0" -execa@^5.0.0: +execa@^5.0.0, execa@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -2360,10 +2826,21 @@ fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" -fast-xml-parser@^4.0.12: - version "4.2.7" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.7.tgz#871f2ca299dc4334b29f8da3658c164e68395167" - integrity sha512-J8r6BriSLO1uj2miOk1NW0YVm8AGOOu3Si2HQp/cSmo6EA4m3fcwu2WKjJ4RK9wMLBtg69y1kS8baDiQBR41Ig== +fast-glob@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-xml-parser@^4.4.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz#2882b7d01a6825dfdf909638f2de0256351def37" + integrity sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg== dependencies: strnum "^1.0.5" @@ -2433,21 +2910,16 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -flow-enums-runtime@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/flow-enums-runtime/-/flow-enums-runtime-0.0.5.tgz#95884bfcc82edaf27eef7e1dd09732331cfbafbc" - integrity sha512-PSZF9ZuaZD03sT9YaIs0FrGJ7lSUw7rHZIex+73UYVXg46eL/wxN5PaVcPJFudE2cJu5f0fezitV5aBkLHPUOQ== +flow-enums-runtime@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz#5bb0cd1b0a3e471330f4d109039b7eba5cb3e787" + integrity sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw== flow-parser@0.*: version "0.214.0" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.214.0.tgz#455efc841ec015c62f6dec022cf6c61480f231a2" integrity sha512-RW1Dh6BuT14DA7+gtNRKzgzvG3GTPdrceHCi4ddZ9VFGQ9HtO5L8wzxMGsor7XtInIrbWZZCSak0oxnBF7tApw== -flow-parser@^0.206.0: - version "0.206.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.206.0.tgz#f4f794f8026535278393308e01ea72f31000bfef" - integrity sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w== - fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -2515,7 +2987,7 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" -glob@^7.1.3: +glob@^7.1.1, glob@^7.1.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -2577,24 +3049,29 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hermes-estree@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.12.0.tgz#8a289f9aee854854422345e6995a48613bac2ca8" - integrity sha512-+e8xR6SCen0wyAKrMT3UD0ZCCLymKhRgjEB5sS28rKiFir/fXgLoeRilRUssFCILmGHb+OvHDUlhxs0+IEyvQw== +hermes-estree@0.20.1: + version "0.20.1" + resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.20.1.tgz#0b9a544cf883a779a8e1444b915fa365bef7f72d" + integrity sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg== + +hermes-estree@0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.22.0.tgz#38559502b119f728901d2cfe2ef422f277802a1d" + integrity sha512-FLBt5X9OfA8BERUdc6aZS36Xz3rRuB0Y/mfocSADWEJfomc1xfene33GdyAmtTkKTBXTN/EgAy+rjTKkkZJHlw== -hermes-parser@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.12.0.tgz#114dc26697cfb41a6302c215b859b74224383773" - integrity sha512-d4PHnwq6SnDLhYl3LHNHvOg7nQ6rcI7QVil418REYksv0Mh3cEkHDcuhGxNQ3vgnLSLl4QSvDrFCwQNYdpWlzw== +hermes-parser@0.20.1: + version "0.20.1" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.20.1.tgz#ad10597b99f718b91e283f81cbe636c50c3cff92" + integrity sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA== dependencies: - hermes-estree "0.12.0" + hermes-estree "0.20.1" -hermes-profile-transformer@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/hermes-profile-transformer/-/hermes-profile-transformer-0.0.6.tgz#bd0f5ecceda80dd0ddaae443469ab26fb38fc27b" - integrity sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ== +hermes-parser@0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.22.0.tgz#fc8e0e6c7bfa8db85b04c9f9544a102c4fcb4040" + integrity sha512-gn5RfZiEXCsIWsFGsKiykekktUoh0PdFWYocXsUdZIyWSckT6UIyPcyyUIPSR3kpnELWeK3n3ztAse7Mat6PSA== dependencies: - source-map "^0.7.3" + hermes-estree "0.22.0" http-errors@2.0.0: version "2.0.0" @@ -2642,7 +3119,7 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.2.1: +import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -2680,11 +3157,6 @@ invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -ip@^1.1.5: - version "1.1.8" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" - integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== - is-absolute@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" @@ -2710,6 +3182,11 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw== +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -2809,6 +3286,13 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== +is-wsl@^2.1.1, 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: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -2824,94 +3308,78 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -jest-environment-node@^29.2.1: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.6.2.tgz#a9ea2cabff39b08eca14ccb32c8ceb924c8bb1ad" - integrity sha512-YGdFeZ3T9a+/612c5mTQIllvWkddPbYcN2v95ZH24oWMbGA4GGS2XdIF92QMhUhvrjjuQWYgUGW2zawOyH63MQ== +jest-environment-node@^29.6.3: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== dependencies: - "@jest/environment" "^29.6.2" - "@jest/fake-timers" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" - jest-mock "^29.6.2" - jest-util "^29.6.2" + jest-mock "^29.7.0" + jest-util "^29.7.0" -jest-get-type@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" - integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== -jest-message-util@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.2.tgz#af7adc2209c552f3f5ae31e77cf0a261f23dc2bb" - integrity sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ== +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.6.2" + pretty-format "^29.7.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.6.2.tgz#ef9c9b4d38c34a2ad61010a021866dad41ce5e00" - integrity sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg== - dependencies: - "@jest/types" "^29.6.1" - "@types/node" "*" - jest-util "^29.6.2" - -jest-regex-util@^27.0.6: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" - integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== - -jest-util@^27.2.0: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" - integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== +jest-mock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" + integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== dependencies: - "@jest/types" "^27.5.1" + "@jest/types" "^29.6.3" "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" + jest-util "^29.7.0" -jest-util@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.2.tgz#8a052df8fff2eebe446769fd88814521a517664d" - integrity sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w== +jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^29.2.1: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.6.2.tgz#25d972af35b2415b83b1373baf1a47bb266c1082" - integrity sha512-vGz0yMN5fUFRRbpJDPwxMpgSXW1LDKROHfBopAvDcmD6s+B/s8WJrwi+4bfH4SdInBA5C3P3BI19dBtKzx1Arg== +jest-validate@^29.6.3: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^29.4.3" + jest-get-type "^29.6.3" leven "^3.1.0" - pretty-format "^29.6.2" + pretty-format "^29.7.0" -jest-worker@^27.2.0: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== +jest-worker@^29.6.3: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== dependencies: "@types/node" "*" + jest-util "^29.7.0" merge-stream "^2.0.0" supports-color "^8.0.0" @@ -2944,6 +3412,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsc-android@^250231.0.0: version "250231.0.0" resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-250231.0.0.tgz#91720f8df382a108872fa4b3f558f33ba5e95262" @@ -3040,6 +3515,14 @@ leven@^3.1.0: resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== +lighthouse-logger@^1.0.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz#aef90f9e97cd81db367c7634292ee22079280aaa" + integrity sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g== + dependencies: + debug "^2.6.9" + marky "^1.2.2" + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -3094,7 +3577,7 @@ logkitty@^0.7.1: dayjs "^1.8.15" yargs "^15.1.0" -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -3130,6 +3613,11 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" +marky@^1.2.2: + version "1.2.5" + resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.5.tgz#55796b688cbd72390d2d399eaaf1832c9413e3c0" + integrity sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q== + memoize-one@^5.0.0: version "5.2.1" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" @@ -3145,62 +3633,60 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -metro-babel-transformer@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.76.8.tgz#5efd1027353b36b73706164ef09c290dceac096a" - integrity sha512-Hh6PW34Ug/nShlBGxkwQJSgPGAzSJ9FwQXhUImkzdsDgVu6zj5bx258J8cJVSandjNoQ8nbaHK6CaHlnbZKbyA== +metro-babel-transformer@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.80.9.tgz#7051ba377b7d2140abd23f4846bbbb1e81fea99b" + integrity sha512-d76BSm64KZam1nifRZlNJmtwIgAeZhZG3fi3K+EmPOlrR8rDtBxQHDSN3fSGeNB9CirdTyabTMQCkCup6BXFSQ== dependencies: "@babel/core" "^7.20.0" - hermes-parser "0.12.0" + hermes-parser "0.20.1" nullthrows "^1.1.1" -metro-cache-key@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.76.8.tgz#8a0a5e991c06f56fcc584acadacb313c312bdc16" - integrity sha512-buKQ5xentPig9G6T37Ww/R/bC+/V1MA5xU/D8zjnhlelsrPG6w6LtHUS61ID3zZcMZqYaELWk5UIadIdDsaaLw== +metro-cache-key@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.80.9.tgz#a04cbb0a7828509bb10dde9789ef761c0c60bc3d" + integrity sha512-hRcYGhEiWIdM87hU0fBlcGr+tHDEAT+7LYNCW89p5JhErFt/QaAkVx4fb5bW3YtXGv5BTV7AspWPERoIb99CXg== -metro-cache@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.76.8.tgz#296c1c189db2053b89735a8f33dbe82575f53661" - integrity sha512-QBJSJIVNH7Hc/Yo6br/U/qQDUpiUdRgZ2ZBJmvAbmAKp2XDzsapnMwK/3BGj8JNWJF7OLrqrYHsRsukSbUBpvQ== +metro-cache@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.80.9.tgz#b914318a90dbcd51b4c27836184519c441ba5123" + integrity sha512-ujEdSI43QwI+Dj2xuNax8LMo8UgKuXJEdxJkzGPU6iIx42nYa1byQ+aADv/iPh5sh5a//h5FopraW5voXSgm2w== dependencies: - metro-core "0.76.8" + metro-core "0.80.9" rimraf "^3.0.2" -metro-config@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.76.8.tgz#20bd5397fcc6096f98d2a813a7cecb38b8af062d" - integrity sha512-SL1lfKB0qGHALcAk2zBqVgQZpazDYvYFGwCK1ikz0S6Y/CM2i2/HwuZN31kpX6z3mqjv/6KvlzaKoTb1otuSAA== +metro-config@0.80.9, metro-config@^0.80.3: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.80.9.tgz#4eb6948b0ddc7c38d9d4ba8ddf22a67ca1c2bc06" + integrity sha512-28wW7CqS3eJrunRGnsibWldqgwRP9ywBEf7kg+uzUHkSFJNKPM1K3UNSngHmH0EZjomizqQA2Zi6/y6VdZMolg== dependencies: connect "^3.6.5" cosmiconfig "^5.0.5" - jest-validate "^29.2.1" - metro "0.76.8" - metro-cache "0.76.8" - metro-core "0.76.8" - metro-runtime "0.76.8" + jest-validate "^29.6.3" + metro "0.80.9" + metro-cache "0.80.9" + metro-core "0.80.9" + metro-runtime "0.80.9" -metro-core@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.76.8.tgz#917c8157c63406cb223522835abb8e7c6291dcad" - integrity sha512-sl2QLFI3d1b1XUUGxwzw/KbaXXU/bvFYrSKz6Sg19AdYGWFyzsgZ1VISRIDf+HWm4R/TJXluhWMEkEtZuqi3qA== +metro-core@0.80.9, metro-core@^0.80.3: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.80.9.tgz#3af21d0b09d71ec9c0840f028bffb36bc3619727" + integrity sha512-tbltWQn+XTdULkGdzHIxlxk4SdnKxttvQQV3wpqqFbHDteR4gwCyTR2RyYJvxgU7HELfHtrVbqgqAdlPByUSbg== dependencies: lodash.throttle "^4.1.1" - metro-resolver "0.76.8" + metro-resolver "0.80.9" -metro-file-map@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.76.8.tgz#a1db1185b6c316904ba6b53d628e5d1323991d79" - integrity sha512-A/xP1YNEVwO1SUV9/YYo6/Y1MmzhL4ZnVgcJC3VmHp/BYVOXVStzgVbWv2wILe56IIMkfXU+jpXrGKKYhFyHVw== +metro-file-map@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.80.9.tgz#ed8783f6e35dfc005794344c2a9fcd6e914885aa" + integrity sha512-sBUjVtQMHagItJH/wGU9sn3k2u0nrCl0CdR4SFMO1tksXLKbkigyQx4cbpcyPVOAmGTVuy3jyvBlELaGCAhplQ== dependencies: anymatch "^3.0.3" debug "^2.2.0" fb-watchman "^2.0.0" graceful-fs "^4.2.4" invariant "^2.2.4" - jest-regex-util "^27.0.6" - jest-util "^27.2.0" - jest-worker "^27.2.0" + jest-worker "^29.6.3" micromatch "^4.0.4" node-abort-controller "^3.1.1" nullthrows "^1.1.1" @@ -3208,130 +3694,55 @@ metro-file-map@0.76.8: optionalDependencies: fsevents "^2.3.2" -metro-inspector-proxy@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.76.8.tgz#6b8678a7461b0b42f913a7881cc9319b4d3cddff" - integrity sha512-Us5o5UEd4Smgn1+TfHX4LvVPoWVo9VsVMn4Ldbk0g5CQx3Gu0ygc/ei2AKPGTwsOZmKxJeACj7yMH2kgxQP/iw== - dependencies: - connect "^3.6.5" - debug "^2.2.0" - node-fetch "^2.2.0" - ws "^7.5.1" - yargs "^17.6.2" - -metro-minify-terser@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.76.8.tgz#915ab4d1419257fc6a0b9fa15827b83fe69814bf" - integrity sha512-Orbvg18qXHCrSj1KbaeSDVYRy/gkro2PC7Fy2tDSH1c9RB4aH8tuMOIXnKJE+1SXxBtjWmQ5Yirwkth2DyyEZA== +metro-minify-terser@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.80.9.tgz#2b7798cba2bd4bd69cc5ce05a45bf66291542f83" + integrity sha512-FEeCeFbkvvPuhjixZ1FYrXtO0araTpV6UbcnGgDUpH7s7eR5FG/PiJz3TsuuPP/HwCK19cZtQydcA2QrCw446A== dependencies: terser "^5.15.0" -metro-minify-uglify@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.76.8.tgz#74745045ea2dd29f8783db483b2fce58385ba695" - integrity sha512-6l8/bEvtVaTSuhG1FqS0+Mc8lZ3Bl4RI8SeRIifVLC21eeSDp4CEBUWSGjpFyUDfi6R5dXzYaFnSgMNyfxADiQ== - dependencies: - uglify-es "^3.1.9" - -metro-react-native-babel-preset@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.76.8.tgz#7476efae14363cbdfeeec403b4f01d7348e6c048" - integrity sha512-Ptza08GgqzxEdK8apYsjTx2S8WDUlS2ilBlu9DR1CUcHmg4g3kOkFylZroogVAUKtpYQNYwAvdsjmrSdDNtiAg== - dependencies: - "@babel/core" "^7.20.0" - "@babel/plugin-proposal-async-generator-functions" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.18.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.0" - "@babel/plugin-proposal-numeric-separator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.20.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.20.0" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.18.0" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-syntax-optional-chaining" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.20.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.20.0" - "@babel/plugin-transform-flow-strip-types" "^7.20.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-self" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.5.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - babel-plugin-transform-flow-enums "^0.0.2" - react-refresh "^0.4.0" - -metro-react-native-babel-transformer@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.76.8.tgz#c3a98e1f4cd5faf1e21eba8e004b94a90c4db69b" - integrity sha512-3h+LfS1WG1PAzhq8QF0kfXjxuXetbY/lgz8vYMQhgrMMp17WM1DNJD0gjx8tOGYbpbBC1qesJ45KMS4o5TA73A== - dependencies: - "@babel/core" "^7.20.0" - babel-preset-fbjs "^3.4.0" - hermes-parser "0.12.0" - metro-react-native-babel-preset "0.76.8" - nullthrows "^1.1.1" - -metro-resolver@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.76.8.tgz#0862755b9b84e26853978322464fb37c6fdad76d" - integrity sha512-KccOqc10vrzS7ZhG2NSnL2dh3uVydarB7nOhjreQ7C4zyWuiW9XpLC4h47KtGQv3Rnv/NDLJYeDqaJ4/+140HQ== +metro-resolver@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.80.9.tgz#bae9120a0553e0cb59da6429e83a7e97465cc1a8" + integrity sha512-wAPIjkN59BQN6gocVsAvvpZ1+LQkkqUaswlT++cJafE/e54GoVkMNCmrR4BsgQHr9DknZ5Um/nKueeN7kaEz9w== -metro-runtime@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.76.8.tgz#74b2d301a2be5f3bbde91b8f1312106f8ffe50c3" - integrity sha512-XKahvB+iuYJSCr3QqCpROli4B4zASAYpkK+j3a0CJmokxCDNbgyI4Fp88uIL6rNaZfN0Mv35S0b99SdFXIfHjg== +metro-runtime@0.80.9, metro-runtime@^0.80.3: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.80.9.tgz#665312bd4e4d38fea921b3153d6ab47846eb4f08" + integrity sha512-8PTVIgrVcyU+X/rVCy/9yxNlvXsBCk5JwwkbAm/Dm+Abo6NBGtNjWF0M1Xo/NWCb4phamNWcD7cHdR91HhbJvg== dependencies: "@babel/runtime" "^7.0.0" - react-refresh "^0.4.0" -metro-source-map@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.76.8.tgz#f085800152a6ba0b41ca26833874d31ec36c5a53" - integrity sha512-Hh0ncPsHPVf6wXQSqJqB3K9Zbudht4aUtNpNXYXSxH+pteWqGAXnjtPsRAnCsCWl38wL0jYF0rJDdMajUI3BDw== +metro-source-map@0.80.9, metro-source-map@^0.80.3: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.80.9.tgz#df8f673137548f37ab9f9dcfa771b354a452cfab" + integrity sha512-RMn+XS4VTJIwMPOUSj61xlxgBvPeY4G6s5uIn6kt6HB6A/k9ekhr65UkkDD7WzHYs3a9o869qU8tvOZvqeQzgw== dependencies: "@babel/traverse" "^7.20.0" "@babel/types" "^7.20.0" invariant "^2.2.4" - metro-symbolicate "0.76.8" + metro-symbolicate "0.80.9" nullthrows "^1.1.1" - ob1 "0.76.8" + ob1 "0.80.9" source-map "^0.5.6" vlq "^1.0.0" -metro-symbolicate@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.76.8.tgz#f102ac1a306d51597ecc8fdf961c0a88bddbca03" - integrity sha512-LrRL3uy2VkzrIXVlxoPtqb40J6Bf1mlPNmUQewipc3qfKKFgtPHBackqDy1YL0njDsWopCKcfGtFYLn0PTUn3w== +metro-symbolicate@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.80.9.tgz#8d1d19d26ebb36b9d13dbd29814fdd71d6009db7" + integrity sha512-Ykae12rdqSs98hg41RKEToojuIW85wNdmSe/eHUgMkzbvCFNVgcC0w3dKZEhSsqQOXapXRlLtHkaHLil0UD/EA== dependencies: invariant "^2.2.4" - metro-source-map "0.76.8" + metro-source-map "0.80.9" nullthrows "^1.1.1" source-map "^0.5.6" through2 "^2.0.1" vlq "^1.0.0" -metro-transform-plugins@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.76.8.tgz#d77c28a6547a8e3b72250f740fcfbd7f5408f8ba" - integrity sha512-PlkGTQNqS51Bx4vuufSQCdSn2R2rt7korzngo+b5GCkeX5pjinPjnO2kNhQ8l+5bO0iUD/WZ9nsM2PGGKIkWFA== +metro-transform-plugins@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.80.9.tgz#473a2c0a9e48043210547abe61cdeedb77725422" + integrity sha512-UlDk/uc8UdfLNJhPbF3tvwajyuuygBcyp+yBuS/q0z3QSuN/EbLllY3rK8OTD9n4h00qZ/qgxGv/lMFJkwP4vg== dependencies: "@babel/core" "^7.20.0" "@babel/generator" "^7.20.0" @@ -3339,28 +3750,28 @@ metro-transform-plugins@0.76.8: "@babel/traverse" "^7.20.0" nullthrows "^1.1.1" -metro-transform-worker@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.76.8.tgz#b9012a196cee205170d0c899b8b175b9305acdea" - integrity sha512-mE1fxVAnJKmwwJyDtThildxxos9+DGs9+vTrx2ktSFMEVTtXS/bIv2W6hux1pqivqAfyJpTeACXHk5u2DgGvIQ== +metro-transform-worker@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.80.9.tgz#f1d8ef4f77228bb7e1d20d3c06934166e8ee3b28" + integrity sha512-c/IrzMUVnI0hSVVit4TXzt3A1GiUltGVlzCmLJWxNrBGHGrJhvgePj38+GXl1Xf4Fd4vx6qLUkKMQ3ux73bFLQ== dependencies: "@babel/core" "^7.20.0" "@babel/generator" "^7.20.0" "@babel/parser" "^7.20.0" "@babel/types" "^7.20.0" - babel-preset-fbjs "^3.4.0" - metro "0.76.8" - metro-babel-transformer "0.76.8" - metro-cache "0.76.8" - metro-cache-key "0.76.8" - metro-source-map "0.76.8" - metro-transform-plugins "0.76.8" + metro "0.80.9" + metro-babel-transformer "0.80.9" + metro-cache "0.80.9" + metro-cache-key "0.80.9" + metro-minify-terser "0.80.9" + metro-source-map "0.80.9" + metro-transform-plugins "0.80.9" nullthrows "^1.1.1" -metro@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.76.8.tgz#ba526808b99977ca3f9ac5a7432fd02a340d13a6" - integrity sha512-oQA3gLzrrYv3qKtuWArMgHPbHu8odZOD9AoavrqSFllkPgOtmkBvNNDLCELqv5SjBfqjISNffypg+5UGG3y0pg== +metro@0.80.9, metro@^0.80.3: + version "0.80.9" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.80.9.tgz#de3c2011df62036520d51d040d2dde0d015aecb6" + integrity sha512-Bc57Xf3GO2Xe4UWQsBj/oW6YfLPABEu8jfDVDiNmJvoQW4CO34oDPuYKe4KlXzXhcuNsqOtSxpbjCRRVjhhREg== dependencies: "@babel/code-frame" "^7.0.0" "@babel/core" "^7.20.0" @@ -3370,7 +3781,6 @@ metro@0.76.8: "@babel/traverse" "^7.20.0" "@babel/types" "^7.20.0" accepts "^1.3.7" - async "^3.2.2" chalk "^4.0.0" ci-info "^2.0.0" connect "^3.6.5" @@ -3378,28 +3788,24 @@ metro@0.76.8: denodeify "^1.2.1" error-stack-parser "^2.0.6" graceful-fs "^4.2.4" - hermes-parser "0.12.0" + hermes-parser "0.20.1" image-size "^1.0.2" invariant "^2.2.4" - jest-worker "^27.2.0" + jest-worker "^29.6.3" jsc-safe-url "^0.2.2" lodash.throttle "^4.1.1" - metro-babel-transformer "0.76.8" - metro-cache "0.76.8" - metro-cache-key "0.76.8" - metro-config "0.76.8" - metro-core "0.76.8" - metro-file-map "0.76.8" - metro-inspector-proxy "0.76.8" - metro-minify-terser "0.76.8" - metro-minify-uglify "0.76.8" - metro-react-native-babel-preset "0.76.8" - metro-resolver "0.76.8" - metro-runtime "0.76.8" - metro-source-map "0.76.8" - metro-symbolicate "0.76.8" - metro-transform-plugins "0.76.8" - metro-transform-worker "0.76.8" + metro-babel-transformer "0.80.9" + metro-cache "0.80.9" + metro-cache-key "0.80.9" + metro-config "0.80.9" + metro-core "0.80.9" + metro-file-map "0.80.9" + metro-resolver "0.80.9" + metro-runtime "0.80.9" + metro-source-map "0.80.9" + metro-symbolicate "0.80.9" + metro-transform-plugins "0.80.9" + metro-transform-worker "0.80.9" mime-types "^2.1.27" node-fetch "^2.2.0" nullthrows "^1.1.1" @@ -3472,6 +3878,11 @@ mkdirp@^0.5.1: dependencies: minimist "^1.2.6" +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -3514,13 +3925,18 @@ node-dir@^0.1.17: dependencies: minimatch "^3.0.2" -node-fetch@^2.2.0, node-fetch@^2.6.0: +node-fetch@^2.2.0: version "2.6.13" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.13.tgz#a20acbbec73c2e09f9007de5cda17104122e0010" integrity sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA== dependencies: whatwg-url "^5.0.0" +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -3531,6 +3947,11 @@ node-releases@^2.0.13: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== + node-stream-zip@^1.9.1: version "1.15.0" resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.15.0.tgz#158adb88ed8004c6c49a396b50a6a5de3bca33ea" @@ -3553,15 +3974,10 @@ nullthrows@^1.1.1: resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== -ob1@0.76.8: - version "0.76.8" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.76.8.tgz#ac4c459465b1c0e2c29aaa527e09fc463d3ffec8" - integrity sha512-dlBkJJV5M/msj9KYA9upc+nUWVwuOFFTbu28X6kZeGwcuW+JxaHSBZ70SYQnk5M+j5JbNLR6yKHmgW4M5E7X5g== - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== +ob1@0.80.9: + version "0.80.9" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.80.9.tgz#4ae3edd807536097674ff943509089f5d4e0649f" + integrity sha512-v9yOxowkZbxWhKOaaTyLjIm1aLy4ebMNcSn4NYJKOAI/Qv+SkfEfszpLr2GIxsccmb2Y2HA9qtsqiIJ80ucpVA== on-finished@2.4.1: version "2.4.1" @@ -3603,6 +4019,14 @@ open@^6.2.0: dependencies: is-wsl "^1.1.0" +open@^7.0.3: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + ora@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" @@ -3680,7 +4104,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -3730,6 +4154,11 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== + picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -3762,12 +4191,12 @@ pretty-format@^26.5.2, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" -pretty-format@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.2.tgz#3d5829261a8a4d89d8b9769064b29c50ed486a47" - integrity sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg== +pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== dependencies: - "@jest/schemas" "^29.6.0" + "@jest/schemas" "^29.6.3" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -3783,7 +4212,7 @@ promise@^8.3.0: dependencies: asap "~2.0.6" -prompts@^2.4.0, prompts@^2.4.2: +prompts@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== @@ -3791,15 +4220,6 @@ prompts@^2.4.0, prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.8.1: - version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -3825,29 +4245,24 @@ range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -react-devtools-core@^4.27.2: - version "4.28.0" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.28.0.tgz#3fa18709b24414adddadac33b6b9cea96db60f2f" - integrity sha512-E3C3X1skWBdBzwpOUbmXG8SgH6BtsluSMe+s6rRcujNKG1DGi8uIfhdhszkgDpAsMoE55hwqRUzeXCmETDBpTg== +react-devtools-core@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-5.3.1.tgz#d57f5b8f74f16e622bd6a7bc270161e4ba162666" + integrity sha512-7FSb9meX0btdBQLwdFOwt6bGqvRPabmVMMslv8fgoSPqXyuGpgQe36kx8gR86XPw7aV1yVouTp6fyZ0EH+NfUw== dependencies: shell-quote "^1.6.1" ws "^7" -"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - -react-is@^16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + react-native-builder-bob@^0.20.4: version "0.20.4" resolved "https://registry.yarnpkg.com/react-native-builder-bob/-/react-native-builder-bob-0.20.4.tgz#02df01b8dc02f1bb2d566f820e33c5d42bfb9c99" @@ -3876,60 +4291,55 @@ react-native-builder-bob@^0.20.4: jetifier "^2.0.0" "react-native@file:../../shared/node_modules/react-native": - version "0.72.7" - dependencies: - "@jest/create-cache-key-function" "^29.2.1" - "@react-native-community/cli" "11.3.10" - "@react-native-community/cli-platform-android" "11.3.10" - "@react-native-community/cli-platform-ios" "11.3.10" - "@react-native/assets-registry" "^0.72.0" - "@react-native/codegen" "^0.72.7" - "@react-native/gradle-plugin" "^0.72.11" - "@react-native/js-polyfills" "^0.72.1" - "@react-native/normalize-colors" "^0.72.0" - "@react-native/virtualized-lists" "^0.72.8" + version "0.75.4" + dependencies: + "@jest/create-cache-key-function" "^29.6.3" + "@react-native-community/cli" "14.1.0" + "@react-native-community/cli-platform-android" "14.1.0" + "@react-native-community/cli-platform-ios" "14.1.0" + "@react-native/assets-registry" "0.75.4" + "@react-native/codegen" "0.75.4" + "@react-native/community-cli-plugin" "0.75.4" + "@react-native/gradle-plugin" "0.75.4" + "@react-native/js-polyfills" "0.75.4" + "@react-native/normalize-colors" "0.75.4" + "@react-native/virtualized-lists" "0.75.4" abort-controller "^3.0.0" anser "^1.4.9" - base64-js "^1.1.2" - deprecated-react-native-prop-types "^4.2.3" + ansi-regex "^5.0.0" + base64-js "^1.5.1" + chalk "^4.0.0" + commander "^9.4.1" event-target-shim "^5.0.1" - flow-enums-runtime "^0.0.5" + flow-enums-runtime "^0.0.6" + glob "^7.1.1" invariant "^2.2.4" - jest-environment-node "^29.2.1" + jest-environment-node "^29.6.3" jsc-android "^250231.0.0" memoize-one "^5.0.0" - metro-runtime "0.76.8" - metro-source-map "0.76.8" + metro-runtime "^0.80.3" + metro-source-map "^0.80.3" mkdirp "^0.5.1" nullthrows "^1.1.1" pretty-format "^26.5.2" promise "^8.3.0" - react-devtools-core "^4.27.2" - react-refresh "^0.4.0" - react-shallow-renderer "^16.15.0" + react-devtools-core "^5.3.1" + react-refresh "^0.14.0" regenerator-runtime "^0.13.2" scheduler "0.24.0-canary-efb381bbf-20230505" + semver "^7.1.3" stacktrace-parser "^0.1.10" - use-sync-external-store "^1.0.0" whatwg-fetch "^3.0.0" ws "^6.2.2" yargs "^17.6.2" -react-refresh@^0.4.0: - version "0.4.3" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.3.tgz#966f1750c191672e76e16c2efa569150cc73ab53" - integrity sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA== - -react-shallow-renderer@^16.15.0: - version "16.15.0" - resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457" - integrity sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA== - dependencies: - object-assign "^4.1.1" - react-is "^16.12.0 || ^17.0.0 || ^18.0.0" +react-refresh@^0.14.0: + version "0.14.2" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" + integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== "react@file:../../shared/node_modules/react": - version "18.2.0" + version "18.3.1" dependencies: loose-envify "^1.1.0" @@ -4098,6 +4508,14 @@ scheduler@0.24.0-canary-efb381bbf-20230505: dependencies: loose-envify "^1.1.0" +selfsigned@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== + dependencies: + "@types/node-forge" "^1.3.0" + node-forge "^1" + semver@^5.6.0: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" @@ -4108,6 +4526,11 @@ semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.1.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + semver@^7.5.2: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" @@ -4225,11 +4648,6 @@ source-map@^0.6.0, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3: - version "0.7.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -4415,15 +4833,7 @@ type-fest@^0.7.1: integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== "typescript@file:../../shared/node_modules/typescript": - version "5.3.2" - -uglify-es@^3.1.9: - version "3.3.9" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" - integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ== - dependencies: - commander "~2.13.0" - source-map "~0.6.1" + version "5.6.3" unc-path-regex@^0.1.2: version "0.1.2" @@ -4476,10 +4886,13 @@ update-browserslist-db@^1.0.11: escalade "^3.1.1" picocolors "^1.0.0" -use-sync-external-store@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" - integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" @@ -4584,6 +4997,13 @@ ws@^6.2.2: dependencies: async-limiter "~1.0.0" +ws@^6.2.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.3.tgz#ccc96e4add5fd6fedbc491903075c85c5a11d9ee" + integrity sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA== + dependencies: + async-limiter "~1.0.0" + ws@^7, ws@^7.5.1: version "7.5.9" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" diff --git a/shared/.eslintignore b/shared/.eslintignore deleted file mode 100644 index ffcf69ad4572..000000000000 --- a/shared/.eslintignore +++ /dev/null @@ -1,18 +0,0 @@ -override-d.ts/** -babel.config.js -coverage -desktop/build/** -desktop/dist/** -desktop/release/** -desktop/renderer/renderer-load.desktop.js -desktop/webpack.config.babel.js -markdown/parser.js -metro.config.js -node_modules -react-native/react-native-contacts -react-native/wipe-cache.js -rn-cli.config.js -rn-transformer.js -common-adapters/icon.constants-gen.desktop.tsx -common-adapters/icon.constants-gen.native.tsx -common-adapters/icon.constants-gen.shared.tsx diff --git a/shared/.eslintrc.js b/shared/.eslintrc.js deleted file mode 100644 index 1945dc8e9ac4..000000000000 --- a/shared/.eslintrc.js +++ /dev/null @@ -1,318 +0,0 @@ -const isFixMode = process.argv.includes('--fix') -module.exports = { - env: {es6: true}, - extends: ['eslint:all', 'plugin:@typescript-eslint/recommended-type-checked', 'plugin:import/recommended'], - globals: { - __DEV__: false, - __HOT__: false, - __FILE_SUFFIX__: false, - cancelAnimationFrame: 'readonly', - requestAnimationFrame: 'readonly', - require: 'readonly', - }, - overrides: [ - { - files: ['*.tsx', '*.ts', '*.d.ts'], - rules: { - 'no-undef': 'off', // ts itself will catch this - 'no-unused-vars': 'off', // ts itself will catch this - }, - }, - ], - parser: '@typescript-eslint/parser', - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - plugins: ['promise', 'react', 'react-hooks', '@typescript-eslint', 'deprecation', 'import'], - reportUnusedDisableDirectives: true, - rules: { - '@typescript-eslint/adjacent-overload-signatures': 'off', - '@typescript-eslint/array-type': 'off', - '@typescript-eslint/await-thenable': 'error', - '@typescript-eslint/ban-ts-comment': 'off', - '@typescript-eslint/ban-tslint-comment': 'off', - '@typescript-eslint/ban-types': 'off', - '@typescript-eslint/brace-style': 'off', - '@typescript-eslint/class-literal-property-style': 'error', - '@typescript-eslint/comma-dangle': 'off', - '@typescript-eslint/comma-spacing': 'off', - '@typescript-eslint/consistent-indexed-object-style': 'off', - '@typescript-eslint/consistent-type-assertions': 'error', - '@typescript-eslint/consistent-type-definitions': 'off', - '@typescript-eslint/consistent-type-exports': 'error', - '@typescript-eslint/consistent-type-imports': 'error', - '@typescript-eslint/default-param-last': 'error', - '@typescript-eslint/dot-notation': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-member-accessibility': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/func-call-spacing': 'off', - '@typescript-eslint/indent': 'off', - '@typescript-eslint/init-declarations': 'off', - '@typescript-eslint/keyword-spacing': 'off', - '@typescript-eslint/lines-between-class-members': 'off', - '@typescript-eslint/member-delimiter-style': 'off', - '@typescript-eslint/member-ordering': 'off', - '@typescript-eslint/method-signature-style': 'error', - '@typescript-eslint/naming-convention': 'off', - '@typescript-eslint/no-array-constructor': 'error', - '@typescript-eslint/no-base-to-string': 'error', - '@typescript-eslint/no-confusing-non-null-assertion': 'off', - '@typescript-eslint/no-confusing-void-expression': 'off', - '@typescript-eslint/no-dupe-class-members': 'error', - '@typescript-eslint/no-dynamic-delete': 'error', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-empty-interface': 'error', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-extra-non-null-assertion': 'error', - '@typescript-eslint/no-extra-parens': 'off', - '@typescript-eslint/no-extra-semi': 'off', - '@typescript-eslint/no-extraneous-class': 'error', - '@typescript-eslint/no-floating-promises': 'error', - '@typescript-eslint/no-for-in-array': 'error', - '@typescript-eslint/no-implied-eval': 'error', - '@typescript-eslint/no-inferrable-types': 'off', - '@typescript-eslint/no-invalid-this': 'off', - '@typescript-eslint/no-invalid-void-type': 'error', - '@typescript-eslint/no-loop-func': 'error', - '@typescript-eslint/no-loss-of-precision': 'error', - '@typescript-eslint/no-magic-numbers': 'off', - '@typescript-eslint/no-meaningless-void-operator': 'error', - '@typescript-eslint/no-misused-new': 'error', - '@typescript-eslint/no-misused-promises': 'error', - '@typescript-eslint/no-namespace': 'error', - '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error', - '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-redeclare': 'error', - '@typescript-eslint/no-require-imports': 'off', - '@typescript-eslint/no-restricted-imports': 'error', - '@typescript-eslint/no-shadow': 'off', - '@typescript-eslint/no-this-alias': 'error', - '@typescript-eslint/no-throw-literal': 'off', - '@typescript-eslint/no-type-alias': 'off', - '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error', - '@typescript-eslint/no-unnecessary-condition': isFixMode - ? 'off' - : ['error', {allowConstantLoopConditions: true}], - '@typescript-eslint/no-unnecessary-qualifier': 'error', - '@typescript-eslint/no-unnecessary-type-arguments': 'error', - '@typescript-eslint/no-unnecessary-type-assertion': 'warn', - '@typescript-eslint/no-unnecessary-type-constraint': 'error', - '@typescript-eslint/no-unsafe-argument': 'warn', - '@typescript-eslint/no-unsafe-assignment': 'warn', - '@typescript-eslint/no-unsafe-call': 'warn', - '@typescript-eslint/no-unsafe-enum-comparison': 'warn', - '@typescript-eslint/no-unsafe-member-access': 'warn', - '@typescript-eslint/no-unsafe-return': 'warn', - '@typescript-eslint/no-unused-expressions': 'off', - '@typescript-eslint/no-unused-vars': ['error', {argsIgnorePattern: '^_', ignoreRestSiblings: true}], - '@typescript-eslint/no-use-before-define': 'off', - '@typescript-eslint/no-useless-constructor': 'error', - '@typescript-eslint/no-var-requires': 'off', - '@typescript-eslint/non-nullable-type-assertion-style': 'off', - '@typescript-eslint/object-curly-spacing': 'error', - '@typescript-eslint/padding-line-between-statements': 'error', - '@typescript-eslint/prefer-as-const': 'error', - '@typescript-eslint/prefer-enum-initializers': 'off', - '@typescript-eslint/prefer-for-of': 'error', - '@typescript-eslint/prefer-function-type': 'error', - '@typescript-eslint/prefer-includes': 'error', - '@typescript-eslint/prefer-literal-enum-member': 'error', - '@typescript-eslint/prefer-namespace-keyword': 'error', - '@typescript-eslint/prefer-nullish-coalescing': 'off', - '@typescript-eslint/prefer-optional-chain': 'error', - '@typescript-eslint/prefer-readonly': 'off', - '@typescript-eslint/prefer-readonly-parameter-types': 'off', - '@typescript-eslint/prefer-reduce-type-parameter': 'warn', - '@typescript-eslint/prefer-regexp-exec': 'off', - '@typescript-eslint/prefer-return-this-type': 'error', - '@typescript-eslint/prefer-string-starts-ends-with': 'error', - '@typescript-eslint/prefer-ts-expect-error': 'off', - '@typescript-eslint/promise-function-async': 'error', - '@typescript-eslint/quotes': 'off', - '@typescript-eslint/require-array-sort-compare': 'off', - '@typescript-eslint/require-await': 'error', - '@typescript-eslint/restrict-plus-operands': 'off', - '@typescript-eslint/restrict-template-expressions': 'error', - '@typescript-eslint/return-await': 'off', - '@typescript-eslint/semi': 'off', - '@typescript-eslint/sort-type-union-intersection-members': 'off', - '@typescript-eslint/space-before-function-paren': 'off', - '@typescript-eslint/space-infix-ops': 'off', - '@typescript-eslint/strict-boolean-expressions': 'off', - '@typescript-eslint/switch-exhaustiveness-check': 'error', - '@typescript-eslint/triple-slash-reference': 'error', - '@typescript-eslint/type-annotation-spacing': 'error', - '@typescript-eslint/typedef': 'error', - '@typescript-eslint/unbound-method': 'error', - '@typescript-eslint/unified-signatures': 'error', - 'array-callback-return': 'error', - 'arrow-body-style': 'off', - 'capitalized-comments': 'off', - 'class-methods-use-this': 'off', - 'consistent-return': 'off', - 'default-case': 'off', - 'default-param-last': 'off', - 'deprecation/deprecation': 'error', - 'dot-notation': 'off', - 'func-names': 'off', - 'func-style': 'off', - 'guard-for-in': 'off', - 'id-length': 'off', - 'import/named': 'off', - 'import/namespace': 'off', - 'import/no-anonymous-default-export': 'error', - 'import/no-unresolved': 'off', - 'init-declarations': 'off', - 'line-comment-position': 'off', - 'logical-assignment-operators': 'off', - 'max-classes-per-file': 'off', - 'max-depth': 'off', - 'max-lines': 'off', - 'max-lines-per-function': 'off', - 'max-params': 'off', - 'max-statements': 'off', - 'multiline-comment-style': 'off', - 'new-cap': 'off', - 'no-await-in-loop': 'off', - 'no-console': 'off', - 'no-constant-condition': ['warn', {checkLoops: false}], - 'no-continue': 'off', - 'no-duplicate-imports': 'off', - 'no-else-return': 'off', - 'no-empty': 'off', - 'no-empty-function': 'off', - 'no-implicit-coercion': 'off', - 'no-implied-eval': 'error', - 'no-inline-comments': 'off', - 'no-lonely-if': 'off', - 'no-loop-func': 'off', - 'no-magic-numbers': 'off', - 'no-negated-condition': 'off', - 'no-nested-ternary': 'off', - 'no-plusplus': 'off', - 'no-script-url': 'error', - 'no-self-compare': 'error', - 'no-sequences': 'error', - 'no-shadow': 'off', - 'no-ternary': 'off', - 'no-undefined': 'off', - 'no-underscore-dangle': 'off', - 'no-unused-expressions': 'off', - 'no-use-before-define': 'off', - 'no-useless-return': 'off', - 'no-warning-comments': 'off', - 'object-shorthand': 'off', - 'one-var': 'off', - 'operator-assignment': 'off', - 'prefer-arrow-callback': 'off', - 'prefer-const': 'error', - 'prefer-destructuring': 'off', - 'prefer-named-capture-group': 'off', - 'prefer-template': 'off', - 'react-hooks/exhaustive-deps': 'error', - 'react-hooks/rules-of-hooks': 'error', - 'react/boolean-prop-naming': 'error', - 'react/button-has-type': 'off', - 'react/default-props-match-prop-types': 'off', - 'react/destructuring-assignment': 'off', - 'react/display-name': 'off', - 'react/forbid-component-props': 'off', - 'react/forbid-dom-props': 'off', - 'react/forbid-elements': 'off', - 'react/forbid-foreign-prop-types': 'off', - 'react/forbid-prop-types': 'off', - 'react/jsx-boolean-value': ['error', 'always'], - 'react/jsx-child-element-spacing': 'off', - 'react/jsx-closing-bracket-location': 'off', - 'react/jsx-closing-tag-location': 'off', - 'react/jsx-curly-brace-presence': 'off', - 'react/jsx-curly-newline': 'off', - 'react/jsx-curly-spacing': 'off', - 'react/jsx-equals-spacing': 'off', - 'react/jsx-filename-extension': 'off', - 'react/jsx-first-prop-new-line': 'off', - 'react/jsx-fragments': ['error', 'syntax'], - 'react/jsx-handler-names': 'off', - 'react/jsx-indent': 'off', - 'react/jsx-indent-props': 'off', - 'react/jsx-key': 'error', - 'react/jsx-max-depth': 'off', - 'react/jsx-max-props-per-line': 'off', - 'react/jsx-no-bind': 'off', - 'react/jsx-no-comment-textnodes': 'error', - 'react/jsx-no-duplicate-props': 'error', - 'react/jsx-no-literals': 'off', - 'react/jsx-no-target-blank': 'error', - 'react/jsx-no-undef': 'error', - 'react/jsx-one-expression-per-line': 'off', - 'react/jsx-pascal-case': 'off', - 'react/jsx-props-no-multi-spaces': 'off', - 'react/jsx-props-no-spreading': 'off', - 'react/jsx-sort-default-props': 'off', - 'react/jsx-sort-props': 'off', - 'react/jsx-space-before-closing': 'off', - 'react/jsx-tag-spacing': 'off', - 'react/jsx-uses-react': 'off', - 'react/jsx-uses-vars': 'error', - 'react/jsx-wrap-multilines': 'off', - 'react/no-access-state-in-setstate': 'error', - 'react/no-array-index-key': 'off', - 'react/no-children-prop': 'off', - 'react/no-danger': 'error', - 'react/no-danger-with-children': 'error', - 'react/no-deprecated': 'error', - 'react/no-did-mount-set-state': 'warn', - 'react/no-did-update-set-state': 'warn', - 'react/no-direct-mutation-state': 'error', - 'react/no-find-dom-node': 'warn', - 'react/no-is-mounted': 'error', - 'react/no-multi-comp': 'off', - 'react/no-redundant-should-component-update': 'error', - 'react/no-render-return-value': 'error', - 'react/no-set-state': 'off', - 'react/no-string-refs': 'error', - 'react/no-this-in-sfc': 'error', - 'react/no-typos': 'warn', - 'react/no-unescaped-entities': 'off', - 'react/no-unknown-property': 'error', - 'react/no-unsafe': 'error', - 'react/no-unused-prop-types': 'off', - 'react/no-unused-state': 'error', - 'react/no-will-update-set-state': 'warn', - 'react/prefer-es6-class': 'off', - 'react/prefer-read-only-props': 'off', - 'react/prefer-stateless-function': 'error', - 'react/prop-types': 'off', - 'react/react-in-jsx-scope': 'off', - 'react/require-default-props': 'off', - 'react/require-optimization': 'off', - 'react/require-render-return': 'off', - 'react/self-closing-comp': 'off', - 'react/sort-comp': 'off', - 'react/sort-prop-types': 'off', - 'react/state-in-constructor': 'off', - 'react/static-property-placement': 'off', - 'react/style-prop-object': 'error', - 'react/void-dom-elements-no-children': 'error', - 'require-unicode-regexp': 'off', - 'sort-imports': 'off', - 'sort-keys': ['error', 'asc', {caseSensitive: true, natural: false}], - camelcase: 'off', - complexity: 'off', - curly: 'off', - radix: 'off', - strict: ['error', 'global'], - yoda: 'off', - }, - settings: { - 'import/resolver': { - node: { - extensions: ['.js', '.tsx', '.d.ts', '.native.tsx', '.desktop.tsx', '.native.js', '.desktop.js'], - }, - }, - react: {version: 'detect'}, - }, -} diff --git a/shared/.gitignore b/shared/.gitignore index 32edfe076467..5afbad593de7 100644 --- a/shared/.gitignore +++ b/shared/.gitignore @@ -51,3 +51,4 @@ main.jsbundle .metro-health-check* coverage-ts +temp.log diff --git a/shared/Gemfile b/shared/Gemfile index a543c630f9bb..ec01b5764761 100644 --- a/shared/Gemfile +++ b/shared/Gemfile @@ -1,4 +1,6 @@ source 'https://rubygems.org' # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version ruby ">= 2.6.10" -gem 'cocoapods', '~> 1.12' +# Exclude problematic versions of cocoapods and activesupport that causes build failures. +gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' +gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' diff --git a/shared/actions/engine-gen-gen.tsx b/shared/actions/engine-gen-gen.tsx index 3c3ba80aca86..e2e6151d4327 100644 --- a/shared/actions/engine-gen-gen.tsx +++ b/shared/actions/engine-gen-gen.tsx @@ -251,325 +251,325 @@ export const stellar1NotifyRequestStatusNotification = 'engine-gen:stellar1Notif export const stellar1UiPaymentReviewed = 'engine-gen:stellar1UiPaymentReviewed' // Action Creators -const createChat1ChatUiChatBotCommandsUpdateStatus = (payload: { +type createChat1ChatUiChatBotCommandsUpdateStatus = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatBotCommandsUpdateStatus']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatBotCommandsUpdateStatus']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatBotCommandsUpdateStatus}) as const -const createChat1ChatUiChatClearWatch = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatBotCommandsUpdateStatus} +type createChat1ChatUiChatClearWatch = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatClearWatch']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatClearWatch']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatClearWatch}) as const -const createChat1ChatUiChatCoinFlipStatus = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatClearWatch} +type createChat1ChatUiChatCoinFlipStatus = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatCoinFlipStatus']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatCoinFlipStatus']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatCoinFlipStatus}) as const -const createChat1ChatUiChatCommandMarkdown = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatCoinFlipStatus} +type createChat1ChatUiChatCommandMarkdown = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatCommandMarkdown']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatCommandMarkdown']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatCommandMarkdown}) as const -const createChat1ChatUiChatCommandStatus = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatCommandMarkdown} +type createChat1ChatUiChatCommandStatus = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatCommandStatus']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatCommandStatus']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatCommandStatus}) as const -const createChat1ChatUiChatConfirmChannelDelete = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatCommandStatus} +type createChat1ChatUiChatConfirmChannelDelete = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatConfirmChannelDelete']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatConfirmChannelDelete']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatConfirmChannelDelete}) as const -const createChat1ChatUiChatGiphySearchResults = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatConfirmChannelDelete} +type createChat1ChatUiChatGiphySearchResults = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatGiphySearchResults']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatGiphySearchResults']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatGiphySearchResults}) as const -const createChat1ChatUiChatGiphyToggleResultWindow = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatGiphySearchResults} +type createChat1ChatUiChatGiphyToggleResultWindow = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatGiphyToggleResultWindow']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatGiphyToggleResultWindow']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatGiphyToggleResultWindow}) as const -const createChat1ChatUiChatInboxConversation = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatGiphyToggleResultWindow} +type createChat1ChatUiChatInboxConversation = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatInboxConversation']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatInboxConversation']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatInboxConversation}) as const -const createChat1ChatUiChatInboxFailed = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatInboxConversation} +type createChat1ChatUiChatInboxFailed = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatInboxFailed']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatInboxFailed']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatInboxFailed}) as const -const createChat1ChatUiChatInboxLayout = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatInboxFailed} +type createChat1ChatUiChatInboxLayout = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatInboxLayout']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatInboxLayout']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatInboxLayout}) as const -const createChat1ChatUiChatInboxUnverified = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatInboxLayout} +type createChat1ChatUiChatInboxUnverified = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatInboxUnverified']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatInboxUnverified']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatInboxUnverified}) as const -const createChat1ChatUiChatLoadGalleryHit = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatInboxUnverified} +type createChat1ChatUiChatLoadGalleryHit = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatLoadGalleryHit']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatLoadGalleryHit']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatLoadGalleryHit}) as const -const createChat1ChatUiChatMaybeMentionUpdate = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatLoadGalleryHit} +type createChat1ChatUiChatMaybeMentionUpdate = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatMaybeMentionUpdate']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatMaybeMentionUpdate']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatMaybeMentionUpdate}) as const -const createChat1ChatUiChatSearchBotHits = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatMaybeMentionUpdate} +type createChat1ChatUiChatSearchBotHits = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatSearchBotHits']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatSearchBotHits']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatSearchBotHits}) as const -const createChat1ChatUiChatSearchConvHits = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatSearchBotHits} +type createChat1ChatUiChatSearchConvHits = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatSearchConvHits']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatSearchConvHits']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatSearchConvHits}) as const -const createChat1ChatUiChatSearchDone = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatSearchConvHits} +type createChat1ChatUiChatSearchDone = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatSearchDone']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatSearchDone']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatSearchDone}) as const -const createChat1ChatUiChatSearchHit = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatSearchDone} +type createChat1ChatUiChatSearchHit = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatSearchHit']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatSearchHit']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatSearchHit}) as const -const createChat1ChatUiChatSearchInboxDone = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatSearchHit} +type createChat1ChatUiChatSearchInboxDone = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatSearchInboxDone']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatSearchInboxDone']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatSearchInboxDone}) as const -const createChat1ChatUiChatSearchInboxHit = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatSearchInboxDone} +type createChat1ChatUiChatSearchInboxHit = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatSearchInboxHit']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatSearchInboxHit']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatSearchInboxHit}) as const -const createChat1ChatUiChatSearchInboxStart = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatSearchInboxHit} +type createChat1ChatUiChatSearchInboxStart = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatSearchInboxStart']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatSearchInboxStart']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatSearchInboxStart}) as const -const createChat1ChatUiChatSearchIndexStatus = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatSearchInboxStart} +type createChat1ChatUiChatSearchIndexStatus = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatSearchIndexStatus']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatSearchIndexStatus']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatSearchIndexStatus}) as const -const createChat1ChatUiChatSearchTeamHits = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatSearchIndexStatus} +type createChat1ChatUiChatSearchTeamHits = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatSearchTeamHits']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatSearchTeamHits']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatSearchTeamHits}) as const -const createChat1ChatUiChatShowManageChannels = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatSearchTeamHits} +type createChat1ChatUiChatShowManageChannels = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatShowManageChannels']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatShowManageChannels']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatShowManageChannels}) as const -const createChat1ChatUiChatStellarDataConfirm = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatShowManageChannels} +type createChat1ChatUiChatStellarDataConfirm = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatStellarDataConfirm']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatStellarDataConfirm']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatStellarDataConfirm}) as const -const createChat1ChatUiChatStellarDataError = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatStellarDataConfirm} +type createChat1ChatUiChatStellarDataError = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatStellarDataError']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatStellarDataError']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatStellarDataError}) as const -const createChat1ChatUiChatStellarDone = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatStellarDataError} +type createChat1ChatUiChatStellarDone = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatStellarDone']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatStellarDone']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatStellarDone}) as const -const createChat1ChatUiChatStellarShowConfirm = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatStellarDone} +type createChat1ChatUiChatStellarShowConfirm = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatStellarShowConfirm']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatStellarShowConfirm']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatStellarShowConfirm}) as const -const createChat1ChatUiChatThreadCached = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatStellarShowConfirm} +type createChat1ChatUiChatThreadCached = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatThreadCached']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatThreadCached']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatThreadCached}) as const -const createChat1ChatUiChatThreadFull = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatThreadCached} +type createChat1ChatUiChatThreadFull = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatThreadFull']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatThreadFull']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatThreadFull}) as const -const createChat1ChatUiChatThreadStatus = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatThreadFull} +type createChat1ChatUiChatThreadStatus = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatThreadStatus']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatThreadStatus']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatThreadStatus}) as const -const createChat1ChatUiChatWatchPosition = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatThreadStatus} +type createChat1ChatUiChatWatchPosition = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.chatWatchPosition']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.chatWatchPosition']['outParam']) => void } -}) => ({payload, type: chat1ChatUiChatWatchPosition}) as const -const createChat1ChatUiTriggerContactSync = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiChatWatchPosition} +type createChat1ChatUiTriggerContactSync = (payload: { readonly params: chat1Types.MessageTypes['chat.1.chatUi.triggerContactSync']['inParam'] response: { error: chat1Types.IncomingErrorCallback result: (param: chat1Types.MessageTypes['chat.1.chatUi.triggerContactSync']['outParam']) => void } -}) => ({payload, type: chat1ChatUiTriggerContactSync}) as const -const createChat1NotifyChatChatArchiveComplete = (payload: { +}) => {payload: typeof payload; type: typeof chat1ChatUiTriggerContactSync} +type createChat1NotifyChatChatArchiveComplete = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatArchiveComplete']['inParam'] -}) => ({payload, type: chat1NotifyChatChatArchiveComplete}) as const -const createChat1NotifyChatChatArchiveProgress = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatArchiveComplete} +type createChat1NotifyChatChatArchiveProgress = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatArchiveProgress']['inParam'] -}) => ({payload, type: chat1NotifyChatChatArchiveProgress}) as const -const createChat1NotifyChatChatAttachmentDownloadComplete = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatArchiveProgress} +type createChat1NotifyChatChatAttachmentDownloadComplete = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatAttachmentDownloadComplete']['inParam'] -}) => ({payload, type: chat1NotifyChatChatAttachmentDownloadComplete}) as const -const createChat1NotifyChatChatAttachmentDownloadProgress = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatAttachmentDownloadComplete} +type createChat1NotifyChatChatAttachmentDownloadProgress = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatAttachmentDownloadProgress']['inParam'] -}) => ({payload, type: chat1NotifyChatChatAttachmentDownloadProgress}) as const -const createChat1NotifyChatChatAttachmentUploadProgress = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatAttachmentDownloadProgress} +type createChat1NotifyChatChatAttachmentUploadProgress = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatAttachmentUploadProgress']['inParam'] -}) => ({payload, type: chat1NotifyChatChatAttachmentUploadProgress}) as const -const createChat1NotifyChatChatAttachmentUploadStart = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatAttachmentUploadProgress} +type createChat1NotifyChatChatAttachmentUploadStart = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatAttachmentUploadStart']['inParam'] -}) => ({payload, type: chat1NotifyChatChatAttachmentUploadStart}) as const -const createChat1NotifyChatChatConvUpdate = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatAttachmentUploadStart} +type createChat1NotifyChatChatConvUpdate = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatConvUpdate']['inParam'] -}) => ({payload, type: chat1NotifyChatChatConvUpdate}) as const -const createChat1NotifyChatChatIdentifyUpdate = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatConvUpdate} +type createChat1NotifyChatChatIdentifyUpdate = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatIdentifyUpdate']['inParam'] -}) => ({payload, type: chat1NotifyChatChatIdentifyUpdate}) as const -const createChat1NotifyChatChatInboxStale = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatIdentifyUpdate} +type createChat1NotifyChatChatInboxStale = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatInboxStale']['inParam'] -}) => ({payload, type: chat1NotifyChatChatInboxStale}) as const -const createChat1NotifyChatChatInboxSyncStarted = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatInboxStale} +type createChat1NotifyChatChatInboxSyncStarted = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatInboxSyncStarted']['inParam'] -}) => ({payload, type: chat1NotifyChatChatInboxSyncStarted}) as const -const createChat1NotifyChatChatInboxSynced = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatInboxSyncStarted} +type createChat1NotifyChatChatInboxSynced = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatInboxSynced']['inParam'] -}) => ({payload, type: chat1NotifyChatChatInboxSynced}) as const -const createChat1NotifyChatChatJoinedConversation = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatInboxSynced} +type createChat1NotifyChatChatJoinedConversation = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatJoinedConversation']['inParam'] -}) => ({payload, type: chat1NotifyChatChatJoinedConversation}) as const -const createChat1NotifyChatChatKBFSToImpteamUpgrade = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatJoinedConversation} +type createChat1NotifyChatChatKBFSToImpteamUpgrade = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatKBFSToImpteamUpgrade']['inParam'] -}) => ({payload, type: chat1NotifyChatChatKBFSToImpteamUpgrade}) as const -const createChat1NotifyChatChatLeftConversation = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatKBFSToImpteamUpgrade} +type createChat1NotifyChatChatLeftConversation = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatLeftConversation']['inParam'] -}) => ({payload, type: chat1NotifyChatChatLeftConversation}) as const -const createChat1NotifyChatChatParticipantsInfo = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatLeftConversation} +type createChat1NotifyChatChatParticipantsInfo = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatParticipantsInfo']['inParam'] -}) => ({payload, type: chat1NotifyChatChatParticipantsInfo}) as const -const createChat1NotifyChatChatPaymentInfo = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatParticipantsInfo} +type createChat1NotifyChatChatPaymentInfo = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatPaymentInfo']['inParam'] -}) => ({payload, type: chat1NotifyChatChatPaymentInfo}) as const -const createChat1NotifyChatChatPromptUnfurl = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatPaymentInfo} +type createChat1NotifyChatChatPromptUnfurl = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatPromptUnfurl']['inParam'] -}) => ({payload, type: chat1NotifyChatChatPromptUnfurl}) as const -const createChat1NotifyChatChatRequestInfo = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatPromptUnfurl} +type createChat1NotifyChatChatRequestInfo = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatRequestInfo']['inParam'] -}) => ({payload, type: chat1NotifyChatChatRequestInfo}) as const -const createChat1NotifyChatChatResetConversation = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatRequestInfo} +type createChat1NotifyChatChatResetConversation = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatResetConversation']['inParam'] -}) => ({payload, type: chat1NotifyChatChatResetConversation}) as const -const createChat1NotifyChatChatSetConvRetention = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatResetConversation} +type createChat1NotifyChatChatSetConvRetention = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatSetConvRetention']['inParam'] -}) => ({payload, type: chat1NotifyChatChatSetConvRetention}) as const -const createChat1NotifyChatChatSetConvSettings = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatSetConvRetention} +type createChat1NotifyChatChatSetConvSettings = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatSetConvSettings']['inParam'] -}) => ({payload, type: chat1NotifyChatChatSetConvSettings}) as const -const createChat1NotifyChatChatSetTeamRetention = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatSetConvSettings} +type createChat1NotifyChatChatSetTeamRetention = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatSetTeamRetention']['inParam'] -}) => ({payload, type: chat1NotifyChatChatSetTeamRetention}) as const -const createChat1NotifyChatChatSubteamRename = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatSetTeamRetention} +type createChat1NotifyChatChatSubteamRename = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatSubteamRename']['inParam'] -}) => ({payload, type: chat1NotifyChatChatSubteamRename}) as const -const createChat1NotifyChatChatTLFFinalize = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatSubteamRename} +type createChat1NotifyChatChatTLFFinalize = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatTLFFinalize']['inParam'] -}) => ({payload, type: chat1NotifyChatChatTLFFinalize}) as const -const createChat1NotifyChatChatTLFResolve = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatTLFFinalize} +type createChat1NotifyChatChatTLFResolve = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatTLFResolve']['inParam'] -}) => ({payload, type: chat1NotifyChatChatTLFResolve}) as const -const createChat1NotifyChatChatThreadsStale = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatTLFResolve} +type createChat1NotifyChatChatThreadsStale = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatThreadsStale']['inParam'] -}) => ({payload, type: chat1NotifyChatChatThreadsStale}) as const -const createChat1NotifyChatChatTypingUpdate = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatThreadsStale} +type createChat1NotifyChatChatTypingUpdate = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatTypingUpdate']['inParam'] -}) => ({payload, type: chat1NotifyChatChatTypingUpdate}) as const -const createChat1NotifyChatChatWelcomeMessageLoaded = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatTypingUpdate} +type createChat1NotifyChatChatWelcomeMessageLoaded = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.ChatWelcomeMessageLoaded']['inParam'] -}) => ({payload, type: chat1NotifyChatChatWelcomeMessageLoaded}) as const -const createChat1NotifyChatNewChatActivity = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatChatWelcomeMessageLoaded} +type createChat1NotifyChatNewChatActivity = (payload: { readonly params: chat1Types.MessageTypes['chat.1.NotifyChat.NewChatActivity']['inParam'] -}) => ({payload, type: chat1NotifyChatNewChatActivity}) as const -const createKeybase1GpgUiConfirmDuplicateKeyChosen = (payload: { +}) => {payload: typeof payload; type: typeof chat1NotifyChatNewChatActivity} +type createKeybase1GpgUiConfirmDuplicateKeyChosen = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.gpgUi.confirmDuplicateKeyChosen']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -577,8 +577,8 @@ const createKeybase1GpgUiConfirmDuplicateKeyChosen = (payload: { param: keybase1Types.MessageTypes['keybase.1.gpgUi.confirmDuplicateKeyChosen']['outParam'] ) => void } -}) => ({payload, type: keybase1GpgUiConfirmDuplicateKeyChosen}) as const -const createKeybase1GpgUiConfirmImportSecretToExistingKey = (payload: { +}) => {payload: typeof payload; type: typeof keybase1GpgUiConfirmDuplicateKeyChosen} +type createKeybase1GpgUiConfirmImportSecretToExistingKey = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.gpgUi.confirmImportSecretToExistingKey']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -586,43 +586,43 @@ const createKeybase1GpgUiConfirmImportSecretToExistingKey = (payload: { param: keybase1Types.MessageTypes['keybase.1.gpgUi.confirmImportSecretToExistingKey']['outParam'] ) => void } -}) => ({payload, type: keybase1GpgUiConfirmImportSecretToExistingKey}) as const -const createKeybase1GpgUiGetTTY = (payload: { +}) => {payload: typeof payload; type: typeof keybase1GpgUiConfirmImportSecretToExistingKey} +type createKeybase1GpgUiGetTTY = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.gpgUi.getTTY']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.gpgUi.getTTY']['outParam']) => void } -}) => ({payload, type: keybase1GpgUiGetTTY}) as const -const createKeybase1GpgUiSelectKey = (payload: { +}) => {payload: typeof payload; type: typeof keybase1GpgUiGetTTY} +type createKeybase1GpgUiSelectKey = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.gpgUi.selectKey']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.gpgUi.selectKey']['outParam']) => void } -}) => ({payload, type: keybase1GpgUiSelectKey}) as const -const createKeybase1GpgUiSelectKeyAndPushOption = (payload: { +}) => {payload: typeof payload; type: typeof keybase1GpgUiSelectKey} +type createKeybase1GpgUiSelectKeyAndPushOption = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.gpgUi.selectKeyAndPushOption']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.gpgUi.selectKeyAndPushOption']['outParam']) => void } -}) => ({payload, type: keybase1GpgUiSelectKeyAndPushOption}) as const -const createKeybase1GpgUiSign = (payload: { +}) => {payload: typeof payload; type: typeof keybase1GpgUiSelectKeyAndPushOption} +type createKeybase1GpgUiSign = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.gpgUi.sign']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.gpgUi.sign']['outParam']) => void } -}) => ({payload, type: keybase1GpgUiSign}) as const -const createKeybase1GpgUiWantToAddGPGKey = (payload: { +}) => {payload: typeof payload; type: typeof keybase1GpgUiSign} +type createKeybase1GpgUiWantToAddGPGKey = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.gpgUi.wantToAddGPGKey']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.gpgUi.wantToAddGPGKey']['outParam']) => void } -}) => ({payload, type: keybase1GpgUiWantToAddGPGKey}) as const -const createKeybase1GregorUIPushOutOfBandMessages = (payload: { +}) => {payload: typeof payload; type: typeof keybase1GpgUiWantToAddGPGKey} +type createKeybase1GregorUIPushOutOfBandMessages = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.gregorUI.pushOutOfBandMessages']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -630,29 +630,29 @@ const createKeybase1GregorUIPushOutOfBandMessages = (payload: { param: keybase1Types.MessageTypes['keybase.1.gregorUI.pushOutOfBandMessages']['outParam'] ) => void } -}) => ({payload, type: keybase1GregorUIPushOutOfBandMessages}) as const -const createKeybase1GregorUIPushState = (payload: { +}) => {payload: typeof payload; type: typeof keybase1GregorUIPushOutOfBandMessages} +type createKeybase1GregorUIPushState = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.gregorUI.pushState']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.gregorUI.pushState']['outParam']) => void } -}) => ({payload, type: keybase1GregorUIPushState}) as const -const createKeybase1HomeUIHomeUIRefresh = (payload: { +}) => {payload: typeof payload; type: typeof keybase1GregorUIPushState} +type createKeybase1HomeUIHomeUIRefresh = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.homeUI.homeUIRefresh']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.homeUI.homeUIRefresh']['outParam']) => void } -}) => ({payload, type: keybase1HomeUIHomeUIRefresh}) as const -const createKeybase1Identify3UiIdentify3Result = (payload: { +}) => {payload: typeof payload; type: typeof keybase1HomeUIHomeUIRefresh} +type createKeybase1Identify3UiIdentify3Result = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3Result']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3Result']['outParam']) => void } -}) => ({payload, type: keybase1Identify3UiIdentify3Result}) as const -const createKeybase1Identify3UiIdentify3ShowTracker = (payload: { +}) => {payload: typeof payload; type: typeof keybase1Identify3UiIdentify3Result} +type createKeybase1Identify3UiIdentify3ShowTracker = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3ShowTracker']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -660,15 +660,15 @@ const createKeybase1Identify3UiIdentify3ShowTracker = (payload: { param: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3ShowTracker']['outParam'] ) => void } -}) => ({payload, type: keybase1Identify3UiIdentify3ShowTracker}) as const -const createKeybase1Identify3UiIdentify3Summary = (payload: { +}) => {payload: typeof payload; type: typeof keybase1Identify3UiIdentify3ShowTracker} +type createKeybase1Identify3UiIdentify3Summary = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3Summary']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3Summary']['outParam']) => void } -}) => ({payload, type: keybase1Identify3UiIdentify3Summary}) as const -const createKeybase1Identify3UiIdentify3TrackerTimedOut = (payload: { +}) => {payload: typeof payload; type: typeof keybase1Identify3UiIdentify3Summary} +type createKeybase1Identify3UiIdentify3TrackerTimedOut = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3TrackerTimedOut']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -676,8 +676,8 @@ const createKeybase1Identify3UiIdentify3TrackerTimedOut = (payload: { param: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3TrackerTimedOut']['outParam'] ) => void } -}) => ({payload, type: keybase1Identify3UiIdentify3TrackerTimedOut}) as const -const createKeybase1Identify3UiIdentify3UpdateRow = (payload: { +}) => {payload: typeof payload; type: typeof keybase1Identify3UiIdentify3TrackerTimedOut} +type createKeybase1Identify3UiIdentify3UpdateRow = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3UpdateRow']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -685,8 +685,8 @@ const createKeybase1Identify3UiIdentify3UpdateRow = (payload: { param: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3UpdateRow']['outParam'] ) => void } -}) => ({payload, type: keybase1Identify3UiIdentify3UpdateRow}) as const -const createKeybase1Identify3UiIdentify3UpdateUserCard = (payload: { +}) => {payload: typeof payload; type: typeof keybase1Identify3UiIdentify3UpdateRow} +type createKeybase1Identify3UiIdentify3UpdateUserCard = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3UpdateUserCard']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -694,8 +694,8 @@ const createKeybase1Identify3UiIdentify3UpdateUserCard = (payload: { param: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3UpdateUserCard']['outParam'] ) => void } -}) => ({payload, type: keybase1Identify3UiIdentify3UpdateUserCard}) as const -const createKeybase1Identify3UiIdentify3UserReset = (payload: { +}) => {payload: typeof payload; type: typeof keybase1Identify3UiIdentify3UpdateUserCard} +type createKeybase1Identify3UiIdentify3UserReset = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3UserReset']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -703,36 +703,36 @@ const createKeybase1Identify3UiIdentify3UserReset = (payload: { param: keybase1Types.MessageTypes['keybase.1.identify3Ui.identify3UserReset']['outParam'] ) => void } -}) => ({payload, type: keybase1Identify3UiIdentify3UserReset}) as const -const createKeybase1IdentifyUiCancel = (payload: { +}) => {payload: typeof payload; type: typeof keybase1Identify3UiIdentify3UserReset} +type createKeybase1IdentifyUiCancel = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.cancel']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identifyUi.cancel']['outParam']) => void } -}) => ({payload, type: keybase1IdentifyUiCancel}) as const -const createKeybase1IdentifyUiConfirm = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiCancel} +type createKeybase1IdentifyUiConfirm = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.confirm']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identifyUi.confirm']['outParam']) => void } -}) => ({payload, type: keybase1IdentifyUiConfirm}) as const -const createKeybase1IdentifyUiDelegateIdentifyUI = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiConfirm} +type createKeybase1IdentifyUiDelegateIdentifyUI = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.delegateIdentifyUI']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identifyUi.delegateIdentifyUI']['outParam']) => void } -}) => ({payload, type: keybase1IdentifyUiDelegateIdentifyUI}) as const -const createKeybase1IdentifyUiDismiss = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiDelegateIdentifyUI} +type createKeybase1IdentifyUiDismiss = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.dismiss']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identifyUi.dismiss']['outParam']) => void } -}) => ({payload, type: keybase1IdentifyUiDismiss}) as const -const createKeybase1IdentifyUiDisplayCryptocurrency = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiDismiss} +type createKeybase1IdentifyUiDisplayCryptocurrency = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.displayCryptocurrency']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -740,15 +740,15 @@ const createKeybase1IdentifyUiDisplayCryptocurrency = (payload: { param: keybase1Types.MessageTypes['keybase.1.identifyUi.displayCryptocurrency']['outParam'] ) => void } -}) => ({payload, type: keybase1IdentifyUiDisplayCryptocurrency}) as const -const createKeybase1IdentifyUiDisplayKey = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiDisplayCryptocurrency} +type createKeybase1IdentifyUiDisplayKey = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.displayKey']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identifyUi.displayKey']['outParam']) => void } -}) => ({payload, type: keybase1IdentifyUiDisplayKey}) as const -const createKeybase1IdentifyUiDisplayStellarAccount = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiDisplayKey} +type createKeybase1IdentifyUiDisplayStellarAccount = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.displayStellarAccount']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -756,8 +756,8 @@ const createKeybase1IdentifyUiDisplayStellarAccount = (payload: { param: keybase1Types.MessageTypes['keybase.1.identifyUi.displayStellarAccount']['outParam'] ) => void } -}) => ({payload, type: keybase1IdentifyUiDisplayStellarAccount}) as const -const createKeybase1IdentifyUiDisplayTLFCreateWithInvite = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiDisplayStellarAccount} +type createKeybase1IdentifyUiDisplayTLFCreateWithInvite = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.displayTLFCreateWithInvite']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -765,8 +765,8 @@ const createKeybase1IdentifyUiDisplayTLFCreateWithInvite = (payload: { param: keybase1Types.MessageTypes['keybase.1.identifyUi.displayTLFCreateWithInvite']['outParam'] ) => void } -}) => ({payload, type: keybase1IdentifyUiDisplayTLFCreateWithInvite}) as const -const createKeybase1IdentifyUiDisplayTrackStatement = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiDisplayTLFCreateWithInvite} +type createKeybase1IdentifyUiDisplayTrackStatement = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.displayTrackStatement']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -774,22 +774,22 @@ const createKeybase1IdentifyUiDisplayTrackStatement = (payload: { param: keybase1Types.MessageTypes['keybase.1.identifyUi.displayTrackStatement']['outParam'] ) => void } -}) => ({payload, type: keybase1IdentifyUiDisplayTrackStatement}) as const -const createKeybase1IdentifyUiDisplayUserCard = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiDisplayTrackStatement} +type createKeybase1IdentifyUiDisplayUserCard = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.displayUserCard']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identifyUi.displayUserCard']['outParam']) => void } -}) => ({payload, type: keybase1IdentifyUiDisplayUserCard}) as const -const createKeybase1IdentifyUiFinish = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiDisplayUserCard} +type createKeybase1IdentifyUiFinish = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.finish']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identifyUi.finish']['outParam']) => void } -}) => ({payload, type: keybase1IdentifyUiFinish}) as const -const createKeybase1IdentifyUiFinishSocialProofCheck = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiFinish} +type createKeybase1IdentifyUiFinishSocialProofCheck = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.finishSocialProofCheck']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -797,8 +797,8 @@ const createKeybase1IdentifyUiFinishSocialProofCheck = (payload: { param: keybase1Types.MessageTypes['keybase.1.identifyUi.finishSocialProofCheck']['outParam'] ) => void } -}) => ({payload, type: keybase1IdentifyUiFinishSocialProofCheck}) as const -const createKeybase1IdentifyUiFinishWebProofCheck = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiFinishSocialProofCheck} +type createKeybase1IdentifyUiFinishWebProofCheck = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.finishWebProofCheck']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -806,8 +806,8 @@ const createKeybase1IdentifyUiFinishWebProofCheck = (payload: { param: keybase1Types.MessageTypes['keybase.1.identifyUi.finishWebProofCheck']['outParam'] ) => void } -}) => ({payload, type: keybase1IdentifyUiFinishWebProofCheck}) as const -const createKeybase1IdentifyUiLaunchNetworkChecks = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiFinishWebProofCheck} +type createKeybase1IdentifyUiLaunchNetworkChecks = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.launchNetworkChecks']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -815,36 +815,36 @@ const createKeybase1IdentifyUiLaunchNetworkChecks = (payload: { param: keybase1Types.MessageTypes['keybase.1.identifyUi.launchNetworkChecks']['outParam'] ) => void } -}) => ({payload, type: keybase1IdentifyUiLaunchNetworkChecks}) as const -const createKeybase1IdentifyUiReportLastTrack = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiLaunchNetworkChecks} +type createKeybase1IdentifyUiReportLastTrack = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.reportLastTrack']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identifyUi.reportLastTrack']['outParam']) => void } -}) => ({payload, type: keybase1IdentifyUiReportLastTrack}) as const -const createKeybase1IdentifyUiReportTrackToken = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiReportLastTrack} +type createKeybase1IdentifyUiReportTrackToken = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.reportTrackToken']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identifyUi.reportTrackToken']['outParam']) => void } -}) => ({payload, type: keybase1IdentifyUiReportTrackToken}) as const -const createKeybase1IdentifyUiStart = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiReportTrackToken} +type createKeybase1IdentifyUiStart = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.identifyUi.start']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.identifyUi.start']['outParam']) => void } -}) => ({payload, type: keybase1IdentifyUiStart}) as const -const createKeybase1LogUiLog = (payload: { +}) => {payload: typeof payload; type: typeof keybase1IdentifyUiStart} +type createKeybase1LogUiLog = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.logUi.log']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.logUi.log']['outParam']) => void } -}) => ({payload, type: keybase1LogUiLog}) as const -const createKeybase1LoginUiChooseDeviceToRecoverWith = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LogUiLog} +type createKeybase1LoginUiChooseDeviceToRecoverWith = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.loginUi.chooseDeviceToRecoverWith']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -852,15 +852,15 @@ const createKeybase1LoginUiChooseDeviceToRecoverWith = (payload: { param: keybase1Types.MessageTypes['keybase.1.loginUi.chooseDeviceToRecoverWith']['outParam'] ) => void } -}) => ({payload, type: keybase1LoginUiChooseDeviceToRecoverWith}) as const -const createKeybase1LoginUiDisplayPaperKeyPhrase = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LoginUiChooseDeviceToRecoverWith} +type createKeybase1LoginUiDisplayPaperKeyPhrase = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.loginUi.displayPaperKeyPhrase']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.loginUi.displayPaperKeyPhrase']['outParam']) => void } -}) => ({payload, type: keybase1LoginUiDisplayPaperKeyPhrase}) as const -const createKeybase1LoginUiDisplayPrimaryPaperKey = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LoginUiDisplayPaperKeyPhrase} +type createKeybase1LoginUiDisplayPrimaryPaperKey = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.loginUi.displayPrimaryPaperKey']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -868,36 +868,36 @@ const createKeybase1LoginUiDisplayPrimaryPaperKey = (payload: { param: keybase1Types.MessageTypes['keybase.1.loginUi.displayPrimaryPaperKey']['outParam'] ) => void } -}) => ({payload, type: keybase1LoginUiDisplayPrimaryPaperKey}) as const -const createKeybase1LoginUiDisplayResetMessage = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LoginUiDisplayPrimaryPaperKey} +type createKeybase1LoginUiDisplayResetMessage = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.loginUi.displayResetMessage']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.loginUi.displayResetMessage']['outParam']) => void } -}) => ({payload, type: keybase1LoginUiDisplayResetMessage}) as const -const createKeybase1LoginUiDisplayResetProgress = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LoginUiDisplayResetMessage} +type createKeybase1LoginUiDisplayResetProgress = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.loginUi.displayResetProgress']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.loginUi.displayResetProgress']['outParam']) => void } -}) => ({payload, type: keybase1LoginUiDisplayResetProgress}) as const -const createKeybase1LoginUiExplainDeviceRecovery = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LoginUiDisplayResetProgress} +type createKeybase1LoginUiExplainDeviceRecovery = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.loginUi.explainDeviceRecovery']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.loginUi.explainDeviceRecovery']['outParam']) => void } -}) => ({payload, type: keybase1LoginUiExplainDeviceRecovery}) as const -const createKeybase1LoginUiGetEmailOrUsername = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LoginUiExplainDeviceRecovery} +type createKeybase1LoginUiGetEmailOrUsername = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.loginUi.getEmailOrUsername']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.loginUi.getEmailOrUsername']['outParam']) => void } -}) => ({payload, type: keybase1LoginUiGetEmailOrUsername}) as const -const createKeybase1LoginUiPromptPassphraseRecovery = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LoginUiGetEmailOrUsername} +type createKeybase1LoginUiPromptPassphraseRecovery = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.loginUi.promptPassphraseRecovery']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -905,51 +905,51 @@ const createKeybase1LoginUiPromptPassphraseRecovery = (payload: { param: keybase1Types.MessageTypes['keybase.1.loginUi.promptPassphraseRecovery']['outParam'] ) => void } -}) => ({payload, type: keybase1LoginUiPromptPassphraseRecovery}) as const -const createKeybase1LoginUiPromptResetAccount = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LoginUiPromptPassphraseRecovery} +type createKeybase1LoginUiPromptResetAccount = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.loginUi.promptResetAccount']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.loginUi.promptResetAccount']['outParam']) => void } -}) => ({payload, type: keybase1LoginUiPromptResetAccount}) as const -const createKeybase1LoginUiPromptRevokePaperKeys = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LoginUiPromptResetAccount} +type createKeybase1LoginUiPromptRevokePaperKeys = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.loginUi.promptRevokePaperKeys']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.loginUi.promptRevokePaperKeys']['outParam']) => void } -}) => ({payload, type: keybase1LoginUiPromptRevokePaperKeys}) as const -const createKeybase1LogsendPrepareLogsend = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LoginUiPromptRevokePaperKeys} +type createKeybase1LogsendPrepareLogsend = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.logsend.prepareLogsend']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.logsend.prepareLogsend']['outParam']) => void } -}) => ({payload, type: keybase1LogsendPrepareLogsend}) as const -const createKeybase1NotifyAppExit = (payload: { +}) => {payload: typeof payload; type: typeof keybase1LogsendPrepareLogsend} +type createKeybase1NotifyAppExit = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyApp.exit']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyApp.exit']['outParam']) => void } -}) => ({payload, type: keybase1NotifyAppExit}) as const -const createKeybase1NotifyAuditBoxAuditError = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyAppExit} +type createKeybase1NotifyAuditBoxAuditError = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyAudit.boxAuditError']['inParam'] -}) => ({payload, type: keybase1NotifyAuditBoxAuditError}) as const -const createKeybase1NotifyAuditRootAuditError = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyAuditBoxAuditError} +type createKeybase1NotifyAuditRootAuditError = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyAudit.rootAuditError']['inParam'] -}) => ({payload, type: keybase1NotifyAuditRootAuditError}) as const -const createKeybase1NotifyBadgesBadgeState = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyAuditRootAuditError} +type createKeybase1NotifyBadgesBadgeState = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyBadges.badgeState']['inParam'] -}) => ({payload, type: keybase1NotifyBadgesBadgeState}) as const -const createKeybase1NotifyCanUserPerformCanUserPerformChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyBadgesBadgeState} +type createKeybase1NotifyCanUserPerformCanUserPerformChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyCanUserPerform.canUserPerformChanged']['inParam'] -}) => ({payload, type: keybase1NotifyCanUserPerformCanUserPerformChanged}) as const -const createKeybase1NotifyDeviceCloneDeviceCloneCountChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyCanUserPerformCanUserPerformChanged} +type createKeybase1NotifyDeviceCloneDeviceCloneCountChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyDeviceClone.deviceCloneCountChanged']['inParam'] -}) => ({payload, type: keybase1NotifyDeviceCloneDeviceCloneCountChanged}) as const -const createKeybase1NotifyEmailAddressEmailAddressVerified = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyDeviceCloneDeviceCloneCountChanged} +type createKeybase1NotifyEmailAddressEmailAddressVerified = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyEmailAddress.emailAddressVerified']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -957,8 +957,8 @@ const createKeybase1NotifyEmailAddressEmailAddressVerified = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyEmailAddress.emailAddressVerified']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyEmailAddressEmailAddressVerified}) as const -const createKeybase1NotifyEmailAddressEmailsChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyEmailAddressEmailAddressVerified} +type createKeybase1NotifyEmailAddressEmailsChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyEmailAddress.emailsChanged']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -966,18 +966,18 @@ const createKeybase1NotifyEmailAddressEmailsChanged = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyEmailAddress.emailsChanged']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyEmailAddressEmailsChanged}) as const -const createKeybase1NotifyEphemeralNewTeamEk = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyEmailAddressEmailsChanged} +type createKeybase1NotifyEphemeralNewTeamEk = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyEphemeral.newTeamEk']['inParam'] -}) => ({payload, type: keybase1NotifyEphemeralNewTeamEk}) as const -const createKeybase1NotifyEphemeralNewTeambotEk = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyEphemeralNewTeamEk} +type createKeybase1NotifyEphemeralNewTeambotEk = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyEphemeral.newTeambotEk']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyEphemeral.newTeambotEk']['outParam']) => void } -}) => ({payload, type: keybase1NotifyEphemeralNewTeambotEk}) as const -const createKeybase1NotifyEphemeralTeambotEkNeeded = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyEphemeralNewTeambotEk} +type createKeybase1NotifyEphemeralTeambotEkNeeded = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyEphemeral.teambotEkNeeded']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -985,25 +985,25 @@ const createKeybase1NotifyEphemeralTeambotEkNeeded = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyEphemeral.teambotEkNeeded']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyEphemeralTeambotEkNeeded}) as const -const createKeybase1NotifyFSFSActivity = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyEphemeralTeambotEkNeeded} +type createKeybase1NotifyFSFSActivity = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSActivity']['inParam'] -}) => ({payload, type: keybase1NotifyFSFSActivity}) as const -const createKeybase1NotifyFSFSEditListResponse = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFSFSActivity} +type createKeybase1NotifyFSFSEditListResponse = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSEditListResponse']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSEditListResponse']['outParam']) => void } -}) => ({payload, type: keybase1NotifyFSFSEditListResponse}) as const -const createKeybase1NotifyFSFSFavoritesChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFSFSEditListResponse} +type createKeybase1NotifyFSFSFavoritesChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSFavoritesChanged']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSFavoritesChanged']['outParam']) => void } -}) => ({payload, type: keybase1NotifyFSFSFavoritesChanged}) as const -const createKeybase1NotifyFSFSOnlineStatusChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFSFSFavoritesChanged} +type createKeybase1NotifyFSFSOnlineStatusChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSOnlineStatusChanged']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1011,8 +1011,8 @@ const createKeybase1NotifyFSFSOnlineStatusChanged = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSOnlineStatusChanged']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyFSFSOnlineStatusChanged}) as const -const createKeybase1NotifyFSFSOverallSyncStatusChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFSFSOnlineStatusChanged} +type createKeybase1NotifyFSFSOverallSyncStatusChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSOverallSyncStatusChanged']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1020,18 +1020,18 @@ const createKeybase1NotifyFSFSOverallSyncStatusChanged = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSOverallSyncStatusChanged']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyFSFSOverallSyncStatusChanged}) as const -const createKeybase1NotifyFSFSPathUpdated = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFSFSOverallSyncStatusChanged} +type createKeybase1NotifyFSFSPathUpdated = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSPathUpdated']['inParam'] -}) => ({payload, type: keybase1NotifyFSFSPathUpdated}) as const -const createKeybase1NotifyFSFSSubscriptionNotify = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFSFSPathUpdated} +type createKeybase1NotifyFSFSSubscriptionNotify = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSSubscriptionNotify']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSSubscriptionNotify']['outParam']) => void } -}) => ({payload, type: keybase1NotifyFSFSSubscriptionNotify}) as const -const createKeybase1NotifyFSFSSubscriptionNotifyPath = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFSFSSubscriptionNotify} +type createKeybase1NotifyFSFSSubscriptionNotifyPath = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSSubscriptionNotifyPath']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1039,25 +1039,25 @@ const createKeybase1NotifyFSFSSubscriptionNotifyPath = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSSubscriptionNotifyPath']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyFSFSSubscriptionNotifyPath}) as const -const createKeybase1NotifyFSFSSyncActivity = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFSFSSubscriptionNotifyPath} +type createKeybase1NotifyFSFSSyncActivity = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSSyncActivity']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSSyncActivity']['outParam']) => void } -}) => ({payload, type: keybase1NotifyFSFSSyncActivity}) as const -const createKeybase1NotifyFSFSSyncStatusResponse = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFSFSSyncActivity} +type createKeybase1NotifyFSFSSyncStatusResponse = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSSyncStatusResponse']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyFS.FSSyncStatusResponse']['outParam']) => void } -}) => ({payload, type: keybase1NotifyFSFSSyncStatusResponse}) as const -const createKeybase1NotifyFavoritesFavoritesChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFSFSSyncStatusResponse} +type createKeybase1NotifyFavoritesFavoritesChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFavorites.favoritesChanged']['inParam'] -}) => ({payload, type: keybase1NotifyFavoritesFavoritesChanged}) as const -const createKeybase1NotifyFeaturedBotsFeaturedBotsUpdate = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFavoritesFavoritesChanged} +type createKeybase1NotifyFeaturedBotsFeaturedBotsUpdate = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyFeaturedBots.featuredBotsUpdate']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1065,8 +1065,8 @@ const createKeybase1NotifyFeaturedBotsFeaturedBotsUpdate = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyFeaturedBots.featuredBotsUpdate']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyFeaturedBotsFeaturedBotsUpdate}) as const -const createKeybase1NotifyInviteFriendsUpdateInviteCounts = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyFeaturedBotsFeaturedBotsUpdate} +type createKeybase1NotifyInviteFriendsUpdateInviteCounts = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyInviteFriends.updateInviteCounts']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1074,8 +1074,8 @@ const createKeybase1NotifyInviteFriendsUpdateInviteCounts = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyInviteFriends.updateInviteCounts']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyInviteFriendsUpdateInviteCounts}) as const -const createKeybase1NotifyKeyfamilyKeyfamilyChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyInviteFriendsUpdateInviteCounts} +type createKeybase1NotifyKeyfamilyKeyfamilyChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyKeyfamily.keyfamilyChanged']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1083,8 +1083,8 @@ const createKeybase1NotifyKeyfamilyKeyfamilyChanged = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyKeyfamily.keyfamilyChanged']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyKeyfamilyKeyfamilyChanged}) as const -const createKeybase1NotifyPGPPgpKeyInSecretStoreFile = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyKeyfamilyKeyfamilyChanged} +type createKeybase1NotifyPGPPgpKeyInSecretStoreFile = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyPGP.pgpKeyInSecretStoreFile']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1092,15 +1092,15 @@ const createKeybase1NotifyPGPPgpKeyInSecretStoreFile = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyPGP.pgpKeyInSecretStoreFile']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyPGPPgpKeyInSecretStoreFile}) as const -const createKeybase1NotifyPaperKeyPaperKeyCached = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyPGPPgpKeyInSecretStoreFile} +type createKeybase1NotifyPaperKeyPaperKeyCached = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyPaperKey.paperKeyCached']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyPaperKey.paperKeyCached']['outParam']) => void } -}) => ({payload, type: keybase1NotifyPaperKeyPaperKeyCached}) as const -const createKeybase1NotifyPhoneNumberPhoneNumbersChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyPaperKeyPaperKeyCached} +type createKeybase1NotifyPhoneNumberPhoneNumbersChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyPhoneNumber.phoneNumbersChanged']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1108,8 +1108,8 @@ const createKeybase1NotifyPhoneNumberPhoneNumbersChanged = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyPhoneNumber.phoneNumbersChanged']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyPhoneNumberPhoneNumbersChanged}) as const -const createKeybase1NotifyRuntimeStatsRuntimeStatsUpdate = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyPhoneNumberPhoneNumbersChanged} +type createKeybase1NotifyRuntimeStatsRuntimeStatsUpdate = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyRuntimeStats.runtimeStatsUpdate']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1117,8 +1117,8 @@ const createKeybase1NotifyRuntimeStatsRuntimeStatsUpdate = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyRuntimeStats.runtimeStatsUpdate']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyRuntimeStatsRuntimeStatsUpdate}) as const -const createKeybase1NotifySaltpackSaltpackOperationDone = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyRuntimeStatsRuntimeStatsUpdate} +type createKeybase1NotifySaltpackSaltpackOperationDone = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifySaltpack.saltpackOperationDone']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1126,8 +1126,8 @@ const createKeybase1NotifySaltpackSaltpackOperationDone = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifySaltpack.saltpackOperationDone']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifySaltpackSaltpackOperationDone}) as const -const createKeybase1NotifySaltpackSaltpackOperationProgress = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifySaltpackSaltpackOperationDone} +type createKeybase1NotifySaltpackSaltpackOperationProgress = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifySaltpack.saltpackOperationProgress']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1135,8 +1135,8 @@ const createKeybase1NotifySaltpackSaltpackOperationProgress = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifySaltpack.saltpackOperationProgress']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifySaltpackSaltpackOperationProgress}) as const -const createKeybase1NotifySaltpackSaltpackOperationStart = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifySaltpackSaltpackOperationProgress} +type createKeybase1NotifySaltpackSaltpackOperationStart = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifySaltpack.saltpackOperationStart']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1144,8 +1144,8 @@ const createKeybase1NotifySaltpackSaltpackOperationStart = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifySaltpack.saltpackOperationStart']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifySaltpackSaltpackOperationStart}) as const -const createKeybase1NotifyServiceHTTPSrvInfoUpdate = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifySaltpackSaltpackOperationStart} +type createKeybase1NotifyServiceHTTPSrvInfoUpdate = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyService.HTTPSrvInfoUpdate']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1153,8 +1153,8 @@ const createKeybase1NotifyServiceHTTPSrvInfoUpdate = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyService.HTTPSrvInfoUpdate']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyServiceHTTPSrvInfoUpdate}) as const -const createKeybase1NotifyServiceHandleKeybaseLink = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyServiceHTTPSrvInfoUpdate} +type createKeybase1NotifyServiceHandleKeybaseLink = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyService.handleKeybaseLink']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1162,32 +1162,32 @@ const createKeybase1NotifyServiceHandleKeybaseLink = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyService.handleKeybaseLink']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyServiceHandleKeybaseLink}) as const -const createKeybase1NotifyServiceShutdown = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyServiceHandleKeybaseLink} +type createKeybase1NotifyServiceShutdown = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyService.shutdown']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyService.shutdown']['outParam']) => void } -}) => ({payload, type: keybase1NotifyServiceShutdown}) as const -const createKeybase1NotifySessionClientOutOfDate = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyServiceShutdown} +type createKeybase1NotifySessionClientOutOfDate = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifySession.clientOutOfDate']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifySession.clientOutOfDate']['outParam']) => void } -}) => ({payload, type: keybase1NotifySessionClientOutOfDate}) as const -const createKeybase1NotifySessionLoggedIn = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifySessionClientOutOfDate} +type createKeybase1NotifySessionLoggedIn = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifySession.loggedIn']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifySession.loggedIn']['outParam']) => void } -}) => ({payload, type: keybase1NotifySessionLoggedIn}) as const -const createKeybase1NotifySessionLoggedOut = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifySessionLoggedIn} +type createKeybase1NotifySessionLoggedOut = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifySession.loggedOut']['inParam'] -}) => ({payload, type: keybase1NotifySessionLoggedOut}) as const -const createKeybase1NotifySimpleFSSimpleFSArchiveStatusChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifySessionLoggedOut} +type createKeybase1NotifySimpleFSSimpleFSArchiveStatusChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifySimpleFS.simpleFSArchiveStatusChanged']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1195,71 +1195,71 @@ const createKeybase1NotifySimpleFSSimpleFSArchiveStatusChanged = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifySimpleFS.simpleFSArchiveStatusChanged']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifySimpleFSSimpleFSArchiveStatusChanged}) as const -const createKeybase1NotifyTeamAvatarUpdated = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifySimpleFSSimpleFSArchiveStatusChanged} +type createKeybase1NotifyTeamAvatarUpdated = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeam.avatarUpdated']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyTeam.avatarUpdated']['outParam']) => void } -}) => ({payload, type: keybase1NotifyTeamAvatarUpdated}) as const -const createKeybase1NotifyTeamNewlyAddedToTeam = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeamAvatarUpdated} +type createKeybase1NotifyTeamNewlyAddedToTeam = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeam.newlyAddedToTeam']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyTeam.newlyAddedToTeam']['outParam']) => void } -}) => ({payload, type: keybase1NotifyTeamNewlyAddedToTeam}) as const -const createKeybase1NotifyTeamTeamAbandoned = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeamNewlyAddedToTeam} +type createKeybase1NotifyTeamTeamAbandoned = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamAbandoned']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamAbandoned']['outParam']) => void } -}) => ({payload, type: keybase1NotifyTeamTeamAbandoned}) as const -const createKeybase1NotifyTeamTeamChangedByID = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeamTeamAbandoned} +type createKeybase1NotifyTeamTeamChangedByID = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamChangedByID']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamChangedByID']['outParam']) => void } -}) => ({payload, type: keybase1NotifyTeamTeamChangedByID}) as const -const createKeybase1NotifyTeamTeamChangedByName = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeamTeamChangedByID} +type createKeybase1NotifyTeamTeamChangedByName = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamChangedByName']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamChangedByName']['outParam']) => void } -}) => ({payload, type: keybase1NotifyTeamTeamChangedByName}) as const -const createKeybase1NotifyTeamTeamDeleted = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeamTeamChangedByName} +type createKeybase1NotifyTeamTeamDeleted = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamDeleted']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamDeleted']['outParam']) => void } -}) => ({payload, type: keybase1NotifyTeamTeamDeleted}) as const -const createKeybase1NotifyTeamTeamExit = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeamTeamDeleted} +type createKeybase1NotifyTeamTeamExit = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamExit']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamExit']['outParam']) => void } -}) => ({payload, type: keybase1NotifyTeamTeamExit}) as const -const createKeybase1NotifyTeamTeamMetadataUpdate = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeamTeamExit} +type createKeybase1NotifyTeamTeamMetadataUpdate = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamMetadataUpdate']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamMetadataUpdate']['outParam']) => void } -}) => ({payload, type: keybase1NotifyTeamTeamMetadataUpdate}) as const -const createKeybase1NotifyTeamTeamRoleMapChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeamTeamMetadataUpdate} +type createKeybase1NotifyTeamTeamRoleMapChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamRoleMapChanged']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamRoleMapChanged']['outParam']) => void } -}) => ({payload, type: keybase1NotifyTeamTeamRoleMapChanged}) as const -const createKeybase1NotifyTeamTeamTreeMembershipsDone = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeamTeamRoleMapChanged} +type createKeybase1NotifyTeamTeamTreeMembershipsDone = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamTreeMembershipsDone']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1267,8 +1267,8 @@ const createKeybase1NotifyTeamTeamTreeMembershipsDone = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamTreeMembershipsDone']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyTeamTeamTreeMembershipsDone}) as const -const createKeybase1NotifyTeamTeamTreeMembershipsPartial = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeamTeamTreeMembershipsDone} +type createKeybase1NotifyTeamTeamTreeMembershipsPartial = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamTreeMembershipsPartial']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1276,11 +1276,11 @@ const createKeybase1NotifyTeamTeamTreeMembershipsPartial = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyTeam.teamTreeMembershipsPartial']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyTeamTeamTreeMembershipsPartial}) as const -const createKeybase1NotifyTeambotNewTeambotKey = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeamTeamTreeMembershipsPartial} +type createKeybase1NotifyTeambotNewTeambotKey = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeambot.newTeambotKey']['inParam'] -}) => ({payload, type: keybase1NotifyTeambotNewTeambotKey}) as const -const createKeybase1NotifyTeambotTeambotKeyNeeded = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeambotNewTeambotKey} +type createKeybase1NotifyTeambotTeambotKeyNeeded = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTeambot.teambotKeyNeeded']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1288,8 +1288,8 @@ const createKeybase1NotifyTeambotTeambotKeyNeeded = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyTeambot.teambotKeyNeeded']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyTeambotTeambotKeyNeeded}) as const -const createKeybase1NotifyTrackingNotifyUserBlocked = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTeambotTeambotKeyNeeded} +type createKeybase1NotifyTrackingNotifyUserBlocked = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTracking.notifyUserBlocked']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1297,59 +1297,59 @@ const createKeybase1NotifyTrackingNotifyUserBlocked = (payload: { param: keybase1Types.MessageTypes['keybase.1.NotifyTracking.notifyUserBlocked']['outParam'] ) => void } -}) => ({payload, type: keybase1NotifyTrackingNotifyUserBlocked}) as const -const createKeybase1NotifyTrackingTrackingChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTrackingNotifyUserBlocked} +type createKeybase1NotifyTrackingTrackingChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTracking.trackingChanged']['inParam'] -}) => ({payload, type: keybase1NotifyTrackingTrackingChanged}) as const -const createKeybase1NotifyTrackingTrackingInfo = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTrackingTrackingChanged} +type createKeybase1NotifyTrackingTrackingInfo = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyTracking.trackingInfo']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyTracking.trackingInfo']['outParam']) => void } -}) => ({payload, type: keybase1NotifyTrackingTrackingInfo}) as const -const createKeybase1NotifyUsersIdentifyUpdate = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyTrackingTrackingInfo} +type createKeybase1NotifyUsersIdentifyUpdate = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyUsers.identifyUpdate']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyUsers.identifyUpdate']['outParam']) => void } -}) => ({payload, type: keybase1NotifyUsersIdentifyUpdate}) as const -const createKeybase1NotifyUsersPasswordChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyUsersIdentifyUpdate} +type createKeybase1NotifyUsersPasswordChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyUsers.passwordChanged']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.NotifyUsers.passwordChanged']['outParam']) => void } -}) => ({payload, type: keybase1NotifyUsersPasswordChanged}) as const -const createKeybase1NotifyUsersUserChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyUsersPasswordChanged} +type createKeybase1NotifyUsersUserChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyUsers.userChanged']['inParam'] -}) => ({payload, type: keybase1NotifyUsersUserChanged}) as const -const createKeybase1NotifyUsersWebOfTrustChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyUsersUserChanged} +type createKeybase1NotifyUsersWebOfTrustChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.NotifyUsers.webOfTrustChanged']['inParam'] -}) => ({payload, type: keybase1NotifyUsersWebOfTrustChanged}) as const -const createKeybase1PgpUiFinished = (payload: { +}) => {payload: typeof payload; type: typeof keybase1NotifyUsersWebOfTrustChanged} +type createKeybase1PgpUiFinished = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.pgpUi.finished']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.pgpUi.finished']['outParam']) => void } -}) => ({payload, type: keybase1PgpUiFinished}) as const -const createKeybase1PgpUiKeyGenerated = (payload: { +}) => {payload: typeof payload; type: typeof keybase1PgpUiFinished} +type createKeybase1PgpUiKeyGenerated = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.pgpUi.keyGenerated']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.pgpUi.keyGenerated']['outParam']) => void } -}) => ({payload, type: keybase1PgpUiKeyGenerated}) as const -const createKeybase1PgpUiOutputPGPWarning = (payload: { +}) => {payload: typeof payload; type: typeof keybase1PgpUiKeyGenerated} +type createKeybase1PgpUiOutputPGPWarning = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.pgpUi.outputPGPWarning']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.pgpUi.outputPGPWarning']['outParam']) => void } -}) => ({payload, type: keybase1PgpUiOutputPGPWarning}) as const -const createKeybase1PgpUiOutputSignatureNonKeybase = (payload: { +}) => {payload: typeof payload; type: typeof keybase1PgpUiOutputPGPWarning} +type createKeybase1PgpUiOutputSignatureNonKeybase = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.pgpUi.outputSignatureNonKeybase']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1357,106 +1357,106 @@ const createKeybase1PgpUiOutputSignatureNonKeybase = (payload: { param: keybase1Types.MessageTypes['keybase.1.pgpUi.outputSignatureNonKeybase']['outParam'] ) => void } -}) => ({payload, type: keybase1PgpUiOutputSignatureNonKeybase}) as const -const createKeybase1PgpUiOutputSignatureSuccess = (payload: { +}) => {payload: typeof payload; type: typeof keybase1PgpUiOutputSignatureNonKeybase} +type createKeybase1PgpUiOutputSignatureSuccess = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.pgpUi.outputSignatureSuccess']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.pgpUi.outputSignatureSuccess']['outParam']) => void } -}) => ({payload, type: keybase1PgpUiOutputSignatureSuccess}) as const -const createKeybase1PgpUiShouldPushPrivate = (payload: { +}) => {payload: typeof payload; type: typeof keybase1PgpUiOutputSignatureSuccess} +type createKeybase1PgpUiShouldPushPrivate = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.pgpUi.shouldPushPrivate']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.pgpUi.shouldPushPrivate']['outParam']) => void } -}) => ({payload, type: keybase1PgpUiShouldPushPrivate}) as const -const createKeybase1ProveUiChecking = (payload: { +}) => {payload: typeof payload; type: typeof keybase1PgpUiShouldPushPrivate} +type createKeybase1ProveUiChecking = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.proveUi.checking']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.proveUi.checking']['outParam']) => void } -}) => ({payload, type: keybase1ProveUiChecking}) as const -const createKeybase1ProveUiContinueChecking = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProveUiChecking} +type createKeybase1ProveUiContinueChecking = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.proveUi.continueChecking']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.proveUi.continueChecking']['outParam']) => void } -}) => ({payload, type: keybase1ProveUiContinueChecking}) as const -const createKeybase1ProveUiDisplayRecheckWarning = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProveUiContinueChecking} +type createKeybase1ProveUiDisplayRecheckWarning = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.proveUi.displayRecheckWarning']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.proveUi.displayRecheckWarning']['outParam']) => void } -}) => ({payload, type: keybase1ProveUiDisplayRecheckWarning}) as const -const createKeybase1ProveUiOkToCheck = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProveUiDisplayRecheckWarning} +type createKeybase1ProveUiOkToCheck = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.proveUi.okToCheck']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.proveUi.okToCheck']['outParam']) => void } -}) => ({payload, type: keybase1ProveUiOkToCheck}) as const -const createKeybase1ProveUiOutputInstructions = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProveUiOkToCheck} +type createKeybase1ProveUiOutputInstructions = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.proveUi.outputInstructions']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.proveUi.outputInstructions']['outParam']) => void } -}) => ({payload, type: keybase1ProveUiOutputInstructions}) as const -const createKeybase1ProveUiOutputPrechecks = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProveUiOutputInstructions} +type createKeybase1ProveUiOutputPrechecks = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.proveUi.outputPrechecks']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.proveUi.outputPrechecks']['outParam']) => void } -}) => ({payload, type: keybase1ProveUiOutputPrechecks}) as const -const createKeybase1ProveUiPreProofWarning = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProveUiOutputPrechecks} +type createKeybase1ProveUiPreProofWarning = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.proveUi.preProofWarning']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.proveUi.preProofWarning']['outParam']) => void } -}) => ({payload, type: keybase1ProveUiPreProofWarning}) as const -const createKeybase1ProveUiPromptOverwrite = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProveUiPreProofWarning} +type createKeybase1ProveUiPromptOverwrite = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.proveUi.promptOverwrite']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.proveUi.promptOverwrite']['outParam']) => void } -}) => ({payload, type: keybase1ProveUiPromptOverwrite}) as const -const createKeybase1ProveUiPromptUsername = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProveUiPromptOverwrite} +type createKeybase1ProveUiPromptUsername = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.proveUi.promptUsername']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.proveUi.promptUsername']['outParam']) => void } -}) => ({payload, type: keybase1ProveUiPromptUsername}) as const -const createKeybase1ProvisionUiChooseDevice = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProveUiPromptUsername} +type createKeybase1ProvisionUiChooseDevice = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.provisionUi.chooseDevice']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.provisionUi.chooseDevice']['outParam']) => void } -}) => ({payload, type: keybase1ProvisionUiChooseDevice}) as const -const createKeybase1ProvisionUiChooseDeviceType = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProvisionUiChooseDevice} +type createKeybase1ProvisionUiChooseDeviceType = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.provisionUi.chooseDeviceType']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.provisionUi.chooseDeviceType']['outParam']) => void } -}) => ({payload, type: keybase1ProvisionUiChooseDeviceType}) as const -const createKeybase1ProvisionUiChooseGPGMethod = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProvisionUiChooseDeviceType} +type createKeybase1ProvisionUiChooseGPGMethod = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.provisionUi.chooseGPGMethod']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.provisionUi.chooseGPGMethod']['outParam']) => void } -}) => ({payload, type: keybase1ProvisionUiChooseGPGMethod}) as const -const createKeybase1ProvisionUiChooseProvisioningMethod = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProvisionUiChooseGPGMethod} +type createKeybase1ProvisionUiChooseProvisioningMethod = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.provisionUi.chooseProvisioningMethod']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1464,8 +1464,8 @@ const createKeybase1ProvisionUiChooseProvisioningMethod = (payload: { param: keybase1Types.MessageTypes['keybase.1.provisionUi.chooseProvisioningMethod']['outParam'] ) => void } -}) => ({payload, type: keybase1ProvisionUiChooseProvisioningMethod}) as const -const createKeybase1ProvisionUiDisplayAndPromptSecret = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProvisionUiChooseProvisioningMethod} +type createKeybase1ProvisionUiDisplayAndPromptSecret = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.provisionUi.DisplayAndPromptSecret']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1473,8 +1473,8 @@ const createKeybase1ProvisionUiDisplayAndPromptSecret = (payload: { param: keybase1Types.MessageTypes['keybase.1.provisionUi.DisplayAndPromptSecret']['outParam'] ) => void } -}) => ({payload, type: keybase1ProvisionUiDisplayAndPromptSecret}) as const -const createKeybase1ProvisionUiDisplaySecretExchanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProvisionUiDisplayAndPromptSecret} +type createKeybase1ProvisionUiDisplaySecretExchanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.provisionUi.DisplaySecretExchanged']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1482,8 +1482,8 @@ const createKeybase1ProvisionUiDisplaySecretExchanged = (payload: { param: keybase1Types.MessageTypes['keybase.1.provisionUi.DisplaySecretExchanged']['outParam'] ) => void } -}) => ({payload, type: keybase1ProvisionUiDisplaySecretExchanged}) as const -const createKeybase1ProvisionUiPromptNewDeviceName = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProvisionUiDisplaySecretExchanged} +type createKeybase1ProvisionUiPromptNewDeviceName = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.provisionUi.PromptNewDeviceName']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1491,8 +1491,8 @@ const createKeybase1ProvisionUiPromptNewDeviceName = (payload: { param: keybase1Types.MessageTypes['keybase.1.provisionUi.PromptNewDeviceName']['outParam'] ) => void } -}) => ({payload, type: keybase1ProvisionUiPromptNewDeviceName}) as const -const createKeybase1ProvisionUiProvisioneeSuccess = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProvisionUiPromptNewDeviceName} +type createKeybase1ProvisionUiProvisioneeSuccess = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.provisionUi.ProvisioneeSuccess']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1500,8 +1500,8 @@ const createKeybase1ProvisionUiProvisioneeSuccess = (payload: { param: keybase1Types.MessageTypes['keybase.1.provisionUi.ProvisioneeSuccess']['outParam'] ) => void } -}) => ({payload, type: keybase1ProvisionUiProvisioneeSuccess}) as const -const createKeybase1ProvisionUiProvisionerSuccess = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProvisionUiProvisioneeSuccess} +type createKeybase1ProvisionUiProvisionerSuccess = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.provisionUi.ProvisionerSuccess']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1509,39 +1509,39 @@ const createKeybase1ProvisionUiProvisionerSuccess = (payload: { param: keybase1Types.MessageTypes['keybase.1.provisionUi.ProvisionerSuccess']['outParam'] ) => void } -}) => ({payload, type: keybase1ProvisionUiProvisionerSuccess}) as const -const createKeybase1ProvisionUiSwitchToGPGSignOK = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProvisionUiProvisionerSuccess} +type createKeybase1ProvisionUiSwitchToGPGSignOK = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.provisionUi.switchToGPGSignOK']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.provisionUi.switchToGPGSignOK']['outParam']) => void } -}) => ({payload, type: keybase1ProvisionUiSwitchToGPGSignOK}) as const -const createKeybase1ReachabilityReachabilityChanged = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ProvisionUiSwitchToGPGSignOK} +type createKeybase1ReachabilityReachabilityChanged = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.reachability.reachabilityChanged']['inParam'] -}) => ({payload, type: keybase1ReachabilityReachabilityChanged}) as const -const createKeybase1RekeyUIDelegateRekeyUI = (payload: { +}) => {payload: typeof payload; type: typeof keybase1ReachabilityReachabilityChanged} +type createKeybase1RekeyUIDelegateRekeyUI = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.rekeyUI.delegateRekeyUI']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.rekeyUI.delegateRekeyUI']['outParam']) => void } -}) => ({payload, type: keybase1RekeyUIDelegateRekeyUI}) as const -const createKeybase1RekeyUIRefresh = (payload: { +}) => {payload: typeof payload; type: typeof keybase1RekeyUIDelegateRekeyUI} +type createKeybase1RekeyUIRefresh = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.rekeyUI.refresh']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.rekeyUI.refresh']['outParam']) => void } -}) => ({payload, type: keybase1RekeyUIRefresh}) as const -const createKeybase1RekeyUIRekeySendEvent = (payload: { +}) => {payload: typeof payload; type: typeof keybase1RekeyUIRefresh} +type createKeybase1RekeyUIRekeySendEvent = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.rekeyUI.rekeySendEvent']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.rekeyUI.rekeySendEvent']['outParam']) => void } -}) => ({payload, type: keybase1RekeyUIRekeySendEvent}) as const -const createKeybase1SaltpackUiSaltpackPromptForDecrypt = (payload: { +}) => {payload: typeof payload; type: typeof keybase1RekeyUIRekeySendEvent} +type createKeybase1SaltpackUiSaltpackPromptForDecrypt = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.saltpackUi.saltpackPromptForDecrypt']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1549,8 +1549,8 @@ const createKeybase1SaltpackUiSaltpackPromptForDecrypt = (payload: { param: keybase1Types.MessageTypes['keybase.1.saltpackUi.saltpackPromptForDecrypt']['outParam'] ) => void } -}) => ({payload, type: keybase1SaltpackUiSaltpackPromptForDecrypt}) as const -const createKeybase1SaltpackUiSaltpackVerifyBadSender = (payload: { +}) => {payload: typeof payload; type: typeof keybase1SaltpackUiSaltpackPromptForDecrypt} +type createKeybase1SaltpackUiSaltpackVerifyBadSender = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.saltpackUi.saltpackVerifyBadSender']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1558,8 +1558,8 @@ const createKeybase1SaltpackUiSaltpackVerifyBadSender = (payload: { param: keybase1Types.MessageTypes['keybase.1.saltpackUi.saltpackVerifyBadSender']['outParam'] ) => void } -}) => ({payload, type: keybase1SaltpackUiSaltpackVerifyBadSender}) as const -const createKeybase1SaltpackUiSaltpackVerifySuccess = (payload: { +}) => {payload: typeof payload; type: typeof keybase1SaltpackUiSaltpackVerifyBadSender} +type createKeybase1SaltpackUiSaltpackVerifySuccess = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.saltpackUi.saltpackVerifySuccess']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1567,43 +1567,43 @@ const createKeybase1SaltpackUiSaltpackVerifySuccess = (payload: { param: keybase1Types.MessageTypes['keybase.1.saltpackUi.saltpackVerifySuccess']['outParam'] ) => void } -}) => ({payload, type: keybase1SaltpackUiSaltpackVerifySuccess}) as const -const createKeybase1SecretUiGetPassphrase = (payload: { +}) => {payload: typeof payload; type: typeof keybase1SaltpackUiSaltpackVerifySuccess} +type createKeybase1SecretUiGetPassphrase = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.secretUi.getPassphrase']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.secretUi.getPassphrase']['outParam']) => void } -}) => ({payload, type: keybase1SecretUiGetPassphrase}) as const -const createKeybase1StreamUiClose = (payload: { +}) => {payload: typeof payload; type: typeof keybase1SecretUiGetPassphrase} +type createKeybase1StreamUiClose = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.streamUi.close']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.streamUi.close']['outParam']) => void } -}) => ({payload, type: keybase1StreamUiClose}) as const -const createKeybase1StreamUiRead = (payload: { +}) => {payload: typeof payload; type: typeof keybase1StreamUiClose} +type createKeybase1StreamUiRead = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.streamUi.read']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.streamUi.read']['outParam']) => void } -}) => ({payload, type: keybase1StreamUiRead}) as const -const createKeybase1StreamUiReset = (payload: { +}) => {payload: typeof payload; type: typeof keybase1StreamUiRead} +type createKeybase1StreamUiReset = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.streamUi.reset']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.streamUi.reset']['outParam']) => void } -}) => ({payload, type: keybase1StreamUiReset}) as const -const createKeybase1StreamUiWrite = (payload: { +}) => {payload: typeof payload; type: typeof keybase1StreamUiReset} +type createKeybase1StreamUiWrite = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.streamUi.write']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.streamUi.write']['outParam']) => void } -}) => ({payload, type: keybase1StreamUiWrite}) as const -const createKeybase1TeamsUiConfirmInviteLinkAccept = (payload: { +}) => {payload: typeof payload; type: typeof keybase1StreamUiWrite} +type createKeybase1TeamsUiConfirmInviteLinkAccept = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.teamsUi.confirmInviteLinkAccept']['inParam'] response: { error: keybase1Types.IncomingErrorCallback @@ -1611,538 +1611,356 @@ const createKeybase1TeamsUiConfirmInviteLinkAccept = (payload: { param: keybase1Types.MessageTypes['keybase.1.teamsUi.confirmInviteLinkAccept']['outParam'] ) => void } -}) => ({payload, type: keybase1TeamsUiConfirmInviteLinkAccept}) as const -const createKeybase1TeamsUiConfirmRootTeamDelete = (payload: { +}) => {payload: typeof payload; type: typeof keybase1TeamsUiConfirmInviteLinkAccept} +type createKeybase1TeamsUiConfirmRootTeamDelete = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.teamsUi.confirmRootTeamDelete']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.teamsUi.confirmRootTeamDelete']['outParam']) => void } -}) => ({payload, type: keybase1TeamsUiConfirmRootTeamDelete}) as const -const createKeybase1TeamsUiConfirmSubteamDelete = (payload: { +}) => {payload: typeof payload; type: typeof keybase1TeamsUiConfirmRootTeamDelete} +type createKeybase1TeamsUiConfirmSubteamDelete = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.teamsUi.confirmSubteamDelete']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.teamsUi.confirmSubteamDelete']['outParam']) => void } -}) => ({payload, type: keybase1TeamsUiConfirmSubteamDelete}) as const -const createKeybase1UiPromptYesNo = (payload: { +}) => {payload: typeof payload; type: typeof keybase1TeamsUiConfirmSubteamDelete} +type createKeybase1UiPromptYesNo = (payload: { readonly params: keybase1Types.MessageTypes['keybase.1.ui.promptYesNo']['inParam'] response: { error: keybase1Types.IncomingErrorCallback result: (param: keybase1Types.MessageTypes['keybase.1.ui.promptYesNo']['outParam']) => void } -}) => ({payload, type: keybase1UiPromptYesNo}) as const -const createStellar1NotifyAccountDetailsUpdate = (payload: { +}) => {payload: typeof payload; type: typeof keybase1UiPromptYesNo} +type createStellar1NotifyAccountDetailsUpdate = (payload: { readonly params: stellar1Types.MessageTypes['stellar.1.notify.accountDetailsUpdate']['inParam'] -}) => ({payload, type: stellar1NotifyAccountDetailsUpdate}) as const -const createStellar1NotifyAccountsUpdate = (payload: { +}) => {payload: typeof payload; type: typeof stellar1NotifyAccountDetailsUpdate} +type createStellar1NotifyAccountsUpdate = (payload: { readonly params: stellar1Types.MessageTypes['stellar.1.notify.accountsUpdate']['inParam'] -}) => ({payload, type: stellar1NotifyAccountsUpdate}) as const -const createStellar1NotifyPaymentNotification = (payload: { +}) => {payload: typeof payload; type: typeof stellar1NotifyAccountsUpdate} +type createStellar1NotifyPaymentNotification = (payload: { readonly params: stellar1Types.MessageTypes['stellar.1.notify.paymentNotification']['inParam'] -}) => ({payload, type: stellar1NotifyPaymentNotification}) as const -const createStellar1NotifyPaymentStatusNotification = (payload: { +}) => {payload: typeof payload; type: typeof stellar1NotifyPaymentNotification} +type createStellar1NotifyPaymentStatusNotification = (payload: { readonly params: stellar1Types.MessageTypes['stellar.1.notify.paymentStatusNotification']['inParam'] -}) => ({payload, type: stellar1NotifyPaymentStatusNotification}) as const -const createStellar1NotifyPendingPaymentsUpdate = (payload: { +}) => {payload: typeof payload; type: typeof stellar1NotifyPaymentStatusNotification} +type createStellar1NotifyPendingPaymentsUpdate = (payload: { readonly params: stellar1Types.MessageTypes['stellar.1.notify.pendingPaymentsUpdate']['inParam'] -}) => ({payload, type: stellar1NotifyPendingPaymentsUpdate}) as const -const createStellar1NotifyRecentPaymentsUpdate = (payload: { +}) => {payload: typeof payload; type: typeof stellar1NotifyPendingPaymentsUpdate} +type createStellar1NotifyRecentPaymentsUpdate = (payload: { readonly params: stellar1Types.MessageTypes['stellar.1.notify.recentPaymentsUpdate']['inParam'] -}) => ({payload, type: stellar1NotifyRecentPaymentsUpdate}) as const -const createStellar1NotifyRequestStatusNotification = (payload: { +}) => {payload: typeof payload; type: typeof stellar1NotifyRecentPaymentsUpdate} +type createStellar1NotifyRequestStatusNotification = (payload: { readonly params: stellar1Types.MessageTypes['stellar.1.notify.requestStatusNotification']['inParam'] -}) => ({payload, type: stellar1NotifyRequestStatusNotification}) as const -const createStellar1UiPaymentReviewed = (payload: { +}) => {payload: typeof payload; type: typeof stellar1NotifyRequestStatusNotification} +type createStellar1UiPaymentReviewed = (payload: { readonly params: stellar1Types.MessageTypes['stellar.1.ui.paymentReviewed']['inParam'] response: { error: stellar1Types.IncomingErrorCallback result: (param: stellar1Types.MessageTypes['stellar.1.ui.paymentReviewed']['outParam']) => void } -}) => ({payload, type: stellar1UiPaymentReviewed}) as const +}) => {payload: typeof payload; type: typeof stellar1UiPaymentReviewed} // Action Payloads -export type Chat1ChatUiChatBotCommandsUpdateStatusPayload = ReturnType< - typeof createChat1ChatUiChatBotCommandsUpdateStatus -> -export type Chat1ChatUiChatClearWatchPayload = ReturnType -export type Chat1ChatUiChatCoinFlipStatusPayload = ReturnType -export type Chat1ChatUiChatCommandMarkdownPayload = ReturnType -export type Chat1ChatUiChatCommandStatusPayload = ReturnType -export type Chat1ChatUiChatConfirmChannelDeletePayload = ReturnType< - typeof createChat1ChatUiChatConfirmChannelDelete -> -export type Chat1ChatUiChatGiphySearchResultsPayload = ReturnType< - typeof createChat1ChatUiChatGiphySearchResults -> -export type Chat1ChatUiChatGiphyToggleResultWindowPayload = ReturnType< - typeof createChat1ChatUiChatGiphyToggleResultWindow -> -export type Chat1ChatUiChatInboxConversationPayload = ReturnType< - typeof createChat1ChatUiChatInboxConversation -> -export type Chat1ChatUiChatInboxFailedPayload = ReturnType -export type Chat1ChatUiChatInboxLayoutPayload = ReturnType -export type Chat1ChatUiChatInboxUnverifiedPayload = ReturnType -export type Chat1ChatUiChatLoadGalleryHitPayload = ReturnType -export type Chat1ChatUiChatMaybeMentionUpdatePayload = ReturnType< - typeof createChat1ChatUiChatMaybeMentionUpdate -> -export type Chat1ChatUiChatSearchBotHitsPayload = ReturnType -export type Chat1ChatUiChatSearchConvHitsPayload = ReturnType -export type Chat1ChatUiChatSearchDonePayload = ReturnType -export type Chat1ChatUiChatSearchHitPayload = ReturnType -export type Chat1ChatUiChatSearchInboxDonePayload = ReturnType -export type Chat1ChatUiChatSearchInboxHitPayload = ReturnType -export type Chat1ChatUiChatSearchInboxStartPayload = ReturnType -export type Chat1ChatUiChatSearchIndexStatusPayload = ReturnType< - typeof createChat1ChatUiChatSearchIndexStatus -> -export type Chat1ChatUiChatSearchTeamHitsPayload = ReturnType -export type Chat1ChatUiChatShowManageChannelsPayload = ReturnType< - typeof createChat1ChatUiChatShowManageChannels -> -export type Chat1ChatUiChatStellarDataConfirmPayload = ReturnType< - typeof createChat1ChatUiChatStellarDataConfirm -> -export type Chat1ChatUiChatStellarDataErrorPayload = ReturnType -export type Chat1ChatUiChatStellarDonePayload = ReturnType -export type Chat1ChatUiChatStellarShowConfirmPayload = ReturnType< - typeof createChat1ChatUiChatStellarShowConfirm -> -export type Chat1ChatUiChatThreadCachedPayload = ReturnType -export type Chat1ChatUiChatThreadFullPayload = ReturnType -export type Chat1ChatUiChatThreadStatusPayload = ReturnType -export type Chat1ChatUiChatWatchPositionPayload = ReturnType -export type Chat1ChatUiTriggerContactSyncPayload = ReturnType -export type Chat1NotifyChatChatArchiveCompletePayload = ReturnType< - typeof createChat1NotifyChatChatArchiveComplete -> -export type Chat1NotifyChatChatArchiveProgressPayload = ReturnType< - typeof createChat1NotifyChatChatArchiveProgress -> -export type Chat1NotifyChatChatAttachmentDownloadCompletePayload = ReturnType< - typeof createChat1NotifyChatChatAttachmentDownloadComplete -> -export type Chat1NotifyChatChatAttachmentDownloadProgressPayload = ReturnType< - typeof createChat1NotifyChatChatAttachmentDownloadProgress -> -export type Chat1NotifyChatChatAttachmentUploadProgressPayload = ReturnType< - typeof createChat1NotifyChatChatAttachmentUploadProgress -> -export type Chat1NotifyChatChatAttachmentUploadStartPayload = ReturnType< - typeof createChat1NotifyChatChatAttachmentUploadStart -> -export type Chat1NotifyChatChatConvUpdatePayload = ReturnType -export type Chat1NotifyChatChatIdentifyUpdatePayload = ReturnType< - typeof createChat1NotifyChatChatIdentifyUpdate -> -export type Chat1NotifyChatChatInboxStalePayload = ReturnType -export type Chat1NotifyChatChatInboxSyncStartedPayload = ReturnType< - typeof createChat1NotifyChatChatInboxSyncStarted -> -export type Chat1NotifyChatChatInboxSyncedPayload = ReturnType -export type Chat1NotifyChatChatJoinedConversationPayload = ReturnType< - typeof createChat1NotifyChatChatJoinedConversation -> -export type Chat1NotifyChatChatKBFSToImpteamUpgradePayload = ReturnType< - typeof createChat1NotifyChatChatKBFSToImpteamUpgrade -> -export type Chat1NotifyChatChatLeftConversationPayload = ReturnType< - typeof createChat1NotifyChatChatLeftConversation -> -export type Chat1NotifyChatChatParticipantsInfoPayload = ReturnType< - typeof createChat1NotifyChatChatParticipantsInfo -> -export type Chat1NotifyChatChatPaymentInfoPayload = ReturnType -export type Chat1NotifyChatChatPromptUnfurlPayload = ReturnType -export type Chat1NotifyChatChatRequestInfoPayload = ReturnType -export type Chat1NotifyChatChatResetConversationPayload = ReturnType< - typeof createChat1NotifyChatChatResetConversation -> -export type Chat1NotifyChatChatSetConvRetentionPayload = ReturnType< - typeof createChat1NotifyChatChatSetConvRetention -> -export type Chat1NotifyChatChatSetConvSettingsPayload = ReturnType< - typeof createChat1NotifyChatChatSetConvSettings -> -export type Chat1NotifyChatChatSetTeamRetentionPayload = ReturnType< - typeof createChat1NotifyChatChatSetTeamRetention -> -export type Chat1NotifyChatChatSubteamRenamePayload = ReturnType< - typeof createChat1NotifyChatChatSubteamRename -> -export type Chat1NotifyChatChatTLFFinalizePayload = ReturnType -export type Chat1NotifyChatChatTLFResolvePayload = ReturnType -export type Chat1NotifyChatChatThreadsStalePayload = ReturnType -export type Chat1NotifyChatChatTypingUpdatePayload = ReturnType -export type Chat1NotifyChatChatWelcomeMessageLoadedPayload = ReturnType< - typeof createChat1NotifyChatChatWelcomeMessageLoaded -> -export type Chat1NotifyChatNewChatActivityPayload = ReturnType -export type Keybase1GpgUiConfirmDuplicateKeyChosenPayload = ReturnType< - typeof createKeybase1GpgUiConfirmDuplicateKeyChosen -> -export type Keybase1GpgUiConfirmImportSecretToExistingKeyPayload = ReturnType< - typeof createKeybase1GpgUiConfirmImportSecretToExistingKey -> -export type Keybase1GpgUiGetTTYPayload = ReturnType -export type Keybase1GpgUiSelectKeyAndPushOptionPayload = ReturnType< - typeof createKeybase1GpgUiSelectKeyAndPushOption -> -export type Keybase1GpgUiSelectKeyPayload = ReturnType -export type Keybase1GpgUiSignPayload = ReturnType -export type Keybase1GpgUiWantToAddGPGKeyPayload = ReturnType -export type Keybase1GregorUIPushOutOfBandMessagesPayload = ReturnType< - typeof createKeybase1GregorUIPushOutOfBandMessages -> -export type Keybase1GregorUIPushStatePayload = ReturnType -export type Keybase1HomeUIHomeUIRefreshPayload = ReturnType -export type Keybase1Identify3UiIdentify3ResultPayload = ReturnType< - typeof createKeybase1Identify3UiIdentify3Result -> -export type Keybase1Identify3UiIdentify3ShowTrackerPayload = ReturnType< - typeof createKeybase1Identify3UiIdentify3ShowTracker -> -export type Keybase1Identify3UiIdentify3SummaryPayload = ReturnType< - typeof createKeybase1Identify3UiIdentify3Summary -> -export type Keybase1Identify3UiIdentify3TrackerTimedOutPayload = ReturnType< - typeof createKeybase1Identify3UiIdentify3TrackerTimedOut -> -export type Keybase1Identify3UiIdentify3UpdateRowPayload = ReturnType< - typeof createKeybase1Identify3UiIdentify3UpdateRow -> -export type Keybase1Identify3UiIdentify3UpdateUserCardPayload = ReturnType< - typeof createKeybase1Identify3UiIdentify3UpdateUserCard -> -export type Keybase1Identify3UiIdentify3UserResetPayload = ReturnType< - typeof createKeybase1Identify3UiIdentify3UserReset -> -export type Keybase1IdentifyUiCancelPayload = ReturnType -export type Keybase1IdentifyUiConfirmPayload = ReturnType -export type Keybase1IdentifyUiDelegateIdentifyUIPayload = ReturnType< - typeof createKeybase1IdentifyUiDelegateIdentifyUI -> -export type Keybase1IdentifyUiDismissPayload = ReturnType -export type Keybase1IdentifyUiDisplayCryptocurrencyPayload = ReturnType< - typeof createKeybase1IdentifyUiDisplayCryptocurrency -> -export type Keybase1IdentifyUiDisplayKeyPayload = ReturnType -export type Keybase1IdentifyUiDisplayStellarAccountPayload = ReturnType< - typeof createKeybase1IdentifyUiDisplayStellarAccount -> -export type Keybase1IdentifyUiDisplayTLFCreateWithInvitePayload = ReturnType< - typeof createKeybase1IdentifyUiDisplayTLFCreateWithInvite -> -export type Keybase1IdentifyUiDisplayTrackStatementPayload = ReturnType< - typeof createKeybase1IdentifyUiDisplayTrackStatement -> -export type Keybase1IdentifyUiDisplayUserCardPayload = ReturnType< - typeof createKeybase1IdentifyUiDisplayUserCard -> -export type Keybase1IdentifyUiFinishPayload = ReturnType -export type Keybase1IdentifyUiFinishSocialProofCheckPayload = ReturnType< - typeof createKeybase1IdentifyUiFinishSocialProofCheck -> -export type Keybase1IdentifyUiFinishWebProofCheckPayload = ReturnType< - typeof createKeybase1IdentifyUiFinishWebProofCheck -> -export type Keybase1IdentifyUiLaunchNetworkChecksPayload = ReturnType< - typeof createKeybase1IdentifyUiLaunchNetworkChecks -> -export type Keybase1IdentifyUiReportLastTrackPayload = ReturnType< - typeof createKeybase1IdentifyUiReportLastTrack -> -export type Keybase1IdentifyUiReportTrackTokenPayload = ReturnType< - typeof createKeybase1IdentifyUiReportTrackToken -> -export type Keybase1IdentifyUiStartPayload = ReturnType -export type Keybase1LogUiLogPayload = ReturnType -export type Keybase1LoginUiChooseDeviceToRecoverWithPayload = ReturnType< - typeof createKeybase1LoginUiChooseDeviceToRecoverWith -> -export type Keybase1LoginUiDisplayPaperKeyPhrasePayload = ReturnType< - typeof createKeybase1LoginUiDisplayPaperKeyPhrase -> -export type Keybase1LoginUiDisplayPrimaryPaperKeyPayload = ReturnType< - typeof createKeybase1LoginUiDisplayPrimaryPaperKey -> -export type Keybase1LoginUiDisplayResetMessagePayload = ReturnType< - typeof createKeybase1LoginUiDisplayResetMessage -> -export type Keybase1LoginUiDisplayResetProgressPayload = ReturnType< - typeof createKeybase1LoginUiDisplayResetProgress -> -export type Keybase1LoginUiExplainDeviceRecoveryPayload = ReturnType< - typeof createKeybase1LoginUiExplainDeviceRecovery -> -export type Keybase1LoginUiGetEmailOrUsernamePayload = ReturnType< - typeof createKeybase1LoginUiGetEmailOrUsername -> -export type Keybase1LoginUiPromptPassphraseRecoveryPayload = ReturnType< - typeof createKeybase1LoginUiPromptPassphraseRecovery -> -export type Keybase1LoginUiPromptResetAccountPayload = ReturnType< - typeof createKeybase1LoginUiPromptResetAccount -> -export type Keybase1LoginUiPromptRevokePaperKeysPayload = ReturnType< - typeof createKeybase1LoginUiPromptRevokePaperKeys -> -export type Keybase1LogsendPrepareLogsendPayload = ReturnType -export type Keybase1NotifyAppExitPayload = ReturnType -export type Keybase1NotifyAuditBoxAuditErrorPayload = ReturnType< - typeof createKeybase1NotifyAuditBoxAuditError -> -export type Keybase1NotifyAuditRootAuditErrorPayload = ReturnType< - typeof createKeybase1NotifyAuditRootAuditError -> -export type Keybase1NotifyBadgesBadgeStatePayload = ReturnType -export type Keybase1NotifyCanUserPerformCanUserPerformChangedPayload = ReturnType< - typeof createKeybase1NotifyCanUserPerformCanUserPerformChanged -> -export type Keybase1NotifyDeviceCloneDeviceCloneCountChangedPayload = ReturnType< - typeof createKeybase1NotifyDeviceCloneDeviceCloneCountChanged -> -export type Keybase1NotifyEmailAddressEmailAddressVerifiedPayload = ReturnType< - typeof createKeybase1NotifyEmailAddressEmailAddressVerified -> -export type Keybase1NotifyEmailAddressEmailsChangedPayload = ReturnType< - typeof createKeybase1NotifyEmailAddressEmailsChanged -> -export type Keybase1NotifyEphemeralNewTeamEkPayload = ReturnType< - typeof createKeybase1NotifyEphemeralNewTeamEk -> -export type Keybase1NotifyEphemeralNewTeambotEkPayload = ReturnType< - typeof createKeybase1NotifyEphemeralNewTeambotEk -> -export type Keybase1NotifyEphemeralTeambotEkNeededPayload = ReturnType< - typeof createKeybase1NotifyEphemeralTeambotEkNeeded -> -export type Keybase1NotifyFSFSActivityPayload = ReturnType -export type Keybase1NotifyFSFSEditListResponsePayload = ReturnType< - typeof createKeybase1NotifyFSFSEditListResponse -> -export type Keybase1NotifyFSFSFavoritesChangedPayload = ReturnType< - typeof createKeybase1NotifyFSFSFavoritesChanged -> -export type Keybase1NotifyFSFSOnlineStatusChangedPayload = ReturnType< - typeof createKeybase1NotifyFSFSOnlineStatusChanged -> -export type Keybase1NotifyFSFSOverallSyncStatusChangedPayload = ReturnType< - typeof createKeybase1NotifyFSFSOverallSyncStatusChanged -> -export type Keybase1NotifyFSFSPathUpdatedPayload = ReturnType -export type Keybase1NotifyFSFSSubscriptionNotifyPathPayload = ReturnType< - typeof createKeybase1NotifyFSFSSubscriptionNotifyPath -> -export type Keybase1NotifyFSFSSubscriptionNotifyPayload = ReturnType< - typeof createKeybase1NotifyFSFSSubscriptionNotify -> -export type Keybase1NotifyFSFSSyncActivityPayload = ReturnType -export type Keybase1NotifyFSFSSyncStatusResponsePayload = ReturnType< - typeof createKeybase1NotifyFSFSSyncStatusResponse -> -export type Keybase1NotifyFavoritesFavoritesChangedPayload = ReturnType< - typeof createKeybase1NotifyFavoritesFavoritesChanged -> -export type Keybase1NotifyFeaturedBotsFeaturedBotsUpdatePayload = ReturnType< - typeof createKeybase1NotifyFeaturedBotsFeaturedBotsUpdate -> -export type Keybase1NotifyInviteFriendsUpdateInviteCountsPayload = ReturnType< - typeof createKeybase1NotifyInviteFriendsUpdateInviteCounts -> -export type Keybase1NotifyKeyfamilyKeyfamilyChangedPayload = ReturnType< - typeof createKeybase1NotifyKeyfamilyKeyfamilyChanged -> -export type Keybase1NotifyPGPPgpKeyInSecretStoreFilePayload = ReturnType< - typeof createKeybase1NotifyPGPPgpKeyInSecretStoreFile -> -export type Keybase1NotifyPaperKeyPaperKeyCachedPayload = ReturnType< - typeof createKeybase1NotifyPaperKeyPaperKeyCached -> -export type Keybase1NotifyPhoneNumberPhoneNumbersChangedPayload = ReturnType< - typeof createKeybase1NotifyPhoneNumberPhoneNumbersChanged -> -export type Keybase1NotifyRuntimeStatsRuntimeStatsUpdatePayload = ReturnType< - typeof createKeybase1NotifyRuntimeStatsRuntimeStatsUpdate -> -export type Keybase1NotifySaltpackSaltpackOperationDonePayload = ReturnType< - typeof createKeybase1NotifySaltpackSaltpackOperationDone -> -export type Keybase1NotifySaltpackSaltpackOperationProgressPayload = ReturnType< - typeof createKeybase1NotifySaltpackSaltpackOperationProgress -> -export type Keybase1NotifySaltpackSaltpackOperationStartPayload = ReturnType< - typeof createKeybase1NotifySaltpackSaltpackOperationStart -> -export type Keybase1NotifyServiceHTTPSrvInfoUpdatePayload = ReturnType< - typeof createKeybase1NotifyServiceHTTPSrvInfoUpdate -> -export type Keybase1NotifyServiceHandleKeybaseLinkPayload = ReturnType< - typeof createKeybase1NotifyServiceHandleKeybaseLink -> -export type Keybase1NotifyServiceShutdownPayload = ReturnType -export type Keybase1NotifySessionClientOutOfDatePayload = ReturnType< - typeof createKeybase1NotifySessionClientOutOfDate -> -export type Keybase1NotifySessionLoggedInPayload = ReturnType -export type Keybase1NotifySessionLoggedOutPayload = ReturnType -export type Keybase1NotifySimpleFSSimpleFSArchiveStatusChangedPayload = ReturnType< - typeof createKeybase1NotifySimpleFSSimpleFSArchiveStatusChanged -> -export type Keybase1NotifyTeamAvatarUpdatedPayload = ReturnType -export type Keybase1NotifyTeamNewlyAddedToTeamPayload = ReturnType< - typeof createKeybase1NotifyTeamNewlyAddedToTeam -> -export type Keybase1NotifyTeamTeamAbandonedPayload = ReturnType -export type Keybase1NotifyTeamTeamChangedByIDPayload = ReturnType< - typeof createKeybase1NotifyTeamTeamChangedByID -> -export type Keybase1NotifyTeamTeamChangedByNamePayload = ReturnType< - typeof createKeybase1NotifyTeamTeamChangedByName -> -export type Keybase1NotifyTeamTeamDeletedPayload = ReturnType -export type Keybase1NotifyTeamTeamExitPayload = ReturnType -export type Keybase1NotifyTeamTeamMetadataUpdatePayload = ReturnType< - typeof createKeybase1NotifyTeamTeamMetadataUpdate -> -export type Keybase1NotifyTeamTeamRoleMapChangedPayload = ReturnType< - typeof createKeybase1NotifyTeamTeamRoleMapChanged -> -export type Keybase1NotifyTeamTeamTreeMembershipsDonePayload = ReturnType< - typeof createKeybase1NotifyTeamTeamTreeMembershipsDone -> -export type Keybase1NotifyTeamTeamTreeMembershipsPartialPayload = ReturnType< - typeof createKeybase1NotifyTeamTeamTreeMembershipsPartial -> -export type Keybase1NotifyTeambotNewTeambotKeyPayload = ReturnType< - typeof createKeybase1NotifyTeambotNewTeambotKey -> -export type Keybase1NotifyTeambotTeambotKeyNeededPayload = ReturnType< - typeof createKeybase1NotifyTeambotTeambotKeyNeeded -> -export type Keybase1NotifyTrackingNotifyUserBlockedPayload = ReturnType< - typeof createKeybase1NotifyTrackingNotifyUserBlocked -> -export type Keybase1NotifyTrackingTrackingChangedPayload = ReturnType< - typeof createKeybase1NotifyTrackingTrackingChanged -> -export type Keybase1NotifyTrackingTrackingInfoPayload = ReturnType< - typeof createKeybase1NotifyTrackingTrackingInfo -> -export type Keybase1NotifyUsersIdentifyUpdatePayload = ReturnType< - typeof createKeybase1NotifyUsersIdentifyUpdate -> -export type Keybase1NotifyUsersPasswordChangedPayload = ReturnType< - typeof createKeybase1NotifyUsersPasswordChanged -> -export type Keybase1NotifyUsersUserChangedPayload = ReturnType -export type Keybase1NotifyUsersWebOfTrustChangedPayload = ReturnType< - typeof createKeybase1NotifyUsersWebOfTrustChanged -> -export type Keybase1PgpUiFinishedPayload = ReturnType -export type Keybase1PgpUiKeyGeneratedPayload = ReturnType -export type Keybase1PgpUiOutputPGPWarningPayload = ReturnType -export type Keybase1PgpUiOutputSignatureNonKeybasePayload = ReturnType< - typeof createKeybase1PgpUiOutputSignatureNonKeybase -> -export type Keybase1PgpUiOutputSignatureSuccessPayload = ReturnType< - typeof createKeybase1PgpUiOutputSignatureSuccess -> -export type Keybase1PgpUiShouldPushPrivatePayload = ReturnType -export type Keybase1ProveUiCheckingPayload = ReturnType -export type Keybase1ProveUiContinueCheckingPayload = ReturnType -export type Keybase1ProveUiDisplayRecheckWarningPayload = ReturnType< - typeof createKeybase1ProveUiDisplayRecheckWarning -> -export type Keybase1ProveUiOkToCheckPayload = ReturnType -export type Keybase1ProveUiOutputInstructionsPayload = ReturnType< - typeof createKeybase1ProveUiOutputInstructions -> -export type Keybase1ProveUiOutputPrechecksPayload = ReturnType -export type Keybase1ProveUiPreProofWarningPayload = ReturnType -export type Keybase1ProveUiPromptOverwritePayload = ReturnType -export type Keybase1ProveUiPromptUsernamePayload = ReturnType -export type Keybase1ProvisionUiChooseDevicePayload = ReturnType -export type Keybase1ProvisionUiChooseDeviceTypePayload = ReturnType< - typeof createKeybase1ProvisionUiChooseDeviceType -> -export type Keybase1ProvisionUiChooseGPGMethodPayload = ReturnType< - typeof createKeybase1ProvisionUiChooseGPGMethod -> -export type Keybase1ProvisionUiChooseProvisioningMethodPayload = ReturnType< - typeof createKeybase1ProvisionUiChooseProvisioningMethod -> -export type Keybase1ProvisionUiDisplayAndPromptSecretPayload = ReturnType< - typeof createKeybase1ProvisionUiDisplayAndPromptSecret -> -export type Keybase1ProvisionUiDisplaySecretExchangedPayload = ReturnType< - typeof createKeybase1ProvisionUiDisplaySecretExchanged -> -export type Keybase1ProvisionUiPromptNewDeviceNamePayload = ReturnType< - typeof createKeybase1ProvisionUiPromptNewDeviceName -> -export type Keybase1ProvisionUiProvisioneeSuccessPayload = ReturnType< - typeof createKeybase1ProvisionUiProvisioneeSuccess -> -export type Keybase1ProvisionUiProvisionerSuccessPayload = ReturnType< - typeof createKeybase1ProvisionUiProvisionerSuccess -> -export type Keybase1ProvisionUiSwitchToGPGSignOKPayload = ReturnType< - typeof createKeybase1ProvisionUiSwitchToGPGSignOK -> -export type Keybase1ReachabilityReachabilityChangedPayload = ReturnType< - typeof createKeybase1ReachabilityReachabilityChanged -> -export type Keybase1RekeyUIDelegateRekeyUIPayload = ReturnType -export type Keybase1RekeyUIRefreshPayload = ReturnType -export type Keybase1RekeyUIRekeySendEventPayload = ReturnType -export type Keybase1SaltpackUiSaltpackPromptForDecryptPayload = ReturnType< - typeof createKeybase1SaltpackUiSaltpackPromptForDecrypt -> -export type Keybase1SaltpackUiSaltpackVerifyBadSenderPayload = ReturnType< - typeof createKeybase1SaltpackUiSaltpackVerifyBadSender -> -export type Keybase1SaltpackUiSaltpackVerifySuccessPayload = ReturnType< - typeof createKeybase1SaltpackUiSaltpackVerifySuccess -> -export type Keybase1SecretUiGetPassphrasePayload = ReturnType -export type Keybase1StreamUiClosePayload = ReturnType -export type Keybase1StreamUiReadPayload = ReturnType -export type Keybase1StreamUiResetPayload = ReturnType -export type Keybase1StreamUiWritePayload = ReturnType -export type Keybase1TeamsUiConfirmInviteLinkAcceptPayload = ReturnType< - typeof createKeybase1TeamsUiConfirmInviteLinkAccept -> -export type Keybase1TeamsUiConfirmRootTeamDeletePayload = ReturnType< - typeof createKeybase1TeamsUiConfirmRootTeamDelete -> -export type Keybase1TeamsUiConfirmSubteamDeletePayload = ReturnType< - typeof createKeybase1TeamsUiConfirmSubteamDelete -> -export type Keybase1UiPromptYesNoPayload = ReturnType -export type Stellar1NotifyAccountDetailsUpdatePayload = ReturnType< - typeof createStellar1NotifyAccountDetailsUpdate -> -export type Stellar1NotifyAccountsUpdatePayload = ReturnType -export type Stellar1NotifyPaymentNotificationPayload = ReturnType< - typeof createStellar1NotifyPaymentNotification -> -export type Stellar1NotifyPaymentStatusNotificationPayload = ReturnType< - typeof createStellar1NotifyPaymentStatusNotification -> -export type Stellar1NotifyPendingPaymentsUpdatePayload = ReturnType< - typeof createStellar1NotifyPendingPaymentsUpdate -> -export type Stellar1NotifyRecentPaymentsUpdatePayload = ReturnType< - typeof createStellar1NotifyRecentPaymentsUpdate -> -export type Stellar1NotifyRequestStatusNotificationPayload = ReturnType< - typeof createStellar1NotifyRequestStatusNotification -> -export type Stellar1UiPaymentReviewedPayload = ReturnType +export type Chat1ChatUiChatBotCommandsUpdateStatusPayload = + ReturnType +export type Chat1ChatUiChatClearWatchPayload = ReturnType +export type Chat1ChatUiChatCoinFlipStatusPayload = ReturnType +export type Chat1ChatUiChatCommandMarkdownPayload = ReturnType +export type Chat1ChatUiChatCommandStatusPayload = ReturnType +export type Chat1ChatUiChatConfirmChannelDeletePayload = ReturnType +export type Chat1ChatUiChatGiphySearchResultsPayload = ReturnType +export type Chat1ChatUiChatGiphyToggleResultWindowPayload = + ReturnType +export type Chat1ChatUiChatInboxConversationPayload = ReturnType +export type Chat1ChatUiChatInboxFailedPayload = ReturnType +export type Chat1ChatUiChatInboxLayoutPayload = ReturnType +export type Chat1ChatUiChatInboxUnverifiedPayload = ReturnType +export type Chat1ChatUiChatLoadGalleryHitPayload = ReturnType +export type Chat1ChatUiChatMaybeMentionUpdatePayload = ReturnType +export type Chat1ChatUiChatSearchBotHitsPayload = ReturnType +export type Chat1ChatUiChatSearchConvHitsPayload = ReturnType +export type Chat1ChatUiChatSearchDonePayload = ReturnType +export type Chat1ChatUiChatSearchHitPayload = ReturnType +export type Chat1ChatUiChatSearchInboxDonePayload = ReturnType +export type Chat1ChatUiChatSearchInboxHitPayload = ReturnType +export type Chat1ChatUiChatSearchInboxStartPayload = ReturnType +export type Chat1ChatUiChatSearchIndexStatusPayload = ReturnType +export type Chat1ChatUiChatSearchTeamHitsPayload = ReturnType +export type Chat1ChatUiChatShowManageChannelsPayload = ReturnType +export type Chat1ChatUiChatStellarDataConfirmPayload = ReturnType +export type Chat1ChatUiChatStellarDataErrorPayload = ReturnType +export type Chat1ChatUiChatStellarDonePayload = ReturnType +export type Chat1ChatUiChatStellarShowConfirmPayload = ReturnType +export type Chat1ChatUiChatThreadCachedPayload = ReturnType +export type Chat1ChatUiChatThreadFullPayload = ReturnType +export type Chat1ChatUiChatThreadStatusPayload = ReturnType +export type Chat1ChatUiChatWatchPositionPayload = ReturnType +export type Chat1ChatUiTriggerContactSyncPayload = ReturnType +export type Chat1NotifyChatChatArchiveCompletePayload = ReturnType +export type Chat1NotifyChatChatArchiveProgressPayload = ReturnType +export type Chat1NotifyChatChatAttachmentDownloadCompletePayload = + ReturnType +export type Chat1NotifyChatChatAttachmentDownloadProgressPayload = + ReturnType +export type Chat1NotifyChatChatAttachmentUploadProgressPayload = + ReturnType +export type Chat1NotifyChatChatAttachmentUploadStartPayload = + ReturnType +export type Chat1NotifyChatChatConvUpdatePayload = ReturnType +export type Chat1NotifyChatChatIdentifyUpdatePayload = ReturnType +export type Chat1NotifyChatChatInboxStalePayload = ReturnType +export type Chat1NotifyChatChatInboxSyncStartedPayload = ReturnType +export type Chat1NotifyChatChatInboxSyncedPayload = ReturnType +export type Chat1NotifyChatChatJoinedConversationPayload = + ReturnType +export type Chat1NotifyChatChatKBFSToImpteamUpgradePayload = + ReturnType +export type Chat1NotifyChatChatLeftConversationPayload = ReturnType +export type Chat1NotifyChatChatParticipantsInfoPayload = ReturnType +export type Chat1NotifyChatChatPaymentInfoPayload = ReturnType +export type Chat1NotifyChatChatPromptUnfurlPayload = ReturnType +export type Chat1NotifyChatChatRequestInfoPayload = ReturnType +export type Chat1NotifyChatChatResetConversationPayload = + ReturnType +export type Chat1NotifyChatChatSetConvRetentionPayload = ReturnType +export type Chat1NotifyChatChatSetConvSettingsPayload = ReturnType +export type Chat1NotifyChatChatSetTeamRetentionPayload = ReturnType +export type Chat1NotifyChatChatSubteamRenamePayload = ReturnType +export type Chat1NotifyChatChatTLFFinalizePayload = ReturnType +export type Chat1NotifyChatChatTLFResolvePayload = ReturnType +export type Chat1NotifyChatChatThreadsStalePayload = ReturnType +export type Chat1NotifyChatChatTypingUpdatePayload = ReturnType +export type Chat1NotifyChatChatWelcomeMessageLoadedPayload = + ReturnType +export type Chat1NotifyChatNewChatActivityPayload = ReturnType +export type Keybase1GpgUiConfirmDuplicateKeyChosenPayload = + ReturnType +export type Keybase1GpgUiConfirmImportSecretToExistingKeyPayload = + ReturnType +export type Keybase1GpgUiGetTTYPayload = ReturnType +export type Keybase1GpgUiSelectKeyAndPushOptionPayload = ReturnType +export type Keybase1GpgUiSelectKeyPayload = ReturnType +export type Keybase1GpgUiSignPayload = ReturnType +export type Keybase1GpgUiWantToAddGPGKeyPayload = ReturnType +export type Keybase1GregorUIPushOutOfBandMessagesPayload = + ReturnType +export type Keybase1GregorUIPushStatePayload = ReturnType +export type Keybase1HomeUIHomeUIRefreshPayload = ReturnType +export type Keybase1Identify3UiIdentify3ResultPayload = ReturnType +export type Keybase1Identify3UiIdentify3ShowTrackerPayload = + ReturnType +export type Keybase1Identify3UiIdentify3SummaryPayload = ReturnType +export type Keybase1Identify3UiIdentify3TrackerTimedOutPayload = + ReturnType +export type Keybase1Identify3UiIdentify3UpdateRowPayload = + ReturnType +export type Keybase1Identify3UiIdentify3UpdateUserCardPayload = + ReturnType +export type Keybase1Identify3UiIdentify3UserResetPayload = + ReturnType +export type Keybase1IdentifyUiCancelPayload = ReturnType +export type Keybase1IdentifyUiConfirmPayload = ReturnType +export type Keybase1IdentifyUiDelegateIdentifyUIPayload = + ReturnType +export type Keybase1IdentifyUiDismissPayload = ReturnType +export type Keybase1IdentifyUiDisplayCryptocurrencyPayload = + ReturnType +export type Keybase1IdentifyUiDisplayKeyPayload = ReturnType +export type Keybase1IdentifyUiDisplayStellarAccountPayload = + ReturnType +export type Keybase1IdentifyUiDisplayTLFCreateWithInvitePayload = + ReturnType +export type Keybase1IdentifyUiDisplayTrackStatementPayload = + ReturnType +export type Keybase1IdentifyUiDisplayUserCardPayload = ReturnType +export type Keybase1IdentifyUiFinishPayload = ReturnType +export type Keybase1IdentifyUiFinishSocialProofCheckPayload = + ReturnType +export type Keybase1IdentifyUiFinishWebProofCheckPayload = + ReturnType +export type Keybase1IdentifyUiLaunchNetworkChecksPayload = + ReturnType +export type Keybase1IdentifyUiReportLastTrackPayload = ReturnType +export type Keybase1IdentifyUiReportTrackTokenPayload = ReturnType +export type Keybase1IdentifyUiStartPayload = ReturnType +export type Keybase1LogUiLogPayload = ReturnType +export type Keybase1LoginUiChooseDeviceToRecoverWithPayload = + ReturnType +export type Keybase1LoginUiDisplayPaperKeyPhrasePayload = + ReturnType +export type Keybase1LoginUiDisplayPrimaryPaperKeyPayload = + ReturnType +export type Keybase1LoginUiDisplayResetMessagePayload = ReturnType +export type Keybase1LoginUiDisplayResetProgressPayload = ReturnType +export type Keybase1LoginUiExplainDeviceRecoveryPayload = + ReturnType +export type Keybase1LoginUiGetEmailOrUsernamePayload = ReturnType +export type Keybase1LoginUiPromptPassphraseRecoveryPayload = + ReturnType +export type Keybase1LoginUiPromptResetAccountPayload = ReturnType +export type Keybase1LoginUiPromptRevokePaperKeysPayload = + ReturnType +export type Keybase1LogsendPrepareLogsendPayload = ReturnType +export type Keybase1NotifyAppExitPayload = ReturnType +export type Keybase1NotifyAuditBoxAuditErrorPayload = ReturnType +export type Keybase1NotifyAuditRootAuditErrorPayload = ReturnType +export type Keybase1NotifyBadgesBadgeStatePayload = ReturnType +export type Keybase1NotifyCanUserPerformCanUserPerformChangedPayload = + ReturnType +export type Keybase1NotifyDeviceCloneDeviceCloneCountChangedPayload = + ReturnType +export type Keybase1NotifyEmailAddressEmailAddressVerifiedPayload = + ReturnType +export type Keybase1NotifyEmailAddressEmailsChangedPayload = + ReturnType +export type Keybase1NotifyEphemeralNewTeamEkPayload = ReturnType +export type Keybase1NotifyEphemeralNewTeambotEkPayload = ReturnType +export type Keybase1NotifyEphemeralTeambotEkNeededPayload = + ReturnType +export type Keybase1NotifyFSFSActivityPayload = ReturnType +export type Keybase1NotifyFSFSEditListResponsePayload = ReturnType +export type Keybase1NotifyFSFSFavoritesChangedPayload = ReturnType +export type Keybase1NotifyFSFSOnlineStatusChangedPayload = + ReturnType +export type Keybase1NotifyFSFSOverallSyncStatusChangedPayload = + ReturnType +export type Keybase1NotifyFSFSPathUpdatedPayload = ReturnType +export type Keybase1NotifyFSFSSubscriptionNotifyPathPayload = + ReturnType +export type Keybase1NotifyFSFSSubscriptionNotifyPayload = + ReturnType +export type Keybase1NotifyFSFSSyncActivityPayload = ReturnType +export type Keybase1NotifyFSFSSyncStatusResponsePayload = + ReturnType +export type Keybase1NotifyFavoritesFavoritesChangedPayload = + ReturnType +export type Keybase1NotifyFeaturedBotsFeaturedBotsUpdatePayload = + ReturnType +export type Keybase1NotifyInviteFriendsUpdateInviteCountsPayload = + ReturnType +export type Keybase1NotifyKeyfamilyKeyfamilyChangedPayload = + ReturnType +export type Keybase1NotifyPGPPgpKeyInSecretStoreFilePayload = + ReturnType +export type Keybase1NotifyPaperKeyPaperKeyCachedPayload = + ReturnType +export type Keybase1NotifyPhoneNumberPhoneNumbersChangedPayload = + ReturnType +export type Keybase1NotifyRuntimeStatsRuntimeStatsUpdatePayload = + ReturnType +export type Keybase1NotifySaltpackSaltpackOperationDonePayload = + ReturnType +export type Keybase1NotifySaltpackSaltpackOperationProgressPayload = + ReturnType +export type Keybase1NotifySaltpackSaltpackOperationStartPayload = + ReturnType +export type Keybase1NotifyServiceHTTPSrvInfoUpdatePayload = + ReturnType +export type Keybase1NotifyServiceHandleKeybaseLinkPayload = + ReturnType +export type Keybase1NotifyServiceShutdownPayload = ReturnType +export type Keybase1NotifySessionClientOutOfDatePayload = + ReturnType +export type Keybase1NotifySessionLoggedInPayload = ReturnType +export type Keybase1NotifySessionLoggedOutPayload = ReturnType +export type Keybase1NotifySimpleFSSimpleFSArchiveStatusChangedPayload = + ReturnType +export type Keybase1NotifyTeamAvatarUpdatedPayload = ReturnType +export type Keybase1NotifyTeamNewlyAddedToTeamPayload = ReturnType +export type Keybase1NotifyTeamTeamAbandonedPayload = ReturnType +export type Keybase1NotifyTeamTeamChangedByIDPayload = ReturnType +export type Keybase1NotifyTeamTeamChangedByNamePayload = ReturnType +export type Keybase1NotifyTeamTeamDeletedPayload = ReturnType +export type Keybase1NotifyTeamTeamExitPayload = ReturnType +export type Keybase1NotifyTeamTeamMetadataUpdatePayload = + ReturnType +export type Keybase1NotifyTeamTeamRoleMapChangedPayload = + ReturnType +export type Keybase1NotifyTeamTeamTreeMembershipsDonePayload = + ReturnType +export type Keybase1NotifyTeamTeamTreeMembershipsPartialPayload = + ReturnType +export type Keybase1NotifyTeambotNewTeambotKeyPayload = ReturnType +export type Keybase1NotifyTeambotTeambotKeyNeededPayload = + ReturnType +export type Keybase1NotifyTrackingNotifyUserBlockedPayload = + ReturnType +export type Keybase1NotifyTrackingTrackingChangedPayload = + ReturnType +export type Keybase1NotifyTrackingTrackingInfoPayload = ReturnType +export type Keybase1NotifyUsersIdentifyUpdatePayload = ReturnType +export type Keybase1NotifyUsersPasswordChangedPayload = ReturnType +export type Keybase1NotifyUsersUserChangedPayload = ReturnType +export type Keybase1NotifyUsersWebOfTrustChangedPayload = + ReturnType +export type Keybase1PgpUiFinishedPayload = ReturnType +export type Keybase1PgpUiKeyGeneratedPayload = ReturnType +export type Keybase1PgpUiOutputPGPWarningPayload = ReturnType +export type Keybase1PgpUiOutputSignatureNonKeybasePayload = + ReturnType +export type Keybase1PgpUiOutputSignatureSuccessPayload = ReturnType +export type Keybase1PgpUiShouldPushPrivatePayload = ReturnType +export type Keybase1ProveUiCheckingPayload = ReturnType +export type Keybase1ProveUiContinueCheckingPayload = ReturnType +export type Keybase1ProveUiDisplayRecheckWarningPayload = + ReturnType +export type Keybase1ProveUiOkToCheckPayload = ReturnType +export type Keybase1ProveUiOutputInstructionsPayload = ReturnType +export type Keybase1ProveUiOutputPrechecksPayload = ReturnType +export type Keybase1ProveUiPreProofWarningPayload = ReturnType +export type Keybase1ProveUiPromptOverwritePayload = ReturnType +export type Keybase1ProveUiPromptUsernamePayload = ReturnType +export type Keybase1ProvisionUiChooseDevicePayload = ReturnType +export type Keybase1ProvisionUiChooseDeviceTypePayload = ReturnType +export type Keybase1ProvisionUiChooseGPGMethodPayload = ReturnType +export type Keybase1ProvisionUiChooseProvisioningMethodPayload = + ReturnType +export type Keybase1ProvisionUiDisplayAndPromptSecretPayload = + ReturnType +export type Keybase1ProvisionUiDisplaySecretExchangedPayload = + ReturnType +export type Keybase1ProvisionUiPromptNewDeviceNamePayload = + ReturnType +export type Keybase1ProvisionUiProvisioneeSuccessPayload = + ReturnType +export type Keybase1ProvisionUiProvisionerSuccessPayload = + ReturnType +export type Keybase1ProvisionUiSwitchToGPGSignOKPayload = + ReturnType +export type Keybase1ReachabilityReachabilityChangedPayload = + ReturnType +export type Keybase1RekeyUIDelegateRekeyUIPayload = ReturnType +export type Keybase1RekeyUIRefreshPayload = ReturnType +export type Keybase1RekeyUIRekeySendEventPayload = ReturnType +export type Keybase1SaltpackUiSaltpackPromptForDecryptPayload = + ReturnType +export type Keybase1SaltpackUiSaltpackVerifyBadSenderPayload = + ReturnType +export type Keybase1SaltpackUiSaltpackVerifySuccessPayload = + ReturnType +export type Keybase1SecretUiGetPassphrasePayload = ReturnType +export type Keybase1StreamUiClosePayload = ReturnType +export type Keybase1StreamUiReadPayload = ReturnType +export type Keybase1StreamUiResetPayload = ReturnType +export type Keybase1StreamUiWritePayload = ReturnType +export type Keybase1TeamsUiConfirmInviteLinkAcceptPayload = + ReturnType +export type Keybase1TeamsUiConfirmRootTeamDeletePayload = + ReturnType +export type Keybase1TeamsUiConfirmSubteamDeletePayload = ReturnType +export type Keybase1UiPromptYesNoPayload = ReturnType +export type Stellar1NotifyAccountDetailsUpdatePayload = ReturnType +export type Stellar1NotifyAccountsUpdatePayload = ReturnType +export type Stellar1NotifyPaymentNotificationPayload = ReturnType +export type Stellar1NotifyPaymentStatusNotificationPayload = + ReturnType +export type Stellar1NotifyPendingPaymentsUpdatePayload = ReturnType +export type Stellar1NotifyRecentPaymentsUpdatePayload = ReturnType +export type Stellar1NotifyRequestStatusNotificationPayload = + ReturnType +export type Stellar1UiPaymentReviewedPayload = ReturnType // All Actions // prettier-ignore diff --git a/shared/android/app/build.gradle b/shared/android/app/build.gradle index 4a84db52c16c..ef4e44da8cd9 100644 --- a/shared/android/app/build.gradle +++ b/shared/android/app/build.gradle @@ -1,4 +1,5 @@ apply plugin: "com.android.application" +apply plugin: "org.jetbrains.kotlin.android" apply plugin: "com.facebook.react" apply plugin: 'com.github.triplet.play' @@ -17,26 +18,23 @@ Integer getVersionCode() { project.logger.lifecycle('Version code: ' + getVersionCode().toString()) -def nodeModules = "../../node_modules" -def defaultDir = file("$nodeModules/react-native/android") -def androidSourcesDir = defaultDir.parentFile.toString() -def prebuiltDir = "$buildDir/react-native-0*/jni" - /** * This is the configuration block to customize your React Native Android app. * By default you don't need to apply any configuration, just uncomment the lines you need. */ react { + cliFile = new File(["node", "--print", "require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })"].execute(null, rootDir).text.trim()) + /* Folders */ - // The root of your project, i.e. where "package.json" lives. Default is '..' + // The root of your project, i.e. where "package.json" lives. Default is '../..' // root = file("../../") - // The folder where the react-native NPM package is. Default is ../node_modules/react-native - // reactNativeDir = file("../node_modules/react-native") - // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen - // codegenDir = file("../node_modules/@react-native/codegen") - // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js - // cliFile = file("../node_modules/react-native/cli.js") + // The folder where the react-native NPM package is. Default is ../../node_modules/react-native + // reactNativeDir = file("../../node_modules/react-native") + // The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen + // codegenDir = file("../../node_modules/@react-native/codegen") + // The cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js + // cliFile = file("../../node_modules/react-native/cli.js") /* Variants */ // The list of variants to that are debuggable. For those we're going to @@ -71,6 +69,8 @@ react { // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" // hermesFlags = ["-O", "-output-source-map"] + /* Autolinking */ + autolinkLibrariesWithApp() } /** @@ -93,8 +93,8 @@ def jscFlavor = 'org.webkit:android-jsc:+' android { ndkVersion rootProject.ext.ndkVersion - - compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion + compileSdk rootProject.ext.compileSdkVersion namespace "io.keybase.ossifrage" defaultConfig { @@ -119,12 +119,6 @@ android { buildTypes { debug { } - - storyBook.initWith(buildTypes.debug) - storyBook { - applicationIdSuffix ".storybook" - matchingFallbacks = ['debug'] - } release { signingConfig signingConfigs.release minifyEnabled enableProguardInReleaseBuilds @@ -166,32 +160,24 @@ dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") - debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") - debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { - exclude group:'com.squareup.okhttp3', module:'okhttp' - } - - debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") if (hermesEnabled.toBoolean()) { implementation("com.facebook.react:hermes-android") } else { implementation jscFlavor } - implementation 'androidx.work:work-runtime:2.8.1' + implementation 'androidx.work:work-runtime:2.9.1' implementation 'androidx.multidex:multidex:2.0.1' - implementation "com.google.firebase:firebase-messaging:22.0.0" - implementation "com.facebook.fresco:animated-gif:2.6.0" - implementation "com.facebook.fresco:fresco:2.6.0" + implementation "com.google.firebase:firebase-messaging:24.0.1" + implementation "com.facebook.fresco:animated-gif:${reactAndroidLibs.versions.fresco.get()}" implementation 'org.msgpack:msgpack-core:0.9.0' implementation project(':keybaselib') implementation 'com.android.installreferrer:installreferrer:2.2' implementation "me.leolin:ShortcutBadger:1.1.22@aar" - implementation "androidx.lifecycle:lifecycle-common-java8:2.6.1" - implementation "androidx.lifecycle:lifecycle-process:2.6.1" + implementation "androidx.lifecycle:lifecycle-common-java8:2.8.5" + implementation "androidx.lifecycle:lifecycle-process:2.8.5" } -apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) // This requires a google-services.json file locally. Drop it in // android/app/src/debug/google-services.json // android/app/src/releaseUnsigned/google-services.json diff --git a/shared/android/app/src/androidTest/java/io/keybase/ossifrage/MainActivityTest.java b/shared/android/app/src/androidTest/java/io/keybase/ossifrage/MainActivityTest.java deleted file mode 100644 index d88f600d193d..000000000000 --- a/shared/android/app/src/androidTest/java/io/keybase/ossifrage/MainActivityTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.keybase.ossifrage.tests; - -import android.test.ActivityInstrumentationTestCase2; -import android.widget.Toast; - -import io.keybase.ossifrage.MainActivity; - -public class MainActivityTest extends ActivityInstrumentationTestCase2 { - private MainActivity mainActivity; - - public MainActivityTest() { - super(MainActivity.class); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - mainActivity = getActivity(); - } - - public void testPreconditions() { - assertNotNull("mFirstTestActivity is null", mainActivity); - } - - public void testToastWorksLikeWeThink() { - Toast.makeText(mainActivity, "Hello World!", Toast.LENGTH_SHORT).show(); - } -} diff --git a/shared/android/app/src/debug/AndroidManifest.xml b/shared/android/app/src/debug/AndroidManifest.xml index 991f74955782..ce2c8f1a813d 100644 --- a/shared/android/app/src/debug/AndroidManifest.xml +++ b/shared/android/app/src/debug/AndroidManifest.xml @@ -1,15 +1,9 @@ - - - - - - + tools:ignore="GoogleAppIndexingWarning"/> diff --git a/shared/android/app/src/debug/java/io/keybase/ossifrage/ReactNativeFlipper.java b/shared/android/app/src/debug/java/io/keybase/ossifrage/ReactNativeFlipper.java deleted file mode 100644 index 1a2a2a3f0889..000000000000 --- a/shared/android/app/src/debug/java/io/keybase/ossifrage/ReactNativeFlipper.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - *

This source code is licensed under the MIT license found in the LICENSE file in the root - * directory of this source tree. - */ -package io.keybase.ossifrage; - -import android.content.Context; -import com.facebook.flipper.android.AndroidFlipperClient; -import com.facebook.flipper.android.utils.FlipperUtils; -import com.facebook.flipper.core.FlipperClient; -import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; -import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; -import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; -import com.facebook.flipper.plugins.inspector.DescriptorMapping; -import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; -import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; -import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; -import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; -import com.facebook.react.ReactInstanceEventListener; -import com.facebook.react.ReactInstanceManager; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.modules.network.NetworkingModule; -import tech.bam.rnperformance.flipper.RNPerfMonitorPlugin; -import okhttp3.OkHttpClient; - -/** - * Class responsible of loading Flipper inside your React Native application. This is the debug - * flavor of it. Here you can add your own plugins and customize the Flipper setup. - */ -public class ReactNativeFlipper { - public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { - if (FlipperUtils.shouldEnableFlipper(context)) { - final FlipperClient client = AndroidFlipperClient.getInstance(context); - - client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); - client.addPlugin(new DatabasesFlipperPlugin(context)); - client.addPlugin(new SharedPreferencesFlipperPlugin(context)); - client.addPlugin(CrashReporterPlugin.getInstance()); - client.addPlugin(new RNPerfMonitorPlugin(reactInstanceManager)); - - NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); - NetworkingModule.setCustomClientBuilder( - new NetworkingModule.CustomClientBuilder() { - @Override - public void apply(OkHttpClient.Builder builder) { - builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); - } - }); - client.addPlugin(networkFlipperPlugin); - client.start(); - - // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized - // Hence we run if after all native modules have been initialized - ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); - if (reactContext == null) { - reactInstanceManager.addReactInstanceEventListener( - new ReactInstanceEventListener() { - @Override - public void onReactContextInitialized(ReactContext reactContext) { - reactInstanceManager.removeReactInstanceEventListener(this); - reactContext.runOnNativeModulesQueueThread( - new Runnable() { - @Override - public void run() { - client.addPlugin(new FrescoFlipperPlugin()); - } - }); - } - }); - } else { - client.addPlugin(new FrescoFlipperPlugin()); - } - } - } -} diff --git a/shared/android/app/src/main/AndroidManifest.xml b/shared/android/app/src/main/AndroidManifest.xml index 0a75308889be..a084faceed82 100644 --- a/shared/android/app/src/main/AndroidManifest.xml +++ b/shared/android/app/src/main/AndroidManifest.xml @@ -19,8 +19,10 @@ android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme" + android:supportsRtl="true" android:networkSecurityConfig="@xml/network_security_config" - android:largeHeap="true"> + android:largeHeap="true" + > - diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/ChatBroadcastReceiver.java b/shared/android/app/src/main/java/io/keybase/ossifrage/ChatBroadcastReceiver.java deleted file mode 100644 index df71b06d0d17..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/ChatBroadcastReceiver.java +++ /dev/null @@ -1,91 +0,0 @@ -package io.keybase.ossifrage; - -import android.app.PendingIntent; -import android.app.RemoteInput; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.util.Log; - -import androidx.annotation.RequiresApi; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationManagerCompat; - -import io.keybase.ossifrage.modules.NativeLogger; -import keybase.Keybase; - -public class ChatBroadcastReceiver extends BroadcastReceiver { - public static String KEY_TEXT_REPLY = "key_text_reply"; - - @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) - private String getMessageText(Intent intent) { - Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); - if (remoteInput != null) { - return remoteInput.getCharSequence(KEY_TEXT_REPLY).toString(); - } - return null; - } - - @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) - @Override - public void onReceive(Context context, Intent intent) { - MainActivity.setupKBRuntime(context, false); - ConvData convData = new ConvData(intent); - PendingIntent openConv = intent.getParcelableExtra("openConvPendingIntent"); - NotificationCompat.Builder repliedNotification = new NotificationCompat.Builder(context, KeybasePushNotificationListenerService.CHAT_CHANNEL_ID) - .setContentIntent(openConv) - .setTimeoutAfter(1000) - .setSmallIcon(R.drawable.ic_notif); - NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); - - String messageBody = getMessageText(intent); - if (messageBody != null) { - - try { - WithBackgroundActive withBackgroundActive = () -> Keybase.handlePostTextReply(convData.convID, convData.tlfName, convData.lastMsgId, messageBody); - withBackgroundActive.whileActive(context); - repliedNotification.setContentText("Replied"); - } catch (Exception e) { - repliedNotification.setContentText("Couldn't send reply"); - NativeLogger.error("Failed to send quick reply", e); - } - - } else { - repliedNotification.setContentText("Couldn't send reply - Failed to read input."); - NativeLogger.error("Message Body in quick reply was null"); - } - - notificationManager.notify(convData.convID, 0, repliedNotification.build()); - } -} - -class ConvData { - String convID; - String tlfName; - long lastMsgId; - - ConvData(String convId, String tlfName, long lastMsgId) { - this.convID = convId; - this.tlfName = tlfName; - this.lastMsgId = lastMsgId; - } - - ConvData (Intent intent) { - Bundle data = intent.getBundleExtra("ConvData"); - this.convID = data.getString("convID"); - this.tlfName = data.getString("tlfName"); - this.lastMsgId = data.getLong("lastMsgId"); - } - - public Intent intoIntent(Context context) { - Bundle data = new Bundle(); - data.putString("convID", this.convID); - data.putString("tlfName", this.tlfName); - data.putLong("lastMsgId", this.lastMsgId); - Intent intent = new Intent(context, ChatBroadcastReceiver.class); - intent.putExtra("ConvData", data); - return intent; - } -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/ChatBroadcastReceiver.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/ChatBroadcastReceiver.kt new file mode 100644 index 000000000000..e7ce43df86cc --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/ChatBroadcastReceiver.kt @@ -0,0 +1,89 @@ +package io.keybase.ossifrage + +import android.app.PendingIntent +import android.app.RemoteInput +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.os.Build +import android.os.Bundle +import androidx.annotation.RequiresApi +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import io.keybase.ossifrage.MainActivity.Companion.setupKBRuntime +import io.keybase.ossifrage.modules.NativeLogger +import keybase.Keybase + +class ChatBroadcastReceiver : BroadcastReceiver() { + @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) + private fun getMessageText(intent: Intent): String? { + val remoteInput = RemoteInput.getResultsFromIntent(intent) + return remoteInput?.getCharSequence(KEY_TEXT_REPLY)?.toString() + } + + @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) + override fun onReceive(context: Context, intent: Intent) { + setupKBRuntime(context, false) + val convData = ConvData(intent) + val openConv = intent.getParcelableExtra("openConvPendingIntent") + val repliedNotification = NotificationCompat.Builder(context, KeybasePushNotificationListenerService.CHAT_CHANNEL_ID) + .setContentIntent(openConv) + .setTimeoutAfter(1000) + .setSmallIcon(R.drawable.ic_notif) + val notificationManager = NotificationManagerCompat.from(context) + val messageBody = getMessageText(intent) + if (messageBody != null) { + try { + val withBackgroundActive: WithBackgroundActive = object : WithBackgroundActive { + override fun task() { + Keybase.handlePostTextReply(convData.convID, convData.tlfName, convData.lastMsgId, messageBody) + } + } + withBackgroundActive.whileActive(context) + repliedNotification.setContentText("Replied") + } catch (e: Exception) { + repliedNotification.setContentText("Couldn't send reply") + NativeLogger.error("Failed to send quick reply", e) + } + } else { + repliedNotification.setContentText("Couldn't send reply - Failed to read input.") + NativeLogger.error("Message Body in quick reply was null") + } + notificationManager.notify(convData.convID, 0, repliedNotification.build()) + } + + companion object { + @JvmField + var KEY_TEXT_REPLY = "key_text_reply" + } +} + +internal class ConvData { + @JvmField + var convID: String? + var tlfName: String? + var lastMsgId: Long + + constructor(convId: String?, tlfName: String?, lastMsgId: Long) { + convID = convId + this.tlfName = tlfName + this.lastMsgId = lastMsgId + } + + constructor(intent: Intent) { + val data = intent.getBundleExtra("ConvData") + convID = data!!.getString("convID") + tlfName = data.getString("tlfName") + lastMsgId = data.getLong("lastMsgId") + } + + fun intoIntent(context: Context?): Intent { + val data = Bundle() + data.putString("convID", convID) + data.putString("tlfName", tlfName) + data.putLong("lastMsgId", lastMsgId) + val intent = Intent(context, ChatBroadcastReceiver::class.java) + intent.putExtra("ConvData", data) + return intent + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/CustomBitmapMemoryCacheParamsSupplier.java b/shared/android/app/src/main/java/io/keybase/ossifrage/CustomBitmapMemoryCacheParamsSupplier.java deleted file mode 100644 index ef6d26fd36f5..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/CustomBitmapMemoryCacheParamsSupplier.java +++ /dev/null @@ -1,56 +0,0 @@ -package io.keybase.ossifrage; - -import android.app.ActivityManager; -import android.content.Context; -import android.os.Build; - -import com.facebook.common.internal.Supplier; -import com.facebook.common.util.ByteConstants; -import com.facebook.imagepipeline.cache.DefaultBitmapMemoryCacheParamsSupplier; -import com.facebook.imagepipeline.cache.MemoryCacheParams; - -/** - * Custom Bitmap cache config for Fresco based off of {@link DefaultBitmapMemoryCacheParamsSupplier} - */ -public class CustomBitmapMemoryCacheParamsSupplier implements Supplier { - - private static final int CACHE_DIVISION = 8; // cache size will be 1/8 of the max allocated app memory - private static final int MAX_CACHE_ENTRIES = 256; - private static final int MAX_EVICTION_QUEUE_SIZE = Integer.MAX_VALUE; - private static final int MAX_EVICTION_QUEUE_ENTRIES = Integer.MAX_VALUE; - private static final int MAX_CACHE_ENTRY_SIZE = Integer.MAX_VALUE; - - private final ActivityManager mActivityManager; - - public CustomBitmapMemoryCacheParamsSupplier(Context context) { - mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - } - - @Override - public MemoryCacheParams get() { - return new MemoryCacheParams( - getMaxCacheSize(), - MAX_CACHE_ENTRIES, - MAX_EVICTION_QUEUE_SIZE, - MAX_EVICTION_QUEUE_ENTRIES, - MAX_CACHE_ENTRY_SIZE); - } - - private int getMaxCacheSize() { - final int maxMemory = - Math.min(mActivityManager.getMemoryClass() * ByteConstants.MB, Integer.MAX_VALUE); - if (maxMemory < 32 * ByteConstants.MB) { - return 4 * ByteConstants.MB; - } else if (maxMemory < 64 * ByteConstants.MB) { - return 6 * ByteConstants.MB; - } else { - // We don't want to use more ashmem on Gingerbread for now, since it doesn't respond well to - // native memory pressure (doesn't throw exceptions, crashes app, crashes phone) - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - return 8 * ByteConstants.MB; - } else { - return maxMemory / CACHE_DIVISION; - } - } - } -} \ No newline at end of file diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/CustomBitmapMemoryCacheParamsSupplier.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/CustomBitmapMemoryCacheParamsSupplier.kt new file mode 100644 index 000000000000..dd9c735ed968 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/CustomBitmapMemoryCacheParamsSupplier.kt @@ -0,0 +1,54 @@ +package io.keybase.ossifrage + +import android.app.ActivityManager +import android.content.Context +import android.os.Build +import com.facebook.common.internal.Supplier +import com.facebook.common.util.ByteConstants +import com.facebook.imagepipeline.cache.MemoryCacheParams + +/** + * Custom Bitmap cache config for Fresco based off of [DefaultBitmapMemoryCacheParamsSupplier] + */ +class CustomBitmapMemoryCacheParamsSupplier(context: Context) : Supplier { + private val mActivityManager: ActivityManager + + init { + mActivityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + } + + override fun get(): MemoryCacheParams { + return MemoryCacheParams( + maxCacheSize, + MAX_CACHE_ENTRIES, + MAX_EVICTION_QUEUE_SIZE, + MAX_EVICTION_QUEUE_ENTRIES, + MAX_CACHE_ENTRY_SIZE) + } + + private val maxCacheSize: Int + get() { + val maxMemory = Math.min(mActivityManager.memoryClass * ByteConstants.MB, Int.MAX_VALUE) + return if (maxMemory < 32 * ByteConstants.MB) { + 4 * ByteConstants.MB + } else if (maxMemory < 64 * ByteConstants.MB) { + 6 * ByteConstants.MB + } else { + // We don't want to use more ashmem on Gingerbread for now, since it doesn't respond well to + // native memory pressure (doesn't throw exceptions, crashes app, crashes phone) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + 8 * ByteConstants.MB + } else { + maxMemory / CACHE_DIVISION + } + } + } + + companion object { + private const val CACHE_DIVISION = 8 // cache size will be 1/8 of the max allocated app memory + private const val MAX_CACHE_ENTRIES = 256 + private const val MAX_EVICTION_QUEUE_SIZE = Int.MAX_VALUE + private const val MAX_EVICTION_QUEUE_ENTRIES = Int.MAX_VALUE + private const val MAX_CACHE_ENTRY_SIZE = Int.MAX_VALUE + } +} \ No newline at end of file diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/KBInstallReferrerListener.java b/shared/android/app/src/main/java/io/keybase/ossifrage/KBInstallReferrerListener.java deleted file mode 100644 index e741d58c73a0..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/KBInstallReferrerListener.java +++ /dev/null @@ -1,110 +0,0 @@ -package io.keybase.ossifrage; - -import android.content.Context; -import android.os.RemoteException; -import android.os.SystemClock; -import android.util.Log; - -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; - -import com.android.installreferrer.api.InstallReferrerClient; -import com.android.installreferrer.api.InstallReferrerStateListener; -import com.android.installreferrer.api.ReferrerDetails; - -import io.keybase.ossifrage.modules.NativeLogger; -import keybase.StringReceiver; - -public class KBInstallReferrerListener implements keybase.NativeInstallReferrerListener, InstallReferrerStateListener { - - private InstallReferrerClient mReferrerClient; - private keybase.StringReceiver callback; - private Context context; - private int retries; - private Executor executor; - - private static final int max_retries = 5; - - KBInstallReferrerListener(Context _context) { - Log.d("KBIR", "KBInstallReferrerListener created"); - context = _context; - executor = Executors.newSingleThreadExecutor(); - retries = 0; - } - - // should only be called once per object - @Override - public void startInstallReferrerListener(StringReceiver cb) { - Log.e("KBIR", "KBInstallReferrerListener started"); - - mReferrerClient = InstallReferrerClient.newBuilder(this.context).build(); - mReferrerClient.startConnection(this); - callback = cb; - } - - @Override - public void onInstallReferrerSetupFinished(int responseCode) { - Log.e("KBIR", "KBInstallReferrerListener#onInstallReferrerSetupFinished: got code " + responseCode); - executor.execute(new Runnable() { - @Override - public void run() { - switch (responseCode) { - case InstallReferrerClient.InstallReferrerResponse.OK: - // Connection established - handleReferrerResponseOK(); - return; - case InstallReferrerClient.InstallReferrerResponse.SERVICE_DISCONNECTED: - reconnect(); - return; - case InstallReferrerClient.InstallReferrerResponse.FEATURE_NOT_SUPPORTED: - case InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE: - case InstallReferrerClient.InstallReferrerResponse.DEVELOPER_ERROR: - default: - // other issues, can't do much here.... - callback.callbackWithString(""); - } - } - }); - } - - private void handleReferrerResponseOK() { - try { - ReferrerDetails response = mReferrerClient.getInstallReferrer(); - String referrerData = response.getInstallReferrer(); - callback.callbackWithString(referrerData); - } catch (RemoteException e) { - Log.e("KBIR", "KBInstallReferrerListener#handleReferrerResponseOK got exception: " + e.toString()); - e.printStackTrace(); - callback.callbackWithString(""); - } - mReferrerClient.endConnection(); - } - - // tries to reconnect up to max_retries times in case of errors - private void reconnect() { - if (retries >= max_retries) { - Log.e("KBIR", "KBInstallReferrerListener max reconnection attempts exceeded"); - callback.callbackWithString(""); - mReferrerClient.endConnection(); - return; - } - - retries++; - // sleep for a bit, hopefully when we wake up the play store - // connection will be available. - SystemClock.sleep(retries * 1000); - Log.e("KBIR", "KBInstallReferrerListener reconnecting..."); - mReferrerClient.startConnection(this); - } - - @Override - public void onInstallReferrerServiceDisconnected() { - Log.e("KBIR", "KBInstallReferrerListener#onInstallReferrerServiceDisconnected: attempting restart..."); - executor.execute(new Runnable() { - @Override - public void run() { - reconnect(); - } - }); - } -} \ No newline at end of file diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/KBInstallReferrerListener.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/KBInstallReferrerListener.kt new file mode 100644 index 000000000000..613e5e259974 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/KBInstallReferrerListener.kt @@ -0,0 +1,97 @@ +package io.keybase.ossifrage + +import android.content.Context +import android.os.RemoteException +import android.os.SystemClock +import android.util.Log +import com.android.installreferrer.api.InstallReferrerClient +import com.android.installreferrer.api.InstallReferrerStateListener +import keybase.NativeInstallReferrerListener +import keybase.StringReceiver +import java.util.concurrent.Executor +import java.util.concurrent.Executors + +class KBInstallReferrerListener internal constructor(_context: Context) : NativeInstallReferrerListener, InstallReferrerStateListener { + private var mReferrerClient: InstallReferrerClient? = null + private var callback: StringReceiver? = null + private val context: Context + private var retries: Int + private val executor: Executor + + init { + Log.d("KBIR", "KBInstallReferrerListener created") + context = _context + executor = Executors.newSingleThreadExecutor() + retries = 0 + } + + // should only be called once per object + override fun startInstallReferrerListener(cb: StringReceiver) { + Log.e("KBIR", "KBInstallReferrerListener started") + val rc = InstallReferrerClient.newBuilder(context).build() + mReferrerClient = rc + rc.startConnection(this) + callback = cb + } + + override fun onInstallReferrerSetupFinished(responseCode: Int) { + Log.e("KBIR", "KBInstallReferrerListener#onInstallReferrerSetupFinished: got code $responseCode") + executor.execute(Runnable { + when (responseCode) { + InstallReferrerClient.InstallReferrerResponse.OK -> { + // Connection established + handleReferrerResponseOK() + return@Runnable + } + + InstallReferrerClient.InstallReferrerResponse.SERVICE_DISCONNECTED -> { + reconnect() + return@Runnable + } + + InstallReferrerClient.InstallReferrerResponse.FEATURE_NOT_SUPPORTED, InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE, InstallReferrerClient.InstallReferrerResponse.DEVELOPER_ERROR -> // other issues, can't do much here.... + callback!!.callbackWithString("") + + else -> callback!!.callbackWithString("") + } + }) + } + + private fun handleReferrerResponseOK() { + try { + val response = mReferrerClient!!.installReferrer + val referrerData = response.installReferrer + callback!!.callbackWithString(referrerData) + } catch (e: RemoteException) { + Log.e("KBIR", "KBInstallReferrerListener#handleReferrerResponseOK got exception: $e") + e.printStackTrace() + callback!!.callbackWithString("") + } + mReferrerClient!!.endConnection() + } + + // tries to reconnect up to max_retries times in case of errors + private fun reconnect() { + if (retries >= max_retries) { + Log.e("KBIR", "KBInstallReferrerListener max reconnection attempts exceeded") + callback!!.callbackWithString("") + mReferrerClient!!.endConnection() + return + } + retries++ + // sleep for a bit, hopefully when we wake up the play store + // connection will be available. + SystemClock.sleep((retries * 1000).toLong()) + Log.e("KBIR", "KBInstallReferrerListener reconnecting...") + mReferrerClient!!.startConnection(this) + } + + override fun onInstallReferrerServiceDisconnected() { + Log.e("KBIR", "KBInstallReferrerListener#onInstallReferrerServiceDisconnected: attempting restart...") + executor.execute { reconnect() } + } + + companion object { + private const val max_retries = 5 + } +} \ No newline at end of file diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/KBPushNotifier.java b/shared/android/app/src/main/java/io/keybase/ossifrage/KBPushNotifier.java deleted file mode 100644 index 1dfa6d7caed7..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/KBPushNotifier.java +++ /dev/null @@ -1,275 +0,0 @@ -package io.keybase.ossifrage; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; -import android.graphics.Rect; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; - -import androidx.annotation.RequiresApi; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationCompat.MessagingStyle; -import androidx.core.app.NotificationManagerCompat; -import androidx.core.app.Person; -import androidx.core.app.RemoteInput; -import androidx.core.graphics.drawable.IconCompat; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; - -import io.keybase.ossifrage.modules.NativeLogger; -import keybase.ChatNotification; -import keybase.Message; -import keybase.PushNotifier; - -public class KBPushNotifier implements PushNotifier { - private final Context context; - private Bundle bundle; - private SmallMsgRingBuffer convMsgCache; - - private MessagingStyle buildStyle(Person person) { - MessagingStyle style = new MessagingStyle(person); - if (convMsgCache != null) { - for (MessagingStyle.Message msg : convMsgCache.summary()) { - style.addMessage(msg); - } - } - - return style; - } - - KBPushNotifier(Context ctx, Bundle bundle) { - this.context = ctx; - this.bundle = bundle; - } - - void setMsgCache(SmallMsgRingBuffer convMsgCache) { - this.convMsgCache = convMsgCache; - } - - // From: https://stackoverflow.com/questions/11932805/cropping-circular-area-from-bitmap-in-android - private static Bitmap getCroppedBitmap(Bitmap bitmap) { - Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), - bitmap.getHeight(), Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(output); - - final int color = 0xff424242; - final Paint paint = new Paint(); - final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); - - paint.setAntiAlias(true); - canvas.drawARGB(0, 0, 0, 0); - paint.setColor(color); - canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, - bitmap.getWidth() / 2, paint); - paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); - canvas.drawBitmap(bitmap, rect, rect, paint); - return output; - } - - // Controls the Intent that gets built - private PendingIntent buildPendingIntent(Bundle bundle) { - Intent open_activity_intent = new Intent(context, MainActivity.class); - open_activity_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - open_activity_intent.setPackage(context.getPackageName()); - open_activity_intent.putExtra("notification", bundle); - - // unique so our intents are deduped, else it'll reuse old ones - PendingIntent pending_intent = PendingIntent.getActivity(this.context, (int)(System.currentTimeMillis()/1000) , open_activity_intent, PendingIntent.FLAG_MUTABLE); - - return pending_intent; - } - - private IconCompat getKeybaseAvatar(String avatarUri) { - if (avatarUri.isEmpty()) { - return null; - } - - HttpURLConnection urlConnection = null; - try { - URL url = new URL(avatarUri); - urlConnection = (HttpURLConnection) url.openConnection(); - InputStream in = new BufferedInputStream(urlConnection.getInputStream()); - Bitmap bitmap = BitmapFactory.decodeStream(in); - Bitmap croppedBitmap = getCroppedBitmap(bitmap); - return IconCompat.createWithBitmap(croppedBitmap); - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (urlConnection != null) { - urlConnection.disconnect(); - } - } - - return null; - } - - @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) - private NotificationCompat.Action newReplyAction(Context context, ConvData convData, PendingIntent openConv) { - String replyLabel = "Reply"; - RemoteInput remoteInput = new RemoteInput.Builder(ChatBroadcastReceiver.KEY_TEXT_REPLY) - .setLabel(replyLabel) - .build(); - - Intent intent = convData.intoIntent(context); - intent.putExtra("openConvPendingIntent", openConv); - - // Our pending intent which will be sent to the broadcast receiver - PendingIntent replyPendingIntent = - PendingIntent.getBroadcast(context, - convData.convID.hashCode(), - intent, - PendingIntent.FLAG_MUTABLE); - - NotificationCompat.Action action = - new NotificationCompat.Action.Builder(R.drawable.ic_notif, "Reply", replyPendingIntent) - .addRemoteInput(remoteInput) - .build(); - return action; - } - - @Override - public void displayChatNotification(ChatNotification chatNotification) { - // We need to specify these parameters so that the data returned - // from the launching intent is processed correctly. - // https://github.com/keybase/client/blob/95959e12d76612f455ab4a90835debff489eacf4/shared/actions/platform-specific/push.native.js#L363-L381 - Bundle bundle = (Bundle) this.bundle.clone(); - bundle.putBoolean("userInteraction", true); - bundle.putString("type", "chat.newmessage"); - bundle.putString("convID", chatNotification.getConvID()); - PendingIntent pending_intent = buildPendingIntent(bundle); - - ConvData convData = new ConvData(chatNotification.getConvID(), chatNotification.getTlfName(), chatNotification.getMessage().getID()); - - NotificationCompat.Builder builder = - new NotificationCompat.Builder(this.context, KeybasePushNotificationListenerService.CHAT_CHANNEL_ID) - .setSmallIcon(R.drawable.ic_notif) - .setContentIntent(pending_intent) - .setAutoCancel(true); - - int notificationDefaults = NotificationCompat.DEFAULT_LIGHTS | NotificationCompat.DEFAULT_VIBRATE; - - // Set notification sound - if (chatNotification.getSoundName().equals("default")) { - notificationDefaults |= NotificationCompat.DEFAULT_SOUND; - } else { - String soundResource = filenameResourceName(chatNotification.getSoundName()); - String soundUriStr = "android.resource://" + this.context.getPackageName() + "/raw/" + soundResource; - Uri soundUri = Uri.parse(soundUriStr); - builder.setSound(soundUri); - } - - builder.setDefaults(notificationDefaults); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { - builder.addAction(newReplyAction(this.context, convData, pending_intent)); - } - - Message msg = chatNotification.getMessage(); - keybase.Person from = msg.getFrom(); - Person.Builder personBuilder = new Person.Builder() - .setName(from.getKeybaseUsername()) - .setBot(from.getIsBot()); - - String avatarUri = chatNotification.getMessage().getFrom().getKeybaseAvatar(); - IconCompat icon = getKeybaseAvatar(avatarUri); - if (icon != null) { - personBuilder.setIcon(icon); - } - - Person fromPerson = personBuilder.build(); - - if (this.convMsgCache != null) { - String msgText = chatNotification.getIsPlaintext() ? chatNotification.getMessage().getPlaintext() : ""; - if (msgText.isEmpty()) { - msgText = chatNotification.getMessage().getServerMessage(); - } - convMsgCache.add(new MessagingStyle.Message(msgText, msg.getAt(), fromPerson)); - } - - MessagingStyle style = buildStyle(fromPerson); - style.setConversationTitle(chatNotification.getConversationName()); - style.setGroupConversation(chatNotification.getIsGroupConversation()); - - builder.setStyle(style); - - NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this.context); - notificationManager.notify(chatNotification.getConvID(), 0, builder.build()); - } - - // Return the resource name of the specified file (i.e. name and no extension), - // suitable for use in a resource URI. - String filenameResourceName(String filename) { - if (filename.indexOf(".") >= 0) { - return filename.substring(0, filename.lastIndexOf(".")); - } else { - // Not all filenames have an extension to be stripped. - return filename; - } - } - - void followNotification(String username, String notificationMsg) { - Bundle bundle = (Bundle) this.bundle.clone(); - bundle.putBoolean("userInteraction", true); - bundle.putString("type", "follow"); - bundle.putString("username", username); - - NotificationCompat.Builder builder = new NotificationCompat.Builder(this.context, KeybasePushNotificationListenerService.FOLLOW_CHANNEL_ID) - .setSmallIcon(R.drawable.ic_notif) - .setContentTitle("Keybase - New Follower") - .setContentText(notificationMsg) - // Set the intent that will fire when the user taps the notification - .setContentIntent(buildPendingIntent(bundle)) - .setAutoCancel(true); - - NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this.context); - notificationManager.notify("follow:" + username, 0, builder.build()); - } - - void deviceNotification() { - Bundle bundle = (Bundle) this.bundle.clone(); - genericNotification(bundle.getString("device_id") + bundle.getString("type"), bundle.getString("message"), "", bundle, KeybasePushNotificationListenerService.DEVICE_CHANNEL_ID); - } - - void generalNotification() { - Bundle bundle = (Bundle) this.bundle.clone(); - genericNotification(bundle.getString("device_id") + bundle.getString("type"), bundle.getString("title"), bundle.getString("message"), bundle, KeybasePushNotificationListenerService.GENERAL_CHANNEL_ID); - } - - public void genericNotification(String uniqueTag, String notificationTitle, String notificationMsg, Bundle bundle, String channelID) { - bundle.putBoolean("userInteraction", true); - NotificationCompat.Builder builder = new NotificationCompat.Builder(this.context, channelID) - .setSmallIcon(R.drawable.ic_notif) - // Set the intent that will fire when the user taps the notification - .setContentIntent(buildPendingIntent(bundle)) - .setAutoCancel(true); - - if (!notificationMsg.isEmpty()) { - builder.setContentText(notificationMsg); - } - if (!notificationTitle.isEmpty()) { - builder.setContentTitle(notificationTitle); - } - - NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this.context); - notificationManager.notify(uniqueTag, 0, builder.build()); - - } - - public void localNotification(String ident, String msg, long badgeCount, String soundName, String convID, - String typ) { - genericNotification(ident, "", msg, this.bundle, KeybasePushNotificationListenerService.GENERAL_CHANNEL_ID); - } - -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/KBPushNotifier.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/KBPushNotifier.kt new file mode 100644 index 000000000000..0b9707487429 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/KBPushNotifier.kt @@ -0,0 +1,229 @@ +package io.keybase.ossifrage + +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.PorterDuff +import android.graphics.PorterDuffXfermode +import android.graphics.Rect +import android.net.Uri +import android.os.Build +import android.os.Bundle +import androidx.annotation.RequiresApi +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import androidx.core.app.Person +import androidx.core.app.RemoteInput +import androidx.core.graphics.drawable.IconCompat +import io.keybase.ossifrage.MainActivity +import keybase.ChatNotification +import keybase.PushNotifier +import java.io.BufferedInputStream +import java.io.IOException +import java.io.InputStream +import java.net.HttpURLConnection +import java.net.URL + +class KBPushNotifier internal constructor(private val context: Context, private val bundle: Bundle) : PushNotifier { + private var convMsgCache: SmallMsgRingBuffer? = null + private fun buildStyle(person: Person): NotificationCompat.MessagingStyle { + val style = NotificationCompat.MessagingStyle(person) + if (convMsgCache != null) { + for (msg in convMsgCache!!.summary()) { + style.addMessage(msg) + } + } + return style + } + + fun setMsgCache(convMsgCache: SmallMsgRingBuffer?) { + this.convMsgCache = convMsgCache + } + + // Controls the Intent that gets built + private fun buildPendingIntent(bundle: Bundle): PendingIntent { + val open_activity_intent = Intent(context, MainActivity::class.java) + open_activity_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP) + open_activity_intent.setPackage(context.packageName) + open_activity_intent.putExtra("notification", bundle) + + // unique so our intents are deduped, else it'll reuse old ones + return PendingIntent.getActivity(context, (System.currentTimeMillis() / 1000).toInt(), open_activity_intent, PendingIntent.FLAG_MUTABLE) + } + + private fun getKeybaseAvatar(avatarUri: String): IconCompat? { + if (avatarUri.isEmpty()) { + return null + } + var urlConnection: HttpURLConnection? = null + try { + val url = URL(avatarUri) + urlConnection = url.openConnection() as HttpURLConnection + val `in`: InputStream = BufferedInputStream(urlConnection.inputStream) + val bitmap = BitmapFactory.decodeStream(`in`) + val croppedBitmap = getCroppedBitmap(bitmap) + return IconCompat.createWithBitmap(croppedBitmap) + } catch (e: IOException) { + e.printStackTrace() + } finally { + urlConnection?.disconnect() + } + return null + } + + @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) + private fun newReplyAction(context: Context, convData: ConvData, openConv: PendingIntent): NotificationCompat.Action { + val replyLabel = "Reply" + val remoteInput = RemoteInput.Builder(ChatBroadcastReceiver.KEY_TEXT_REPLY) + .setLabel(replyLabel) + .build() + val intent = convData.intoIntent(context) + intent.putExtra("openConvPendingIntent", openConv) + + // Our pending intent which will be sent to the broadcast receiver + val replyPendingIntent = PendingIntent.getBroadcast(context, + convData.convID.hashCode(), + intent, + PendingIntent.FLAG_MUTABLE) + return NotificationCompat.Action.Builder(R.drawable.ic_notif, "Reply", replyPendingIntent) + .addRemoteInput(remoteInput) + .build() + } + + override fun displayChatNotification(chatNotification: ChatNotification) { + // We need to specify these parameters so that the data returned + // from the launching intent is processed correctly. + // https://github.com/keybase/client/blob/95959e12d76612f455ab4a90835debff489eacf4/shared/actions/platform-specific/push.native.js#L363-L381 + val bundle = bundle.clone() as Bundle + bundle.putBoolean("userInteraction", true) + bundle.putString("type", "chat.newmessage") + bundle.putString("convID", chatNotification.convID) + val pending_intent = buildPendingIntent(bundle) + val convData = ConvData(chatNotification.convID, chatNotification.tlfName, chatNotification.message.id) + val builder = NotificationCompat.Builder(context, KeybasePushNotificationListenerService.CHAT_CHANNEL_ID) + .setSmallIcon(R.drawable.ic_notif) + .setContentIntent(pending_intent) + .setAutoCancel(true) + var notificationDefaults = NotificationCompat.DEFAULT_LIGHTS or NotificationCompat.DEFAULT_VIBRATE + + // Set notification sound + if (chatNotification.soundName == "default") { + notificationDefaults = notificationDefaults or NotificationCompat.DEFAULT_SOUND + } else { + val soundResource = filenameResourceName(chatNotification.soundName) + val soundUriStr = "android.resource://" + context.packageName + "/raw/" + soundResource + val soundUri = Uri.parse(soundUriStr) + builder.setSound(soundUri) + } + builder.setDefaults(notificationDefaults) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { + builder.addAction(newReplyAction(context, convData, pending_intent)) + } + val msg = chatNotification.message + val from = msg.from + val personBuilder = Person.Builder() + .setName(from.keybaseUsername) + .setBot(from.isBot) + val avatarUri = chatNotification.message.from.keybaseAvatar + val icon = getKeybaseAvatar(avatarUri) + if (icon != null) { + personBuilder.setIcon(icon) + } + val fromPerson = personBuilder.build() + if (convMsgCache != null) { + var msgText = if (chatNotification.isPlaintext) chatNotification.message.plaintext else "" + if (msgText.isEmpty()) { + msgText = chatNotification.message.serverMessage + } + convMsgCache!!.add(NotificationCompat.MessagingStyle.Message(msgText, msg.at, fromPerson)) + } + val style = buildStyle(fromPerson) + style.setConversationTitle(chatNotification.conversationName) + style.setGroupConversation(chatNotification.isGroupConversation) + builder.setStyle(style) + val notificationManager = NotificationManagerCompat.from(context) + notificationManager.notify(chatNotification.convID, 0, builder.build()) + } + + // Return the resource name of the specified file (i.e. name and no extension), + // suitable for use in a resource URI. + fun filenameResourceName(filename: String): String { + return if (filename.indexOf(".") >= 0) { + filename.substring(0, filename.lastIndexOf(".")) + } else { + // Not all filenames have an extension to be stripped. + filename + } + } + + fun followNotification(username: String, notificationMsg: String?) { + val bundle = bundle.clone() as Bundle + bundle.putBoolean("userInteraction", true) + bundle.putString("type", "follow") + bundle.putString("username", username) + val builder = NotificationCompat.Builder(context, KeybasePushNotificationListenerService.FOLLOW_CHANNEL_ID) + .setSmallIcon(R.drawable.ic_notif) + .setContentTitle("Keybase - New Follower") + .setContentText(notificationMsg) // Set the intent that will fire when the user taps the notification + .setContentIntent(buildPendingIntent(bundle)) + .setAutoCancel(true) + val notificationManager = NotificationManagerCompat.from(context) + notificationManager.notify("follow:$username", 0, builder.build()) + } + + fun deviceNotification() { + val bundle = bundle.clone() as Bundle + genericNotification(bundle.getString("device_id") + bundle.getString("type"), bundle.getString("message"), "", bundle, KeybasePushNotificationListenerService.DEVICE_CHANNEL_ID) + } + + fun generalNotification() { + val bundle = bundle.clone() as Bundle + genericNotification(bundle.getString("device_id") + bundle.getString("type"), bundle.getString("title"), bundle.getString("message"), bundle, KeybasePushNotificationListenerService.GENERAL_CHANNEL_ID) + } + + fun genericNotification(uniqueTag: String?, notificationTitle: String?, notificationMsg: String?, bundle: Bundle, channelID: String?) { + bundle.putBoolean("userInteraction", true) + val builder = NotificationCompat.Builder(context, channelID!!) + .setSmallIcon(R.drawable.ic_notif) // Set the intent that will fire when the user taps the notification + .setContentIntent(buildPendingIntent(bundle)) + .setAutoCancel(true) + if (!notificationMsg!!.isEmpty()) { + builder.setContentText(notificationMsg) + } + if (!notificationTitle!!.isEmpty()) { + builder.setContentTitle(notificationTitle) + } + val notificationManager = NotificationManagerCompat.from(context) + notificationManager.notify(uniqueTag, 0, builder.build()) + } + + override fun localNotification(ident: String, msg: String, badgeCount: Long, soundName: String, convID: String, + typ: String) { + genericNotification(ident, "", msg, bundle, KeybasePushNotificationListenerService.GENERAL_CHANNEL_ID) + } + + companion object { + // From: https://stackoverflow.com/questions/11932805/cropping-circular-area-from-bitmap-in-android + private fun getCroppedBitmap(bitmap: Bitmap): Bitmap { + val output = Bitmap.createBitmap(bitmap.width, + bitmap.height, Bitmap.Config.ARGB_8888) + val canvas = Canvas(output) + val color = -0xbdbdbe + val paint = Paint() + val rect = Rect(0, 0, bitmap.width, bitmap.height) + paint.isAntiAlias = true + canvas.drawARGB(0, 0, 0, 0) + paint.color = color + canvas.drawCircle((bitmap.width / 2).toFloat(), (bitmap.height / 2).toFloat(), + ( + bitmap.width / 2).toFloat(), paint) + paint.setXfermode(PorterDuffXfermode(PorterDuff.Mode.SRC_IN)) + canvas.drawBitmap(bitmap, rect, rect, paint) + return output + } + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/KBReactPackage.java b/shared/android/app/src/main/java/io/keybase/ossifrage/KBReactPackage.java deleted file mode 100644 index 68b54c3e900d..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/KBReactPackage.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.keybase.ossifrage; - -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -public class KBReactPackage implements com.facebook.react.ReactPackage { - @Override - public List createNativeModules(ReactApplicationContext reactApplicationContext) { - List modules = new ArrayList<>(); - // modules.add(); - return modules; - } - - @Override - public List createViewManagers(ReactApplicationContext reactApplicationContext) { - return Arrays.asList(); - } -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/KBReactPackage.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/KBReactPackage.kt new file mode 100644 index 000000000000..4e3dd8d8c697 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/KBReactPackage.kt @@ -0,0 +1,17 @@ +package io.keybase.ossifrage + +import com.facebook.react.ReactPackage +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.uimanager.ViewManager + +open class KBReactPackage : ReactPackage { + override fun createNativeModules(reactApplicationContext: ReactApplicationContext): List { + // modules.add(); + return ArrayList() + } + + override fun createViewManagers(reactApplicationContext: ReactApplicationContext): List> { + return mutableListOf() + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/KeyStore.java b/shared/android/app/src/main/java/io/keybase/ossifrage/KeyStore.java deleted file mode 100644 index e0ee2bd798ee..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/KeyStore.java +++ /dev/null @@ -1,241 +0,0 @@ -package io.keybase.ossifrage; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Build; -import android.security.keystore.KeyPermanentlyInvalidatedException; -import android.util.Base64; - -import org.msgpack.core.MessageBufferPacker; -import org.msgpack.core.MessagePack; - -import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.KeyPair; -import java.security.KeyStore.Entry; -import java.security.KeyStore.PrivateKeyEntry; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.cert.CertificateException; -import java.util.ArrayList; -import java.util.Iterator; - -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import keybase.UnsafeExternalKeyStore; -import io.keybase.ossifrage.keystore.KeyStoreHelper; -import io.keybase.ossifrage.modules.NativeLogger; - -public class KeyStore implements UnsafeExternalKeyStore { - private final Context context; - private final SharedPreferences prefs; - private java.security.KeyStore ks; - - // Prefix for the key we use when we place the data in shared preferences - private static final String PREFS_KEY = "_wrappedKey_"; - // The name of the key we use to store our created RSA keypair in android's keystore - private static final String KEY_ALIAS = "_keybase-rsa-wrapper_"; - - private static final String ALGORITHM = "RSA_SECRETBOX"; - - public KeyStore(final Context context, final SharedPreferences prefs) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException { - this.context = context; - this.prefs = prefs; - - ks = java.security.KeyStore.getInstance("AndroidKeyStore"); - ks.load(null); - NativeLogger.info("KeyStore: initialized"); - } - - private String sharedPrefKeyPrefix(final String serviceName) { - return serviceName + PREFS_KEY; - } - - private String keyStoreAlias(final String serviceName) { - return serviceName + KEY_ALIAS; - } - - @SuppressLint("CommitPrefEdits") - @Override - public void clearSecret(final String serviceName, final String key) throws Exception { - String id = serviceName + ":" + key; - NativeLogger.info("KeyStore: clearing secret for " + id); - - try { - prefs.edit().remove(sharedPrefKeyPrefix(serviceName) + key).commit(); - } catch (Exception e) { - NativeLogger.error("KeyStore: error clearing secret for " + id, e); - throw e; - } - - NativeLogger.info("KeyStore: cleared secret for " + id); - } - - @Override - public synchronized byte[] getUsersWithStoredSecretsMsgPack(final String serviceName) throws Exception { - NativeLogger.info("KeyStore: getting users with stored secrets for " + serviceName); - - try { - final Iterator keyIterator = prefs.getAll().keySet().iterator(); - final ArrayList userNames = new ArrayList<>(); - - while (keyIterator.hasNext()) { - final String key = keyIterator.next(); - if (key.indexOf(sharedPrefKeyPrefix(serviceName)) == 0) { - userNames.add(key.substring(sharedPrefKeyPrefix(serviceName).length())); - } - } - - NativeLogger.info("KeyStore: got " + userNames.size() + " users with stored secrets for " + serviceName); - - MessageBufferPacker packer = MessagePack.newDefaultBufferPacker(); - packer.packArrayHeader(userNames.size()); - for (String s: userNames) { - packer.packString(s); - } - packer.close(); - return packer.toByteArray(); - } catch (Exception e) { - NativeLogger.error("KeyStore: error getting users with stored secrets for " + serviceName, e); - throw e; - } - } - - @Override - public synchronized byte[] retrieveSecret(final String serviceName, final String key) throws Exception { - String id = serviceName + ":" + key; - NativeLogger.info("KeyStore: retrieving secret for " + id); - - try { - final byte[] wrappedSecret = readWrappedSecret(prefs, sharedPrefKeyPrefix(serviceName) + key); - Entry entry = ks.getEntry(keyStoreAlias(serviceName), null); - - if (entry == null) { - throw new KeyStoreException("No RSA keys in the keystore"); - } - - if (!(entry instanceof PrivateKeyEntry)) { - throw new KeyStoreException("Entry is not a PrivateKeyEntry. It is: " + entry.getClass()); - } - - try { - byte[] secret = unwrapSecret((PrivateKeyEntry) entry, wrappedSecret).getEncoded(); - NativeLogger.info("KeyStore: retrieved " + secret.length + "-byte secret for " + id); - return secret; - } catch (InvalidKeyException e) { - // Invalid key, this can happen when a user changes their lock screen from something to nothing - // or enrolls a new finger. See https://developer.android.com/reference/android/security/keystore/KeyPermanentlyInvalidatedException.html - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && e instanceof KeyPermanentlyInvalidatedException) { - NativeLogger.info("KeyStore: key no longer valid; deleting entry", e); - ks.deleteEntry((keyStoreAlias(serviceName))); - } - throw e; - } - } catch (Exception e) { - NativeLogger.error("KeyStore: error retrieving secret for " + id, e); - throw e; - } - } - - @Override - public synchronized void setupKeyStore(final String serviceName, final String key) throws Exception { - String id = serviceName + ":" + key; - NativeLogger.info("KeyStore: setting up key store for " + id); - - try { - if (!ks.containsAlias(keyStoreAlias(serviceName))) { - KeyStoreHelper.generateRSAKeyPair(context, keyStoreAlias(serviceName)); - } - - // Try to read the entry from the keystore. - // The entry may exist, but it may not be readable by us. - // (this happens when the app is uninstalled and reinstalled) - // In that case, lets' delete the entry and recreate it. - // Note we are purposely not recursing to avoid a state where we - // constantly try to generate new RSA keys (which is slow) - try { - final Entry entry = ks.getEntry(keyStoreAlias(serviceName), null); - if (entry == null) { - ks.deleteEntry(keyStoreAlias(serviceName)); - KeyStoreHelper.generateRSAKeyPair(context, keyStoreAlias(serviceName)); - } - } finally { - // Reload the keystore - ks = java.security.KeyStore.getInstance("AndroidKeyStore"); - ks.load(null); - } - } catch (Exception e) { - NativeLogger.error("KeyStore: error setting up key store for " + id, e); - throw e; - } - - NativeLogger.info("KeyStore: finished setting up key store for " + id); - } - - @Override - public synchronized void storeSecret(final String serviceName, final String key, final byte[] bytes) throws Exception { - String id = serviceName + ":" + key; - NativeLogger.info("KeyStore: storing " + bytes.length + "-byte secret for " + id); - - try { - Entry entry = ks.getEntry(keyStoreAlias(serviceName), null); - - if (entry == null) { - throw new KeyStoreException("No RSA keys in the keystore"); - } - - final byte[] wrappedSecret = wrapSecret((PrivateKeyEntry) entry, new SecretKeySpec(bytes, ALGORITHM)); - - if (wrappedSecret == null) { - throw new IOException("Null return when wrapping secret"); - } - - saveWrappedSecret(prefs, sharedPrefKeyPrefix(serviceName) + key, wrappedSecret); - } catch (Exception e) { - NativeLogger.error("KeyStore: error storing secret for " + id, e); - throw e; - } - - NativeLogger.info("KeyStore: stored " + bytes.length + "-byte secret for " + id); - } - - private static void saveWrappedSecret(SharedPreferences prefs, String prefsKey, byte[] wrappedSecret) { - prefs.edit().putString(prefsKey, Base64.encodeToString(wrappedSecret, Base64.NO_WRAP)).apply(); - } - - - private static byte[] readWrappedSecret(SharedPreferences prefs, String prefsKey) throws Exception { - final String wrappedKey = prefs.getString(prefsKey, ""); - if (wrappedKey.isEmpty()) { - throw new KeyStoreException("No secret for " + prefsKey); - } - return Base64.decode(wrappedKey, Base64.NO_WRAP); - } - - /** - * Similar to Android's example Vault https://github.com/android/platform_development/tree/master/samples/Vault - */ - private static byte[] wrapSecret(PrivateKeyEntry entry, SecretKey key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException { - KeyPair mPair = new KeyPair(entry.getCertificate().getPublicKey(), entry.getPrivateKey()); - // This is the only cipher that's supported by AndroidKeystore (api version +18) - // The padding makes sure this encryption isn't deterministic - Cipher mCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - mCipher.init(Cipher.WRAP_MODE, mPair.getPublic()); - return mCipher.wrap(key); - } - - private static SecretKey unwrapSecret(PrivateKeyEntry entry, byte[] wrappedSecretKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException { - KeyPair mPair = new KeyPair(entry.getCertificate().getPublicKey(), entry.getPrivateKey()); - Cipher mCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - mCipher.init(Cipher.UNWRAP_MODE, mPair.getPrivate()); - return (SecretKey) mCipher.unwrap(wrappedSecretKey, ALGORITHM, Cipher.SECRET_KEY); - } - - -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/KeyStore.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/KeyStore.kt new file mode 100644 index 000000000000..66c815069010 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/KeyStore.kt @@ -0,0 +1,207 @@ +package io.keybase.ossifrage + +import android.annotation.SuppressLint +import android.content.Context +import android.content.SharedPreferences +import android.os.Build +import android.security.keystore.KeyPermanentlyInvalidatedException +import android.util.Base64 +import io.keybase.ossifrage.keystore.KeyStoreHelper +import io.keybase.ossifrage.modules.NativeLogger +import keybase.UnsafeExternalKeyStore +import org.msgpack.core.MessagePack +import java.io.IOException +import java.security.InvalidKeyException +import java.security.KeyPair +import java.security.KeyStore +import java.security.KeyStoreException +import java.security.NoSuchAlgorithmException +import java.security.NoSuchProviderException +import javax.crypto.Cipher +import javax.crypto.IllegalBlockSizeException +import javax.crypto.NoSuchPaddingException +import javax.crypto.SecretKey +import javax.crypto.spec.SecretKeySpec + +class KeyStore(private val context: Context, private val prefs: SharedPreferences) : UnsafeExternalKeyStore { + private var ks: KeyStore + + init { + ks = KeyStore.getInstance("AndroidKeyStore") + ks.load(null) + NativeLogger.info("KeyStore: initialized") + } + + private fun sharedPrefKeyPrefix(serviceName: String): String { + return serviceName + PREFS_KEY + } + + private fun keyStoreAlias(serviceName: String): String { + return serviceName + KEY_ALIAS + } + + @SuppressLint("CommitPrefEdits") + @Throws(Exception::class) + override fun clearSecret(serviceName: String, key: String) { + val id = "$serviceName:$key" + NativeLogger.info("KeyStore: clearing secret for $id") + try { + prefs.edit().remove(sharedPrefKeyPrefix(serviceName) + key).commit() + } catch (e: Exception) { + NativeLogger.error("KeyStore: error clearing secret for $id", e) + throw e + } + NativeLogger.info("KeyStore: cleared secret for $id") + } + + @Synchronized + @Throws(Exception::class) + override fun getUsersWithStoredSecretsMsgPack(serviceName: String): ByteArray { + NativeLogger.info("KeyStore: getting users with stored secrets for $serviceName") + return try { + val keyIterator: Iterator = prefs.all.keys.iterator() + val userNames = ArrayList() + while (keyIterator.hasNext()) { + val key = keyIterator.next() + if (key.indexOf(sharedPrefKeyPrefix(serviceName)) == 0) { + userNames.add(key.substring(sharedPrefKeyPrefix(serviceName).length)) + } + } + NativeLogger.info("KeyStore: got " + userNames.size + " users with stored secrets for " + serviceName) + val packer = MessagePack.newDefaultBufferPacker() + packer.packArrayHeader(userNames.size) + for (s in userNames) { + packer.packString(s) + } + packer.close() + packer.toByteArray() + } catch (e: Exception) { + NativeLogger.error("KeyStore: error getting users with stored secrets for $serviceName", e) + throw e + } + } + + @Synchronized + @Throws(Exception::class) + override fun retrieveSecret(serviceName: String, key: String): ByteArray { + val id = "$serviceName:$key" + NativeLogger.info("KeyStore: retrieving secret for $id") + return try { + val wrappedSecret = readWrappedSecret(prefs, sharedPrefKeyPrefix(serviceName) + key) + val entry = ks.getEntry(keyStoreAlias(serviceName), null) + ?: throw KeyStoreException("No RSA keys in the keystore") + if (entry !is KeyStore.PrivateKeyEntry) { + throw KeyStoreException("Entry is not a PrivateKeyEntry. It is: " + entry.javaClass) + } + try { + val secret = unwrapSecret(entry, wrappedSecret).encoded + NativeLogger.info("KeyStore: retrieved " + secret.size + "-byte secret for " + id) + secret + } catch (e: InvalidKeyException) { + // Invalid key, this can happen when a user changes their lock screen from something to nothing + // or enrolls a new finger. See https://developer.android.com/reference/android/security/keystore/KeyPermanentlyInvalidatedException.html + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && e is KeyPermanentlyInvalidatedException) { + NativeLogger.info("KeyStore: key no longer valid; deleting entry", e) + ks.deleteEntry(keyStoreAlias(serviceName)) + } + throw e + } + } catch (e: Exception) { + NativeLogger.error("KeyStore: error retrieving secret for $id", e) + throw e + } + } + + @Synchronized + @Throws(Exception::class) + override fun setupKeyStore(serviceName: String, key: String) { + val id = "$serviceName:$key" + NativeLogger.info("KeyStore: setting up key store for $id") + try { + if (!ks.containsAlias(keyStoreAlias(serviceName))) { + KeyStoreHelper.generateRSAKeyPair(context, keyStoreAlias(serviceName)) + } + + // Try to read the entry from the keystore. + // The entry may exist, but it may not be readable by us. + // (this happens when the app is uninstalled and reinstalled) + // In that case, lets' delete the entry and recreate it. + // Note we are purposely not recursing to avoid a state where we + // constantly try to generate new RSA keys (which is slow) + try { + val entry = ks.getEntry(keyStoreAlias(serviceName), null) + if (entry == null) { + ks.deleteEntry(keyStoreAlias(serviceName)) + KeyStoreHelper.generateRSAKeyPair(context, keyStoreAlias(serviceName)) + } + } finally { + // Reload the keystore + ks = KeyStore.getInstance("AndroidKeyStore") + ks.load(null) + } + } catch (e: Exception) { + NativeLogger.error("KeyStore: error setting up key store for $id", e) + throw e + } + NativeLogger.info("KeyStore: finished setting up key store for $id") + } + + @Synchronized + @Throws(Exception::class) + override fun storeSecret(serviceName: String, key: String, bytes: ByteArray) { + val id = "$serviceName:$key" + NativeLogger.info("KeyStore: storing " + bytes.size + "-byte secret for " + id) + try { + val entry = ks.getEntry(keyStoreAlias(serviceName), null) + ?: throw KeyStoreException("No RSA keys in the keystore") + val wrappedSecret = wrapSecret(entry as KeyStore.PrivateKeyEntry, SecretKeySpec(bytes, ALGORITHM)) + saveWrappedSecret(prefs, sharedPrefKeyPrefix(serviceName) + key, wrappedSecret) + } catch (e: Exception) { + NativeLogger.error("KeyStore: error storing secret for $id", e) + throw e + } + NativeLogger.info("KeyStore: stored " + bytes.size + "-byte secret for " + id) + } + + companion object { + // Prefix for the key we use when we place the data in shared preferences + private const val PREFS_KEY = "_wrappedKey_" + + // The name of the key we use to store our created RSA keypair in android's keystore + private const val KEY_ALIAS = "_keybase-rsa-wrapper_" + private const val ALGORITHM = "RSA_SECRETBOX" + private fun saveWrappedSecret(prefs: SharedPreferences, prefsKey: String, wrappedSecret: ByteArray) { + prefs.edit().putString(prefsKey, Base64.encodeToString(wrappedSecret, Base64.NO_WRAP)).apply() + } + + @Throws(Exception::class) + private fun readWrappedSecret(prefs: SharedPreferences, prefsKey: String): ByteArray { + val wrappedKey = prefs.getString(prefsKey, "") + if (wrappedKey!!.isEmpty()) { + throw KeyStoreException("No secret for $prefsKey") + } + return Base64.decode(wrappedKey, Base64.NO_WRAP) + } + + /** + * Similar to Android's example Vault https://github.com/android/platform_development/tree/master/samples/Vault + */ + @Throws(NoSuchPaddingException::class, NoSuchAlgorithmException::class, InvalidKeyException::class, IllegalBlockSizeException::class, NoSuchProviderException::class) + private fun wrapSecret(entry: KeyStore.PrivateKeyEntry, key: SecretKey): ByteArray { + val mPair = KeyPair(entry.certificate.publicKey, entry.privateKey) + // This is the only cipher that's supported by AndroidKeystore (api version +18) + // The padding makes sure this encryption isn't deterministic + val mCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding") + mCipher.init(Cipher.WRAP_MODE, mPair.public) + return mCipher.wrap(key) + } + + @Throws(NoSuchPaddingException::class, NoSuchAlgorithmException::class, InvalidKeyException::class, IllegalBlockSizeException::class, NoSuchProviderException::class) + private fun unwrapSecret(entry: KeyStore.PrivateKeyEntry, wrappedSecretKey: ByteArray): SecretKey { + val mPair = KeyPair(entry.certificate.publicKey, entry.privateKey) + val mCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding") + mCipher.init(Cipher.UNWRAP_MODE, mPair.private) + return mCipher.unwrap(wrappedSecretKey, ALGORITHM, Cipher.SECRET_KEY) as SecretKey + } + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/KeybasePushNotificationListenerService.java b/shared/android/app/src/main/java/io/keybase/ossifrage/KeybasePushNotificationListenerService.java deleted file mode 100644 index bf3e18d8b81c..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/KeybasePushNotificationListenerService.java +++ /dev/null @@ -1,318 +0,0 @@ -package io.keybase.ossifrage; - -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.content.Context; -import android.os.Build; -import android.os.Bundle; - -import androidx.annotation.RequiresApi; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationCompat.MessagingStyle; -import androidx.core.app.NotificationManagerCompat; -import androidx.core.app.Person; - -import me.leolin.shortcutbadger.ShortcutBadger; -import com.google.firebase.messaging.FirebaseMessagingService; -import com.google.firebase.messaging.RemoteMessage; - -import org.json.JSONArray; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; - -import io.keybase.ossifrage.modules.NativeLogger; -import keybase.Keybase; - -public class KeybasePushNotificationListenerService extends FirebaseMessagingService { - public static String CHAT_CHANNEL_ID = "kb_chat_channel"; - public static String FOLLOW_CHANNEL_ID = "kb_follow_channel"; - public static String DEVICE_CHANNEL_ID = "kb_device_channel"; - public static String GENERAL_CHANNEL_ID = "kb_rest_channel"; - - // This keeps a small ring buffer cache of the last 5 messages per conversation the user - // was notified about to give context to future notifications. - private HashMap msgCache = new HashMap(); - // Avoid ever showing doubles - private HashSet seenChatNotifications = new HashSet(); - - private NotificationCompat.Style buildStyle(String convID, Person person) { - MessagingStyle style = new MessagingStyle(person); - SmallMsgRingBuffer buf = msgCache.get(convID); - if (buf != null) { - for (MessagingStyle.Message msg: buf.summary()) { - style.addMessage(msg); - } - } - - return style; - } - - @Override - public void onCreate() { - MainActivity.setupKBRuntime(this, false); - NativeLogger.info("KeybasePushNotificationListenerService created"); - createNotificationChannel(this); - } - - - public static void createNotificationChannel(Context context) { - // Create the NotificationChannel, but only on API 26+ because - // the NotificationChannel class is new and not in the support library - // Safe to call this multiple times - no ops afterwards - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationManager notificationManager = context.getSystemService(NotificationManager.class); - - if (notificationManager.getNotificationChannel("keybase_all") != null) { - notificationManager.deleteNotificationChannel("keybase_all"); - } - - // Chat Notifications - { - CharSequence name = context.getString(R.string.channel_name); - String description = context.getString(R.string.channel_description); - int importance = NotificationManager.IMPORTANCE_HIGH; - NotificationChannel chat_channel = new NotificationChannel(CHAT_CHANNEL_ID, name, importance); - chat_channel.setDescription(description); - // Register the channel with the system; you can't change the importance - // or other notification behaviors after this - notificationManager.createNotificationChannel(chat_channel); - } - - - // Follow Notifications - { - CharSequence follow_name = context.getString(R.string.notif_follows_name); - String follow_description = context.getString(R.string.notif_follow_desc); - int follow_importance = NotificationManager.IMPORTANCE_DEFAULT; - NotificationChannel follow_channel = new NotificationChannel(FOLLOW_CHANNEL_ID, follow_name, follow_importance); - follow_channel.setDescription(follow_description); - notificationManager.createNotificationChannel(follow_channel); - } - - // Device Notifications - { - CharSequence device_name = context.getString(R.string.notif_devices_name); - String device_description = context.getString(R.string.notif_device_description); - int device_importance = NotificationManager.IMPORTANCE_HIGH; - NotificationChannel device_channel = new NotificationChannel(DEVICE_CHANNEL_ID, device_name, device_importance); - device_channel.setDescription(device_description); - notificationManager.createNotificationChannel(device_channel); - } - - // The rest of the notifications - { - CharSequence general_name = context.getString(R.string.general_channel_name); - String general_description = context.getString(R.string.general_channel_description); - int general_importance = NotificationManager.IMPORTANCE_LOW; - NotificationChannel general_channel = new NotificationChannel(GENERAL_CHANNEL_ID, general_name, general_importance); - general_channel.setDescription(general_description); - notificationManager.createNotificationChannel(general_channel); - } - - } - } - - @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB_MR1) - @Override - public void onMessageReceived(RemoteMessage message) { - final Bundle bundle = new Bundle(); - for (Map.Entry entry : message.getData().entrySet()) { - bundle.putString(entry.getKey(), entry.getValue()); - } - JSONObject data = parseJSONObject(bundle.getString("data")); - if (data != null) { - if (!bundle.containsKey("message")) { - bundle.putString("message", data.optString("alert", null)); - } - if (!bundle.containsKey("title")) { - bundle.putString("title", data.optString("title", null)); - } - if (!bundle.containsKey("sound")) { - bundle.putString("soundName", data.optString("sound", null)); - } - if (!bundle.containsKey("color")) { - bundle.putString("color", data.optString("color", null)); - } - - final int badge = data.optInt("badge", -1); - if (badge >= 0) { - ShortcutBadger.applyCount(this, badge); - } - } - - NativeLogger.info("KeybasePushNotificationListenerService.onMessageReceived"); - - try { - String type = bundle.getString("type"); - String payload = bundle.getString("m"); - KBPushNotifier notifier = new KBPushNotifier(getApplicationContext(), bundle); - switch (type) { - case "chat.newmessage": - case "chat.newmessageSilent_2": { - NotificationData n = new NotificationData(type, bundle); - - // Blow the cache if we aren't displaying plaintext - if (!msgCache.containsKey(n.convID) || !n.displayPlaintext) { - msgCache.put(n.convID, new SmallMsgRingBuffer()); - } - - // We've shown this notification already - if (seenChatNotifications.contains(n.convID + n.messageId)) { - return; - } - - // If we aren't displaying the plain text version in a silent notif drop this. - // We'll get the non-silent version with a servermessagebody that we can display - // later. - boolean dontNotify = (type.equals("chat.newmessageSilent_2") && !n.displayPlaintext); - - notifier.setMsgCache(msgCache.get(n.convID)); - WithBackgroundActive withBackgroundActive = () -> { - try { - Keybase.handleBackgroundNotification(n.convID, payload, n.serverMessageBody, n.sender, - n.membersType, n.displayPlaintext, n.messageId, n.pushId, - n.badgeCount, n.unixTime, n.soundName, dontNotify ? null : notifier, true); - if (!dontNotify) { - seenChatNotifications.add(n.convID + n.messageId); - } - } catch (Exception ex) { - NativeLogger.error("Go Couldn't handle background notification2: " + ex.getMessage()); - } - }; - withBackgroundActive.whileActive(getApplicationContext()); - - } - break; - case "follow": { - notifier.followNotification(bundle.getString("username"), bundle.getString("message")); - } - break; - case "device.revoked": - case "device.new": { - notifier.deviceNotification(); - } - break; - case "chat.readmessage": { - String convID = bundle.getString("c"); - // Clear the cache of msgs for this conv id - if (msgCache.containsKey(convID)) { - msgCache.put(convID, new SmallMsgRingBuffer()); - } - // Cancel any push notifications. - NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplicationContext()); - notificationManager.cancelAll(); - } - break; - default: - notifier.generalNotification(); - } - } catch (Exception ex) { - NativeLogger.error("Couldn't handle background notification: " + ex.getMessage()); - } - - } - - private JSONObject parseJSONObject(String str) { - try { - return new JSONObject(str); - } catch (Exception e) { - return null; - } - } - -} - -class SmallMsgRingBuffer { - private ArrayList buffer = new ArrayList(); - - public void add(MessagingStyle.Message m) { - while (buffer.size() > 4) { - buffer.remove(0); - } - buffer.add(m); - } - - public List summary() { - return buffer; - } -} - -class NotificationData { - final boolean displayPlaintext; - final int membersType; - final String convID; - final int messageId; - final String pushId; - final int badgeCount; - final long unixTime; - final String soundName; - final String serverMessageBody; - final String sender; - - // Derived from go/gregord/chatpush/push.go - @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB_MR1) - NotificationData(String type, Bundle bundle) { - displayPlaintext = "true".equals(bundle.getString("n")); - membersType = Integer.parseInt(bundle.getString("t")); - badgeCount = Integer.parseInt(bundle.getString("b", "0")); - soundName = bundle.getString("s", ""); - serverMessageBody = bundle.getString("message", ""); - sender = bundle.getString("u", ""); - unixTime = Long.parseLong(bundle.getString("x", "0")); - - if (type.equals("chat.newmessage")) { - messageId = Integer.parseInt(bundle.getString("msgID", "0")); - convID = bundle.getString("convID"); - pushId = ""; - } else if (type.equals("chat.newmessageSilent_2")) { - messageId = Integer.parseInt(bundle.getString("d", "")); - convID = bundle.getString("c"); - - String pushIdTmp = ""; - try { - JSONArray pushes = new JSONArray(bundle.getString("p")); - pushIdTmp = pushes.getString(0); - } catch (Exception e) { - e.printStackTrace(); - } - pushId = pushIdTmp; - } else { - throw new Error("Tried to parse notification of unhandled type: " + type ); - } - - } -} - -// Interface to run some task while in backgroundActive. -// If already foreground, just runs the task. -interface WithBackgroundActive { - abstract void task() throws Exception; - - default void whileActive(Context context) throws Exception { - // We are foreground we don't need to change to background active - if (Keybase.isAppStateForeground()) { - this.task(); - } else { - Keybase.setAppStateBackgroundActive(); - this.task(); - - // Check if we are foreground now for some reason. In that case we don't want to go background again - if (Keybase.isAppStateForeground()) { - return; - } - - if (Keybase.appDidEnterBackground()) { - Keybase.appBeginBackgroundTaskNonblock(new KBPushNotifier(context, new Bundle())); - } else { - Keybase.setAppStateBackground(); - } - } - } - - -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/KeybasePushNotificationListenerService.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/KeybasePushNotificationListenerService.kt new file mode 100644 index 000000000000..c6c6b421d7a9 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/KeybasePushNotificationListenerService.kt @@ -0,0 +1,303 @@ +package io.keybase.ossifrage + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.content.Context +import android.os.Build +import android.os.Bundle +import androidx.annotation.RequiresApi +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import androidx.core.app.Person +import com.google.firebase.messaging.FirebaseMessagingService +import com.google.firebase.messaging.RemoteMessage +import io.keybase.ossifrage.MainActivity.Companion.setupKBRuntime +import io.keybase.ossifrage.modules.NativeLogger +import keybase.Keybase +import me.leolin.shortcutbadger.ShortcutBadger +import org.json.JSONArray +import org.json.JSONObject + +class KeybasePushNotificationListenerService : FirebaseMessagingService() { + // This keeps a small ring buffer cache of the last 5 messages per conversation the user + // was notified about to give context to future notifications. + private val msgCache = HashMap() + + // Avoid ever showing doubles + private val seenChatNotifications = HashSet() + private fun buildStyle(convID: String, person: Person): NotificationCompat.Style { + val style = NotificationCompat.MessagingStyle(person) + val buf = msgCache[convID] + if (buf != null) { + for (msg in buf.summary()) { + style.addMessage(msg) + } + } + return style + } + + override fun onCreate() { + setupKBRuntime(this, false) + NativeLogger.info("KeybasePushNotificationListenerService created") + createNotificationChannel(this) + } + + @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB_MR1) + override fun onMessageReceived(message: RemoteMessage) { + val bundle = Bundle() + for ((key, value) in message.data) { + bundle.putString(key, value) + } + val data = parseJSONObject(bundle.getString("data")) + if (data != null) { + if (!bundle.containsKey("message")) { + bundle.putString("message", data.optString("alert", "")) + } + if (!bundle.containsKey("title")) { + bundle.putString("title", data.optString("title", "")) + } + if (!bundle.containsKey("sound")) { + bundle.putString("soundName", data.optString("sound", "")) + } + if (!bundle.containsKey("color")) { + bundle.putString("color", data.optString("color", "")) + } + val badge = data.optInt("badge", -1) + if (badge >= 0) { + ShortcutBadger.applyCount(this, badge) + } + } + NativeLogger.info("KeybasePushNotificationListenerService.onMessageReceived") + try { + val type = bundle.getString("type") + val payload = bundle.getString("m") + val notifier = KBPushNotifier(applicationContext, bundle) + when (type) { + "chat.newmessage", "chat.newmessageSilent_2" -> { + val n = NotificationData(type, bundle) + + // Blow the cache if we aren't displaying plaintext + if (!msgCache.containsKey(n.convID) || !n.displayPlaintext) { + msgCache[n.convID] = SmallMsgRingBuffer() + } + + // We've shown this notification already + if (seenChatNotifications.contains(n.convID + n.messageId)) { + return + } + + // If we aren't displaying the plain text version in a silent notif drop this. + // We'll get the non-silent version with a servermessagebody that we can display + // later. + val dontNotify = type == "chat.newmessageSilent_2" && !n.displayPlaintext + notifier.setMsgCache(msgCache[n.convID]) + val withBackgroundActive: WithBackgroundActive = object : WithBackgroundActive { + override fun task() { + try { + Keybase.handleBackgroundNotification(n.convID, payload, n.serverMessageBody, n.sender, + n.membersType.toLong(), n.displayPlaintext, n.messageId.toLong(), n.pushId, + n.badgeCount.toLong(), n.unixTime, n.soundName, if (dontNotify) null else notifier, true) + if (!dontNotify) { + seenChatNotifications.add(n.convID + n.messageId) + } + } catch (ex: Exception) { + NativeLogger.error("Go Couldn't handle background notification2: " + ex.message) + } + } + } + withBackgroundActive.whileActive(applicationContext) + } + + "follow" -> { + val username = bundle.getString("username") + val m = bundle.getString("message") + if (username != null && m != null) { + notifier.followNotification(username, m) + } + } + + "device.revoked", "device.new" -> { + notifier.deviceNotification() + } + + "chat.readmessage" -> { + val convID = bundle.getString("c") + // Clear the cache of msgs for this conv id + if (msgCache.containsKey(convID)) { + msgCache[convID] = SmallMsgRingBuffer() + } + // Cancel any push notifications. + val notificationManager = NotificationManagerCompat.from(applicationContext) + notificationManager.cancelAll() + } + + else -> notifier.generalNotification() + } + } catch (ex: Exception) { + NativeLogger.error("Couldn't handle background notification: " + ex.message) + } + } + + private fun parseJSONObject(str: String?): JSONObject? { + return try { + if (str != null) { + return JSONObject(str) + } else { + return null + } + } catch (e: Exception) { + null + } + } + + companion object { + @JvmField + var CHAT_CHANNEL_ID = "kb_chat_channel" + @JvmField + var FOLLOW_CHANNEL_ID = "kb_follow_channel" + @JvmField + var DEVICE_CHANNEL_ID = "kb_device_channel" + @JvmField + var GENERAL_CHANNEL_ID = "kb_rest_channel" + fun createNotificationChannel(context: Context) { + // Create the NotificationChannel, but only on API 26+ because + // the NotificationChannel class is new and not in the support library + // Safe to call this multiple times - no ops afterwards + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val notificationManager = context.getSystemService(NotificationManager::class.java) + if (notificationManager.getNotificationChannel("keybase_all") != null) { + notificationManager.deleteNotificationChannel("keybase_all") + } + + // Chat Notifications + run { + val name: CharSequence = context.getString(R.string.channel_name) + val description = context.getString(R.string.channel_description) + val importance = NotificationManager.IMPORTANCE_HIGH + val chat_channel = NotificationChannel(CHAT_CHANNEL_ID, name, importance) + chat_channel.description = description + // Register the channel with the system; you can't change the importance + // or other notification behaviors after this + notificationManager.createNotificationChannel(chat_channel) + } + + + // Follow Notifications + run { + val follow_name: CharSequence = context.getString(R.string.notif_follows_name) + val follow_description = context.getString(R.string.notif_follow_desc) + val follow_importance = NotificationManager.IMPORTANCE_DEFAULT + val follow_channel = NotificationChannel(FOLLOW_CHANNEL_ID, follow_name, follow_importance) + follow_channel.description = follow_description + notificationManager.createNotificationChannel(follow_channel) + } + + // Device Notifications + run { + val device_name: CharSequence = context.getString(R.string.notif_devices_name) + val device_description = context.getString(R.string.notif_device_description) + val device_importance = NotificationManager.IMPORTANCE_HIGH + val device_channel = NotificationChannel(DEVICE_CHANNEL_ID, device_name, device_importance) + device_channel.description = device_description + notificationManager.createNotificationChannel(device_channel) + } + + // The rest of the notifications + run { + val general_name: CharSequence = context.getString(R.string.general_channel_name) + val general_description = context.getString(R.string.general_channel_description) + val general_importance = NotificationManager.IMPORTANCE_LOW + val general_channel = NotificationChannel(GENERAL_CHANNEL_ID, general_name, general_importance) + general_channel.description = general_description + notificationManager.createNotificationChannel(general_channel) + } + } + } + } +} + +class SmallMsgRingBuffer { + private val buffer = ArrayList() + fun add(m: NotificationCompat.MessagingStyle.Message) { + while (buffer.size > 4) { + buffer.removeAt(0) + } + buffer.add(m) + } + + fun summary(): List { + return buffer + } +} + +internal class NotificationData @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB_MR1) constructor(type: String, bundle: Bundle) { + val displayPlaintext: Boolean + val membersType: Int + var convID: String? = null + var messageId = 0 + var pushId: String? = null + val badgeCount: Int + val unixTime: Long + val soundName: String + val serverMessageBody: String + val sender: String + + // Derived from go/gregord/chatpush/push.go + init { + displayPlaintext = "true" == bundle.getString("n") + membersType = bundle.getString("t")!!.toInt() + badgeCount = bundle.getString("b", "0").toInt() + soundName = bundle.getString("s", "") + serverMessageBody = bundle.getString("message", "") + sender = bundle.getString("u", "") + unixTime = bundle.getString("x", "0").toLong() + if (type == "chat.newmessage") { + messageId = bundle.getString("msgID", "0").toInt() + convID = bundle.getString("convID") + pushId = "" + } else if (type == "chat.newmessageSilent_2") { + messageId = bundle.getString("d", "").toInt() + convID = bundle.getString("c") + var pushIdTmp = "" + try { + val pushes = JSONArray(bundle.getString("p")) + pushIdTmp = pushes.getString(0) + } catch (e: Exception) { + e.printStackTrace() + } + pushId = pushIdTmp + } else { + throw Error("Tried to parse notification of unhandled type: $type") + } + } +} + +// Interface to run some task while in backgroundActive. +// If already foreground, just runs the task. +internal interface WithBackgroundActive { + @Throws(Exception::class) + fun task() + + @Throws(Exception::class) + fun whileActive(context: Context?) { + // We are foreground we don't need to change to background active + if (Keybase.isAppStateForeground()) { + task() + } else { + Keybase.setAppStateBackgroundActive() + task() + + // Check if we are foreground now for some reason. In that case we don't want to go background again + if (Keybase.isAppStateForeground()) { + return + } + if (Keybase.appDidEnterBackground()) { + if (context != null) { + Keybase.appBeginBackgroundTaskNonblock(KBPushNotifier(context, Bundle())) + } + } else { + Keybase.setAppStateBackground() + } + } + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/MainActivity.java b/shared/android/app/src/main/java/io/keybase/ossifrage/MainActivity.java deleted file mode 100644 index 68e355af84f6..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/MainActivity.java +++ /dev/null @@ -1,528 +0,0 @@ -package io.keybase.ossifrage; - -import android.annotation.TargetApi; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.provider.MediaStore; -import android.provider.Settings; -import android.util.Log; -import android.view.KeyEvent; -import android.view.Window; -import android.webkit.MimeTypeMap; - -import com.facebook.react.ReactActivityDelegate; -import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; -import com.facebook.react.defaults.DefaultReactActivityDelegate; -import com.facebook.react.ReactApplication; -import com.facebook.react.ReactInstanceManager; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.ReactActivity; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.modules.core.DeviceEventManagerModule; -import com.facebook.react.modules.core.PermissionListener; - -import com.github.emilioicai.hwkeyboardevent.HWKeyboardEventModule; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.util.Arrays; -import java.util.Objects; -import java.util.ArrayList; -import java.util.UUID; - -import io.keybase.ossifrage.modules.NativeLogger; -import io.keybase.ossifrage.util.DNSNSFetcher; -import io.keybase.ossifrage.util.VideoHelper; -import com.reactnativekb.GuiConfig; -import com.reactnativekb.DarkModePreference; -import keybase.Keybase; - -import static keybase.Keybase.initOnce; - -public class MainActivity extends ReactActivity { - private static final String TAG = MainActivity.class.getName(); - private PermissionListener listener; - private boolean isUsingHardwareKeyboard = false; - static boolean createdReact = false; - private Bundle initialBundleFromNotification; - private String[] shareFileUrls; - private String shareText; - - public void setInitialBundleFromNotification(Bundle bundle) { - this.initialBundleFromNotification = bundle; - } - public void setInitialShareFileUrls(String [] urls) { - this.shareFileUrls = urls; - } - public void setInitialShareText(String text) { - this.shareText = text; - } - - public Bundle getInitialBundleFromNotification() { - Bundle b = this.initialBundleFromNotification; - this.initialBundleFromNotification = null; - return b; - } - public String []getInitialShareFileUrls() { - String []s = this.shareFileUrls; - this.shareFileUrls = null; - return s; - } - public String getInitialShareText() { - String s = this.shareText; - this.shareText = null; - return s; - } - - - @Override - public void invokeDefaultOnBackPressed() { - moveTaskToBack(true); - } - - private static void createDummyFile(Context context) { - File dummyFile = new File(context.getFilesDir(), "dummy.txt"); - try { - if (dummyFile.createNewFile()) { - dummyFile.setWritable(true); - try (FileOutputStream stream = new FileOutputStream(dummyFile)) { - stream.write("hi".getBytes()); - } - } else { - Log.d(TAG, "dummy.txt exists"); - } - } catch (Exception e) { - NativeLogger.error("Exception in createDummyFile", e); - } - } - - private ReactContext getReactContext() { - ReactInstanceManager instanceManager = ((ReactApplication) getApplication()).getReactNativeHost().getReactInstanceManager(); - if (instanceManager == null) { - NativeLogger.warn("react instance manager not ready"); - return null; - } - - return instanceManager.getCurrentReactContext(); - } - - // Is this a robot controlled test device? (i.e. pre-launch report?) - public static boolean isTestDevice(Context context) { - String testLabSetting = Settings.System.getString(context.getContentResolver(), "firebase.test.lab"); - return "true".equals(testLabSetting); - } - - - public static void setupKBRuntime(Context context, boolean shouldCreateDummyFile) { - try { - Keybase.setGlobalExternalKeyStore(new KeyStore(context, context.getSharedPreferences("KeyStore", MODE_PRIVATE))); - } catch (KeyStoreException | CertificateException | IOException | NoSuchAlgorithmException e) { - NativeLogger.error("Exception in MainActivity.onCreate", e); - } - - if (shouldCreateDummyFile) { - createDummyFile(context); - } - String mobileOsVersion = Integer.toString(android.os.Build.VERSION.SDK_INT); - boolean isIPad = false; - boolean isIOS = false; - initOnce(context.getFilesDir().getPath(), "", context.getFileStreamPath("service.log").getAbsolutePath(), "prod", false, - new DNSNSFetcher(), new VideoHelper(), mobileOsVersion, isIPad, new KBInstallReferrerListener(context), isIOS); - } - - private String colorSchemeForCurrentConfiguration() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; - switch (currentNightMode) { - case Configuration.UI_MODE_NIGHT_NO: - return "light"; - case Configuration.UI_MODE_NIGHT_YES: - return "dark"; - } - } - - return "light"; - } - - - @Override - @TargetApi(Build.VERSION_CODES.KITKAT) - protected void onCreate(Bundle savedInstanceState) { - NativeLogger.info("Activity onCreate"); - ReactInstanceManager instanceManager = ((ReactApplication) getApplication()).getReactNativeHost().getReactInstanceManager(); - if (!this.createdReact) { - this.createdReact = true; - instanceManager.createReactContextInBackground(); - } - - setupKBRuntime(this, true); - super.onCreate(null); - - new android.os.Handler().postDelayed(new Runnable() { - public void run() { - try { - setBackgroundColor(GuiConfig.getInstance(getFilesDir()).getDarkMode()); - } catch (Exception e) {} - } - }, 300); - - KeybasePushNotificationListenerService.createNotificationChannel(this); - updateIsUsingHardwareKeyboard(); - } - - @Override - public boolean onCreateThumbnail(final Bitmap outBitmap, final Canvas canvas) { - return super.onCreateThumbnail(outBitmap, canvas); - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - if (BuildConfig.DEBUG && keyCode == KeyEvent.KEYCODE_VOLUME_UP) { - return super.onKeyUp(KeyEvent.KEYCODE_MENU, null); - } - return super.onKeyUp(keyCode, event); - } - - @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { - if (listener != null) { - listener.onRequestPermissionsResult(requestCode, permissions, grantResults); - } - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - } - - @Override - protected void onPause() { - NativeLogger.info("Activity onPause"); - super.onPause(); - if (Keybase.appDidEnterBackground()) { - Keybase.appBeginBackgroundTaskNonblock(new KBPushNotifier(this, new Bundle())); - } else { - Keybase.setAppStateBackground(); - } - } - - private String getFileNameFromResolver(ContentResolver resolver, Uri uri, String extension) { - // Use a GUID default. - String filename = String.format("%s.%s", UUID.randomUUID().toString(), extension); - - String[] nameProjection = {MediaStore.MediaColumns.DISPLAY_NAME}; - try (Cursor cursor = resolver.query(uri, nameProjection, null, null, null)) { - if (cursor != null && cursor.moveToFirst()) { - filename = cursor.getString(0); - } - } - - int cut = filename.lastIndexOf('/'); - if (cut != -1) { - filename = filename.substring(cut + 1); - } - - return filename; - } - - private File saveFileToCache(ReactContext reactContext, Uri uri, String filename) { - File file = new File(reactContext.getCacheDir(), filename); - - try (InputStream istream = reactContext.getContentResolver().openInputStream(uri); - OutputStream ostream = new FileOutputStream(file)) { - - byte[] buf = new byte[64 * 1024]; - int len; - - while ((len = istream.read(buf)) != -1) { - ostream.write(buf, 0, len); - } - - } catch (IOException ex) { - Log.w(TAG, "Error writing shared file " + uri.toString(), ex); - } - - return file; - } - - private String readFileFromUri(ReactContext reactContext, Uri uri) { - if (uri == null) return null; - - String filePath = null; - if (uri.getScheme().equals("content")) { - ContentResolver resolver = reactContext.getContentResolver(); - String mimeType = resolver.getType(uri); - String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType); - - // Load the filename from the resolver. - String filename = getFileNameFromResolver(resolver, uri, extension); - - // Now load the file itself. - File file = saveFileToCache(reactContext, uri, filename); - filePath = file.getPath(); - } else { - filePath = uri.getPath(); - } - return filePath; - } - - private class IntentEmitter { - private final Intent intent; - - private IntentEmitter(Intent intent) { - this.intent = intent; - } - - public void emit() { - - // Here we are just reading from the notification bundle. - // If other sources start the app, we can get their intent data the same way. - Bundle bundleFromNotification = intent.getBundleExtra("notification"); - intent.removeExtra("notification"); - - String action = intent.getAction(); - - Uri [] uris_ = null; - if (Intent.ACTION_SEND_MULTIPLE.equals(action)) { - ArrayList alUri = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); - uris_ = alUri.toArray(new Uri[0]); - } else if (Intent.ACTION_SEND.equals(action)) { - Uri oneUri = intent.getParcelableExtra(Intent.EXTRA_STREAM); - uris_ = new Uri[]{oneUri}; - } - intent.removeExtra(Intent.EXTRA_STREAM); - final Uri [] uris = uris_; - - String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT); - intent.removeExtra(Intent.EXTRA_SUBJECT); - - String text = intent.getStringExtra(Intent.EXTRA_TEXT); - intent.removeExtra(Intent.EXTRA_TEXT); - - StringBuilder sb = new StringBuilder(); - if (subject != null) { - sb.append(subject); - } - if (subject != null && text != null){ - sb.append(" "); - } - if (text != null) { - sb.append(text); - } - String textPayload = sb.toString(); - - String[] filePaths; - if (uris != null) { - ArrayList filePathList = new ArrayList(); - for (Uri uri : uris) { - String filePath = readFileFromUri(getReactContext(), uri); - - if (filePath != null) { - filePathList.add(filePath); - } - } - filePaths = filePathList.toArray(new String[0]); - } else { - filePaths = new String[0]; - } - if (bundleFromNotification != null) { - setInitialBundleFromNotification(bundleFromNotification); - } else if (filePaths.length != 0) { - setInitialShareFileUrls(filePaths); - } else if (textPayload.length() > 0){ - setInitialShareText(textPayload); - } - - // Closure like class so we can keep our emit logic together - class Emit { - private final ReactContext context; - private DeviceEventManagerModule.RCTDeviceEventEmitter emitter; - - Emit(DeviceEventManagerModule.RCTDeviceEventEmitter emitter, ReactContext context) { - this.emitter = emitter; - this.context = context; - } - - private void run() { - ReactContext context = getReactContext(); - if (context == null) { - return; - } - // assert emitter != null; - // If there are any other bundle sources we care about, emit them here - if (bundleFromNotification != null) { - emitter.emit("initialIntentFromNotification", Arguments.fromBundle(bundleFromNotification)); - } - - if (filePaths.length != 0) { - WritableMap args = Arguments.createMap(); - WritableArray lPaths = Arguments.createArray(); - for (String path : filePaths) { - lPaths.pushString(path); - } - args.putArray("localPaths", lPaths); - emitter.emit("onShareData", args); - } else if (textPayload.length() > 0) { - WritableMap args = Arguments.createMap(); - args.putString("text", textPayload); - emitter.emit("onShareData", args); - } - } - } - - // We need to run this on the main thread, as the React code assumes that is true. - // Namely, DevServerHelper constructs a Handler() without a Looper, which triggers: - // "Can't create handler inside thread that has not called Looper.prepare()" - Handler handler = new Handler(Looper.getMainLooper()); - handler.post(() -> { - // Construct and load our normal React JS code bundle - ReactInstanceManager reactInstanceManager = ((ReactApplication) getApplication()).getReactNativeHost().getReactInstanceManager(); - ReactContext context = reactInstanceManager.getCurrentReactContext(); - - // If it's constructed, send a notification - if (context != null) { - DeviceEventManagerModule.RCTDeviceEventEmitter emitter = context - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class); - (new Emit(emitter, context)).run(); - - } else { - // Otherwise wait for construction, then send the notification - reactInstanceManager.addReactInstanceEventListener(rctContext -> { - DeviceEventManagerModule.RCTDeviceEventEmitter emitter = rctContext - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class); - (new Emit(emitter, rctContext)).run(); - }); - if (!reactInstanceManager.hasStartedCreatingInitialContext()) { - // Construct it in the background - reactInstanceManager.createReactContextInBackground(); - } - } - }); - } - } - - @Override - protected void onResume() { - NativeLogger.info("Activity onResume"); - super.onResume(); - Keybase.setAppStateForeground(); - // Emit the intent data to JS - Intent intent = getIntent(); - if (intent != null) { - (new IntentEmitter(intent)).emit(); - } - } - - @Override - protected void onStart() { - NativeLogger.info("Activity onStart"); - super.onStart(); - Keybase.setAppStateForeground(); - } - - @Override - protected void onDestroy() { - NativeLogger.info("Activity onDestroy"); - super.onDestroy(); - Keybase.appWillExit(new KBPushNotifier(this, new Bundle())); - } - - @Override - public void onNewIntent(Intent intent) { - super.onNewIntent(intent); - setIntent(intent); - } - - /** - * Returns the name of the main component registered from JavaScript. This is - * used to schedule rendering of the component. - */ - @Override - protected String getMainComponentName() { - return "Keybase"; - } - - /** - * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link - * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React - * (aka React 18) with two boolean flags. - */ - @Override - protected ReactActivityDelegate createReactActivityDelegate() { - return new DefaultReactActivityDelegate( - this, - getMainComponentName(), - // If you opted-in for the New Architecture, we enable the Fabric Renderer. - DefaultNewArchitectureEntryPoint.getFabricEnabled() - ); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - ReactInstanceManager instanceManager = ((ReactApplication) getApplication()).getReactNativeHost().getReactInstanceManager(); - - try { - setBackgroundColor(GuiConfig.getInstance(getFilesDir()).getDarkMode()); - } catch (Exception e) {} - - if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) { - isUsingHardwareKeyboard = true; - } else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) { - isUsingHardwareKeyboard = false; - } - } - - public void setBackgroundColor(DarkModePreference pref) { - final int bgColor; - if (pref == DarkModePreference.System) { - bgColor = this.colorSchemeForCurrentConfiguration().equals("light") ? R.color.white : R.color.black; - } else if (pref == DarkModePreference.AlwaysDark) { - bgColor = R.color.black; - } else { - bgColor = R.color.white; - } - final Window mainWindow = this.getWindow(); - Handler handler = new Handler(Looper.getMainLooper()); - // Run this on the main thread. - handler.post(() -> { - mainWindow.setBackgroundDrawableResource(bgColor); - }); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (isUsingHardwareKeyboard && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { - // Detects user pressing the enter key - if (event.getAction() == KeyEvent.ACTION_DOWN && !event.isShiftPressed()) { - // Enter is pressed - HWKeyboardEventModule.getInstance().keyPressed("enter"); - return true; - } - if (event.getAction() == KeyEvent.ACTION_DOWN && event.isShiftPressed()) { - // Shift-Enter is pressed - HWKeyboardEventModule.getInstance().keyPressed("shift-enter"); - return true; - } - } - return super.dispatchKeyEvent(event); - } - - private void updateIsUsingHardwareKeyboard() { - isUsingHardwareKeyboard = getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY; - } -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/MainActivity.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/MainActivity.kt new file mode 100644 index 000000000000..99c06c35cac6 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/MainActivity.kt @@ -0,0 +1,441 @@ +package io.keybase.ossifrage + +import android.annotation.TargetApi +import android.content.ContentResolver +import android.content.Context +import android.content.Intent +import android.content.res.Configuration +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.provider.MediaStore +import android.provider.Settings +import android.util.Log +import android.view.KeyEvent +import android.webkit.MimeTypeMap +import com.facebook.react.ReactActivity +import com.facebook.react.ReactActivityDelegate +import com.facebook.react.ReactApplication +import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.ReactContext +import com.facebook.react.bridge.WritableMap +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled +import com.facebook.react.defaults.DefaultReactActivityDelegate +import com.facebook.react.modules.core.DeviceEventManagerModule +import com.facebook.react.modules.core.PermissionListener +import com.github.emilioicai.hwkeyboardevent.HWKeyboardEventModule +import com.reactnativekb.DarkModePreference +import com.reactnativekb.GuiConfig +import io.keybase.ossifrage.modules.NativeLogger +import io.keybase.ossifrage.util.DNSNSFetcher +import io.keybase.ossifrage.util.VideoHelper +import keybase.Keybase +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.security.KeyStoreException +import java.security.NoSuchAlgorithmException +import java.security.cert.CertificateException +import java.util.UUID + +class MainActivity : ReactActivity() { + private val listener: PermissionListener? = null + private var isUsingHardwareKeyboard = false + var initialBundleFromNotification: Bundle? = null + get() { + val b = field + field = null + return b + } + private var shareFileUrls: Array? = null + private var shareText: String? = null + var initialShareFileUrls: Array? + get() { + val s = shareFileUrls + shareFileUrls = null + return s + } + set(urls) { + shareFileUrls = urls + } + var initialShareText: String? + get() { + val s = shareText + shareText = null + return s + } + set(text) { + shareText = text + } + + override fun invokeDefaultOnBackPressed() { + moveTaskToBack(true) + } + + private val reactContext: ReactContext? + get() { + val reactHost = (application as ReactApplication).reactHost + if (reactHost == null) { + NativeLogger.warn("react instance manager not ready") + return null + } + return reactHost.currentReactContext + } + + private fun colorSchemeForCurrentConfiguration(): String { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK + when (currentNightMode) { + Configuration.UI_MODE_NIGHT_NO -> return "light" + Configuration.UI_MODE_NIGHT_YES -> return "dark" + } + } + return "light" + } + + @TargetApi(Build.VERSION_CODES.KITKAT) + override fun onCreate(savedInstanceState: Bundle?) { + NativeLogger.info("Activity onCreate") + setupKBRuntime(this, true) + super.onCreate(null) + Handler(Looper.getMainLooper()).postDelayed({ + try { + var gc = GuiConfig.getInstance(filesDir) + if (gc != null) { + setBackgroundColor(gc.getDarkMode()) + } + } catch (e: Exception) { + } + }, 300) + KeybasePushNotificationListenerService.createNotificationChannel(this) + updateIsUsingHardwareKeyboard() + handleIntent(intent) + } + + + override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { + return if (BuildConfig.DEBUG && keyCode == KeyEvent.KEYCODE_VOLUME_UP) { + super.onKeyUp(KeyEvent.KEYCODE_MENU, null) + } else super.onKeyUp(keyCode, event) + } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + listener?.onRequestPermissionsResult(requestCode, permissions, grantResults) + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + } + + override fun onPause() { + NativeLogger.info("Activity onPause") + super.onPause() + if (Keybase.appDidEnterBackground()) { + Keybase.appBeginBackgroundTaskNonblock(KBPushNotifier(this, Bundle())) + } else { + Keybase.setAppStateBackground() + } + } + + private fun getFileNameFromResolver(resolver: ContentResolver, uri: Uri, extension: String?): String { + // Use a GUID default. + var filename = String.format("%s.%s", UUID.randomUUID().toString(), extension) + val nameProjection = arrayOf(MediaStore.MediaColumns.DISPLAY_NAME) + resolver.query(uri, nameProjection, null, null, null).use { cursor -> + if (cursor != null && cursor.moveToFirst()) { + filename = cursor.getString(0) + } + } + val cut = filename.lastIndexOf('/') + if (cut != -1) { + filename = filename.substring(cut + 1) + } + return filename + } + + private fun saveFileToCache(reactContext: ReactContext?, uri: Uri, filename: String): File { + val file = File(reactContext!!.cacheDir, filename) + try { + reactContext.contentResolver.openInputStream(uri).use { istream -> + FileOutputStream(file).use { ostream -> + val buf = ByteArray(64 * 1024) + var len: Int + while (istream!!.read(buf).also { len = it } != -1) { + ostream.write(buf, 0, len) + } + } + } + } catch (ex: IOException) { + Log.w(TAG, "Error writing shared file $uri", ex) + } + return file + } + + private fun readFileFromUri(reactContext: ReactContext?, uri: Uri?): String? { + if (uri == null) return null + var filePath: String? + filePath = if (uri.scheme == "content") { + val resolver = reactContext!!.contentResolver + val mimeType = resolver.getType(uri) + val extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType) + + // Load the filename from the resolver. + val filename = getFileNameFromResolver(resolver, uri, extension) + + // Now load the file itself. + val file = saveFileToCache(reactContext, uri, filename) + file.path + } else { + uri.path + } + return filePath + } + + + fun onReactContextInitialized(context: ReactContext?) { + val emitter = reactContext?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) + if (emitter == null) { + Log.w(TAG, "Error no emitter onReactContextInitialized") + return + } + if (onShareDataPayload != null) { + emitter.emit("onShareData", onShareDataPayload) + onShareDataPayload = null + } + + if (initialIntentFromNotificationPayload != null) { + emitter.emit( + "initialIntentFromNotification", + initialIntentFromNotificationPayload + ) + initialIntentFromNotificationPayload = null + } + } + + override fun onResume() { + NativeLogger.info("Activity onResume") + super.onResume() + Keybase.setAppStateForeground() + } + + override fun onStart() { + NativeLogger.info("Activity onStart") + super.onStart() + Keybase.setAppStateForeground() + } + + override fun onDestroy() { + NativeLogger.info("Activity onDestroy") + super.onDestroy() + Keybase.appWillExit(KBPushNotifier(this, Bundle())) + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + handleIntent(intent) + } + + private fun handleIntent(intent: Intent?) { + if (intent == null) { + return + } + // Here we are just reading from the notification bundle. + // If other sources start the app, we can get their intent data the same way. + val bundleFromNotification = intent.getBundleExtra("notification") + intent.removeExtra("notification") + val action = intent.action + var uris_: Array? = null + if (Intent.ACTION_SEND_MULTIPLE == action) { + val alUri = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM) + uris_ = alUri!!.toTypedArray() + } else if (Intent.ACTION_SEND == action) { + val oneUri = intent.getParcelableExtra(Intent.EXTRA_STREAM) + uris_ = arrayOf(oneUri) + } + intent.removeExtra(Intent.EXTRA_STREAM) + val uris = uris_ + val subject = intent.getStringExtra(Intent.EXTRA_SUBJECT) + intent.removeExtra(Intent.EXTRA_SUBJECT) + val text = intent.getStringExtra(Intent.EXTRA_TEXT) + intent.removeExtra(Intent.EXTRA_TEXT) + val sb = StringBuilder() + if (subject != null) { + sb.append(subject) + } + if (subject != null && text != null) { + sb.append(" ") + } + if (text != null) { + sb.append(text) + } + val textPayload = sb.toString() + /*val filePaths = if (uris != null) Arrays.stream(uris) + .map { uri: Uri? -> readFileFromUri(reactContext, uri) } + .filter { obj: String? -> Objects.nonNull(obj) } + .toArray { _Dummy_.__Array__() } else arrayOfNulls(0) + + */ + // TODO check this works + val filePaths = uris?.mapNotNull { uri -> + readFileFromUri(reactContext, uri) + }?.toTypedArray() ?: emptyArray() + if (bundleFromNotification != null) { + initialBundleFromNotification = bundleFromNotification + } else if (filePaths.size != 0) { + initialShareFileUrls = filePaths + } else if (textPayload.length > 0) { + initialShareText = textPayload + } + + val emitter = reactContext?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) + // assert emitter != null; + // If there are any other bundle sources we care about, emit them here + if (bundleFromNotification != null) { + var payload = Arguments.fromBundle(bundleFromNotification) + if (emitter != null) { + initialIntentFromNotificationPayload = null + emitter.emit( + "initialIntentFromNotification", + payload + ) + } else { + initialIntentFromNotificationPayload = payload + } + } + if (filePaths.size != 0) { + val args = Arguments.createMap() + val lPaths = Arguments.createArray() + for (path in filePaths) { + lPaths.pushString(path) + } + args.putArray("localPaths", lPaths) + if (emitter != null) { + onShareDataPayload = null + emitter.emit("onShareData", args) + } else { + onShareDataPayload = args + } + } else if (textPayload.length > 0) { + val args = Arguments.createMap() + args.putString("text", textPayload) + if (emitter != null) { + onShareDataPayload = null + emitter.emit("onShareData", args) + } else { + onShareDataPayload = args + } + } + } + + var onShareDataPayload: WritableMap? = null + var initialIntentFromNotificationPayload: WritableMap? = null + + override fun getMainComponentName(): String = "Keybase" + + override fun createReactActivityDelegate(): ReactActivityDelegate { + return DefaultReactActivityDelegate( + this, + mainComponentName, // If you opted-in for the New Architecture, we enable the Fabric Renderer. + fabricEnabled + ) + } + + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + try { + var gc = GuiConfig.getInstance(filesDir) + if (gc != null) { + setBackgroundColor(gc.getDarkMode()) + } + } catch (e: Exception) { + } + if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) { + isUsingHardwareKeyboard = true + } else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) { + isUsingHardwareKeyboard = false + } + } + + fun setBackgroundColor(pref: DarkModePreference) { + val bgColor: Int + bgColor = if (pref == DarkModePreference.System) { + if (colorSchemeForCurrentConfiguration() == "light") R.color.white else R.color.black + } else if (pref == DarkModePreference.AlwaysDark) { + R.color.black + } else { + R.color.white + } + val mainWindow = this.window + val handler = Handler(Looper.getMainLooper()) + // Run this on the main thread. + handler.post { mainWindow.setBackgroundDrawableResource(bgColor) } + } + + override fun dispatchKeyEvent(event: KeyEvent): Boolean { + if (isUsingHardwareKeyboard && event.keyCode == KeyEvent.KEYCODE_ENTER) { + // Detects user pressing the enter key + if (event.action == KeyEvent.ACTION_DOWN && !event.isShiftPressed) { + // Enter is pressed + HWKeyboardEventModule.getInstance().keyPressed("enter") + return true + } + if (event.action == KeyEvent.ACTION_DOWN && event.isShiftPressed) { + // Shift-Enter is pressed + HWKeyboardEventModule.getInstance().keyPressed("shift-enter") + return true + } + } + return super.dispatchKeyEvent(event) + } + + private fun updateIsUsingHardwareKeyboard() { + isUsingHardwareKeyboard = resources.configuration.keyboard == Configuration.KEYBOARD_QWERTY + } + + companion object { + private val TAG = MainActivity::class.java.name + var createdReact = false + private fun createDummyFile(context: Context) { + val dummyFile = File(context.filesDir, "dummy.txt") + try { + if (dummyFile.createNewFile()) { + dummyFile.setWritable(true) + FileOutputStream(dummyFile).use { stream -> stream.write("hi".toByteArray()) } + } else { + Log.d(TAG, "dummy.txt exists") + } + } catch (e: Exception) { + NativeLogger.error("Exception in createDummyFile", e) + } + } + + // Is this a robot controlled test device? (i.e. pre-launch report?) + fun isTestDevice(context: Context): Boolean { + val testLabSetting = Settings.System.getString(context.contentResolver, "firebase.test.lab") + return "true" == testLabSetting + } + + @JvmStatic + fun setupKBRuntime(context: Context, shouldCreateDummyFile: Boolean) { + try { + Keybase.setGlobalExternalKeyStore(KeyStore(context, context.getSharedPreferences("KeyStore", MODE_PRIVATE))) + } catch (e: KeyStoreException) { + NativeLogger.error("Exception in MainActivity.onCreate", e) + } catch (e: CertificateException) { + NativeLogger.error("Exception in MainActivity.onCreate", e) + } catch (e: IOException) { + NativeLogger.error("Exception in MainActivity.onCreate", e) + } catch (e: NoSuchAlgorithmException) { + NativeLogger.error("Exception in MainActivity.onCreate", e) + } + if (shouldCreateDummyFile) { + createDummyFile(context) + } + val mobileOsVersion = Integer.toString(Build.VERSION.SDK_INT) + val isIPad = false + val isIOS = false + Keybase.initOnce(context.filesDir.path, "", context.getFileStreamPath("service.log").absolutePath, "prod", false, + DNSNSFetcher(), VideoHelper(), mobileOsVersion, isIPad, KBInstallReferrerListener(context), isIOS) + } + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/MainApplication.java b/shared/android/app/src/main/java/io/keybase/ossifrage/MainApplication.java deleted file mode 100644 index 92be3b54068a..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/MainApplication.java +++ /dev/null @@ -1,154 +0,0 @@ -package io.keybase.ossifrage; - -import android.os.Build; -import android.content.res.Configuration; -import expo.modules.ApplicationLifecycleDispatcher; -import expo.modules.ReactNativeHostWrapper; -import android.app.Application; -import android.content.Context; - -import androidx.multidex.MultiDex; -import androidx.work.PeriodicWorkRequest; -import androidx.work.WorkManager; -import androidx.work.WorkRequest; - -import com.facebook.react.ReactInstanceManager; -import com.facebook.react.PackageList; -import com.facebook.react.ReactApplication; -import com.facebook.react.ReactNativeHost; -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; -import com.facebook.react.defaults.DefaultReactNativeHost; -import com.facebook.soloader.SoLoader; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import io.keybase.ossifrage.modules.BackgroundSyncWorker; -import io.keybase.ossifrage.modules.NativeLogger; -import io.keybase.ossifrage.modules.StorybookConstants; -import androidx.lifecycle.ProcessLifecycleOwner; -import androidx.lifecycle.DefaultLifecycleObserver; -import androidx.lifecycle.LifecycleOwner; -import androidx.annotation.NonNull; -import com.bumptech.glide.Glide; - -import static keybase.Keybase.forceGC; - -class AppLifecycleListener implements DefaultLifecycleObserver { - private final Context context; - public AppLifecycleListener (Context c) { - this.context = c; - } - @Override - public void onStop(LifecycleOwner owner) { // app moved to background - new Thread(new Runnable() { - @Override - public void run() { - Glide.get(context).clearDiskCache(); - } - }).start(); - } -} - -public class MainApplication extends Application implements ReactApplication { - private final ReactNativeHost mReactNativeHost = new DefaultReactNativeHost(this) { - @Override - public boolean getUseDeveloperSupport() { - return BuildConfig.DEBUG; - } - - @Override - protected List getPackages() { - //@SuppressWarnings("UnnecessaryLocalVariable") - List packages = new PackageList(this).getPackages(); - packages.add(new KBReactPackage() { - @Override - public List createNativeModules(ReactApplicationContext reactApplicationContext) { - if (BuildConfig.BUILD_TYPE == "storyBook") { - List modules = new ArrayList<>(); - modules.add(new StorybookConstants(reactApplicationContext)); - return modules; - } else { - return super.createNativeModules(reactApplicationContext); - } - } - }); - - return packages; - } - - @Override - protected String getJSMainModuleName() { - return "index"; - } - - @Override - protected boolean isNewArchEnabled() { - return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; - } - @Override - protected Boolean isHermesEnabled() { - return BuildConfig.IS_HERMES_ENABLED; - } - }; - - @Override - public ReactNativeHost getReactNativeHost() { - return mReactNativeHost; - } - - @Override - public void onCreate() { - NativeLogger.info("MainApplication created"); - super.onCreate(); - SoLoader.init(this, /* native exopackage */ false); - if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { - // If you opted-in for the New Architecture, we load the native entry point for this app. - DefaultNewArchitectureEntryPoint.load(); - } - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { - ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); - } - - // KB - ApplicationLifecycleDispatcher.onApplicationCreate(this); - - ReactInstanceManager instanceManager = getReactNativeHost().getReactInstanceManager(); - if (instanceManager != null) { - ProcessLifecycleOwner.get().getLifecycle().addObserver( - new AppLifecycleListener(instanceManager.getCurrentReactContext()) - ); - } - - WorkRequest backgroundSyncRequest = - new PeriodicWorkRequest.Builder(BackgroundSyncWorker.class, - 1, TimeUnit.HOURS, - 15, TimeUnit.MINUTES) - .build(); - WorkManager - .getInstance(this) - .enqueue(backgroundSyncRequest); - } - - @Override - protected void attachBaseContext(Context base) { - super.attachBaseContext(base); - MultiDex.install(this); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig); - } - - @Override - public void onLowMemory() { - forceGC(); - super.onLowMemory(); - } -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/MainApplication.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/MainApplication.kt new file mode 100644 index 000000000000..edacff4d8bee --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/MainApplication.kt @@ -0,0 +1,104 @@ +package io.keybase.ossifrage + +import android.app.Application +import android.content.Context +import android.content.res.Configuration +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ProcessLifecycleOwner +import androidx.multidex.MultiDex +import androidx.work.PeriodicWorkRequest +import androidx.work.WorkManager +import androidx.work.WorkRequest +import com.bumptech.glide.Glide +import com.facebook.react.PackageList +import com.facebook.react.ReactApplication +import com.facebook.react.ReactHost +import com.facebook.react.ReactNativeHost +import com.facebook.react.ReactPackage +import com.facebook.react.bridge.ReactContext +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load +import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost +import com.facebook.react.defaults.DefaultReactNativeHost +import com.facebook.soloader.SoLoader +import expo.modules.ApplicationLifecycleDispatcher.onApplicationCreate +import expo.modules.ApplicationLifecycleDispatcher.onConfigurationChanged +import io.keybase.ossifrage.modules.BackgroundSyncWorker +import io.keybase.ossifrage.modules.NativeLogger +import keybase.Keybase +import java.util.concurrent.TimeUnit + +internal class AppLifecycleListener(private val context: Context?) : + DefaultLifecycleObserver { + override fun onStop(owner: LifecycleOwner) { // app moved to background + Thread { + try { + Glide.get(context!!).clearDiskCache() + } catch (e: Exception) { + } + }.start() + } +} + +class MainApplication : Application(), ReactApplication { + override val reactNativeHost: ReactNativeHost = object : DefaultReactNativeHost(this) { + override fun getPackages(): List { + val packages = PackageList(this).packages.toMutableList() + packages.add(KBReactPackage()) + return packages + } + + override fun getJSMainModuleName(): String = "index" + override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG + override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED + override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED + } + + override val reactHost: ReactHost + get() = getDefaultReactHost(applicationContext, reactNativeHost) + + + override fun onCreate() { + NativeLogger.info("MainApplication created") + super.onCreate() + SoLoader.init(this, /* native exopackage */false) + if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { + // If you opted-in for the New Architecture, we load the native entry point for this app. + load(bridgelessEnabled = true) + } + + // KB + onApplicationCreate(this) + + val backgroundSyncRequest: WorkRequest = PeriodicWorkRequest.Builder( + BackgroundSyncWorker::class.java, + 1, TimeUnit.HOURS, + 15, TimeUnit.MINUTES + ) + .build() + WorkManager + .getInstance(this) + .enqueue(backgroundSyncRequest) + } + + fun onReactContextInitialized(context: ReactContext?) { + ProcessLifecycleOwner.get().lifecycle.addObserver( + AppLifecycleListener(context) + ) + } + + override fun attachBaseContext(base: Context) { + super.attachBaseContext(base) + MultiDex.install(this) + } + + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + onConfigurationChanged(this, newConfig) + } + + override fun onLowMemory() { + Keybase.forceGC() + super.onLowMemory() + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/keystore/KeyStoreHelper.java b/shared/android/app/src/main/java/io/keybase/ossifrage/keystore/KeyStoreHelper.java deleted file mode 100644 index 9fb4f671ce6f..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/keystore/KeyStoreHelper.java +++ /dev/null @@ -1,64 +0,0 @@ -package io.keybase.ossifrage.keystore; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build; -import android.security.KeyChain; -import android.security.KeyPairGeneratorSpec; -import android.security.keystore.KeyGenParameterSpec; -import android.security.keystore.KeyInfo; -import android.security.keystore.KeyProperties; - -import java.math.BigInteger; -import java.security.InvalidAlgorithmParameterException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PrivateKey; -import java.security.spec.AlgorithmParameterSpec; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.RSAKeyGenParameterSpec; -import java.util.Calendar; - -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.security.auth.x500.X500Principal; - -public class KeyStoreHelper { - - @TargetApi(Build.VERSION_CODES.KITKAT) - public static void generateRSAKeyPair(Context ctx, String keyAlias) throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException { - KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"); - - final AlgorithmParameterSpec spec; - final Calendar endTime = Calendar.getInstance(); - endTime.add(Calendar.YEAR, 10); - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { - spec = new KeyGenParameterSpec.Builder( - keyAlias, - KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(KeyProperties.BLOCK_MODE_ECB) - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) - .setCertificateSerialNumber(BigInteger.ONE) - .setCertificateSubject(new X500Principal("CN=" + keyAlias)) - .setKeySize(2048) - .build(); - } else { - spec = new KeyPairGeneratorSpec.Builder(ctx) - .setAlias(keyAlias) - .setEncryptionRequired() - .setSerialNumber(BigInteger.ONE) - .setSubject(new X500Principal("CN=" + keyAlias)) - .setStartDate(Calendar.getInstance().getTime()) - .setEndDate(endTime.getTime()) - .setKeySize(2048) - .build(); - } - - kpg.initialize(spec); - KeyPair kp = kpg.generateKeyPair(); - } -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/keystore/KeyStoreHelper.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/keystore/KeyStoreHelper.kt new file mode 100644 index 000000000000..5cd423eeacde --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/keystore/KeyStoreHelper.kt @@ -0,0 +1,52 @@ +package io.keybase.ossifrage.keystore + +import android.annotation.TargetApi +import android.content.Context +import android.os.Build +import android.security.keystore.KeyGenParameterSpec +import android.security.keystore.KeyProperties +import java.math.BigInteger +import java.security.InvalidAlgorithmParameterException +import java.security.KeyPairGenerator +import java.security.KeyStoreException +import java.security.NoSuchAlgorithmException +import java.security.NoSuchProviderException +import java.security.spec.AlgorithmParameterSpec +import java.util.Calendar +import javax.security.auth.x500.X500Principal + +object KeyStoreHelper { + @TargetApi(Build.VERSION_CODES.KITKAT) + @Throws(KeyStoreException::class, NoSuchProviderException::class, NoSuchAlgorithmException::class, InvalidAlgorithmParameterException::class) + fun generateRSAKeyPair(ctx: Context?, keyAlias: String) { + val kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore") + val spec: AlgorithmParameterSpec + val endTime = Calendar.getInstance() + endTime.add(Calendar.YEAR, 10) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + spec = KeyGenParameterSpec.Builder( + keyAlias, + KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(KeyProperties.BLOCK_MODE_ECB) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) + .setCertificateSerialNumber(BigInteger.ONE) + .setCertificateSubject(X500Principal("CN=$keyAlias")) + .setKeySize(2048) + .build() + } else { + @Suppress("DEPRECATION") + spec = android.security.KeyPairGeneratorSpec.Builder(ctx!!) + .setAlias(keyAlias) + .setEncryptionRequired() + .setSerialNumber(BigInteger.ONE) + .setSubject(X500Principal("CN=$keyAlias")) + .setStartDate(Calendar.getInstance().time) + .setEndDate(endTime.time) + .setKeySize(2048) + .build() + } + kpg.initialize(spec) + kpg.generateKeyPair() + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/BackgroundSyncWorker.java b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/BackgroundSyncWorker.java deleted file mode 100644 index e829efa1061d..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/BackgroundSyncWorker.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.keybase.ossifrage.modules; - -import android.content.Context; -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.work.Worker; -import androidx.work.WorkerParameters; - -import keybase.Keybase; - -public class BackgroundSyncWorker extends Worker { - public static final String TAG = "background_sync_job"; - - public BackgroundSyncWorker( - @NonNull Context context, - @NonNull WorkerParameters params) { - super(context, params); - } - - @Override - public Result doWork() { - Log.d(TAG, "Background sync start."); - Keybase.backgroundSync(); - Log.d(TAG, "Background sync complete."); - return Result.success(); - } -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/BackgroundSyncWorker.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/BackgroundSyncWorker.kt new file mode 100644 index 000000000000..f80fd27fcdf3 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/BackgroundSyncWorker.kt @@ -0,0 +1,22 @@ +package io.keybase.ossifrage.modules + +import android.content.Context +import android.util.Log +import androidx.work.Worker +import androidx.work.WorkerParameters +import keybase.Keybase + +class BackgroundSyncWorker( + context: Context, + params: WorkerParameters) : Worker(context, params) { + override fun doWork(): Result { + Log.d(TAG, "Background sync start.") + Keybase.backgroundSync() + Log.d(TAG, "Background sync complete.") + return Result.success() + } + + companion object { + const val TAG = "background_sync_job" + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/KillableModule.java b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/KillableModule.java deleted file mode 100644 index 8027d982950a..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/KillableModule.java +++ /dev/null @@ -1,5 +0,0 @@ -package io.keybase.ossifrage.modules; - -public interface KillableModule { - void destroy (); -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/KillableModule.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/KillableModule.kt new file mode 100644 index 000000000000..3265cf0173f1 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/KillableModule.kt @@ -0,0 +1,5 @@ +package io.keybase.ossifrage.modules + +interface KillableModule { + fun destroy() +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/NativeLogger.java b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/NativeLogger.java deleted file mode 100644 index 8bb34340c18c..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/NativeLogger.java +++ /dev/null @@ -1,58 +0,0 @@ -package io.keybase.ossifrage.modules; - -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.WritableArray; - -public class NativeLogger extends ReactContextBaseJavaModule { - private static final String NAME = "NativeLogger"; - private static final String RN_NAME = "ReactNativeJS"; - - private static void rawLog(String tag, String jsonLog) { - Log.i(tag + NAME, jsonLog); - } - - private static String formatLine(String tagPrefix, String toLog) { - // Copies the Style JS outputs in native/logger.native.tsx - return tagPrefix + NAME + ": [" + System.currentTimeMillis() + ",\"" + toLog + "\"]"; - } - - public static void error(String log) { - Log.e(RN_NAME, formatLine("e", log)); - } - - public static void error(String log, Throwable tr) { - Log.e(RN_NAME, formatLine("e", log + Log.getStackTraceString(tr))); - } - - public static void info(String log) { - Log.i(RN_NAME, formatLine("i", log)); - } - - public static void info(String log, Throwable tr) { - Log.i(RN_NAME, formatLine("i", log + Log.getStackTraceString(tr))); - } - - public static void warn(String log) { - Log.i(RN_NAME, formatLine("w", log)); - } - - public static void warn(String log, Throwable tr) { - Log.i(RN_NAME, formatLine("w", log + Log.getStackTraceString(tr))); - } - - public NativeLogger(final ReactApplicationContext reactContext) { - super(reactContext); - } - - @Override - public String getName() { - return NAME; - } -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/NativeLogger.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/NativeLogger.kt new file mode 100644 index 000000000000..c185214df84c --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/NativeLogger.kt @@ -0,0 +1,48 @@ +package io.keybase.ossifrage.modules + +import android.util.Log +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReactContextBaseJavaModule + +class NativeLogger(reactContext: ReactApplicationContext?) : ReactContextBaseJavaModule(reactContext) { + override fun getName(): String { + return NAME + } + + companion object { + private const val NAME = "NativeLogger" + private const val RN_NAME = "ReactNativeJS" + private fun rawLog(tag: String, jsonLog: String) { + Log.i(tag + NAME, jsonLog) + } + + private fun formatLine(tagPrefix: String, toLog: String): String { + // Copies the Style JS outputs in native/logger.native.tsx + return tagPrefix + NAME + ": [" + System.currentTimeMillis() + ",\"" + toLog + "\"]" + } + + fun error(log: String) { + Log.e(RN_NAME, formatLine("e", log)) + } + + fun error(log: String, tr: Throwable?) { + Log.e(RN_NAME, formatLine("e", log + Log.getStackTraceString(tr))) + } + + fun info(log: String) { + Log.i(RN_NAME, formatLine("i", log)) + } + + fun info(log: String, tr: Throwable?) { + Log.i(RN_NAME, formatLine("i", log + Log.getStackTraceString(tr))) + } + + fun warn(log: String) { + Log.i(RN_NAME, formatLine("w", log)) + } + + fun warn(log: String, tr: Throwable?) { + Log.i(RN_NAME, formatLine("w", log + Log.getStackTraceString(tr))) + } + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/StorybookConstants.java b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/StorybookConstants.java deleted file mode 100644 index 708abab6d475..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/StorybookConstants.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.keybase.ossifrage.modules; - -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; - -import java.util.HashMap; -import java.util.Map; - -import io.keybase.ossifrage.BuildConfig; - -public class StorybookConstants extends ReactContextBaseJavaModule { - public StorybookConstants(final ReactApplicationContext reactContext) { - super(reactContext); - } - - @Override - public Map getConstants() { - final boolean isStoryBook = BuildConfig.BUILD_TYPE == "storyBook"; - final Map constants = new HashMap<>(); - constants.put("isStorybook", isStoryBook); - return constants; - } - - @Override - public String getName() { - return "Storybook"; - } -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/modules/StorybookConstants.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/StorybookConstants.kt new file mode 100644 index 000000000000..e24f193135ab --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/modules/StorybookConstants.kt @@ -0,0 +1,18 @@ +package io.keybase.ossifrage.modules + +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReactContextBaseJavaModule +import io.keybase.ossifrage.BuildConfig + +class StorybookConstants(reactContext: ReactApplicationContext?) : ReactContextBaseJavaModule(reactContext) { + override fun getConstants(): Map? { + val isStoryBook = BuildConfig.BUILD_TYPE === "storyBook" + val constants: MutableMap = HashMap() + constants["isStorybook"] = isStoryBook + return constants + } + + override fun getName(): String { + return "Storybook" + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/util/DNSNSFetcher.java b/shared/android/app/src/main/java/io/keybase/ossifrage/util/DNSNSFetcher.java deleted file mode 100644 index f8652adab5de..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/util/DNSNSFetcher.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.keybase.ossifrage.util; - -import java.lang.reflect.Method; -import java.util.ArrayList; - -public class DNSNSFetcher implements keybase.ExternalDNSNSFetcher { - public byte[] getServers() { - try { - Class SystemProperties = Class.forName("android.os.SystemProperties"); - Method method = SystemProperties.getMethod("get", new Class[] { String.class }); - ArrayList servers = new ArrayList(); - for (String name : new String[] { "net.dns1", "net.dns2", "net.dns3", "net.dns4", }) { - String value = (String) method.invoke(null, name); - if (value != null && !"".equals(value) && !servers.contains(value)) - servers.add(value); - } - String srvStr = new String(); - for (int i = 0; i < servers.size(); i++) { - srvStr += servers.get(i); - if (i < servers.size()-1) { - srvStr+=","; - } - } - return srvStr.getBytes(); - } catch (Exception e) { - return "".getBytes(); - } - } -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/util/DNSNSFetcher.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/util/DNSNSFetcher.kt new file mode 100644 index 000000000000..e4206d6f3311 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/util/DNSNSFetcher.kt @@ -0,0 +1,27 @@ +package io.keybase.ossifrage.util + +import keybase.ExternalDNSNSFetcher + +class DNSNSFetcher : ExternalDNSNSFetcher { + override fun getServers(): ByteArray { + return try { + val SystemProperties = Class.forName("android.os.SystemProperties") + val method = SystemProperties.getMethod("get", *arrayOf>(String::class.java)) + val servers = ArrayList() + for (name in arrayOf("net.dns1", "net.dns2", "net.dns3", "net.dns4")) { + val value = method.invoke(null, name) as String? + if (value != null && "" != value && !servers.contains(value)) servers.add(value) + } + var srvStr = "" + for (i in servers.indices) { + srvStr += servers[i] + if (i < servers.size - 1) { + srvStr += "," + } + } + srvStr.toByteArray() + } catch (e: Exception) { + "".toByteArray() + } + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/util/DeviceLockType.java b/shared/android/app/src/main/java/io/keybase/ossifrage/util/DeviceLockType.java deleted file mode 100644 index 957e51af941e..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/util/DeviceLockType.java +++ /dev/null @@ -1,115 +0,0 @@ -package io.keybase.ossifrage.util; - -import android.app.admin.DevicePolicyManager; -import android.content.ContentResolver; -import android.os.Environment; -import android.provider.Settings; - -import java.io.File; - -/** - * Code to check if the device has some lockscreen setup. - * Adapted from: http://stackoverflow.com/questions/7768879/check-whether-lock-was-enabled-or-not - */ -public class DeviceLockType { - private final static String PASSWORD_TYPE_KEY = "lockscreen.password_type"; - - /** - * This constant means that android using some unlock method not described here. - * Possible new methods would be added in the future releases. - */ - public final static int SOMETHING_ELSE = 0; - - /** - * Android using "None" or "Slide" unlock method. It seems there is no way to determine which method exactly used. - * In both cases you'll get "PASSWORD_QUALITY_SOMETHING" and "LOCK_PATTERN_ENABLED" == 0. - */ - public final static int NONE_OR_SLIDER = 1; - - /** - * Android using "Face Unlock" with "Pattern" as additional unlock method. Android don't allow you to select - * "Face Unlock" without additional unlock method. - */ - public final static int FACE_WITH_PATTERN = 3; - - /** - * Android using "Face Unlock" with "PIN" as additional unlock method. Android don't allow you to select - * "Face Unlock" without additional unlock method. - */ - public final static int FACE_WITH_PIN = 4; - - /** - * Android using "Face Unlock" with some additional unlock method not described here. - * Possible new methods would be added in the future releases. Values from 5 to 8 reserved for this situation. - */ - public final static int FACE_WITH_SOMETHING_ELSE = 9; - - /** - * Android using "Pattern" unlock method. - */ - public final static int PATTERN = 10; - - /** - * Android using "PIN" unlock method. - */ - public final static int PIN = 11; - - /** - * Android using "Password" unlock method with password containing only letters. - */ - public final static int PASSWORD_ALPHABETIC = 12; - - /** - * Android using "Password" unlock method with password containing both letters and numbers. - */ - public final static int PASSWORD_ALPHANUMERIC = 13; - - /** - * Returns current unlock method as integer value. You can see all possible values above - * - * @param contentResolver we need to pass ContentResolver to Settings.Secure.getLong(...) and - * Settings.Secure.getInt(...) - * @return current unlock method as integer value - */ - public static int getCurrent(ContentResolver contentResolver) { - long mode = android.provider.Settings.Secure.getLong(contentResolver, PASSWORD_TYPE_KEY, - DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); - if (mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) { - if (android.provider.Settings.Secure.getInt(contentResolver, Settings.Secure.LOCK_PATTERN_ENABLED, 0) == 1) { - return PATTERN; - } else return NONE_OR_SLIDER; - } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) { - String dataDirPath = Environment.getDataDirectory().getAbsolutePath(); - if (nonEmptyFileExists(dataDirPath + "/system/gesture.key")) { - return FACE_WITH_PATTERN; - } else if (nonEmptyFileExists(dataDirPath + "/system/password.key")) { - return FACE_WITH_PIN; - } else return FACE_WITH_SOMETHING_ELSE; - } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC) { - return PASSWORD_ALPHANUMERIC; - } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC) { - return PASSWORD_ALPHABETIC; - } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) { - return PIN; - } else return SOMETHING_ELSE; - } - - private static boolean nonEmptyFileExists(String filename) { - File file = new File(filename); - return file.exists() && file.length() > 0; - } - - public static boolean isDeviceLockEnabled(ContentResolver contentResolver) { - switch (getCurrent(contentResolver)) { - case PIN: - case PASSWORD_ALPHANUMERIC: - case PASSWORD_ALPHABETIC: - case FACE_WITH_PIN: - case FACE_WITH_PATTERN: - case PATTERN: - return true; - default: - return false; - } - } -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/util/DeviceLockType.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/util/DeviceLockType.kt new file mode 100644 index 000000000000..649ce9328e2a --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/util/DeviceLockType.kt @@ -0,0 +1,108 @@ +package io.keybase.ossifrage.util + +import android.app.admin.DevicePolicyManager +import android.content.ContentResolver +import android.os.Environment +import android.provider.Settings +import java.io.File + +/** + * Code to check if the device has some lockscreen setup. + * Adapted from: http://stackoverflow.com/questions/7768879/check-whether-lock-was-enabled-or-not + */ +object DeviceLockType { + private const val PASSWORD_TYPE_KEY = "lockscreen.password_type" + + /** + * This constant means that android using some unlock method not described here. + * Possible new methods would be added in the future releases. + */ + const val SOMETHING_ELSE = 0 + + /** + * Android using "None" or "Slide" unlock method. It seems there is no way to determine which method exactly used. + * In both cases you'll get "PASSWORD_QUALITY_SOMETHING" and "LOCK_PATTERN_ENABLED" == 0. + */ + const val NONE_OR_SLIDER = 1 + + /** + * Android using "Face Unlock" with "Pattern" as additional unlock method. Android don't allow you to select + * "Face Unlock" without additional unlock method. + */ + const val FACE_WITH_PATTERN = 3 + + /** + * Android using "Face Unlock" with "PIN" as additional unlock method. Android don't allow you to select + * "Face Unlock" without additional unlock method. + */ + const val FACE_WITH_PIN = 4 + + /** + * Android using "Face Unlock" with some additional unlock method not described here. + * Possible new methods would be added in the future releases. Values from 5 to 8 reserved for this situation. + */ + const val FACE_WITH_SOMETHING_ELSE = 9 + + /** + * Android using "Pattern" unlock method. + */ + const val PATTERN = 10 + + /** + * Android using "PIN" unlock method. + */ + const val PIN = 11 + + /** + * Android using "Password" unlock method with password containing only letters. + */ + const val PASSWORD_ALPHABETIC = 12 + + /** + * Android using "Password" unlock method with password containing both letters and numbers. + */ + const val PASSWORD_ALPHANUMERIC = 13 + + /** + * Returns current unlock method as integer value. You can see all possible values above + * + * @param contentResolver we need to pass ContentResolver to Settings.Secure.getLong(...) and + * Settings.Secure.getInt(...) + * @return current unlock method as integer value + */ + fun getCurrent(contentResolver: ContentResolver?): Int { + val mode = Settings.Secure.getLong(contentResolver, PASSWORD_TYPE_KEY, + DevicePolicyManager.PASSWORD_QUALITY_SOMETHING.toLong()) + return if (mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING.toLong()) { + @Suppress("DEPRECATION") + if (Settings.Secure.getInt(contentResolver, Settings.Secure.LOCK_PATTERN_ENABLED, 0) == 1) { + PATTERN + } else NONE_OR_SLIDER + } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK.toLong()) { + val dataDirPath = Environment.getDataDirectory().absolutePath + if (nonEmptyFileExists("$dataDirPath/system/gesture.key")) { + FACE_WITH_PATTERN + } else if (nonEmptyFileExists("$dataDirPath/system/password.key")) { + FACE_WITH_PIN + } else FACE_WITH_SOMETHING_ELSE + } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC.toLong()) { + PASSWORD_ALPHANUMERIC + } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC.toLong()) { + PASSWORD_ALPHABETIC + } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC.toLong()) { + PIN + } else SOMETHING_ELSE + } + + private fun nonEmptyFileExists(filename: String): Boolean { + val file = File(filename) + return file.exists() && file.length() > 0 + } + + fun isDeviceLockEnabled(contentResolver: ContentResolver?): Boolean { + return when (getCurrent(contentResolver)) { + PIN, PASSWORD_ALPHANUMERIC, PASSWORD_ALPHABETIC, FACE_WITH_PIN, FACE_WITH_PATTERN, PATTERN -> true + else -> false + } + } +} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/util/SharedFileProvider.java b/shared/android/app/src/main/java/io/keybase/ossifrage/util/SharedFileProvider.java deleted file mode 100644 index 82d6b0d483d1..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/util/SharedFileProvider.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.keybase.ossifrage.util; - -import androidx.core.content.FileProvider; - -public class SharedFileProvider extends FileProvider { -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/util/SharedFileProvider.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/util/SharedFileProvider.kt new file mode 100644 index 000000000000..d489a059efc4 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/util/SharedFileProvider.kt @@ -0,0 +1,5 @@ +package io.keybase.ossifrage.util + +import androidx.core.content.FileProvider + +class SharedFileProvider : FileProvider() diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/util/VideoHelper.java b/shared/android/app/src/main/java/io/keybase/ossifrage/util/VideoHelper.java deleted file mode 100644 index 2ef62ec5faec..000000000000 --- a/shared/android/app/src/main/java/io/keybase/ossifrage/util/VideoHelper.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.keybase.ossifrage.util; - -import android.media.MediaMetadataRetriever; -import android.graphics.Bitmap; -import java.io.ByteArrayOutputStream; - -public class VideoHelper implements keybase.NativeVideoHelper { - public byte[] thumbnail(String filename) { - try { - MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - retriever.setDataSource(filename); - Bitmap bmp = retriever.getFrameAtTime(); - if (bmp == null) { - return new byte[0]; - } - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream); - byte[] ret = stream.toByteArray(); - retriever.release(); - return ret; - } catch(Exception e) { - return new byte[0]; - } - } - - public long duration(String filename) { - try { - MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - retriever.setDataSource(filename); - String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); - if (time == null) { - return 0; - } - int ret = Integer.parseInt(time); - retriever.release(); - return ret; - } catch (Exception e) { - return 0; - } - } -} diff --git a/shared/android/app/src/main/java/io/keybase/ossifrage/util/VideoHelper.kt b/shared/android/app/src/main/java/io/keybase/ossifrage/util/VideoHelper.kt new file mode 100644 index 000000000000..8bad323d3850 --- /dev/null +++ b/shared/android/app/src/main/java/io/keybase/ossifrage/util/VideoHelper.kt @@ -0,0 +1,37 @@ +package io.keybase.ossifrage.util + +import android.graphics.Bitmap +import android.media.MediaMetadataRetriever +import keybase.NativeVideoHelper +import java.io.ByteArrayOutputStream + +class VideoHelper : NativeVideoHelper { + override fun thumbnail(filename: String): ByteArray { + return try { + val retriever = MediaMetadataRetriever() + retriever.setDataSource(filename) + val bmp = retriever.frameAtTime ?: return ByteArray(0) + val stream = ByteArrayOutputStream() + bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream) + val ret = stream.toByteArray() + retriever.release() + ret + } catch (e: Exception) { + ByteArray(0) + } + } + + override fun duration(filename: String): Long { + return try { + val retriever = MediaMetadataRetriever() + retriever.setDataSource(filename) + val time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION) + ?: return 0 + val ret = time.toInt() + retriever.release() + ret.toLong() + } catch (e: Exception) { + 0 + } + } +} diff --git a/shared/android/app/src/release/java/io/keybase/ossifrage/ReactNativeFlipper.java b/shared/android/app/src/release/java/io/keybase/ossifrage/ReactNativeFlipper.java deleted file mode 100644 index 3e7a4fa1104e..000000000000 --- a/shared/android/app/src/release/java/io/keybase/ossifrage/ReactNativeFlipper.java +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - *

This source code is licensed under the MIT license found in the LICENSE file in the root - * directory of this source tree. - */ -package io.keybase.ossifrage; -import android.content.Context; -import com.facebook.react.ReactInstanceManager; -/** - * Class responsible of loading Flipper inside your React Native application. This is the release - * flavor of it so it's empty as we don't want to load Flipper. - */ -public class ReactNativeFlipper { - public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { - // Do nothing as we don't want to initialize Flipper on Release. - } -} diff --git a/shared/android/app/src/releaseUnsigned/java/io/keybase/ossifrage/ReactNativeFlipper.java b/shared/android/app/src/releaseUnsigned/java/io/keybase/ossifrage/ReactNativeFlipper.java deleted file mode 100644 index a859203dab0f..000000000000 --- a/shared/android/app/src/releaseUnsigned/java/io/keybase/ossifrage/ReactNativeFlipper.java +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - *

This source code is licensed under the MIT license found in the LICENSE file in the root - * directory of this source tree. - */ -package io.keybase.ossifrage; -import android.content.Context; -import com.facebook.react.ReactInstanceManager; -/** - * Class responsible of loading Flipper inside your React Native application. This is the release - * flavor of it so it's empty as we don't want to load Flipper. - */ -public class ReactNativeFlipper { - public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { - // Do nothing as we don't want to initialize Flipper on Release. - } -} - diff --git a/shared/android/build.gradle b/shared/android/build.gradle index dc1c42919c32..c410f8d390e4 100644 --- a/shared/android/build.gradle +++ b/shared/android/build.gradle @@ -1,14 +1,11 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { - buildToolsVersion = "33.0.0" - minSdkVersion = 21 - compileSdkVersion = 33 + buildToolsVersion = "34.0.0" + minSdkVersion = 23 + compileSdkVersion = 34 targetSdkVersion = 34 - kotlinVersion = "1.6.21" - - // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. - ndkVersion = "23.1.7779620" + ndkVersion = "26.1.10909125" + kotlinVersion = "1.9.24" } repositories { @@ -16,13 +13,36 @@ buildscript { mavenCentral() } dependencies { - classpath("com.google.gms:google-services:4.4.0") classpath("com.android.tools.build:gradle") classpath("com.facebook.react:react-native-gradle-plugin") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") + classpath("com.github.triplet.gradle:play-publisher:3.7.0") // To publish from gradle + classpath("com.google.gms:google-services:4.4.0") } } -plugins { - id 'org.jetbrains.kotlin.android' version '1.8.10' apply false +apply plugin: "com.facebook.react.rootproject" + +// fix expo-camera +allprojects { + repositories { + maven { + // expo-camera bundles a custom com.google.android:cameraview + url "$rootDir/../node_modules/expo-camera/android/maven" + } + + maven { + // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm + url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android')) + } + maven { + // Android JSC is installed from npm + url(new File(['node', '--print', "require.resolve('jsc-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), '../dist')) + } + + google() + mavenCentral() + maven { url 'https://www.jitpack.io' } + } } diff --git a/shared/android/gradle.properties b/shared/android/gradle.properties index 9e486ae28259..4d940c3edd93 100644 --- a/shared/android/gradle.properties +++ b/shared/android/gradle.properties @@ -1,12 +1,3 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m @@ -20,9 +11,6 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true -# Version of flipper SDK to use with React Native -# Updating flipper can cause android to crash on start. be careful updating! -FLIPPER_VERSION=0.182.0 # Use this property to specify which architecture you want to build. # You can also override it from the CLI using # ./gradlew -PreactNativeArchitectures=x86_64 diff --git a/shared/android/gradle/wrapper/gradle-wrapper.jar b/shared/android/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa754578e88a3dae77fce6e3dea56edbf..e6441136f3d4ba8a0da8d277868979cfbc8ad796 100644 GIT binary patch literal 43453 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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

NnX)EH+Nua)3Y(c z&{(nX_ht=QbJ%DzAya}!&uNu!4V0xI)QE$SY__m)SAKcN0P(&JcoK*Lxr@P zY&P=}&B3*UWNlc|&$Oh{BEqwK2+N2U$4WB7Fd|aIal`FGANUa9E-O)!gV`((ZGCc$ zBJA|FFrlg~9OBp#f7aHodCe{6= zay$6vN~zj1ddMZ9gQ4p32(7wD?(dE>KA2;SOzXRmPBiBc6g`eOsy+pVcHu=;Yd8@{ zSGgXf@%sKKQz~;!J;|2fC@emm#^_rnO0esEn^QxXgJYd`#FPWOUU5b;9eMAF zZhfiZb|gk8aJIw*YLp4!*(=3l8Cp{(%p?ho22*vN9+5NLV0TTazNY$B5L6UKUrd$n zjbX%#m7&F#U?QNOBXkiiWB*_tk+H?N3`vg;1F-I+83{M2!8<^nydGr5XX}tC!10&e z7D36bLaB56WrjL&HiiMVtpff|K%|*{t*ltt^5ood{FOG0<>k&1h95qPio)2`eL${YAGIx(b4VN*~nKn6E~SIQUuRH zQ+5zP6jfnP$S0iJ@~t!Ai3o`X7biohli;E zT#yXyl{bojG@-TGZzpdVDXhbmF%F9+-^YSIv|MT1l3j zrxOFq>gd2%U}?6}8mIj?M zc077Zc9fq(-)4+gXv?Az26IO6eV`RAJz8e3)SC7~>%rlzDwySVx*q$ygTR5kW2ds- z!HBgcq0KON9*8Ff$X0wOq$`T7ml(@TF)VeoF}x1OttjuVHn3~sHrMB++}f7f9H%@f z=|kP_?#+fve@{0MlbkC9tyvQ_R?lRdRJ@$qcB(8*jyMyeME5ns6ypVI1Xm*Zr{DuS zZ!1)rQfa89c~;l~VkCiHI|PCBd`S*2RLNQM8!g9L6?n`^evQNEwfO@&JJRme+uopQX0%Jo zgd5G&#&{nX{o?TQwQvF1<^Cg3?2co;_06=~Hcb6~4XWpNFL!WU{+CK;>gH%|BLOh7@!hsa(>pNDAmpcuVO-?;Bic17R}^|6@8DahH)G z!EmhsfunLL|3b=M0MeK2vqZ|OqUqS8npxwge$w-4pFVXFq$_EKrZY?BuP@Az@(k`L z`ViQBSk`y+YwRT;&W| z2e3UfkCo^uTA4}Qmmtqs+nk#gNr2W4 zTH%hhErhB)pkXR{B!q5P3-OM+M;qu~f>}IjtF%>w{~K-0*jPVLl?Chz&zIdxp}bjx zStp&Iufr58FTQ36AHU)0+CmvaOpKF;W@sMTFpJ`j;3d)J_$tNQI^c<^1o<49Z(~K> z;EZTBaVT%14(bFw2ob@?JLQ2@(1pCdg3S%E4*dJ}dA*v}_a4_P(a`cHnBFJxNobAv zf&Zl-Yt*lhn-wjZsq<9v-IsXxAxMZ58C@e0!rzhJ+D@9^3~?~yllY^s$?&oNwyH!#~6x4gUrfxplCvK#!f z$viuszW>MFEcFL?>ux*((!L$;R?xc*myjRIjgnQX79@UPD$6Dz0jutM@7h_pq z0Zr)#O<^y_K6jfY^X%A-ip>P%3saX{!v;fxT-*0C_j4=UMH+Xth(XVkVGiiKE#f)q z%Jp=JT)uy{&}Iq2E*xr4YsJ5>w^=#-mRZ4vPXpI6q~1aFwi+lQcimO45V-JXP;>(Q zo={U`{=_JF`EQj87Wf}{Qy35s8r1*9Mxg({CvOt}?Vh9d&(}iI-quvs-rm~P;eRA@ zG5?1HO}puruc@S{YNAF3vmUc2B4!k*yi))<5BQmvd3tr}cIs#9)*AX>t`=~{f#Uz0 z0&Nk!7sSZwJe}=)-R^$0{yeS!V`Dh7w{w5rZ9ir!Z7Cd7dwZcK;BT#V0bzTt>;@Cl z#|#A!-IL6CZ@eHH!CG>OO8!%G8&8t4)Ro@}USB*k>oEUo0LsljsJ-%5Mo^MJF2I8- z#v7a5VdJ-Cd%(a+y6QwTmi+?f8Nxtm{g-+WGL>t;s#epv7ug>inqimZCVm!uT5Pf6 ziEgQt7^%xJf#!aPWbuC_3Nxfb&CFbQy!(8ANpkWLI4oSnH?Q3f?0k1t$3d+lkQs{~(>06l&v|MpcFsyAv zin6N!-;pggosR*vV=DO(#+}4ps|5$`udE%Kdmp?G7B#y%H`R|i8skKOd9Xzx8xgR$>Zo2R2Ytktq^w#ul4uicxW#{ zFjG_RNlBroV_n;a7U(KIpcp*{M~e~@>Q#Av90Jc5v%0c>egEdY4v3%|K1XvB{O_8G zkTWLC>OZKf;XguMH2-Pw{BKbFzaY;4v2seZV0>^7Q~d4O=AwaPhP3h|!hw5aqOtT@ z!SNz}$of**Bl3TK209@F=Tn1+mgZa8yh(Png%Zd6Mt}^NSjy)etQrF zme*llAW=N_8R*O~d2!apJnF%(JcN??=`$qs3Y+~xs>L9x`0^NIn!8mMRFA_tg`etw z3k{9JAjnl@ygIiJcNHTy02GMAvBVqEss&t2<2mnw!; zU`J)0>lWiqVqo|ex7!+@0i>B~BSU1A_0w#Ee+2pJx0BFiZ7RDHEvE*ptc9md(B{&+ zKE>TM)+Pd>HEmdJao7U@S>nL(qq*A)#eLOuIfAS@j`_sK0UEY6OAJJ-kOrHG zjHx`g!9j*_jRcJ%>CE9K2MVf?BUZKFHY?EpV6ai7sET-tqk=nDFh-(65rhjtlKEY% z@G&cQ<5BKatfdA1FKuB=i>CCC5(|9TMW%K~GbA4}80I5%B}(gck#Wlq@$nO3%@QP_ z8nvPkJFa|znk>V92cA!K1rKtr)skHEJD;k8P|R8RkCq1Rh^&}Evwa4BUJz2f!2=MH zo4j8Y$YL2313}H~F7@J7mh>u%556Hw0VUOz-Un@ZASCL)y8}4XXS`t1AC*^>PLwIc zUQok5PFS=*#)Z!3JZN&eZ6ZDP^-c@StY*t20JhCnbMxXf=LK#;`4KHEqMZ-Ly9KsS zI2VUJGY&PmdbM+iT)zek)#Qc#_i4uH43 z@T5SZBrhNCiK~~esjsO9!qBpaWK<`>!-`b71Y5ReXQ4AJU~T2Njri1CEp5oKw;Lnm)-Y@Z3sEY}XIgSy%xo=uek(kAAH5MsV$V3uTUsoTzxp_rF=tx zV07vlJNKtJhCu`b}*#m&5LV4TAE&%KtHViDAdv#c^x`J7bg z&N;#I2GkF@SIGht6p-V}`!F_~lCXjl1BdTLIjD2hH$J^YFN`7f{Q?OHPFEM$65^!u zNwkelo*5+$ZT|oQ%o%;rBX$+?xhvjb)SHgNHE_yP%wYkkvXHS{Bf$OiKJ5d1gI0j< zF6N}Aq=(WDo(J{e-uOecxPD>XZ@|u-tgTR<972`q8;&ZD!cep^@B5CaqFz|oU!iFj zU0;6fQX&~15E53EW&w1s9gQQ~Zk16X%6 zjG`j0yq}4deX2?Tr(03kg>C(!7a|b9qFI?jcE^Y>-VhudI@&LI6Qa}WQ>4H_!UVyF z((cm&!3gmq@;BD#5P~0;_2qgZhtJS|>WdtjY=q zLnHH~Fm!cxw|Z?Vw8*~?I$g#9j&uvgm7vPr#&iZgPP~v~BI4jOv;*OQ?jYJtzO<^y z7-#C={r7CO810!^s(MT!@@Vz_SVU)7VBi(e1%1rvS!?PTa}Uv`J!EP3s6Y!xUgM^8 z4f!fq<3Wer_#;u!5ECZ|^c1{|q_lh3m^9|nsMR1#Qm|?4Yp5~|er2?W^7~cl;_r4WSme_o68J9p03~Hc%X#VcX!xAu%1`R!dfGJCp zV*&m47>s^%Ib0~-2f$6oSgn3jg8m%UA;ArcdcRyM5;}|r;)?a^D*lel5C`V5G=c~k zy*w_&BfySOxE!(~PI$*dwG><+-%KT5p?whOUMA*k<9*gi#T{h3DAxzAPxN&Xws8o9Cp*`PA5>d9*Z-ynV# z9yY*1WR^D8|C%I@vo+d8r^pjJ$>eo|j>XiLWvTWLl(^;JHCsoPgem6PvegHb-OTf| zvTgsHSa;BkbG=(NgPO|CZu9gUCGr$8*EoH2_Z#^BnxF0yM~t`|9ws_xZ8X8iZYqh! zAh;HXJ)3P&)Q0(&F>!LN0g#bdbis-cQxyGn9Qgh`q+~49Fqd2epikEUw9caM%V6WgP)532RMRW}8gNS%V%Hx7apSz}tn@bQy!<=lbhmAH=FsMD?leawbnP5BWM0 z5{)@EEIYMu5;u)!+HQWhQ;D3_Cm_NADNeb-f56}<{41aYq8p4=93d=-=q0Yx#knGYfXVt z+kMxlus}t2T5FEyCN~!}90O_X@@PQpuy;kuGz@bWft%diBTx?d)_xWd_-(!LmVrh**oKg!1CNF&LX4{*j|) zIvjCR0I2UUuuEXh<9}oT_zT#jOrJAHNLFT~Ilh9hGJPI1<5`C-WA{tUYlyMeoy!+U zhA#=p!u1R7DNg9u4|QfED-2TuKI}>p#2P9--z;Bbf4Op*;Q9LCbO&aL2i<0O$ByoI z!9;Ght733FC>Pz>$_mw(F`zU?`m@>gE`9_p*=7o=7av`-&ifU(^)UU`Kg3Kw`h9-1 z6`e6+im=|m2v`pN(2dE%%n8YyQz;#3Q-|x`91z?gj68cMrHl}C25|6(_dIGk*8cA3 zRHB|Nwv{@sP4W+YZM)VKI>RlB`n=Oj~Rzx~M+Khz$N$45rLn6k1nvvD^&HtsMA4`s=MmuOJID@$s8Ph4E zAmSV^+s-z8cfv~Yd(40Sh4JG#F~aB>WFoX7ykaOr3JaJ&Lb49=B8Vk-SQT9%7TYhv z?-Pprt{|=Y5ZQ1?od|A<_IJU93|l4oAfBm?3-wk{O<8ea+`}u%(kub(LFo2zFtd?4 zwpN|2mBNywv+d^y_8#<$r>*5+$wRTCygFLcrwT(qc^n&@9r+}Kd_u@Ithz(6Qb4}A zWo_HdBj#V$VE#l6pD0a=NfB0l^6W^g`vm^sta>Tly?$E&{F?TTX~DsKF~poFfmN%2 z4x`Dc{u{Lkqz&y!33;X}weD}&;7p>xiI&ZUb1H9iD25a(gI|`|;G^NwJPv=1S5e)j z;U;`?n}jnY6rA{V^ zxTd{bK)Gi^odL3l989DQlN+Zs39Xe&otGeY(b5>rlIqfc7Ap4}EC?j<{M=hlH{1+d zw|c}}yx88_xQr`{98Z!d^FNH77=u(p-L{W6RvIn40f-BldeF-YD>p6#)(Qzf)lfZj z?3wAMtPPp>vMehkT`3gToPd%|D8~4`5WK{`#+}{L{jRUMt zrFz+O$C7y8$M&E4@+p+oV5c%uYzbqd2Y%SSgYy#xh4G3hQv>V*BnuKQhBa#=oZB~w{azUB+q%bRe_R^ z>fHBilnRTUfaJ201czL8^~Ix#+qOHSO)A|xWLqOxB$dT2W~)e-r9;bm=;p;RjYahB z*1hegN(VKK+ztr~h1}YP@6cfj{e#|sS`;3tJhIJK=tVJ-*h-5y9n*&cYCSdg#EHE# zSIx=r#qOaLJoVVf6v;(okg6?*L_55atl^W(gm^yjR?$GplNP>BZsBYEf_>wM0Lc;T zhf&gpzOWNxS>m+mN92N0{;4uw`P+9^*|-1~$uXpggj4- z^SFc4`uzj2OwdEVT@}Q`(^EcQ_5(ZtXTql*yGzdS&vrS_w>~~ra|Nb5abwf}Y!uq6R5f&6g2ge~2p(%c< z@O)cz%%rr4*cRJ5f`n@lvHNk@lE1a*96Kw6lJ~B-XfJW%?&-y?;E&?1AacU@`N`!O z6}V>8^%RZ7SQnZ-z$(jsX`amu*5Fj8g!3RTRwK^`2_QHe;_2y_n|6gSaGyPmI#kA0sYV<_qOZc#-2BO%hX)f$s-Z3xlI!ub z^;3ru11DA`4heAu%}HIXo&ctujzE2!6DIGE{?Zs>2}J+p&C$rc7gJC35gxhflorvsb%sGOxpuWhF)dL_&7&Z99=5M0b~Qa;Mo!j&Ti_kXW!86N%n= zSC@6Lw>UQ__F&+&Rzv?gscwAz8IP!n63>SP)^62(HK98nGjLY2*e^OwOq`3O|C92? z;TVhZ2SK%9AGW4ZavTB9?)mUbOoF`V7S=XM;#3EUpR+^oHtdV!GK^nXzCu>tpR|89 zdD{fnvCaN^^LL%amZ^}-E+214g&^56rpdc@yv0b<3}Ys?)f|fXN4oHf$six)-@<;W&&_kj z-B}M5U*1sb4)77aR=@%I?|Wkn-QJVuA96an25;~!gq(g1@O-5VGo7y&E_srxL6ZfS z*R%$gR}dyONgju*D&?geiSj7SZ@ftyA|}(*Y4KbvU!YLsi1EDQQCnb+-cM=K1io78o!v*);o<XwjaQH%)uIP&Zm?)Nfbfn;jIr z)d#!$gOe3QHp}2NBak@yYv3m(CPKkwI|{;d=gi552u?xj9ObCU^DJFQp4t4e1tPzM zvsRIGZ6VF+{6PvqsplMZWhz10YwS={?`~O0Ec$`-!klNUYtzWA^f9m7tkEzCy<_nS z=&<(awFeZvt51>@o_~>PLs05CY)$;}Oo$VDO)?l-{CS1Co=nxjqben*O1BR>#9`0^ zkwk^k-wcLCLGh|XLjdWv0_Hg54B&OzCE^3NCP}~OajK-LuRW53CkV~Su0U>zN%yQP zH8UH#W5P3-!ToO-2k&)}nFe`t+mdqCxxAHgcifup^gKpMObbox9LFK;LP3}0dP-UW z?Zo*^nrQ6*$FtZ(>kLCc2LY*|{!dUn$^RW~m9leoF|@Jy|M5p-G~j%+P0_#orRKf8 zvuu5<*XO!B?1E}-*SY~MOa$6c%2cM+xa8}_8x*aVn~57v&W(0mqN1W`5a7*VN{SUH zXz98DDyCnX2EPl-`Lesf`=AQT%YSDb`$%;(jUTrNen$NPJrlpPDP}prI>Ml!r6bCT;mjsg@X^#&<}CGf0JtR{Ecwd&)2zuhr#nqdgHj+g2n}GK9CHuwO zk>oZxy{vcOL)$8-}L^iVfJHAGfwN$prHjYV0ju}8%jWquw>}_W6j~m<}Jf!G?~r5&Rx)!9JNX!ts#SGe2HzobV5); zpj@&`cNcO&q+%*<%D7za|?m5qlmFK$=MJ_iv{aRs+BGVrs)98BlN^nMr{V_fcl_;jkzRju+c-y?gqBC_@J0dFLq-D9@VN&-`R9U;nv$Hg?>$oe4N&Ht$V_(JR3TG^! zzJsbQbi zFE6-{#9{G{+Z}ww!ycl*7rRdmU#_&|DqPfX3CR1I{Kk;bHwF6jh0opI`UV2W{*|nn zf_Y@%wW6APb&9RrbEN=PQRBEpM(N1w`81s=(xQj6 z-eO0k9=Al|>Ej|Mw&G`%q8e$2xVz1v4DXAi8G};R$y)ww638Y=9y$ZYFDM$}vzusg zUf+~BPX>(SjA|tgaFZr_e0{)+z9i6G#lgt=F_n$d=beAt0Sa0a7>z-?vcjl3e+W}+ z1&9=|vC=$co}-Zh*%3588G?v&U7%N1Qf-wNWJ)(v`iO5KHSkC5&g7CrKu8V}uQGcfcz zmBz#Lbqwqy#Z~UzHgOQ;Q-rPxrRNvl(&u6ts4~0=KkeS;zqURz%!-ERppmd%0v>iRlEf+H$yl{_8TMJzo0 z>n)`On|7=WQdsqhXI?#V{>+~}qt-cQbokEbgwV3QvSP7&hK4R{Z{aGHVS3;+h{|Hz z6$Js}_AJr383c_+6sNR|$qu6dqHXQTc6?(XWPCVZv=)D#6_;D_8P-=zOGEN5&?~8S zl5jQ?NL$c%O)*bOohdNwGIKM#jSAC?BVY={@A#c9GmX0=T(0G}xs`-%f3r=m6-cpK z!%waekyAvm9C3%>sixdZj+I(wQlbB4wv9xKI*T13DYG^T%}zZYJ|0$Oj^YtY+d$V$ zAVudSc-)FMl|54n=N{BnZTM|!>=bhaja?o7s+v1*U$!v!qQ%`T-6fBvmdPbVmro&d zk07TOp*KuxRUSTLRrBj{mjsnF8`d}rMViY8j`jo~Hp$fkv9F_g(jUo#Arp;Xw0M$~ zRIN!B22~$kx;QYmOkos@%|5k)!QypDMVe}1M9tZfkpXKGOxvKXB!=lo`p?|R1l=tA zp(1}c6T3Fwj_CPJwVsYtgeRKg?9?}%oRq0F+r+kdB=bFUdVDRPa;E~~>2$w}>O>v=?|e>#(-Lyx?nbg=ckJ#5U6;RT zNvHhXk$P}m9wSvFyU3}=7!y?Y z=fg$PbV8d7g25&-jOcs{%}wTDKm>!Vk);&rr;O1nvO0VrU&Q?TtYVU=ir`te8SLlS zKSNmV=+vF|ATGg`4$N1uS|n??f}C_4Sz!f|4Ly8#yTW-FBfvS48Tef|-46C(wEO_%pPhUC5$-~Y?!0vFZ^Gu`x=m7X99_?C-`|h zfmMM&Y@zdfitA@KPw4Mc(YHcY1)3*1xvW9V-r4n-9ZuBpFcf{yz+SR{ zo$ZSU_|fgwF~aakGr(9Be`~A|3)B=9`$M-TWKipq-NqRDRQc}ABo*s_5kV%doIX7LRLRau_gd@Rd_aLFXGSU+U?uAqh z8qusWWcvgQ&wu{|sRXmv?sl=xc<$6AR$+cl& zFNh5q1~kffG{3lDUdvEZu5c(aAG~+64FxdlfwY^*;JSS|m~CJusvi-!$XR`6@XtY2 znDHSz7}_Bx7zGq-^5{stTRy|I@N=>*y$zz>m^}^{d&~h;0kYiq8<^Wq7Dz0w31ShO^~LUfW6rfitR0(=3;Uue`Y%y@ex#eKPOW zO~V?)M#AeHB2kovn1v=n^D?2{2jhIQd9t|_Q+c|ZFaWt+r&#yrOu-!4pXAJuxM+Cx z*H&>eZ0v8Y`t}8{TV6smOj=__gFC=eah)mZt9gwz>>W$!>b3O;Rm^Ig*POZP8Rl0f zT~o=Nu1J|lO>}xX&#P58%Yl z83`HRs5#32Qm9mdCrMlV|NKNC+Z~ z9OB8xk5HJ>gBLi+m@(pvpw)1(OaVJKs*$Ou#@Knd#bk+V@y;YXT?)4eP9E5{J%KGtYinNYJUH9PU3A}66c>Xn zZ{Bn0<;8$WCOAL$^NqTjwM?5d=RHgw3!72WRo0c;+houoUA@HWLZM;^U$&sycWrFd zE7ekt9;kb0`lps{>R(}YnXlyGY}5pPd9zBpgXeJTY_jwaJGSJQC#-KJqmh-;ad&F- z-Y)E>!&`Rz!HtCz>%yOJ|v(u7P*I$jqEY3}(Z-orn4 zlI?CYKNl`6I){#2P1h)y(6?i;^z`N3bxTV%wNvQW+eu|x=kbj~s8rhCR*0H=iGkSj zk23lr9kr|p7#qKL=UjgO`@UnvzU)`&fI>1Qs7ubq{@+lK{hH* zvl6eSb9%yngRn^T<;jG1SVa)eA>T^XX=yUS@NCKpk?ovCW1D@!=@kn;l_BrG;hOTC z6K&H{<8K#dI(A+zw-MWxS+~{g$tI7|SfP$EYKxA}LlVO^sT#Oby^grkdZ^^lA}uEF zBSj$weBJG{+Bh@Yffzsw=HyChS(dtLE3i*}Zj@~!_T-Ay7z=B)+*~3|?w`Zd)Co2t zC&4DyB!o&YgSw+fJn6`sn$e)29`kUwAc+1MND7YjV%lO;H2}fNy>hD#=gT ze+-aFNpyKIoXY~Vq-}OWPBe?Rfu^{ps8>Xy%42r@RV#*QV~P83jdlFNgkPN=T|Kt7 zV*M`Rh*30&AWlb$;ae130e@}Tqi3zx2^JQHpM>j$6x`#{mu%tZlwx9Gj@Hc92IuY* zarmT|*d0E~vt6<+r?W^UW0&#U&)8B6+1+;k^2|FWBRP9?C4Rk)HAh&=AS8FS|NQaZ z2j!iZ)nbEyg4ZTp-zHwVlfLC~tXIrv(xrP8PAtR{*c;T24ycA-;auWsya-!kF~CWZ zw_uZ|%urXgUbc@x=L=_g@QJ@m#5beS@6W195Hn7>_}z@Xt{DIEA`A&V82bc^#!q8$ zFh?z_Vn|ozJ;NPd^5uu(9tspo8t%&-U9Ckay-s@DnM*R5rtu|4)~e)`z0P-sy?)kc zs_k&J@0&0!q4~%cKL)2l;N*T&0;mqX5T{Qy60%JtKTQZ-xb%KOcgqwJmb%MOOKk7N zgq})R_6**{8A|6H?fO+2`#QU)p$Ei2&nbj6TpLSIT^D$|`TcSeh+)}VMb}LmvZ{O| ze*1IdCt3+yhdYVxcM)Q_V0bIXLgr6~%JS<<&dxIgfL=Vnx4YHuU@I34JXA|+$_S3~ zy~X#gO_X!cSs^XM{yzDGNM>?v(+sF#<0;AH^YrE8smx<36bUsHbN#y57K8WEu(`qHvQ6cAZPo=J5C(lSmUCZ57Rj6cx!e^rfaI5%w}unz}4 zoX=nt)FVNV%QDJH`o!u9olLD4O5fl)xp+#RloZlaA92o3x4->?rB4`gS$;WO{R;Z3>cG3IgFX2EA?PK^M}@%1%A;?f6}s&CV$cIyEr#q5;yHdNZ9h{| z-=dX+a5elJoDo?Eq&Og!nN6A)5yYpnGEp}?=!C-V)(*~z-+?kY1Q7qs#Rsy%hu_60rdbB+QQNr?S1 z?;xtjUv|*E3}HmuNyB9aFL5H~3Ho0UsmuMZELp1a#CA1g`P{-mT?BchuLEtK}!QZ=3AWakRu~?f9V~3F;TV`5%9Pcs_$gq&CcU}r8gOO zC2&SWPsSG{&o-LIGTBqp6SLQZPvYKp$$7L4WRRZ0BR$Kf0I0SCFkqveCp@f)o8W)! z$%7D1R`&j7W9Q9CGus_)b%+B#J2G;l*FLz#s$hw{BHS~WNLODV#(!u_2Pe&tMsq={ zdm7>_WecWF#D=?eMjLj=-_z`aHMZ=3_-&E8;ibPmM}61i6J3is*=dKf%HC>=xbj4$ zS|Q-hWQ8T5mWde6h@;mS+?k=89?1FU<%qH9B(l&O>k|u_aD|DY*@~(`_pb|B#rJ&g zR0(~(68fpUPz6TdS@4JT5MOPrqDh5_H(eX1$P2SQrkvN8sTxwV>l0)Qq z0pzTuvtEAKRDkKGhhv^jk%|HQ1DdF%5oKq5BS>szk-CIke{%js?~%@$uaN3^Uz6Wf z_iyx{bZ(;9y4X&>LPV=L=d+A}7I4GkK0c1Xts{rrW1Q7apHf-))`BgC^0^F(>At1* za@e7{lq%yAkn*NH8Q1{@{lKhRg*^TfGvv!Sn*ed*x@6>M%aaqySxR|oNadYt1mpUZ z6H(rupHYf&Z z29$5g#|0MX#aR6TZ$@eGxxABRKakDYtD%5BmKp;HbG_ZbT+=81E&=XRk6m_3t9PvD zr5Cqy(v?gHcYvYvXkNH@S#Po~q(_7MOuCAB8G$a9BC##gw^5mW16cML=T=ERL7wsk zzNEayTG?mtB=x*wc@ifBCJ|irFVMOvH)AFRW8WE~U()QT=HBCe@s$dA9O!@`zAAT) zaOZ7l6vyR+Nk_OOF!ZlZmjoImKh)dxFbbR~z(cMhfeX1l7S_`;h|v3gI}n9$sSQ>+3@AFAy9=B_y$)q;Wdl|C-X|VV3w8 z2S#>|5dGA8^9%Bu&fhmVRrTX>Z7{~3V&0UpJNEl0=N32euvDGCJ>#6dUSi&PxFW*s zS`}TB>?}H(T2lxBJ!V#2taV;q%zd6fOr=SGHpoSG*4PDaiG0pdb5`jelVipkEk%FV zThLc@Hc_AL1#D&T4D=w@UezYNJ%0=f3iVRuVL5H?eeZM}4W*bomebEU@e2d`M<~uW zf#Bugwf`VezG|^Qbt6R_=U0}|=k;mIIakz99*>FrsQR{0aQRP6ko?5<7bkDN8evZ& zB@_KqQG?ErKL=1*ZM9_5?Pq%lcS4uLSzN(Mr5=t6xHLS~Ym`UgM@D&VNu8e?_=nSFtF$u@hpPSmI4Vo_t&v?>$~K4y(O~Rb*(MFy_igM7 z*~yYUyR6yQgzWnWMUgDov!!g=lInM+=lOmOk4L`O?{i&qxy&D*_qorRbDwj6?)!ef z#JLd7F6Z2I$S0iYI={rZNk*<{HtIl^mx=h>Cim*04K4+Z4IJtd*-)%6XV2(MCscPiw_a+y*?BKbTS@BZ3AUao^%Zi#PhoY9Vib4N>SE%4>=Jco0v zH_Miey{E;FkdlZSq)e<{`+S3W=*ttvD#hB8w=|2aV*D=yOV}(&p%0LbEWH$&@$X3x~CiF-?ejQ*N+-M zc8zT@3iwkdRT2t(XS`d7`tJQAjRmKAhiw{WOqpuvFp`i@Q@!KMhwKgsA}%@sw8Xo5Y=F zhRJZg)O4uqNWj?V&&vth*H#je6T}}p_<>!Dr#89q@uSjWv~JuW(>FqoJ5^ho0%K?E z9?x_Q;kmcsQ@5=}z@tdljMSt9-Z3xn$k)kEjK|qXS>EfuDmu(Z8|(W?gY6-l z@R_#M8=vxKMAoi&PwnaIYw2COJM@atcgfr=zK1bvjW?9B`-+Voe$Q+H$j!1$Tjn+* z&LY<%)L@;zhnJlB^Og6I&BOR-m?{IW;tyYC%FZ!&Z>kGjHJ6cqM-F z&19n+e1=9AH1VrVeHrIzqlC`w9=*zfmrerF?JMzO&|Mmv;!4DKc(sp+jy^Dx?(8>1 zH&yS_4yL7m&GWX~mdfgH*AB4{CKo;+egw=PrvkTaoBU+P-4u?E|&!c z)DKc;>$$B6u*Zr1SjUh2)FeuWLWHl5TH(UHWkf zLs>7px!c5n;rbe^lO@qlYLzlDVp(z?6rPZel=YB)Uv&n!2{+Mb$-vQl=xKw( zve&>xYx+jW_NJh!FV||r?;hdP*jOXYcLCp>DOtJ?2S^)DkM{{Eb zS$!L$e_o0(^}n3tA1R3-$SNvgBq;DOEo}fNc|tB%%#g4RA3{|euq)p+xd3I8^4E&m zFrD%}nvG^HUAIKe9_{tXB;tl|G<%>yk6R;8L2)KUJw4yHJXUOPM>(-+jxq4R;z8H#>rnJy*)8N+$wA$^F zN+H*3t)eFEgxLw+Nw3};4WV$qj&_D`%ADV2%r zJCPCo%{=z7;`F98(us5JnT(G@sKTZ^;2FVitXyLe-S5(hV&Ium+1pIUB(CZ#h|g)u zSLJJ<@HgrDiA-}V_6B^x1>c9B6%~847JkQ!^KLZ2skm;q*edo;UA)~?SghG8;QbHh z_6M;ouo_1rq9=x$<`Y@EA{C%6-pEV}B(1#sDoe_e1s3^Y>n#1Sw;N|}8D|s|VPd+g z-_$QhCz`vLxxrVMx3ape1xu3*wjx=yKSlM~nFgkNWb4?DDr*!?U)L_VeffF<+!j|b zZ$Wn2$TDv3C3V@BHpSgv3JUif8%hk%OsGZ=OxH@8&4`bbf$`aAMchl^qN>Eyu3JH} z9-S!x8-s4fE=lad%Pkp8hAs~u?|uRnL48O|;*DEU! zuS0{cpk%1E0nc__2%;apFsTm0bKtd&A0~S3Cj^?72-*Owk3V!ZG*PswDfS~}2<8le z5+W^`Y(&R)yVF*tU_s!XMcJS`;(Tr`J0%>p=Z&InR%D3@KEzzI+-2)HK zuoNZ&o=wUC&+*?ofPb0a(E6(<2Amd6%uSu_^-<1?hsxs~0K5^f(LsGqgEF^+0_H=uNk9S0bb!|O8d?m5gQjUKevPaO+*VfSn^2892K~%crWM8+6 z25@V?Y@J<9w%@NXh-2!}SK_(X)O4AM1-WTg>sj1{lj5@=q&dxE^9xng1_z9w9DK>| z6Iybcd0e zyi;Ew!KBRIfGPGytQ6}z}MeXCfLY0?9%RiyagSp_D1?N&c{ zyo>VbJ4Gy`@Fv+5cKgUgs~na$>BV{*em7PU3%lloy_aEovR+J7TfQKh8BJXyL6|P8un-Jnq(ghd!_HEOh$zlv2$~y3krgeH;9zC}V3f`uDtW(%mT#944DQa~^8ZI+zAUu4U(j0YcDfKR$bK#gvn_{JZ>|gZ5+)u?T$w7Q%F^;!Wk?G z(le7r!ufT*cxS}PR6hIVtXa)i`d$-_1KkyBU>qmgz-=T};uxx&sKgv48akIWQ89F{ z0XiY?WM^~;|T8zBOr zs#zuOONzH?svv*jokd5SK8wG>+yMC)LYL|vLqm^PMHcT=`}V$=nIRHe2?h)8WQa6O zPAU}d`1y(>kZiP~Gr=mtJLMu`i<2CspL|q2DqAgAD^7*$xzM`PU4^ga`ilE134XBQ z99P(LhHU@7qvl9Yzg$M`+dlS=x^(m-_3t|h>S}E0bcFMn=C|KamQ)=w2^e)35p`zY zRV8X?d;s^>Cof2SPR&nP3E+-LCkS0J$H!eh8~k0qo$}00b=7!H_I2O+Ro@3O$nPdm ztmbOO^B+IHzQ5w>@@@J4cKw5&^_w6s!s=H%&byAbUtczPQ7}wfTqxxtQNfn*u73Qw zGuWsrky_ajPx-5`R<)6xHf>C(oqGf_Fw|-U*GfS?xLML$kv;h_pZ@Kk$y0X(S+K80 z6^|z)*`5VUkawg}=z`S;VhZhxyDfrE0$(PMurAxl~<>lfZa>JZ288ULK7D` zl9|#L^JL}Y$j*j`0-K6kH#?bRmg#5L3iB4Z)%iF@SqT+Lp|{i`m%R-|ZE94Np7Pa5 zCqC^V3}B(FR340pmF*qaa}M}+h6}mqE~7Sh!9bDv9YRT|>vBNAqv09zXHMlcuhKD| zcjjA(b*XCIwJ33?CB!+;{)vX@9xns_b-VO{i0y?}{!sdXj1GM8+$#v>W7nw;+O_9B z_{4L;C6ol?(?W0<6taGEn1^uG=?Q3i29sE`RfYCaV$3DKc_;?HsL?D_fSYg}SuO5U zOB_f4^vZ_x%o`5|C@9C5+o=mFy@au{s)sKw!UgC&L35aH(sgDxRE2De%(%OT=VUdN ziVLEmdOvJ&5*tCMKRyXctCwQu_RH%;m*$YK&m;jtbdH#Ak~13T1^f89tn`A%QEHWs~jnY~E}p_Z$XC z=?YXLCkzVSK+Id`xZYTegb@W8_baLt-Fq`Tv|=)JPbFsKRm)4UW;yT+J`<)%#ue9DPOkje)YF2fsCilK9MIIK>p*`fkoD5nGfmLwt)!KOT+> zOFq*VZktDDyM3P5UOg`~XL#cbzC}eL%qMB=Q5$d89MKuN#$6|4gx_Jt0Gfn8w&q}%lq4QU%6#jT*MRT% zrLz~C8FYKHawn-EQWN1B75O&quS+Z81(zN)G>~vN8VwC+e+y(`>HcxC{MrJ;H1Z4k zZWuv$w_F0-Ub%MVcpIc){4PGL^I7M{>;hS?;eH!;gmcOE66z3;Z1Phqo(t zVP(Hg6q#0gIKgsg7L7WE!{Y#1nI(45tx2{$34dDd#!Z0NIyrm)HOn5W#7;f4pQci# zDW!FI(g4e668kI9{2+mLwB+=#9bfqgX%!B34V-$wwSN(_cm*^{y0jQtv*4}eO^sOV z*9xoNvX)c9isB}Tgx&ZRjp3kwhTVK?r9;n!x>^XYT z@Q^7zp{rkIs{2mUSE^2!Gf6$6;j~&4=-0cSJJDizZp6LTe8b45;{AKM%v99}{{FfC zz709%u0mC=1KXTo(=TqmZQ;c?$M3z(!xah>aywrj40sc2y3rKFw4jCq+Y+u=CH@_V zxz|qeTwa>+<|H%8Dz5u>ZI5MmjTFwXS-Fv!TDd*`>3{krWoNVx$<133`(ftS?ZPyY z&4@ah^3^i`vL$BZa>O|Nt?ucewzsF)0zX3qmM^|waXr=T0pfIb0*$AwU=?Ipl|1Y; z*Pk6{C-p4MY;j@IJ|DW>QHZQJcp;Z~?8(Q+Kk3^0qJ}SCk^*n4W zu9ZFwLHUx-$6xvaQ)SUQcYd6fF8&x)V`1bIuX@>{mE$b|Yd(qomn3;bPwnDUc0F=; zh*6_((%bqAYQWQ~odER?h>1mkL4kpb3s7`0m@rDKGU*oyF)$j~Ffd4fXV$?`f~rHf zB%Y)@5SXZvfwm10RY5X?TEo)PK_`L6qgBp=#>fO49$D zDq8Ozj0q6213tV5Qq=;fZ0$|KroY{Dz=l@lU^J)?Ko@ti20TRplXzphBi>XGx4bou zEWrkNjz0t5j!_ke{g5I#PUlEU$Km8g8TE|XK=MkU@PT4T><2OVamoK;wJ}3X0L$vX zgd7gNa359*nc)R-0!`2X@FOTB`+oETOPc=ubp5R)VQgY+5BTZZJ2?9QwnO=dnulIUF3gFn;BODC2)65)HeVd%t86sL7Rv^Y+nbn+&l z6BAJY(ETvwI)Ts$aiE8rht4KD*qNyE{8{x6R|%akbTBzw;2+6Echkt+W+`u^XX z_z&x%nYNR8p1vbMJH7ubt# zZR`2@zJD1Ad^Oa6Hk1{VlN1wGR-u;_dyt)+kddaNpM#U8qn@6eX;fldWZ6BspQIa= zoRXcQk)#ENJ`XiXJuK3q0$`Ap92QXrW00Yv7NOrc-8ljOOOIcj{J&cR{W`aIGXJ-` z`ez%Mf7qBi8JgIb{-35Oe>Zh^GIVe-b^5nULQhxRDZa)^4+98@`hUJe{J%R>|LYHA z4K3~Hjcp8_owGF{d~lZVKJ;kc48^OQ+`_2migWY?JqgW&))70RgSB6KY9+&wm<*8 z_{<;(c;5H|u}3{Y>y_<0Z59a)MIGK7wRMX0Nvo>feeJs+U?bt-++E8bu7 zh#_cwz0(4#RaT@xy14c7d<92q-Dd}Dt<*RS+$r0a^=LGCM{ny?rMFjhgxIG4>Hc~r zC$L?-FW0FZ((8@dsowXlQq}ja%DM{z&0kia*w7B*PQ`gLvPGS7M}$T&EPl8mew3In z0U$u}+bk?Vei{E$6dAYI8Tsze6A5wah?d(+fyP_5t4ytRXNktK&*JB!hRl07G62m_ zAt1nj(37{1p~L|m(Bsz3vE*usD`78QTgYIk zQ6BF14KLzsJTCqx&E!h>XP4)bya|{*G7&T$^hR0(bOWjUs2p0uw7xEjbz1FNSBCDb@^NIA z$qaq^0it^(#pFEmuGVS4&-r4(7HLmtT%_~Xhr-k8yp0`$N|y>#$Ao#zibzGi*UKzi zhaV#@e1{2@1Vn2iq}4J{1-ox;7K(-;Sk{3G2_EtV-D<)^Pk-G<6-vP{W}Yd>GLL zuOVrmN@KlD4f5sVMTs7c{ATcIGrv4@2umVI$r!xI8a?GN(R;?32n0NS(g@B8S00-=zzLn z%^Agl9eV(q&8UrK^~&$}{S(6-nEXnI8%|hoQ47P?I0Kd=woZ-pH==;jEg+QOfMSq~ zOu>&DkHsc{?o&M5`jyJBWbfoPBv9Y#70qvoHbZXOj*qRM(CQV=uX5KN+b>SQf-~a8 ziZg}@&XHHXkAUqr)Q{y`jNd7`1F8nm6}n}+_She>KO`VNlnu(&??!(i#$mKOpWpi1 z#WfWxi3L)bNRodhPM~~?!5{TrrBY_+nD?CIUupkwAPGz-P;QYc-DcUoCe`w(7)}|S zRvN)9ru8b)MoullmASwsgKQo1U6nsVAvo8iKnbaWydto4y?#-|kP^%e6m@L`88KyDrLH`=EDx*6>?r5~7Iv~I zr__%SximG(izLKSnbTlXa-ksH@R6rvBrBavt4)>o3$dgztLt4W=!3=O(*w7I+pHY2(P0QbTma+g#dXoD7N#?FaXNQ^I0*;jzvjM}%=+km`YtC%O#Alm| zqgORKSqk!#^~6whtLQASqiJ7*nq?38OJ3$u=Tp%Y`x^eYJtOqTzVkJ60b2t>TzdQ{I}!lEBxm}JSy7sy8DpDb zIqdT%PKf&Zy--T^c-;%mbDCxLrMWTVLW}c=DP2>Td74)-mLl|70)8hU??(2)I@Zyo z2i`q5oyA!!(2xV~gahuKl&L(@_3SP012#x(7P!1}6vNFFK5f*A1xF({JwxSFwA|TM z&1z}!*mZKcUA-v4QzLz&5wS$7=5{M@RAlx@RkJaA4nWVqsuuaW(eDh^LNPPkmM~Al zwxCe@*-^4!ky#iNv2NIIU$CS+UW%ziW0q@6HN3{eCYOUe;2P)C*M`Bt{~-mC%T3%# zEaf)lATO1;uF33x>Hr~YD0Ju*Syi!Jz+x3myVvU^-O>C*lFCKS&=Tuz@>&o?68aF& zBv<^ziPywPu#;WSlTkzdZ9`GWe7D8h<1-v0M*R@oYgS5jlPbgHcx)n2*+!+VcGlYh?;9Ngkg% z=MPD+`pXryN1T|%I7c?ZPLb3bqWr7 zU4bfG1y+?!bw)5Iq#8IqWN@G=Ru%Thxf)#=yL>^wZXSCC8we@>$hu=yrU;2=7>h;5 zvj_pYgKg2lKvNggl1ALnsz2IlcvL;q79buN5T3IhXuJvy@^crqWpB-5NOm{7UVfxmPJ>`?;Tn@qHzF+W!5W{8Z&ZAnDOquw6r4$bv*jM#5lc%3v|c~^ zdqo4LuxzkKhK4Q+JTK8tR_|i6O(x#N2N0Fy5)!_trK&cn9odQu#Vlh1K~7q|rE z61#!ZPZ+G&Y7hqmY;`{XeDbQexC2@oFWY)Nzg@lL3GeEVRxWQlx@0?Zt`PcP0iq@6 zLgc)p&s$;*K_;q0L(mQ8mKqOJSrq$aQYO-Hbssf3P=wC6CvTVHudzJH-Jgm&foBSy zx0=qu$w477lIHk);XhaUR!R-tQOZ;tjLXFH6;%0)8^IAc*MO>Q;J={We(0OHaogG0 zE_C@bXic&m?F7slFAB~x|n#>a^@u8lu;=!sqE*?vq zu4`(x!Jb4F#&3+jQ|ygldPjyYn#uCjNWR)%M3(L!?3C`miKT;~iv_)dll>Q6b+I&c zrlB04k&>mSYLR7-k{Od+lARt~3}Bv!LWY4>igJl!L5@;V21H6dNHIGr+qV551e@yL z`*SdKGPE^yF?FJ|`#L)RQ?LJ;8+={+|Cl<$*ZF@j^?$H%V;jqVqt#2B0yVr}Nry5R z5D?S9n+qB_yEqvdy9nFc+8WxK$XME$3ftSceLb+L(_id5MMc*hSrC;E1SaZYow%jh zPgo#1PKjE+1QB`Of|aNmX?}3TP;y6~0iN}TKi3b+yvGk;)X&i3mTnf9M zuv3qvhErosfZ%Pb-Q>|BEm5(j-RV6Zf^$icM=sC-5^6MnAvcE9xzH@FwnDeG0YU{J zi~Fq?=bi0;Ir=hfOJu8PxC)qjYW~cv^+74Hs#GmU%Cw6?3LUUHh|Yab`spoqh8F@_ zm4bCyiXPx-Cp4!JpI~w!ShPfJOXsy>f*|$@P8L8(oeh#~w z-2a4IOeckn6}_TQ+rgl_gLArS3|Ml(i<`*Lqv6rWh$(Z5ycTYD#Z*&-5mpa}a_zHt z6E`Ty-^L9RK-M*mN5AasoBhc|XWZ7=YRQSvG)3$v zgr&U_X`Ny0)IOZtX}e$wNUzTpD%iF7Rgf?nWoG2J@PsS-qK4OD!kJ?UfO+1|F*|Bo z1KU`qDA^;$0*4mUJ#{EPOm7)t#EdX=Yx1R2T&xlzzThfRC7eq@pX&%MO&2AZVO%zw zS;A{HtJiL=rfXDigS=NcWL-s>Rbv|=)7eDoOVnVI>DI_8x>{E>msC$kXsS}z?R6*x zi(yO`$WN)_F1$=18cbA^5|f`pZA+9DG_Zu8uW?rA9IxUXx^QCAp3Gk1MSdq zBZv;_$W>*-zLL)F>Vn`}ti1k!%6{Q=g!g1J*`KONL#)M{ZC*%QzsNRaL|uJcGB7jD zTbUe%T(_x`UtlM!Ntp&-qu!v|mPZGcJw$mdnanY3Uo>5{oiFOjDr!ZznKz}iWT#x& z?*#;H$`M0VC|a~1u_<(}WD>ogx(EvF6A6S8l0%9U<( zH||OBbh8Tnzz*#bV8&$d#AZNF$xF9F2{_B`^(zWNC}af(V~J+EZAbeC2%hjKz3V1C zj#%d%Gf(uyQ@0Y6CcP^CWkq`n+YR^W0`_qkDw333O<0FoO9()vP^!tZ{`0zsNQx~E zb&BcBU>GTP2svE2Tmd;~73mj!_*V8uL?ZLbx}{^l9+yvR5fas+w&0EpA?_g?i9@A$j*?LnmctPDQG|zJ`=EF}Vx8aMD^LrtMvpNIR*|RHA`ctK*sbG= zjN7Q)(|dGpC}$+nt~bupuKSyaiU}Ws{?Tha@$q}cJ;tvH>+MuPih+B4d$Zbq9$Y*U z)iA(-dK?Ov@uCDq48Zm%%t5uw1GrnxDm7*ITGCEF!2UjA`BqPRiUR`yNq^zz|A3wU zG(8DAnY-GW+PR2&7@In{Sla(XnMz5Rk^*5u4UvCiDQs@hvZXoiziv{6*i?fihVI|( zPrY8SOcOIh9-AzyJ*wF4hq%ojB&Abrf;4kX@^-p$mmhr}xxn#fVU?ydmD=21&S)s*v*^3E96(K1}J$6bi8pyUr-IU)p zcwa$&EAF$0Aj?4OYPcOwb-#qB=kCEDIV8%^0oa567_u6`9+XRhKaBup z2gwj*m#(}=5m24fBB#9cC?A$4CCBj7kanaYM&v754(b%Vl!gg&N)ZN_gO0mv(jM0# z>FC|FHi=FGlEt6Hk6H3!Yc|7+q{&t%(>3n#>#yx@*aS+bw)(2!WK#M0AUD~wID>yG z?&{p66jLvP1;!T7^^*_9F322wJB*O%TY2oek=sA%AUQT75VQ_iY9`H;ZNKFQELpZd z$~M`wm^Y>lZ8+F0_WCJ0T2td`bM+b`)h3YOV%&@o{C#|t&7haQfq#uJJP;81|2e+$ z|K#e~YTE87s+e0zCE2X$df`o$`8tQhmO?nqO?lOuTJ%GDv&-m_kP9X<5GCo1=?+LY z?!O^AUrRb~3F!k=H7Aae5W0V1{KlgH379eAPTwq=2+MlNcJ6NM+4ztXFTwI)g+)&Q7G4H%KH_(}1rq%+eIJ*3$?WwnZxPZ;EC=@`QS@|-I zyl+NYh&G>k%}GL}1;ap8buvF>x^yfR*d+4Vkg7S!aQ++_oNx6hLz6kKWi>pjWGO5k zlUZ45MbA=v(xf>Oeqhg8ctl56y{;uDG?A9Ga5aEzZB80BW6vo2Bz&O-}WAq>(PaV;*SX0=xXgI_SJ< zYR&5HyeY%IW}I>yKu^?W2$~S!pw?)wd4(#6;V|dVoa}13Oiz5Hs6zA zgICc;aoUt$>AjDmr0nCzeCReTuvdD1{NzD1wr*q@QqVW*Wi1zn;Yw1dSwLvTUwg#7 zpp~Czra7U~nSZZTjieZxiu~=}!xgV68(!UmQz@#w9#$0Vf@y%!{uN~w^~U_d_Aa&r zt2l>)H8-+gA;3xBk?ZV2Cq!L71;-tb%7A0FWziYwMT|#s_Ze_B>orZQWqDOZuT{|@ zX04D%y&8u@>bur&*<2??1KnaA7M%%gXV@C3YjipS4|cQH68OSYxC`P#ncvtB%gnEI z%fxRuH=d{L70?vHMi>~_lhJ@MC^u#H66=tx?8{HG;G2j$9@}ZDYUuTetwpvuqy}vW)kDmj^a|A%z(xs7yY2mU0#X2$un&MCirr|7 z%m?8+9aekm0x5hvBQ2J+>XeAdel$cy>J<6R3}*O^j{ObSk_Ucv$8a3_WPTd5I4HRT z(PKP5!{l*{lk_19@&{5C>TRV8_D~v*StN~Pm*(qRP+`1N12y{#w_fsXrtSt={0hJw zQ(PyWgA;;tBBDql#^2J(pnuv;fPn(H>^d<6BlI%00ylJZ?Evkh%=j2n+|VqTM~EUh zTx|IY)W;3{%x(O{X|$PS&x0?z#S2q-kW&G}7#D?p7!Q4V&NtA_DbF~v?cz6_l+t8e zoh1`dk;P-%$m(Ud?wnoZn0R=Ka$`tnZ|yQ-FN!?!9Wmb^b(R!s#b)oj9hs3$p%XX9DgQcZJE7B_dz0OEF6C zx|%jlqj0WG5K4`cVw!19doNY+(;SrR_txAlXxf#C`uz5H6#0D>SzG*t9!Fn|^8Z8; z1w$uiQzufUzvPCHXhGma>+O327SitsB1?Rn6|^F198AOx}! zfXg22Lm0x%=gRvXXx%WU2&R!p_{_1H^R`+fRO2LT%;He@yiekCz3%coJ=8+Xbc$mN zJ;J7*ED|yKWDK3CrD?v#VFj|l-cTgtn&lL`@;sMYaM1;d)VUHa1KSB5(I54sBErYp z>~4Jz41?Vt{`o7T`j=Se{-kgJBJG^MTJ}hT00H%U)pY-dy!M|6$v+-d(CkZH5wmo1 zc2RaU`p3_IJ^hf{g&c|^;)k3zXC0kF1>rUljSxd}Af$!@@R1fJWa4g5vF?S?8rg=Z z4_I!$dap>3l+o|fyYy(sX}f@Br4~%&&#Z~bEca!nMKV zgQSCVC!zw^j<61!7#T!RxC6KdoMNONcM5^Q;<#~K!Q?-#6SE16F*dZ;qv=`5 z(kF|n!QIVd*6BqRR8b8H>d~N@ab+1+{3dDVPVAo>{mAB#m&jX{usKkCg^a9Fef`tR z?M79j7hH*;iC$XM)#IVm&tUoDv!(#f=XsTA$)(ZE37!iu3Gkih5~^Vlx#<(M25gr@ zOkSw4{l}6xI(b0Gy#ywglot$GnF)P<FQt~9ge1>qp8Q^k;_Dm1X@Tc^{CwYb4v_ld}k5I$&u}avIDQ-D(_EP zhgdc{)5r_iTFiZ;Q)5Uq=U73lW%uYN=JLo#OS;B0B=;j>APk?|!t{f3grv0nv}Z%` zM%XJk^#R69iNm&*^0SV0s9&>cl1BroIw*t3R0()^ldAsq)kWcI=>~4!6fM#0!K%TS ziZH=H%7-f=#-2G_XmF$~Wl~Um%^9%AeNSk)*`RDl##y+s)$V`oDlnK@{y+#LNUJp1^(e89sed@BB z^W)sHm;A^9*RgQ;f(~MHK~bJRvzezWGr#@jYAlXIrCk_iiUfC_FBWyvKj2mBF=FI;9|?0_~=E<)qnjLg9k*Qd!_ zl}VuSJB%#M>`iZm*1U^SP1}rkkI};91IRpZw%Hb$tKmr6&H5~m?A7?+uFOSnf)j14 zJCYLOYdaRu>zO%5d+VeXa-Ai7{7Z}iTn%yyz7hsmo7E|{ z@+g9cBcI-MT~2f@WrY0dpaC=v{*lDPBDX}OXtJ|niu$xyit;tyX5N&3pgmCxq>7TP zcOb9%(TyvOSxtw%Y2+O&jg39&YuOtgzn`uk{INC}^Na_-V;63b#+*@NOBnU{lG5TS zbC+N-qt)u26lggGPcdrTn@m+m>bcrh?sG4b(BrtdIKq3W<%?WuQtEW0Z)#?c_Lzqj*DlZ zVUpEV3~mG#DN$I#JJp3xc8`9ex)1%Il7xKwrpJt)qtpq}DXqI=5~~N}N?0g*YwETZ z(NKJO5kzh?Os`BQ7HYaTl>sXVr!b8>(Wd&PU*3ivSn{;q`|@n*J~-3tbm;4WK>j3&}AEZ*`_!gJ3F4w~4{{PyLZklDqWo|X}D zbZU_{2E6^VTCg#+6yJt{QUhu}uMITs@sRwH0z5OqM>taO^(_+w1c ztQ?gvVPj<_F_=(ISaB~qML59HT;#c9x(;0vkCi2#Zp`;_r@+8QOV1Ey2RWm6{*J&9 zG(Dt$zF^7qYpo9Ne}ce5re^j|rvDo*DQ&1Be#Fvo#?m4mfFrNZb1#D4f`Lf(t_Fib zwxL3lx(Zp(XVRjo_ocElY#yS$LHb6yl;9;Ycm1|5y_praEcGUZxLhS%7?b&es2skI z9l!O)b%D=cXBa@v9;64f^Q9IV$xOkl;%cG6WLQ`_a7I`woHbEX&?6NJ9Yn&z+#^#! zc8;5=jt~Unn7!cQa$=a7xSp}zuz#Lc#Q3-e7*i`Xk5tx_+^M~!DlyBOwVEq3c(?`@ zZ_3qlTN{eHOwvNTCLOHjwg0%niFYm({LEfAieI+k;U2&uTD4J;Zg#s`k?lxyJN<$mK6>j?J4eOM@T*o?&l@LFG$Gs5f4R*p*V1RkTdCfv9KUfa< z{k;#JfA3XA5NQJziGd%DchDR*Dkld&t;6i9e2t7{hQPIG_uDXN1q0T;IFCmCcua-e z`o#=uS2_en206(TuB4g-!#=rziBTs%(-b1N%(Bl}ea#xKK9zzZGCo@<*i1ZoETjeC zJ)ll{$mpX7Eldxnjb1&cB6S=7v@EDCsmIOBWc$p^W*;C0i^Hc{q(_iaWtE{0qbLjxWlqBe%Y|A z>I|4)(5mx3VtwRBrano|P))JWybOHUyOY67zRst259tx;l(hbY@%Z`v8Pz^0Sw$?= zwSd^HLyL+$l&R+TDnbV_u+h{Z>n$)PMf*YGQ}1Df@Nr{#Gr+@|gKlnv?`s1rm^$1+ zic`WeKSH?{+E}0^#T<&@P;dFf;P5zCbuCOijADb}n^{k=>mBehDD6PtCrn5ZBhh2L zjF$TbzvnwT#AzGEG_Rg>W1NS{PxmL9Mf69*?YDeB*pK!&2PQ7!u6eJEHk5e(H~cnG zZQ?X_rtws!;Tod88j=aMaylLNJbgDoyzlBv0g{2VYRXObL=pn!n8+s1s2uTwtZc

YH!Z*ZaR%>WTVy8-(^h5J^1%NZ$@&_ZQ)3AeHlhL~=X9=fKPzFbZ;~cS**=W-LF1 z5F82SZ zG8QZAet|10U*jK*GVOA(iULStsUDMjhT$g5MRIc4b8)5q_a?ma-G+@xyNDk{pR*YH zjCXynm-fV`*;}%3=+zMj**wlCo6a{}*?;`*j%fU`t+3Korws%dsCXAANKkmVby*eJ z6`2%GB{+&`g2;snG`LM9S~>#^G|nZ|JMnWLgSmJ4!kB->uAEF0sVn6km@s=#_=d)y zzld%;gJY>ypQuE z!wgqqTSPxaUPoG%FQ()1hz(VHN@5sfnE68of>9BgGsQP|9$7j zGqN{nxZx4CD6ICwmXSv6&RD<-etQmbyTHIXn!Q+0{18=!p))>To8df$nCjycnW07Q zsma_}$tY#Xc&?#OK}-N`wPm)+2|&)9=9>YOXQYfaCI*cV1=TUl5({a@1wn#V?y0Yn z(3;3-@(QF|0PA}|w4hBWQbTItc$(^snj$36kz{pOx*f`l7V8`rZK}82pPRuy zxwE=~MlCwOLRC`y%q8SMh>3BUCjxLa;v{pFSdAc7m*7!}dtH`MuMLB)QC4B^Uh2_? zApl6z_VHU}=MAA9*g4v-P=7~3?Lu#ig)cRe90>@B?>})@X*+v&yT6FvUsO=p#n8p{ zFA6xNarPy0qJDO1BPBYk4~~LP0ykPV ztoz$i+QC%Ch%t}|i^(Rb9?$(@ijUc@w=3F1AM}OgFo1b89KzF6qJO~W52U_;R_MsB zfAC29BNUXpl!w&!dT^Zq<__Hr#w6q%qS1CJ#5Wrb*)2P1%h*DmZ?br)*)~$^TExX1 zL&{>xnM*sh=@IY)i?u5@;;k6+MLjx%m(qwDF3?K3p>-4c2fe(cIpKq#Lc~;#I#Wwz zywZ!^&|9#G7PM6tpgwA@3ev@Ev_w`ZZRs#VS4}<^>tfP*(uqLL65uSi9H!Gqd59C&=LSDo{;#@Isg3caF1X+4T}sL2B+Q zK*kO0?4F7%8mx3di$B~b&*t7y|{x%2BUg4kLFXt`FK;Vi(FIJ+!H zW;mjBrfZdNT>&dDfc4m$^f@k)mum{DioeYYJ|XKQynXl-IDs~1c(`w{*ih0-y_=t$ zaMDwAz>^CC;p*Iw+Hm}%6$GN49<(rembdFvb!ZyayLoqR*KBLc^OIA*t8CXur+_e0 z3`|y|!T>7+jdny7x@JHtV0CP1jI^)9){!s#{C>BcNc5#*hioZ>OfDv)&PAM!PTjS+ zy1gRZirf>YoGpgprd?M1k<;=SShCMn406J>>iRVnw9QxsR|_j5U{Ixr;X5n$ih+-=X0fo(Oga zB=uer9jc=mYY=tV-tAe@_d-{aj`oYS%CP@V3m6Y{)mZ5}b1wV<9{~$`qR9 zEzXo|ok?1fS?zneLA@_C(BAjE_Bv7Dl2s?=_?E9zO5R^TBg8Be~fpG?$9I; zDWLH9R9##?>ISN8s2^wj3B?qJxrSSlC6YB}Yee{D3Ex8@QFLZ&zPx-?0>;Cafcb-! zlGLr)wisd=C(F#4-0@~P-C&s%C}GvBhb^tTiL4Y_dsv@O;S56@?@t<)AXpqHx9V;3 zgB!NXwp`=%h9!L9dBn6R0M<~;(g*nvI`A@&K!B`CU3^FpRWvRi@Iom>LK!hEh8VjX z_dSw5nh-f#zIUDkKMq|BL+IO}HYJjMo=#_srx8cRAbu9bvr&WxggWvxbS_Ix|B}DE zk!*;&k#1BcinaD-w#E+PR_k8I_YOYNkoxw5!g&3WKx4{_Y6T&EV>NrnN9W*@OH+niSC0nd z#x*dm=f2Zm?6qhY3}Kurxl@}d(~ z<}?Mw+>%y3T{!i3d1%ig*`oIYK|Vi@8Z~*vxY%Od-N0+xqtJ*KGrqo*9GQ14WluUn z+%c+og=f0s6Mcf%r1Be#e}&>1n!!ZxnWZ`7@F9ymfVkuFL;m6M5t%6OrnK#*lofS{ z=2;WPobvGCu{(gy8|Mn(9}NV99Feps6r*6s&bg(5aNw$eE ztbYsrm0yS`UIJ?Kv-EpZT#76g76*hVNg)L#Hr7Q@L4sqHI;+q5P&H{GBo1$PYkr@z zFeVdcS?N1klRoBt4>fMnygNrDL!3e)k3`TXoa3#F#0SFP(Xx^cc)#e2+&z9F=6{qk z%33-*f6=+W@baq){!d_;ouVthV1PREX^ykCjD|%WUMnNA2GbA#329aEihLk~0!!}k z)SIEXz(;0lemIO{|JdO{6d|-9LePs~$}6vZ>`xYCD(ODG;OuwOe3jeN;|G$~ml%r* z%{@<9qDf8Vsw581v9y+)I4&te!6ZDJMYrQ*g4_xj!~pUu#er`@_bJ34Ioez)^055M$)LfC|i*2*3E zLB<`5*H#&~R*VLYlNMCXl~=9%o0IYJ$bY+|m-0OJ-}6c@3m<~C;;S~#@j-p?DBdr<><3Y92rW-kc2C$zhqwyq09;dc5;BAR#PPpZxqo-@e_s9*O`?w5 zMnLUs(2c-zw9Pl!2c#+9lFpmTR>P;SA#Id;+fo|g{*n&gLi}7`K)(=tcK|?qR4qNT z%aEsSCL0j9DN$j8g(a+{Z-qPMG&O)H0Y9!c*d?aN0tC&GqC+`%(IFY$ll~!_%<2pX zuD`w_l)*LTG%Qq3ZSDE)#dt-xp<+n=3&lPPzo}r2u~>f8)mbcdN6*r)_AaTYq%Scv zEdwzZw&6Ls8S~RTvMEfX{t@L4PtDi{o;|LyG>rc~Um3;x)rOOGL^Bmp0$TbvPgnwE zJEmZ>ktIfiJzdW5i{OSWZuQWd13tz#czek~&*?iZkVlLkgxyiy^M~|JH(?IB-*o6% zZT8+svJzcVjcE0UEkL_5$kNmdrkOl3-`eO#TwpTnj?xB}AlV2`ks_Ua9(sJ+ok|%b z=2n2rgF}hvVRHJLA@9TK4h#pLzw?A8u31&qbr~KA9;CS7aRf$^f1BZ5fsH2W8z}FU zC}Yq76IR%%g|4aNF9BLx6!^RMhv|JYtoZW&!7uOskGSGL+}_>L$@Jg2Vzugq-NJW7 zzD$7QK7cftU1z*Fxd@}wcK$n6mje}=C|W)tm?*V<<{;?8V9hdoi2NRm#~v^#bhwlc z5J5{cSRAUztxc6NH>Nwm4yR{(T>0x9%%VeU&<&n6^vFvZ{>V3RYJ_kC9zN(M(` zp?1PHN>f!-aLgvsbIp*oTZv4yWsXM2Q=C}>t7V(iX*N8{aoWphUJ^(n3k`pncUt&` ze+sYjo)>>=I?>X}1B*ZrxYu`|WD0J&RIb~ zPA_~u)?&`}JPwc1tu=OlKlJ3f!9HXa)KMb|2%^~;)fL>ZtycHQg`j1Vd^nu^XexYkcae@su zOhxk8ws&Eid_KAm_<}65zbgGNzwshR#yv&rQ8Ae<9;S^S}Dsk zubzo?l{0koX8~q*{uA%)wqy*Vqh4>_Os7PPh-maB1|eT-4 zK>*v3q}TBk1QlOF!113XOn(Kzzb5o4Dz@?q3aEb9%X5m{xV6yT{;*rnLCoI~BO&SM zXf=CHLI>kaSsRP2B{z_MgbD;R_yLnd>^1g`l;uXBw7|)+Q_<_rO!!VaU-O+j`u%zO z1>-N8OlHDJlAqi2#z@2yM|Dsc$(nc>%ZpuR&>}r(i^+qO+sKfg(Ggj9vL%hB6 zJ$8an-DbmKBK6u6oG7&-c0&QD#?JuDYKvL5pWXG{ztpq3BWF)e|7aF-(91xvKt047 zvR{G@KVKz$0qPNXK*gt*%qL-boz-*E;7LJXSyj3f$7;%5wj)2p8gvX}9o_u}A*Q|7 z)hjs?k`8EOxv1zahjg2PQDz5pYF3*Cr{%iUW3J+JU3P+l?n%CwV;`noa#3l@vd#6N zc#KD2J;5(Wd1BP)`!IM;L|(d9m*L8QP|M7W#S7SUF3O$GFnWvSZOwC_Aq~5!=1X+s z6;_M++j0F|x;HU6kufX-Ciy|du;T%2@hASD9(Z)OSVMsJg+=7SNTAjV<8MYN-zX5U zVp~|N&{|#Z)c6p?BEBBexg4Q((kcFwE`_U>ZQotiVrS-BAHKQLr87lpmwMCF_Co1M z`tQI{{7xotiN%Q~q{=Mj5*$!{aE4vi6aE$cyHJC@VvmemE4l_v1`b{)H4v7=l5+lm^ ztGs>1gnN(Vl+%VuwB+|4{bvdhCBRxGj3ady^ zLxL@AIA>h@eP|H41@b}u4R`s4yf9a2K!wGcGkzUe?!21Dk)%N6l+#MP&}B0%1Ar*~ zE^88}(mff~iKMPaF+UEp5xn(gavK(^9pvsUQT8V;v!iJt|7@&w+_va`(s_57#t?i6 zh$p!4?BzS9fZm+ui`276|I307lA-rKW$-y^lK#=>N|<-#?WPPNs86Iugsa&n{x%*2 zzL_%$#TmshCw&Yo$Ol?^|hy{=LYEUb|bMMY`n@#(~oegs-nF){0ppwee|b{ca)OXzS~01a%cg&^ zp;}mI0ir3zapNB)5%nF>Sd~gR1dBI!tDL z&m24z9sE%CEv*SZh1PT6+O`%|SG>x74(!d!2xNOt#C5@I6MnY%ij6rK3Y+%d7tr3&<^4XU-Npx{^`_e z9$-|@$t`}A`UqS&T?cd@-+-#V7n7tiZU!)tD8cFo4Sz=u65?f#7Yj}MDFu#RH_GUQ z{_-pKVEMAQ7ljrJ5Wxg4*0;h~vPUI+Ce(?={CTI&(RyX&GVY4XHs>Asxcp%B+Y9rK z5L$q94t+r3=M*~seA3BO$<0%^iaEb2K=c7((dIW$ggxdvnC$_gq~UWy?wljgA0Dwd`ZsyqOC>)UCn-qU5@~!f znAWKSZeKRaq#L$3W21fDCMXS;$X(C*YgL7zi8E|grQg%Jq8>YTqC#2~ys%Wnxu&;ZG<`uZ1L<53jf2yxYR3f0>a;%=$SYI@zUE*g7f)a{QH^<3F?%({Gg)yx^zsdJ3^J2 z#(!C3qmwx77*3#3asBA(jsL`86|OLB)j?`0hQIh>v;c2A@|$Yg>*f+iMatg8w#SmM z<;Y?!$L--h9vH+DL|Wr3lnfggMk*kyGH^8P48or4m%K^H-v~`cBteWvnN9port02u zF;120HE2WUDi@8?&Oha6$sB20(XPd3LhaT~dRR2_+)INDTPUQ9(-370t6a!rLKHkIA`#d-#WUcqK%pMcTs6iS2nD?hln+F-cQPUtTz2bZ zq+K`wtc1;ex_iz9?S4)>Fkb~bj0^VV?|`qe7W02H)BiibE9=_N8=(5hQK7;(`v7E5Mi3o? z>J_)L`z(m(27_&+89P?DU|6f9J*~Ih#6FWawk`HU1bPWfdF?02aY!YSo_!v$`&W znzH~kY)ll^F07=UNo|h;ZG2aJ<5W~o7?*${(XZ9zP0tTCg5h-dNPIM=*x@KO>a|Bk zO13Cbnbn7+_Kj=EEMJh4{DW<))H!3)vcn?_%WgRy=FpIkVW>NuV`knP`VjT78dqzT z>~ay~f!F?`key$EWbp$+w$8gR1RHR}>wA8|l9rl7jsT+>sQLqs{aITUW{US&p{Y)O zRojdm|7yoA_U+`FkQkS?$4$uf&S52kOuUaJT9lP@LEqjKDM)iqp9aKNlkpMyJ76eb zAa%9G{YUTXa4c|UE>?CCv(x1X3ebjXuL&9Dun1WTlw@Wltn3zTareM)uOKs$5>0tR zDA~&tM~J~-YXA<)&H(ud)JyFm+d<97d8WBr+H?6Jn&^Ib0<{6ov- ze@q`#Y%KpD?(k{if5-M(fO3PpK{Wjqh)7h+ojH ztb=h&vmy0tn$eA8_368TlF^DKg>BeFtU%3|k~3lZAp(C$&Qjo9lR<#rK{nVn$)r*y z#58_+t=UJm7tp|@#7}6M*o;vn7wM?8Srtc z3ZFlKRDYc^HqI!O9Z*OZZ8yo-3ie9i8C%KDYCfE?`rjrf(b&xBXub!54yaZY2hFi2w2asEOiO8;Hru4~KsqQZMrs+OhO8WMX zFN0=EvME`WfQ85bmsnPFp|RU;GP^&Ik#HV(iR1B}8apb9W9)Nv#LwpED~%w67o;r! zVzm@zGjsl)loBy6p>F(G+#*b|7BzZbV#E0Pi`02uAC}D%6d12TzOD19-9bhZZT*GS zqY|zxCTWn+8*JlL3QH&eLZ}incJzgX>>i1dhff}DJ=qL{d?yv@k33UhC!}#hC#31H zOTNv5e*ozksj`4q5H+75O70w4PoA3B5Ea*iGSqA=v)}LifPOuD$ss*^W}=9kq4qqd z6dqHmy_IGzq?j;UzFJ*gI5)6qLqdUL;G&E*;lnAS+ZV1nO%OdoXqw(I+*2-nuWjwM-<|XD541^5&!u2 z1XflFJp(`^D|ZUECbaoqT5$#MJ=c23KYpBjGknPZ7boYRxpuaO`!D6C_Al?T$<47T zFd@QT%860pwLnUwer$BspTO9l1H`fknMR|GC?@1Wn`HscOe4mf{KbVio zahne0&hJd0UL#{Xyz=&h@oc>E4r*T|PHuNtK6D279q!2amh%r#@HjaN_LT4j>{&2I z?07K#*aaZ?lNT6<8o85cjZoT~?=J&Xd35I%JJom{P=jj?HQ5yfvIR8bd~#7P^m%B-szS{v<)7i?#at=WA+}?r zwMlc-iZv$GT};AP4k2nL70=Q-(+L_CYUN{V?dnvG-Av+%)JxfwF4-r^Z$BTwbT!Jh zG0YXK4e8t`3~){5Qf6U(Ha0WKCKl^zlqhqHj~F}DoPV#yHqLu+ZWlv2zH29J6}4amZ3+-WZkR7(m{qEG%%57G!Yf&!Gu~FDeSYmNEkhi5nw@#6=Bt& zOKT!UWVY-FFyq1u2c~BJ4F`39K7Vw!1U;aKZw)2U8hAb&7ho|FyEyP~D<31{_L>RrCU>eEk-0)TBt5sS5?;NwAdRzRj5qRSD?J6 ze9ueq%TA*pgwYflmo`=FnGj2r_u2!HkhE5ZbR_Xf=F2QW@QTLD5n4h(?xrbOwNp5` zXMEtm`m52{0^27@=9VLt&GI;nR9S)p(4e+bAO=e4E;qprIhhclMO&7^ThphY9HEko z#WfDFKKCcf%Bi^umN({q(avHrnTyPH{o=sXBOIltHE?Q65y_At<9DsN*xWP|Q=<|R z{JfV?B5dM9gsXTN%%j;xCp{UuHuYF;5=k|>Q=;q zU<3AEYawUG;=%!Igjp!FIAtJvoo!*J^+!oT%VI4{P=XlbYZl;Dc467Nr*3j zJtyn|g{onj!_vl)yv)Xv#}(r)@25OHW#|eN&q7_S4i2xPA<*uY9vU_R7f};uqRgVb zM%<_N3ys%M;#TU_tQa#6I1<+7Bc+f%mqHQ}A@(y^+Up5Q*W~bvS9(21FGQRCosvIX zhmsjD^OyOpae*TKs=O?(_YFjSkO`=CJIb*yJ)Pts1egl@dX6-YI1qb?AqGtIOir&u zyn>qxbJhhJi9SjK+$knTBy-A)$@EfzOj~@>s$M$|cT5V!#+|X`aLR_gGYmNuLMVH4 z(K_Tn;i+fR28M~qv4XWqRg~+18Xb?!sQ=Dy)oRa)Jkl{?pa?66h$YxD)C{F%EfZt| z^qWFB2S_M=Ryrj$a?D<|>-Qa5Y6RzJ$6Yp`FOy6p2lZSjk%$9guVsv$OOT*6V$%TH zMO}a=JR(1*u`MN8jTn|OD!84_h${A)_eFRoH7WTCCue9X73nbD282V`VzTH$ckVaC zalu%ek#pHxAx=0migDNXwcfbK3TwB7@T7wx2 zGV7rS+2g9eIT9>uWfao+lW2Qi9L^EBu#IZSYl0Q~A^KYbQKwNU(YO4Xa1XH_>ml1v z#qS;P!3Lt%2|U^=++T`A!;V-!I%upi?<#h~h!X`p7eP!{+2{7DM0$yxi9gBfm^W?M zD1c)%I7N>CG6250NW54T%HoCo^ud#`;flZg_4ciWuj4a884oWUYV(#VW`zO1T~m(_ zkayymAJI)NU9_0b6tX)GU+pQ3K9x=pZ-&{?07oeb1R7T4RjYYbfG^>3Y>=?dryJq& zw9VpqkvgVB?&aK}4@m78NQhTqZeF=zUtBkJoz8;6LO<4>wP7{UPEs1tP69;v919I5 zzCqXUhfi~FoK5niVU~hQqAksPsD@_|nwH4avOw67#fb@Z5_OS=$eP%*TrPU%HG<-A z`9)Y3*SAdfiqNTJ2eKj8B;ntdqa@U46)B+odlH)jW;U{A*0sg@z>-?;nN}I=z3nEE@Bf3kh1B zdqT{TWJvb#AT&01hNsBz8v(OwBJSu#9}A6Y!lv|`J#Z3uVK1G`0$J&OH{R?3YVfk% z9P3HGpo<1uy~VRCAe&|c4L!SR{~^0*TbVtqej3ARx(Okl5c>m~|H9ZwKVHc_tCe$hsqA`l&h7qPP5xBgtwu!; zzQyUD<6J!M5fsV-9P?C9P49qnXR+iXt#G_AS2N<6!HZ(eS`|-ndb|y!(0Y({2 z4aF~GO8bHM7s+wnhPz>sa!Z%|!qWk*DGr)azB}j6bLe#FQXV4aO>Eo7{v`0x=%5SY zy&{kY+VLXni6pPJYG_Sa*9hLy-s$79$zAhkF)r?9&?UaNGmY9F$uf>iJ~u@Q;sydU zQaN7B>4B*V;rtl^^pa3nFh$q*c&sx^Um}I)Z)R&oLEoWi3;Yv6za?;7m?fZe>#_mS z-EGInS^#UHdOzCaMRSLh7Mr0}&)WCuw$4&K^lx{;O+?Q1p5PD8znQ~srGrygJ?b~Q5hIPt?Wf2)N?&Dae4%GRcRKL(a-2koctrcvxSslXn-k9cYS|<-KJ#+$Wo>}yKKh*3Q zHsK(4-Jv!9R3*FKmN$Z#^aZcACGrlGjOe^#Z&DfPyS-1bT9OIX~-I-5lN6Y>M}dvivbs2BcbPcaNH%25-xMkT$>*soDJ) z27;};8oCYHSLF0VawZFn8^H;hIN=J457@eoI6s2P87QN6O`q8coa;PN$mRZ>2Vv+! zQj1}Tvp8?>yyd_U>dnhx%q~k*JR`HO=43mB?~xKAW9Z}Vh2b0<(T89%eZ z57kGs@{NUHM>|!+QtqI@vE8hp`IIGc`A9Y{p?c;@a!zJFmdaCJ;JmzOJ8)B1x{yZp zi!U{Wh-h+u6vj`2F+(F6gTv*cRX7MR z9@?>is`MSS1L#?PaW6BWEd#EX4+O1x6WdU~LZaQ^Quow~ybz*aAu{ZMrQ;yQ8g)-qh>x z^}@eFu1u7+3C0|hRMD1{MEn(JOmJ|wYHqGyn*xt-Y~J3j@nY56i)sgNjS4n@Q&p@@^>HQjzNaw#C9=TbwzDtiMr2a^}bX< zZE%HU^|CnS`WYVcs}D)+fP#bW0+Q#l#JC+!`OlhffKUCN8M-*CqS;VQX`If78$as0 z=$@^NFcDpTh~45heE63=x5nmP@4hBaFn(rmTY2Yj{S&k;{4W!0Nu9O5pK30}oxM7{ z>l4cKb~9D?N#u_AleD<~8XD@23sY^rt&fN%Q0L=Ti2bV#px`RhM$}h*Yg-iC4A+rI zV~@yY7!1}-@onsZ)@0tUM23cN-rXrZYWF#!V-&>vds8rP+w0t{?~Q zT^LN*lW==+_ifPb+-yMh9JhfcYiXo_zWa`ObRP9_En3P))Qyu0qPJ3*hiFSu>Vt-j z<*HWbiP2#BK@nt<g|pe3 zfBKS@i;ISkorx@cOIx9}p^d8Gis%$)))%ByVYU^KG#eE+j1p;^(Y1ndHnV&YuQZm~ zj;f+mf>0ru!N`)_p@Ls<& z`t+JDx7}R568Q|8`4A}G@t8Wc?SOXunyW5C-AWoB@P>r}uwFY*=?=!K@J(!t@#xOuPXhFS@FTf6-7|%k;nw2%Z+iHl219Ho1!bv(Ee0|ao!Rs%Jl0@3suGrOsb_@VM;(xzrf^Cbd;CK3b%a|ih-fG)`Rd00O74=sQYW~Ve z#fl!*(fo~SIQ5-Sl?1@o7-E*|SK|hoVEKzxeg!$KmQLSTN=5N`rYeh$AH&x}JMR+5dq|~FUy&Oj%QIy;HNr;V*7cQC+ka>LAwdU)?ubI@W z={eg%A&7D**SIj$cu=CN%vN^(_JeIHMUyejCrO%C3MhOcVL~Niu;8WYoN}YVhb+=- zR}M3p|H0`E2Id99y#03r`8$s0t*iD>`^7EPm1~guC)L~uW#O~>I85Q3Nj8(sG<@T| zL^e~XQt9O0AXQ^zkMdgzk5bdYttP~nf-<831zulL>>ghTFii$lg3^80t8Gb*x1w5| zN{kZuv`^8Fj=t(T*46M=S$6xY@0~AvWaGOYOBTl0?}KTkplmGn-*P(X=o-v^48OY} zi11-+Y}y)fdy_tI;*W(>#qzvgQZ52t!nrGsJEy!c86TKIN(n|!&ucCduG$XaIapI z{(Z9gZANsI={A=5Aorgq2H25Dd}H5@-5=j=s{f`%^>6b5qkm_2|3g>r-^amf=B_xV zXg*>aqxXZ6=VUI4$})ypDMy$IKkgJ;V>077T9o#OhpFhKtHP_4mnjS5QCgGe<;~Xe zt<2ZhL7?JL6Mi|U_w?;?@4OD@=4EB2op_s)N-ehm#7`zSU#7itU$#%^ncqjc`9HCG zfj;O1T+*oTkzRi-6NN`oS3w3$7ZB37L>PcN$C$L^qqHfiYO4_>0_qCw0r@FEMj=>}}%q_`d#pUT;c?=gI zqTGpiY4Z;Q(B~#hXIVBFbi#dO=cOdmOqD0|An?7nMdrm2^C>yw*dQ=#lf8)@DvXK; z$MXp}QZgnE!&L73x0LZX_bCdD4lRY$$^?9dt1RwCng{lIpbb%Ej%yOh{@76yEyb}K zXZy%^656Sk3BLKbalcc>Dt5iDzo^tj2!wnDL(X;urJfpkWrab!frFSC6Q7m zuoqN!(t=L&+Ov&~9mz(yEB`MK%RPXS>26Ww5(F;aZ zR@tPAw~=q2ioOiynxgBqE&3-R-@6yCo0*mE;#I^c!=g~HyyjGA6}|<(0EseKDTM4w z94YnCO^VYIUY@}x8kr;;El-cFHVO<$6;-UdmUB|J8R*Wf$a37gVgYT|w5^KkYe=(i zMkA$%7;^a*$V+}e%S~&*^^O;AX9NLt@cIPc*v!lKZ)(zahAsUj%PJot19ErFU=Uk( z9Hw;Lb`V+BzVpMu;TGB9}y~ff)^mbEmF?g{{7_0SR zPgp*n)l{?>7-Ji;eWG{ln$)Bro+UJAQo6W2-23d@SI=HiFV3hR2OUcAq_9q~ye)o@ zq8WZvhg`H(?1AUZ-NM%_Cuj}eb{4wOCnqs^E1G9U4HKjqaw@4dsXWP#$wx^}XPZ0F zywsJ0aJHA>AHc^q#nhQjD3!KDFT6FaDioJ#HsZU7Wo?8WH19TJ%OMDz$XH5J4Cjdt z@crE;#JNG`&1H8ekB(R4?QiiZ55kztsx}pQti}gG0&8`dP=d(8aCLOExd*Sw^WL`Q zHvZ(u`5A58h?+G&GVsA;pQNNPFI)U@O`#~RjaG(6Y<=gKT2?1 z*pCUGU)f??VlyP64P@uT`qh?L03ZQyLOBn?EKwH+IG{XvTh5|NldaSV_n~DK&F1aa znq~C_lCQHMfW6xib%a2m!h&%J)aXb{%-0!HCcW|kzaoSwPMhJ6$KL|F~Sx(tctbwfkgV;#KZlEmJN5&l5XF9eD;Kqb<| z>os)CqC^qF8$be|v;)LY{Gh@c0?a??k7M7&9CH+-B)t&T$xeSzCs30sf8O-+I#rq} z&kZj5&i>UyK9lDjI<*TLZ3USVwwpiE5x8<|{Db z3`HX3+Tt>1hg?+uY{^wC$|Tb7ud@3*Ub?=2xgztgv6OOz0G z-4VRyIChHfegUak^-)-P;VZY@FT64#xyo=+jG<48n2%wcx`ze6yd51(!NclmN=$*kY=#uu#>=yAU-u4I9Bt0n_6ta?&9jN+tM_5_3RH);I zxTN4n$EhvKH%TmOh5mq|?Cx$m>$Ed?H7hUEiRW^lnW+}ZoN#;}aAuy_n189qe1Juk z6;QeZ!gdMAEx4Na;{O*j$3F3e?FLAYuJ2iuMbWf8Ub6(nDo?zI5VNhN@ib6Yw_4P)GY^0M7TJwat z2S*2AcP}e0tibZ@k&htTD&yxT9QRG0CEq$;obfgV^&6YVX9B9|VJf`1aS_#Xk>DFo zwhk?~)>XlP5(u~UW0hP7dWZuCuN4QM24Td&j^7~)WQ6YeCg)njG*ri}tTcG-NxX}p zNB>kcxd5ipW@tN3=6r@Jgm#rgrK*dXA!gxy6fAvP7$)8)Vc~PPQ|`( zPy|bG1sUz958-!zW^j(8ILV%QC@x`~PDFczboZqWjvSU<9O3!TQ&xYi%?Y0AiVBLV z%R?#1L#G&xw*RZPsrwF?)B5+MSM(b$L;GLnRsSU!_$N;6pD97~H}`c>0F`&E_FCNE z_)Q*EA1%mOp`z>+h&aqlLKUD9*w?D>stDeBRdR*AS9)u;ABm7w1}eE|>YH>YtMyBR z^e%rPeZzBx_hj?zhJVNRM_PX(O9N#^ngmIJ0W@A)PRUV7#2D!#3vyd}ADuLry;jdn zSsTsHfQ@6`lH z^GWQf?ANJS>bBO-_obBL$Apvakhr1e5}l3axEgcNWRN$4S6ByH+viK#CnC1|6Xqj& z*_i7cullAJKy9GBAkIxUIzsmN=M|(4*WfBhePPHp?55xfF}yjeBld7+A7cQPX8PE-|Pe_xqboE;2AJb5ifrEfr86k&F0+y!r`-urW}OXSkfz2;E``UTrGSt^B)7&#RSLTQitk=mmPKUKP`uGQ4)vp_^$^U`2Jjq zeul!ptEpa%aJo0S(504oXPGdWM7dAA9=o9s4-{>z*pP zJ31L#|L?YR;^%+>YRJrLrFC=5vc;0{hcxDKF z!ntmgO>rVDaGmRpMI7-+mv(j~;s_LARvcpkXj|{GHu1c<1 zKI)#7RE~Dizu1lG>p-PcY2jX#)!oJlBA$LHnTUWX=lu``E)vhf9h4tYL-juZ`e|Kb z=F?C;Ou)h^cxB;M-8@$ZSH0jkVD>x-XS$ePV1vlU8&CG))4NgU(=XFH=Jb1IB7dBysS+94}Y>sjS(&YcJwhn zifzA|g$D5rW89vkJSv()I+Th4R&C$g-!CB30xkh%aw4po3$@DK2fW>}enE2YPt&{C~j}`>RYICK{ zYAPfZ&%`R}u6MYo<>d`^O#Q(dM{3>T^%J{Vu;lr#Utg4x9!Z9J%iXs(j+dn&SS1_2 zzxGtMnu^`d%K4Xq4Ms-ErG3_7n?c(3T!?rvyW=G<7_XKDv*ox`zN*^BVwUoqh{D7o zdEiq;Zp6}k_mCIAVTUcMdH|fo%L#qkN19X$%b1#Oko|u4!M*oRqdBa3z98{H#g=d%5X&D#NXhLh`nUjxi8@3oo(AgeItdJ zIrt9ieHI1GiwHiU4Cba-*nK@eHI4uj^LVmVIntU@Gwf^t6i3{;SfLMCs#L;s;P4s5oqd^}8Uil!NssP>?!K z07nAH>819U=^4H6l-Dhy`^Q6DV^}B9^aR0B%4AH=D&+dowt9N}zCK+xHnXb-tsKaV6kjf;Wdp#uIZ_QsI4ralE>MWP@%_5eN=MApv92( z09SSB#%eE|2atm9P~X2W2F-zJD+#{q9@1}L2fF|Lzu@1CAJq*d6gA8*Jjb;<+Asih zctE|7hdr5&b-hRhVe}PN z$0G{~;pz1yhkbwuLkfbvnX=<7?b(1PhxAmefKn$VS6Sv)t-UypwhEs3?*E=(pc%Dlul1V~OdWvdf z{WBX?lhfO_g$$X~hm^Bhl@U0t<|beYgT)2L_C(z@B^-63c9Ak2*Aa)iOMylfl|qyNQdO#yoJ?m2FOkhZ1ou@G%+^m z#!#(gTv8nx^34(HddDp|dcFl@&eh+&FFJc@^FL3fV2?u&9Wt|Yp3&MS)e+ez0g~Ys zY7d0n^)+ z0@K^GJTLN?XAV(0F6e>o>HCGJU5(8WsSFErs0FsO=O1u$=T~xx7HYK{7C>-IGB8U+ z&G^Vy>uY}Bq7HX-X`U^nNh+11GjG-)N1l_tG<^4Tu4+4X9KO9IrdH+eXGk|G6Tc(U zU~g7BoO!{elBk>;uN-`rGQP-7qIf9lQhj-=_~0Qyszu>s$s0FrJatSylv!ol&{29~ z7S4fv&-UBOF&cR@xpuW*{x9$R;c_ALt?{+dI&HoBKG-!EY{yE=>aWhlmNhHlCXc(B zuA-zI*?Z9ohO$i8s*SEIHzVvyEF$65b5m=H*fQ)hi*rX8 zKlPqjD*Ix1tPzfR_Z3bO^n32iQ#vhjWDwj6g@4S?_2GyjiGdZZRs3MLM zTfl0_Dsn=CvL`zRey?yi)&4TpF&skAi|)+`N-wrB_%I_Osi~)9`X+`Z^03whrnP7f z?T`*4Id`J@1x#T~L(h5^5z%Cok~U|&g&GpCF%E4sB#i3xAe>6>24%Kuu=)=HRS;Pu2wghgTFa zHqm#sa{7-~{w_039gH0vrOm&KPMiPmuPRpAQTm5fkPTZVT&9eKuu%Riu%-oMQl2X6 z{Bnx`3ro^Z$}rVzvUZsk9T)pX|4%sY+j0i)If_z-9;a^vr1YN>=D(I7PX){_JTJ&T zPS6~9iDT{TFPn}%H=QS!Tc$I9FPgI<0R7?Mu`{FTP~rRq(0ITmP1yrJdy|m;nWmDelF-V^y7*UEVvbxNv0sHR?Q=PVYRuZinR(;RjVAG zm&qlSYvaiIbVEqBwyDaJ8LVmiCi{6ESF4pO?U&7pk&CASm6vuB;n-RauPFzdr!C%1 z8pjdSUts7EbA4Kg(01zK!ZU<-|d zU&jWswHnSLIg&mTR;!=-=~z(#!UsXt%NJR|^teM8kG@8Qg_0^6Jqfn&(eENtP8D7K zvnll3Y%7yh1Ai~0+l6dAG|lEGe~Oa+3hO>K2}{ulO?Vf*R{o2feaRBolc;SJg)HXHn4qtzomq^EM zb)JygZ=_4@I_T=Xu$_;!Q`pv6l)4E%bV%37)RAba{sa4T*cs%C!zK?T8(cPTqE`bJ zrBWY`04q&+On`qH^KrAQT7SD2j@C>aH7E8=9U*VZPN-(x>2a++w7R$!sHH+wlze2X)<<=zC_JJvTdY7h&Jum?s?VRV)JU`T;vjdi7N-V)_QCBzI zcWqZT{RI4(lYU~W0N}tdOY@dYO8Rx5d7DF1Ba5*U7l$_Er$cO)R4dV zE#ss{Dl`s#!*MdLfGP>?q2@GSNboVP!9ZcHBZhQZ>TJ85(=-_i4jdX5A-|^UT}~W{CO^Lt4r;<1ps@s|K7A z90@6x1583&fobrg9-@p&`Gh+*&61N!$v2He2fi9pk9W2?6|)ng7Y~pJT3=g~DjTcYWjY9gtZ5hk*1Qf!y2$ot@0St$@r8|9^GMWEE>iB~etL zXYxn#Rvc`DV&y93@U$Z91md1qVtGY*M(=uCc}@STDOry@58JNx`bUH}EIb(n6I}i? zSYJOZ2>B6&Payu+@V!gxb;)_zh-{~qtgVwQ-V;vK7e0^Ag_$3+g+{xSVudVOY_p-R z$sXhpFSk7je2lk5)7Y2;Z847E1<;5?;z(I)55YFtgF!J;NT|eVi}q^*2sM}zyM{+s zD0phl+J>k1E7cZEGmP?1-3~RE;R$q(I5}m?MX8xi?6@0f#rD8Cjkpv1GmL5HVbTnM zAQ&4-rbkpdaoLp~?ZoW>^+t0t1t%GO2B;ZD4?{qeP+qsjOm{1%!oy1OfmX?_POQJ4 zGwvChl|uE;{zGoO?9B_m{c8p(-;_yq?b^jA({}iQG35?7H7`1cm`BGyfuq7z1s~T| zm88HpS{z54T{jxC=>kZ=Z#8G@uya3tt0$xST5V$-V<;6MA66VFg}`LLU8L=q3DmkU z)P^X8pg`ndMY*>gr{6~ur^Q@Z8LNQf*6wkP03K<|M*+cDc#XKZ`Z0$1FkI-IDRw#| za52W4MyHlDABs~AQu7Duebjgc}02W;1jgBx&I@TMDXU`LJutQ?@r%1z`W zlB8G-U$q37G1ob>Er8j0$q@OU3IwG#8HsvJM#)j=Y%~#zY`jaG%5;!(kY3*a^t>(qf6>I zpAJpF%;FQ?BhDSsVG27tQEG*CmWhl4)Ngp%}D?U0!nb1=)1M==^B)^$8Li$boCY$S4U;G^A!?24nSYHra{< zSNapX#G+0BTac|xh`w&}K!);$sA3ay%^a2f?+^*9Ev8ONilfwYUaDTMvhqz2Ue2<81uuB71 zAl|VEOy%GQ7zxAJ&;V^h6HOrAzF=q!s4x)Mdlmp{WWI=gZRk(;4)saI0cpWJw$2TJcyc2hWG=|v^1CAkKYp;s_QmU?A;Yj!VQ1m-ugzkaJA(wQ_ zah00eSuJg<5Nd#OWWE?|GrmWr+{-PpE_Dbqs&2`BI=<%ggbwK^8VcGiwC-6x`x|ZY z1&{Vj*XIF2$-2Lx?KC3UNRT z&=j7p1B(akO5G)SjxXOjEzujDS{s?%o*k{Ntu4*X z;2D|UsC@9Wwk5%)wzTrR`qJX!c1zDZXG>-Q<3Z)7@=8Y?HAlj_ZgbvOJ4hPlcH#Iw z!M-f`OSHF~R5U`p(3*JY=kgBZ{Gk;0;bqEu%A;P6uvlZ0;BAry`VUoN(*M9NJ z%CU2_w<0(mSOqG;LS4@`p(3*Z7jC|Khm5-i>FcYr87};_J9)XKlE}(|HSfnA(I3)I zfxNYZhs#E6k5W(z9TI2)qGY&++K@Z?bd;H%B@^!>e2Wi@gLk)wC)T93gTxdRPU7uh z)`$-m(G2I5AuK52aj!fMJR|d^H?0X~+4xSpw zqNRtq5r8hic*{eAwUT<=gI5uXLg)o5mg4XnO^T+Rd+{l)<$Aqp{+RxhNYuX^45W0k z5$t%+7R;dX$`s6CYQYcims>5bNt+k&l_t%C9D-6sYVm%Y8SRC#kgRh*%2kqMg2ewb zp_X*$NFU%#$PuQ@ULP>h9Xw`cJ>J-ma8lU`n*9PcWFpE%x0^}(DvOVe2jz@ z0^2QOi0~t!ov?jI{#bw~`Aj5ymQW@eruRg`ZNJ5IT5_5AHbQ?|C>_7rwREf2e2x&L zlV8xdOkp_*+wdaqE?6bmdrFfaGepcj=0AI<+c=Tg^WB9BhFx?SvwoVdTEm&zPy@Vs zPs2mVPiw1n_h?Xi6!+w)ypsFXXuM>gIY(J+1N6r!sJ{+r1%BzRF20!D;bN>L^?O8n z(5|x2p^Q6X`!pm3!MMFET5`nJXn>tK`fFAj5Eo&t6;F>TU_4G93YGyzvF2_fB& zfE8(dq?R@@&Wh8~%G~rDt1+e)96O5)by_%;G~Zv`TpmZ)vY@BkAan*zEy(s`*{-@U z;$WPjoNx~m?`6Z;^O=K3SBL3LrIxfU{&g)edERkPQZK!mVYU-zHuV0ENDq^e<-?^U zGyRcrPDZZw*wxK(1SPUR$0t0Wc^*u_gb*>qEOP102FX|`^U%n*7z=wM@pOmYa6Z=-)T%!{tAFELY2`dTl3$&w! z7sgKXCTU(h3+8)H#Qov19%85Xo+oQh?C-q0zaM_X2twSCz|j_u!te3J2zLV#Ut_q7 zl+5LGx#{I`(9FzE$0==km|?%m?g~HB#BSz2vHynf1x14mEX^~pej*dhzD|6gMgOJ_ z8F_<>&OIz;`NSqrel?HI-K(|ypxwz}NtX!CF3&T(CkuYOnKS&%lUSU44KsgS`L>!w zl{MoT4`t=+p8>@88)Ea%*hOIkxt#b4RfrwRMr91UF_Ic~kV;|+dRW0a8Vl725+gsvtHr5 z>?3fai&9NmU|3;-nAu8OB|<(-2Kfub4MX&1i}dDd=R~Dk=U-Vr=@&lfEIYU~xtHHO z4TKt=wze`qm=69lD)sOOkZ;$9=0B#*g@X6xPM-%zG*rCXkN%eRDEUp$gAaEd29t&T zRTAg##Sk+TAYaa(LyTD__zL3?Z+45^+1o}(&f<~lQ*-z7`Um^>v@PKqOunTE#OyKFY^q&L^fqZgplhXQ>P3?BMaq6%rO5hfsiln7TppJ z>nG9|2MmL|lShn4-yz0qH>+o;Fe`V!-e*R0M|q~31B=EC$(bQZTW^!PrHCPE4i|>e zyAFK!@P}u>@hqwf%<#uv*jen5xEL|v!VQEK!F`SIz_H8emZfn#Hg}}@SuqPv+gJ@- zf3a`DT_Q#)DnHv+XVXX`H}At zmQwW2K`t@(k%ULJrBe6ln9|W8+3B*pJ#-^9P?21%mOk(W1{t#h?|j0ZrRi_dwGh#*eBd?fy(UBXWqAt5I@L3=@QdaiK`B_NQ$ zLXzm{0#6zh2^M zfu>HFK^d`&v|x&xxa&M|pr))A4)gFw<_X@eN`B1X%C^a{$39fq`(mOG!~22h)DYut z(?MONP1>xp4@dIN^rxtMp&a^yeGc8gmcajyuXhgaB;3}vFCQFa!pTDht9ld9`&ql`2&(dwNl5FZqedD^BP zf5K1`(_&i7x-&rD=^zkFD87idQrk(Y?E;-j^DMCht`A8Qa5J-46@G_*Y3J+&l{$}*QCATEc9zuzaQGHR8B;y*>eWuv)E##?Ba3w= zZ|v(l{EB`XzD#|ncVm#Wy?#Nzm3bS1!FJ70e{DGe$EgNDg7<_ic^mJSh&Xc|aTwCrTv;XkW~UlS&G%KyLklCn}F^i(YP(f z{cqH%5q9ND_S;l$HRP$Q@`D=F*_1$CXIA5X@|V&Vir$NQ$vCx!b&LGCR<-2y)m%HI zxeeyQIjiWcf4uD9+FP+EJ`&$oJ%$R(#w~GjqP|aTQj#d(;l#rq$vcM&Y4ZQ_i{Kpx z?k2BtoKb?+1-EVmG^ne-W%8+y?i#J5N5g8f^qpH5(ZZp7$u+?I9GB+&MREX?TmVV$ zA}Ps=^CkD^sD9N;tNtN!a>@D^&940cTETu*DUZlJO*z7BBy`Rl;$-D@8$6PFq@tz0 z=_2JMmq-JRSvx`;!XM|kO!|DENI-5ke8WR*Zj#vy#Nf1;mW-{6>_sCO8?sVWOKDM| zR(iaZrBrzlRatUzp_Y|2nOXnY2G%WLGXCo9*)th_RnXvXV=q;WNAimI98!A54|$&OCCG%$4m{%E&o?S|Qx<4K~YGmM1CS!vZAzLN%d znbZsw6ql=XkiwSbNofNeA42q8#LH6Rk(u@z172O#6K>Sb{#`t#GUgpd{2;D(9@I_9 zwsY(6Go7RmOThs2rM3|Z#Vbs}CHPLgBK6gE8;XkJQDx~p5wJ?XkE(0<^hwnt6;$~R zXCAzMfK@`myzdkkpv*ZbarVwCi&{-O#rswrb-#x4zRkxfVCq;mJLic|*C92T?0CYv z)FCqY$xA(QZmggPocZqQj0Rc?=Afna`@fpSn)&nSqtI}?;cLphqEF3F9^OZfW9@HDunc^2{_H)1D9(O}4e zJMi_4(&$CD{Jf5&u|7#Iq*F~)l!8pAzNrX^<&wfEu~}Ipslzx=g^ff2?B9SnV=!$ zv&K0`hMN6BVIusHNX-lr`#K?OG1S*S4rCQaI3ea(!gCl7YjxJ3YQ)7-b&N*D8k><*x|47s3; z4f~WTWuk|Qd*d*DICV}Vb0YSzFZp5|%s4}@jvtTfm&`|(jNpajge zD}@CMaUBs+b?Yu6&c#18=TxzMCLE76#Dy=DLiq_a_knQX4Uxk$&@3ORoBFK_&a>`QKaWu^)Hzrqz{5)?h3B_`4AOn{fG9k zEwnjQb>8XRq!k?rmCd6E**1cY#b9yczN4mD%GLCeRk}{TmR1*!dTNzY;(f!B0yVuk zSjRyf;9i@2>bdGSZJ=FNrnxOExb075;gB z*7&YR|4ZraFO#45-4h%8z8U}jdt?83AmU3)Ln#m3GT!@hYdzqqDrkeHW zU#R`Z8RHq996HR=mC}SRGtsz07;-C-!n*ALpwwBe~loM)YqMH)Um$sH0RbTTzxFd)h1=-w5Yl3k|3nQ zZG>=_yZ7Lsn=b8_MZI+LSHLGYSSCc?ht~7cv#39>Moz6AS}5 zus?xge0PGdFd2FpXgIscWOyG}oxATgd$yl0Ugf_&J_vwt`)XWx!p*gE_cWU(tUTnz zQS}!bMxJyi3KWh^W9m zxLcy``V@EfJzYjK@$e7Yk=q!kL8cd3E-zpc*wwvGJ62O!V;N zFG7Y?sJ+^a%H1;rdDZRu2JmGn6<&ERKes=Pwx)GG-nt73&M78+>SOy!^#=gvLB)2H zjv!J0O`-zft|0Jv$3k5wScY)XB+9leZgR5%3~HtZA=bCg7=Dn+F}>2lf;!*1+vBtf z9jhmqlH=t5XW{0MC7Y~O7jaju&2`p!ZDLGlgnd~%+EJ%A#pIByi-+EOmoLVoK&ow8 zTDjB%0hxhiRv+O3c2*y00rMA=)s|3-ev7emcbT43#izku7dvaDXy1IMV0ahjB9yzi z9C9fN+I2Mzt1*{`a6B?+PdWHiJ5fH}rb2t>q)~3RfCxmyK^y5jN7Pn(9DFh61GO%p zuBErj=m|bDn_L8SINU)Z&@K*AgGz+SUYO_RUeJt=E0M+eh&kqK;%Y1psBNU<4-s9# ziHFr7QP6Ew=-2CdfA#Bf|EsctH;<&=Hsd>)Ma8NvHB$cpVY@}TV!UN}3?9o@CS5kw zx%nXo%y|r5`YOWoZi#hE(3+rNKLZ2g5^(%Z99nSVt$2TeU2zD%$Q(=$Y;%@QyT5Rq zRI#b><}zztscQaTiFbsu2+%O~sd`L+oKYy5nkF4Co6p88i0pmJN9In`zg*Q;&u#uK zj#>lsuWWH14-2iG z&4w{6QN8h$(MWPNu84w1m{Qg0I31ra?jdyea*I~Xk(+A5bz{x%7+IL}vFDUI-Rf{! zE^&Dau9QxA2~)M98b42(D6Q}2PUum0%g>B?JS?o~VrP+Go2&c-7hIf7(@o1*7k$zS zy@o5MEe8DoX$Ie(%SZByyf9Xf9n8xkoX}s6RiO1sg*kAV^6EAAz$>*x^OmIy!*?1k zG+UQ|aIWDEl%)#;k{>-(w9UE7oKM#2AvQud}sby=D7$l6{$}SE8O9WgHM_+ zJ?tHeu@Pi93{AuwVF^)N(B~0?#V*6z;zY)wtgqF7Nx7?YQdD^s+f8T0_;mFV9r<+C z4^NloIJIir%}ptEpDk!z`l+B z5h(k$0bO$VV(i$E@(ngVG^YAjdieHWwMrz6DvNGM*ydHGU#ZG{HG5YGTT&SIqub@) z=U)hR_)Q@#!jck+V`$X5itp9&PGiENo(yT5>4erS<|Rh#mbCA^aO2rw+~zR&2N6XP z5qAf^((HYO2QQQu2j9fSF)#rRAwpbp+o=X>au|J5^|S@(vqun`du;1_h-jxJU-%v| z_#Q!izX;$3%BBE8Exh3ojXC?$Rr6>dqXlxIGF?_uY^Z#INySnWam=5dV`v_un`=G*{f$51(G`PfGDBJNJfg1NRT2&6E^sG%z8wZyv|Yuj z%#)h~7jGEI^U&-1KvyxIbHt2%zb|fa(H0~Qwk7ED&KqA~VpFtQETD^AmmBo54RUhi z=^Xv>^3L^O8~HO`J_!mg4l1g?lLNL$*oc}}QDeh!w@;zex zHglJ-w>6cqx3_lvZ_R#`^19smw-*WwsavG~LZUP@suUGz;~@Cj9E@nbfdH{iqCg>! zD7hy1?>dr^ynOw|2(VHK-*e%fvU0AoKxsmReM7Uy{qqUVvrYc5Z#FK&Z*XwMNJ$TJ zW1T**U1Vfvq1411ol1R?nE)y%NpR?4lVjqZL`J}EWT0m7r>U{2BYRVVzAQamN#wiT zu*A`FGaD=fz|{ahqurK^jCapFS^2e>!6hSQTh87V=OjzVZ}ShM3vHX+5IY{f^_uFp zIpKBGq)ildb_?#fzJWy)MLn#ov|SvVOA&2|y;{s;Ym4#as?M^K}L_g zDkd`3GR+CuH0_$s*Lm6j)6@N;L7Vo@R=W3~a<#VxAmM&W33LiEioyyVpsrtMBbON+ zX^#%iKHM;ueExK@|t3fX`R+vO(C zucU#Xf>OjSH0Kd%521=Sz%5Y!O(ug(?gRH@K>IUayFU~ntx`Wdm27dB-2s@)J=jf_ zjI-o;hKnjQ|Lg~GKX!*OHB69xvuDU zuG-H48~inKa)^r539a{F)OS`*4GShX>%BR)LU~a-|6+sx&FYsrS1}_b)xSNOzH|Kv zq>+1-cSc0`99EsUz(XWcoRO)|shn>TqKoQBHE)w8i8K`*Xy6(ls%WN_#d}YC^)NJ; zzl8!Zduz^Gg8*f0tCWnLEzw6k5Fv!QWC1x4)3r}+x~@#O8_)0>lP-@3(kFwLl%%Mz(TpATVnL5Pl2Gahw45QXI~>Hrw))CcEs@PP?}4^zkM$ z@(?H6^`Jl?A=(&Ue;W0`*a8&fR7vde@^q^AzX^H#gd~96`Ay^_A%?;?@q@t7l7iGn zWms#2J|To4;o1?3g3L!K_chdtmbEg~>U>$5{WO@Ip~YE&H($(^X6y_OBuNHkd0wu= z4rXGy#-@vZ?>M<_gpE8+W-{#ZJeAfgE#yIDSS?M?K(oY@A|FaS3P;OjMNOG% zGWyZWS(}LJCPaGi9=5b%sq$i!6x@o(G}wwfpI5|yJe24d_V}cT1{^(Qe$KEMZ;>I@ zuE6ee%FLgem>CKEN8SeY)fpK#>*lGcH~71)T4p|9jWT;vwM@N!gL}nCW=Oi6+_>K2 zl4sWXeM1U}RETA~hp=o3tCk+?Zwl#*QA>Wwd|FlUF0)U;rEGPD1s0Syluo zfW9L(F>q9li8YKwKXZrp*t)N9E;?&Hdbm-AZp2BcDTHO6q=tzVkZsozEIXjIH`tm} zo2-UleNm*Lj7zgvhBph_|1IggkSuW~S(9ueZEfao8BuzqlF(a+pRivTv(Zb zXFaHwcuovdM#d+!rjV7F<^VW&@}=5|xj!OUF)s0zh|8yzC)7!9CZB+TLnycoGBsDF z$u&j={5c(4A$iik;x6_S96Krw8--+9pGY+*oSVTIuq;$z8*)W8B~rMX_(U6uM}!Gc`T;WfEKwI84%)-e7j}>NA(O_)3Vn9 zjXxY1Fnx3Fx%CFpUHVu0xjvxgZv}F9@!vC!lD|05#ew3eJ}@!V&urwRKH`1f{0e^o zWvM1S@NbI6pHdzm33pza_q;#?s%J*$4>10uYi4l%5qi|j5qh+D=oqSJR=7QwkQh>>c$|uJ#Z@lK6PMHs@ zyvnnoOSkGQkYz#g>||xN&1fV)aJb*y--Y`UQV~lt!u8yTUG59ns1l7u>CX2F>9fl; zB)zH3z^XHmSU{F_jlvESvaNL&nj^;j)29~1LcTYw>(6}>bt0hiRooqm0@qTj%A&P9 zKmexPwyXG@Rs1i+8>AJ;=?&7RHC7Mn%nO>@+l?Qj~+lD376O2rp)>tlVHn8MKq zwop1KRLhUjZ|+6ecGIAftSPT*3i94=QzYCi_ay+5J&O(%^IsqZ!$w-^bmd7ds$^!q z;AkC;5mTAU>l0S$6NSyG30Ej?KPq@#T)^x#x?@U~fl2m$Ffk)s6u|iPr!)-j0BlA7p3E*A|My8S#KH;8i-IQq7Q*F4*ZVPe<{^SWz_ zr?!6cS+@|C#-P~d#=W1n7acn8_pg#W-lcyf+41zwR+BU6`jUkP^`*wgX)FxEaXzoi z8)?FE*97Yqz|b@fR1(r{QD363t260rQ(F||dt9^xABi+{C*_HL9Zt5T;fq|#*b}=K zo5yj_cZB(oydMAL&X(W6yKf>ui?!%(HhiHJ83EA|#k0hQ!gpVd( zVSqRR&ado+v4BP9mzamKtSsV<|0U-Fe2HP5{{x&K>NxWLIT+D^7md{%>D1Z-5lwS~ z6Q<1`Hfc+0G{4-84o-6dr@)>5;oTt|P6jt9%a43^wGCslQtONH)7QXJEYa!c~39 zWJpTL@bMYhtem1de>svLvOUa*DL7+Ah0(_~2|ng`!Z!qiN}6xL;F}<%M8qWv&52-Y zG*1A&ZKlp~{UFV%Hb_*Re({93f7W*jJZMV-Yn|<+l3SPN+%GuPl=+tSZxxr%?6SEc zntb0~hcK691wwxlQz_jSY+V_h+0o`X!Vm{;qYK$n?6ib1G{q>a%UejzOfk6q<=8oM z6Izkn2%JA2E)aRZbel(M#gI45(Fo^O=F=W26RA8Qb0X;m(IPD{^Wd|Q;#jgBg}e( z+zY(c!4nxoIWAE4H*_ReTm|0crMv8#RLSDwAv<+|fsaqT)3}g=|0_CJgxKZo7MhUiYc8Dy7B~kohCQ$O6~l#1*#v4iWZ=7AoNuXkkVVrnARx?ZW^4-%1I8 zEdG1%?@|KmyQ}tploH>5@&8Cp{`)CxVQOss&x|Z7@gGL3=tCVNDG!N9`&;N$gu^MDk|`rRm=lhnXAJ5v1T)WTz)qvz|Dw zR?{}W4VB(O6#9%o9Z^kFZZV*PDTAWqkQ8TH!rti8QIcR&>zcg3qG}&A( zwH^K8=`1C1lRfhrX{IvNn9R9!$UMC%k(;;VH%`S0h_on|Gh6qDSH&#}*m-u{;p~WB zF$_I~xx!RxVrxNQdr@3T>{F#^D{@N9OYC9LsV62F_Z1KYQ5yk*C5WQ4&q}Kz(I{9UWWf?LIcCZicB1EO_FUH*a9QKS(4IR%#D5DTi_@M}Q_-4)J4d zz@!vR0}5MPAOK(#uL+$7XOcP$5SS#*EK9Rt6XN%}HB7@`8S^gNRk!HLv(CvCjX4o= z>9scPwWbE!F8T=@x9^;s-OF2!eO(!gL9$-AmzUiDnu&QS4If5ea2T070n1-IyNhck z9$J8b!he3@q5qB-cQ;5ymVIXXn46kK0sqKZV+3s3^mac=3~BrCW})WNrrRs1KtMmg zLzwXYC?@_H#s3W4D$W0rh%WL|G<1$$uYdptPbxy0ke!c%v#x9I=2?S)YVkg1X$W^cB!i>B{e9wXlm8AcCT8|verIZQngj>{%W%~W0J%N`Q($h z^u3}p|HyHk?(ls7?R`a&&-q@R<94fI30;ImG3jARzFz<(!K|o9@lqB@Va+on`X2G) zegCM8$vvJ$kUwXlM8df|r^GQXr~2q*Zepf&Mc%kgWGTf;=Wx%7e{&KId-{G}r22lI zmq%L6Y-M*T$xf8 z#kWOBg2TF1cwcd{<$B)AZmD%h-a6>j z%I=|#ir#iEkj3t4UhHy)cRB$3-K12y!qH^1Z%g*-t;RK z6%Mjb*?GGROZSHSRVY1Ip=U_V%(GNfjnUkhk>q%&h!xjFvh69W8Mzg)7?UM=8VHS* zx|)6Ew!>6-`!L+uS+f0xLQC^brt2b(8Y9|5j=2pxHHlbdSN*J1pz(#O%z*W-5WSf# z6EW5Nh&r<;$<3o1b013?U$#Y!jXY)*QiGFt|M58sO45TBGPiHl4PKqZhJ|VRX=AOO zsFz-=3$~g#t4Ji9c;GFS9L~}~bzgCqnYuJ-60AMDdN7HZt8_$~Of{oXaD3HVn9zkH z`>#xQNe=YpWTq_LcOoy}R`L<_4il7w4)QH4rl?AUk%?fH##I>`1_mnp&=$-%SutYT zs}sSNMWo;(a&D()U$~PG0MvZ#1lmsF&^P4l_oN#_NORD-GSmR{h_NbJ^ZdY#R9#qW zKAC%V*?y~}V1Zh#d|-z1Z8sy5A+}*cOq$xk@Pn&{QffzG-9ReyPeEhqF%~Z3@|r(s z3(wA&)dV~fELW*&*=!~l9M=7wq8xE(<@)BjjN8bUiS8@N9E{wi+Dd!V1AtT;Nl}9> zTz`2ge2Jn#Dlg1kC%oFlOe<>?jYC`Asr^%i4hH;S`*qZTPRan2a9Kjj=0aq{iVi2Z z87PZt$d(LAm_{92kl+2Z%k3KGV;~gsp;C>k?gMYZrVIzaI|0D+fka9G_4v>N96*8T zI(C8bj?A7l%V&U?H_IpSeCvf7@y1e?b>G7cN382GVO0qAMQ93(T*<*9c_;%P1}x2l zi8S$s<=e_8ww%DaBAf4oIQ7}U7_48$eYpo}Fb+F|K|43IAPR1y9xbqPPg6er{I7xj|=>-c%pGBRLn1~=5KbAb1mJAx=z(loN!w{49VkEthF>*OX z)=gqXyZB5%5lIWYPWh~{!5pSt43-)-@L@x=pmiuKP-3Cwq8qSxGNwaTT4->BWEjxk zUjr)z7WrBZB5u3iV>Y_>*i~*!vRYL)iAh5hMqNzVq1eeq=&d9Ye!26jks{f~6Ru&c zg$D;^4ui#kC`rSxx`fP!zZ^6&qSneQzZRq0F*V4QvKYKB<9FC%t#)Tik%Zq*G*IOW z3*`2!4d)!3oH>GxVcXlorJDt+JnH)p{~olYBPq|>_V@8=l#(f*diW=L+%>rfWCcPQ z#H^ksQt15Z5Uc4ODq8_JwD5^H&OGqyH6E@MabJQO>s`?bqgA6}J_QpytW{2jH#eCN z8k7y*TFZ2lj2B|1CB(@QZedFfPhX|IQbKMI;$YK>9Zla0fsU7}an6(kP;sXpBWLR` zJ#z_kk!`JJC7h(1J!+G)gL2WB2&0*~Q!%s??}GH?=`hU@03xOwU} z6s7?tGySLz!%(MwxQRiF)2(vR2wQX`YB}u&I-S+RR)LQcyH407#-{*pWLJJR?X|5 zsAl2k{&0N-?JArn@)9YTo-5+gl}R~XkbZM*5AOjPrcikpE3P?p0oN^?H+5+n)}Qxe z*RQ!-eu0RxPyF8B=}xnseNpQMXFU$d^=(G%kUd&|!BHSm7bXoGR$WA+%yjuA{|S>u z?9N6JDhS+ui~rd?wY_t7`p)|qKIMM>6jz%$jv4hc_YUDjF6-%5muq|SNuoji2)|qK zNY5+oWMe+5vu{I*grk6xlVk;(J)uuy13G`VDbj(~Vz9lA)_;$aj?=-cmd#h~N0mn{ z9EIS_d4C=L3H;Pl^;vcpb&-B+)8vt%#?gn5z>#;G{1L&8u8cXJYADMUsm9>%*%)&F zsi&I{Y=VUsV82+)hdNgDWh^M7^hMs|TA0M269^|RIGfdX1MetV2z`Ycb&_Mn4iRI! zeI6O}O9mOhN6pzfs5IfMz#Gxl`C{(111okA8M4gijgb~5s7QTyh84zUiZZ^sr1^ps z1GO`$eOS@k@XP^OVH|8)n}Wx)fKHoGwL&5;W?qEf5Jdsd!3hf7L`%QNwN0gGBm^2= z@WI+qJMJG1w2AS9d@Dt$sj_P$+S2kh7+M72^SfcdBjQEtWQ5?PT&a~G9hOo6CtS>h zoghqoR;sk{X)`ZK-M|lu{M}0>Mrs^ZW@ngC?c$26_vYKDBK^n7sFiod_xV#XcPL!^ zRPyqD{w^9u{oA3y73IW0 zH;%xop$r(Q=bq=JaLT%myEKD_2&?L@s6TzsUwE#g^OkiU6{lN)(7I?%a;_%r5_^@d zS-Z)Q-2o|~?F~f`sHlhNhiZk;!CW;3Ma6{xPlBjJx8PXc!Oq{uTo$p*tyH~ka`g<` z;3?wLhLg5pfL)2bYZTd)jP%f+N7|vIi?c491#Kv57sE3fQh(ScM?+ucH2M>9Rqj?H zY^d!KezBk6rQ|p{^RNn2dRt(9)VN_j#O!3TV`AGl-@jbbBAW$!3S$LXS0xNMr}S%f z%K9x%MRp(D2uO90(0||EOzFc6DaLm((mCe9Hy2 z-59y8V)5(K^{B0>YZUyNaQD5$3q41j-eX))x+REv|TIckJ+g#DstadNn_l~%*RBSss_jV3XS&>yNBc8H2jo(lwcLz-PuYp< z7>)~}zl$Ts0+RFxnYj7-UMpmFcw_H zYrsXM>8icD)@Iauiu_(Y#~Iyl)|pj@kHkWvg2N$kGG(W>Y)nfNn%z2xvTLwk1O2GQ zb^5KAW?c%5;VM4RWBy}`JVCBFOGQWoA9|+bgn7^fY3tSk1MSZccs9&Fy6{8F>_K@? zK(z=zgmq1R#jGE^eGV`<`>SP9SEBx!_-Ao|VZq6)-rUpd^<2GgVN&uHiM{0zA9kI( z<1^1%*uE$?4mXV@?W8}fvnBOpfwCo^?(a0E402!pZi&Kd5pp$oV%2Ofx<}YC-1mynB3X|BzWC_ufrmaH1F&VrU&Gs+5>uixj*OJ*f=gs9VR8k^7HRR$Ns|DYBc*Slz>hGK5B1}U+}#j0{ohGC zE80>WClD5FP+nUS?1qa}ENOPb2`P4ccI<9j;k?hqEe|^#jE4gguHYz-$_BCovNqIb zMUrsU;Fq%n$Ku_wB{Ny>%(B&x9$pr=Anti@#U%DgKX|HzC^=21<5Fn6EKc#~g!Mcj zJrI(gW+aK+3BWVFPWEF*ntHX5;aabHqRgU-Nr2t++%JRPP7-6$XS|M8o&YSgf3a9A zLW*tSJxoe1?#T4EocApa*+1kUIgy7oA%Ig9n@)AdY%)p_FWgF-Kxx{6vta)2X1O5y z#+%KQlxETmcIz@64y`mrSk2Z17~}k1n{=>d#$AVMbp>_60Jc&$ILCg-DTN~kM8)#o$M#Fk~<10{bQ>_@gU2uZE z*eN~mqqQC*wh{CI(!xvRQ^{jyUcvE~8N)S0bMA^SK@v;b7|xUOi63X~3Qc>2UNSD1) z7moi9K3QN_iW5KmKH>1ijU41PO>BvA6f1;kL)6io%^r>?YQ#+bB;)Rzad5;{XAJGeAT#FnDV0$w2>v|JeFIB zZ>8vmz?WVs78PuCDiHfb@D0Yi;2#%){*#?bY4dpta6dSjquGLcOw?Z{nxg98mN^4* zj&^!WMUQ_zFp+}B|G0vcNsk8(2u9(LAPk5ogKt%zgQ4^1#UCd;`-W#X8v{YyQ_m9g z8`jydw>>@1J{Q*q#5^cHVA~xR9LR3Hl@^bx)`IBKmj+Gmye36;xwL0>sS|mV+$~%b zC;2wEm&Ht3#6P|2Y0XQ+5t-aI)jn{o%&ZHWvjzEtSojFgXxNKO^e(RmM`gsJ4GrR8 zKhBtBoRjnH`mD$kT;-8ttq|iw?*`7iTF_AX<^Qe3=h8L^tqz$w$#Z@Z$`C579Jeeu ztr0z~HEazU&htfG@`HW!201!N(70hCd{%~@Wv)G*uKnJZ8>hFx`9LnYs;T>8p!`5T zx#aXXU?}B{QTV_Ux(EMzDhl-a^y^f5tRU;xnOQoN)pThr4M>-HU)As8nQ34-0*sab&z<2ye-D_3m&Q`KJJ|ZEZbaDrE%j>yQ(LM#N845j zNYrP)@)md;&r5|;JA?<~l^<=F1VRGFM93c=6@MJ`tDO_7E7Ru zW{ShCijJ?yHl63Go)-YlOW2n3W*x%w||iw(Cy>@dBJHdQl){bBVg{wmRt{#oXb9kaWqe{bJPmGE$$ z_0=cmD9dVzh<8&oyM8rK9F^bufW$Bj2cFhw&f*oKKyu$H{PI=Aqe^NL6B=dkMEAk& zE3y&F=x;e|!7kMn%(UX>G!OE$Y$@UyME#d;#d+WLmm@W@y!sboiIox^DZPB|EN<>7 z57xm5YWlFUGyF|{<*;b&Cqm+|DC8{rB9R@2EFHGL^NX*l#AcDpw6}bCmhY7!(Gv{s zm^eYNvzyJLQA#GhmL*oSt^Uulb5&ZYBuGJTC>Vm9yGaZ=Vd--pMUoDRaV_^3hE9b*Pby#Ubl65U!VBm7sV}coY)m zn1Ag^jPPLT93J{wpK%>8TnkNp;=a@;`sA7{Q}JmmS1bEK5=d@hQEWl;k$9M-PYX~S zayGm;P(Wwk23}JR7XM~kNqba`6!Z+Wt2|5K>g_j3ajhR>+;HF?88GBN!P; zr6sQ8YYpn%r^gbi8yYK7qx6U5^Tf<|VfcR$jCo`$VMVh_&(9w@O?|o3eRHq*e*#P z8-==G)D?vB3Zo~b-dkx8lg0^=gn`9FUy?ZzAfWQd>>@cyqF!sHQ_S&@$r&tTB~Lxq zAjAZTK~?J{A|L3)8K>S{`Qf%131B>?<~t=w!D{;olQ>#31R#{go`a9DOy+H*q5t+; z^*Ka!r@#8tk?~tQbylaG-$n#wP2VzIm3vjrZjcmTL zl`{6mhBhMKbSWoGqi;g3z1@G0q!ib`(Zz_o8HG_*vr8U5G|vhZn26h`f~bO&)RY0; zw(CWk*a_{ji_=O9U}66lI` zCm32)SEcAo5)5k>{<8DLI@Zz)*R29BB!^wF;WZRF9sAi39BGObmZzg?$lUn6w1rYPHSB^L4^AN zLObEaUh7TXpt6)hWck#6AZV(2`lze<`urGFre|>LUF+j5;9z%=K@&BPXCM)P$>;Xc z!tRA4j0grcS%E!urO^lsH-Ey*XY4m&9lK(;gJOyKk*#l!y7$BaBC)xHc|3i~e^bpR zz5E-=BX_5n8|<6hLj(W67{mWk@Bfc){NGAX z5-O3SP^38wjh6dCEDLB#0((3`g4rl}@I(&E8V2yDB=wYhSxlxB4&!sRy>NTh#cVvv z=HyRrf9dVK&3lyXel+#=R6^hf`;lF$COPUYG)Bq4`#>p z@u%=$28dn8+?|u94l6)-ay7Z!8l*6?m}*!>#KuZ1rF??R@Zd zrRXSfn3}tyD+Z0WOeFnKEZi^!az>x zDgDtgv>Hk-xS~pZRq`cTQD(f=kMx3Mfm2AVxtR(u^#Ndd6xli@n1(c6QUgznNTseV z_AV-qpfQ0#ZIFIccG-|a+&{gSAgtYJ{5g!ane(6mLAs5z?>ajC?=-`a5p8%b*r*mOk}?)zMfus$+W~k z{Tmz9p5$wsX1@q`aNMukq-jREu;;A6?LA(kpRut+jX?Tt?}4HGQr}7>+8z4miohO2 zU4fQ?Y8ggl%cj&>+M+)TTjn8(?^%`~!oAt#ri8gIbzIig$y#d7o##077fM9sCu%N9 zOIsq4vyox6`itu*j{eOD<$gTZd-$JuyM^cM>{?v<8# zS1yN%R0zRy&>+D*Gv-&S80?JF+Y|c^^IJWDnfy06MI2{NFO-x4JXsb@3Qp;EnL!a{ zJwKwV@mO zYVGvNmeJ!;+ce+@j@oo-+`DaPJX|h@7@4BD`QEdP?NKkYzdIa3KrZt%VUSsR+{b+| zk?dSd#9NnVl?&Y$A{-OtZ>wk%mWVF5)bf`)AA2{EFapIS4jil69Xan>*J^6Juou&`oJx|7-&|@8z?$ z2V#jm!UHstCE*qM{OGtqYY8q+x%SL6&aGY!a>@d=_G~^0;+7dY9P`oJ*)67*9Kx*O zKitC5V3g5;&L-fa37?eN=;V_c^L-ph_uKv5)Q`&!Z!RPlDWA2{J%a2q@_*?-cn@bH zIt)+mA@HaJj2RV+-MNc#y#Vji*N~m!ZyrYyg-7UK4PYK4F7Y$3Y%@Lk6iPp=I96N> z!;ih(KtZMB23*v{`5cJ}^4D*P!k1&OfU&1%borv_q|7jfaV7fL+wwx8Zp*b}B_O>NRSeJeM zpvw3M`=vSYjFYQ11kx1xqOnJ@degPh&SyXnWz-l719EiW17Yo?c~Bh~;R$MOl+jzV zM1yTq-1**x-=AVR;p0;IPi`#=E!G5qIT>EFE`Bn<7o*8!aVd7?(CZT=U9^Gi3rmWUQG z0|GaP9s$^4t_oLCs!fInyCoB(d?=tZ%%Bb2Y+X&7gvQ6~C4kU%e$W_H;-%XSM;&*HYYnLI z>%{5x_RtSUC~PI4C0H^>O%FixKYVubA>#72wexd}Cgwuw5ZYTvcN2ywVP(dO=5975 zCjo)mOa2Bo&ucEsaq8wi1{h*brT(H=XrTOy*P>?0%VV1QDr09X+Je!T)JT`02?gjX zT@B8}h|;4lH35Guq2gKZT?ags-~Ts~S=poPnQ_T1*?U|{$jaur_PjQ6WmF_(XLFG)d#|iiBC=&B zp}1eOQvQ!3UpL?K`=8hAzMkv#a^COr`J8i}d!BPX&*xp-LL#qse~mOtxI-}{yPRNV zJNTL1{7A55F~K>0e&Os%MwQ~?n1>QV=j!8o_`^-&*E|Q-L9DNr%#6sw8kQVE3E|*}$aAoO$@27ei1w=+zU%?AA!;mf#!%IV*w_D=u516!Kz1F0-WnyVB`I6F1Pc3r1=0iT<_(pCyk>@22z1$w$@M>7AIuk6+ zRG&MFVQ_7>5DLoR5HeOa$?2SA(v2u!#8;5I(ss%=x9U#R zU62n~&)22RTTsp${}6C&$+l&0skFVX%ACgc$(iQ#DVRRz!`Y+b>E?;ib(TH#6Wa=} zs(q_;SA|fhyEo7Ix%rAY9j=Ul^Rzd`3ABf+yO@~h@Rh=wo`?;8PdHE1AUo34r7izy znAr`;VavQueSu7bD5r^nXTERcW(P-{2SOSfF1x0cW1Nczvj0}@!!upORN1%_-b2bh zGt#zokJz&SveJRzlUK4DruxR(YuHEAmB%F}buU`*pAzJ7Mbgs4sg;H@&6x*wxvGm6 z>KH@ilsvvdl@CGfm4T+$agodrB=md8ygG!|O=r@FY>S_zX%*)mqf?XBX*chhQ9uPP z-(T(24)})vWD*{bQM5_hy3CD8C>anuNtCXMkG7T?Yew^>=PK!~Hlr0{-0h0cNAJ8> zRMzLFz7aJv)Yh)_s)^L&L*nDV@qfeg>_<`z1z(?s}}3tE4h|7_taB> zPfmmOCFZ8%>`gyf1@|7t3;e~mwBRCDDw(Rrt>@O}obs#1?!W((+9>d$b7t!{&wR!P ziQbn0@j=&sw={`s##Uc@uS^(tbShjtsk=qrU1LW0lu}BplIfzv{fwxNsSaG~b|ryo zTQ}YXfp6o?^sSHW>s~m;l@h6wFbIPw{Z(IqO1u){{hEZgrTdF0o$n;hYIm`h5ejym zWt^w~#8p1J)FtfY6LvGmNQ~#n>4#mN4B^ zjrQk)Zt%k}GBRD>l`<~og6N_{6HYKDtsAtd%y?KbXCQR(sW8O(v_)kwYMz|(OW zsFz6A1^abSklOl`wLC-KYI8x=oMD^qZBs}}JVW@YY|3&k&IZ_n2Ia@5WiK>buV!E- zOsYcS4dFPE7vzj%_?5i2!XY`TiPd*jy>#C`i^XG8h?f35`=)s`0EhQBN!+YrXbpt( z-bwg_Jen`w<+6&B`hldU%rr&Xdgtze>rKuJ61AI12ja-eDZZX-+u1H>Sa|7pCine9 z&MEhmT7nq`P!pPK>l?I8cjuPpN<7(hqH~beChC*YMR+p;;@6#0j2k$=onUM`IXW3> z`dtX8`|@P|Ep-_0>)@&7@aLeg$jOd4G`eIW=^dQQ*^cgKeWAsSHOY?WEOsrtnG|^yeQ3lSd`pKAR}kzgIiEk@OvQb>DS*pGidh`E=BHYepHXbV)SV6pE2dx6 zkND~nK}2qjDVX3Z`H;2~lUvar>zT7u%x8LZa&rp7YH@n@GqQ65Cv+pkxI1OU6(g`b z?>)NcE7>j@p>V0mFk-5Rpi`W}oQ!tUU&Yn8m0OWYFj|~`?aVFOx;e`M)Q!YSokY)3 zV6l-;hK6?j=mp2#1e5cCn7P6n_7)n^+MdRw@5pvkOA>|&B8`QZ32|ynqaf}Kcdro= zzQchCYM0^)7$;m2iZnMbE$!}hwk&AVvN`iX3A9mB&`*BDmLV-m`OMvd`sJ?;%U`p~ zmwow{y6sPbcZNQPZ#GQS0&mzy?s%>_p>ZM|sCXVAUlST;rQ-3#Iu!-bpFSV4g7?-l zGfX>Z#hR+i;9B};^CO@7<<#MGFeY)SC&;a{!` zf;yaQo%{bjSa8KT~@?O$cK z(DGnm7w>cG1hH#*J%X}%Y%~+nLT*{aP08@l&Nu}>!-j|!8lSqt_xUNF+Y}SQmupyb zPua2PI;@1YaIsRF*knA^rJv84Tc=7?J2}!1kMfHSO$d$+PK*u?OI%=P7;`PHxMB0k zau~T0Wk)rPEGJ$NiXW~kfPA#m%Sr|7=$tHelF9A6rFLa$^g{6)8GSW*6}#~Zb^qk% zg=pLwC!SkY+&Gne((9`TCy`i`a#eCS{A2yMi>J>p*NS*!V~aAgK;wnSOHPULqzyj- z-q4BPXqXn))iRnMF*WZj17wUYjC!h43tI7uScHLf1|WJfA7^5O9`%lH>ga`cmpiz( zs|I8nTUD4?d{CQ-vwD!2uwGU_Ts&{1_mvqY`@A{j^b?n&WbPhb418NY1*Otz19`1w zc9rn?0e_*En&8?OWii89x+jaqRVzlL!QUCg^qU&+WERycV&1+fcsJ%ExEPjiQWRTU zCJpu*1dXyvrJJcH`+OKn7;q`X#@Gmy3U?5ZAV~mXjQhBJOCMw>o@2kznF>*?qOW;D z6!GTcM)P-OY-R`Yd>FeX%UyL%dY%~#^Yl!c42;**WqdGtGwTfB9{2mf2h@#M8YyY+!Q(4}X^+V#r zcZXYE$-hJyYzq%>$)k8vSQU` zIpxU*yy~naYp=IocRp5no^PeFROluibl( zmaKkWgSWZHn(`V_&?hM{%xl3TBWCcr59WlX6Q{j45)`A^-kUv4!qM=OdcwpsGB)l} z&-_U+8S8bQ!RDc&Y3~?w5NwLNstoUYqPYs(y+lj!HFqIZ7FA>WsxAE7vB=20K zn_&y{2)Uaw4b^NCFNhJXd&XrhA4E~zD7Ue7X^f98=&5!wn_r=6qAwDkd>g#2+*ahd zaV|_P_8e%jiHh7W;cl(d=&-r-C}_Ov?bts8s^rKUWQ|XkuW!ToSwe}Z{4|kl+q&&W zn%iW48c5*ft#*m)+xSps+j(B5bPh&u0&m6=@WgwBf_QfJJzg2Qdz89HwcV`5kZ#5z zw;W&H8>5R(>KRwvd0gh30wJHA>|2N(im;~wy1HTv_}Ue%qb)>5qL^$hIyPvoT(nk_<`7F;#nS8;q!cqKspvBc<%xMsQj*h|>`Z)F6LDxue@to))OIbs2X+zY2L9#2UNrR^)?c8&PFc?j*&Q-r|C%7a$)ZRQ->#|?rEj&M4spQfNt;J^ntwf(d+q;tt)C`d{*|t)czD4x-qw{Chm0vuKp8axqy5`Yz z1756|;JX1q(lEieR=uT;%havqflgv+`5i!Z`R}(JNV~&`x}I9Lmm;aB7Bnc^UC?>W zu)(J7@fs}pL=Y-4aLq&Z*lO$e^0(bOW z3gWbcvb^gjEfhV=6Lgu2aX{(zjq|NH*fSgm&kBj?6dFqD2MWk5@eHt@_&^ZTX$b?o}S<9BGaCZIm6Hz)Qkruacn!qv*>La|#%j*XFp(*;&v3h4 zcjPbZWzv|cOypb@XDnd}g%(@f7A>w2Nseo|{KdeVQu)mN=W=Q`N?ID%J_SXUr0Rl# z3X;tO*^?41^%c!H;ia@hX``kWS3TR|CJ4_9j-?l6RjC=n?}r&sr>m%58&~?$JJV6{ zDq5h#m4S_BPiibQQaPGg6LIHVCc`9w3^3ZVWP$n>p7 z5dIEH-W9e;$Id8>9?wh%WnWf>4^1U<%vn=<4oNFhVl9zVk+jn;WtQUQ)ZeEjKYy8C z3g#tIb28thR1nZdKrN}(r zJdy-Y3Rvr5D3D|msZbmE;FLePbiM0ZjwTIQQHk)8G+sB$iwmEa2kQv&9Vs9m#$_8j zNKz}(x$Wc(M)a9H-Pn?5(Lk-CmOS(&+EVLOfsiq>e3ru6P?Lp>FOwPt>0o=j8UyF^ zO{(vf#MGx^y~WaOKnt%I78s}60(O#jFx0^47^Ikh$QTar(Dg$c=0KR|rRD|6s zz?tEX0_=(Hm0jWl;QOu!-k)mV?^i(Etl=Lg-{ z0G}CBprLX60zgAUz-fS^&m#o;erEC5TU+mn_Wj(zL$zqMo!e`D>s7X&;E zFz}}}puI+c%xq0uTpWS3RBlIS2jH0)W(9FU1>6PLcj|6O>=y)l`*%P`6K4}U2p}a0 zvInj%$AmqzkNLy%azH|_f7x$lYxSG=-;7BViUN(&0HPUobDixM1RVBzWhv8LokKI2 zjDwvWu=S~8We)+K{oMd-_cuXNO&+{eUaA8Ope3MxME0?PD+0a)99N>WZ66*;sn(N++hjPyz5z0RC{- z$pcSs{|)~a_h?w)y}42A6fg|nRnYUjMaBqg=68&_K%h3eboQ=%i083nfIVZZ04qOp%d*)*hNJA_foPjiW z$1r8ZZiRSvJT3zhK>iR@8_+TTJ!tlNLdL`e0=yjzv3Ie80h#wSfS3$>DB!!@JHxNd z0Mvd0Vqq!zfDy$?goY+|h!e(n3{J2;Ag=b)eLq{F0W*O?j&@|882U5?hUVIw_v3aV8tMn`8jPa5pSxzaZe{z}z|}$zM$o=3-mQ0Zgd?ZtaI> zQVHP1W3v1lbw>|?z@2MO(Ex!5KybKQ@+JRAg1>nzpP-!@3!th3rV=o?eiZ~fQRWy_ zfA!U9^bUL+z_$VJI=ic;{epla<&J@W-QMPZm^kTQ8a^2TX^TDpza*^tOu!WZ=T!PT z+0lJ*HuRnNGobNk0PbPT?i;^h{&0u+-fejISNv#9&j~Ep2;dYspntgzwR6<$@0dTQ z!qLe3Ztc=Ozy!btCcx!G$U7FlBRe}-L(E|RpH%_gt4m_LJllX3!iRYJEPvxcJ>C76 zfBy0_zKaYn{3yG6@;}S&+BeJk5X}$Kchp<Ea-=>VDg&zi*8xM0-ya!{ zcDN@>%H#vMwugU&1KN9pqA6-?Q8N@Dz?VlJ3IDfz#i#_RxgQS*>K+|Q@bek+s7#Qk z(5NZ-4xs&$j)X=@(1(hLn)vPj&pP>Nyu)emQ1MW6)g0hqXa5oJ_slh@(5MMS4xnG= z{0aK#F@_p=e}FdAa3tEl!|+j?h8h`t0CvCmNU%dOwEq<+jmm-=n|r|G^7QX4N4o(v zPU!%%w(Cet)Zev3QA?;TMm_aEK!5(~Nc6pJlp|sQP@z%JI}f0_`u+rc`1Df^j0G&s ScNgau(U?ep-K_E5zy1%ZQTdPn diff --git a/shared/android/gradle/wrapper/gradle-wrapper.properties b/shared/android/gradle/wrapper/gradle-wrapper.properties index 448da98bb858..7d410a5819ba 100644 --- a/shared/android/gradle/wrapper/gradle-wrapper.properties +++ b/shared/android/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,8 @@ #Mon May 06 15:15:57 PDT 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip -networkTimeout=10000 diff --git a/shared/android/gradlew b/shared/android/gradlew index d0e3e7aa5d78..2a31766d0258 100755 --- a/shared/android/gradlew +++ b/shared/android/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -69,37 +69,35 @@ app_path=$0 # Need this for daisy-chained symlinks. while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac + ls=$(ls -ld "$app_path") + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$(cd "${APP_HOME:-./}" >/dev/null && pwd -P) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum -warn () { - echo "$*" +warn() { + echo "$*" } >&2 -die () { - echo - echo "$*" - echo - exit 1 +die() { + echo + echo "$*" + echo + exit 1 } >&2 # OS specific support (must be 'true' or 'false'). @@ -107,55 +105,58 @@ cygwin=false msys=false darwin=false nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; +case "$(uname)" in #( +CYGWIN*) cygwin=true ;; #( +Darwin*) darwin=true ;; #( +MSYS* | MINGW*) msys=true ;; #( +NONSTOP*) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - # Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME +if [ -n "$JAVA_HOME" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ]; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." - fi + fi else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1; then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac +if ! "$cygwin" && ! "$darwin" && ! "$nonstop"; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$(ulimit -H -n) || + warn "Could not query maximum file descriptor limit" + ;; + esac + case $MAX_FD in #( + '' | soft) : ;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + ;; + esac fi # Collect all arguments for the java command, stacking in reverse order: @@ -167,52 +168,56 @@ fi # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done +if "$cygwin" || "$msys"; then + APP_HOME=$(cygpath --path --mixed "$APP_HOME") + CLASSPATH=$(cygpath --path --mixed "$CLASSPATH") + + JAVACMD=$(cygpath --unix "$JAVACMD") + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg; do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) + t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] + ;; #( + *) false ;; + esac + then + arg=$(cygpath --path --ignore --mixed "$arg") + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" # Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" +if ! command -v xargs >/dev/null 2>&1; then + die "xargs is not available" fi # Use "xargs" to parse quoted args. @@ -235,11 +240,10 @@ fi # eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' +)" '"$@"' exec "$JAVACMD" "$@" - diff --git a/shared/android/gradlew.bat b/shared/android/gradlew.bat index d45ec1e59103..fe228cc20605 100644 --- a/shared/android/gradlew.bat +++ b/shared/android/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/shared/android/settings.gradle b/shared/android/settings.gradle index 78552bc4f391..e3faea6fe9bf 100644 --- a/shared/android/settings.gradle +++ b/shared/android/settings.gradle @@ -1,8 +1,18 @@ +pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } +plugins { id("com.facebook.react.settings") } +extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } rootProject.name = 'Keybase' +dependencyResolutionManagement { + versionCatalogs { + reactAndroidLibs { + from(files(new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../gradle/libs.versions.toml"))) + } + } +} + apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle") useExpoModules() -apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app', ':keybaselib' -includeBuild('../node_modules/@react-native/gradle-plugin') +includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile()) diff --git a/shared/app/global-errors/hook.tsx b/shared/app/global-errors/hook.tsx index 9053c82b5a09..086773311403 100644 --- a/shared/app/global-errors/hook.tsx +++ b/shared/app/global-errors/hook.tsx @@ -32,7 +32,6 @@ const useData = () => { const [cachedDetails, setDetails] = React.useState(detailsForError(error)) const [size, setSize] = React.useState('Closed') const countdownTimerRef = React.useRef>() - const newErrorTimerRef = React.useRef>() const clearCountdown = React.useCallback(() => { countdownTimerRef.current && clearTimeout(countdownTimerRef.current) @@ -48,7 +47,6 @@ const useData = () => { C.useOnUnMountOnce(() => { clearCountdown() - newErrorTimerRef.current && clearTimeout(newErrorTimerRef.current) }) C.useOnMountOnce(() => { @@ -70,11 +68,8 @@ const useData = () => { [clearCountdown, onDismiss] ) - const [lastError, setLastError] = React.useState(error) - - if (lastError !== error) { - setLastError(error) - newErrorTimerRef.current = setTimeout( + React.useEffect(() => { + const id = setTimeout( () => { setDetails(detailsForError(error)) if (!C.isMobile) { @@ -84,7 +79,10 @@ const useData = () => { error ? 0 : 7000 ) // if it's set, do it immediately, if it's cleared set it in a bit resetError(!!error) - } + return () => { + clearTimeout(id) + } + }, [error, resetError]) return { cachedDetails, diff --git a/shared/app/global-errors/index.d.ts b/shared/app/global-errors/index.d.ts index 58348a14340a..695dd42f1e55 100644 --- a/shared/app/global-errors/index.d.ts +++ b/shared/app/global-errors/index.d.ts @@ -1,4 +1,3 @@ import type * as React from 'react' -export type Props = {} declare const GlobalError: () => React.ReactNode export default GlobalError diff --git a/shared/app/globals.native.tsx b/shared/app/globals.native.tsx index 96d4c8ec3231..75b3a18dbdb7 100644 --- a/shared/app/globals.native.tsx +++ b/shared/app/globals.native.tsx @@ -1,4 +1,3 @@ -/* eslint-disable no-global-assign */ // >>>>>>>>>>>>>>>>>>>>>>> DO NOT REORDER ANYTHING in this file <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // This is supposed to bootstrap / polyfill / fixup the app. Do NOT add things here or change things unless you really know // what's happening @@ -34,6 +33,19 @@ if (!Array.prototype.at) { }) } +// Needs jsc 5.4+ +// @ts-ignore +if (!String.prototype.replaceAll) { + Object.defineProperty(String.prototype, 'replaceAll', { + value: function (this: string, search: string, replace: string): string { + return this.replace(new RegExp(search, 'g'), replace) + }, + writable: true, + enumerable: false, + configurable: true, + }) +} + global.btoa = btoa global.atob = atob __FILE_SUFFIX__ = '' diff --git a/shared/app/index.native.tsx b/shared/app/index.native.tsx index 245d4dc9b0ce..b132eacd1768 100644 --- a/shared/app/index.native.tsx +++ b/shared/app/index.native.tsx @@ -23,7 +23,7 @@ module.hot?.accept(() => { const useDarkHookup = () => { const appStateRef = React.useRef('active') - const {setSystemDarkMode} = C.useDarkModeState.getState().dispatch + const setSystemDarkMode = C.useDarkModeState(s => s.dispatch.setSystemDarkMode) const setMobileAppState = C.useConfigState(s => s.dispatch.setMobileAppState) React.useEffect(() => { const appStateChangeSub = AppState.addEventListener('change', nextAppState => { @@ -115,27 +115,33 @@ const useInit = () => { C.useConfigState.getState().dispatch.installerRan() } +// react gesture handler has issues with this on currently. crashes out going into a thread +const UseStrict = false as boolean +const WRAP = UseStrict + ? ({children}: {children: React.ReactNode}) => {children} + : ({children}: {children: React.ReactNode}) => <>{children} + // on android this can be recreated a bunch so our engine/store / etc should live outside const Keybase = () => { useInit() - // reanimated still isn't compatible yet with strict mode - // - // const {unmountAll, show} = useUnmountAll() + return show ? ( - - - - - -

- {unmountAll} - - - - - + + + + + + +
+ {unmountAll} + + + + + + ) : ( unmountAll ) diff --git a/shared/app/runtime-stats.tsx b/shared/app/runtime-stats.tsx index 5369d8b8955a..7dbfbd2ca901 100644 --- a/shared/app/runtime-stats.tsx +++ b/shared/app/runtime-stats.tsx @@ -83,21 +83,23 @@ const LogStats = (props: {num?: number}) => { const {num} = props const maxBuckets = num ?? 5 - const bucketsRef = React.useRef>( - [] - ) + const [buckets, setBuckets] = React.useState< + Array<{count: number; label: string; labelFull: string; updated: boolean}> + >([]) const [, setDoRender] = React.useState(0) const events = C.useConfigState(s => s.runtimeStats?.perfEvents) const lastEventsRef = React.useRef(new WeakSet>()) const eventsRef = React.useRef>([]) - if (events) { - // only if unprocessed - if (!lastEventsRef.current.has(events)) { - lastEventsRef.current.add(events) - eventsRef.current.push(...events) + React.useEffect(() => { + if (events) { + // only if unprocessed + if (!lastEventsRef.current.has(events)) { + lastEventsRef.current.add(events) + eventsRef.current.push(...events) + } } - } + }, [events]) Kb.useInterval(() => { const events = eventsRef.current @@ -128,7 +130,7 @@ const LogStats = (props: {num?: number}) => { }) // copy existing buckets - let newBuckets = bucketsRef.current.map(b => ({...b, updated: false})) + let newBuckets = buckets.map(b => ({...b, updated: false})) // find existing or add new ones incoming.forEach((i, idx) => { @@ -172,7 +174,7 @@ const LogStats = (props: {num?: number}) => { // sort remainder by alpha so things don't move around a lot newBuckets = newBuckets.sort((a, b) => a.label.localeCompare(b.label)) - bucketsRef.current = newBuckets + setBuckets(newBuckets) setDoRender(r => r + 1) }, 2000) @@ -190,7 +192,7 @@ const LogStats = (props: {num?: number}) => { Logs )} - {bucketsRef.current.map((b, i) => ( + {buckets.map((b, i) => ( { ) : null } -const styles = Styles.styleSheetCreate(() => ({ - boxGrow: Styles.platformStyles({ - isElectron: { - overflow: 'auto', - }, - }), - container: Styles.platformStyles({ - common: {backgroundColor: Styles.globalColors.blackOrBlack}, - isElectron: { - overflow: 'auto', - padding: Styles.globalMargins.tiny, - position: 'relative', - }, - isMobile: { - bottom: isIPhoneX ? 15 : 0, - position: 'absolute', - right: isIPhoneX ? 10 : 0, - }, - }), - logStat: Styles.platformStyles({ - common: {color: Styles.globalColors.whiteOrWhite}, - isElectron: {wordBreak: 'break-all'}, - isMobile: { - fontFamily: 'Courier', - fontSize: 12, - lineHeight: 16, - }, - }), - modalLogStats: { - position: 'absolute', - right: 0, - top: 20, - width: 130, - }, - modalLogStatsHidden: { - backgroundColor: 'yellow', - position: 'absolute', - right: 0, - top: 20, - width: 20, - }, - // radarContainer: Styles.platformStyles({ - // isElectron: { - // backgroundColor: Styles.globalColors.white_20, - // borderRadius: '50%', - // height: radarSize, - // position: 'absolute', - // right: Styles.globalMargins.tiny, - // top: Styles.globalMargins.tiny, - // width: radarSize, - // }, - // }), - stat: Styles.platformStyles({ - common: {color: Styles.globalColors.whiteOrGreenDark}, - isElectron: {wordBreak: 'break-all'}, - isMobile: { - fontFamily: 'Courier', - fontSize: 10, - lineHeight: 14, - }, - }), - statNormal: { - color: Styles.globalColors.whiteOrGreenDark, - }, - statSevere: { - color: Styles.globalColors.red, - }, - statWarning: { - color: Styles.globalColors.yellowOrYellowAlt, - }, -})) +const styles = Styles.styleSheetCreate( + () => + ({ + boxGrow: Styles.platformStyles({ + isElectron: { + overflow: 'auto', + }, + }), + container: Styles.platformStyles({ + common: {backgroundColor: Styles.globalColors.blackOrBlack}, + isElectron: { + overflow: 'auto', + padding: Styles.globalMargins.tiny, + position: 'relative', + }, + isMobile: { + bottom: isIPhoneX ? 15 : 0, + position: 'absolute', + right: isIPhoneX ? 10 : 0, + }, + }), + logStat: Styles.platformStyles({ + common: {color: Styles.globalColors.whiteOrWhite}, + isElectron: {wordBreak: 'break-all'}, + isMobile: { + fontFamily: 'Courier', + fontSize: 12, + lineHeight: 16, + }, + }), + modalLogStats: { + position: 'absolute', + right: 0, + top: 20, + width: 130, + }, + modalLogStatsHidden: { + backgroundColor: 'yellow', + position: 'absolute', + right: 0, + top: 20, + width: 20, + }, + // radarContainer: Styles.platformStyles({ + // isElectron: { + // backgroundColor: Styles.globalColors.white_20, + // borderRadius: '50%', + // height: radarSize, + // position: 'absolute', + // right: Styles.globalMargins.tiny, + // top: Styles.globalMargins.tiny, + // width: radarSize, + // }, + // }), + stat: Styles.platformStyles({ + common: {color: Styles.globalColors.whiteOrGreenDark}, + isElectron: {wordBreak: 'break-all'}, + isMobile: { + fontFamily: 'Courier', + fontSize: 10, + lineHeight: 14, + }, + }), + statNormal: { + color: Styles.globalColors.whiteOrGreenDark, + }, + statSevere: { + color: Styles.globalColors.red, + }, + statWarning: { + color: Styles.globalColors.yellowOrYellowAlt, + }, + }) as const +) export default RuntimeStats diff --git a/shared/babel.config.js b/shared/babel.config.js index 0f20620eefaf..fbe28a0deffb 100644 --- a/shared/babel.config.js +++ b/shared/babel.config.js @@ -43,7 +43,7 @@ module.exports = function (api /*: any */) { // console.error('KB babel.config.js for Electron') return { presets: [ - isTest ? ['@babel/preset-env', {targets: {node: 'current'}}] : '@babel/preset-env', + isTest ? ['@babel/preset-env', { targets: { node: 'current' } }] : '@babel/preset-env', '@babel/preset-typescript', ], } @@ -62,21 +62,23 @@ module.exports = function (api /*: any */) { }, ], ...(skipAnimation ? [] : ['react-native-reanimated/plugin']), - '@babel/plugin-proposal-numeric-separator', + // '@babel/plugin-proposal-numeric-separator', '@babel/plugin-transform-export-namespace-from', - isDev - ? [ - '@babel/plugin-transform-react-jsx-development', - { - runtime: 'automatic', - ...(enableWDYR ? {importSource: '@welldone-software/why-did-you-render'} : {}), - }, - ] - : ['@babel/plugin-transform-react-jsx', {runtime: 'automatic'}], + ...(isDev + ? [[ + '@babel/plugin-transform-react-jsx-development', + { + runtime: 'automatic', + ...(enableWDYR ? { importSource: '@welldone-software/why-did-you-render' } : {}), + }, + ]] + : [[ + '@babel/plugin-transform-react-jsx', { runtime: 'automatic' } + ]]), ], presets: [ // lets us set our own jsx above - ['module:metro-react-native-babel-preset', {useTransformReactJSXExperimental: true}], + ['module:@react-native/babel-preset', { useTransformReactJSXExperimental: true }], ], sourceMaps: true, } diff --git a/shared/chat/audio/audio-player.tsx b/shared/chat/audio/audio-player.tsx index a3a93dd93264..09ea8002e675 100644 --- a/shared/chat/audio/audio-player.tsx +++ b/shared/chat/audio/audio-player.tsx @@ -69,7 +69,6 @@ type Props = { const AudioPlayer = (props: Props) => { const {duration, big, maxWidth, url, visAmps} = props - const seekRef = React.useRef void)>(null) const [playedRatio, setPlayedRatio] = React.useState(0) const [paused, setPaused] = React.useState(true) const onClick = () => { @@ -111,13 +110,7 @@ const AudioPlayer = (props: Props) => { {formatAudioRecordDuration(timeLeft)} {url.length > 0 && ( - + )} ) diff --git a/shared/chat/audio/audio-recorder.native.tsx b/shared/chat/audio/audio-recorder.native.tsx index 69037c065dea..443f8fd2374e 100644 --- a/shared/chat/audio/audio-recorder.native.tsx +++ b/shared/chat/audio/audio-recorder.native.tsx @@ -120,6 +120,7 @@ const makePanOnFinalize = (p: { } const onPanFinalizeWorklet = (_e: unknown, success: boolean) => { + 'worklet' startedSV.value = 0 runOnJS(onPanFinalizeJS)(!success, canceledSV.value === 1, lockedSV.value === 1) } @@ -135,6 +136,7 @@ const makePanOnStart = (p: {startRecording: () => void; fadeSV: SVN; startedSV: } const onPanStartWorklet = () => { + 'worklet' // we get this multiple times for some reason if (startedSV.value) { return @@ -150,6 +152,7 @@ const makePanOnStart = (p: {startRecording: () => void; fadeSV: SVN; startedSV: const makePanOnUpdate = (p: {lockedSV: SVN; canceledSV: SVN; dragYSV: SVN; dragXSV: SVN}) => { const {lockedSV, dragYSV, dragXSV, canceledSV} = p const onOnUpdateWorklet = (e: GestureUpdateEvent) => { + 'worklet' if (lockedSV.value || canceledSV.value) { return } @@ -173,8 +176,20 @@ const GestureIcon = React.memo( panOnUpdate: ReturnType panOnStart: ReturnType }) { + const [visible, setVisible] = React.useState(false) + + // work around bug in gesture handler where it crashes on mount + React.useEffect(() => { + const id = setTimeout(() => { + setVisible(true) + return () => { + clearTimeout(id) + } + }, 1000) + }, []) + const {panOnStart, panOnUpdate, panOnFinalize} = p - return ( + return visible ? ( - + + + + ) : ( + ) }, // we never want to rerender the icon, all the helpers are fine at mount @@ -642,7 +661,7 @@ const LockHint = (props: {fadeSV: SVN; lockedSV: SVN; dragXSV: SVN; dragYSV: SVN interpolate(dragYSV.value, [dragDistanceX, 0], [0, 1], Extrapolation.CLAMP) * dragXOpacity, transform: [{translateX: 10}, {translateY: deltaY - fadeSV.value * slideAmount}], - } + } as const }) const lockStyle = useAnimatedStyle(() => { // worklet needs this locally for some reason @@ -666,8 +685,12 @@ const LockHint = (props: {fadeSV: SVN; lockedSV: SVN; dragXSV: SVN; dragYSV: SVN }) return ( <> - - + + ) } @@ -677,7 +700,7 @@ const AnimatedText = Animated.createAnimatedComponent(Kb.Text) const CancelHint = (props: {fadeSV: SVN; dragXSV: SVN; lockedSV: SVN; onCancel: () => void}) => { const {lockedSV, fadeSV, onCancel, dragXSV} = props - const arrowStyle = useAnimatedStyle(() => { + const arrowStyle: any = useAnimatedStyle(() => { // copy paste so we don't share as many vars between jsc contexts const dragDistanceX = -50 const deltaX = 180 @@ -690,7 +713,7 @@ const CancelHint = (props: {fadeSV: SVN; dragXSV: SVN; lockedSV: SVN; onCancel: transform: [{translateX: deltaX - spaceBetween - fadeSV.value * slideAmount}, {translateY: -4}], } }) - const closeStyle = useAnimatedStyle(() => { + const closeStyle: any = useAnimatedStyle(() => { const dragDistanceX = -50 const deltaX = 180 const slideAmount = 220 @@ -702,7 +725,7 @@ const CancelHint = (props: {fadeSV: SVN; dragXSV: SVN; lockedSV: SVN; onCancel: transform: [{translateX: deltaX - spaceBetween - fadeSV.value * slideAmount}, {translateY: -4}], } }) - const textStyle = useAnimatedStyle(() => { + const textStyle: any = useAnimatedStyle(() => { const dragDistanceX = -50 const deltaX = 180 const slideAmount = 220 @@ -718,7 +741,7 @@ const CancelHint = (props: {fadeSV: SVN; dragXSV: SVN; lockedSV: SVN; onCancel: ], } }) - const textStyleLocked = useAnimatedStyle(() => { + const textStyleLocked: any = useAnimatedStyle(() => { const dragDistanceX = -50 const deltaX = 180 const slideAmount = 220 @@ -778,10 +801,10 @@ const SendRecordingButton = (props: {fadeSV: SVN; lockedSV: SVN; sendRecording: const AudioCounter = () => { const [seconds, setSeconds] = React.useState(0) - const startTime = React.useRef(Date.now()).current + const startTime = React.useRef(Date.now()) React.useEffect(() => { const timer = setTimeout(() => { - setSeconds((Date.now() - startTime) / 1000) + setSeconds((Date.now() - startTime.current) / 1000) }, 1000) return () => clearTimeout(timer) }, [seconds, startTime]) diff --git a/shared/chat/audio/audio-send.native.tsx b/shared/chat/audio/audio-send.native.tsx index 610e67fda153..99517fe10a09 100644 --- a/shared/chat/audio/audio-send.native.tsx +++ b/shared/chat/audio/audio-send.native.tsx @@ -28,9 +28,8 @@ const AudioSend = (props: Props) => { const {cancelRecording, sendRecording, duration, ampTracker, path} = props // render - let player = No recording available const audioUrl = `file://${path}` - player = ( + const player = ( void)> onPositionUpdated: (ratio: number) => void onEnded: () => void } diff --git a/shared/chat/audio/audio-video.desktop.tsx b/shared/chat/audio/audio-video.desktop.tsx index 22f6daa6d956..ff6aec9f978e 100644 --- a/shared/chat/audio/audio-video.desktop.tsx +++ b/shared/chat/audio/audio-video.desktop.tsx @@ -2,21 +2,9 @@ import * as React from 'react' import type {Props} from './audio-video' const AudioVideo = (props: Props) => { - const {url, seekRef, paused, onPositionUpdated, onEnded} = props + const {url, paused, onPositionUpdated, onEnded} = props const vidRef = React.useRef(null) - const seek = React.useCallback( - (seconds: number) => { - if (vidRef.current) { - vidRef.current.currentTime = seconds - } - if (paused) { - vidRef.current?.pause() - } - }, - [vidRef, paused] - ) - seekRef.current = seek const onTimeUpdate = React.useCallback( (e: React.SyntheticEvent) => { const ct = e.currentTarget.currentTime @@ -33,9 +21,12 @@ const AudioVideo = (props: Props) => { onEnded() }, [onEnded]) - const [lastPaused, setLastPaused] = React.useState(paused) - if (lastPaused !== paused) { - setLastPaused(paused) + const lastPausedRef = React.useRef(paused) + React.useEffect(() => { + if (lastPausedRef.current === paused) { + return + } + lastPausedRef.current = paused if (paused) { vidRef.current?.pause() } else { @@ -44,7 +35,7 @@ const AudioVideo = (props: Props) => { .then(() => {}) .catch(() => {}) } - } + }, [paused]) return (