about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhailey <me@haileyok.com>2025-06-12 10:46:22 -0700
committerGitHub <noreply@github.com>2025-06-12 10:46:22 -0700
commit477e5f4ecfaa0007aeed90b51274c78a730c1a9e (patch)
tree45cd5cfff9eab1bd52b5ade6c60efebe3cc5e6b6
parenta26b20b56cd0ac80f625a5eb5136b805b9341e8d (diff)
downloadvoidsky-477e5f4ecfaa0007aeed90b51274c78a730c1a9e.tar.zst
new arch (#8295)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Co-authored-by: Charlotte Som <charlotte@som.codes>
Co-authored-by: Hailey <me@haileyok.com>
-rw-r--r--__tests__/lib/images.test.ts51
-rw-r--r--app.config.js2
-rw-r--r--jest/jestSetup.js9
-rw-r--r--package.json78
-rw-r--r--patches/@mattermost+react-native-paste-input+0.8.1.patch.disabled (renamed from patches/@mattermost+react-native-paste-input+0.7.1.patch)111
-rw-r--r--patches/@sentry+react-native+6.14.0.patch (renamed from patches/@sentry+react-native+6.10.0.patch)0
-rw-r--r--patches/expo-media-library+17.1.7.patch (renamed from patches/expo-media-library+17.1.6.patch)0
-rw-r--r--patches/expo-modules-core+2.4.0.patch (renamed from patches/expo-modules-core+2.3.12.patch)0
-rw-r--r--patches/expo-modules-core+2.4.0.patch.md (renamed from patches/expo-modules-core+2.3.12.patch.md)0
-rw-r--r--patches/expo-notifications+0.31.3.patch (renamed from patches/expo-notifications+0.31.1.patch)0
-rw-r--r--patches/expo-notifications+0.31.3.patch.md (renamed from patches/expo-notifications+0.31.1.patch.md)0
-rw-r--r--patches/expo-updates+0.28.14.patch (renamed from patches/expo-updates+0.28.12.patch)0
-rw-r--r--patches/expo-updates+0.28.14.patch.md (renamed from patches/expo-updates+0.28.12.patch.md)0
-rw-r--r--patches/react-native+0.79.3.patch (renamed from patches/react-native+0.79.2.patch)49
-rw-r--r--patches/react-native+0.79.3.patch.md (renamed from patches/react-native+0.79.2.patch.md)0
-rw-r--r--patches/react-native-svg+15.12.0.patch (renamed from patches/react-native-svg+15.11.2.patch)0
-rw-r--r--src/components/forms/TextField.tsx14
-rw-r--r--src/lib/hooks/useHandleRef.ts39
-rw-r--r--src/lib/media/manip.ts87
-rw-r--r--src/screens/Profile/Header/Shell.tsx24
-rw-r--r--src/view/com/composer/text-input/TextInput.tsx14
-rw-r--r--src/view/com/pager/Pager.tsx220
-rw-r--r--src/view/com/pager/Pager.web.tsx47
-rw-r--r--src/view/com/pager/PagerWithHeader.tsx315
-rw-r--r--src/view/com/profile/ProfileSubpageHeader.tsx24
-rw-r--r--src/view/com/util/Toast.web.tsx1
-rw-r--r--src/view/com/util/images/AutoSizedImage.tsx22
-rw-r--r--src/view/com/util/images/Gallery.tsx16
-rw-r--r--src/view/com/util/images/ImageLayoutGrid.tsx20
-rw-r--r--src/view/com/util/post-embeds/index.tsx11
-rw-r--r--yarn.lock766
31 files changed, 1011 insertions, 909 deletions
diff --git a/__tests__/lib/images.test.ts b/__tests__/lib/images.test.ts
index a5acad25f..c7a645d39 100644
--- a/__tests__/lib/images.test.ts
+++ b/__tests__/lib/images.test.ts
@@ -1,10 +1,9 @@
-import {deleteAsync} from 'expo-file-system'
+import {createDownloadResumable, deleteAsync} from 'expo-file-system'
 import {manipulateAsync, SaveFormat} from 'expo-image-manipulator'
-import RNFetchBlob from 'rn-fetch-blob'
 
 import {
   downloadAndResize,
-  DownloadAndResizeOpts,
+  type DownloadAndResizeOpts,
   getResizedDimensions,
 } from '../../src/lib/media/manip'
 
@@ -32,11 +31,12 @@ describe('downloadAndResize', () => {
   })
 
   it('should return resized image for valid URI and options', async () => {
-    const mockedFetch = RNFetchBlob.fetch as jest.Mock
-    mockedFetch.mockResolvedValueOnce({
-      path: jest.fn().mockReturnValue('file://downloaded-image.jpg'),
-      info: jest.fn().mockReturnValue({status: 200}),
-      flush: jest.fn(),
+    const mockedFetch = createDownloadResumable as jest.Mock
+    mockedFetch.mockReturnValue({
+      cancelAsync: jest.fn(),
+      downloadAsync: jest
+        .fn()
+        .mockResolvedValue({uri: 'file://resized-image.jpg'}),
     })
 
     const opts: DownloadAndResizeOpts = {
@@ -50,13 +50,12 @@ describe('downloadAndResize', () => {
 
     const result = await downloadAndResize(opts)
     expect(result).toEqual(mockResizedImage)
-    expect(RNFetchBlob.config).toHaveBeenCalledWith({
-      fileCache: true,
-      appendExt: 'jpeg',
-    })
-    expect(RNFetchBlob.fetch).toHaveBeenCalledWith(
-      'GET',
-      'https://example.com/image.jpg',
+    expect(createDownloadResumable).toHaveBeenCalledWith(
+      opts.uri,
+      expect.anything(),
+      {
+        cache: true,
+      },
     )
 
     // First time it gets called is to get dimensions
@@ -86,28 +85,6 @@ describe('downloadAndResize', () => {
     expect(result).toBeUndefined()
   })
 
-  it('should return undefined for non-200 response', async () => {
-    const mockedFetch = RNFetchBlob.fetch as jest.Mock
-    mockedFetch.mockResolvedValueOnce({
-      path: jest.fn().mockReturnValue('file://downloaded-image'),
-      info: jest.fn().mockReturnValue({status: 400}),
-      flush: jest.fn(),
-    })
-
-    const opts: DownloadAndResizeOpts = {
-      uri: 'https://example.com/image',
-      width: 100,
-      height: 100,
-      maxSize: 500000,
-      mode: 'cover',
-      timeout: 10000,
-    }
-
-    const result = await downloadAndResize(opts)
-    expect(errorSpy).not.toHaveBeenCalled()
-    expect(result).toBeUndefined()
-  })
-
   it('should not downsize whenever dimensions are below the max dimensions', () => {
     const initialDimensionsOne = {
       width: 1200,
diff --git a/app.config.js b/app.config.js
index 0fa91f2ce..36af08415 100644
--- a/app.config.js
+++ b/app.config.js
@@ -219,7 +219,7 @@ module.exports = function (_config) {
               compileSdkVersion: 35,
               targetSdkVersion: 35,
               buildToolsVersion: '35.0.0',
-              newArchEnabled: false,
+              newArchEnabled: true,
             },
           },
         ],
diff --git a/jest/jestSetup.js b/jest/jestSetup.js
index d303225f6..700d20afc 100644
--- a/jest/jestSetup.js
+++ b/jest/jestSetup.js
@@ -33,15 +33,10 @@ jest.mock('react-native-safe-area-context', () => {
   }
 })
 
-jest.mock('rn-fetch-blob', () => ({
-  config: jest.fn().mockReturnThis(),
-  cancel: jest.fn(),
-  fetch: jest.fn(),
-}))
-
 jest.mock('expo-file-system', () => ({
   getInfoAsync: jest.fn().mockResolvedValue({exists: true, size: 100}),
   deleteAsync: jest.fn(),
+  createDownloadResumable: jest.fn(),
 }))
 
 jest.mock('expo-image-manipulator', () => ({
@@ -101,7 +96,7 @@ jest.mock('expo-modules-core', () => ({
       }
     }
   }),
-  requireNativeViewManager: jest.fn().mockImplementation(moduleName => {
+  requireNativeViewManager: jest.fn().mockImplementation(_ => {
     return () => null
   }),
 }))
diff --git a/package.json b/package.json
index f0bc5bbe7..38f574f42 100644
--- a/package.json
+++ b/package.json
@@ -74,7 +74,7 @@
     "@braintree/sanitize-url": "^6.0.2",
     "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet",
     "@emoji-mart/react": "^1.1.1",
-    "@expo/html-elements": "^0.12.4",
+    "@expo/html-elements": "^0.12.5",
     "@expo/webpack-config": "^19.0.1",
     "@floating-ui/dom": "^1.6.3",
     "@floating-ui/react-dom": "^2.0.8",
@@ -85,12 +85,12 @@
     "@fortawesome/free-regular-svg-icons": "^6.1.1",
     "@fortawesome/free-solid-svg-icons": "^6.1.1",
     "@fortawesome/react-native-fontawesome": "^0.3.2",
-    "@haileyok/bluesky-video": "0.2.6",
+    "@haileyok/bluesky-video": "0.3.1",
     "@ipld/dag-cbor": "^9.2.0",
     "@lingui/react": "^4.14.1",
-    "@mattermost/react-native-paste-input": "^0.7.1",
-    "@miblanchard/react-native-slider": "^2.3.1",
-    "@mozzius/expo-dynamic-app-icon": "^1.5.0",
+    "@mattermost/react-native-paste-input": "mattermost/react-native-paste-input",
+    "@miblanchard/react-native-slider": "^2.6.0",
+    "@mozzius/expo-dynamic-app-icon": "1.5.0",
     "@react-native-async-storage/async-storage": "2.1.2",
     "@react-native-menu/menu": "^1.2.3",
     "@react-native-picker/picker": "2.11.0",
@@ -98,7 +98,7 @@
     "@react-navigation/drawer": "^7.3.12",
     "@react-navigation/native": "^7.1.9",
     "@react-navigation/native-stack": "^7.3.13",
-    "@sentry/react-native": "~6.10.0",
+    "@sentry/react-native": "~6.14.0",
     "@tanstack/query-async-storage-persister": "^5.25.0",
     "@tanstack/react-query": "^5.8.1",
     "@tanstack/react-query-persist-client": "^5.25.0",
@@ -130,33 +130,33 @@
     "emoji-mart": "^5.5.2",
     "emoji-regex": "^10.4.0",
     "eventemitter3": "^5.0.1",
-    "expo": "^53.0.5",
+    "expo": "53.0.11",
     "expo-application": "~6.1.4",
-    "expo-blur": "~14.1.4",
+    "expo-blur": "~14.1.5",
     "expo-build-properties": "~0.14.6",
-    "expo-camera": "~16.1.6",
+    "expo-camera": "~16.1.8",
     "expo-clipboard": "~7.1.4",
-    "expo-dev-client": "~5.1.7",
+    "expo-dev-client": "~5.2.0",
     "expo-device": "~7.1.4",
-    "expo-file-system": "~18.1.8",
-    "expo-font": "~13.3.0",
+    "expo-file-system": "~18.1.10",
+    "expo-font": "~13.3.1",
     "expo-haptics": "~14.1.4",
-    "expo-image": "~2.1.6",
+    "expo-image": "~2.2.1",
     "expo-image-crop-tool": "^0.1.8",
-    "expo-image-manipulator": "~13.1.5",
+    "expo-image-manipulator": "~13.1.7",
     "expo-image-picker": "~16.1.4",
-    "expo-linear-gradient": "~14.1.4",
-    "expo-linking": "~7.1.4",
+    "expo-linear-gradient": "~14.1.5",
+    "expo-linking": "~7.1.5",
     "expo-localization": "~16.1.5",
-    "expo-media-library": "~17.1.6",
-    "expo-notifications": "~0.31.1",
-    "expo-screen-orientation": "~8.1.5",
+    "expo-media-library": "~17.1.7",
+    "expo-notifications": "~0.31.3",
+    "expo-screen-orientation": "~8.1.7",
     "expo-sharing": "~13.1.5",
-    "expo-splash-screen": "~0.30.8",
-    "expo-system-ui": "~5.0.7",
+    "expo-splash-screen": "~0.30.9",
+    "expo-system-ui": "~5.0.8",
     "expo-task-manager": "~13.1.5",
-    "expo-updates": "~0.28.12",
-    "expo-video": "~2.1.8",
+    "expo-updates": "~0.28.14",
+    "expo-video": "~2.2.1",
     "expo-web-browser": "~14.1.6",
     "fast-text-encoding": "^1.0.6",
     "history": "^5.3.0",
@@ -182,35 +182,34 @@
     "react-image-crop": "^11.0.7",
     "react-is": "19",
     "react-keyed-flatten-children": "^5.0.0",
-    "react-native": "0.79.2",
-    "react-native-compressor": "1.11.0",
+    "react-native": "^0.79.3",
+    "react-native-compressor": "^1.11.0",
     "react-native-date-picker": "^5.0.12",
-    "react-native-drawer-layout": "^4.1.6",
+    "react-native-drawer-layout": "^4.1.8",
     "react-native-edge-to-edge": "^1.6.0",
     "react-native-gesture-handler": "2.25.0",
     "react-native-get-random-values": "~1.11.0",
     "react-native-ios-context-menu": "^1.15.3",
     "react-native-keyboard-controller": "^1.17.1",
     "react-native-mmkv": "^2.12.2",
-    "react-native-pager-view": "6.7.1",
+    "react-native-pager-view": "^6.7.1",
     "react-native-progress": "bluesky-social/react-native-progress",
     "react-native-qrcode-styled": "^0.3.3",
     "react-native-reanimated": "~3.17.5",
-    "react-native-root-siblings": "^4.1.1",
+    "react-native-root-siblings": "^5.0.1",
     "react-native-safe-area-context": "5.4.0",
     "react-native-screens": "^4.11.1",
-    "react-native-svg": "15.11.2",
+    "react-native-svg": "15.12.0",
     "react-native-uitextview": "^1.4.0",
     "react-native-url-polyfill": "^1.3.0",
     "react-native-uuid": "^2.0.3",
     "react-native-view-shot": "^4.0.3",
     "react-native-web": "~0.20.0",
     "react-native-web-webview": "^1.0.2",
-    "react-native-webview": "13.13.5",
+    "react-native-webview": "^13.13.5",
     "react-remove-scroll-bar": "^2.3.8",
     "react-responsive": "^9.0.2",
     "react-textarea-autosize": "^8.5.3",
-    "rn-fetch-blob": "^0.12.0",
     "statsig-react-native-expo": "^4.6.1",
     "tippy.js": "^6.3.7",
     "tlds": "^1.234.0",
@@ -227,8 +226,9 @@
     "@lingui/cli": "^4.14.1",
     "@lingui/macro": "^4.14.1",
     "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
-    "@react-native/eslint-config": "^0.79.2",
-    "@react-native/typescript-config": "^0.79.2",
+    "@react-native/babel-preset": "0.79.3",
+    "@react-native/eslint-config": "^0.79.3",
+    "@react-native/typescript-config": "^0.79.3",
     "@sentry/webpack-plugin": "^3.2.2",
     "@testing-library/jest-native": "^5.4.3",
     "@testing-library/react-native": "^13.2.0",
@@ -247,6 +247,7 @@
     "babel-plugin-module-resolver": "^5.0.2",
     "babel-plugin-react-compiler": "^19.1.0-rc.1",
     "babel-preset-expo": "~13.1.11",
+    "browserslist": "^4.25.0",
     "eslint": "^8.19.0",
     "eslint-plugin-bsky-internal": "link:./eslint",
     "eslint-plugin-ft-flow": "^2.0.3",
@@ -260,7 +261,7 @@
     "husky": "^8.0.3",
     "is-ci": "^3.0.1",
     "jest": "^29.7.0",
-    "jest-expo": "~53.0.3",
+    "jest-expo": "~53.0.7",
     "jest-junit": "^16.0.0",
     "lint-staged": "^13.2.3",
     "lockfile-lint": "^4.14.0",
@@ -275,11 +276,11 @@
   },
   "resolutions": {
     "@expo/image-utils": "0.6.3",
-    "@react-native/babel-preset": "0.79.2",
-    "@react-native/normalize-colors": "0.79.2",
+    "@react-native/babel-preset": "0.79.3",
+    "@react-native/normalize-colors": "0.79.3",
     "@types/react": "^18",
     "**/expo-constants": "17.0.3",
-    "**/expo-device": "7.0.1",
+    "**/expo-device": "7.1.4",
     "**/zod": "3.23.8",
     "**/multiformats": "9.9.0"
   },
@@ -359,7 +360,8 @@
     ],
     "allowedUrls": [
       "https://codeload.github.com/bluesky-social/react-native-bottom-sheet/tar.gz/28a87d1bb55e10fc355fa1455545a30734995908",
-      "https://codeload.github.com/bluesky-social/react-native-progress/tar.gz/5a372f4f2ce5feb26f4f47b6a4d187ab9b923ab4"
+      "https://codeload.github.com/bluesky-social/react-native-progress/tar.gz/5a372f4f2ce5feb26f4f47b6a4d187ab9b923ab4",
+      "https://codeload.github.com/mattermost/react-native-paste-input/tar.gz/f260447edc645a817ab1ba7b46d8341d84dba8e9"
     ],
     "emptyHostname": false,
     "validatePackageNames": true,
diff --git a/patches/@mattermost+react-native-paste-input+0.7.1.patch b/patches/@mattermost+react-native-paste-input+0.8.1.patch.disabled
index f25b6a776..a7f146143 100644
--- a/patches/@mattermost+react-native-paste-input+0.7.1.patch
+++ b/patches/@mattermost+react-native-paste-input+0.8.1.patch.disabled
@@ -114,7 +114,7 @@ index e916023..5049c33 100644
  }
  
  #pragma mark - UIScrollViewDelegate
-@@ -62,7 +92,6 @@
+@@ -62,7 +92,6 @@ - (void)setSmartPunctuation:(NSString *)smartPunctuation {
  - (void)scrollViewDidScroll:(UIScrollView *)scrollView
  {
    RCTDirectEventBlock onScroll = self.onScroll;
@@ -122,7 +122,7 @@ index e916023..5049c33 100644
    if (onScroll) {
      CGPoint contentOffset = scrollView.contentOffset;
      CGSize contentSize = scrollView.contentSize;
-@@ -71,22 +100,22 @@
+@@ -71,22 +100,22 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView
  
      onScroll(@{
        @"contentOffset": @{
@@ -155,3 +155,110 @@ index e916023..5049c33 100644
        },
        @"zoomScale": @(scrollView.zoomScale ?: 1),
      });
+diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm
+index dd50053..2ed7017 100644
+--- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm
++++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm
+@@ -122,8 +122,8 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &
+   const auto &newTextInputProps = static_cast<const PasteTextInputProps &>(*props);
+ 
+   // Traits:
+-  if (newTextInputProps.traits.multiline != oldTextInputProps.traits.multiline) {
+-    [self _setMultiline:newTextInputProps.traits.multiline];
++  if (newTextInputProps.multiline != oldTextInputProps.multiline) {
++    [self _setMultiline:newTextInputProps.multiline];
+   }
+ 
+   if (newTextInputProps.traits.autocapitalizationType != oldTextInputProps.traits.autocapitalizationType) {
+@@ -421,7 +421,7 @@ - (void)textInputDidChangeSelection
+     return;
+   }
+   const auto &props = static_cast<const PasteTextInputProps &>(*_props);
+-  if (props.traits.multiline && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
++  if (props.multiline && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
+     [self textInputDidChange];
+     _ignoreNextTextInputCall = YES;
+   }
+@@ -708,11 +708,11 @@ - (BOOL)_textOf:(NSAttributedString *)newText equals:(NSAttributedString *)oldTe
+ - (SubmitBehavior)getSubmitBehavior
+ {
+   const auto &props = static_cast<const PasteTextInputProps &>(*_props);
+-  const SubmitBehavior submitBehaviorDefaultable = props.traits.submitBehavior;
++  const SubmitBehavior submitBehaviorDefaultable = props.submitBehavior;
+ 
+   // We should always have a non-default `submitBehavior`, but in case we don't, set it based on multiline.
+   if (submitBehaviorDefaultable == SubmitBehavior::Default) {
+-    return props.traits.multiline ? SubmitBehavior::Newline : SubmitBehavior::BlurAndSubmit;
++    return props.multiline ? SubmitBehavior::Newline : SubmitBehavior::BlurAndSubmit;
+   }
+ 
+   return submitBehaviorDefaultable;
+diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp
+index 29e094f..7ef519a 100644
+--- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp
++++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp
+@@ -22,8 +22,7 @@ PasteTextInputProps::PasteTextInputProps(
+     const PropsParserContext &context,
+     const PasteTextInputProps &sourceProps,
+     const RawProps& rawProps)
+-    : ViewProps(context, sourceProps, rawProps),
+-    BaseTextProps(context, sourceProps, rawProps),
++    : BaseTextInputProps(context, sourceProps, rawProps),
+     traits(convertRawProp(context, rawProps, sourceProps.traits, {})),
+     smartPunctuation(convertRawProp(context, rawProps, "smartPunctuation", sourceProps.smartPunctuation, {})),
+     disableCopyPaste(convertRawProp(context, rawProps, "disableCopyPaste", sourceProps.disableCopyPaste, {false})),
+@@ -133,7 +132,7 @@ TextAttributes PasteTextInputProps::getEffectiveTextAttributes(Float fontSizeMul
+ ParagraphAttributes PasteTextInputProps::getEffectiveParagraphAttributes() const {
+     auto result = paragraphAttributes;
+ 
+-    if (!traits.multiline) {
++    if (!multiline) {
+         result.maximumNumberOfLines = 1;
+     }
+ 
+diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h
+index 723d00c..31cfe66 100644
+--- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h
++++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h
+@@ -15,6 +15,7 @@
+ #include <react/renderer/components/iostextinput/conversions.h>
+ #include <react/renderer/components/iostextinput/primitives.h>
+ #include <react/renderer/components/text/BaseTextProps.h>
++#include <react/renderer/components/textinput/BaseTextInputProps.h>
+ #include <react/renderer/components/view/ViewProps.h>
+ #include <react/renderer/core/Props.h>
+ #include <react/renderer/core/PropsParserContext.h>
+@@ -25,7 +26,7 @@
+ 
+ namespace facebook::react {
+ 
+-class PasteTextInputProps final : public ViewProps, public BaseTextProps {
++class PasteTextInputProps final : public BaseTextInputProps {
+ public:
+     PasteTextInputProps() = default;
+     PasteTextInputProps(const PropsParserContext& context, const PasteTextInputProps& sourceProps, const RawProps& rawProps);
+diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp
+index 31e07e3..7f0ebfb 100644
+--- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp
++++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp
+@@ -91,20 +91,11 @@ void PasteTextInputShadowNode::updateStateIfNeeded(
+   const auto& state = getStateData();
+ 
+   react_native_assert(textLayoutManager_);
+-  react_native_assert(
+-      (!state.layoutManager || state.layoutManager == textLayoutManager_) &&
+-      "`StateData` refers to a different `TextLayoutManager`");
+-
+-  if (state.reactTreeAttributedString == reactTreeAttributedString &&
+-      state.layoutManager == textLayoutManager_) {
+-    return;
+-  }
+ 
+   auto newState = TextInputState{};
+   newState.attributedStringBox = AttributedStringBox{reactTreeAttributedString};
+   newState.paragraphAttributes = getConcreteProps().paragraphAttributes;
+   newState.reactTreeAttributedString = reactTreeAttributedString;
+-  newState.layoutManager = textLayoutManager_;
+   newState.mostRecentEventCount = getConcreteProps().mostRecentEventCount;
+   setStateData(std::move(newState));
+ }
diff --git a/patches/@sentry+react-native+6.10.0.patch b/patches/@sentry+react-native+6.14.0.patch
index 2291c598c..2291c598c 100644
--- a/patches/@sentry+react-native+6.10.0.patch
+++ b/patches/@sentry+react-native+6.14.0.patch
diff --git a/patches/expo-media-library+17.1.6.patch b/patches/expo-media-library+17.1.7.patch
index 4fa853ec3..4fa853ec3 100644
--- a/patches/expo-media-library+17.1.6.patch
+++ b/patches/expo-media-library+17.1.7.patch
diff --git a/patches/expo-modules-core+2.3.12.patch b/patches/expo-modules-core+2.4.0.patch
index f3d9bfd14..f3d9bfd14 100644
--- a/patches/expo-modules-core+2.3.12.patch
+++ b/patches/expo-modules-core+2.4.0.patch
diff --git a/patches/expo-modules-core+2.3.12.patch.md b/patches/expo-modules-core+2.4.0.patch.md
index a71324c19..a71324c19 100644
--- a/patches/expo-modules-core+2.3.12.patch.md
+++ b/patches/expo-modules-core+2.4.0.patch.md
diff --git a/patches/expo-notifications+0.31.1.patch b/patches/expo-notifications+0.31.3.patch
index 56e639a26..56e639a26 100644
--- a/patches/expo-notifications+0.31.1.patch
+++ b/patches/expo-notifications+0.31.3.patch
diff --git a/patches/expo-notifications+0.31.1.patch.md b/patches/expo-notifications+0.31.3.patch.md
index 05f841725..05f841725 100644
--- a/patches/expo-notifications+0.31.1.patch.md
+++ b/patches/expo-notifications+0.31.3.patch.md
diff --git a/patches/expo-updates+0.28.12.patch b/patches/expo-updates+0.28.14.patch
index 6fc4fc5fc..6fc4fc5fc 100644
--- a/patches/expo-updates+0.28.12.patch
+++ b/patches/expo-updates+0.28.14.patch
diff --git a/patches/expo-updates+0.28.12.patch.md b/patches/expo-updates+0.28.14.patch.md
index 6d5d7093d..6d5d7093d 100644
--- a/patches/expo-updates+0.28.12.patch.md
+++ b/patches/expo-updates+0.28.14.patch.md
diff --git a/patches/react-native+0.79.2.patch b/patches/react-native+0.79.3.patch
index 609ae6617..6d465475e 100644
--- a/patches/react-native+0.79.2.patch
+++ b/patches/react-native+0.79.3.patch
@@ -1,3 +1,32 @@
+diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
+index 914a249..0deac55 100644
+--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
++++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
+@@ -19,6 +19,8 @@ NS_ASSUME_NONNULL_BEGIN
+  */
+ @interface RCTPullToRefreshViewComponentView : RCTViewComponentView <RCTCustomPullToRefreshViewProtocol>
+ 
++- (void)beginRefreshingProgrammatically;
++
+ @end
+ 
+ NS_ASSUME_NONNULL_END
+diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
+index d029337..0f63ea3 100644
+--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
++++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
+@@ -1003,6 +1003,11 @@ - (void)_adjustForMaintainVisibleContentPosition
+   }
+ }
+ 
+++ (BOOL)shouldBeRecycled
++{
++  return NO;
++}
++
+ @end
+ 
+ Class<RCTComponentViewProtocol> RCTScrollViewCls(void)
 diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
 index e9b330f..ec5f58c 100644
 --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
@@ -15,7 +44,7 @@ diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshCont
 index 53bfd04..ff1b1ed 100644
 --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
 +++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
-@@ -23,6 +23,7 @@
+@@ -23,6 +23,7 @@ @implementation RCTRefreshControl {
    UIColor *_titleColor;
    CGFloat _progressViewOffset;
    BOOL _hasMovedToWindow;
@@ -23,7 +52,7 @@ index 53bfd04..ff1b1ed 100644
  }
  
  - (instancetype)init
-@@ -58,6 +59,12 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
+@@ -58,6 +59,12 @@ - (void)layoutSubviews
    _isInitialRender = false;
  }
  
@@ -36,7 +65,7 @@ index 53bfd04..ff1b1ed 100644
  - (void)didMoveToWindow
  {
    [super didMoveToWindow];
-@@ -221,4 +228,50 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
+@@ -221,4 +228,50 @@ - (void)refreshControlValueChanged
    }
  }
  
@@ -91,7 +120,7 @@ diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshCont
 index 40aaf9c..1c60164 100644
 --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
 +++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
-@@ -22,11 +22,12 @@ RCT_EXPORT_MODULE()
+@@ -22,11 +22,12 @@ - (UIView *)view
  
  RCT_EXPORT_VIEW_PROPERTY(onRefresh, RCTDirectEventBlock)
  RCT_EXPORT_VIEW_PROPERTY(refreshing, BOOL)
@@ -105,15 +134,3 @@ index 40aaf9c..1c60164 100644
  RCT_EXPORT_METHOD(setNativeRefreshing : (nonnull NSNumber *)viewTag toRefreshing : (BOOL)refreshing)
  {
    [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
-diff --git a/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m b/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m
-index cd1e7eb..c1d0172 100644
---- a/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m
-+++ b/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m
-@@ -83,6 +83,7 @@ RCT_EXPORT_VIEW_PROPERTY(showsVerticalScrollIndicator, BOOL)
- RCT_EXPORT_VIEW_PROPERTY(scrollEventThrottle, NSTimeInterval)
- RCT_EXPORT_VIEW_PROPERTY(zoomScale, CGFloat)
- RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets)
-+RCT_EXPORT_VIEW_PROPERTY(scrollIndicatorInsets, UIEdgeInsets)
- RCT_EXPORT_VIEW_PROPERTY(verticalScrollIndicatorInsets, UIEdgeInsets)
- RCT_EXPORT_VIEW_PROPERTY(scrollToOverflowEnabled, BOOL)
- RCT_EXPORT_VIEW_PROPERTY(snapToInterval, int)
diff --git a/patches/react-native+0.79.2.patch.md b/patches/react-native+0.79.3.patch.md
index 9c93aee5c..9c93aee5c 100644
--- a/patches/react-native+0.79.2.patch.md
+++ b/patches/react-native+0.79.3.patch.md
diff --git a/patches/react-native-svg+15.11.2.patch b/patches/react-native-svg+15.12.0.patch
index 54540023f..54540023f 100644
--- a/patches/react-native-svg+15.11.2.patch
+++ b/patches/react-native-svg+15.12.0.patch
diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx
index e5fb33849..ea7f8e94e 100644
--- a/src/components/forms/TextField.tsx
+++ b/src/components/forms/TextField.tsx
@@ -1,12 +1,12 @@
 import React from 'react'
 import {
-  AccessibilityProps,
+  type AccessibilityProps,
   StyleSheet,
   TextInput,
-  TextInputProps,
-  TextStyle,
+  type TextInputProps,
+  type TextStyle,
   View,
-  ViewStyle,
+  type ViewStyle,
 } from 'react-native'
 
 import {HITSLOP_20} from '#/lib/constants'
@@ -16,13 +16,13 @@ import {
   applyFonts,
   atoms as a,
   ios,
-  TextStyleProp,
+  type TextStyleProp,
   useAlf,
   useTheme,
   web,
 } from '#/alf'
 import {useInteractionState} from '#/components/hooks/useInteractionState'
-import {Props as SVGIconProps} from '#/components/icons/common'
+import {type Props as SVGIconProps} from '#/components/icons/common'
 import {Text} from '#/components/Typography'
 
 const Context = React.createContext<{
@@ -196,7 +196,7 @@ export function createInput(Component: typeof TextInput) {
         minWidth: 0,
       },
       ios({paddingTop: 12, paddingBottom: 13}),
-      android(a.py_sm),
+      android(a.py_md),
       // fix for autofill styles covering border
       web({
         paddingTop: 10,
diff --git a/src/lib/hooks/useHandleRef.ts b/src/lib/hooks/useHandleRef.ts
deleted file mode 100644
index 167ba270b..000000000
--- a/src/lib/hooks/useHandleRef.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import {useState} from 'react'
-import {AnimatedRef, measure, MeasuredDimensions} from 'react-native-reanimated'
-
-export type HandleRef = {
-  (node: any): void
-  current: null | number
-}
-
-// This is a lighterweight alternative to `useAnimatedRef()` for imperative UI thread actions.
-// Render it like <View ref={ref} />, then pass `ref.current` to `measureHandle()` and such.
-export function useHandleRef(): HandleRef {
-  return useState(() => {
-    const ref = (node: any) => {
-      if (node) {
-        ref.current =
-          node._nativeTag ??
-          node.__nativeTag ??
-          node.canonical?.nativeTag ??
-          null
-      } else {
-        ref.current = null
-      }
-    }
-    ref.current = null
-    return ref
-  })[0] as HandleRef
-}
-
-// When using this version, you need to read ref.current on the JS thread, and pass it to UI.
-export function measureHandle(
-  current: number | null,
-): MeasuredDimensions | null {
-  'worklet'
-  if (current !== null) {
-    return measure((() => current) as AnimatedRef<any>)
-  } else {
-    return null
-  }
-}
diff --git a/src/lib/media/manip.ts b/src/lib/media/manip.ts
index 62cbc55ac..c7a429a24 100644
--- a/src/lib/media/manip.ts
+++ b/src/lib/media/manip.ts
@@ -1,8 +1,9 @@
-import {Image as RNImage, Share as RNShare} from 'react-native'
+import {Image as RNImage} from 'react-native'
 import uuid from 'react-native-uuid'
 import {
   cacheDirectory,
   copyAsync,
+  createDownloadResumable,
   deleteAsync,
   EncodingType,
   getInfoAsync,
@@ -14,7 +15,6 @@ import {manipulateAsync, SaveFormat} from 'expo-image-manipulator'
 import * as MediaLibrary from 'expo-media-library'
 import * as Sharing from 'expo-sharing'
 import {Buffer} from 'buffer'
-import RNFetchBlob from 'rn-fetch-blob'
 
 import {POST_IMG_MAX} from '#/lib/constants'
 import {logger} from '#/logger'
@@ -68,28 +68,13 @@ export async function downloadAndResize(opts: DownloadAndResizeOpts) {
     return
   }
 
-  let downloadRes
-  try {
-    const downloadResPromise = RNFetchBlob.config({
-      fileCache: true,
-      appendExt,
-    }).fetch('GET', opts.uri)
-    const to1 = setTimeout(() => downloadResPromise.cancel(), opts.timeout)
-    downloadRes = await downloadResPromise
-    clearTimeout(to1)
-
-    const status = downloadRes.info().status
-    if (status !== 200) {
-      return
-    }
+  const path = createPath(appendExt)
 
-    const localUri = normalizePath(downloadRes.path(), true)
-    return await doResize(localUri, opts)
+  try {
+    await downloadImage(opts.uri, path, opts.timeout)
+    return await doResize(path, opts)
   } finally {
-    // TODO Whenever we remove `rn-fetch-blob`, we will need to replace this `flush()` with a `deleteAsync()` -hailey
-    if (downloadRes) {
-      downloadRes.flush()
-    }
+    safeDeleteAsync(path)
   }
 }
 
@@ -98,32 +83,16 @@ export async function shareImageModal({uri}: {uri: string}) {
     // TODO might need to give an error to the user in this case -prf
     return
   }
-  const downloadResponse = await RNFetchBlob.config({
-    fileCache: true,
-  }).fetch('GET', uri)
 
-  // NOTE
-  // assuming PNG
   // we're currently relying on the fact our CDN only serves pngs
   // -prf
-
-  let imagePath = downloadResponse.path()
-  imagePath = normalizePath(await moveToPermanentPath(imagePath, '.png'), true)
-
-  // NOTE
-  // for some reason expo-sharing refuses to work on iOS
-  // ...and visa versa
-  // -prf
-  if (isIOS) {
-    await RNShare.share({url: imagePath})
-  } else {
-    await Sharing.shareAsync(imagePath, {
-      mimeType: 'image/png',
-      UTI: 'image/png',
-    })
-  }
-
-  safeDeleteAsync(imagePath)
+  const imageUri = await downloadImage(uri, createPath('png'), 5e3)
+  const imagePath = await moveToPermanentPath(imageUri, '.png')
+  safeDeleteAsync(imageUri)
+  await Sharing.shareAsync(imagePath, {
+    mimeType: 'image/png',
+    UTI: 'image/png',
+  })
 }
 
 const ALBUM_NAME = 'Bluesky'
@@ -134,11 +103,8 @@ export async function saveImageToMediaLibrary({uri}: {uri: string}) {
   // assuming PNG
   // we're currently relying on the fact our CDN only serves pngs
   // -prf
-  const downloadResponse = await RNFetchBlob.config({
-    fileCache: true,
-  }).fetch('GET', uri)
-  let imagePath = downloadResponse.path()
-  imagePath = normalizePath(await moveToPermanentPath(imagePath, '.png'), true)
+  const imageUri = await downloadImage(uri, createPath('png'), 5e3)
+  const imagePath = await moveToPermanentPath(imageUri, '.png')
 
   // save
   try {
@@ -403,3 +369,24 @@ export function getResizedDimensions(originalDims: {
     height: Math.round(originalDims.height * ratio),
   }
 }
+
+function createPath(ext: string) {
+  // cacheDirectory will never be null on native, so the null check here is not necessary except for typescript.
+  // we use a web-only function for downloadAndResize on web
+  return `${cacheDirectory ?? ''}/${uuid.v4()}.${ext}`
+}
+
+async function downloadImage(uri: string, path: string, timeout: number) {
+  const dlResumable = createDownloadResumable(uri, path, {cache: true})
+
+  const to1 = setTimeout(() => dlResumable.cancelAsync(), timeout)
+
+  const dlRes = await dlResumable.downloadAsync()
+  clearTimeout(to1)
+
+  if (!dlRes?.uri) {
+    throw new Error('Failed to download image - dlRes is undefined')
+  }
+
+  return normalizePath(dlRes.uri)
+}
diff --git a/src/screens/Profile/Header/Shell.tsx b/src/screens/Profile/Header/Shell.tsx
index 9777c8cc7..53585c094 100644
--- a/src/screens/Profile/Header/Shell.tsx
+++ b/src/screens/Profile/Header/Shell.tsx
@@ -1,9 +1,11 @@
-import React, {memo, useEffect} from 'react'
+import {memo, useCallback, useEffect, useMemo} from 'react'
 import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'
-import {
+import Animated, {
+  measure,
   type MeasuredDimensions,
   runOnJS,
   runOnUI,
+  useAnimatedRef,
 } from 'react-native-reanimated'
 import {useSafeAreaInsets} from 'react-native-safe-area-context'
 import {type AppBskyActorDefs, type ModerationDecision} from '@atproto/api'
@@ -14,7 +16,6 @@ import {useNavigation} from '@react-navigation/native'
 import {useActorStatus} from '#/lib/actor-status'
 import {BACK_HITSLOP} from '#/lib/constants'
 import {useHaptics} from '#/lib/haptics'
-import {measureHandle, useHandleRef} from '#/lib/hooks/useHandleRef'
 import {type NavigationProp} from '#/lib/routes/types'
 import {logger} from '#/logger'
 import {isIOS} from '#/platform/detection'
@@ -59,9 +60,9 @@ let ProfileHeaderShell = ({
   const playHaptic = useHaptics()
   const liveStatusControl = useDialogControl()
 
-  const aviRef = useHandleRef()
+  const aviRef = useAnimatedRef()
 
-  const onPressBack = React.useCallback(() => {
+  const onPressBack = useCallback(() => {
     if (navigation.canGoBack()) {
       navigation.goBack()
     } else {
@@ -69,7 +70,7 @@ let ProfileHeaderShell = ({
     }
   }, [navigation])
 
-  const _openLightbox = React.useCallback(
+  const _openLightbox = useCallback(
     (uri: string, thumbRect: MeasuredDimensions | null) => {
       openLightbox({
         images: [
@@ -92,7 +93,7 @@ let ProfileHeaderShell = ({
     [openLightbox],
   )
 
-  const isMe = React.useMemo(
+  const isMe = useMemo(
     () => currentAccount?.did === profile.did,
     [currentAccount, profile],
   )
@@ -109,7 +110,7 @@ let ProfileHeaderShell = ({
     }
   }, [live.isActive, profile.did])
 
-  const onPressAvi = React.useCallback(() => {
+  const onPressAvi = useCallback(() => {
     if (live.isActive) {
       playHaptic('Light')
       logger.metric(
@@ -122,10 +123,9 @@ let ProfileHeaderShell = ({
       const modui = moderation.ui('avatar')
       const avatar = profile.avatar
       if (avatar && !(modui.blur && modui.noOverride)) {
-        const aviHandle = aviRef.current
         runOnUI(() => {
           'worklet'
-          const rect = measureHandle(aviHandle)
+          const rect = measure(aviRef)
           runOnJS(_openLightbox)(avatar, rect)
         })()
       }
@@ -223,7 +223,7 @@ let ProfileHeaderShell = ({
               styles.avi,
               profile.associated?.labeler && styles.aviLabeler,
             ]}>
-            <View ref={aviRef} collapsable={false}>
+            <Animated.View ref={aviRef} collapsable={false}>
               <UserAvatar
                 type={profile.associated?.labeler ? 'labeler' : 'user'}
                 size={live.isActive ? 88 : 90}
@@ -231,7 +231,7 @@ let ProfileHeaderShell = ({
                 moderation={moderation.ui('avatar')}
               />
               {live.isActive && <LiveIndicator size="large" />}
-            </View>
+            </Animated.View>
           </View>
         </TouchableWithoutFeedback>
       </GrowableAvatar>
diff --git a/src/view/com/composer/text-input/TextInput.tsx b/src/view/com/composer/text-input/TextInput.tsx
index 6f5e812ed..f927015af 100644
--- a/src/view/com/composer/text-input/TextInput.tsx
+++ b/src/view/com/composer/text-input/TextInput.tsx
@@ -1,5 +1,5 @@
 import React, {
-  ComponentProps,
+  type ComponentProps,
   forwardRef,
   useCallback,
   useMemo,
@@ -7,16 +7,16 @@ import React, {
   useState,
 } from 'react'
 import {
-  NativeSyntheticEvent,
+  type NativeSyntheticEvent,
   Text as RNText,
-  TextInput as RNTextInput,
-  TextInputSelectionChangeEventData,
+  type TextInput as RNTextInput,
+  type TextInputSelectionChangeEventData,
   View,
 } from 'react-native'
 import {AppBskyRichtextFacet, RichText} from '@atproto/api'
 import PasteInput, {
-  PastedFile,
-  PasteInputRef,
+  type PastedFile,
+  type PasteInputRef, // @ts-expect-error no types when installing from github
 } from '@mattermost/react-native-paste-input'
 
 import {POST_IMG_MAX} from '#/lib/constants'
@@ -27,7 +27,7 @@ import {getMentionAt, insertMentionAt} from '#/lib/strings/mention-manip'
 import {useTheme} from '#/lib/ThemeContext'
 import {isAndroid, isNative} from '#/platform/detection'
 import {
-  LinkFacetMatch,
+  type LinkFacetMatch,
   suggestLinkCardUri,
 } from '#/view/com/composer/text-input/text-input-util'
 import {atoms as a, useAlf} from '#/alf'
diff --git a/src/view/com/pager/Pager.tsx b/src/view/com/pager/Pager.tsx
index f62bffc53..8cc346903 100644
--- a/src/view/com/pager/Pager.tsx
+++ b/src/view/com/pager/Pager.tsx
@@ -1,16 +1,22 @@
-import React, {forwardRef, useCallback, useContext} from 'react'
+import {
+  useCallback,
+  useContext,
+  useImperativeHandle,
+  useRef,
+  useState,
+} from 'react'
 import {View} from 'react-native'
 import {DrawerGestureContext} from 'react-native-drawer-layout'
 import {Gesture, GestureDetector} from 'react-native-gesture-handler'
 import PagerView, {
-  PagerViewOnPageScrollEventData,
-  PagerViewOnPageSelectedEvent,
-  PagerViewOnPageSelectedEventData,
-  PageScrollStateChangedNativeEventData,
+  type PagerViewOnPageScrollEventData,
+  type PagerViewOnPageSelectedEvent,
+  type PagerViewOnPageSelectedEventData,
+  type PageScrollStateChangedNativeEventData,
 } from 'react-native-pager-view'
 import Animated, {
   runOnJS,
-  SharedValue,
+  type SharedValue,
   useEvent,
   useHandler,
   useSharedValue,
@@ -36,8 +42,12 @@ export interface RenderTabBarFnProps {
 export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element
 
 interface Props {
+  ref?: React.Ref<PagerRef>
   initialPage?: number
   renderTabBar: RenderTabBarFn
+  // tab pressed, yet to scroll to page
+  onTabPressed?: (index: number) => void
+  // scroll settled
   onPageSelected?: (index: number) => void
   onPageScrollStateChanged?: (
     scrollState: 'idle' | 'dragging' | 'settling',
@@ -47,114 +57,112 @@ interface Props {
 
 const AnimatedPagerView = Animated.createAnimatedComponent(PagerView)
 
-export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
-  function PagerImpl(
-    {
-      children,
-      initialPage = 0,
-      renderTabBar,
-      onPageScrollStateChanged: parentOnPageScrollStateChanged,
-      onPageSelected: parentOnPageSelected,
-      testID,
-    }: React.PropsWithChildren<Props>,
-    ref,
-  ) {
-    const [selectedPage, setSelectedPage] = React.useState(initialPage)
-    const pagerView = React.useRef<PagerView>(null)
+export function Pager({
+  ref,
+  children,
+  initialPage = 0,
+  renderTabBar,
+  onPageSelected: parentOnPageSelected,
+  onTabPressed: parentOnTabPressed,
+  onPageScrollStateChanged: parentOnPageScrollStateChanged,
+  testID,
+}: React.PropsWithChildren<Props>) {
+  const [selectedPage, setSelectedPage] = useState(initialPage)
+  const pagerView = useRef<PagerView>(null)
 
-    const [isIdle, setIsIdle] = React.useState(true)
-    const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
-    useFocusEffect(
-      useCallback(() => {
-        const canSwipeDrawer = selectedPage === 0 && isIdle
-        setDrawerSwipeDisabled(!canSwipeDrawer)
-        return () => {
-          setDrawerSwipeDisabled(false)
-        }
-      }, [setDrawerSwipeDisabled, selectedPage, isIdle]),
-    )
+  const [isIdle, setIsIdle] = useState(true)
+  const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
+  useFocusEffect(
+    useCallback(() => {
+      const canSwipeDrawer = selectedPage === 0 && isIdle
+      setDrawerSwipeDisabled(!canSwipeDrawer)
+      return () => {
+        setDrawerSwipeDisabled(false)
+      }
+    }, [setDrawerSwipeDisabled, selectedPage, isIdle]),
+  )
 
-    React.useImperativeHandle(ref, () => ({
-      setPage: (index: number) => {
-        pagerView.current?.setPage(index)
-      },
-    }))
+  useImperativeHandle(ref, () => ({
+    setPage: (index: number) => {
+      pagerView.current?.setPage(index)
+    },
+  }))
 
-    const onPageSelectedJSThread = React.useCallback(
-      (nextPosition: number) => {
-        setSelectedPage(nextPosition)
-        parentOnPageSelected?.(nextPosition)
-      },
-      [setSelectedPage, parentOnPageSelected],
-    )
+  const onPageSelectedJSThread = useCallback(
+    (nextPosition: number) => {
+      setSelectedPage(nextPosition)
+      parentOnPageSelected?.(nextPosition)
+    },
+    [setSelectedPage, parentOnPageSelected],
+  )
 
-    const onTabBarSelect = React.useCallback(
-      (index: number) => {
-        pagerView.current?.setPage(index)
-      },
-      [pagerView],
-    )
+  const onTabBarSelect = useCallback(
+    (index: number) => {
+      parentOnTabPressed?.(index)
+      pagerView.current?.setPage(index)
+    },
+    [pagerView, parentOnTabPressed],
+  )
 
-    const dragState = useSharedValue<'idle' | 'settling' | 'dragging'>('idle')
-    const dragProgress = useSharedValue(selectedPage)
-    const didInit = useSharedValue(false)
-    const handlePageScroll = usePagerHandlers(
-      {
-        onPageScroll(e: PagerViewOnPageScrollEventData) {
-          'worklet'
-          if (didInit.get() === false) {
-            // On iOS, there's a spurious scroll event with 0 position
-            // even if a different page was supplied as the initial page.
-            // Ignore it and wait for the first confirmed selection instead.
-            return
-          }
-          dragProgress.set(e.offset + e.position)
-        },
-        onPageScrollStateChanged(e: PageScrollStateChangedNativeEventData) {
-          'worklet'
-          runOnJS(setIsIdle)(e.pageScrollState === 'idle')
-          if (dragState.get() === 'idle' && e.pageScrollState === 'settling') {
-            // This is a programmatic scroll on Android.
-            // Stay "idle" to match iOS and avoid confusing downstream code.
-            return
-          }
-          dragState.set(e.pageScrollState)
-          parentOnPageScrollStateChanged?.(e.pageScrollState)
-        },
-        onPageSelected(e: PagerViewOnPageSelectedEventData) {
-          'worklet'
-          didInit.set(true)
-          runOnJS(onPageSelectedJSThread)(e.position)
-        },
+  const dragState = useSharedValue<'idle' | 'settling' | 'dragging'>('idle')
+  const dragProgress = useSharedValue(selectedPage)
+  const didInit = useSharedValue(false)
+  const handlePageScroll = usePagerHandlers(
+    {
+      onPageScroll(e: PagerViewOnPageScrollEventData) {
+        'worklet'
+        if (didInit.get() === false) {
+          // On iOS, there's a spurious scroll event with 0 position
+          // even if a different page was supplied as the initial page.
+          // Ignore it and wait for the first confirmed selection instead.
+          return
+        }
+        dragProgress.set(e.offset + e.position)
+      },
+      onPageScrollStateChanged(e: PageScrollStateChangedNativeEventData) {
+        'worklet'
+        runOnJS(setIsIdle)(e.pageScrollState === 'idle')
+        if (dragState.get() === 'idle' && e.pageScrollState === 'settling') {
+          // This is a programmatic scroll on Android.
+          // Stay "idle" to match iOS and avoid confusing downstream code.
+          return
+        }
+        dragState.set(e.pageScrollState)
+        parentOnPageScrollStateChanged?.(e.pageScrollState)
+      },
+      onPageSelected(e: PagerViewOnPageSelectedEventData) {
+        'worklet'
+        didInit.set(true)
+        runOnJS(onPageSelectedJSThread)(e.position)
       },
-      [parentOnPageScrollStateChanged],
-    )
+    },
+    [parentOnPageScrollStateChanged],
+  )
 
-    const drawerGesture = useContext(DrawerGestureContext) ?? Gesture.Native() // noop for web
-    const nativeGesture =
-      Gesture.Native().requireExternalGestureToFail(drawerGesture)
+  const drawerGesture = useContext(DrawerGestureContext) ?? Gesture.Native() // noop for web
+  const nativeGesture =
+    Gesture.Native().requireExternalGestureToFail(drawerGesture)
 
-    return (
-      <View testID={testID} style={[a.flex_1, native(a.overflow_hidden)]}>
-        {renderTabBar({
-          selectedPage,
-          onSelect: onTabBarSelect,
-          dragProgress,
-          dragState,
-        })}
-        <GestureDetector gesture={nativeGesture}>
-          <AnimatedPagerView
-            ref={pagerView}
-            style={[a.flex_1]}
-            initialPage={initialPage}
-            onPageScroll={handlePageScroll}>
-            {children}
-          </AnimatedPagerView>
-        </GestureDetector>
-      </View>
-    )
-  },
-)
+  return (
+    <View testID={testID} style={[a.flex_1, native(a.overflow_hidden)]}>
+      {renderTabBar({
+        selectedPage,
+        onSelect: onTabBarSelect,
+        dragProgress,
+        dragState,
+      })}
+      <GestureDetector gesture={nativeGesture}>
+        <AnimatedPagerView
+          ref={pagerView}
+          style={[a.flex_1]}
+          initialPage={initialPage}
+          onPageScroll={handlePageScroll}>
+          {children}
+        </AnimatedPagerView>
+      </GestureDetector>
+    </View>
+  )
+}
 
 function usePagerHandlers(
   handlers: {
diff --git a/src/view/com/pager/Pager.web.tsx b/src/view/com/pager/Pager.web.tsx
index c620e73e3..06aac169c 100644
--- a/src/view/com/pager/Pager.web.tsx
+++ b/src/view/com/pager/Pager.web.tsx
@@ -1,8 +1,19 @@
-import React from 'react'
+import {
+  Children,
+  useCallback,
+  useImperativeHandle,
+  useRef,
+  useState,
+} from 'react'
 import {View} from 'react-native'
 import {flushSync} from 'react-dom'
 
 import {s} from '#/lib/styles'
+import {atoms as a} from '#/alf'
+
+export interface PagerRef {
+  setPage: (index: number) => void
+}
 
 export interface RenderTabBarFnProps {
   selectedPage: number
@@ -12,30 +23,30 @@ export interface RenderTabBarFnProps {
 export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element
 
 interface Props {
+  ref?: React.Ref<PagerRef>
   initialPage?: number
   renderTabBar: RenderTabBarFn
   onPageSelected?: (index: number) => void
 }
-export const Pager = React.forwardRef(function PagerImpl(
-  {
-    children,
-    initialPage = 0,
-    renderTabBar,
-    onPageSelected,
-  }: React.PropsWithChildren<Props>,
+
+export function Pager({
   ref,
-) {
-  const [selectedPage, setSelectedPage] = React.useState(initialPage)
-  const scrollYs = React.useRef<Array<number | null>>([])
-  const anchorRef = React.useRef(null)
+  children,
+  initialPage = 0,
+  renderTabBar,
+  onPageSelected,
+}: React.PropsWithChildren<Props>) {
+  const [selectedPage, setSelectedPage] = useState(initialPage)
+  const scrollYs = useRef<Array<number | null>>([])
+  const anchorRef = useRef(null)
 
-  React.useImperativeHandle(ref, () => ({
+  useImperativeHandle(ref, () => ({
     setPage: (index: number) => {
       onTabBarSelect(index)
     },
   }))
 
-  const onTabBarSelect = React.useCallback(
+  const onTabBarSelect = useCallback(
     (index: number) => {
       const scrollY = window.scrollY
       // We want to determine if the tabbar is already "sticking" at the top (in which
@@ -75,11 +86,13 @@ export const Pager = React.forwardRef(function PagerImpl(
         tabBarAnchor: <View ref={anchorRef} />,
         onSelect: e => onTabBarSelect(e),
       })}
-      {React.Children.map(children, (child, i) => (
-        <View style={selectedPage === i ? s.flex1 : s.hidden} key={`page-${i}`}>
+      {Children.map(children, (child, i) => (
+        <View
+          style={selectedPage === i ? a.flex_1 : a.hidden}
+          key={`page-${i}`}>
           {child}
         </View>
       ))}
     </View>
   )
-})
+}
diff --git a/src/view/com/pager/PagerWithHeader.tsx b/src/view/com/pager/PagerWithHeader.tsx
index 1746d2ca1..57aaac074 100644
--- a/src/view/com/pager/PagerWithHeader.tsx
+++ b/src/view/com/pager/PagerWithHeader.tsx
@@ -1,17 +1,16 @@
-import * as React from 'react'
+import {memo, useCallback, useEffect, useRef, useState} from 'react'
 import {
-  LayoutChangeEvent,
-  NativeScrollEvent,
-  ScrollView,
+  type LayoutChangeEvent,
+  type NativeScrollEvent,
+  type ScrollView,
   StyleSheet,
   View,
 } from 'react-native'
 import Animated, {
-  AnimatedRef,
-  runOnJS,
+  type AnimatedRef,
   runOnUI,
   scrollTo,
-  SharedValue,
+  type SharedValue,
   useAnimatedRef,
   useAnimatedStyle,
   useSharedValue,
@@ -20,9 +19,13 @@ import Animated, {
 import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
 import {ScrollProvider} from '#/lib/ScrollContext'
 import {isIOS} from '#/platform/detection'
-import {Pager, PagerRef, RenderTabBarFnProps} from '#/view/com/pager/Pager'
+import {
+  Pager,
+  type PagerRef,
+  type RenderTabBarFnProps,
+} from '#/view/com/pager/Pager'
 import {useTheme} from '#/alf'
-import {ListMethods} from '../util/List'
+import {type ListMethods} from '../util/List'
 import {PagerHeaderProvider} from './PagerHeaderContext'
 import {TabBar} from './TabBar'
 
@@ -33,6 +36,7 @@ export interface PagerWithHeaderChildParams {
 }
 
 export interface PagerWithHeaderProps {
+  ref?: React.Ref<PagerRef>
   testID?: string
   children:
     | (((props: PagerWithHeaderChildParams) => JSX.Element) | null)[]
@@ -49,97 +53,94 @@ export interface PagerWithHeaderProps {
   onCurrentPageSelected?: (index: number) => void
   allowHeaderOverScroll?: boolean
 }
-export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
-  function PageWithHeaderImpl(
-    {
-      children,
-      testID,
+export function PagerWithHeader({
+  ref,
+  children,
+  testID,
+  items,
+  isHeaderReady,
+  renderHeader,
+  initialPage,
+  onPageSelected,
+  onCurrentPageSelected,
+  allowHeaderOverScroll,
+}: PagerWithHeaderProps) {
+  const [currentPage, setCurrentPage] = useState(0)
+  const [tabBarHeight, setTabBarHeight] = useState(0)
+  const [headerOnlyHeight, setHeaderOnlyHeight] = useState(0)
+  const scrollY = useSharedValue(0)
+  const headerHeight = headerOnlyHeight + tabBarHeight
+
+  // capture the header bar sizing
+  const onTabBarLayout = useNonReactiveCallback((evt: LayoutChangeEvent) => {
+    const height = evt.nativeEvent.layout.height
+    if (height > 0) {
+      // The rounding is necessary to prevent jumps on iOS
+      setTabBarHeight(Math.round(height * 2) / 2)
+    }
+  })
+  const onHeaderOnlyLayout = useNonReactiveCallback((height: number) => {
+    if (height > 0) {
+      // The rounding is necessary to prevent jumps on iOS
+      setHeaderOnlyHeight(Math.round(height * 2) / 2)
+    }
+  })
+
+  const renderTabBar = useCallback(
+    (props: RenderTabBarFnProps) => {
+      return (
+        <PagerHeaderProvider scrollY={scrollY} headerHeight={headerOnlyHeight}>
+          <PagerTabBar
+            headerOnlyHeight={headerOnlyHeight}
+            items={items}
+            isHeaderReady={isHeaderReady}
+            renderHeader={renderHeader}
+            currentPage={currentPage}
+            onCurrentPageSelected={onCurrentPageSelected}
+            onTabBarLayout={onTabBarLayout}
+            onHeaderOnlyLayout={onHeaderOnlyLayout}
+            onSelect={props.onSelect}
+            scrollY={scrollY}
+            testID={testID}
+            allowHeaderOverScroll={allowHeaderOverScroll}
+            dragProgress={props.dragProgress}
+            dragState={props.dragState}
+          />
+        </PagerHeaderProvider>
+      )
+    },
+    [
+      headerOnlyHeight,
       items,
       isHeaderReady,
       renderHeader,
-      initialPage,
-      onPageSelected,
+      currentPage,
       onCurrentPageSelected,
+      onTabBarLayout,
+      onHeaderOnlyLayout,
+      scrollY,
+      testID,
       allowHeaderOverScroll,
-    }: PagerWithHeaderProps,
-    ref,
-  ) {
-    const [currentPage, setCurrentPage] = React.useState(0)
-    const [tabBarHeight, setTabBarHeight] = React.useState(0)
-    const [headerOnlyHeight, setHeaderOnlyHeight] = React.useState(0)
-    const scrollY = useSharedValue(0)
-    const headerHeight = headerOnlyHeight + tabBarHeight
-
-    // capture the header bar sizing
-    const onTabBarLayout = useNonReactiveCallback((evt: LayoutChangeEvent) => {
-      const height = evt.nativeEvent.layout.height
-      if (height > 0) {
-        // The rounding is necessary to prevent jumps on iOS
-        setTabBarHeight(Math.round(height * 2) / 2)
-      }
-    })
-    const onHeaderOnlyLayout = useNonReactiveCallback((height: number) => {
-      if (height > 0) {
-        // The rounding is necessary to prevent jumps on iOS
-        setHeaderOnlyHeight(Math.round(height * 2) / 2)
-      }
-    })
-
-    const renderTabBar = React.useCallback(
-      (props: RenderTabBarFnProps) => {
-        return (
-          <PagerHeaderProvider
-            scrollY={scrollY}
-            headerHeight={headerOnlyHeight}>
-            <PagerTabBar
-              headerOnlyHeight={headerOnlyHeight}
-              items={items}
-              isHeaderReady={isHeaderReady}
-              renderHeader={renderHeader}
-              currentPage={currentPage}
-              onCurrentPageSelected={onCurrentPageSelected}
-              onTabBarLayout={onTabBarLayout}
-              onHeaderOnlyLayout={onHeaderOnlyLayout}
-              onSelect={props.onSelect}
-              scrollY={scrollY}
-              testID={testID}
-              allowHeaderOverScroll={allowHeaderOverScroll}
-              dragProgress={props.dragProgress}
-              dragState={props.dragState}
-            />
-          </PagerHeaderProvider>
-        )
-      },
-      [
-        headerOnlyHeight,
-        items,
-        isHeaderReady,
-        renderHeader,
-        currentPage,
-        onCurrentPageSelected,
-        onTabBarLayout,
-        onHeaderOnlyLayout,
-        scrollY,
-        testID,
-        allowHeaderOverScroll,
-      ],
-    )
+    ],
+  )
 
-    const scrollRefs = useSharedValue<Array<AnimatedRef<any> | null>>([])
-    const registerRef = React.useCallback(
-      (scrollRef: AnimatedRef<any> | null, atIndex: number) => {
-        scrollRefs.modify(refs => {
-          'worklet'
-          refs[atIndex] = scrollRef
-          return refs
-        })
-      },
-      [scrollRefs],
-    )
+  const scrollRefs = useSharedValue<Array<AnimatedRef<any> | null>>([])
+  const registerRef = useCallback(
+    (scrollRef: AnimatedRef<any> | null, atIndex: number) => {
+      scrollRefs.modify(refs => {
+        'worklet'
+        refs[atIndex] = scrollRef
+        return refs
+      })
+    },
+    [scrollRefs],
+  )
 
-    const lastForcedScrollY = useSharedValue(0)
-    const adjustScrollForOtherPages = () => {
+  const lastForcedScrollY = useSharedValue(0)
+  const adjustScrollForOtherPages = useCallback(
+    (scrollState: 'idle' | 'dragging' | 'settling') => {
       'worklet'
+      if (scrollState !== 'dragging') return
       const currentScrollY = scrollY.get()
       const forcedScrollY = Math.min(currentScrollY, headerOnlyHeight)
       if (lastForcedScrollY.get() !== forcedScrollY) {
@@ -152,75 +153,69 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
           }
         }
       }
-    }
+    },
+    [currentPage, headerOnlyHeight, lastForcedScrollY, scrollRefs, scrollY],
+  )
 
-    const throttleTimeout = React.useRef<ReturnType<typeof setTimeout> | null>(
-      null,
-    )
-    const queueThrottledOnScroll = useNonReactiveCallback(() => {
-      if (!throttleTimeout.current) {
-        throttleTimeout.current = setTimeout(() => {
-          throttleTimeout.current = null
-          runOnUI(adjustScrollForOtherPages)()
-        }, 80 /* Sync often enough you're unlikely to catch it unsynced */)
+  const onScrollWorklet = useCallback(
+    (e: NativeScrollEvent) => {
+      'worklet'
+      const nextScrollY = e.contentOffset.y
+      // HACK: onScroll is reporting some strange values on load (negative header height).
+      // Highly improbable that you'd be overscrolled by over 400px -
+      // in fact, I actually can't do it, so let's just ignore those. -sfn
+      const isPossiblyInvalid =
+        headerHeight > 0 && Math.round(nextScrollY * 2) / 2 === -headerHeight
+      if (!isPossiblyInvalid) {
+        scrollY.set(nextScrollY)
       }
-    })
+    },
+    [scrollY, headerHeight],
+  )
 
-    const onScrollWorklet = React.useCallback(
-      (e: NativeScrollEvent) => {
-        'worklet'
-        const nextScrollY = e.contentOffset.y
-        // HACK: onScroll is reporting some strange values on load (negative header height).
-        // Highly improbable that you'd be overscrolled by over 400px -
-        // in fact, I actually can't do it, so let's just ignore those. -sfn
-        const isPossiblyInvalid =
-          headerHeight > 0 && Math.round(nextScrollY * 2) / 2 === -headerHeight
-        if (!isPossiblyInvalid) {
-          scrollY.set(nextScrollY)
-          runOnJS(queueThrottledOnScroll)()
-        }
-      },
-      [scrollY, queueThrottledOnScroll, headerHeight],
-    )
+  const onPageSelectedInner = useCallback(
+    (index: number) => {
+      setCurrentPage(index)
+      onPageSelected?.(index)
+    },
+    [onPageSelected, setCurrentPage],
+  )
 
-    const onPageSelectedInner = React.useCallback(
-      (index: number) => {
-        setCurrentPage(index)
-        onPageSelected?.(index)
-      },
-      [onPageSelected, setCurrentPage],
-    )
+  const onTabPressed = useCallback(() => {
+    runOnUI(adjustScrollForOtherPages)('dragging')
+  }, [adjustScrollForOtherPages])
 
-    return (
-      <Pager
-        ref={ref}
-        testID={testID}
-        initialPage={initialPage}
-        onPageSelected={onPageSelectedInner}
-        renderTabBar={renderTabBar}>
-        {toArray(children)
-          .filter(Boolean)
-          .map((child, i) => {
-            const isReady =
-              isHeaderReady && headerOnlyHeight > 0 && tabBarHeight > 0
-            return (
-              <View key={i} collapsable={false}>
-                <PagerItem
-                  headerHeight={headerHeight}
-                  index={i}
-                  isReady={isReady}
-                  isFocused={i === currentPage}
-                  onScrollWorklet={i === currentPage ? onScrollWorklet : noop}
-                  registerRef={registerRef}
-                  renderTab={child}
-                />
-              </View>
-            )
-          })}
-      </Pager>
-    )
-  },
-)
+  return (
+    <Pager
+      ref={ref}
+      testID={testID}
+      initialPage={initialPage}
+      onTabPressed={onTabPressed}
+      onPageSelected={onPageSelectedInner}
+      renderTabBar={renderTabBar}
+      onPageScrollStateChanged={adjustScrollForOtherPages}>
+      {toArray(children)
+        .filter(Boolean)
+        .map((child, i) => {
+          const isReady =
+            isHeaderReady && headerOnlyHeight > 0 && tabBarHeight > 0
+          return (
+            <View key={i} collapsable={false}>
+              <PagerItem
+                headerHeight={headerHeight}
+                index={i}
+                isReady={isReady}
+                isFocused={i === currentPage}
+                onScrollWorklet={i === currentPage ? onScrollWorklet : noop}
+                registerRef={registerRef}
+                renderTab={child}
+              />
+            </View>
+          )
+        })}
+    </Pager>
+  )
+}
 
 let PagerTabBar = ({
   currentPage,
@@ -258,7 +253,7 @@ let PagerTabBar = ({
   dragState: SharedValue<'idle' | 'dragging' | 'settling'>
 }): React.ReactNode => {
   const t = useTheme()
-  const [minimumHeaderHeight, setMinimumHeaderHeight] = React.useState(0)
+  const [minimumHeaderHeight, setMinimumHeaderHeight] = useState(0)
   const headerTransform = useAnimatedStyle(() => {
     const translateY =
       Math.min(
@@ -275,7 +270,7 @@ let PagerTabBar = ({
       ],
     }
   })
-  const headerRef = React.useRef(null)
+  const headerRef = useRef(null)
   return (
     <Animated.View
       pointerEvents={isIOS ? 'auto' : 'box-none'}
@@ -327,7 +322,7 @@ let PagerTabBar = ({
     </Animated.View>
   )
 }
-PagerTabBar = React.memo(PagerTabBar)
+PagerTabBar = memo(PagerTabBar)
 
 function PagerItem({
   headerHeight,
@@ -348,7 +343,7 @@ function PagerItem({
 }) {
   const scrollElRef = useAnimatedRef()
 
-  React.useEffect(() => {
+  useEffect(() => {
     registerRef(scrollElRef, index)
     return () => {
       registerRef(null, index)
diff --git a/src/view/com/profile/ProfileSubpageHeader.tsx b/src/view/com/profile/ProfileSubpageHeader.tsx
index b0cf4d10e..02a6704bf 100644
--- a/src/view/com/profile/ProfileSubpageHeader.tsx
+++ b/src/view/com/profile/ProfileSubpageHeader.tsx
@@ -1,23 +1,28 @@
 import React from 'react'
 import {Pressable, View} from 'react-native'
-import {MeasuredDimensions, runOnJS, runOnUI} from 'react-native-reanimated'
-import {AppBskyGraphDefs} from '@atproto/api'
+import Animated, {
+  measure,
+  type MeasuredDimensions,
+  runOnJS,
+  runOnUI,
+  useAnimatedRef,
+} from 'react-native-reanimated'
+import {type AppBskyGraphDefs} from '@atproto/api'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useNavigation} from '@react-navigation/native'
 
-import {measureHandle, useHandleRef} from '#/lib/hooks/useHandleRef'
 import {usePalette} from '#/lib/hooks/usePalette'
 import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
 import {makeProfileLink} from '#/lib/routes/links'
-import {NavigationProp} from '#/lib/routes/types'
+import {type NavigationProp} from '#/lib/routes/types'
 import {sanitizeHandle} from '#/lib/strings/handles'
 import {emitSoftReset} from '#/state/events'
 import {useLightboxControls} from '#/state/lightbox'
 import {TextLink} from '#/view/com/util/Link'
 import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
 import {Text} from '#/view/com/util/text/Text'
-import {UserAvatar, UserAvatarType} from '#/view/com/util/UserAvatar'
+import {UserAvatar, type UserAvatarType} from '#/view/com/util/UserAvatar'
 import {StarterPack} from '#/components/icons/StarterPack'
 import * as Layout from '#/components/Layout'
 
@@ -52,7 +57,7 @@ export function ProfileSubpageHeader({
   const {openLightbox} = useLightboxControls()
   const pal = usePalette('default')
   const canGoBack = navigation.canGoBack()
-  const aviRef = useHandleRef()
+  const aviRef = useAnimatedRef()
 
   const _openLightbox = React.useCallback(
     (uri: string, thumbRect: MeasuredDimensions | null) => {
@@ -81,10 +86,9 @@ export function ProfileSubpageHeader({
     if (
       avatar // TODO && !(view.moderation.avatar.blur && view.moderation.avatar.noOverride)
     ) {
-      const aviHandle = aviRef.current
       runOnUI(() => {
         'worklet'
-        const rect = measureHandle(aviHandle)
+        const rect = measure(aviRef)
         runOnJS(_openLightbox)(avatar, rect)
       })()
     }
@@ -111,7 +115,7 @@ export function ProfileSubpageHeader({
           paddingBottom: 14,
           paddingHorizontal: isMobile ? 12 : 14,
         }}>
-        <View ref={aviRef} collapsable={false}>
+        <Animated.View ref={aviRef} collapsable={false}>
           <Pressable
             testID="headerAviButton"
             onPress={onPressAvi}
@@ -125,7 +129,7 @@ export function ProfileSubpageHeader({
               <UserAvatar type={avatarType} size={58} avatar={avatar} />
             )}
           </Pressable>
-        </View>
+        </Animated.View>
         <View style={{flex: 1, gap: 4}}>
           {isLoading ? (
             <LoadingPlaceholder
diff --git a/src/view/com/util/Toast.web.tsx b/src/view/com/util/Toast.web.tsx
index 7e22fcefc..d3b7bda33 100644
--- a/src/view/com/util/Toast.web.tsx
+++ b/src/view/com/util/Toast.web.tsx
@@ -9,7 +9,6 @@ import {
   type FontAwesomeIconStyle,
   type Props as FontAwesomeProps,
 } from '@fortawesome/react-native-fontawesome'
-import type React from 'react'
 
 const DURATION = 3500
 
diff --git a/src/view/com/util/images/AutoSizedImage.tsx b/src/view/com/util/images/AutoSizedImage.tsx
index 883d3814f..4e9c61d47 100644
--- a/src/view/com/util/images/AutoSizedImage.tsx
+++ b/src/view/com/util/images/AutoSizedImage.tsx
@@ -1,12 +1,15 @@
 import React, {useRef} from 'react'
-import {DimensionValue, Pressable, View} from 'react-native'
+import {type DimensionValue, Pressable, View} from 'react-native'
+import Animated, {
+  type AnimatedRef,
+  useAnimatedRef,
+} from 'react-native-reanimated'
 import {Image} from 'expo-image'
-import {AppBskyEmbedImages} from '@atproto/api'
+import {type AppBskyEmbedImages} from '@atproto/api'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
-import {HandleRef, useHandleRef} from '#/lib/hooks/useHandleRef'
-import type {Dimensions} from '#/lib/media/types'
+import {type Dimensions} from '#/lib/media/types'
 import {isNative} from '#/platform/detection'
 import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
 import {atoms as a, useBreakpoints, useTheme} from '#/alf'
@@ -68,14 +71,17 @@ export function AutoSizedImage({
   image: AppBskyEmbedImages.ViewImage
   crop?: 'none' | 'square' | 'constrained'
   hideBadge?: boolean
-  onPress?: (containerRef: HandleRef, fetchedDims: Dimensions | null) => void
+  onPress?: (
+    containerRef: AnimatedRef<any>,
+    fetchedDims: Dimensions | null,
+  ) => void
   onLongPress?: () => void
   onPressIn?: () => void
 }) {
   const t = useTheme()
   const {_} = useLingui()
   const largeAlt = useLargeAltBadgeEnabled()
-  const containerRef = useHandleRef()
+  const containerRef = useAnimatedRef()
   const fetchedDimsRef = useRef<{width: number; height: number} | null>(null)
 
   let aspectRatio: number | undefined
@@ -103,7 +109,7 @@ export function AutoSizedImage({
   const hasAlt = !!image.alt
 
   const contents = (
-    <View ref={containerRef} collapsable={false} style={{flex: 1}}>
+    <Animated.View ref={containerRef} collapsable={false} style={{flex: 1}}>
       <Image
         contentFit={isContain ? 'contain' : 'cover'}
         style={[a.w_full, a.h_full]}
@@ -185,7 +191,7 @@ export function AutoSizedImage({
           )}
         </View>
       ) : null}
-    </View>
+    </Animated.View>
   )
 
   if (cropDisabled) {
diff --git a/src/view/com/util/images/Gallery.tsx b/src/view/com/util/images/Gallery.tsx
index cc3eda68d..1d35c88c5 100644
--- a/src/view/com/util/images/Gallery.tsx
+++ b/src/view/com/util/images/Gallery.tsx
@@ -1,12 +1,12 @@
-import React from 'react'
-import {Pressable, StyleProp, View, ViewStyle} from 'react-native'
-import {Image, ImageStyle} from 'expo-image'
-import {AppBskyEmbedImages} from '@atproto/api'
+import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native'
+import {type AnimatedRef} from 'react-native-reanimated'
+import {Image, type ImageStyle} from 'expo-image'
+import {type AppBskyEmbedImages} from '@atproto/api'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
+import type React from 'react'
 
-import {HandleRef} from '#/lib/hooks/useHandleRef'
-import {Dimensions} from '#/lib/media/types'
+import {type Dimensions} from '#/lib/media/types'
 import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
 import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types'
 import {atoms as a, useTheme} from '#/alf'
@@ -20,7 +20,7 @@ interface Props {
   index: number
   onPress?: (
     index: number,
-    containerRefs: HandleRef[],
+    containerRefs: AnimatedRef<any>[],
     fetchedDims: (Dimensions | null)[],
   ) => void
   onLongPress?: EventFunction
@@ -28,7 +28,7 @@ interface Props {
   imageStyle?: StyleProp<ImageStyle>
   viewContext?: PostEmbedViewContext
   insetBorderStyle?: StyleProp<ViewStyle>
-  containerRefs: HandleRef[]
+  containerRefs: AnimatedRef<any>[]
   thumbDimsRef: React.MutableRefObject<(Dimensions | null)[]>
 }
 
diff --git a/src/view/com/util/images/ImageLayoutGrid.tsx b/src/view/com/util/images/ImageLayoutGrid.tsx
index 16ea9d453..b91d7a7ad 100644
--- a/src/view/com/util/images/ImageLayoutGrid.tsx
+++ b/src/view/com/util/images/ImageLayoutGrid.tsx
@@ -1,18 +1,18 @@
 import React from 'react'
-import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
-import {AppBskyEmbedImages} from '@atproto/api'
+import {type StyleProp, StyleSheet, View, type ViewStyle} from 'react-native'
+import {type AnimatedRef, useAnimatedRef} from 'react-native-reanimated'
+import {type AppBskyEmbedImages} from '@atproto/api'
 
-import {HandleRef, useHandleRef} from '#/lib/hooks/useHandleRef'
 import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types'
 import {atoms as a, useBreakpoints} from '#/alf'
-import {Dimensions} from '../../lightbox/ImageViewing/@types'
+import {type Dimensions} from '../../lightbox/ImageViewing/@types'
 import {GalleryItem} from './Gallery'
 
 interface ImageLayoutGridProps {
   images: AppBskyEmbedImages.ViewImage[]
   onPress?: (
     index: number,
-    containerRefs: HandleRef[],
+    containerRefs: AnimatedRef<any>[],
     fetchedDims: (Dimensions | null)[],
   ) => void
   onLongPress?: (index: number) => void
@@ -43,7 +43,7 @@ interface ImageLayoutGridInnerProps {
   images: AppBskyEmbedImages.ViewImage[]
   onPress?: (
     index: number,
-    containerRefs: HandleRef[],
+    containerRefs: AnimatedRef<any>[],
     fetchedDims: (Dimensions | null)[],
   ) => void
   onLongPress?: (index: number) => void
@@ -56,10 +56,10 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
   const gap = props.gap
   const count = props.images.length
 
-  const containerRef1 = useHandleRef()
-  const containerRef2 = useHandleRef()
-  const containerRef3 = useHandleRef()
-  const containerRef4 = useHandleRef()
+  const containerRef1 = useAnimatedRef()
+  const containerRef2 = useAnimatedRef()
+  const containerRef3 = useAnimatedRef()
+  const containerRef4 = useAnimatedRef()
   const thumbDimsRef = React.useRef<(Dimensions | null)[]>([])
 
   switch (count) {
diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx
index 431baa2b2..4cf71f948 100644
--- a/src/view/com/util/post-embeds/index.tsx
+++ b/src/view/com/util/post-embeds/index.tsx
@@ -7,6 +7,8 @@ import {
   type ViewStyle,
 } from 'react-native'
 import {
+  type AnimatedRef,
+  measure,
   type MeasuredDimensions,
   runOnJS,
   runOnUI,
@@ -25,7 +27,6 @@ import {
   type ModerationDecision,
 } from '@atproto/api'
 
-import {type HandleRef, measureHandle} from '#/lib/hooks/useHandleRef'
 import {usePalette} from '#/lib/hooks/usePalette'
 import {useLightboxControls} from '#/state/lightbox'
 import {useModerationOpts} from '#/state/preferences/moderation-opts'
@@ -162,13 +163,15 @@ export function PostEmbeds({
       }
       const onPress = (
         index: number,
-        refs: HandleRef[],
+        refs: AnimatedRef<any>[],
         fetchedDims: (Dimensions | null)[],
       ) => {
-        const handles = refs.map(r => r.current)
         runOnUI(() => {
           'worklet'
-          const rects = handles.map(measureHandle)
+          const rects: (MeasuredDimensions | null)[] = []
+          for (const r of refs) {
+            rects.push(measure(r))
+          }
           runOnJS(_openLightbox)(index, rects, fetchedDims)
         })()
       }
diff --git a/yarn.lock b/yarn.lock
index 9c6a36847..125c985ea 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3776,29 +3776,29 @@
   resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.47.0.tgz#5478fdf443ff8158f9de171c704ae45308696c7d"
   integrity sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==
 
-"@expo/cli@0.24.10":
-  version "0.24.10"
-  resolved "https://registry.yarnpkg.com/@expo/cli/-/cli-0.24.10.tgz#f23d150f011cdebd6f503343d9be3c6283fb4096"
-  integrity sha512-auPE4MSRdkJkHsWJk935VoqX/BGMKARgXOLtJybTFUi64K3MkvdUoBrujcn/QzXl5DTGhacFd9qxUeQss6/qwg==
+"@expo/cli@0.24.14":
+  version "0.24.14"
+  resolved "https://registry.yarnpkg.com/@expo/cli/-/cli-0.24.14.tgz#af2e7ea5a08e3574e868cb0ec2110e68d32672e0"
+  integrity sha512-o+QYyfIBhSRTgaywKTLJhm2Fg5PrSeUVCXS+uQySamgoMjLNhHa8QwE64mW/FmJr5hZLiqUEQxb60FK4JcyqXg==
   dependencies:
     "@0no-co/graphql.web" "^1.0.8"
     "@babel/runtime" "^7.20.0"
     "@expo/code-signing-certificates" "^0.0.5"
-    "@expo/config" "~11.0.7"
+    "@expo/config" "~11.0.10"
     "@expo/config-plugins" "~10.0.2"
     "@expo/devcert" "^1.1.2"
     "@expo/env" "~1.0.5"
     "@expo/image-utils" "^0.7.4"
     "@expo/json-file" "^9.1.4"
-    "@expo/metro-config" "~0.20.12"
+    "@expo/metro-config" "~0.20.14"
     "@expo/osascript" "^2.2.4"
     "@expo/package-manager" "^1.8.4"
     "@expo/plist" "^0.3.4"
-    "@expo/prebuild-config" "^9.0.5"
+    "@expo/prebuild-config" "^9.0.6"
     "@expo/spawn-async" "^1.7.2"
     "@expo/ws-tunnel" "^1.0.1"
     "@expo/xcpretty" "^4.3.0"
-    "@react-native/dev-middleware" "0.79.2"
+    "@react-native/dev-middleware" "0.79.3"
     "@urql/core" "^5.0.6"
     "@urql/exchange-retry" "^1.3.0"
     accepts "^1.3.8"
@@ -3813,9 +3813,9 @@
     debug "^4.3.4"
     env-editor "^0.4.1"
     freeport-async "^2.0.0"
-    getenv "^1.0.0"
+    getenv "^2.0.0"
     glob "^10.4.2"
-    lan-network "^0.1.4"
+    lan-network "^0.1.6"
     minimatch "^9.0.0"
     node-forge "^1.3.1"
     npm-package-arg "^11.0.0"
@@ -3871,7 +3871,7 @@
     xcode "^3.0.1"
     xml2js "0.6.0"
 
-"@expo/config-plugins@~10.0.1", "@expo/config-plugins@~10.0.2":
+"@expo/config-plugins@~10.0.2":
   version "10.0.2"
   resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-10.0.2.tgz#040867991e9c8c527b4f5c13a47bcf040a7479fe"
   integrity sha512-TzUn3pPdpwCS0yYaSlZOClgDmCX8N4I2lfgitX5oStqmvpPtB+vqtdyqsVM02fQ2tlJIAqwBW+NHaHqqy8Jv7g==
@@ -3926,6 +3926,11 @@
   resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-53.0.3.tgz#d083d9b095972e89eee96c41d085feb5b92d2749"
   integrity sha512-V1e6CiM4TXtGxG/W2Msjp/QOx/vikLo5IUGMvEMjgAglBfGYx3PXfqsUb5aZDt6kqA3bDDwFuZoS5vNm/SYwSg==
 
+"@expo/config-types@^53.0.4":
+  version "53.0.4"
+  resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-53.0.4.tgz#fe64fac734531ae883d18529b32586c23ffb1ceb"
+  integrity sha512-0s+9vFx83WIToEr0Iwy4CcmiUXa5BgwBmEjylBB2eojX5XAMm9mJvw9KpjAb8m7zq2G0Q6bRbeufkzgbipuNQg==
+
 "@expo/config@~10.0.4":
   version "10.0.5"
   resolved "https://registry.yarnpkg.com/@expo/config/-/config-10.0.5.tgz#2de75e3f5d46a55f9f5140b73e0913265e6a41c6"
@@ -3945,14 +3950,14 @@
     slugify "^1.3.4"
     sucrase "3.35.0"
 
-"@expo/config@~11.0.6", "@expo/config@~11.0.7":
-  version "11.0.7"
-  resolved "https://registry.yarnpkg.com/@expo/config/-/config-11.0.7.tgz#e6a6071942854269825e2450c3a115c963a4fd56"
-  integrity sha512-pppH3Cy2IfituiYACMeW7cWYezcjmHKq7lDLfH1gMHT+zZ1QaYNs3EN6Kcc/QAXV//KFFhU0Qq4H/UrLuPp/yg==
+"@expo/config@~11.0.10", "@expo/config@~11.0.9":
+  version "11.0.10"
+  resolved "https://registry.yarnpkg.com/@expo/config/-/config-11.0.10.tgz#559d9425a4e0de4fab96ccac01ff40f5cebbc04b"
+  integrity sha512-8S8Krr/c5lnl0eF03tA2UGY9rGBhZcbWKz2UWw5dpL/+zstwUmog8oyuuC8aRcn7GiTQLlbBkxcMeT8sOGlhbA==
   dependencies:
     "@babel/code-frame" "~7.10.4"
-    "@expo/config-plugins" "~10.0.1"
-    "@expo/config-types" "^53.0.3"
+    "@expo/config-plugins" "~10.0.2"
+    "@expo/config-types" "^53.0.4"
     "@expo/json-file" "^9.1.4"
     deepmerge "^4.3.1"
     getenv "^1.0.0"
@@ -4005,23 +4010,24 @@
     dotenv-expand "~11.0.6"
     getenv "^1.0.0"
 
-"@expo/fingerprint@0.12.4":
-  version "0.12.4"
-  resolved "https://registry.yarnpkg.com/@expo/fingerprint/-/fingerprint-0.12.4.tgz#d4cc4de50e7b6d4e03b0d38850d1e4a136b74c8c"
-  integrity sha512-HOJVvjiQYVHIouCOfFf4JRrQvBDIV/12GVG2iwbw1iGwmpQVkPgEXa9lN0f2yuS4J3QXHs73wr9jvuCjMmJlfw==
+"@expo/fingerprint@0.13.0":
+  version "0.13.0"
+  resolved "https://registry.yarnpkg.com/@expo/fingerprint/-/fingerprint-0.13.0.tgz#5f5600122940ac381ed697743c10bdbddf6c55c1"
+  integrity sha512-3IwpH0p3uO8jrJSLOUNDzJVh7VEBod0emnCBq0hD72sy6ICmzauM6Xf4he+2Tip7fzImCJRd63GaehV+CCtpvA==
   dependencies:
     "@expo/spawn-async" "^1.7.2"
     arg "^5.0.2"
     chalk "^4.1.2"
     debug "^4.3.4"
     find-up "^5.0.0"
-    getenv "^1.0.0"
+    getenv "^2.0.0"
+    ignore "^5.3.1"
     minimatch "^9.0.0"
     p-limit "^3.1.0"
     resolve-from "^5.0.0"
     semver "^7.6.0"
 
-"@expo/html-elements@^0.12.4":
+"@expo/html-elements@^0.12.5":
   version "0.12.5"
   resolved "https://registry.yarnpkg.com/@expo/html-elements/-/html-elements-0.12.5.tgz#be7e7af9f2be6d3f1aa3ec2e7ae1c121c91a9aa1"
   integrity sha512-28KWO88YKykKU7ke5sEQs5TivFRMs1Aktz13xxgqAf5rTgb+lka0VKVt3W2fG7ksbUQ407rtUqz7SEAq298NvQ==
@@ -4068,16 +4074,16 @@
     json5 "^2.2.3"
     write-file-atomic "^2.3.0"
 
-"@expo/metro-config@0.20.12", "@expo/metro-config@~0.20.12":
-  version "0.20.12"
-  resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.20.12.tgz#f6e2c33a305cb0ab8b0aa0dadafd6adf09058b9c"
-  integrity sha512-O9zaAF3gH76EXkwuQCpXLKC5dBy344/pqoszWmtOloKo4gJy74aNPUy2LRS57pDHyjZe1HjrxVkMcr7lZCIsag==
+"@expo/metro-config@0.20.14", "@expo/metro-config@~0.20.14":
+  version "0.20.14"
+  resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.20.14.tgz#5abf8cd6454fe7f75c1f8529cf79619da32af82d"
+  integrity sha512-tYDDubuZycK+NX00XN7BMu73kBur/evOPcKfxc+UBeFfgN2EifOITtdwSUDdRsbtJ2OnXwMY1HfRUG3Lq3l4cw==
   dependencies:
     "@babel/core" "^7.20.0"
     "@babel/generator" "^7.20.5"
     "@babel/parser" "^7.20.0"
     "@babel/types" "^7.20.0"
-    "@expo/config" "~11.0.7"
+    "@expo/config" "~11.0.9"
     "@expo/env" "~1.0.5"
     "@expo/json-file" "~9.1.4"
     "@expo/spawn-async" "^1.7.2"
@@ -4140,14 +4146,14 @@
     base64-js "^1.2.3"
     xmlbuilder "^15.1.1"
 
-"@expo/prebuild-config@^9.0.5":
-  version "9.0.5"
-  resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-9.0.5.tgz#b8b864b5e19489a1f66442ae30d5d7295f658297"
-  integrity sha512-oiSVU5ePu9lsOvn5p4xplqjzPlcZHzKYwzuonTa9GCH1GxcOEIBsvMVQiHBXHtqvgV2dztjm34kdXV//+9jtCA==
+"@expo/prebuild-config@^9.0.6":
+  version "9.0.6"
+  resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-9.0.6.tgz#f634e7b8f9ebebeaf2e7d2f2be46926c23834d2b"
+  integrity sha512-HDTdlMkTQZ95rd6EpvuLM+xkZV03yGLc38FqI37qKFLJtUN1WnYVaWsuXKoljd1OrVEVsHe6CfqKwaPZ52D56Q==
   dependencies:
-    "@expo/config" "~11.0.7"
+    "@expo/config" "~11.0.9"
     "@expo/config-plugins" "~10.0.2"
-    "@expo/config-types" "^53.0.3"
+    "@expo/config-types" "^53.0.4"
     "@expo/image-utils" "^0.7.4"
     "@expo/json-file" "^9.1.4"
     "@react-native/normalize-colors" "0.79.2"
@@ -4416,10 +4422,10 @@
     protobufjs "^7.2.5"
     yargs "^17.7.2"
 
-"@haileyok/bluesky-video@0.2.6":
-  version "0.2.6"
-  resolved "https://registry.yarnpkg.com/@haileyok/bluesky-video/-/bluesky-video-0.2.6.tgz#61bb4ff908498558fd2320f06ba0f74ea03598b4"
-  integrity sha512-IlzrTATD7ci/a+ehSA7pIhOvxxNTe35zdzBYt8EmVvKKafyeFhxGfDuuP5qxfQmHurcQMIL+3HeZgnAXwQQNmQ==
+"@haileyok/bluesky-video@0.3.1":
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/@haileyok/bluesky-video/-/bluesky-video-0.3.1.tgz#c996d8433e8f1988f2e9644adf39366fb4305d00"
+  integrity sha512-TU5c0RCV1yWF/HEZA22E0qXjxNzu0SOuMZpvdo+QVrO4tQcja9k8nHBbKRmyj60Odke4HQMoTOfNDNq/xo2Grw==
 
 "@hapi/accept@^6.0.3":
   version "6.0.3"
@@ -5119,12 +5125,11 @@
     "@babel/runtime" "^7.20.13"
     "@lingui/core" "4.14.1"
 
-"@mattermost/react-native-paste-input@^0.7.1":
-  version "0.7.1"
-  resolved "https://registry.yarnpkg.com/@mattermost/react-native-paste-input/-/react-native-paste-input-0.7.1.tgz#f14585030b992cf7c9bbd0921225eefa501756ba"
-  integrity sha512-kY8LKtqRX2T/rtn/HNrzTitijuATvyzd6yl5WNWOsszmyzNcssKStjjCTBup04CyMxfwutUU1CWrYUb3hQO7oA==
+"@mattermost/react-native-paste-input@mattermost/react-native-paste-input":
+  version "0.8.1"
+  resolved "https://codeload.github.com/mattermost/react-native-paste-input/tar.gz/f260447edc645a817ab1ba7b46d8341d84dba8e9"
   dependencies:
-    semver "7.6.0"
+    semver "7.6.3"
 
 "@messageformat/parser@^5.0.0":
   version "5.1.0"
@@ -5133,12 +5138,12 @@
   dependencies:
     moo "^0.5.1"
 
-"@miblanchard/react-native-slider@^2.3.1":
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/@miblanchard/react-native-slider/-/react-native-slider-2.3.1.tgz#79e0f1f9b1ce43ef25ee51ee9256c012e5dfa412"
-  integrity sha512-J/hZDBWmXq8fJeOnTVHqIUVDHshqMSpJVxJ4WqwuCBKl5Rke9OBYXIdkSlgi75OgtScAr8FKK5KNkDKHUf6JIg==
+"@miblanchard/react-native-slider@^2.6.0":
+  version "2.6.0"
+  resolved "https://registry.yarnpkg.com/@miblanchard/react-native-slider/-/react-native-slider-2.6.0.tgz#9f78c805d637ffaff0e3e7429932d2995a67edc9"
+  integrity sha512-o7hk/f/8vkqh6QNR5L52m+ws846fQeD/qNCC9CCSRdBqjq66KiCgbxzlhRzKM/gbtxcvMYMIEEJ1yes5cr6I3A==
 
-"@mozzius/expo-dynamic-app-icon@^1.5.0":
+"@mozzius/expo-dynamic-app-icon@1.5.0":
   version "1.5.0"
   resolved "https://registry.yarnpkg.com/@mozzius/expo-dynamic-app-icon/-/expo-dynamic-app-icon-1.5.0.tgz#c5f88c309965b6d6b89cfd5e2c00faa7bda736af"
   integrity sha512-yE2yEPO+HQmOqsX7cECh7/vu/LXnqhHGsVm3UiVi/3gaK8u5hAkPTNzZ0Qu6vnMwjPnY+uFbN6X+6Aj9c9yjMQ==
@@ -6141,23 +6146,23 @@
   resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-2.11.0.tgz#4587fbce6a382adedad74311e96ee10bb2b2d63a"
   integrity sha512-QuZU6gbxmOID5zZgd/H90NgBnbJ3VV6qVzp6c7/dDrmWdX8S0X5YFYgDcQFjE3dRen9wB9FWnj2VVdPU64adSg==
 
-"@react-native/assets-registry@0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.79.2.tgz#731963e664c8543f5b277e56c058bde612b69f50"
-  integrity sha512-5h2Z7/+/HL/0h88s0JHOdRCW4CXMCJoROxqzHqxdrjGL6EBD1DdaB4ZqkCOEVSW4Vjhir5Qb97C8i/MPWEYPtg==
+"@react-native/assets-registry@0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.79.3.tgz#022218d55a5d9d221a6d176987ab0b35c10d388b"
+  integrity sha512-Vy8DQXCJ21YSAiHxrNBz35VqVlZPpRYm50xRTWRf660JwHuJkFQG8cUkrLzm7AUriqUXxwpkQHcY+b0ibw9ejQ==
 
-"@react-native/babel-plugin-codegen@0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.79.2.tgz#f3f86766a01487aaaa623ec62514af4c84400953"
-  integrity sha512-d+NB7Uosn2ZWd4O4+7ZkB6q1a+0z2opD/4+Bzhk/Tv6fc5FrSftK2Noqxvo3/bhbdGFVPxf0yvLE8et4W17x/Q==
+"@react-native/babel-plugin-codegen@0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.79.3.tgz#acad4acaead398a8c8bcdecbe44040aa0c2dc2d7"
+  integrity sha512-Zb8F4bSEKKZfms5n1MQ0o5mudDcpAINkKiFuFTU0PErYGjY3kZ+JeIP+gS6KCXsckxCfMEKQwqKicP/4DWgsZQ==
   dependencies:
     "@babel/traverse" "^7.25.3"
-    "@react-native/codegen" "0.79.2"
+    "@react-native/codegen" "0.79.3"
 
-"@react-native/babel-preset@0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.79.2.tgz#5a683a6efeea357a326f70c84a881be2bafbeae3"
-  integrity sha512-/HNu869oUq4FUXizpiNWrIhucsYZqu0/0spudJEzk9SEKar0EjVDP7zkg/sKK+KccNypDQGW7nFXT8onzvQ3og==
+"@react-native/babel-preset@0.79.2", "@react-native/babel-preset@0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.79.3.tgz#8ad6c149cd488fbc18d62983119bdcbfc15ff651"
+  integrity sha512-VHGNP02bDD2Ul1my0pLVwe/0dsEBHxR343ySpgnkCNEEm9C1ANQIL2wvnJrHZPcqfAkWfFQ8Ln3t+6fdm4A/Dg==
   dependencies:
     "@babel/core" "^7.25.2"
     "@babel/plugin-proposal-export-default-from" "^7.24.7"
@@ -6200,15 +6205,15 @@
     "@babel/plugin-transform-typescript" "^7.25.2"
     "@babel/plugin-transform-unicode-regex" "^7.24.7"
     "@babel/template" "^7.25.0"
-    "@react-native/babel-plugin-codegen" "0.79.2"
+    "@react-native/babel-plugin-codegen" "0.79.3"
     babel-plugin-syntax-hermes-parser "0.25.1"
     babel-plugin-transform-flow-enums "^0.0.2"
     react-refresh "^0.14.0"
 
-"@react-native/codegen@0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.79.2.tgz#75270d8162e78c02b0272396a3c6942e39e8703d"
-  integrity sha512-8JTlGLuLi1p8Jx2N/enwwEd7/2CfrqJpv90Cp77QLRX3VHF2hdyavRIxAmXMwN95k+Me7CUuPtqn2X3IBXOWYg==
+"@react-native/codegen@0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.79.3.tgz#49689132718c81a3b25426769bc6fd8fd2a0469f"
+  integrity sha512-CZejXqKch/a5/s/MO5T8mkAgvzCXgsTkQtpCF15kWR9HN8T+16k0CsN7TXAxXycltoxiE3XRglOrZNEa/TiZUQ==
   dependencies:
     glob "^7.1.1"
     hermes-parser "0.25.1"
@@ -6216,12 +6221,12 @@
     nullthrows "^1.1.1"
     yargs "^17.6.2"
 
-"@react-native/community-cli-plugin@0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.79.2.tgz#d3a0efbdfb554cf3a7e9bfb27865a7caeeeaa1b3"
-  integrity sha512-E+YEY2dL+68HyR2iahsZdyBKBUi9QyPyaN9vsnda1jNgCjNpSPk2yAF5cXsho+zKK5ZQna3JSeE1Kbi2IfGJbw==
+"@react-native/community-cli-plugin@0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.79.3.tgz#84821d3401074e036ba05b8b6ca1ee122cb43e29"
+  integrity sha512-N/+p4HQqN4yK6IRzn7OgMvUIcrmEWkecglk1q5nj+AzNpfIOzB+mqR20SYmnPfeXF+mZzYCzRANb3KiM+WsSDA==
   dependencies:
-    "@react-native/dev-middleware" "0.79.2"
+    "@react-native/dev-middleware" "0.79.3"
     chalk "^4.0.0"
     debug "^2.2.0"
     invariant "^2.2.4"
@@ -6230,18 +6235,18 @@
     metro-core "^0.82.0"
     semver "^7.1.3"
 
-"@react-native/debugger-frontend@0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.79.2.tgz#1377de6d9cabe5455bf332e06408167da5f60c19"
-  integrity sha512-cGmC7X6kju76DopSBNc+PRAEetbd7TWF9J9o84hOp/xL3ahxR2kuxJy0oJX8Eg8oehhGGEXTuMKHzNa3rDBeSg==
+"@react-native/debugger-frontend@0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.79.3.tgz#9cb57d8e88c22552194ab5f6f257605b151bc5b3"
+  integrity sha512-ImNDuEeKH6lEsLXms3ZsgIrNF94jymfuhPcVY5L0trzaYNo9ZFE9Ni2/18E1IbfXxdeIHrCSBJlWD6CTm7wu5A==
 
-"@react-native/dev-middleware@0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.79.2.tgz#f09f1a75b4cd0b56dfd82a07bf41157a9c45619c"
-  integrity sha512-9q4CpkklsAs1L0Bw8XYCoqqyBSrfRALGEw4/r0EkR38Y/6fVfNfdsjSns0pTLO6h0VpxswK34L/hm4uK3MoLHw==
+"@react-native/dev-middleware@0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.79.3.tgz#3e315ef7516ebad60a4202b4094d84fedecb4064"
+  integrity sha512-x88+RGOyG71+idQefnQg7wLhzjn/Scs+re1O5vqCkTVzRAc/f7SdHMlbmECUxJPd08FqMcOJr7/X3nsJBrNuuw==
   dependencies:
     "@isaacs/ttlcache" "^1.4.1"
-    "@react-native/debugger-frontend" "0.79.2"
+    "@react-native/debugger-frontend" "0.79.3"
     chrome-launcher "^0.15.2"
     chromium-edge-launcher "^0.2.0"
     connect "^3.6.5"
@@ -6252,14 +6257,14 @@
     serve-static "^1.16.2"
     ws "^6.2.3"
 
-"@react-native/eslint-config@^0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/eslint-config/-/eslint-config-0.79.2.tgz#b42c95fe2399aae84209356b0971dd68c4149e4e"
-  integrity sha512-ukb9qGvrFC/3YVlWVy/GGM+auKdGIsbbumCyfOYPfUdhHFWA/twz1zK4bJQmCZ38iINuTENYedRzoE+U57GclA==
+"@react-native/eslint-config@^0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/eslint-config/-/eslint-config-0.79.3.tgz#a72352ce98a7d05b5686dc446ba933fee3b944a9"
+  integrity sha512-pvPXfXFoVfwqGEItIl7emv6bRTpi0NWv4jmb0ZBwSJ7+zM8bRRw7JwxLA+iwrevh0QAqrF66Nu5xl39ysWcavg==
   dependencies:
     "@babel/core" "^7.25.2"
     "@babel/eslint-parser" "^7.25.1"
-    "@react-native/eslint-plugin" "0.79.2"
+    "@react-native/eslint-plugin" "0.79.3"
     "@typescript-eslint/eslint-plugin" "^7.1.1"
     "@typescript-eslint/parser" "^7.1.1"
     eslint-config-prettier "^8.5.0"
@@ -6270,35 +6275,35 @@
     eslint-plugin-react-hooks "^4.6.0"
     eslint-plugin-react-native "^4.0.0"
 
-"@react-native/eslint-plugin@0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/eslint-plugin/-/eslint-plugin-0.79.2.tgz#23d18226bb4335404e6db561bf1a47ac7d1380ed"
-  integrity sha512-Abu+0OuwTje9E5eQOvYpTUuXvDgGjHeFhnfNVY9BXalBK8OrX20EFlonWvIbFqii136eS5KLEBm2Wjqk2V5XJg==
+"@react-native/eslint-plugin@0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/eslint-plugin/-/eslint-plugin-0.79.3.tgz#c1ac34d45b92f963b9af66e860c45cd891235741"
+  integrity sha512-6QZzCsV+Wc+HdOAMMoMqDea3SSzsvBBktGc/cqaLubKGiztTb22d+vtzZGWqCqUEVkhQKdK7qhWAs0kJPEbiXw==
 
-"@react-native/gradle-plugin@0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.79.2.tgz#d41d4e2c63baf688a2b47652c6260f2a2f1ec091"
-  integrity sha512-6MJFemrwR0bOT0QM+2BxX9k3/pvZQNmJ3Js5pF/6owsA0cUDiCO57otiEU8Fz+UywWEzn1FoQfOfQ8vt2GYmoA==
+"@react-native/gradle-plugin@0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.79.3.tgz#69ba47ac406ccdb3b3829f311bd7c27e6fad7ebc"
+  integrity sha512-imfpZLhNBc9UFSzb/MOy2tNcIBHqVmexh/qdzw83F75BmUtLb/Gs1L2V5gw+WI1r7RqDILbWk7gXB8zUllwd+g==
 
-"@react-native/js-polyfills@0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.79.2.tgz#15eb4da0fe9e8d61d2980d08fd06b5f49e133b0f"
-  integrity sha512-IaY87Ckd4GTPMkO1/Fe8fC1IgIx3vc3q9Tyt/6qS3Mtk9nC0x9q4kSR5t+HHq0/MuvGtu8HpdxXGy5wLaM+zUw==
+"@react-native/js-polyfills@0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.79.3.tgz#bf5614363f118c6bdf2f773c578e603c88d0425c"
+  integrity sha512-PEBtg6Kox6KahjCAch0UrqCAmHiNLEbp2SblUEoFAQnov4DSxBN9safh+QSVaCiMAwLjvNfXrJyygZz60Dqz3Q==
 
-"@react-native/normalize-colors@0.79.2", "@react-native/normalize-colors@^0.73.0", "@react-native/normalize-colors@^0.74.1":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.79.2.tgz#9ab70ca257c7411e4ab74cf7f91332c27d39cc6f"
-  integrity sha512-+b+GNrupWrWw1okHnEENz63j7NSMqhKeFMOyzYLBwKcprG8fqJQhDIGXfizKdxeIa5NnGSAevKL1Ev1zJ56X8w==
+"@react-native/normalize-colors@0.79.2", "@react-native/normalize-colors@0.79.3", "@react-native/normalize-colors@^0.73.0", "@react-native/normalize-colors@^0.74.1":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.79.3.tgz#e491937436a2c287707e24263308c818a66eb447"
+  integrity sha512-T75NIQPRFCj6DFMxtcVMJTZR+3vHXaUMSd15t+CkJpc5LnyX91GVaPxpRSAdjFh7m3Yppl5MpdjV/fntImheYQ==
 
-"@react-native/typescript-config@^0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/typescript-config/-/typescript-config-0.79.2.tgz#02cb07db89ef80159b3c1b3e82e81b0c0d5ce908"
-  integrity sha512-krHAkkPRCOEhuqN3iwRUwIyE1rAnUQ9//huzUc1ukcoQ7Y4qFxM6amhNloAmYn4QH1Ay6o5At00VbEh2xoHISA==
+"@react-native/typescript-config@^0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/typescript-config/-/typescript-config-0.79.3.tgz#21101b591c67ecef6ae5189f96a448b3bcaf1e9e"
+  integrity sha512-dqKAU8D3NkExthnpBOPZjZ/NGU5qqBaqZ12v9IlMqP9sVTWSuY1iswfzomp0AYeJBxo4ZpBNmrdlnQZYQSVWiw==
 
-"@react-native/virtualized-lists@0.79.2":
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.79.2.tgz#ed5a419a30b7ddec978b7816ff698a9d85507e15"
-  integrity sha512-9G6ROJeP+rdw9Bvr5ruOlag11ET7j1z/En1riFFNo6W3xZvJY+alCuH1ttm12y9+zBm4n8jwCk4lGhjYaV4dKw==
+"@react-native/virtualized-lists@0.79.3":
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.79.3.tgz#4a2799017cd3795f519422f48b3c0bbc4739a245"
+  integrity sha512-/0rRozkn+iIHya2vnnvprDgT7QkfI54FLrACAN3BLP7MRlfOIGOrZsXpRLndnLBVnjNzkcre84i1RecjoXnwIA==
   dependencies:
     invariant "^2.2.4"
     nullthrows "^1.1.1"
@@ -6412,6 +6417,11 @@
   resolved "https://registry.yarnpkg.com/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-3.2.2.tgz#0c5f26e417b8f524924fa4531b82ad5603216e90"
   integrity sha512-D+SKQ266ra/wo87s9+UI/rKQi3qhGPCR8eSCDe0VJudhjHsqyNU+JJ5lnIGCgmZaWFTXgdBP/gdr1Iz1zqGs4Q==
 
+"@sentry/babel-plugin-component-annotate@3.4.0":
+  version "3.4.0"
+  resolved "https://registry.yarnpkg.com/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-3.4.0.tgz#f47a7652e16f84556df82cbc38f0004bca1335d1"
+  integrity sha512-tSzfc3aE7m0PM0Aj7HBDet5llH9AB9oc+tBQ8AvOqUSnWodLrNCuWeQszJ7mIBovD3figgCU3h0cvI6U5cDtsg==
+
 "@sentry/browser@8.54.0":
   version "8.54.0"
   resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-8.54.0.tgz#5487075908aac564892e689e1b6d233fdb314f5b"
@@ -6442,70 +6452,75 @@
   resolved "https://registry.yarnpkg.com/@sentry/cli-darwin/-/cli-darwin-2.42.2.tgz#a32a4f226e717122b37d9969e8d4d0e14779f720"
   integrity sha512-GtJSuxER7Vrp1IpxdUyRZzcckzMnb4N5KTW7sbTwUiwqARRo+wxS+gczYrS8tdgtmXs5XYhzhs+t4d52ITHMIg==
 
-"@sentry/cli-darwin@2.42.4":
-  version "2.42.4"
-  resolved "https://registry.yarnpkg.com/@sentry/cli-darwin/-/cli-darwin-2.42.4.tgz#029521d3052c644e3bac1c926e53d1e658b8cb28"
-  integrity sha512-PZV4Y97VDWBR4rIt0HkJfXaBXlebIN2s/FDzC3iHINZE5OG62CDFsnC4/lbGlf2/UZLDaGGIK7mYwSHhTvN+HQ==
+"@sentry/cli-darwin@2.45.0":
+  version "2.45.0"
+  resolved "https://registry.yarnpkg.com/@sentry/cli-darwin/-/cli-darwin-2.45.0.tgz#e3d6feae4fadcfdf91db9c7b9c4689a66d3d8d19"
+  integrity sha512-p4Uxfv/L2fQdP3/wYnKVVz9gzZJf/1Xp9D+6raax/3Bu5y87yHYUqcdt98y/VAXQD4ofp2QgmhGUVPofvQNZmg==
 
 "@sentry/cli-linux-arm64@2.42.2":
   version "2.42.2"
   resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.42.2.tgz#1c06c83ff21f51ec23acf5be3b1f8c7553bf86b1"
   integrity sha512-BOxzI7sgEU5Dhq3o4SblFXdE9zScpz6EXc5Zwr1UDZvzgXZGosUtKVc7d1LmkrHP8Q2o18HcDWtF3WvJRb5Zpw==
 
-"@sentry/cli-linux-arm64@2.42.4":
-  version "2.42.4"
-  resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.42.4.tgz#b5e2d2399764998e3d661f144aae0c3f3495d1f1"
-  integrity sha512-Ex8vRnryyzC/9e43daEmEqPS+9uirY/l6Hw2lAvhBblFaL7PTWNx52H+8GnYGd9Zy2H3rWNyBDYfHwnErg38zA==
+"@sentry/cli-linux-arm64@2.45.0":
+  version "2.45.0"
+  resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.45.0.tgz#384c8e17f7e7dc007d164033d0e7c75aa83a2e9b"
+  integrity sha512-gUcLoEjzg7AIc4QQGEZwRHri+EHf3Gcms9zAR1VHiNF3/C/jL4WeDPJF2YiWAQt6EtH84tHiyhw1Ab/R8XFClg==
 
 "@sentry/cli-linux-arm@2.42.2":
   version "2.42.2"
   resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm/-/cli-linux-arm-2.42.2.tgz#00cadc359ae3c051efb3e63873c033c61dbd1ca1"
   integrity sha512-7udCw+YL9lwq+9eL3WLspvnuG+k5Icg92YE7zsteTzWLwgPVzaxeZD2f8hwhsu+wmL+jNqbpCRmktPteh3i2mg==
 
-"@sentry/cli-linux-arm@2.42.4":
-  version "2.42.4"
-  resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm/-/cli-linux-arm-2.42.4.tgz#286996c3969a553c07a74a2a67c6d3671e2c79b5"
-  integrity sha512-lBn0oeeg62h68/4Eo6zbPq99Idz5t0VRV48rEU/WKeM4MtQCvG/iGGQ3lBFW2yNiUBzXZIK9poXLEcgbwmcRVw==
+"@sentry/cli-linux-arm@2.45.0":
+  version "2.45.0"
+  resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm/-/cli-linux-arm-2.45.0.tgz#b9d6f86f3934b4d9ced5b45a8158ff2ac2bdd25d"
+  integrity sha512-6sEskFLlFKJ+e0MOYgIclBTUX5jYMyYhHIxXahEkI/4vx6JO0uvpyRAkUJRpJkRh/lPog0FM+tbP3so+VxB2qQ==
 
 "@sentry/cli-linux-i686@2.42.2":
   version "2.42.2"
   resolved "https://registry.yarnpkg.com/@sentry/cli-linux-i686/-/cli-linux-i686-2.42.2.tgz#3b817b715dd806c20dfbffd539725ad8089c310a"
   integrity sha512-Sw/dQp5ZPvKnq3/y7wIJyxTUJYPGoTX/YeMbDs8BzDlu9to2LWV3K3r7hE7W1Lpbaw4tSquUHiQjP5QHCOS7aQ==
 
-"@sentry/cli-linux-i686@2.42.4":
-  version "2.42.4"
-  resolved "https://registry.yarnpkg.com/@sentry/cli-linux-i686/-/cli-linux-i686-2.42.4.tgz#03e72598dc37e96a99e4329e20db9e74df277f83"
-  integrity sha512-IBJg0aHjsLCL4LvcFa3cXIjA+4t5kPqBT9y+PoDu4goIFxYD8zl7mbUdGJutvJafTk8Akf4ss4JJXQBjg019zA==
+"@sentry/cli-linux-i686@2.45.0":
+  version "2.45.0"
+  resolved "https://registry.yarnpkg.com/@sentry/cli-linux-i686/-/cli-linux-i686-2.45.0.tgz#39e22beb84cfa26e11bdc198364315fdfb4da4d5"
+  integrity sha512-VmmOaEAzSW23YdGNdy/+oQjCNAMY+HmOGA77A25/ep/9AV7PQB6FI7xO5Y1PVvlkxZFJ23e373njSsEeg4uDZw==
 
 "@sentry/cli-linux-x64@2.42.2":
   version "2.42.2"
   resolved "https://registry.yarnpkg.com/@sentry/cli-linux-x64/-/cli-linux-x64-2.42.2.tgz#ddf906bc3071cc79ce6e633eddcb76bb9068e688"
   integrity sha512-mU4zUspAal6TIwlNLBV5oq6yYqiENnCWSxtSQVzWs0Jyq97wtqGNG9U+QrnwjJZ+ta/hvye9fvL2X25D/RxHQw==
 
-"@sentry/cli-linux-x64@2.42.4":
-  version "2.42.4"
-  resolved "https://registry.yarnpkg.com/@sentry/cli-linux-x64/-/cli-linux-x64-2.42.4.tgz#a3bc31a909f61029620e5d2ae0f8d8625ed8982a"
-  integrity sha512-gXI5OEiOSNiAEz7VCE6AZcAgHJ47mlgal3+NmbE8XcHmFOnyDws9FNie6PJAy8KZjXi3nqoBP9JVAbnmOix3uA==
+"@sentry/cli-linux-x64@2.45.0":
+  version "2.45.0"
+  resolved "https://registry.yarnpkg.com/@sentry/cli-linux-x64/-/cli-linux-x64-2.45.0.tgz#25cd3699297f9433835fb5edd42dad722c11f041"
+  integrity sha512-a0Oj68mrb25a0WjX/ShZ6AAd4PPiuLcgyzQr7bl2+DvYxIOajwkGbR+CZFEhOVZcfhTnixKy/qIXEzApEPHPQg==
+
+"@sentry/cli-win32-arm64@2.45.0":
+  version "2.45.0"
+  resolved "https://registry.yarnpkg.com/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.45.0.tgz#50c7d29ea2169bdb4d98bbde81c5f7dac0dd3955"
+  integrity sha512-vn+CwS4p+52pQSLNPoi20ZOrQmv01ZgAmuMnjkh1oUZfTyBAwWLrAh6Cy4cztcN8DfL5dOWKQBo8DBKURE4ttg==
 
 "@sentry/cli-win32-i686@2.42.2":
   version "2.42.2"
   resolved "https://registry.yarnpkg.com/@sentry/cli-win32-i686/-/cli-win32-i686-2.42.2.tgz#9036085c7c6ce455ad45fda411c55ff39c06eb95"
   integrity sha512-iHvFHPGqgJMNqXJoQpqttfsv2GI3cGodeTq4aoVLU/BT3+hXzbV0x1VpvvEhncJkDgDicJpFLM8sEPHb3b8abw==
 
-"@sentry/cli-win32-i686@2.42.4":
-  version "2.42.4"
-  resolved "https://registry.yarnpkg.com/@sentry/cli-win32-i686/-/cli-win32-i686-2.42.4.tgz#0de663fc574f4bce2057e099c5b76b65f99a3bd6"
-  integrity sha512-vZuR3UPHKqOMniyrijrrsNwn9usaRysXq78F6WV0cL0ZyPLAmY+KBnTDSFk1Oig2pURnzaTm+RtcZu2fc8mlzg==
+"@sentry/cli-win32-i686@2.45.0":
+  version "2.45.0"
+  resolved "https://registry.yarnpkg.com/@sentry/cli-win32-i686/-/cli-win32-i686-2.45.0.tgz#201075c4aec37a3e797160e0b468641245437f0c"
+  integrity sha512-8mMoDdlwxtcdNIMtteMK7dbi7054jak8wKSHJ5yzMw8UmWxC5thc/gXBc1uPduiaI56VjoJV+phWHBKCD+6I4w==
 
 "@sentry/cli-win32-x64@2.42.2":
   version "2.42.2"
   resolved "https://registry.yarnpkg.com/@sentry/cli-win32-x64/-/cli-win32-x64-2.42.2.tgz#7d6464b63f32c9f97fff428f246b1f039b402233"
   integrity sha512-vPPGHjYoaGmfrU7xhfFxG7qlTBacroz5NdT+0FmDn6692D8IvpNXl1K+eV3Kag44ipJBBeR8g1HRJyx/F/9ACw==
 
-"@sentry/cli-win32-x64@2.42.4":
-  version "2.42.4"
-  resolved "https://registry.yarnpkg.com/@sentry/cli-win32-x64/-/cli-win32-x64-2.42.4.tgz#f572a03084f3b1a4f355c1fbeb1339cb56ad91c9"
-  integrity sha512-OIBj3uaQ6nAERSm5Dcf8UIhyElEEwMNsZEEppQpN4IKl0mrwb/57AznM23Dvpu6GR8WGbVQUSolt879YZR5E9g==
+"@sentry/cli-win32-x64@2.45.0":
+  version "2.45.0"
+  resolved "https://registry.yarnpkg.com/@sentry/cli-win32-x64/-/cli-win32-x64-2.45.0.tgz#2075e9e1ea3c3609e0fa1a758ca033e94e1c600f"
+  integrity sha512-ZvK9cIqFaq7vZ0jkHJ/xh5au6902Dr+AUxSk6L6vCL7JCe2p93KGL/4d8VFB5PD/P7Y9b+105G/e0QIFKzpeOw==
 
 "@sentry/cli@2.42.2":
   version "2.42.2"
@@ -6526,10 +6541,10 @@
     "@sentry/cli-win32-i686" "2.42.2"
     "@sentry/cli-win32-x64" "2.42.2"
 
-"@sentry/cli@2.42.4":
-  version "2.42.4"
-  resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-2.42.4.tgz#df6ac3e92a60a715b231873433894ed77e601086"
-  integrity sha512-BoSZDAWJiz/40tu6LuMDkSgwk4xTsq6zwqYoUqLU3vKBR/VsaaQGvu6EWxZXORthfZU2/5Agz0+t220cge6VQw==
+"@sentry/cli@2.45.0":
+  version "2.45.0"
+  resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-2.45.0.tgz#35feed7a2fee54faf25daed73001a2a2a3143396"
+  integrity sha512-4sWu7zgzgHAjIxIjXUA/66qgeEf5ZOlloO+/JaGD5qXNSW0G7KMTR6iYjReNKMgdBCTH6bUUt9qiuA+Ex9Masw==
   dependencies:
     https-proxy-agent "^5.0.0"
     node-fetch "^2.6.7"
@@ -6537,27 +6552,28 @@
     proxy-from-env "^1.1.0"
     which "^2.0.2"
   optionalDependencies:
-    "@sentry/cli-darwin" "2.42.4"
-    "@sentry/cli-linux-arm" "2.42.4"
-    "@sentry/cli-linux-arm64" "2.42.4"
-    "@sentry/cli-linux-i686" "2.42.4"
-    "@sentry/cli-linux-x64" "2.42.4"
-    "@sentry/cli-win32-i686" "2.42.4"
-    "@sentry/cli-win32-x64" "2.42.4"
+    "@sentry/cli-darwin" "2.45.0"
+    "@sentry/cli-linux-arm" "2.45.0"
+    "@sentry/cli-linux-arm64" "2.45.0"
+    "@sentry/cli-linux-i686" "2.45.0"
+    "@sentry/cli-linux-x64" "2.45.0"
+    "@sentry/cli-win32-arm64" "2.45.0"
+    "@sentry/cli-win32-i686" "2.45.0"
+    "@sentry/cli-win32-x64" "2.45.0"
 
 "@sentry/core@8.54.0":
   version "8.54.0"
   resolved "https://registry.yarnpkg.com/@sentry/core/-/core-8.54.0.tgz#a2ebec965cadcb6de89e116689feeef79d5862a6"
   integrity sha512-03bWf+D1j28unOocY/5FDB6bUHtYlm6m6ollVejhg45ZmK9iPjdtxNWbrLsjT1WRym0Tjzowu+A3p+eebYEv0Q==
 
-"@sentry/react-native@~6.10.0":
-  version "6.10.0"
-  resolved "https://registry.yarnpkg.com/@sentry/react-native/-/react-native-6.10.0.tgz#9efafb9b85870bd4c5189763edde30709b9f3213"
-  integrity sha512-B56vc+pnFHMiu3cabFb454v4qD0zObW6JVzJ5Gb6fIMdt93AFIJg10ZErzC+ump7xM4BOEROFFRuLiyvadvlPA==
+"@sentry/react-native@~6.14.0":
+  version "6.14.0"
+  resolved "https://registry.yarnpkg.com/@sentry/react-native/-/react-native-6.14.0.tgz#bc6bdaf03860bb8946f8c30570a9abd82ed6cfc0"
+  integrity sha512-BBqixN6oV6tCNp1ABXfzvD531zxj1fUAH0HDPvOR/jX0h9f9pYfxCyI64B+DoQbVZKFsg8nte0QIHkZDhRAW9A==
   dependencies:
-    "@sentry/babel-plugin-component-annotate" "3.2.2"
+    "@sentry/babel-plugin-component-annotate" "3.4.0"
     "@sentry/browser" "8.54.0"
-    "@sentry/cli" "2.42.4"
+    "@sentry/cli" "2.45.0"
     "@sentry/core" "8.54.0"
     "@sentry/react" "8.54.0"
     "@sentry/types" "8.54.0"
@@ -8731,6 +8747,33 @@ babel-preset-expo@~13.1.11:
     react-refresh "^0.14.2"
     resolve-from "^5.0.0"
 
+babel-preset-expo@~13.2.0:
+  version "13.2.0"
+  resolved "https://registry.yarnpkg.com/babel-preset-expo/-/babel-preset-expo-13.2.0.tgz#d4540009d07242e3c3d63184b7a34efda95e8e64"
+  integrity sha512-oNUeUZPMNRPmx/2jaKJLSQFP/MFI1M91vP+Gp+j8/FPl9p/ps603DNwCaRdcT/Vj3FfREdlIwRio1qDCjY0oAA==
+  dependencies:
+    "@babel/helper-module-imports" "^7.25.9"
+    "@babel/plugin-proposal-decorators" "^7.12.9"
+    "@babel/plugin-proposal-export-default-from" "^7.24.7"
+    "@babel/plugin-syntax-export-default-from" "^7.24.7"
+    "@babel/plugin-transform-export-namespace-from" "^7.25.9"
+    "@babel/plugin-transform-flow-strip-types" "^7.25.2"
+    "@babel/plugin-transform-modules-commonjs" "^7.24.8"
+    "@babel/plugin-transform-object-rest-spread" "^7.24.7"
+    "@babel/plugin-transform-parameters" "^7.24.7"
+    "@babel/plugin-transform-private-methods" "^7.24.7"
+    "@babel/plugin-transform-private-property-in-object" "^7.24.7"
+    "@babel/plugin-transform-runtime" "^7.24.7"
+    "@babel/preset-react" "^7.22.15"
+    "@babel/preset-typescript" "^7.23.0"
+    "@react-native/babel-preset" "0.79.3"
+    babel-plugin-react-native-web "~0.19.13"
+    babel-plugin-syntax-hermes-parser "^0.25.1"
+    babel-plugin-transform-flow-enums "^0.0.2"
+    debug "^4.3.4"
+    react-refresh "^0.14.2"
+    resolve-from "^5.0.0"
+
 babel-preset-jest@^29.6.3:
   version "29.6.3"
   resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c"
@@ -8749,11 +8792,6 @@ balanced-match@^1.0.0:
   resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
   integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
 
-base-64@0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb"
-  integrity sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==
-
 base64-arraybuffer@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc"
@@ -8960,6 +8998,16 @@ browserslist@^4.24.0, browserslist@^4.24.2:
     node-releases "^2.0.18"
     update-browserslist-db "^1.1.1"
 
+browserslist@^4.25.0:
+  version "4.25.0"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.0.tgz#986aa9c6d87916885da2b50d8eb577ac8d133b2c"
+  integrity sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==
+  dependencies:
+    caniuse-lite "^1.0.30001718"
+    electron-to-chromium "^1.5.160"
+    node-releases "^2.0.19"
+    update-browserslist-db "^1.1.3"
+
 bser@2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05"
@@ -9102,6 +9150,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001517, caniuse-lite@^1.0.30001587, can
   resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001697.tgz"
   integrity sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ==
 
+caniuse-lite@^1.0.30001718:
+  version "1.0.30001722"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001722.tgz#ec25a2b3085b25b9079b623db83c22a70882ce85"
+  integrity sha512-DCQHBBZtiK6JVkAGw7drvAMK0Q0POD/xZvEmDp6baiMMP6QXXk9HpD6mNYBZWhOPG6LvIDb82ITqtWjhDckHCA==
+
 cbor-extract@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/cbor-extract/-/cbor-extract-2.1.1.tgz#f154b31529fdb6b7c70fb3ca448f44eda96a1b42"
@@ -10340,6 +10393,11 @@ electron-to-chromium@^1.4.668:
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.777.tgz#f846fbba23fd11b3c6f97848cdda94896fdb8baf"
   integrity sha512-n02NCwLJ3wexLfK/yQeqfywCblZqLcXphzmid5e8yVPdtEcida7li0A5WQKghHNG0FeOMCzeFOzEbtAh5riXFw==
 
+electron-to-chromium@^1.5.160:
+  version "1.5.166"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.166.tgz#3fff386ed473cc2169dbe2d3ace9592262601114"
+  integrity sha512-QPWqHL0BglzPYyJJ1zSSmwFFL6MFXhbACOCcsCdUMCkzPdS9/OIBVxg516X/Ado2qwAq8k0nJJ7phQPCqiaFAw==
+
 electron-to-chromium@^1.5.41:
   version "1.5.51"
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.51.tgz#bb99216fed4892d131a8585a8593b00739310163"
@@ -11146,18 +11204,18 @@ expo-application@~6.1.4:
   resolved "https://registry.yarnpkg.com/expo-application/-/expo-application-6.1.4.tgz#34ee2f7a86e3689f15961b296e82934e0f85afd6"
   integrity sha512-jXVZb3llTQ5j4C/I03GxKjujmhKex9Xo5JDZo/pRjScHSr4NoeMjPKWThyWVlWDM1v5YSEcsRJebVfTvq9SR5Q==
 
-expo-asset@~11.1.4:
-  version "11.1.4"
-  resolved "https://registry.yarnpkg.com/expo-asset/-/expo-asset-11.1.4.tgz#0258156f76c306521eb2a0d27e98d26258d12ad9"
-  integrity sha512-e3210sF0YHKRTCjVUOVmDAJ0Dk4vepL9RocKe36S7S+VthoCZwsBGLAM2LLvBa1SdmODF92AS0Nrcfi/1/VlbQ==
+expo-asset@~11.1.5:
+  version "11.1.5"
+  resolved "https://registry.yarnpkg.com/expo-asset/-/expo-asset-11.1.5.tgz#5cad3d781c9d0edec31b9b3adbba574eb4d5dd3e"
+  integrity sha512-GEQDCqC25uDBoXHEnXeBuwpeXvI+3fRGvtzwwt0ZKKzWaN+TgeF8H7c76p3Zi4DfBMFDcduM0CmOvJX+yCCLUQ==
   dependencies:
     "@expo/image-utils" "^0.7.4"
-    expo-constants "~17.1.4"
+    expo-constants "~17.1.5"
 
-expo-blur@~14.1.4:
-  version "14.1.4"
-  resolved "https://registry.yarnpkg.com/expo-blur/-/expo-blur-14.1.4.tgz#d246c0a224ce63321d022edfc0e6a8c5fa2cc865"
-  integrity sha512-55P9tK/RjJZEcu2tU7BqX3wmIOrGMOOkmHztJMMws+ZGHzvtjnPmT7dsQxhOU9vPj77oHnKetYHU2sik3iBcCw==
+expo-blur@~14.1.5:
+  version "14.1.5"
+  resolved "https://registry.yarnpkg.com/expo-blur/-/expo-blur-14.1.5.tgz#910712389e19286ccdc136275bf569f427aa05ef"
+  integrity sha512-CCLJHxN4eoAl06ESKT3CbMasJ98WsjF9ZQEJnuxtDb9ffrYbZ+g9ru84fukjNUOTtc8A8yXE5z8NgY1l0OMrmQ==
 
 expo-build-properties@~0.14.6:
   version "0.14.6"
@@ -11167,10 +11225,10 @@ expo-build-properties@~0.14.6:
     ajv "^8.11.0"
     semver "^7.6.0"
 
-expo-camera@~16.1.6:
-  version "16.1.6"
-  resolved "https://registry.yarnpkg.com/expo-camera/-/expo-camera-16.1.6.tgz#9badbc3b93cab3386e3e70721d4f3c1983ab539c"
-  integrity sha512-caVSfoTUaayYhH5gicrXWCgBQIVrotPOH3jUDr4vhN5VQDB/+TWaY+le2nQtNXgQEz14Af+H/TNvYpvvNj5Ktg==
+expo-camera@~16.1.8:
+  version "16.1.8"
+  resolved "https://registry.yarnpkg.com/expo-camera/-/expo-camera-16.1.8.tgz#6c30dfb5c982795351f1053c36f048a11869e21b"
+  integrity sha512-NpBbkUhHG6cs2TNUQBFSEtXb5j1/kTPIhiuqBcHosZG2yb/8MuM/ii4McJaqfe/6pn0YPqkH4k0Uod11DOSLmw==
   dependencies:
     invariant "^2.2.4"
 
@@ -11179,7 +11237,7 @@ expo-clipboard@~7.1.4:
   resolved "https://registry.yarnpkg.com/expo-clipboard/-/expo-clipboard-7.1.4.tgz#f2cda0d3cbfd2d307aa85dd7ba6843d6bbaf4227"
   integrity sha512-NHhfKnrzb4o0PacUKD93ByadU0JmPBoFTFYbbFJZ9OAX6SImpSqG5gfrMUR3vVj4Qx9f1LpMcdAv5lBzv868ow==
 
-expo-constants@17.0.3, expo-constants@^13.0.2, expo-constants@~17.1.4, expo-constants@~17.1.5:
+expo-constants@17.0.3, expo-constants@^13.0.2, expo-constants@~17.1.5, expo-constants@~17.1.6:
   version "17.0.3"
   resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-17.0.3.tgz#a05b38e0417d59759ece1642b4d483889e04dbda"
   integrity sha512-lnbcX2sAu8SucHXEXxSkhiEpqH+jGrf+TF+MO6sHWIESjwOUVVYlT8qYdjR9xbxWmqFtrI4KV44FkeJf2DaFjQ==
@@ -11187,25 +11245,25 @@ expo-constants@17.0.3, expo-constants@^13.0.2, expo-constants@~17.1.4, expo-cons
     "@expo/config" "~10.0.4"
     "@expo/env" "~0.4.0"
 
-expo-dev-client@~5.1.7:
-  version "5.1.7"
-  resolved "https://registry.yarnpkg.com/expo-dev-client/-/expo-dev-client-5.1.7.tgz#b75d5c4650a2b19e8d5c4666a798a4150a7fbd68"
-  integrity sha512-/xcwNIeZIBA/y6Io7jv1ZbEG8XRUuAynIJyIGJvpMxf6hm7eEw8rEzhO9rZNk6H8bMjTjASs0Vf1bqIV6v3j6A==
+expo-dev-client@~5.2.0:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/expo-dev-client/-/expo-dev-client-5.2.0.tgz#a3d4f8c79fafe747ea8d0bfc6e3918b02011025c"
+  integrity sha512-7GgO3BGlFM016Zkp3c9bUbi35pubqKh8Z/iHC1arIvckEjDrLER+92zfUTFr49XLk2o64arItRPJyQL49pA/hg==
   dependencies:
-    expo-dev-launcher "5.1.10"
-    expo-dev-menu "6.1.9"
+    expo-dev-launcher "5.1.12"
+    expo-dev-menu "6.1.11"
     expo-dev-menu-interface "1.10.0"
-    expo-manifests "~0.16.4"
+    expo-manifests "~0.16.5"
     expo-updates-interface "~1.1.0"
 
-expo-dev-launcher@5.1.10:
-  version "5.1.10"
-  resolved "https://registry.yarnpkg.com/expo-dev-launcher/-/expo-dev-launcher-5.1.10.tgz#eaa8a7a4edcab557e6623f176e60d964606651ff"
-  integrity sha512-OW4k0efB6cWigYj1GlJGObMuMpg6DIwsAZkECsGqNU3U80zE7pBMPB0sy1xehFuTplO6F+dCTLg0hPPuqkSsTg==
+expo-dev-launcher@5.1.12:
+  version "5.1.12"
+  resolved "https://registry.yarnpkg.com/expo-dev-launcher/-/expo-dev-launcher-5.1.12.tgz#cad239327e258d84c4221a212ecd30a051f9097d"
+  integrity sha512-ALedYerjJtSiPa95l41zMAO/m1m1kgS39i2H0io+6Ix4OksYNhILNzMNB1qDht/oWt2yjLBvXfWULfs5+3vnaA==
   dependencies:
     ajv "8.11.0"
-    expo-dev-menu "6.1.8"
-    expo-manifests "~0.16.4"
+    expo-dev-menu "6.1.11"
+    expo-manifests "~0.16.5"
     resolve-from "^5.0.0"
 
 expo-dev-menu-interface@1.10.0:
@@ -11213,28 +11271,14 @@ expo-dev-menu-interface@1.10.0:
   resolved "https://registry.yarnpkg.com/expo-dev-menu-interface/-/expo-dev-menu-interface-1.10.0.tgz#04671bda3c163d1d7b9438ce7095c3913a3f53f9"
   integrity sha512-NxtM/qot5Rh2cY333iOE87dDg1S8CibW+Wu4WdLua3UMjy81pXYzAGCZGNOeY7k9GpNFqDPNDXWyBSlk9r2pBg==
 
-expo-dev-menu@6.1.8:
-  version "6.1.8"
-  resolved "https://registry.yarnpkg.com/expo-dev-menu/-/expo-dev-menu-6.1.8.tgz#cec53379b76f5cb53e2e87a8c62555610a26e6bb"
-  integrity sha512-i8DW1OXvj4yxQuPP8p2AMGoYdnyhfTkoqWI/AiDYReh2viZv4kZlRloGAemV2bIQwswMq2GsvZehYrQPEK9QBw==
-  dependencies:
-    expo-dev-menu-interface "1.10.0"
-
-expo-dev-menu@6.1.9:
-  version "6.1.9"
-  resolved "https://registry.yarnpkg.com/expo-dev-menu/-/expo-dev-menu-6.1.9.tgz#897dcb4c49aed9c1f871b13e1359079f23981050"
-  integrity sha512-Uz02Bsc1xsYzjW4Ld+PxWLRNkbsoJYSbQtw/pZDSrJk5Hj869M4KQSOI8JpZ7WVlKEKkIRA8kBLepjhdFhq+Dg==
+expo-dev-menu@6.1.11:
+  version "6.1.11"
+  resolved "https://registry.yarnpkg.com/expo-dev-menu/-/expo-dev-menu-6.1.11.tgz#829118326bcd618aec3941cfbb5b32fd3dd72379"
+  integrity sha512-yrlDXGcqlbQX3Pgw/iPLRea7+pHFC17MdtkNaXYQ5K5u64mn9l4KZ2ZYUeQ8cKDG5l8ZdC4F9R9vfCJYFi82AA==
   dependencies:
     expo-dev-menu-interface "1.10.0"
 
-expo-device@7.0.1, expo-device@~4.1.1:
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-7.0.1.tgz#3702fe8b4475eac63ed27f9d580ec8a78546e0d1"
-  integrity sha512-/3lk0f9wvle+6svHqWSCBC1B5NYFmXp1D7hmIyecJJVYRLwzrwwTDyNs76oG/UDU5Appdu8QyDKycsx2hqv71w==
-  dependencies:
-    ua-parser-js "^0.7.33"
-
-expo-device@~7.1.4:
+expo-device@7.1.4, expo-device@~4.1.1, expo-device@~7.1.4:
   version "7.1.4"
   resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-7.1.4.tgz#84ae7c2520cc45f15a9cb0433ae1226c33f7a8ef"
   integrity sha512-HS04IiE1Fy0FRjBLurr9e5A6yj3kbmQB+2jCZvbSGpsjBnCLdSk/LCii4f5VFhPIBWJLyYuN5QqJyEAw6BcS4Q==
@@ -11246,15 +11290,15 @@ expo-eas-client@~0.14.3:
   resolved "https://registry.yarnpkg.com/expo-eas-client/-/expo-eas-client-0.14.3.tgz#3fc22378cc454953ecba88f70c16c20a74e0aa27"
   integrity sha512-BW2mSNEjFRFC8/CbkMQ3mfVhBdeZIjZhNfncw7PP80xEptLWhVjGTqwG8Usi0/yPpIu/YNYgop+XGMfhXyh9uA==
 
-expo-file-system@~18.1.8:
-  version "18.1.8"
-  resolved "https://registry.yarnpkg.com/expo-file-system/-/expo-file-system-18.1.8.tgz#caa0831b9826f568be36deb25aed835978e957b3"
-  integrity sha512-1HXpunpRMGnoIw0+f2urjUNaePAvac1X9wIwVRsGJTw7A2WHBFATRuFB7jUOhZac/qK1MDm0GZsggzoRi1oteQ==
+expo-file-system@~18.1.10:
+  version "18.1.10"
+  resolved "https://registry.yarnpkg.com/expo-file-system/-/expo-file-system-18.1.10.tgz#22f3bcc2c9a7edcd6bba5ece3c90a8467fda47be"
+  integrity sha512-SyaWg+HitScLuyEeSG9gMSDT0hIxbM9jiZjSBP9l9zMnwZjmQwsusE6+7qGiddxJzdOhTP4YGUfvEzeeS0YL3Q==
 
-expo-font@~13.3.0:
-  version "13.3.0"
-  resolved "https://registry.yarnpkg.com/expo-font/-/expo-font-13.3.0.tgz#139e6e1024e414afe1180ffed0add98aa8c8950b"
-  integrity sha512-TdbHoxCfLWN9Uvnqsrcak+5EkDCbNIWfgtNWx3JZ6sD9WYB7gvbS+Eu5YlZ85NvCOSJ9Khmw4mFQxEi2LUPZfQ==
+expo-font@~13.3.1:
+  version "13.3.1"
+  resolved "https://registry.yarnpkg.com/expo-font/-/expo-font-13.3.1.tgz#ed69ae14f263a4c447efb2615b60d9e045372e68"
+  integrity sha512-d+xrHYvSM9WB42wj8vP9OOFWyxed5R1evphfDb6zYBmC1dA9Hf89FpT7TNFtj2Bk3clTnpmVqQTCYbbA2P3CLg==
   dependencies:
     fontfaceobserver "^2.1.0"
 
@@ -11273,10 +11317,10 @@ expo-image-loader@~5.1.0:
   resolved "https://registry.yarnpkg.com/expo-image-loader/-/expo-image-loader-5.1.0.tgz#f7d65f9b9a9714eaaf5d50a406cb34cb25262153"
   integrity sha512-sEBx3zDQIODWbB5JwzE7ZL5FJD+DK3LVLWBVJy6VzsqIA6nDEnSFnsnWyCfCTSvbGigMATs1lgkC2nz3Jpve1Q==
 
-expo-image-manipulator@~13.1.5:
-  version "13.1.5"
-  resolved "https://registry.yarnpkg.com/expo-image-manipulator/-/expo-image-manipulator-13.1.5.tgz#d657dceeb8ce8da9345a1903f1327b0fedfd08c1"
-  integrity sha512-V9cGJp0zVwAvAyL3w9JsLH8UEQjQZfFmwJM1l9/oXjlDrSDynQrPFwJq4VI8dCOJ+/nhYZK37yytFNG14Sqt4Q==
+expo-image-manipulator@~13.1.7:
+  version "13.1.7"
+  resolved "https://registry.yarnpkg.com/expo-image-manipulator/-/expo-image-manipulator-13.1.7.tgz#e891ce9b49d75962eafdf5b7d670116583379e76"
+  integrity sha512-DBy/Xdd0E/yFind14x36XmwfWuUxOHI/oH97/giKjjPaRc2dlyjQ3tuW3x699hX6gAs9Sixj5WEJ1qNf3c8sag==
   dependencies:
     expo-image-loader "~5.1.0"
 
@@ -11287,10 +11331,10 @@ expo-image-picker@~16.1.4:
   dependencies:
     expo-image-loader "~5.1.0"
 
-expo-image@~2.1.6:
-  version "2.1.6"
-  resolved "https://registry.yarnpkg.com/expo-image/-/expo-image-2.1.6.tgz#f046fa631768e37326cc14c49de9113ceffa9e8b"
-  integrity sha512-AFQxeAI1iTXFZ4dMxUB+SOACGMQxEk+t7PvT3j4mrvffRFoOLfHZ4uJc8SAdDFJak7ByqKhCIPIEhL+1Deq4Sg==
+expo-image@~2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/expo-image/-/expo-image-2.2.1.tgz#b4aa706a25f7e8902ac854a8da249caf4a90cd67"
+  integrity sha512-5ZSggMi0X2G9AN0aM+sdkCyyZ6YcWvGs9KYLYrRBVUN3ph6RBiu6mKGpaNN1TAscySRnH1eHbUE1H+Qeq7qm1g==
 
 expo-json-utils@~0.15.0:
   version "0.15.0"
@@ -11302,17 +11346,17 @@ expo-keep-awake@~14.1.4:
   resolved "https://registry.yarnpkg.com/expo-keep-awake/-/expo-keep-awake-14.1.4.tgz#80197728563e0e17523e5a606fbd6fbed9639503"
   integrity sha512-wU9qOnosy4+U4z/o4h8W9PjPvcFMfZXrlUoKTMBW7F4pLqhkkP/5G4EviPZixv4XWFMjn1ExQ5rV6BX8GwJsWA==
 
-expo-linear-gradient@~14.1.4:
-  version "14.1.4"
-  resolved "https://registry.yarnpkg.com/expo-linear-gradient/-/expo-linear-gradient-14.1.4.tgz#fcb2b586cfd21dd5f3076de467f92b55d9c47cb2"
-  integrity sha512-bImj2qqIjnl+VHYGnIwan9LxmGvb8e4hFqHpxsPzUiK7Ady7uERrXPhJcyTKTxRf4RL2sQRDpoOKzBYNdQDmuw==
+expo-linear-gradient@~14.1.5:
+  version "14.1.5"
+  resolved "https://registry.yarnpkg.com/expo-linear-gradient/-/expo-linear-gradient-14.1.5.tgz#414bf0c8145089087198d4dd5a419eb324af2a02"
+  integrity sha512-BSN3MkSGLZoHMduEnAgfhoj3xqcDWaoICgIr4cIYEx1GcHfKMhzA/O4mpZJ/WC27BP1rnAqoKfbclk1eA70ndQ==
 
-expo-linking@~7.1.4:
-  version "7.1.4"
-  resolved "https://registry.yarnpkg.com/expo-linking/-/expo-linking-7.1.4.tgz#7d398d99788d8d95b67d1ae463d24686cbeb1c1b"
-  integrity sha512-zLAbUzTB3+KGjqqLeIdhhkXayyN0qulHGjRI24X7W/0Mq/4oPbPZklKtCP0k7XOn/k4553m8OgJ7GPC03PlV9g==
+expo-linking@~7.1.5:
+  version "7.1.5"
+  resolved "https://registry.yarnpkg.com/expo-linking/-/expo-linking-7.1.5.tgz#99633892712d5442ddb1c6c3857346eb7a67119b"
+  integrity sha512-8g20zOpROW78bF+bLI4a3ZWj4ntLgM0rCewKycPL0jk9WGvBrBtFtwwADJgOiV1EurNp3lcquerXGlWS+SOQyA==
   dependencies:
-    expo-constants "~17.1.4"
+    expo-constants "~17.1.6"
     invariant "^2.2.4"
 
 expo-localization@~16.1.5:
@@ -11322,23 +11366,23 @@ expo-localization@~16.1.5:
   dependencies:
     rtl-detect "^1.0.2"
 
-expo-manifests@~0.16.4:
-  version "0.16.4"
-  resolved "https://registry.yarnpkg.com/expo-manifests/-/expo-manifests-0.16.4.tgz#d1a648bab0068a2712cf49009a5f26377a585849"
-  integrity sha512-zB6ohgnsNbJDaLI/KRZQXxEHadhMJt+gA4LCqbiZQNa3P4FJq4JFRXPV6QQjgjJ998g9vY7eDCTduxTJYBqUaA==
+expo-manifests@~0.16.5:
+  version "0.16.5"
+  resolved "https://registry.yarnpkg.com/expo-manifests/-/expo-manifests-0.16.5.tgz#bb57ceff3db4eb74679d4a155b2ca2050375ce10"
+  integrity sha512-zLUeJogn2C7qOE75Zz7jcmJorMfIbSRR35ctspN0OK/Hq/+PAAptA8p9jNVC8xp/91uP9uI8f3xPhh+A11eR2A==
   dependencies:
-    "@expo/config" "~11.0.6"
+    "@expo/config" "~11.0.10"
     expo-json-utils "~0.15.0"
 
-expo-media-library@~17.1.6:
-  version "17.1.6"
-  resolved "https://registry.yarnpkg.com/expo-media-library/-/expo-media-library-17.1.6.tgz#118ada2d28139d540861b338acf1d088bc03d51f"
-  integrity sha512-Py8Y9wJlNXBZkhtJYy9acj0oRoUV09WXsZnjcvy6xZjpniPQIq0wkIkgS2DLhlYmMdjBrSux2TGp7Omi2WHp1g==
+expo-media-library@~17.1.7:
+  version "17.1.7"
+  resolved "https://registry.yarnpkg.com/expo-media-library/-/expo-media-library-17.1.7.tgz#71ed3d2d246d33410d6aecc335098a23519bd890"
+  integrity sha512-hLCoMvlhjtt+iYxPe71P1F6t06mYGysuNOfjQzDbbf64PCkglCZJYmywPyUSV1V5Hu9DhRj//gEg+Ki+7VWXog==
 
-expo-modules-autolinking@2.1.9:
-  version "2.1.9"
-  resolved "https://registry.yarnpkg.com/expo-modules-autolinking/-/expo-modules-autolinking-2.1.9.tgz#7bf8338d4b7a1b6e8eccab51634de9b339e90c04"
-  integrity sha512-54InfnWy1BR54IDZoawqdFAaF2lyLHe9J+2dZ7y91/36jVpBtAval39ZKt2IISFJZ7TVglsojl4P5BDcDGcvjQ==
+expo-modules-autolinking@2.1.11:
+  version "2.1.11"
+  resolved "https://registry.yarnpkg.com/expo-modules-autolinking/-/expo-modules-autolinking-2.1.11.tgz#efc2e756ccc8b9e0b927596ba074aefe31b5cbe4"
+  integrity sha512-KrWQo+cE4gWYNePBBhmHGVzf63gYV19ZLXe9EIH3GHTkViVzIX+Lp618H/7GxfawpN5kbhvilATH1QEKKnUUww==
   dependencies:
     "@expo/spawn-async" "^1.7.2"
     chalk "^4.1.0"
@@ -11348,10 +11392,10 @@ expo-modules-autolinking@2.1.9:
     require-from-string "^2.0.2"
     resolve-from "^5.0.0"
 
-expo-modules-core@2.3.12:
-  version "2.3.12"
-  resolved "https://registry.yarnpkg.com/expo-modules-core/-/expo-modules-core-2.3.12.tgz#1c06402564c02b32f192adfe6946e671d8a95e79"
-  integrity sha512-bOm83mskw1S7xuDX50DlLdx68u0doQ6BZHSU2qTv8P1/5QYeAae3pCgFLq2hoptUNeMF7W+68ShJFTOHAe68BQ==
+expo-modules-core@2.4.0:
+  version "2.4.0"
+  resolved "https://registry.yarnpkg.com/expo-modules-core/-/expo-modules-core-2.4.0.tgz#3081d62fadff913090cc5abfe46d9ec6b0e75789"
+  integrity sha512-Ko5eHBdvuMykjw9P9C9PF54/wBSsGOxaOjx92I5BwgKvEmUwN3UrXFV4CXzlLVbLfSYUQaLcB220xmPfgvT7Fg==
   dependencies:
     invariant "^2.2.4"
 
@@ -11362,10 +11406,10 @@ expo-modules-core@^2.1.1:
   dependencies:
     invariant "^2.2.4"
 
-expo-notifications@~0.31.1:
-  version "0.31.1"
-  resolved "https://registry.yarnpkg.com/expo-notifications/-/expo-notifications-0.31.1.tgz#3be669ab78c6099d82f4fc3607f77f7d9e1805b6"
-  integrity sha512-g1CMi+3wUaMuX+tAU+Fhnfs5bJtJ3JVRXihO415aOInQkox+Mh79n38RlT6snLWCHjfSojQIxmydzUHt6ywTIQ==
+expo-notifications@~0.31.3:
+  version "0.31.3"
+  resolved "https://registry.yarnpkg.com/expo-notifications/-/expo-notifications-0.31.3.tgz#eb82c9975e26dcc4fa694b79970792c897ad8d16"
+  integrity sha512-AATxKoav5ZvwcRel2SKYNZc+EvOAKvAjxyBezC8y3J5fMNe/uKIhMzh3FN4fKdOi9ao/UBHkvLiUO2MqVnvBNg==
   dependencies:
     "@expo/image-utils" "^0.7.4"
     "@ide/backoff" "^1.0.0"
@@ -11373,7 +11417,7 @@ expo-notifications@~0.31.1:
     assert "^2.0.0"
     badgin "^1.1.5"
     expo-application "~6.1.4"
-    expo-constants "~17.1.4"
+    expo-constants "~17.1.6"
 
 expo-pwa@0.0.127:
   version "0.0.127"
@@ -11385,34 +11429,34 @@ expo-pwa@0.0.127:
     commander "2.20.0"
     update-check "1.5.3"
 
-expo-screen-orientation@~8.1.5:
-  version "8.1.5"
-  resolved "https://registry.yarnpkg.com/expo-screen-orientation/-/expo-screen-orientation-8.1.5.tgz#447c19b8ad59d1d2cf0894900ee273836367ca0d"
-  integrity sha512-t2ss7a52f1VNrugmIYj1wlnGICUgrkqu2+J3Csew8ixczI8s6r6EXT4E4EeyQ/9WvcEUOOyh8TWC9EbbswPhUw==
+expo-screen-orientation@~8.1.7:
+  version "8.1.7"
+  resolved "https://registry.yarnpkg.com/expo-screen-orientation/-/expo-screen-orientation-8.1.7.tgz#3751b441f2bfcbde798b1508c0ff9f099f4be911"
+  integrity sha512-nYwadYtdU6mMDk0MCHMPPPQtBoeFYJ2FspLRW+J35CMLqzE4nbpwGeiImfXzkvD94fpOCfI4KgLj5vGauC3pfA==
 
 expo-sharing@~13.1.5:
   version "13.1.5"
   resolved "https://registry.yarnpkg.com/expo-sharing/-/expo-sharing-13.1.5.tgz#73d86cdcc037b46ddc82be224dfd3d6bceec497c"
   integrity sha512-X/5sAEiWXL2kdoGE3NO5KmbfcmaCWuWVZXHu8OQef7Yig4ZgHFkGD11HKJ5KqDrDg+SRZe4ISd6MxE7vGUgm4w==
 
-expo-splash-screen@~0.30.8:
-  version "0.30.8"
-  resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.30.8.tgz#2e960ccff053bc8ace85eb56f7d6745e4ddfc6b6"
-  integrity sha512-2eh+uA543brfeG5HILXmtNKA7E2/pfywKzNumzy3Ef6OtDjYy6zJUGNSbhnZRbVEjUZo3/QNRs0JRBfY80okZg==
+expo-splash-screen@~0.30.9:
+  version "0.30.9"
+  resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.30.9.tgz#8f2a86b3b802ea46065fc761ed60e77e81bdb84c"
+  integrity sha512-curHUaZxUTZ2dWvz32ao3xPv5mJr1LBqn5V8xm/IULAehB9RGCn8iKiROMN1PYebSG+56vPMuJmBm9P+ayvJpA==
   dependencies:
-    "@expo/prebuild-config" "^9.0.5"
+    "@expo/prebuild-config" "^9.0.6"
 
 expo-structured-headers@~4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/expo-structured-headers/-/expo-structured-headers-4.1.0.tgz#5475fc3f9559701cc755fd2d50605f8817d42ad0"
   integrity sha512-2X+aUNzC/qaw7/WyUhrVHNDB0uQ5rE12XA2H/rJXaAiYQSuOeU90ladaN0IJYV9I2XlhYrjXLktLXWbO7zgbag==
 
-expo-system-ui@~5.0.7:
-  version "5.0.7"
-  resolved "https://registry.yarnpkg.com/expo-system-ui/-/expo-system-ui-5.0.7.tgz#ccf047a689ab488d9bcda375afd063419578f494"
-  integrity sha512-ijSnSFA4VfuQc84N6WyCUNsKKTIyQb6QuC8q2zGvYC/sBXTMrOtZg0zrisQGzCRW+WhritQTiVqHlp3Ix9xDmQ==
+expo-system-ui@~5.0.8:
+  version "5.0.8"
+  resolved "https://registry.yarnpkg.com/expo-system-ui/-/expo-system-ui-5.0.8.tgz#1eaaa95cfa8b5e20750e5fb30918635a58276199"
+  integrity sha512-2sI7ALq3W8sKKa3FRW7PmuNznk+48cb1VzFy96vYZLZgTDZViz+fEJNdp1RHgLui/mAl3f8md1LneygSJvZ1EQ==
   dependencies:
-    "@react-native/normalize-colors" "0.79.2"
+    "@react-native/normalize-colors" "0.79.3"
     debug "^4.3.2"
 
 expo-task-manager@~13.1.5:
@@ -11427,55 +11471,55 @@ expo-updates-interface@~1.1.0:
   resolved "https://registry.yarnpkg.com/expo-updates-interface/-/expo-updates-interface-1.1.0.tgz#62497d4647b381da9fdb68868ed180203ae737ef"
   integrity sha512-DeB+fRe0hUDPZhpJ4X4bFMAItatFBUPjw/TVSbJsaf3Exeami+2qbbJhWkcTMoYHOB73nOIcaYcWXYJnCJXO0w==
 
-expo-updates@~0.28.12:
-  version "0.28.12"
-  resolved "https://registry.yarnpkg.com/expo-updates/-/expo-updates-0.28.12.tgz#abf6e0c593837b20af64feee31aa018e1a85b332"
-  integrity sha512-GUQNI7apaQa8mVLGyeUQZsSaY75lq3yIp2OO+gX0BZIeD5hr8ADZ0Gw2+9+uRSB70B7AWQklUCMBxvOsA2DVfg==
+expo-updates@~0.28.14:
+  version "0.28.14"
+  resolved "https://registry.yarnpkg.com/expo-updates/-/expo-updates-0.28.14.tgz#bc75b00c0744fec33ba36f8c96e7c86ed0d3c7f6"
+  integrity sha512-kxI428W7LGSdDWmN/ud5cIg8+SjmQ5XSaUrYauZ0DKsHm2qq1Lh+NYSUWLvYmps+Baalafe6mILmAX8ZnNg26Q==
   dependencies:
     "@expo/code-signing-certificates" "0.0.5"
-    "@expo/config" "~11.0.7"
+    "@expo/config" "~11.0.10"
     "@expo/config-plugins" "~10.0.2"
     "@expo/spawn-async" "^1.7.2"
     arg "4.1.0"
     chalk "^4.1.2"
     expo-eas-client "~0.14.3"
-    expo-manifests "~0.16.4"
+    expo-manifests "~0.16.5"
     expo-structured-headers "~4.1.0"
     expo-updates-interface "~1.1.0"
     glob "^10.4.2"
     ignore "^5.3.1"
     resolve-from "^5.0.0"
 
-expo-video@~2.1.8:
-  version "2.1.8"
-  resolved "https://registry.yarnpkg.com/expo-video/-/expo-video-2.1.8.tgz#507305ae2ea18f435a51ababd6b2dec21291d328"
-  integrity sha512-OEToLVEGLvfTq7ypjgOf1DUNGHLGxUiL/1K6WHwdew5tgFxiLBZesGQhKToyrSVPVmWaxMBSP4sQuwtTjWUpHg==
+expo-video@~2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/expo-video/-/expo-video-2.2.1.tgz#d45357ee7a7da5a87c49177587183d1c7feabc57"
+  integrity sha512-dw3h0eMLK8WpY1Tnwsgrxx3sFqXiOujmurjGdr+RFG63ZurAze/H9uuKMVl3ps/ZNuK4q/2ifIiJudoFJfwKwA==
 
 expo-web-browser@~14.1.6:
   version "14.1.6"
   resolved "https://registry.yarnpkg.com/expo-web-browser/-/expo-web-browser-14.1.6.tgz#26d66e641e6e96d155be6fa513e7e667a719a0b0"
   integrity sha512-/4P8eWqRyfXIMZna3acg320LXNA+P2cwyEVbjDX8vHnWU+UnOtyRKWy3XaAIyMPQ9hVjBNUQTh4MPvtnPRzakw==
 
-expo@^53.0.5:
-  version "53.0.5"
-  resolved "https://registry.yarnpkg.com/expo/-/expo-53.0.5.tgz#f8c30643c4e45d769934415ea9196531612cb657"
-  integrity sha512-A9nh7ojGcdsv05TCH39q/7RRQsTfgcQ3qD2CFzlADVW8jIIFNiIg80shE8DQiXHkeCKWT78Iy7iog2yIu4sq3Q==
+expo@53.0.11:
+  version "53.0.11"
+  resolved "https://registry.yarnpkg.com/expo/-/expo-53.0.11.tgz#66053862520ce2a6700d13346ebaf8210a68f24b"
+  integrity sha512-+QtvU+6VPd7/o4vmtwuRE/Li2rAiJtD25I6BOnoQSxphaWWaD0PdRQnIV3VQ0HESuJYRuKJ3DkAHNJ3jI6xwzA==
   dependencies:
     "@babel/runtime" "^7.20.0"
-    "@expo/cli" "0.24.10"
-    "@expo/config" "~11.0.7"
+    "@expo/cli" "0.24.14"
+    "@expo/config" "~11.0.10"
     "@expo/config-plugins" "~10.0.2"
-    "@expo/fingerprint" "0.12.4"
-    "@expo/metro-config" "0.20.12"
+    "@expo/fingerprint" "0.13.0"
+    "@expo/metro-config" "0.20.14"
     "@expo/vector-icons" "^14.0.0"
-    babel-preset-expo "~13.1.11"
-    expo-asset "~11.1.4"
-    expo-constants "~17.1.5"
-    expo-file-system "~18.1.8"
-    expo-font "~13.3.0"
+    babel-preset-expo "~13.2.0"
+    expo-asset "~11.1.5"
+    expo-constants "~17.1.6"
+    expo-file-system "~18.1.10"
+    expo-font "~13.3.1"
     expo-keep-awake "~14.1.4"
-    expo-modules-autolinking "2.1.9"
-    expo-modules-core "2.3.12"
+    expo-modules-autolinking "2.1.11"
+    expo-modules-core "2.4.0"
     react-native-edge-to-edge "1.6.0"
     whatwg-url-without-unicode "8.0.0-3"
 
@@ -12055,6 +12099,11 @@ getenv@^1.0.0:
   resolved "https://registry.yarnpkg.com/getenv/-/getenv-1.0.0.tgz#874f2e7544fbca53c7a4738f37de8605c3fcfc31"
   integrity sha512-7yetJWqbS9sbn0vIfliPsFgoXMKn/YMF+Wuiog97x+urnSRRRZ7xB+uVkwGKzRgq9CDFfMQnE9ruL5DHv9c6Xg==
 
+getenv@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/getenv/-/getenv-2.0.0.tgz#b1698c7b0f29588f4577d06c42c73a5b475c69e0"
+  integrity sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==
+
 github-from-package@0.0.0:
   version "0.0.0"
   resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
@@ -12079,18 +12128,6 @@ glob-to-regexp@^0.4.1:
   resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
   integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
 
-glob@7.0.6:
-  version "7.0.6"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a"
-  integrity sha512-f8c0rE8JiCxpa52kWPAOa3ZaYEnzofDzCQLCn3Vdk0Z5OVLq3BsRFJI4S4ykpeVW6QMGBUkMeUpoEgWnMTnw5Q==
-  dependencies:
-    fs.realpath "^1.0.0"
-    inflight "^1.0.4"
-    inherits "2"
-    minimatch "^3.0.2"
-    once "^1.3.0"
-    path-is-absolute "^1.0.0"
-
 glob@^10.3.10:
   version "10.3.12"
   resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.12.tgz#3a65c363c2e9998d220338e88a5f6ac97302960b"
@@ -13469,12 +13506,12 @@ jest-environment-node@^29.7.0:
     jest-mock "^29.7.0"
     jest-util "^29.7.0"
 
-jest-expo@~53.0.3:
-  version "53.0.3"
-  resolved "https://registry.yarnpkg.com/jest-expo/-/jest-expo-53.0.3.tgz#094da673d5b7953565c4cc6c41af4337465ddfc9"
-  integrity sha512-aOJyy/i0wPAWrQpSVNTTFWjcNTbUE/0eXr2cpdM3WW57K3EB1sueuKj8j2tWlzeKz4bk3+DVRy8K44V/XMoy3Q==
+jest-expo@~53.0.7:
+  version "53.0.7"
+  resolved "https://registry.yarnpkg.com/jest-expo/-/jest-expo-53.0.7.tgz#ab1c288940dcdf470c25b7b18e2ed99f03d26bc6"
+  integrity sha512-Uiu3ES0sWbsxpifQuBzXMI1/N9JygfJfwEby/Qw/OPndIQ1YeeIQqkbP52xn6UhdSM4qYQiteX3EjY8TfrZIoA==
   dependencies:
-    "@expo/config" "~11.0.7"
+    "@expo/config" "~11.0.10"
     "@expo/json-file" "^9.1.4"
     "@jest/create-cache-key-function" "^29.2.1"
     "@jest/globals" "^29.2.1"
@@ -14061,10 +14098,10 @@ kysely@^0.23.4:
   resolved "https://registry.yarnpkg.com/kysely/-/kysely-0.23.5.tgz#60c63d94e1c42cc0411be8aaa688a0f27405f514"
   integrity sha512-TH+b56pVXQq0tsyooYLeNfV11j6ih7D50dyN8tkM0e7ndiUH28Nziojiog3qRFlmEj9XePYdZUrNJ2079Qjdow==
 
-lan-network@^0.1.4:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/lan-network/-/lan-network-0.1.5.tgz#e781889b7bd4dbedd9126fff3ceddd809a83c3ff"
-  integrity sha512-CV3k7l8jW0Z1b+G41tB7JInVyJEKQzh/YPl2v9uXpZMusp0aa+rh3OqG77xWuX7+eVBa8PsdTuMznTAssF4qwg==
+lan-network@^0.1.6:
+  version "0.1.7"
+  resolved "https://registry.yarnpkg.com/lan-network/-/lan-network-0.1.7.tgz#9fcb9967c6d951f10b2f9a9ffabe4a312d63f69d"
+  integrity sha512-mnIlAEMu4OyEvUNdzco9xpuB9YVcPkQec+QsgycBCtPZvEqWPCDPfbAE4OJMdBBWpZWtpCn1xw9jJYlwjWI5zQ==
 
 lande@^1.0.10:
   version "1.0.10"
@@ -14846,7 +14883,7 @@ minimalistic-crypto-utils@^1.0.1:
   resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
   integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
 
-minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
+minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
   integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
@@ -15097,6 +15134,11 @@ node-releases@^2.0.18:
   resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f"
   integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==
 
+node-releases@^2.0.19:
+  version "2.0.19"
+  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314"
+  integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
+
 nodemailer-html-to-text@^3.2.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/nodemailer-html-to-text/-/nodemailer-html-to-text-3.2.0.tgz#91b959491fef8f7d91796047abb728aa86d4a12b"
@@ -15755,7 +15797,7 @@ picocolors@^1.0.1:
   resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1"
   integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==
 
-picocolors@^1.1.0:
+picocolors@^1.1.0, picocolors@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
   integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
@@ -16770,7 +16812,7 @@ react-keyed-flatten-children@^5.0.0:
   resolved "https://registry.yarnpkg.com/react-keyed-flatten-children/-/react-keyed-flatten-children-5.0.0.tgz#3024fc8819f7b60fc5039b527f133d9ac3a02a82"
   integrity sha512-XA5ah02sZAeDrbz4Lusd4acqG5q5BtVwPHWierruVhrgX6CMCldbGcTZZM14cQZ+GWq+tzRzEpsCvnTtLODvjw==
 
-react-native-compressor@1.11.0:
+react-native-compressor@^1.11.0:
   version "1.11.0"
   resolved "https://registry.yarnpkg.com/react-native-compressor/-/react-native-compressor-1.11.0.tgz#e297fa650b09cc754392153c38ae2ca510aee024"
   integrity sha512-XaI0U2CtlW6ZYjwdQ4jdpnJa3C9CD1pc1a4jiUMtnUxWtCqgT7PNjOiEqlYLLwwGTvorXXNuby5In1yy7Vdmhg==
@@ -16787,20 +16829,13 @@ react-native-dotenv@^3.4.11:
   dependencies:
     dotenv "^16.4.5"
 
-react-native-drawer-layout@^4.1.10:
+react-native-drawer-layout@^4.1.10, react-native-drawer-layout@^4.1.8:
   version "4.1.10"
   resolved "https://registry.yarnpkg.com/react-native-drawer-layout/-/react-native-drawer-layout-4.1.10.tgz#9007cb747767ca8e1c9c3337671ad35ed95ad4d9"
   integrity sha512-wejQo0F+EffCkOkRh+DP6ENWMB+aWEHkXV8Pd564PmtoySZLUsV/ksYrh/mrufh7T7EuvGT8+fNHz7mMRYftWg==
   dependencies:
     use-latest-callback "^0.2.3"
 
-react-native-drawer-layout@^4.1.6:
-  version "4.1.7"
-  resolved "https://registry.yarnpkg.com/react-native-drawer-layout/-/react-native-drawer-layout-4.1.7.tgz#1c741c9bf9c739d6672201692e4ba4839ca0c8ff"
-  integrity sha512-KeTGZsNEDbOmgo8ICwr1vBmvWjRrRsvbLc2IAfQnW5h5UtxVZVRxY4QaN84BSBQPXm6tQ6AXfII8TCXCv3c0Ew==
-  dependencies:
-    use-latest-callback "^0.2.3"
-
 react-native-edge-to-edge@1.6.0, react-native-edge-to-edge@^1.6.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/react-native-edge-to-edge/-/react-native-edge-to-edge-1.6.0.tgz#2ba63b941704a7f713e298185c26cde4d9e4b973"
@@ -16858,10 +16893,10 @@ react-native-mmkv@^2.12.2:
   resolved "https://registry.yarnpkg.com/react-native-mmkv/-/react-native-mmkv-2.12.2.tgz#4bba0f5f04e2cf222494cce3a9794ba6a4894dee"
   integrity sha512-6058Aq0p57chPrUutLGe9fYoiDVDNMU2PKV+lLFUJ3GhoHvUrLdsS1PDSCLr00yqzL4WJQ7TTzH+V8cpyrNcfg==
 
-react-native-pager-view@6.7.1:
-  version "6.7.1"
-  resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.7.1.tgz#60d52dedbcc92ee7037a13287ebeed5f74e49df7"
-  integrity sha512-cBSr6xw4g5N7Kd3VGWcf+kmaH7iBWb0DXAf2bVo3bXkzBcBbTOmYSvc0LVLHhUPW8nEq5WjT9LCIYAzgF++EXw==
+react-native-pager-view@^6.7.1:
+  version "6.8.1"
+  resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.8.1.tgz#fa0ec09ea7c44190c7c013d75dd09fdc17b96100"
+  integrity sha512-XIyVEMhwq7sZqM7GobOJZXxFCfdFgVNq/CFB2rZIRNRSVPJqE1k1fsc8xfQKfdzsp6Rpt6I7VOIvhmP7/YHdVg==
 
 react-native-progress@bluesky-social/react-native-progress:
   version "5.0.0"
@@ -16895,10 +16930,10 @@ react-native-reanimated@~3.17.5:
     invariant "^2.2.4"
     react-native-is-edge-to-edge "1.1.7"
 
-react-native-root-siblings@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/react-native-root-siblings/-/react-native-root-siblings-4.1.1.tgz#b7742db7634a87f507eb99a5fd699c4f10c46ab0"
-  integrity sha512-sdmLElNs5PDWqmZmj4/aNH4anyxreaPm61c4ZkRiR8SO/GzLg6KjAbb0e17RmMdnBdD0AIQbS38h/l55YKN4ZA==
+react-native-root-siblings@^5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/react-native-root-siblings/-/react-native-root-siblings-5.0.1.tgz#97e050e5155228f65810fb1c466ff8e769c5272c"
+  integrity sha512-Ay3k/fBj6ReUkWX5WNS+oEAcgPLEGOK8n7K/L7D85mf3xvd8rm/b4spsv26E4HlFzluVx5HKbxEt9cl0wQ1u3g==
 
 react-native-safe-area-context@5.4.0:
   version "5.4.0"
@@ -16914,10 +16949,10 @@ react-native-screens@^4.11.1:
     react-native-is-edge-to-edge "^1.1.7"
     warn-once "^0.1.0"
 
-react-native-svg@15.11.2:
-  version "15.11.2"
-  resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.11.2.tgz#7540e8e1eabc4dcd3b1e35ada5a1d9f1b96d37c4"
-  integrity sha512-+YfF72IbWQUKzCIydlijV1fLuBsQNGMT6Da2kFlo1sh+LE3BIm/2Q7AR1zAAR6L0BFLi1WaQPLfFUC9bNZpOmw==
+react-native-svg@15.12.0:
+  version "15.12.0"
+  resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.12.0.tgz#0e2d476961e8b07f8c549fe4489c99b5130dc150"
+  integrity sha512-iE25PxIJ6V0C6krReLquVw6R0QTsRTmEQc4K2Co3P6zsimU/jltcDBKYDy1h/5j9S/fqmMeXnpM+9LEWKJKI6A==
   dependencies:
     css-select "^5.1.0"
     css-tree "^1.1.3"
@@ -16968,27 +17003,27 @@ react-native-web@~0.20.0:
     postcss-value-parser "^4.2.0"
     styleq "^0.1.3"
 
-react-native-webview@13.13.5:
-  version "13.13.5"
-  resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-13.13.5.tgz#4ef5f9310ddff5747f884a6655228ec9c7d52c73"
-  integrity sha512-MfC2B+woL4Hlj2WCzcb1USySKk+SteXnUKmKktOk/H/AQy5+LuVdkPKm8SknJ0/RxaxhZ48WBoTRGaqgR137hw==
+react-native-webview@^13.13.5:
+  version "13.15.0"
+  resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-13.15.0.tgz#b6d2f8d8dd65897db76659ddd8198d2c74ec5a79"
+  integrity sha512-Vzjgy8mmxa/JO6l5KZrsTC7YemSdq+qB01diA0FqjUTaWGAGwuykpJ73MDj3+mzBSlaDxAEugHzTtkUQkQEQeQ==
   dependencies:
     escape-string-regexp "^4.0.0"
     invariant "2.2.4"
 
-react-native@0.79.2:
-  version "0.79.2"
-  resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.79.2.tgz#f1a53099701c1736d09e441eb79f97cfc90dd202"
-  integrity sha512-AnGzb56JvU5YCL7cAwg10+ewDquzvmgrMddiBM0GAWLwQM/6DJfGd2ZKrMuKKehHerpDDZgG+EY64gk3x3dEkw==
+react-native@^0.79.3:
+  version "0.79.3"
+  resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.79.3.tgz#16580ca202016c75e3c61116fcfe3b30f6d762fc"
+  integrity sha512-EzH1+9gzdyEo9zdP6u7Sh3Jtf5EOMwzy+TK65JysdlgAzfEVfq4mNeXcAZ6SmD+CW6M7ARJbvXLyTD0l2S5rpg==
   dependencies:
     "@jest/create-cache-key-function" "^29.7.0"
-    "@react-native/assets-registry" "0.79.2"
-    "@react-native/codegen" "0.79.2"
-    "@react-native/community-cli-plugin" "0.79.2"
-    "@react-native/gradle-plugin" "0.79.2"
-    "@react-native/js-polyfills" "0.79.2"
-    "@react-native/normalize-colors" "0.79.2"
-    "@react-native/virtualized-lists" "0.79.2"
+    "@react-native/assets-registry" "0.79.3"
+    "@react-native/codegen" "0.79.3"
+    "@react-native/community-cli-plugin" "0.79.3"
+    "@react-native/gradle-plugin" "0.79.3"
+    "@react-native/js-polyfills" "0.79.3"
+    "@react-native/normalize-colors" "0.79.3"
+    "@react-native/virtualized-lists" "0.79.3"
     abort-controller "^3.0.0"
     anser "^1.4.9"
     ansi-regex "^5.0.0"
@@ -17541,14 +17576,6 @@ rimraf@^3.0.2:
   dependencies:
     glob "^7.1.3"
 
-rn-fetch-blob@^0.12.0:
-  version "0.12.0"
-  resolved "https://registry.yarnpkg.com/rn-fetch-blob/-/rn-fetch-blob-0.12.0.tgz#ec610d2f9b3f1065556b58ab9c106eeb256f3cba"
-  integrity sha512-+QnR7AsJ14zqpVVUbzbtAjq0iI8c9tCg49tIoKO2ezjzRunN7YL6zFSFSWZm6d+mE/l9r+OeDM3jmb2tBb2WbA==
-  dependencies:
-    base-64 "0.1.0"
-    glob "7.0.6"
-
 roarr@^7.0.4:
   version "7.15.1"
   resolved "https://registry.yarnpkg.com/roarr/-/roarr-7.15.1.tgz#e4d93105c37b5ea7dd1200d96a3500f757ddc39f"
@@ -17736,12 +17763,10 @@ semver-compare@^1.0.0:
   resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
   integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==
 
-semver@7.6.0:
-  version "7.6.0"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d"
-  integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==
-  dependencies:
-    lru-cache "^6.0.0"
+semver@7.6.3, semver@^7.1.3, semver@^7.6.3:
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
+  integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
 
 semver@^5.5.0, semver@^5.6.0:
   version "5.7.2"
@@ -17753,11 +17778,6 @@ semver@^6.0.0, semver@^6.3.0, 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, semver@^7.6.3:
-  version "7.6.3"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
-  integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
-
 semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@~7.5.4:
   version "7.5.4"
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
@@ -19372,6 +19392,14 @@ update-browserslist-db@^1.1.1:
     escalade "^3.2.0"
     picocolors "^1.1.0"
 
+update-browserslist-db@^1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420"
+  integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==
+  dependencies:
+    escalade "^3.2.0"
+    picocolors "^1.1.1"
+
 update-check@1.5.3:
   version "1.5.3"
   resolved "https://registry.yarnpkg.com/update-check/-/update-check-1.5.3.tgz#45240fcfb8755a7c7fa68bbdd9eda026a41639ed"