Compare commits

18 Commits

Author SHA1 Message Date
2c7928daaa fix issues in android studio, like new file to file 2025-03-31 06:18:05 -07:00
ac9df75e84 start to incorporate whisper-native 2025-03-30 07:06:33 -07:00
0ba5c4b309 encountered weird network error. 2025-03-17 06:56:05 -07:00
e61fb43ee3 give up on downloader idea. Use file from assets. 2025-03-16 07:45:59 -07:00
123933d459 attempt to use part/copy idea. 2025-03-14 06:54:06 -07:00
f0a722b3fb add expo-audio. work on memory issue when reading file. 2025-03-11 18:35:37 -07:00
dca3987e18 work on downloading some more. 2025-03-11 07:26:49 -07:00
8f67d0421b did more of the knex -> sqlite migration. 2025-03-10 10:32:27 -07:00
3616592896 bring back sqlite3 and migrations. 2025-03-09 20:16:54 -07:00
e9c04a7b39 add straight lang-flags. Try to resolve expo dialect error. 2025-03-09 19:39:49 -07:00
918d651638 add knex-expo-sqlite-dialect submodule. migrate to expo (possibly a mistake) 2025-03-09 06:57:41 -07:00
5352ae8eb1 add more mocking 2025-03-04 07:20:00 -08:00
61e54ded3c start mock of file bytes. 2025-03-03 17:28:35 -08:00
75b76efd33 add jest mocking for settings. 2025-03-03 06:52:57 -08:00
1492a38e0b resolve merge. 2025-03-03 05:47:11 -08:00
d15916f3e3 resolve merge 2025-03-03 05:46:00 -08:00
a9b5ccf84f updating code using knex. 2025-03-02 20:15:27 -08:00
d00e6d62ff add readme. fix downloader operation. 2025-02-28 14:38:36 -08:00
47 changed files with 3408 additions and 1475 deletions

1
.gitignore vendored
View File

@ -36,3 +36,4 @@ yarn-error.*
*.tsbuildinfo *.tsbuildinfo
coverage/**/* coverage/**/*
assets/whisper

6
.gitmodules vendored
View File

@ -1,3 +1,9 @@
[submodule "langs-flags-list"] [submodule "langs-flags-list"]
path = langs-flags-list path = langs-flags-list
url = https://github.com/martinsik/langs-flags-list.git url = https://github.com/martinsik/langs-flags-list.git
[submodule "knex-expo-sqlite-dialect"]
path = knex-expo-sqlite-dialect
url = https://github.com/expo/knex-expo-sqlite-dialect.git
[submodule "whisper_android"]
path = whisper_android
url = https://github.com/vilassn/whisper_android.git

View File

@ -1,2 +1,3 @@
{ {
"java.compile.nullAnalysis.mode": "disabled"
} }

226
README.md
View File

@ -1,195 +1,81 @@
# react-native-linear-gradient # Translation Terrace
A `<LinearGradient>` element for React Native Translation Terrace is an Expo/React-Native application designed for a translation kiosk. It leverages an offline Whisper speech-to-text model and interfaces with a LibreTranslate server to provide seamless translation services.
[![ci][1]][2] ## Project Structure
[![npm version][3]][4]
[![npm downloads][5]][4]
<p align="center"> ```
<img src="https://github.com/react-native-linear-gradient/react-native-linear-gradient/assets/743291/8ff2a78b-f0b1-463a-aa5b-555df2e71360" width="300"> <img src="https://github.com/react-native-linear-gradient/react-native-linear-gradient/assets/743291/9c738be3-6fba-43d5-9c9f-1db1c10fd377" width="300"> translation-terraces/
</p> ├── expo-file-system/
│ └── next.js
## Table of Contents ├── @react-native-async-storage/
│ └── async-storage.ts
- [Installation](#installation) ├── .ollama/
- [Usage and Examples](#examples) │ ├── ExampleComponent.tsx
- [Props](#props) │ └── ExampleTest.spec.tsx
- [Example App](#an-example-app) ├── package.json
- [Troubleshooting](#troubleshooting) ├── README.md
- [Other Platforms](#other-platforms) └── ...
## Installation
```sh
yarn add react-native-linear-gradient
``` ```
Or, using npm: `npm install react-native-linear-gradient` ## Technologies Used
## Examples - **React-Native**: Core framework for building the application.
- **Whisper Speech-to-Text Model**: Offline model for converting spoken language to text.
- **LibreTranslate Server**: Interface for translation services.
[react-native-login](https://github.com/brentvatne/react-native-login) is a ## Installation Instructions
legacy component which showcases the use of `<LinearGradient>`.
### Simple 1. **Install Packages**: Run `npm install` to install all necessary dependencies as listed in `package.json`.
2. **Prebuild Android**: Since this project cannot be run using Expo Go, prebuild the Android app by running `npm run android`.
3. **Run Unit Tests**: Execute Jest unit tests with `npm run test`.
The following code will produce something like this: ## Usage Examples
![Example code result](https://raw.githubusercontent.com/react-native-community/react-native-linear-gradient/HEAD/images/example.png) ### Example 1: Initializing Whisper Model
```javascript ```javascript
import LinearGradient from 'react-native-linear-gradient'; import { initializeWhisper } from './path/to/whisper';
// Within your render function const initModel = async () => {
<LinearGradient colors={['#4c669f', '#3b5998', '#192f6a']} style={styles.linearGradient}> try {
<Text style={styles.buttonText}> await initializeWhisper();
Sign in with Facebook console.log('Whisper model initialized successfully.');
</Text> } catch (error) {
</LinearGradient> console.error('Error initializing Whisper model:', error);
}
};
// Later on in your styles.. initModel();
var styles = StyleSheet.create({
linearGradient: {
flex: 1,
paddingLeft: 15,
paddingRight: 15,
borderRadius: 5
},
buttonText: {
fontSize: 18,
fontFamily: 'Gill Sans',
textAlign: 'center',
margin: 10,
color: '#ffffff',
backgroundColor: 'transparent',
},
});
``` ```
### Horizontal gradient ### Example 2: Translating Text
Using the styles from above, set `start` and `end` like this to make the gradient go from left to right, instead of from top to bottom:
```javascript ```javascript
<LinearGradient start={{x: 0, y: 0}} end={{x: 1, y: 0}} colors={['#4c669f', '#3b5998', '#192f6a']} style={styles.linearGradient}> import { translateText } from './path/to/libreTranslate';
<Text style={styles.buttonText}>
Sign in with Facebook const translate = async () => {
</Text> try {
</LinearGradient> const translatedText = await translateText('Hello, world!', 'en', 'es');
console.log('Translated text:', translatedText);
} catch (error) {
console.error('Error translating text:', error);
}
};
translate();
``` ```
### Text gradient (iOS) ## Contributing Guidelines
On iOS you can use the `MaskedViewIOS` to display text with a gradient. The trick here is to render the text twice; once for the mask, and once to let the gradient have the correct size (hence the `opacity: 0`): 1. **Create Feature Branch**: Use the naming convention `<year>-<work week>_<username>_<feature_description>` for your feature branch.
2. **Initiate Pull Request (PR)**: Open a PR and provide a detailed description of the changes made.
3. **Discuss Features**: Suggest new features or improvements in GitTea issues.
```jsx ## License Information
<MaskedViewIOS maskElement={<Text style={styles.text} />}>
<LinearGradient colors={['#f00', '#0f0']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }}>
<Text style={[styles.text, { opacity: 0 }]} />
</LinearGradient>
</MaskedViewIOS>
```
### Animated Gradient This project is licensed under the MIT License. For more details, please refer to the [LICENSE](LICENSE) file.
Check out the [example app](https://github.com/react-native-linear-gradient/react-native-linear-gradient/tree/HEAD/example/) (`git clone` this project, cd into it, npm install, open in Xcode and run) to see how this is done: ---
![Example with extra props](https://raw.githubusercontent.com/react-native-community/react-native-linear-gradient/HEAD/images/example-animated.gif) Feel free to explore the codebase and contribute to Translation Terrace! If you have any questions or need further assistance, feel free to reach out.
*This gif was created using [licecap](http://www.cockos.com/licecap/) - a great piece of free OSS*
### Transparent Gradient
The use of `transparent` color will most likely not lead to the expected result. `transparent` is actually a transparent black color (`rgba(0, 0, 0, 0)`). If you need a gradient in which the color is "fading", you need to have the same color with changing alpha channel. Example:
```jsx
// RGBA
<LinearGradient colors={['rgba(255, 255, 255, 0)', 'rgba(255, 255, 255, 1)']} {...otherGradientProps} />
// Hex
<LinearGradient colors={['#FFFFFF00', '#FFFFFF']} {...otherGradientProps} />
```
## Props
In addition to regular `View` props, you can also provide additional props to customize your gradient look:
#### colors
An array of at least two color values that represent gradient colors. Example: `['red', 'blue']` sets gradient from red to blue.
#### start
An optional object of the following type: `{ x: number, y: number }`. Coordinates declare the position that the gradient starts at, as a fraction of the overall size of the gradient, starting from the top left corner. Example: `{ x: 0.1, y: 0.1 }` means that the gradient will start 10% from the top and 10% from the left.
#### end
Same as start, but for the end of the gradient.
#### locations
An optional array of numbers defining the location of each gradient color stop, mapping to the color with the same index in `colors` prop. Example: `[0.1, 0.75, 1]` means that first color will take 0% - 10%, second color will take 10% - 75% and finally third color will occupy 75% - 100%.
```javascript
<LinearGradient
start={{x: 0.0, y: 0.25}} end={{x: 0.5, y: 1.0}}
locations={[0,0.5,0.6]}
colors={['#4c669f', '#3b5998', '#192f6a']}
style={styles.linearGradient}>
<Text style={styles.buttonText}>
Sign in with Facebook
</Text>
</LinearGradient>
```
![Example with extra props](https://raw.githubusercontent.com/react-native-community/react-native-linear-gradient/HEAD/images/example-other-props.png)
#### useAngle / angle / angleCenter
You may want to achieve an angled gradient effect, similar to those in image editors like Photoshop.
One issue is that you have to calculate the angle based on the view's size, which only happens asynchronously and will cause unwanted flickr.
In order to do that correctly you can set `useAngle={true} angle={45} angleCenter={{x:0.5,y:0.5}}`, to achieve a gradient with a 45 degrees angle, with its center positioned in the view's exact center.
`useAngle` is used to turn on/off angle based calculation (as opposed to `start`/`end`).
`angle` is the angle in degrees.
`angleCenter` is the center point of the angle (will control the weight and stretch of the gradient like it does in photoshop.
## An example app
You can see this component in action in [brentvatne/react-native-login](https://github.com/brentvatne/react-native-login/blob/HEAD/App/Screens/LoginScreen.js#L58-L62).
## Troubleshooting
### iOS build fails: library not found, "BVLinearGradient" was not found in the UIManager
1. Ensure to run `pod install` before running the app on iOS
2. Ensure you use `ios/**.xcworkspace` file instead of `ios./**.xcodeproj`
### Other
Clearing build caches and reinstalling dependencies sometimes solve some issues. Try next steps:
1. Reinstalling `node_modules` with `rm -rf node_modules && yarn`
2. Clearing Android Gradle cache with `(cd android && ./gradlew clean)`
3. Reinstalling iOS CocoaPods with `(cd ios && rm -rf ./ios/Pods/**) && npx pod-install`
4. Clearing Xcode Build cache (open Xcode and go to Product -> Clean Build Folder)
For other troubleshooting issues, go to [React Native Troubleshooting](https://reactnative.dev/docs/troubleshooting.html)
## Other platforms
- Web: [react-native-web-community/react-native-web-linear-gradient](https://github.com/react-native-web-community/react-native-web-linear-gradient)
## License
MIT
[1]: https://github.com/react-native-linear-gradient/react-native-linear-gradient/workflows/ci/badge.svg
[2]: https://github.com/react-native-linear-gradient/react-native-linear-gradient/actions
[3]: https://img.shields.io/npm/v/react-native-linear-gradient.svg
[4]: https://www.npmjs.com/package/react-native-linear-gradient
[5]: https://img.shields.io/npm/dm/react-native-linear-gradient.svg

View File

@ -1,7 +1,8 @@
export default { export default {
getDb: jest.fn(() => { getDb: jest.fn(() => {
return { return {
runAsync: jest.fn((statement: string, value: string) => {}), runAsync: jest.fn((statement: string, ... values: string []) => {}),
runSync: jest.fn((statement: string, ... values : string []) => {}),
getFirstAsync: jest.fn((statement: string, value: string) => { getFirstAsync: jest.fn((statement: string, value: string) => {
return []; return [];
}), }),

View File

@ -21,11 +21,14 @@ react {
/* Folders */ /* Folders */
// The root of your project, i.e. where "package.json" lives. Default is '../..' // The root of your project, i.e. where "package.json" lives. Default is '../..'
// root = file("../../") root = file("../../")
// The folder where the react-native NPM package is. Default is ../../node_modules/react-native // The folder where the react-native NPM package is. Default is ../../node_modules/react-native
// reactNativeDir = file("../../node_modules/react-native") // reactNativeDir = file("../../node_modules/react-native")
// The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen // The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen
// codegenDir = file("../../node_modules/@react-native/codegen") // codegenDir = file("../../node_modules/@react-native/codegen")
// the sub-project for whisper-native
// whisper_android = file("$root/whisper-android/")
/* Variants */ /* Variants */
// The list of variants to that are debuggable. For those we're going to // The list of variants to that are debuggable. For those we're going to

View File

@ -12,3 +12,5 @@
-keep class com.facebook.react.turbomodule.** { *; } -keep class com.facebook.react.turbomodule.** { *; }
# Add any project specific keep options here: # Add any project specific keep options here:
# whisper.rn
-keep class com.rnwhisper.** { *; }

View File

@ -3,5 +3,5 @@
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:usesCleartextTraffic" /> <application android:largeHeap="true" android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:usesCleartextTraffic" />
</manifest> </manifest>

View File

@ -1,7 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.WAKE_LOCK"/>
@ -13,11 +15,11 @@
<data android:scheme="https"/> <data android:scheme="https"/>
</intent> </intent>
</queries> </queries>
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true"> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true" android:largeHeap="true">
<meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/> <meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/> <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/> <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
<activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait"> <activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="landscape">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>

View File

@ -1,65 +0,0 @@
package com.anonymous.translationterrace
import expo.modules.splashscreen.SplashScreenManager
import android.os.Build
import android.os.Bundle
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
import expo.modules.ReactActivityDelegateWrapper
class MainActivity : ReactActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Set the theme to AppTheme BEFORE onCreate to support
// coloring the background, status bar, and navigation bar.
// This is required for expo-splash-screen.
// setTheme(R.style.AppTheme);
// @generated begin expo-splashscreen - expo prebuild (DO NOT MODIFY) sync-f3ff59a738c56c9a6119210cb55f0b613eb8b6af
SplashScreenManager.registerOnActivity(this)
// @generated end expo-splashscreen
super.onCreate(null)
}
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
override fun getMainComponentName(): String = "main"
/**
* Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
* which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
*/
override fun createReactActivityDelegate(): ReactActivityDelegate {
return ReactActivityDelegateWrapper(
this,
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
object : DefaultReactActivityDelegate(
this,
mainComponentName,
fabricEnabled
){})
}
/**
* Align the back button behavior with Android S
* where moving root activities to background instead of finishing activities.
* @see <a href="https://developer.android.com/reference/android/app/Activity#onBackPressed()">onBackPressed</a>
*/
override fun invokeDefaultOnBackPressed() {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
if (!moveTaskToBack(false)) {
// For non-root activities, use the default implementation to finish them.
super.invokeDefaultOnBackPressed()
}
return
}
// Use the default back button implementation on Android S
// because it's doing more than [Activity.moveTaskToBack] in fact.
super.invokeDefaultOnBackPressed()
}
}

View File

@ -1,57 +0,0 @@
package com.anonymous.translationterrace
import android.app.Application
import android.content.res.Configuration
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.ReactHost
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.react.soloader.OpenSourceMergedSoMapping
import com.facebook.soloader.SoLoader
import expo.modules.ApplicationLifecycleDispatcher
import expo.modules.ReactNativeHostWrapper
class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper(
this,
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> {
val packages = PackageList(this).packages
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
return packages
}
override fun getJSMainModuleName(): String = ".expo/.virtual-metro-entry"
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
}
)
override val reactHost: ReactHost
get() = ReactNativeHostWrapper.createReactHost(applicationContext, reactNativeHost)
override fun onCreate() {
super.onCreate()
SoLoader.init(this, OpenSourceMergedSoMapping)
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
load()
}
ApplicationLifecycleDispatcher.onApplicationCreate(this)
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
}
}

View File

@ -0,0 +1,30 @@
package com.nativewhisperengine;
// react-native turbo spec
import com.nativewhisperengine.NativeWhisperEngineSpec;
// inherent context
import android.content.Context;
import com.facebook.react.bridge.ReactApplicationContext;
// packages we'll be using.
import com.whispertflite.engine.WhisperEngine;
public class NativeWhisperModule extends NativeLocalStorageSpec {
public static final String NAME = "NativeLocalStorage";
private WhisperEngineNative mNativeEngine;
public NativeWhisperModule(ReactApplicationContext reactContext) {
super(reactContext);
mNativeEngine = new WhisperEngineNative(reactContext);
}
@Override
public void loadWhisper(String path) {}
@Override
public void translate(String text, String language) {
}
}

View File

@ -0,0 +1,41 @@
package com.nativewhisperengine;
import com.facebook.react.BaseReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import java.util.HashMap;
import java.util.Map;
public class NativeWhisperPackage extends BaseReactPackage {
@Override
public NativeModule getModule(String name, ReactApplicationContext reactContext) {
if (name.equals(NativeWhisperModule.NAME)) {
return new NativeWhisperModule(reactContext);
} else {
return null;
}
}
@Override
public ReactModuleInfoProvider getReactModuleInfoProvider() {
return new ReactModuleInfoProvider() {
@Override
public Map<String, ReactModuleInfo> getReactModuleInfos() {
Map<String, ReactModuleInfo> map = new HashMap<>();
map.put(NativeWhisperModule.NAME, new ReactModuleInfo(
NativeWhisperModule.NAME, // name
NativeWhisperModule.NAME, // className
false, // canOverrideExistingModule
false, // needsEagerInit
false, // isCXXModule
true // isTurboModule
));
return map;
}
};
}
}

View File

@ -6,7 +6,7 @@ buildscript {
minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '24') minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '24')
compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '35') compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '35')
targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34') targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34')
kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.24' kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.25'
ndkVersion = "26.1.10909125" ndkVersion = "26.1.10909125"
} }

View File

@ -1,5 +1,5 @@
pluginManagement { pluginManagement {
includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().toString()) includeBuild(file(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().toString())
} }
plugins { id("com.facebook.react.settings") } plugins { id("com.facebook.react.settings") }
@ -26,13 +26,17 @@ rootProject.name = 'translation-terrace'
dependencyResolutionManagement { dependencyResolutionManagement {
versionCatalogs { versionCatalogs {
reactAndroidLibs { reactAndroidLibs {
from(files(new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../gradle/libs.versions.toml"))) from(files(file(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../gradle/libs.versions.toml")))
} }
} }
} }
apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle"); apply from: file(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle")
useExpoModules() useExpoModules()
include ':whisper-android'
project(':whisper-android').projectDir = file(rootProject.projectDir, '../whisper_native')
include ':app' include ':app'
includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile()) includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile())

View File

@ -57,10 +57,11 @@
] ]
} }
} }
] ],
"expo-audio"
], ],
"experiments": { "experiments": {
"typedRoutes": true "typedRoutes": true
} }
} }
} }

View File

@ -1,123 +1,155 @@
import { Cache } from "react-native-cache"; import { Cache } from "react-native-cache";
import { LIBRETRANSLATE_BASE_URL } from "@/constants/api"; import { LIBRETRANSLATE_BASE_URL } from "@/constants/api";
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from "@react-native-async-storage/async-storage";
import { Settings } from "../lib/settings"; import { Settings } from "../lib/settings";
type language_t = string; type language_t = string;
const cache = new Cache({ const cache = new Cache({
namespace: "translation_terrace", namespace: "translation_terrace",
policy: { policy: {
maxEntries: 50000, // if unspecified, it can have unlimited entries maxEntries: 50000, // if unspecified, it can have unlimited entries
stdTTL: 0 // the standard ttl as number in seconds, default: 0 (unlimited) stdTTL: 0, // the standard ttl as number in seconds, default: 0 (unlimited)
}, },
backend: AsyncStorage backend: AsyncStorage,
}); });
export type language_matrix_entry = { export type language_matrix_entry = {
code: string, code: string;
name: string, name: string;
targets: string [] targets: string[];
} };
export type language_matrix = { export type language_matrix = {
[key:string] : language_matrix_entry [key: string]: language_matrix_entry;
} };
export async function fetchWithTimeout(url : string, options : RequestInit, timeout = 5000) : Promise<Response> { export async function fetchWithTimeout(
return Promise.race([ url: string,
fetch(url, options), options: RequestInit,
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout)) timeout = 5000
]); ): Promise<Response> {
return Promise.race([
fetch(url, options),
new Promise((_, reject) =>
setTimeout(() => reject(new Error("timeout")), timeout)
),
]);
} }
export class LanguageServer { export class LanguageServer {
constructor(public baseUrl : string) {} constructor(public baseUrl: string) {}
async fetchLanguages(timeout = 500) : Promise<language_matrix> { async fetchLanguages(timeout = 500): Promise<language_matrix> {
let data = {}; let data = {};
const res = await fetchWithTimeout(this.baseUrl + "/languages", { const res = await fetchWithTimeout(
headers: { this.baseUrl + "/languages",
"Content-Type": "application/json" {
} headers: {
}, timeout); "Content-Type": "application/json",
try { },
data = await res.json(); },
} catch (e) { timeout
throw new Error(`Parsing data from ${await res.text()}: ${e}`) );
} try {
try { data = await res.json();
return Object.fromEntries( } catch (e) {
Object.values(data as language_matrix_entry []).map((obj : language_matrix_entry) => { throw new Error(`Parsing data from ${await res.text()}: ${e}`);
return [
obj["code"],
obj,
]
})
)
} catch(e) {
throw new Error(`Can't extract values from data: ${JSON.stringify(data)}`)
}
} }
try {
return Object.fromEntries(
Object.values(data as language_matrix_entry[]).map(
(obj: language_matrix_entry) => {
return [obj["code"], obj];
}
)
);
} catch (e) {
throw new Error(
`Can't extract values from data: ${JSON.stringify(data)}`
);
}
}
static async getDefault() { static async getDefault() {
const settings = await Settings.getDefault(); const settings = await Settings.getDefault();
return new LanguageServer(await settings.getLibretranslateBaseUrl() || LIBRETRANSLATE_BASE_URL); return new LanguageServer(
} (await settings.getLibretranslateBaseUrl()) || LIBRETRANSLATE_BASE_URL
);
}
} }
export class Translator { export class Translator {
constructor(public source : language_t, public defaultTarget : string = "en", private _languageServer : LanguageServer) { constructor(
} public source: language_t,
public defaultTarget: string = "en",
private _languageServer: LanguageServer
) {}
get languageServer() { get languageServer() {
return this._languageServer; return this._languageServer;
} }
async translate(text : string, target : string|undefined = undefined) { async translate(text: string, target: string | undefined = undefined) {
const url = this._languageServer.baseUrl + `/translate`; const url = this._languageServer.baseUrl + `/translate`;
const res = await fetch(url, { console.log(url);
method: "POST", const postData = {
body: JSON.stringify({ method: "POST",
q: text, body: JSON.stringify({
source: this.source, q: text,
target: target || this.defaultTarget, source: this.source,
format: "text", target: target || this.defaultTarget,
alternatives: 3, format: "text",
api_key: "" alternatives: 3,
}), api_key: "",
headers: { "Content-Type": "application/json" } }),
}); headers: { "Content-Type": "application/json" },
};
console.debug("Requesting %s with %o", url, postData);
const data = await res.json();
console.log(data)
return data.translatedText
}
static async getDefault(defaultTarget: string | undefined = undefined) { const res = await fetch(url, postData);
const settings = await Settings.getDefault();
const source = await settings.getHostLanguage(); const data = await res.json();
return new Translator(source, defaultTarget, await LanguageServer.getDefault()) if (res.status === 200) {
console.log(data);
return data.translatedText;
} else {
console.error("Status %d: %s", res.status, JSON.stringify(data));
} }
}
static async getDefault(defaultTarget: string | undefined = undefined) {
const settings = await Settings.getDefault();
const source = await settings.getHostLanguage() || "en";
return new Translator(
source,
defaultTarget,
await LanguageServer.getDefault()
);
}
} }
export class CachedTranslator extends Translator { export class CachedTranslator extends Translator {
async translate (text : string, target : string|undefined = undefined) { async translate(text: string, target: string | undefined = undefined) {
const targetKey = target || this.defaultTarget; const targetKey = target || this.defaultTarget;
// console.debug(`Translating from ${this.source} -> ${targetKey}`) // console.debug(`Translating from ${this.source} -> ${targetKey}`)
const key1 = `${this.source}::${targetKey}::${text}` const key1 = `${this.source}::${targetKey}::${text}`;
const tr1 = await cache.get(key1); const tr1 = await cache.get(key1);
if (tr1) return tr1; if (tr1) return tr1;
const tr2 = await super.translate(text, target); const tr2 = await super.translate(text, target);
const key2 = `${this.source}::${targetKey}::${text}` const key2 = `${this.source}::${targetKey}::${text}`;
await cache.set(key2, tr2); await cache.set(key2, tr2);
return tr2; return tr2;
} }
static async getDefault(defaultTarget: string | undefined = undefined) { static async getDefault(defaultTarget: string | undefined = undefined) {
const settings = await Settings.getDefault(); const settings = await Settings.getDefault();
const source = await settings.getHostLanguage(); const source = await settings.getHostLanguage() || "en";
return new CachedTranslator(source, defaultTarget, await LanguageServer.getDefault()) return new CachedTranslator(
} source,
} defaultTarget,
await LanguageServer.getDefault()
);
}
}

View File

@ -1,5 +1,5 @@
import _countries from "@/assets/countries.min.json"; import _countries from "@/assets/countries.min.json";
import LANG_FLAGS from "@/langs-flags-list/lang-flags.json" import LANG_FLAGS from "./lang-flags.json"
import { language_matrix_entry } from "./api"; import { language_matrix_entry } from "./api";
import { lang_a2_a3 } from "./lang"; import { lang_a2_a3 } from "./lang";

72
app/i18n/lang-flags.json Normal file
View File

@ -0,0 +1,72 @@
{
"af": ["za"],
"am": ["et"],
"ar": ["eg", "sa", "ae"],
"az": ["az"],
"be": ["by"],
"bg": ["bg"],
"bn": ["bd", "in"],
"bs": ["ba"],
"ca": ["es"],
"cs": ["cz"],
"cy": ["gb"],
"da": ["dk"],
"de": ["de", "at", "ch"],
"el": ["gr"],
"en": ["us", "gb", "au"],
"es": ["es", "mx", "ar"],
"et": ["ee"],
"fa": ["ir"],
"fi": ["fi"],
"fr": ["fr", "ca", "be"],
"ga": ["ie"],
"gl": ["es"],
"gu": ["in"],
"he": ["il"],
"hi": ["in"],
"hr": ["hr"],
"ht": ["ht"],
"hu": ["hu"],
"hy": ["am"],
"id": ["id"],
"is": ["is"],
"it": ["it", "ch", "sm"],
"ja": ["jp"],
"ka": ["ge"],
"kn": ["in"],
"ko": ["kr"],
"ku": ["tr"],
"lv": ["lv"],
"mk": ["mk"],
"ml": ["in"],
"mn": ["mn"],
"mr": ["in"],
"ms": ["my"],
"mt": ["mt"],
"nb": ["no"],
"ne": ["np"],
"nl": ["nl", "be"],
"or": ["in"],
"pa": ["in", "pk"],
"pl": ["pl"],
"pt": ["pt", "br"],
"ro": ["ro"],
"ru": ["ru", "ua", "by"],
"si": ["lk"],
"sk": ["sk"],
"sl": ["si"],
"sq": ["al"],
"sr": ["rs"],
"sv": ["se", "no", "fi"],
"sw": ["tz"],
"ta": ["in", "lk", "sg"],
"te": ["in"],
"th": ["th"],
"tr": ["tr"],
"uk": ["ua"],
"ur": ["pk"],
"uz": ["uz"],
"vi": ["vn"],
"zh": ["cn", "tw", "hk"]
}

View File

@ -1,4 +1,4 @@
import _LANG_FLAGS from "@/langs-flags-list/lang-flags.json" import _LANG_FLAGS from "./lang-flags.json"
import _LANGUAGES from "@/assets/languages.min.json" import _LANGUAGES from "@/assets/languages.min.json"
export const LANG_FLAGS = _LANG_FLAGS export const LANG_FLAGS = _LANG_FLAGS

View File

@ -1,32 +1,27 @@
import {describe, expect, beforeEach} from '@jest/globals'; import { Settings } from '@/app/lib/settings';
import {Settings} from '@/app/lib/settings';
import { getDb, migrateDb } from '@/app/lib/db'; import { getDb, migrateDb } from '@/app/lib/db';
import { SQLiteDatabase } from 'expo-sqlite';
describe('Settings', () => { describe('Settings', () => {
let settings: Settings; let settings: Settings;
let db: SQLiteDatabase;
beforeEach(async () => { beforeEach(async () => {
// Initialize your Settings class here with a fresh database instance db = await getDb("development");
await migrateDb(); await migrateDb("development");
const db = await getDb();
if (!db) throw new Error("Could not get db");
settings = new Settings(db); settings = new Settings(db);
}); });
afterEach(async () => { afterEach(async () => {
// Clean up the database after each test await migrateDb("development", "down");
settings && await settings.db.executeSql('DELETE FROM settings');
}); });
describe('setHostLanguage', () => { it('should set the host language in the database', async () => {
it('should set the host language in the database', async () => { const value = 'en';
const value = 'en'; await settings.setHostLanguage(value);
await settings.db.runAsync("REPLACE INTO settings (host_language) VALUES (?)", "en");
await settings.setHostLanguage(value);
const result = await settings.getHostLanguage(); const result = await settings.getHostLanguage();
expect(result).toEqual(value); expect(result).toEqual(value);
});
}); });
describe('getHostLanguage', () => { describe('getHostLanguage', () => {
@ -40,7 +35,7 @@ describe('Settings', () => {
it('should return null if the host language is not set', async () => { it('should return null if the host language is not set', async () => {
const result = await settings.getHostLanguage(); const result = await settings.getHostLanguage();
expect(result).toBeNull(); expect(result).toBeUndefined();
}); });
}); });
@ -57,7 +52,34 @@ describe('Settings', () => {
describe('getLibretranslateBaseUrl', () => { describe('getLibretranslateBaseUrl', () => {
it('should return null if the LibreTranslate base URL is not set', async () => { it('should return null if the LibreTranslate base URL is not set', async () => {
const result = await settings.getLibretranslateBaseUrl(); const result = await settings.getLibretranslateBaseUrl();
expect(result).toBeNull(); expect(result).toBeUndefined();
}); });
}); });
});
describe('setWhisperModel', () => {
it('should set the Whisper model in the database', async () => {
const value = 'base';
await settings.setWhisperModel(value);
const result = await settings.getWhisperModel();
expect(result).toEqual(value);
});
});
describe('setWhisperModel', () => {
it('should set the Whisper model in the database', async () => {
const value = 'base';
await settings.setWhisperModel(value);
const result = await settings.getWhisperModel();
expect(result).toEqual(value);
});
});
describe('getWhisperModel', () => {
it('should return null if the Whisper model is not set', async () => {
const result = await settings.getWhisperModel();
expect(result).toBeUndefined();
});
});
});

View File

@ -0,0 +1,170 @@
// app/lib/__tests__/whisper.spec.tsx
import React from "react";
import { getDb } from "@/app/lib/db";
import { WhisperFile, WhisperModelTag } from "@/app/lib/whisper"; // Corrected to use WhisperFile and WhisperModelTag instead of WhisperDownloader
import { Settings } from "@/app/lib/settings";
import { File } from "expo-file-system/next";
jest.mock('expo-file-system');
import * as FileSystem from 'expo-file-system';
jest.mock("@/app/lib/db", () => ({
getDb: jest.fn().mockResolvedValue({
runAsync: jest.fn(),
upsert: jest.fn(), // Mock the upsert method used in addToDatabase
}),
}));
jest.mock("@/app/lib/settings", () => ({
Settings: {
getDefault: jest.fn(() => ({
getValue: jest.fn((key) => {
switch (key) {
case "whisper_model":
return "base";
default:
throw new Error(`Invalid setting: '${key}'`);
}
}),
})),
},
}));
jest.mock("expo-file-system/next", () => {
const _next = jest.requireActual("expo-file-system/next");
return {
..._next,
File: jest.fn().mockImplementation(() => ({
..._next.File,
text: jest.fn(() => {
return new String("text");
}),
})),
};
});
describe("WhisperFile", () => {
// Corrected to use WhisperFile instead of WhisperDownloader
let whisperFile: WhisperFile;
beforeEach(async () => {
whisperFile = new WhisperFile("small");
});
it("should create a download resumable with existing data if available", async () => {
const mockExistingData = "mockExistingData";
jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(true);
await whisperFile.createDownloadResumable();
// expect(whisperFile.targetFileName).toEqual("small.bin");
expect(whisperFile.targetPath).toContain("small.bin");
expect(FileSystem.createDownloadResumable).toHaveBeenCalledWith(
"https://huggingface.co/openai/whisper-small/resolve/main/pytorch_model.bin",
"file:///whisper/small.bin",
{},
expect.any(Function),
expect.anything(),
);
});
// it("should create a download resumable without existing data if not available", async () => {
// jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(false);
// await whisperFile.createDownloadResumable(); // Updated to use createDownloadResumable instead of download
// expect(FileSystem.createDownloadResumable).toHaveBeenCalledWith(
// "http://mock.model.com/model",
// "mockTargetPath",
// {},
// expect.any(Function),
// undefined
// );
// });
// it("should update the download status in the database", async () => {
// const mockRunAsync = jest.fn();
// (getDb as jest.Mock).mockResolvedValue({ runAsync: mockRunAsync });
// const downloadable = await whisperFile.createDownloadResumable(); // Updated to use createDownloadResumable instead of download
// await downloadable.resumeAsync();
// jest.advanceTimersByTime(1000);
// expect(mockRunAsync).toHaveBeenCalled();
// });
// it("should record the latest target hash after downloading", async () => {
// const mockRecordLatestTargetHash = jest.spyOn(
// whisperFile,
// "recordLatestTargetHash"
// );
// await whisperFile.createDownloadResumable(); // Updated to use createDownloadResumable instead of download
// expect(mockRecordLatestTargetHash).toHaveBeenCalled();
// });
// it("should call the onData callback if provided", async () => {
// const mockOnData = jest.fn();
// const options = { onData: mockOnData };
// await whisperFile.createDownloadResumable(options); // Updated to use createDownloadResumable instead of download
// expect(mockOnData).toHaveBeenCalledWith(expect.any(Object));
// });
// describe("getDownloadStatus", () => {
// it("should return the correct download status when model size is known and download has started", async () => {
// whisperFile.size = 1024;
// jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(true);
// jest.spyOn(whisperFile, "isDownloadComplete").mockResolvedValue(false);
// jest.spyOn(whisperFile, "targetFile").mockReturnValue({
// size: 512,
// });
// const status = await whisperFile.getDownloadStatus();
// expect(status).toEqual({
// doesTargetExist: true,
// isDownloadComplete: false,
// hasDownloadStarted: true,
// progress: {
// current: 512,
// total: 1024,
// remaining: 512,
// percentRemaining: 50.0,
// },
// });
// });
// it("should return the correct download status when model size is known and download is complete", async () => {
// whisperFile.size = 1024;
// jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(true);
// jest.spyOn(whisperFile, "isDownloadComplete").mockResolvedValue(true);
// const status = await whisperFile.getDownloadStatus();
// expect(status).toEqual({
// doesTargetExist: true,
// isDownloadComplete: true,
// hasDownloadStarted: false,
// progress: undefined,
// });
// });
// it("should return the correct download status when model size is unknown", async () => {
// jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(false);
// const status = await whisperFile.getDownloadStatus();
// expect(status).toEqual({
// doesTargetExist: false,
// isDownloadComplete: false,
// hasDownloadStarted: false,
// progress: undefined,
// });
// });
// });
});

View File

@ -1,14 +1,16 @@
import * as SQLite from "expo-sqlite"; import * as SQLite from "expo-sqlite";
import { MIGRATE_UP, MIGRATE_DOWN } from "./migrations"; import { MIGRATE_UP, MIGRATE_DOWN } from "./migrations";
export async function getDb() { export type db_mode = "development" | "staging" | "production";
return await SQLite.openDatabaseAsync("translation_terrace");
export async function getDb(mode : db_mode = "production") {
return await SQLite.openDatabaseAsync(`translation_terrace_${mode}`);
} }
export async function migrateDb(direction: "up" | "down" = "up") { export async function migrateDb(mode : db_mode = "production", direction: "up" | "down" = "up") {
const db = await getDb(); const db = await getDb(mode);
const m = direction === "up" ? MIGRATE_UP : MIGRATE_DOWN; const m = direction === "up" ? MIGRATE_UP : MIGRATE_DOWN;

View File

@ -2,15 +2,16 @@
export const MIGRATE_UP = { export const MIGRATE_UP = {
1: [ 1: [
`CREATE TABLE IF NOT EXISTS settings ( `CREATE TABLE IF NOT EXISTS settings (
host_language TEXT, key TEXT PRIMARY KEY,
libretranslate_base_url TEXT, value TEXT
ui_direction INTEGER, )`,
whisper_model TEXT
)`,
], ],
2: [ 2: [
`CREATE TABLE IF NOT EXISTS whisper_models ( `CREATE TABLE IF NOT EXISTS whisper_models (
model TEXT PRIMARY KEY, model TEXT PRIMARY KEY,
download_status STRING(255),
expected_size INTEGER,
last_hash STRING(1024),
bytes_done INTEGER, bytes_done INTEGER,
bytes_total INTEGER bytes_total INTEGER
)`, )`,

0
app/lib/models.ts Normal file
View File

61
app/lib/readstream.ts Normal file
View File

@ -0,0 +1,61 @@
/* eslint-disable unicorn/no-null */
import * as fs from 'expo-file-system';
import { Readable } from 'readable-stream';
class ExpoReadStream extends Readable {
private readonly fileUri: string;
private fileSize: number;
private currentPosition: number;
private readonly chunkSize: number;
constructor(fileUri: string, options: fs.ReadingOptions) {
super();
this.fileUri = fileUri;
this.fileSize = 0; // Initialize file size (could be fetched if necessary)
this.currentPosition = options.position ?? 0;
/**
* Default chunk size in bytes. React Native Expo will OOM at 110MB, so we set this to 1/100 of it to balance speed and memory usage and importantly the feedback for user.
* If this is too large, the progress bar will be stuck when down stream processing this chunk.
*/
this.chunkSize = options.length ?? 1024 * 1024;
void this._init();
}
async _init() {
try {
const fileInfo = await fs.getInfoAsync(this.fileUri, { size: true });
if (fileInfo.exists) {
this.fileSize = fileInfo.size ?? 0;
} else {
this.fileSize = 0;
}
} catch (error) {
this.emit('error', error);
}
}
_read() {
const readingOptions = {
encoding: fs.EncodingType.Base64,
position: this.currentPosition,
length: this.chunkSize,
} satisfies fs.ReadingOptions;
fs.readAsStringAsync(this.fileUri, readingOptions).then(chunk => {
if (chunk.length === 0) {
// End of the stream
this.emit('progress', 1);
this.push(null);
} else {
this.currentPosition = Math.min(this.chunkSize + this.currentPosition, this.fileSize);
this.emit('progress', this.fileSize === 0 ? 0.5 : (this.currentPosition / this.fileSize));
this.push(Buffer.from(chunk, 'base64'));
}
}).catch(error => {
this.emit('error', error);
});
}
}
export function createReadStream(fileUri: string, options: { encoding?: fs.EncodingType; end?: number; highWaterMark?: number; start?: number } = {}): ExpoReadStream {
return new ExpoReadStream(fileUri, options);
}

View File

@ -1,6 +1,6 @@
import { SQLiteDatabase } from "expo-sqlite"; import { SQLiteDatabase } from "expo-sqlite";
import FileSystem from "expo-file-system"
import { getDb } from "./db"; import { getDb } from "./db";
import { WhisperFile, whisper_model_tag_t } from "./whisper";
export class Settings { export class Settings {
@ -21,23 +21,23 @@ export class Settings {
throw new Error(`Invalid setting: '${key}'`) throw new Error(`Invalid setting: '${key}'`)
} }
const query = ` const row: { value: string } | null = this.db.getFirstSync(`SELECT value FROM settings WHERE key = ?`, key)
SELECT ${key}
FROM settings return row?.value;
LIMIT 1`
const result = await this.db.getFirstAsync(
query
);
return result ? (result as any)[key] : null;
} }
private async setValue(key: string, value: any) { private async setValue(key: string, value: any) {
if (!Settings.KEYS.includes(key)) { if (!Settings.KEYS.includes(key)) {
throw new Error(`Invalid setting: '${key}'`) throw new Error(`Invalid setting: '${key}'`);
} }
const statement = `REPLACE INTO settings (${key}) VALUES (?)`
await this.db.runAsync(statement, value); // Check if the key already exists
this.db.runSync(`INSERT OR REPLACE INTO
settings
(key, value)
VALUES
(?, ?)`, key, value);
} }
async setHostLanguage(value: string) { async setHostLanguage(value: string) {
@ -48,7 +48,7 @@ LIMIT 1`
return await this.getValue("host_language") return await this.getValue("host_language")
} }
async setLibretranslateBaseUrl(value : string) { async setLibretranslateBaseUrl(value: string) {
await this.setValue("libretranslate_base_url", value) await this.setValue("libretranslate_base_url", value)
} }
@ -56,16 +56,15 @@ LIMIT 1`
return await this.getValue("libretranslate_base_url") return await this.getValue("libretranslate_base_url")
} }
async setWhisperModel(value : string) { async setWhisperModel(value: string) {
await this.setValue("whisper_model", value); await this.setValue("whisper_model", value);
} }
async getWhisperModel() { async getWhisperModel() {
return await this.getValue("whisper_model"); return await this.getValue("whisper_model") as whisper_model_tag_t;
} }
static async getDefault() { static async getDefault() {
return new Settings(await getDb()) return new Settings(await getDb())
} }
} }

9
app/lib/util.ts Normal file
View File

@ -0,0 +1,9 @@
import { TextDecoder } from "util";
export function arrbufToStr(arrayBuffer : ArrayBuffer) {
return new TextDecoder().decode(new Uint8Array(arrayBuffer));
}
export function strToArrBuf(input : string) : Uint8Array<ArrayBufferLike> {
return new TextEncoder().encode(input)
}

View File

@ -1,213 +1,14 @@
import { Platform } from "react-native"; import { File, Paths } from "expo-file-system/next";
import * as FileSystem from "expo-file-system"; import FileSystem from "expo-file-system"
import { File, Paths } from 'expo-file-system/next'; import { pathToFileURLString } from "expo-file-system/src/next/pathUtilities/url";
import { getDb } from "./db";
export const WHISPER_MODEL_PATH = Paths.join(FileSystem.bundleDirectory || "file:///", "whisper"); export const WHISPER_MODEL_PATH = Paths.join("..", "..", "assets", "whisper");
export const WHISPER_MODEL_DIR = new File(WHISPER_MODEL_PATH); export const WHISPER_MODEL_DIR = new File(WHISPER_MODEL_PATH);
// Thanks to https://medium.com/@fabi.mofar/downloading-and-saving-files-in-react-native-expo-5b3499adda84 export const WHISPER_MODEL_SMALL_PATH = "file://../../assets/whisper/whisper-small.bin";
export async function saveFile(
uri: string,
filename: string,
mimetype: string
) {
if (Platform.OS === "android") {
const permissions =
await FileSystem.StorageAccessFramework.requestDirectoryPermissionsAsync();
if (permissions.granted) { export async function whisperModelExists() {
const base64 = await FileSystem.readAsStringAsync(uri, { const file = new File(WHISPER_MODEL_PATH);
encoding: FileSystem.EncodingType.Base64, return file.exists;
});
await FileSystem.StorageAccessFramework.createFileAsync(
permissions.directoryUri,
filename,
mimetype
)
.then(async (uri) => {
await FileSystem.writeAsStringAsync(uri, base64, {
encoding: FileSystem.EncodingType.Base64,
});
})
.catch((e) => console.log(e));
} else {
shareAsync(uri);
}
} else {
shareAsync(uri);
}
}
function shareAsync(uri: string) {
throw new Error("Function not implemented.");
}
export const WHISPER_MODEL_TAGS = ["small", "medium", "large"];
export type whisper_model_tag_t = (typeof WHISPER_MODEL_TAGS)[number];
export const WHISPER_MODELS = {
small: {
source:
"https://huggingface.co/openai/whisper-small/blob/main/pytorch_model.bin",
target: "small.bin",
label: "Small",
},
medium: {
source:
"https://huggingface.co/openai/whisper-medium/blob/main/pytorch_model.bin",
target: "medium.bin",
label: "Medium",
},
large: {
source:
"https://huggingface.co/openai/whisper-large/blob/main/pytorch_model.bin",
target: "large.bin",
label: "Large",
},
} as {
[key: whisper_model_tag_t]: { source: string; target: string; label: string };
};
export function getWhisperTarget(key : whisper_model_tag_t) {
const path = Paths.join(WHISPER_MODEL_DIR, WHISPER_MODELS[key].target);
return new File(path)
}
export type download_status =
| {
status: "not_started" | "complete";
}
| {
status: "in_progress";
bytes: {
total: number;
done: number;
};
};
export async function getModelFileSize(whisper_model: whisper_model_tag_t) {
const target = getWhisperTarget(whisper_model)
if (!target.exists) return undefined;
return target.size;
}
/**
*
* @param whisper_model The whisper model key to check (e.g. `"small"`)
* @returns
*/
export async function getWhisperDownloadStatus(
whisper_model: whisper_model_tag_t
): Promise<download_status> {
// const files = await FileSystem.readDirectoryAsync("file:///whisper");
const result = (await (
await getDb()
).getFirstSync(
`
SELECT (bytes_done, total) WHERE model = ?
`,
[whisper_model]
)) as { bytes_done: number; total: number } | undefined;
if (!result)
return {
status: "not_started",
};
if (result.bytes_done < result.total)
return {
status: "in_progress",
bytes: {
done: result.bytes_done,
total: result.total,
},
};
return {
status: "complete",
};
}
export function whisperFileExists(whisper_model : whisper_model_tag_t) {
const target = getWhisperTarget(whisper_model);
return target.exists
}
export type DownloadCallback = (arg0 : FileSystem.DownloadProgressData) => any;
async function updateModelSize(model_label : string, size : number) {
const db = await getDb();
const query = "INSERT OR REPLACE INTO whisper_models (model, bytes_total) VALUES (?, ?)"
const stmt = db.prepareSync(query);
stmt.executeSync(model_label, size);
}
async function getExpectedModelSize(model_label : string) : Promise<number | undefined> {
const db = await getDb();
const query = "SELECT bytes_total FROM whisper_models WHERE model = ?"
const stmt = db.prepareSync(query);
const curs = stmt.executeSync(model_label);
const row = curs.getFirstSync()
return row ? row.bytes_total : undefined;
}
export async function initiateWhisperDownload(
whisper_model: whisper_model_tag_t,
options: {
force_redownload?: boolean;
onDownload?: DownloadCallback | undefined;
} = {
force_redownload: false,
onDownload: undefined,
}
) {
console.debug("Starting download of %s", whisper_model);
if (!WHISPER_MODEL_DIR.exists) {
await FileSystem.makeDirectoryAsync(WHISPER_MODEL_PATH, {
intermediates: true,
});
console.debug("Created %s", WHISPER_MODEL_DIR);
}
const whisperTarget = getWhisperTarget(whisper_model);
// If the target file exists, delete it.
if (whisperTarget.exists) {
if (options.force_redownload) {
whisperTarget.delete()
} else {
const expected = await getExpectedModelSize(whisper_model);
if (whisperTarget.size === expected) {
console.warn("Whisper model for %s already exists", whisper_model);
return undefined;
}
}
}
// Initiate a new resumable download.
const spec = WHISPER_MODELS[whisper_model];
console.log("Downloading %s", spec.source);
const resumable = FileSystem.createDownloadResumable(
spec.source,
whisperTarget.uri,
{},
// On each data write, update the whisper model download status.
// Note that since createDownloadResumable callback only works in the foreground,
// a background process will also be updating the file size.
async (data) => {
console.log("%s: %d bytes of %d", whisperTarget.uri, data.totalBytesWritten, data.totalBytesExpectedToWrite);
await updateModelSize(whisper_model, data.totalBytesExpectedToWrite)
if (options.onDownload) await options.onDownload(data);
},
whisperTarget.exists ? whisperTarget.base64() : undefined,
);
return resumable;
} }

8
babel.config.js Normal file
View File

@ -0,0 +1,8 @@
module.exports = function (api) {
api.cache.forever();
return {
presets: [
'babel-preset-expo', 'module:@expo/knex-expo-sqlite-dialect/babel-preset',
],
};
};

View File

@ -1,9 +1,27 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { ScrollView, StyleSheet, Text, TouchableHighlight, View } from "react-native"; import {
Alert,
ScrollView,
StyleSheet,
Text,
TouchableHighlight,
View,
} from "react-native";
import { useNavigation, Route } from "@react-navigation/native"; import { useNavigation, Route } from "@react-navigation/native";
import { Conversation, Message } from "@/app/lib/conversation"; import { Conversation, Message } from "@/app/lib/conversation";
import MessageBubble from "@/components/ui/MessageBubble"; import MessageBubble from "@/components/ui/MessageBubble";
import { CachedTranslator, LanguageServer, language_matrix_entry } from "@/app/i18n/api"; import {
CachedTranslator,
LanguageServer,
language_matrix_entry,
} from "@/app/i18n/api";
import {
WHISPER_MODEL_SMALL_PATH,
whisperModelExists,
} from "@/app/lib/whisper";
import { initWhisper, WhisperContext } from "whisper.rn";
import { useAudioRecorder, AudioModule, RecordingPresets } from "expo-audio";
import FileSystem from "expo-file-system";
const lasOptions = { const lasOptions = {
sampleRate: 32000, // default is 44100 but 32000 is adequate for accurate voice recognition sampleRate: 32000, // default is 44100 but 32000 is adequate for accurate voice recognition
@ -14,11 +32,19 @@ const lasOptions = {
}; };
// LiveAudioStream.init(lasOptions as any); // LiveAudioStream.init(lasOptions as any);
const ConversationThread = ({ route } : {route?: Route<"Conversation", {conversation : Conversation}>}) => { const ConversationThread = ({
route,
}: {
route?: Route<"Conversation", { conversation: Conversation }>;
}) => {
const navigation = useNavigation(); const navigation = useNavigation();
if (!route) { if (!route) {
return (<View><Text>Missing Params!</Text></View>) return (
<View>
<Text>Missing Params!</Text>
</View>
);
} }
/* 2. Get the param */ /* 2. Get the param */
@ -27,60 +53,128 @@ const ConversationThread = ({ route } : {route?: Route<"Conversation", {conversa
const [messages, setMessages] = useState<Message[]>([]); const [messages, setMessages] = useState<Message[]>([]);
const [guestSpeak, setGuestSpeak] = useState<string | undefined>(); const [guestSpeak, setGuestSpeak] = useState<string | undefined>();
const [guestSpeakLoaded, setGuestSpeakLoaded] = useState<boolean>(false); const [guestSpeakLoaded, setGuestSpeakLoaded] = useState<boolean>(false);
const [whisperContext, setWhisperContext] = useState<
WhisperContext | undefined
>();
const [cachedTranslator, setCachedTranslator] = useState< const [cachedTranslator, setCachedTranslator] = useState<
undefined | CachedTranslator undefined | CachedTranslator
>(); >();
const [languageLabels, setLanguageLabels] = useState<undefined | { const [languageLabels, setLanguageLabels] = useState<
hostNative: { | undefined
host: string, | {
guest: string, hostNative: {
}, host: string;
guestNative: { guest: string;
host: string, };
guest: string, guestNative: {
} host: string;
}>() guest: string;
};
}
>();
// recorder settings
const audioRecorder = useAudioRecorder(RecordingPresets.HIGH_QUALITY);
const record = async () => {
await audioRecorder.prepareToRecordAsync();
audioRecorder.record();
};
const stopRecording = async () => {
// The recording will be available on `audioRecorder.uri`.
await audioRecorder.stop();
};
useEffect(() => { useEffect(() => {
(async () => { (async function () {
const languageServer = await LanguageServer.getDefault(); const languageServer = await LanguageServer.getDefault();
const languages = await languageServer.fetchLanguages(); try {
const cc = new CachedTranslator( const languages = await languageServer.fetchLanguages(5000);
"en", const cachedTranslator = new CachedTranslator(
conversation.guest.language, "en",
languageServer, conversation.guest.language,
) languageServer
setCachedTranslator(cc); );
setGuestSpeak(await cc.translate("Speak")); console.log("Set cached translator from %s", languageServer.baseUrl);
const hostLang1 = languages[conversation.host.language].name; setCachedTranslator(cachedTranslator);
const guestLang1 = languages[conversation.host.language].name;
const hostLang2 = await cc.translate(languages[conversation.host.language].name); try {
const guestLang2 = await cc.translate(languages[conversation.host.language].name); if (!(await whisperModelExists())) {
setLanguageLabels({ throw new Error(`${WHISPER_MODEL_SMALL_PATH} does not exist`);
hostNative: { }
host: hostLang1, } catch (err) {
guest: guestLang1, console.error(
}, `Could not determine if %s exists: %s`,
guestNative: { WHISPER_MODEL_SMALL_PATH,
host: hostLang2, err
guest: guestLang2, );
throw err;
} }
})
try {
setWhisperContext(
await initWhisper({
filePath: WHISPER_MODEL_SMALL_PATH,
})
);
} catch (err) {
console.error(err);
throw err;
}
// recorder settings
(async () => {
const status = await AudioModule.requestRecordingPermissionsAsync();
if (!status.granted) {
Alert.alert("Permission to access microphone was denied");
}
})();
setGuestSpeak(await cachedTranslator.translate("Speak"));
const hostLang1 = languages[conversation.host.language].name;
const guestLang1 = languages[conversation.host.language].name;
const hostLang2 = await cachedTranslator.translate(
languages[conversation.host.language].name
);
const guestLang2 = await cachedTranslator.translate(
languages[conversation.host.language].name
);
setLanguageLabels({
hostNative: {
host: hostLang1,
guest: guestLang1,
},
guestNative: {
host: hostLang2,
guest: guestLang2,
},
});
} catch (err) {
console.error(
"Could not set translator from %s: %s",
languageServer.baseUrl,
err
);
}
})(); })();
const updateMessages = (c: Conversation) => { const updateMessages = (c: Conversation) => {
setMessages([...c]); setMessages([...c]);
}; };
conversation.onAddMessage = updateMessages; if (!conversation) {
conversation.onTranslationDone = updateMessages; console.warn("Conversation is null or undefined.");
}
return () => { conversation.on("add_message", updateMessages);
conversation.onAddMessage = undefined; conversation.on("translation_done", updateMessages);
conversation.onTranslationDone = undefined;
}; // return () => {
// conversation.on("add_message", undefined);
// conversation.on("translation_done", undefined);
// };
}, [conversation, guestSpeak]); }, [conversation, guestSpeak]);
const renderMessages = () => const renderMessages = () =>
@ -90,11 +184,17 @@ const ConversationThread = ({ route } : {route?: Route<"Conversation", {conversa
return cachedTranslator ? ( return cachedTranslator ? (
<View style={{ flex: 1, flexDirection: "column" }}> <View style={{ flex: 1, flexDirection: "column" }}>
{languageLabels && (<View style={styles.languageLabels}> {languageLabels && (
<Text style={styles.nativeHostLabel}>{ languageLabels.hostNative.host } / { languageLabels.hostNative.guest }</Text> <View style={styles.languageLabels}>
<Text style={styles.nativeGuestLabel}>{ languageLabels.guestNative.host } / { languageLabels.guestNative.guest }</Text> <Text style={styles.nativeHostLabel}>
</View>) {languageLabels.hostNative.host} / {languageLabels.hostNative.guest}
} </Text>
<Text style={styles.nativeGuestLabel}>
{languageLabels.guestNative.host} /{" "}
{languageLabels.guestNative.guest}
</Text>
</View>
)}
<ScrollView <ScrollView
style={{ style={{
borderColor: "black", borderColor: "black",
@ -134,15 +234,9 @@ const ConversationThread = ({ route } : {route?: Route<"Conversation", {conversa
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
languageLabels: { languageLabels: {},
nativeHostLabel: {},
}, nativeGuestLabel: {},
nativeHostLabel: { });
},
nativeGuestLabel: {
},
})
export default ConversationThread; export default ConversationThread;

View File

@ -8,6 +8,7 @@ import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";
import { Conversation, Speaker } from "@/app/lib/conversation"; import { Conversation, Speaker } from "@/app/lib/conversation";
import { NavigationProp, ParamListBase } from "@react-navigation/native"; import { NavigationProp, ParamListBase } from "@react-navigation/native";
import { Link, useNavigation } from "expo-router"; import { Link, useNavigation } from "expo-router";
import { migrateDb } from "@/app/lib/db";
export function LanguageSelection(props: { export function LanguageSelection(props: {
@ -17,7 +18,7 @@ export function LanguageSelection(props: {
}) { }) {
const [languages, setLanguages] = useState<language_matrix | undefined>(); const [languages, setLanguages] = useState<language_matrix | undefined>();
const [languagesLoaded, setLanguagesLoaded] = useState<boolean>(false); const [languagesLoaded, setLanguagesLoaded] = useState<boolean>(false);
const [translator, setTranslator] = useState<Translator|undefined>(); const [translator, setTranslator] = useState<Translator | undefined>();
const nav = useNavigation(); const nav = useNavigation();
@ -30,11 +31,12 @@ export function LanguageSelection(props: {
useEffect(() => { useEffect(() => {
(async () => { (async () => {
await migrateDb();
try { try {
// Replace with your actual async data fetching logic // Replace with your actual async data fetching logic
setTranslator(await CachedTranslator.getDefault()); setTranslator(await CachedTranslator.getDefault());
const languageServer = await LanguageServer.getDefault(); const languageServer = await LanguageServer.getDefault();
const languages = await languageServer.fetchLanguages(5000); const languages = await languageServer.fetchLanguages(10000);
setLanguages(languages); setLanguages(languages);
setLanguagesLoaded(true); setLanguagesLoaded(true);
} catch (error) { } catch (error) {
@ -49,8 +51,8 @@ export function LanguageSelection(props: {
<Text>Settings</Text> <Text>Settings</Text>
</Pressable> </Pressable>
<ScrollView > <ScrollView >
<SafeAreaProvider > <SafeAreaProvider>
<SafeAreaView> <SafeAreaView style={styles.table}>
{(languages && languagesLoaded) ? Object.entries(languages).filter((l) => (LANG_FLAGS as any)[l[0]] !== undefined).map( {(languages && languagesLoaded) ? Object.entries(languages).filter((l) => (LANG_FLAGS as any)[l[0]] !== undefined).map(
([lang, lang_entry]) => { ([lang, lang_entry]) => {
return ( return (
@ -66,11 +68,15 @@ export function LanguageSelection(props: {
) )
} }
const DEBUG_BORDER = {
borderWidth: 3,
borderStyle: "dotted",
borderColor: "blue",
}
const styles = StyleSheet.create({ const styles = StyleSheet.create({
column: { table: {
flex: 1, flexDirection: "row",
flexDirection: 'row', flexWrap: "wrap",
flexWrap: 'wrap',
padding: 8,
}, },
}) })

View File

@ -1,214 +1,81 @@
// Import necessary packages
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { View, Text, TextInput, StyleSheet, Pressable } from "react-native"; // Add Picker import import { View, Text, TextInput, StyleSheet } from "react-native";
import { getDb } from "@/app/lib/db";
import { Settings } from "@/app/lib/settings"; import { Settings } from "@/app/lib/settings";
import { LanguageServer, fetchWithTimeout } from "@/app/i18n/api";
import { Picker } from "@react-native-picker/picker"; import { Picker } from "@react-native-picker/picker";
import { longLang } from "@/app/i18n/lang";
import FileSystem, { DownloadResumable } from "expo-file-system";
import { LIBRETRANSLATE_BASE_URL } from "@/constants/api";
import { import {
WHISPER_MODELS, LanguageServer,
WHISPER_MODEL_DIR, language_matrix,
initiateWhisperDownload, } from "@/app/i18n/api";
download_status,
getWhisperDownloadStatus,
getWhisperTarget,
whisper_model_tag_t,
} from "@/app/lib/whisper";
import { Paths } from "expo-file-system/next";
type Language = { const LIBRETRANSLATE_BASE_URL = "https://translate.argosopentech.com/translate";
code: string;
name: string;
};
type LanguageMatrix = { const SettingsComponent = () => {
[key: string]: Language;
};
type connection_test_t =
| {
success: true;
}
| {
success: false;
error: string;
};
const SettingsComponent: React.FC = () => {
const [hostLanguage, setHostLanguage] = useState<string | null>(null); const [hostLanguage, setHostLanguage] = useState<string | null>(null);
const [libretranslateBaseUrl, setLibretranslateBaseUrl] = useState< const [libretranslateBaseUrl, setLibretranslateBaseUrl] = useState<
string | null string | null
>(null); >(null);
const [languages, setLanguages] = useState<undefined | LanguageMatrix>(); const [languageOptions, setLanguageOptions] = useState<
const [isLoaded, setIsLoaded] = useState<boolean>(false); language_matrix | undefined
const [whisperModel, setWhisperModel] = useState<
undefined | whisper_model_tag_t
>(); >();
const [downloadStatus, setDownloadStatus] = useState< const [langServerConn, setLangServerConn] = useState<{
undefined | download_status success: boolean;
>(); error?: string;
} | null>(null);
const [langServerConn, setLangServerConn] = useState<
undefined | connection_test_t
>();
const [whisperDownloadProgress, setWhisperDownloadProgress] = useState<
FileSystem.DownloadProgressData | undefined
>();
const [downloader, setDownloader] = useState<DownloadResumable | undefined>();
const fillHostLanguageOptions = async () => {
const settings = await Settings.getDefault();
const hostLang = await settings.getHostLanguage();
setHostLanguage(hostLang || "en");
const langServer = new LanguageServer(
libretranslateBaseUrl || LIBRETRANSLATE_BASE_URL
);
// Fetch languages from API
try {
const langData = await langServer.fetchLanguages();
setLanguages(langData);
setLangServerConn({ success: true });
} catch (err) {
console.warn("Got an error fetching: %s", err);
setLangServerConn({
success: false,
error: `Could not connect to ${libretranslateBaseUrl}: ${err}`,
});
}
};
useEffect(() => { useEffect(() => {
(async () => { (async function () {
// Fetch the database connection
// const db = await getDb("down");
const settings = await Settings.getDefault(); const settings = await Settings.getDefault();
setHostLanguage((await settings.getHostLanguage()) || "en");
await fillHostLanguageOptions(); setLibretranslateBaseUrl(
(await settings.getLibretranslateBaseUrl()) || LIBRETRANSLATE_BASE_URL
console.log("Fetched settings");
// Get the current settings values
const libretranslateUrl =
(await settings.getLibretranslateBaseUrl()) || LIBRETRANSLATE_BASE_URL;
setLibretranslateBaseUrl(libretranslateUrl);
console.log("libretranslate url = %s", libretranslateUrl);
try {
const wModel = await settings.getWhisperModel();
setWhisperModel(wModel || "small");
} catch (err) {
console.warn(err);
}
// setWhisperModel(wModel);
setIsLoaded(true);
// console.log("Set is loaded: %s", isLoaded);
})();
// Check for whether a model is currently downloading and set the status.
setInterval(async () => {
if (!whisperModel) return null;
const dlStatus = await getWhisperDownloadStatus(whisperModel);
setDownloadStatus(dlStatus);
}, 200);
setInterval(async () => {
if (!libretranslateBaseUrl) return;
try {
const resp = await fetchWithTimeout(
libretranslateBaseUrl + "/languages",
{
method: "HEAD",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
},
5000
);
if (resp.status !== 200) {
throw new Error(resp.statusText);
}
setLangServerConn({ success: true });
} catch (err) {
setLangServerConn({
success: false,
error: `Could not connect to ${libretranslateBaseUrl}: ${err}`,
});
}
}, 1000);
setInterval(async () => {
const settings = await Settings.getDefault();
await settings.setHostLanguage(hostLanguage || "en");
await settings.setLibretranslateBaseUrl(
libretranslateBaseUrl || LIBRETRANSLATE_BASE_URL
); );
await settings.setWhisperModel(whisperModel || "small"); })();
}, 1000); });
}, []);
const doReadownload = async () => {
if (!whisperModel) return; const handleHostLanguageChange = async (lang: string) => {
await initiateWhisperDownload(whisperModel, { const settings = await Settings.getDefault();
force_redownload: true, setHostLanguage(lang);
onDownload: setWhisperDownloadProgress, await settings.setHostLanguage(lang);
});
}; };
const doDownload = async () => { const handleLibretranslateBaseUrlChange = async (url: string) => {
if (!whisperModel) return; const settings = await Settings.getDefault();
setLibretranslateBaseUrl(url);
await settings.setLibretranslateBaseUrl(url);
checkLangServerConnection(url);
};
const checkLangServerConnection = async (baseUrl: string) => {
try { try {
setDownloader( // Replace with actual connection check logic
await initiateWhisperDownload(whisperModel, { const testResult = await fetch(baseUrl, {
onDownload: setWhisperDownloadProgress, method: "HEAD",
}) });
); if (testResult.status !== 200) {
await downloader?.downloadAsync(); setLangServerConn({ success: true, error: testResult.statusText });
console.log("completed download"); }
} catch (err) { } catch (error) {
console.error(err); setLangServerConn({ success: false, error: `${error}` });
} }
}; };
const handleHostLanguageChange = async (value: string) => { return hostLanguage && libretranslateBaseUrl ? (
setHostLanguage(value);
// Fetch the database connection
const db = await getDb();
const settings = new Settings(db);
// Save the updated setting value
await settings.setHostLanguage(value);
};
const handleLibretranslateBaseUrlChange = async (value: string) => {
setLibretranslateBaseUrl(value);
const settings = await Settings.getDefault();
// Save the updated setting value
await settings.setLibretranslateBaseUrl(value);
await fillHostLanguageOptions();
};
return isLoaded ? (
<View style={styles.container}> <View style={styles.container}>
<Text style={styles.label}>Host Language:</Text> <Text style={styles.label}>Host Language:</Text>
<Picker {
selectedValue={hostLanguage || ""} <Picker
style={{ height: 50, width: "100%" }} selectedValue={hostLanguage}
onValueChange={handleHostLanguageChange} style={{ height: 50, width: "100%" }}
accessibilityHint="hostLanguage" onValueChange={handleHostLanguageChange}
> accessibilityHint="host language"
{languages && >
Object.entries(languages).map((lang) => ( {languageOptions &&
<Picker.Item key={lang[0]} label={lang[1].name} value={lang[0]} /> Object.entries(languageOptions).map(([key, value]) => {
))} return <Picker.Item label={value.name} value={value.code} />;
</Picker> })}
</Picker>
}
<Text style={styles.label}>LibreTranslate Base URL:</Text> <Text style={styles.label}>LibreTranslate Base URL:</Text>
<TextInput <TextInput
@ -225,28 +92,6 @@ const SettingsComponent: React.FC = () => {
Error connecting to {libretranslateBaseUrl}: {langServerConn.error} Error connecting to {libretranslateBaseUrl}: {langServerConn.error}
</Text> </Text>
))} ))}
<Picker
selectedValue={whisperModel || ""}
style={{ height: 50, width: "100%" }}
onValueChange={setWhisperModel}
accessibilityHint="language"
>
{Object.entries(WHISPER_MODELS).map(([key, { label }]) => (
<Picker.Item key={key} label={label} value={key} />
))}
</Picker>
<View>
{ /* If there's a downloader, that means we're in the middle of a download */}
{downloader && whisperDownloadProgress && (
<Text>
{whisperDownloadProgress.totalBytesWritten} of {whisperDownloadProgress.totalBytesExpectedToWrite}
</Text>
)
}
<Pressable onPress={doDownload} style={styles.button}>
<Text style={styles.buttonText}>Download</Text>
</Pressable>
</View>
</View> </View>
) : ( ) : (
<View> <View>
@ -257,18 +102,38 @@ const SettingsComponent: React.FC = () => {
// Create styles for the component // Create styles for the component
const styles = StyleSheet.create({ const styles = StyleSheet.create({
button: { downloadButtonWrapper: {
backgroundColor: "blue",
flexDirection: "row", flexDirection: "row",
display: "flex", },
flexShrink: 1, downloadButton: {
backgroundColor: "#236b9f",
padding: 20, padding: 20,
margin: 10,
flex: 1,
flexDirection: "column",
alignItems: "center", alignItems: "center",
alignContent: "center", },
deleteButton: {
backgroundColor: "darkred",
flex: 1,
flexDirection: "column",
padding: 10,
margin: 10,
height: 50,
},
pauseDownloadButton: {
backgroundColor: "#444444",
padding: 10,
margin: 10,
height: 50,
}, },
buttonText: { buttonText: {
color: "white", color: "#fff",
alignSelf: "center", // flex: 1,
// fontSize: 16,
// alignSelf: "center",
// textAlign: "center",
// textAlignVertical: "top",
}, },
container: { container: {
flex: 1, flex: 1,

View File

@ -1,5 +1,5 @@
jest.mock("@/app/i18n/api", () => require("../../__mocks__/api.ts")); jest.mock("@/app/i18n/api", () => require("../../__mocks__/api.ts"));
import { renderRouter} from 'expo-router/testing-library'; import { renderRouter } from "expo-router/testing-library";
import React from "react"; import React from "react";
import { import {
act, act,
@ -13,14 +13,21 @@ import {
createNavigationContainerRef, createNavigationContainerRef,
} from "@react-navigation/native"; } from "@react-navigation/native";
import TTNavStack from "../TTNavStack"; import TTNavStack from "../TTNavStack";
import { migrateDb } from "@/app/lib/db";
describe("Navigation", () => { describe("Navigation", () => {
beforeEach(() => { beforeEach(async () => {
await migrateDb("development", "up");
// Reset the navigation state before each test // Reset the navigation state before each test
jest.clearAllMocks();
jest.useFakeTimers(); jest.useFakeTimers();
}); });
afterEach(async () => {
await migrateDb("development", "down");
jest.clearAllMocks();
jest.useRealTimers();
});
it("Navigates to ConversationThread on language selection", async () => { it("Navigates to ConversationThread on language selection", async () => {
const MockComponent = jest.fn(() => <TTNavStack />); const MockComponent = jest.fn(() => <TTNavStack />);
renderRouter( renderRouter(
@ -28,7 +35,7 @@ describe("Navigation", () => {
index: MockComponent, index: MockComponent,
}, },
{ {
initialUrl: '/', initialUrl: "/",
} }
); );
const languageSelectionText = await waitFor(() => const languageSelectionText = await waitFor(() =>
@ -47,14 +54,16 @@ describe("Navigation", () => {
index: MockComponent, index: MockComponent,
}, },
{ {
initialUrl: '/', initialUrl: "/",
} }
); );
const settingsButton = await waitFor(() => const settingsButton = await waitFor(() =>
screen.getByText(/.*Settings.*/i) screen.getByText(/.*Settings.*/i)
); );
fireEvent.press(settingsButton); fireEvent.press(settingsButton);
expect(await waitFor(() => screen.getByText(/Settings/i))).toBeOnTheScreen(); expect(
await waitFor(() => screen.getByText(/Settings/i))
).toBeOnTheScreen();
// expect(waitFor(() => screen.getByText(/Settings/i))).toBeTruthy() // expect(waitFor(() => screen.getByText(/Settings/i))).toBeTruthy()
expect(screen.getByText("Settings")).toBeOnTheScreen(); expect(screen.getByText("Settings")).toBeOnTheScreen();
}); });

View File

@ -92,7 +92,7 @@ const ISpeakButton = (props: ISpeakButtonProps) => {
}, []); }, []);
const countries = const countries =
// @ts-ignore // @ts-ignore
DEFAULT_FLAGS[props.language.code] || chooseCountry(props.language.code); DEFAULT_FLAGS[props.language.code] || chooseCountry(props.language.code);
return title ? ( return title ? (
@ -106,7 +106,9 @@ const ISpeakButton = (props: ISpeakButtonProps) => {
<View style={styles.flag}> <View style={styles.flag}>
{countries && {countries &&
countries.map((c) => { countries.map((c) => {
return <CountryFlag isoCode={c} size={25} key={c} />; return (
<CountryFlag isoCode={c} size={25} key={c} />
);
})} })}
</View> </View>
<View> <View>
@ -121,14 +123,13 @@ const ISpeakButton = (props: ISpeakButtonProps) => {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
button: { button: {
width: "20%",
borderRadius: 10, borderRadius: 10,
borderColor: "white", borderColor: "white",
borderWidth: 1, borderWidth: 1,
borderStyle: "solid", borderStyle: "solid",
height: 110, height: 110,
alignSelf: "flex-start", width: 170,
margin: 8, margin: 10,
}, },
flag: {}, flag: {},
iSpeak: { iSpeak: {

View File

@ -4,107 +4,219 @@ import SettingsComponent from "@/components/Settings";
import { language_matrix } from "@/app/i18n/api"; import { language_matrix } from "@/app/i18n/api";
import { Settings } from "@/app/lib/settings"; import { Settings } from "@/app/lib/settings";
import { getDb, migrateDb } from "@/app/lib/db"; import { getDb, migrateDb } from "@/app/lib/db";
import { Knex } from "knex";
import { WhisperFile } from "@/app/lib/whisper";
import { SQLiteDatabase } from "expo-sqlite";
const RENDER_TIME = 1000; const RENDER_TIME = 1000;
jest.mock("@/app/lib/whisper", () => {
const originalModule = jest.requireActual("@/app/lib/whisper");
return {
...originalModule,
WhisperFile: jest.fn().mockImplementation((tag, targetFileName, label, size) => ({
tag,
targetFileName,
label,
size,
doesTargetExist: jest.fn(),
getDownloadStatus: jest.fn(), // Mock other methods as needed
isDownloadComplete: jest.fn(() => false), // Initially assume download is not complete
createDownloadResumable: jest.fn().mockResolvedValue({
startAsync: jest.fn().mockResolvedValue({}),
}),
})),
};
});
jest.mock("expo-file-system", () => {
const originalModule = jest.requireActual("expo-file-system");
return {
...originalModule,
File: jest.fn().mockImplementation(() => ({
bytes: jest.fn(),
exists: jest.fn(),
})),
};
});
jest.mock("@/app/i18n/api", () => { jest.mock("@/app/i18n/api", () => {
class LanguageServer { const LanguageServer = jest.fn();
fetchLanguages = () => { const Translator = jest.fn();
return {
"en": { // Mock the fetchLanguages method to return a predefined language matrix
code: "en", LanguageServer.prototype.fetchLanguages = jest.fn(() => ({
name: "English", en: {
targets: [ code: "en",
"fr", name: "English",
"es" targets: ["fr", "es"],
] },
}, fr: {
"fr": { code: "fr",
code: "fr", name: "French",
name: "French", targets: ["en", "es"],
targets: [ },
"en", es: {
"es" code: "es",
] name: "Spanish",
}, targets: ["en", "fr"],
"es": { },
code: "es", } as language_matrix));
name: "Spanish",
targets: [ // Mock the translate method
"en", Translator.prototype.translate = jest.fn((text: string, target: string) => {
"fr" return "Hola, como estas?";
] });
},
} as language_matrix return {
} LanguageServer,
} Translator,
class Translator { };
translate = jest.fn((text : string, target : string) => { });
return "Hola, como estas?"
})
}
return {
LanguageServer,
Translator,
}
})
describe("SettingsComponent", () => { describe("SettingsComponent", () => {
beforeEach(async() => { let db: SQLiteDatabase;
await migrateDb(); let settings: Settings;
const settings = await Settings.getDefault();
await settings.setHostLanguage("en");
await settings.setLibretranslateBaseUrl("https://example.com");
})
beforeAll(() => { beforeEach(async () => {
jest.useFakeTimers(); db = await getDb("development");
}) await migrateDb("development");
settings = new Settings(db);
jest.spyOn(Settings, 'getDefault').mockResolvedValue(settings);
await settings.setHostLanguage("en");
await settings.setLibretranslateBaseUrl("https://example.com");
});
afterAll(() => { afterEach(async () => {
jest.useRealTimers() jest.restoreAllMocks();
}) await migrateDb("development", "down");
});
test("renders correctly with initial settings", async () => { beforeAll(async () => {
render(<SettingsComponent />); jest.useFakeTimers();
jest.advanceTimersByTime(RENDER_TIME); });
screen.debug();
// Wait for the component to fetch and display the initial settings afterAll(() => {
await screen.findByText(/Host Language:/i); jest.useRealTimers();
await screen.findByText(/LibreTranslate Base URL:/i); });
// expect(screen.getByDisplayValue("English")).toBeTruthy(); test("renders correctly with initial settings", async () => {
expect(screen.getByAccessibilityHint("libretranslate base url")).toBeTruthy(); render(<SettingsComponent />);
screen.debug();
// Wait for the component to fetch and display the initial settings
await screen.findByText(/Host Language:/i);
await screen.findByText(/LibreTranslate Base URL:/i);
// expect(screen.getByDisplayValue("English")).toBeTruthy();
expect(
screen.getByAccessibilityHint("libretranslate base url")
).toBeTruthy();
});
test("updates host language setting when input changes", async () => {
render(<SettingsComponent />);
// Wait for the component to fetch and display the initial settings
await screen.findByText(/Host Language:/i);
await screen.findByText(/LibreTranslate Base URL:/i);
// Change the host language input value
const picker = screen.getByAccessibilityHint("host language");
fireEvent(picker, "onvalueChange", "es");
expect(picker.props.selectedIndex).toStrictEqual(0);
});
test("updates LibreTranslate base URL setting when input changes", async () => {
render(<SettingsComponent />);
jest.advanceTimersByTime(RENDER_TIME);
screen.debug();
// Wait for the component to fetch and display the initial settings
await screen.findByText(/Host Language:/i);
await screen.findByText(/LibreTranslate Base URL:/i);
// Change the LibreTranslate base URL input value
fireEvent.changeText(
screen.getByAccessibilityHint("libretranslate base url"),
"http://new-example.com"
);
jest.advanceTimersByTime(RENDER_TIME);
expect(
screen.getByAccessibilityHint("libretranslate base url")
).toBeTruthy();
});
describe("Download Whisper Model", () => {
it("should trigger download when model is not present", async () => {
const whisperFile = new WhisperFile("small");
(whisperFile.doesTargetExist as jest.Mock).mockResolvedValue(false);
render(<SettingsComponent />);
await screen.findByText(/\s*Download Small\s*/i);
// Assuming there's a button or trigger to start download
act(() => {
fireEvent.press(screen.getByText(/\s*Download Small\s*/i));
})
expect(whisperFile.createDownloadResumable).toHaveBeenCalled();
}); });
test("updates host language setting when input changes", async () => { it("should show progress when download is in progress", async () => {
render(<SettingsComponent />); const whisperFile = new WhisperFile("small");
(whisperFile.doesTargetExist as jest.Mock).mockResolvedValue(false);
(whisperFile.getDownloadStatus as jest.Mock).mockResolvedValue({
doesTargetExist: false,
isDownloadComplete: false,
hasDownloadStarted: true,
progress: {
current: 1024,
total: 2048,
remaining: 1024,
percentRemaining: 50,
},
});
// Wait for the component to fetch and display the initial settings render(<SettingsComponent />);
await screen.findByText(/Host Language:/i); await screen.findByText(/Host Language:/i);
await screen.findByText(/LibreTranslate Base URL:/i); fireEvent.press(screen.getByText(/Download Model/i));
// Change the host language input value expect(await screen.findByText("50%")).toBeTruthy();
const picker = screen.getByAccessibilityHint("hostLanguage");
fireEvent(picker, "onvalueChange", "es");
expect(picker.props.selectedIndex).toStrictEqual(0);
}); });
test("updates LibreTranslate base URL setting when input changes", async () => { it("should indicate download is complete", async () => {
render(<SettingsComponent />); const whisperFile = new WhisperFile("small");
(whisperFile.doesTargetExist as jest.Mock).mockResolvedValue(false);
(whisperFile.getDownloadStatus as jest.Mock)
.mockResolvedValueOnce({
doesTargetExist: false,
isDownloadComplete: false,
hasDownloadStarted: true,
progress: {
current: 1024,
total: 2048,
remaining: 1024,
percentRemaining: 50,
},
})
.mockResolvedValueOnce({
doesTargetExist: true,
isDownloadComplete: true,
hasDownloadStarted: false,
progress: undefined,
});
jest.advanceTimersByTime(RENDER_TIME) render(<SettingsComponent />);
screen.debug(); await screen.findByText(/Host Language:/i);
fireEvent.press(screen.getByText(/Download Model/i));
// Wait for the component to fetch and display the initial settings expect(await screen.findByText("Download Complete")).toBeTruthy();
await screen.findByText(/Host Language:/i);
await screen.findByText(/LibreTranslate Base URL:/i);
// Change the LibreTranslate base URL input value
fireEvent.changeText(screen.getByAccessibilityHint("libretranslate base url"), "http://new-example.com");
jest.advanceTimersByTime(RENDER_TIME);
expect(screen.getByAccessibilityHint("libretranslate base url")).toBeTruthy();
}); });
}); });
});

15
file.ts Normal file
View File

@ -0,0 +1,15 @@
interface Settings {
host_language: string;
libretranslate_base_url: string;
ui_direction: number;
whisper_model: string;
}
interface WhisperModel {
model: string;
download_status: boolean;
expected_size: number;
last_hash: string;
bytes_done: string;
bytes_total: string;
}

View File

@ -9,43 +9,37 @@ jest.mock("expo-sqlite", () => {
const { MIGRATE_UP } = jest.requireActual("./app/lib/migrations"); const { MIGRATE_UP } = jest.requireActual("./app/lib/migrations");
const genericRun = (sql: string, ... params : string []) => {
// console.log("Running %s with %s", sql, params);
try {
const stmt = db.prepare(sql);
stmt.run(...params);
} catch (e) {
throw new Error(
`running ${sql} with params ${JSON.stringify(params)}: ${e}`
);
}
}
const genericGetFirst = (sql: string, params = []) => {
const stmt = db.prepare(sql);
// const result = stmt.run(...params);
return stmt.get(params);
};
const openDatabaseAsync = async (name: string) => { const openDatabaseAsync = async (name: string) => {
return { return {
closeAsync: jest.fn(() => db.close()), closeAsync: jest.fn(() => db.close()),
executeSql: jest.fn((sql: string) => db.exec(sql)), executeSql: jest.fn((sql: string) => db.exec(sql)),
runAsync: jest.fn(async (sql: string, params = []) => { runAsync: jest.fn(genericRun),
for (let m of Object.values(MIGRATE_UP)) { runSync: jest.fn(genericRun),
for (let stmt of m) { getFirstAsync: jest.fn(genericGetFirst),
const s = db.prepare(stmt); getFirstSync: jest.fn(genericGetFirst),
s.run();
}
}
const stmt = db.prepare(sql);
// console.log("Running %s with %s", sql, params);
try {
stmt.run(params);
} catch (e) {
throw new Error(
`running ${sql} with params ${JSON.stringify(params)}: ${e}`
);
}
}),
getFirstAsync: jest.fn(async (sql: string, params = []) => {
for (let m of Object.values(MIGRATE_UP)) {
for (let stmt of m) {
const s = db.prepare(stmt);
s.run();
}
}
const stmt = db.prepare(sql);
// const result = stmt.run(...params);
return stmt.get(params);
}),
}; };
}; };
return { return {
migrateDb: async (direction: "up" | "down" = "up") => { migrateDb: async (direction: "up" | "down" = "up") => {
const db = await openDatabaseAsync("translation_terrace"); const db = await openDatabaseAsync("translation_terrace_development");
for (let m of Object.values(MIGRATE_UP)) { for (let m of Object.values(MIGRATE_UP)) {
for (let stmt of m) { for (let stmt of m) {
await db.executeSql(stmt); await db.executeSql(stmt);
@ -68,4 +62,69 @@ jest.mock('react-native-reanimated', () => {
}); });
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing // Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
// jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper'); // jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
// Mock implementation of the Settings class for Jest
// Mock implementation of the Settings class
jest.mock('@/app/lib/settings', () => {
const originalModule = jest.requireActual('@/app/lib/settings');
class MockSettings extends originalModule.Settings {
constructor(db: any) {
super(db);
}
private getValue(key: string) {
// Return mock values for testing
switch (key) {
case "host_language":
return "en";
case "libretranslate_base_url":
return "http://mock.libretranslate.com";
case 'ui_direction':
return "ltr";
case "whisper_model":
return "base";
default:
throw new Error(`Invalid setting: '${key}'`);
}
}
private setValue(key: string, value: any) {
// Mock setting values
console.log(`Mock set ${key} to ${value}`);
}
static getDefault() {
const mockDb = { // Mock database object
select: jest.fn().mockReturnThis(),
limit: jest.fn().mockReturnThis(),
first: jest.fn().mockResolvedValue({ host_language: "en" }),
update: jest.fn().mockResolvedValue(1),
insert: jest.fn().mockResolvedValue([1])
};
return new MockSettings(mockDb);
}
}
return {
__esModule: true,
...originalModule,
default: MockSettings
};
});
jest.mock('expo-file-system', () => ({
// ... other methods ...
createDownloadResumable: jest.fn(() => ({
downloadAsync: jest.fn(() => Promise.resolve({ uri: 'mocked-uri' })),
pauseAsync: jest.fn(() => Promise.resolve()),
resumeAsync: jest.fn(() => Promise.resolve()),
cancelAsync: jest.fn(() => Promise.resolve()),
})),
getInfoAsync: jest.fn(() => ({
exists: () => false,
}))
// ... other methods ...
}));

37
knexfile.ts Normal file
View File

@ -0,0 +1,37 @@
// import type { Knex } from "knex";
import ExpoSQLiteDialect from "@expo/knex-expo-sqlite-dialect";
import {Knex} from "knex"
const EXPO_CONFIG = {
client: ExpoSQLiteDialect,
connection: {
filename: "translation_terrace.db",
},
};
// Update with your config settings.
export default {
development: {
...EXPO_CONFIG,
client: "sqlite3"
},
staging: {
...EXPO_CONFIG,
migrations: {
tableName: "knex_migrations",
},
},
production: {
...EXPO_CONFIG,
migrations: {
tableName: "knex_migrations",
},
},
} as {
development: Knex.Config,
staging: Knex.Config,
production: Knex.Config,
};

Submodule langs-flags-list deleted from f888fb8e1b

View File

@ -0,0 +1,27 @@
import type { Knex } from "knex";
export async function up(knex: Knex): Promise<void> {
await knex.schema.createTable("settings", (table) => {
table.string("host_language");
table.string("libretranslate_base_url");
table.integer("ui_direction");
table.string("whisper_model");
});
await knex.schema.createTable("whisper_models", (table) => {
table.string("model");
table.boolean("download_status");
table.integer("expected_size");
table.text("last_hash"),
table.string("bytes_done");
table.string("bytes_total");
});
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.dropTable("whisper_models");
await knex.schema.dropTable("settings");
}

2468
package-lock.json generated
View File

@ -9,6 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.26.7", "@babel/runtime": "^7.26.7",
"@expo/knex-expo-sqlite-dialect": "^0.0.1",
"@expo/vector-icons": "^14.0.4", "@expo/vector-icons": "^14.0.4",
"@mmomtchev/react-native-settings": "^1.1.0", "@mmomtchev/react-native-settings": "^1.1.0",
"@react-native-async-storage/async-storage": "^2.1.0", "@react-native-async-storage/async-storage": "^2.1.0",
@ -16,9 +17,11 @@
"@react-navigation/bottom-tabs": "^7.2.0", "@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native-stack": "^7.2.0", "@react-navigation/native-stack": "^7.2.0",
"expo": "~52.0.28", "expo": "~52.0.28",
"expo-audio": "~0.3.4",
"expo-background-fetch": "~13.0.5", "expo-background-fetch": "~13.0.5",
"expo-blur": "~14.0.3", "expo-blur": "~14.0.3",
"expo-constants": "~17.0.6", "expo-constants": "~17.0.6",
"expo-crypto": "~14.0.2",
"expo-device": "~7.0.2", "expo-device": "~7.0.2",
"expo-file-system": "^18.0.10", "expo-file-system": "^18.0.10",
"expo-font": "~13.0.3", "expo-font": "~13.0.3",
@ -29,14 +32,14 @@
"expo-screen-orientation": "~8.0.4", "expo-screen-orientation": "~8.0.4",
"expo-sharing": "^13.0.1", "expo-sharing": "^13.0.1",
"expo-splash-screen": "~0.29.21", "expo-splash-screen": "~0.29.21",
"expo-sqlite": "~15.1.2", "expo-sqlite": "^15.1.2",
"expo-status-bar": "~2.0.1", "expo-status-bar": "~2.0.1",
"expo-symbols": "~0.2.2", "expo-symbols": "~0.2.2",
"expo-system-ui": "~4.0.7", "expo-system-ui": "~4.0.7",
"expo-web-browser": "~14.0.2", "expo-web-browser": "~14.0.2",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-native": "0.76.6", "react-native": "^0.76.7",
"react-native-cache": "^2.0.3", "react-native-cache": "^2.0.3",
"react-native-country-flag": "^2.0.2", "react-native-country-flag": "^2.0.2",
"react-native-gesture-handler": "~2.20.2", "react-native-gesture-handler": "~2.20.2",
@ -47,6 +50,9 @@
"react-native-sqlite-storage": "^6.0.1", "react-native-sqlite-storage": "^6.0.1",
"react-native-web": "~0.19.13", "react-native-web": "~0.19.13",
"react-native-webview": "13.12.5", "react-native-webview": "13.12.5",
"readable-stream": "^4.7.0",
"sqlite": "^5.1.1",
"sqlite3": "^5.1.7",
"whisper.rn": "^0.3.9" "whisper.rn": "^0.3.9"
}, },
"devDependencies": { "devDependencies": {
@ -61,12 +67,14 @@
"@types/react-native-sqlite-storage": "^6.0.5", "@types/react-native-sqlite-storage": "^6.0.5",
"@types/react-navigation": "^3.0.8", "@types/react-navigation": "^3.0.8",
"@types/react-test-renderer": "^18.3.1", "@types/react-test-renderer": "^18.3.1",
"@types/readable-stream": "^4.0.18",
"babel-jest": "^29.7.0", "babel-jest": "^29.7.0",
"babel-plugin-module-resolver": "^5.0.2", "babel-plugin-module-resolver": "^5.0.2",
"expo": "~52.0.28", "expo": "~52.0.28",
"expo-sqlite-mock": "^2.0.1", "expo-sqlite-mock": "^2.0.1",
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-expo": "~52.0.3", "jest-expo": "~52.0.3",
"knex": "^3.1.0",
"metro-react-native-babel-preset": "^0.77.0", "metro-react-native-babel-preset": "^0.77.0",
"react-test-renderer": "18.3.1", "react-test-renderer": "18.3.1",
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",
@ -155,13 +163,13 @@
} }
}, },
"node_modules/@babel/generator": { "node_modules/@babel/generator": {
"version": "7.26.8", "version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz",
"integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==", "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.26.8", "@babel/parser": "^7.26.9",
"@babel/types": "^7.26.8", "@babel/types": "^7.26.9",
"@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25", "@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2" "jsesc": "^3.0.2"
@ -517,12 +525,12 @@
} }
}, },
"node_modules/@babel/parser": { "node_modules/@babel/parser": {
"version": "7.26.8", "version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz",
"integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==", "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/types": "^7.26.8" "@babel/types": "^7.26.9"
}, },
"bin": { "bin": {
"parser": "bin/babel-parser.js" "parser": "bin/babel-parser.js"
@ -2282,14 +2290,14 @@
} }
}, },
"node_modules/@babel/template": { "node_modules/@babel/template": {
"version": "7.26.8", "version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
"integrity": "sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==", "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.26.2", "@babel/code-frame": "^7.26.2",
"@babel/parser": "^7.26.8", "@babel/parser": "^7.26.9",
"@babel/types": "^7.26.8" "@babel/types": "^7.26.9"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@ -2315,16 +2323,16 @@
}, },
"node_modules/@babel/traverse--for-generate-function-map": { "node_modules/@babel/traverse--for-generate-function-map": {
"name": "@babel/traverse", "name": "@babel/traverse",
"version": "7.26.8", "version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz",
"integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==", "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.26.2", "@babel/code-frame": "^7.26.2",
"@babel/generator": "^7.26.8", "@babel/generator": "^7.26.9",
"@babel/parser": "^7.26.8", "@babel/parser": "^7.26.9",
"@babel/template": "^7.26.8", "@babel/template": "^7.26.9",
"@babel/types": "^7.26.8", "@babel/types": "^7.26.9",
"debug": "^4.3.1", "debug": "^4.3.1",
"globals": "^11.1.0" "globals": "^11.1.0"
}, },
@ -2333,9 +2341,9 @@
} }
}, },
"node_modules/@babel/types": { "node_modules/@babel/types": {
"version": "7.26.8", "version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz",
"integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==", "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/helper-string-parser": "^7.25.9", "@babel/helper-string-parser": "^7.25.9",
@ -2966,6 +2974,26 @@
"signal-exit": "^3.0.2" "signal-exit": "^3.0.2"
} }
}, },
"node_modules/@expo/knex-expo-sqlite-dialect": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/@expo/knex-expo-sqlite-dialect/-/knex-expo-sqlite-dialect-0.0.1.tgz",
"integrity": "sha512-nCSBIW3uZqQiK/HyoXTJnuxUGxcM5ayYxppwMECGCQ90ouiTkboGFoS6nRzIIqwhvb41vsdikE0m6C9IWdcTig==",
"license": "MIT",
"dependencies": {
"assert": "^2.1.0",
"babel-plugin-module-resolver": "^5.0.0",
"crypto-browserify": "^3.12.0",
"events": "^3.3.0",
"node-libs-browser": "^2.2.1",
"stream-browserify": "^3.0.0",
"timers-browserify": "^2.0.12",
"tty-browserify": "^0.0.1"
},
"peerDependencies": {
"expo-sqlite": "*",
"knex": "*"
}
},
"node_modules/@expo/metro-config": { "node_modules/@expo/metro-config": {
"version": "0.19.9", "version": "0.19.9",
"resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.19.9.tgz", "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.19.9.tgz",
@ -3395,6 +3423,13 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
"integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
"license": "MIT",
"optional": true
},
"node_modules/@ide/backoff": { "node_modules/@ide/backoff": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/@ide/backoff/-/backoff-1.0.0.tgz", "resolved": "https://registry.npmjs.org/@ide/backoff/-/backoff-1.0.0.tgz",
@ -4012,6 +4047,34 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/@npmcli/move-file": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
"integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
"deprecated": "This functionality has been moved to @npmcli/fs",
"license": "MIT",
"optional": true,
"dependencies": {
"mkdirp": "^1.0.4",
"rimraf": "^3.0.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@npmcli/move-file/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"license": "MIT",
"optional": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@pkgjs/parseargs": { "node_modules/@pkgjs/parseargs": {
"version": "0.11.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@ -4073,9 +4136,9 @@
} }
}, },
"node_modules/@react-native/assets-registry": { "node_modules/@react-native/assets-registry": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.7.tgz",
"integrity": "sha512-YI8HoReYiIwdFQs+k9Q9qpFTnsyYikZxgs/UVtVbhKixXDQF6F9LLvj2naOx4cfV+RGybNKxwmDl1vUok/dRFQ==", "integrity": "sha512-o79whsqL5fbPTUQO9w1FptRd4cw1TaeOrXtQSLQeDrMVAenw/wmsjyPK10VKtvqxa1KNMtWEyfgxcM8CVZVFmg==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
@ -4196,13 +4259,13 @@
} }
}, },
"node_modules/@react-native/community-cli-plugin": { "node_modules/@react-native/community-cli-plugin": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.76.7.tgz",
"integrity": "sha512-nETlc/+U5cESVluzzgN0OcVfcoMijGBaDWzOaJhoYUodcuqnqtu75XsSEc7yzlYjwNQG+vF83mu9CQGezruNMA==", "integrity": "sha512-lrcsY2WPLCEWU1pjdNV9+Ccj8vCEwCCURZiPa5aqi7lKB4C++1hPrxA8/CWWnTNcQp76DsBKGYqTFj7Ud4aupw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@react-native/dev-middleware": "0.76.6", "@react-native/dev-middleware": "0.76.7",
"@react-native/metro-babel-transformer": "0.76.6", "@react-native/metro-babel-transformer": "0.76.7",
"chalk": "^4.0.0", "chalk": "^4.0.0",
"execa": "^5.1.1", "execa": "^5.1.1",
"invariant": "^2.2.4", "invariant": "^2.2.4",
@ -4225,46 +4288,6 @@
} }
} }
}, },
"node_modules/@react-native/community-cli-plugin/node_modules/@react-native/debugger-frontend": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.6.tgz",
"integrity": "sha512-kP97xMQjiANi5/lmf8MakS7d8FTJl+BqYHQMqyvNiY+eeWyKnhqW2GL2v3eEUBAuyPBgJGivuuO4RvjZujduJg==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=18"
}
},
"node_modules/@react-native/community-cli-plugin/node_modules/@react-native/dev-middleware": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.76.6.tgz",
"integrity": "sha512-1bAyd2/X48Nzb45s5l2omM75vy764odx/UnDs4sJfFCuK+cupU4nRPgl0XWIqgdM/2+fbQ3E4QsVS/WIKTFxvQ==",
"license": "MIT",
"dependencies": {
"@isaacs/ttlcache": "^1.4.1",
"@react-native/debugger-frontend": "0.76.6",
"chrome-launcher": "^0.15.2",
"chromium-edge-launcher": "^0.2.0",
"connect": "^3.6.5",
"debug": "^2.2.0",
"nullthrows": "^1.1.1",
"open": "^7.0.3",
"selfsigned": "^2.4.1",
"serve-static": "^1.13.1",
"ws": "^6.2.3"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@react-native/community-cli-plugin/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/@react-native/community-cli-plugin/node_modules/execa": { "node_modules/@react-native/community-cli-plugin/node_modules/execa": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
@ -4321,12 +4344,6 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/@react-native/community-cli-plugin/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
"node_modules/@react-native/community-cli-plugin/node_modules/npm-run-path": { "node_modules/@react-native/community-cli-plugin/node_modules/npm-run-path": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@ -4366,15 +4383,6 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/@react-native/community-cli-plugin/node_modules/ws": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
"integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
"license": "MIT",
"dependencies": {
"async-limiter": "~1.0.0"
}
},
"node_modules/@react-native/debugger-frontend": { "node_modules/@react-native/debugger-frontend": {
"version": "0.76.7", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.7.tgz", "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.7.tgz",
@ -4432,31 +4440,31 @@
} }
}, },
"node_modules/@react-native/gradle-plugin": { "node_modules/@react-native/gradle-plugin": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.76.7.tgz",
"integrity": "sha512-sDzpf4eiynryoS6bpYCweGoxSmWgCSx9lzBoxIIW+S6siyGiTaffzZHWCm8mIn9UZsSPlEO37q62ggnR9Zu/OA==", "integrity": "sha512-gQI6RcrJbigU8xk7F960C5xQIgvbBj20TUvGecD+N2PHfbLpqR+92cj7hz3UcbrCONmTP40WHnbMMJ8P+kLsrA==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/@react-native/js-polyfills": { "node_modules/@react-native/js-polyfills": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.76.7.tgz",
"integrity": "sha512-cDD7FynxWYxHkErZzAJtzPGhJ13JdOgL+R0riTh0hCovOfIUz9ItffdLQv2nx48lnvMTQ+HZXMnGOZnsFCNzQw==", "integrity": "sha512-+iEikj6c6Zvrg1c3cYMeiPB+5nS8EaIC3jCtP6Muk3qc7c386IymEPM2xycIlfg04DPZvO3D4P2/vaO9/TCnUg==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/@react-native/metro-babel-transformer": { "node_modules/@react-native/metro-babel-transformer": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.76.7.tgz",
"integrity": "sha512-xSBi9jPliThu5HRSJvluqUlDOLLEmf34zY/U7RDDjEbZqC0ufPcPS7c5XsSg0GDPiXc7lgjBVesPZsKFkoIBgA==", "integrity": "sha512-jDS1wR7q46xY5ah+jF714Mvss9l7+lmwW/tplahZgLKozkYDC8Td5o9TOCgKlv18acw9H1V7zv8ivuRSj8ICPg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
"@react-native/babel-preset": "0.76.6", "@react-native/babel-preset": "0.76.7",
"hermes-parser": "0.23.1", "hermes-parser": "0.23.1",
"nullthrows": "^1.1.1" "nullthrows": "^1.1.1"
}, },
@ -4467,120 +4475,6 @@
"@babel/core": "*" "@babel/core": "*"
} }
}, },
"node_modules/@react-native/metro-babel-transformer/node_modules/@react-native/babel-plugin-codegen": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.76.6.tgz",
"integrity": "sha512-yFC9I/aDBOBz3ZMlqKn2NY/mDUtCksUNZ7AQmBiTAeVTUP0ujEjE0hTOx5Qd+kok7A7hwZEX87HdSgjiJZfr5g==",
"license": "MIT",
"dependencies": {
"@react-native/codegen": "0.76.6"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@react-native/metro-babel-transformer/node_modules/@react-native/babel-preset": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.76.6.tgz",
"integrity": "sha512-ojlVWY6S/VE/nb9hIRetPMTsW9ZmGb2R3dnToEXAtQQDz41eHMHXbkw/k2h0THp6qhas25ruNvn3N5n2o+lBzg==",
"license": "MIT",
"dependencies": {
"@babel/core": "^7.25.2",
"@babel/plugin-proposal-export-default-from": "^7.24.7",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-export-default-from": "^7.24.7",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
"@babel/plugin-syntax-optional-chaining": "^7.8.3",
"@babel/plugin-transform-arrow-functions": "^7.24.7",
"@babel/plugin-transform-async-generator-functions": "^7.25.4",
"@babel/plugin-transform-async-to-generator": "^7.24.7",
"@babel/plugin-transform-block-scoping": "^7.25.0",
"@babel/plugin-transform-class-properties": "^7.25.4",
"@babel/plugin-transform-classes": "^7.25.4",
"@babel/plugin-transform-computed-properties": "^7.24.7",
"@babel/plugin-transform-destructuring": "^7.24.8",
"@babel/plugin-transform-flow-strip-types": "^7.25.2",
"@babel/plugin-transform-for-of": "^7.24.7",
"@babel/plugin-transform-function-name": "^7.25.1",
"@babel/plugin-transform-literals": "^7.25.2",
"@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
"@babel/plugin-transform-modules-commonjs": "^7.24.8",
"@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
"@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
"@babel/plugin-transform-numeric-separator": "^7.24.7",
"@babel/plugin-transform-object-rest-spread": "^7.24.7",
"@babel/plugin-transform-optional-catch-binding": "^7.24.7",
"@babel/plugin-transform-optional-chaining": "^7.24.8",
"@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-react-display-name": "^7.24.7",
"@babel/plugin-transform-react-jsx": "^7.25.2",
"@babel/plugin-transform-react-jsx-self": "^7.24.7",
"@babel/plugin-transform-react-jsx-source": "^7.24.7",
"@babel/plugin-transform-regenerator": "^7.24.7",
"@babel/plugin-transform-runtime": "^7.24.7",
"@babel/plugin-transform-shorthand-properties": "^7.24.7",
"@babel/plugin-transform-spread": "^7.24.7",
"@babel/plugin-transform-sticky-regex": "^7.24.7",
"@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.76.6",
"babel-plugin-syntax-hermes-parser": "^0.25.1",
"babel-plugin-transform-flow-enums": "^0.0.2",
"react-refresh": "^0.14.0"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@babel/core": "*"
}
},
"node_modules/@react-native/metro-babel-transformer/node_modules/@react-native/codegen": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.76.6.tgz",
"integrity": "sha512-BABb3e5G/+hyQYEYi0AODWh2km2d8ERoASZr6Hv90pVXdUHRYR+yxCatX7vSd9rnDUYndqRTzD0hZWAucPNAKg==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.25.3",
"glob": "^7.1.1",
"hermes-parser": "0.23.1",
"invariant": "^2.2.4",
"jscodeshift": "^0.14.0",
"mkdirp": "^0.5.1",
"nullthrows": "^1.1.1",
"yargs": "^17.6.2"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@babel/preset-env": "^7.1.6"
}
},
"node_modules/@react-native/metro-babel-transformer/node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@react-native/normalize-colors": { "node_modules/@react-native/normalize-colors": {
"version": "0.76.7", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.7.tgz", "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.7.tgz",
@ -4588,9 +4482,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@react-native/virtualized-lists": { "node_modules/@react-native/virtualized-lists": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.76.7.tgz",
"integrity": "sha512-0HUWVwJbRq1BWFOu11eOWGTSmK9nMHhoMPyoI27wyWcl/nqUx7HOxMbRVq0DsTCyATSMPeF+vZ6o1REapcNWKw==", "integrity": "sha512-pRUf1jUO8H9Ft04CaWv76t34QI9wY0sydoYlIwEtqXjjMJgmgDoOCAWBjArgn2mk8/rK+u/uicI67ZCYCp1pJw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"invariant": "^2.2.4", "invariant": "^2.2.4",
@ -5155,6 +5049,24 @@
"@types/react": "^18" "@types/react": "^18"
} }
}, },
"node_modules/@types/readable-stream": {
"version": "4.0.18",
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.18.tgz",
"integrity": "sha512-21jK/1j+Wg+7jVw1xnSwy/2Q1VgVjWuFssbYGTREPUBeZ+rqVFl2udq0IkxzPC0ZhOzVceUbyIACFZKLqKEBlA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
"safe-buffer": "~5.1.1"
}
},
"node_modules/@types/readable-stream/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/stack-utils": { "node_modules/@types/stack-utils": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
@ -5429,6 +5341,13 @@
"dev": true, "dev": true,
"license": "BSD-3-Clause" "license": "BSD-3-Clause"
}, },
"node_modules/abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"license": "ISC",
"optional": true
},
"node_modules/abort-controller": { "node_modules/abort-controller": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
@ -5507,7 +5426,7 @@
"version": "6.0.2", "version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dev": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"debug": "4" "debug": "4"
@ -5516,6 +5435,19 @@
"node": ">= 6.0.0" "node": ">= 6.0.0"
} }
}, },
"node_modules/agentkeepalive": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
"integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"humanize-ms": "^1.2.1"
},
"engines": {
"node": ">= 8.0.0"
}
},
"node_modules/aggregate-error": { "node_modules/aggregate-error": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
@ -5656,6 +5588,43 @@
"integrity": "sha512-zy9cHePtMP0YhwG+CfHm0bgwdnga2X3gZexpdCwEj//dpb+TKajtiC8REEUJUSq6Ab4f9cgNy2l8ObXzCXFkEw==", "integrity": "sha512-zy9cHePtMP0YhwG+CfHm0bgwdnga2X3gZexpdCwEj//dpb+TKajtiC8REEUJUSq6Ab4f9cgNy2l8ObXzCXFkEw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/aproba": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
"license": "ISC",
"optional": true
},
"node_modules/are-we-there-yet": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
"integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"dependencies": {
"delegates": "^1.0.0",
"readable-stream": "^3.6.0"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/are-we-there-yet/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"optional": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/arg": { "node_modules/arg": {
"version": "5.0.2", "version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
@ -5686,6 +5655,23 @@
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/asn1.js": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
"integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.0.0",
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0"
}
},
"node_modules/asn1.js/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/assert": { "node_modules/assert": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz",
@ -5819,7 +5805,6 @@
"version": "5.0.2", "version": "5.0.2",
"resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.2.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.2.tgz",
"integrity": "sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg==", "integrity": "sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"find-babel-config": "^2.1.1", "find-babel-config": "^2.1.1",
@ -6065,9 +6050,7 @@
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"file-uri-to-path": "1.0.0" "file-uri-to-path": "1.0.0"
} }
@ -6076,15 +6059,33 @@
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"buffer": "^5.5.0", "buffer": "^5.5.0",
"inherits": "^2.0.4", "inherits": "^2.0.4",
"readable-stream": "^3.4.0" "readable-stream": "^3.4.0"
} }
}, },
"node_modules/bl/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/bn.js": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
"license": "MIT"
},
"node_modules/bplist-creator": { "node_modules/bplist-creator": {
"version": "0.0.7", "version": "0.0.7",
"resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz",
@ -6128,6 +6129,129 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/brorand": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
"integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==",
"license": "MIT"
},
"node_modules/browserify-aes": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"license": "MIT",
"dependencies": {
"buffer-xor": "^1.0.3",
"cipher-base": "^1.0.0",
"create-hash": "^1.1.0",
"evp_bytestokey": "^1.0.3",
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/browserify-cipher": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
"integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
"license": "MIT",
"dependencies": {
"browserify-aes": "^1.0.4",
"browserify-des": "^1.0.0",
"evp_bytestokey": "^1.0.0"
}
},
"node_modules/browserify-des": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
"integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
"license": "MIT",
"dependencies": {
"cipher-base": "^1.0.1",
"des.js": "^1.0.0",
"inherits": "^2.0.1",
"safe-buffer": "^5.1.2"
}
},
"node_modules/browserify-rsa": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz",
"integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==",
"license": "MIT",
"dependencies": {
"bn.js": "^5.2.1",
"randombytes": "^2.1.0",
"safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/browserify-sign": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz",
"integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==",
"license": "ISC",
"dependencies": {
"bn.js": "^5.2.1",
"browserify-rsa": "^4.1.0",
"create-hash": "^1.2.0",
"create-hmac": "^1.1.7",
"elliptic": "^6.5.5",
"hash-base": "~3.0",
"inherits": "^2.0.4",
"parse-asn1": "^5.1.7",
"readable-stream": "^2.3.8",
"safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 0.12"
}
},
"node_modules/browserify-sign/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/browserify-sign/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/browserify-zlib": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
"integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
"license": "MIT",
"dependencies": {
"pako": "~1.0.5"
}
},
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.24.4", "version": "4.24.4",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
@ -6234,6 +6358,18 @@
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/buffer-xor": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
"integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==",
"license": "MIT"
},
"node_modules/builtin-status-codes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
"integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==",
"license": "MIT"
},
"node_modules/bytes": { "node_modules/bytes": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@ -6549,6 +6685,19 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/cipher-base": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz",
"integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.4",
"safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/cjs-module-lexer": { "node_modules/cjs-module-lexer": {
"version": "1.4.3", "version": "1.4.3",
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
@ -6691,6 +6840,22 @@
"simple-swizzle": "^0.2.2" "simple-swizzle": "^0.2.2"
} }
}, },
"node_modules/color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"license": "ISC",
"optional": true,
"bin": {
"color-support": "bin.js"
}
},
"node_modules/colorette": {
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
"integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==",
"license": "MIT"
},
"node_modules/combined-stream": { "node_modules/combined-stream": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@ -6823,6 +6988,24 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/console-browserify": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
"integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA=="
},
"node_modules/console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
"license": "ISC",
"optional": true
},
"node_modules/constants-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
"integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==",
"license": "MIT"
},
"node_modules/convert-source-map": { "node_modules/convert-source-map": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@ -6860,6 +7043,12 @@
"url": "https://opencollective.com/core-js" "url": "https://opencollective.com/core-js"
} }
}, },
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"license": "MIT"
},
"node_modules/cosmiconfig": { "node_modules/cosmiconfig": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
@ -6888,6 +7077,49 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/create-ecdh": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
"integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.1.0",
"elliptic": "^6.5.3"
}
},
"node_modules/create-ecdh/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/create-hash": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"license": "MIT",
"dependencies": {
"cipher-base": "^1.0.1",
"inherits": "^2.0.1",
"md5.js": "^1.3.4",
"ripemd160": "^2.0.1",
"sha.js": "^2.4.0"
}
},
"node_modules/create-hmac": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"license": "MIT",
"dependencies": {
"cipher-base": "^1.0.3",
"create-hash": "^1.1.0",
"inherits": "^2.0.1",
"ripemd160": "^2.0.0",
"safe-buffer": "^5.0.1",
"sha.js": "^2.4.8"
}
},
"node_modules/create-jest": { "node_modules/create-jest": {
"version": "29.7.0", "version": "29.7.0",
"resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz",
@ -6942,6 +7174,32 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/crypto-browserify": {
"version": "3.12.1",
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz",
"integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==",
"license": "MIT",
"dependencies": {
"browserify-cipher": "^1.0.1",
"browserify-sign": "^4.2.3",
"create-ecdh": "^4.0.4",
"create-hash": "^1.2.0",
"create-hmac": "^1.1.7",
"diffie-hellman": "^5.0.3",
"hash-base": "~3.0.4",
"inherits": "^2.0.4",
"pbkdf2": "^3.1.2",
"public-encrypt": "^4.0.3",
"randombytes": "^2.1.0",
"randomfill": "^1.0.4"
},
"engines": {
"node": ">= 0.10"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/crypto-random-string": { "node_modules/crypto-random-string": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
@ -7054,9 +7312,7 @@
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"mimic-response": "^3.1.0" "mimic-response": "^3.1.0"
}, },
@ -7199,6 +7455,13 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
"license": "MIT",
"optional": true
},
"node_modules/depd": { "node_modules/depd": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@ -7208,6 +7471,16 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/des.js": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz",
"integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0"
}
},
"node_modules/destroy": { "node_modules/destroy": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
@ -7250,6 +7523,23 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0" "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
} }
}, },
"node_modules/diffie-hellman": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.1.0",
"miller-rabin": "^4.0.0",
"randombytes": "^2.0.0"
}
},
"node_modules/diffie-hellman/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/dir-glob": { "node_modules/dir-glob": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@ -7262,6 +7552,16 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/domain-browser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
"integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
"license": "MIT",
"engines": {
"node": ">=0.4",
"npm": ">=1.2"
}
},
"node_modules/domexception": { "node_modules/domexception": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
@ -7351,6 +7651,27 @@
"integrity": "sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w==", "integrity": "sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/elliptic": {
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz",
"integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.11.9",
"brorand": "^1.1.0",
"hash.js": "^1.0.0",
"hmac-drbg": "^1.0.1",
"inherits": "^2.0.4",
"minimalistic-assert": "^1.0.1",
"minimalistic-crypto-utils": "^1.0.1"
}
},
"node_modules/elliptic/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/emittery": { "node_modules/emittery": {
"version": "0.13.1", "version": "0.13.1",
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
@ -7385,7 +7706,6 @@
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"peer": true,
"dependencies": { "dependencies": {
"iconv-lite": "^0.6.2" "iconv-lite": "^0.6.2"
} }
@ -7436,12 +7756,29 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/env-paths": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=6"
}
},
"node_modules/eol": { "node_modules/eol": {
"version": "0.9.1", "version": "0.9.1",
"resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz",
"integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==", "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/err-code": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
"license": "MIT",
"optional": true
},
"node_modules/error-ex": { "node_modules/error-ex": {
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@ -7584,6 +7921,15 @@
"node": ">=4.0" "node": ">=4.0"
} }
}, },
"node_modules/esm": {
"version": "3.2.25",
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/esprima": { "node_modules/esprima": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
@ -7652,13 +7998,21 @@
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=0.8.x" "node": ">=0.8.x"
} }
}, },
"node_modules/evp_bytestokey": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
"integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
"license": "MIT",
"dependencies": {
"md5.js": "^1.3.4",
"safe-buffer": "^5.1.1"
}
},
"node_modules/exec-async": { "node_modules/exec-async": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/exec-async/-/exec-async-2.2.0.tgz", "resolved": "https://registry.npmjs.org/exec-async/-/exec-async-2.2.0.tgz",
@ -7763,9 +8117,7 @@
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
"dev": true,
"license": "(MIT OR WTFPL)", "license": "(MIT OR WTFPL)",
"peer": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
@ -7860,6 +8212,17 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/expo-audio": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/expo-audio/-/expo-audio-0.3.5.tgz",
"integrity": "sha512-gzpDH3vZI1FDL1Q8pXryACtNIW+idZ/zIZ8WqdTRzJuzxucazrG2gLXUS2ngcXQBn09Jyz4RUnU10Tu2N7/Hgg==",
"license": "MIT",
"peerDependencies": {
"expo": "*",
"react": "*",
"react-native": "*"
}
},
"node_modules/expo-background-fetch": { "node_modules/expo-background-fetch": {
"version": "13.0.5", "version": "13.0.5",
"resolved": "https://registry.npmjs.org/expo-background-fetch/-/expo-background-fetch-13.0.5.tgz", "resolved": "https://registry.npmjs.org/expo-background-fetch/-/expo-background-fetch-13.0.5.tgz",
@ -7897,6 +8260,18 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/expo-crypto": {
"version": "14.0.2",
"resolved": "https://registry.npmjs.org/expo-crypto/-/expo-crypto-14.0.2.tgz",
"integrity": "sha512-WRc9PBpJraJN29VD5Ef7nCecxJmZNyRKcGkNiDQC1nhY5agppzwhqh7zEzNFarE/GqDgSiaDHS8yd5EgFhP9AQ==",
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.0"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-device": { "node_modules/expo-device": {
"version": "7.0.2", "version": "7.0.2",
"resolved": "https://registry.npmjs.org/expo-device/-/expo-device-7.0.2.tgz", "resolved": "https://registry.npmjs.org/expo-device/-/expo-device-7.0.2.tgz",
@ -8411,9 +8786,7 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/filelist": { "node_modules/filelist": {
"version": "1.0.4", "version": "1.0.4",
@ -8506,7 +8879,6 @@
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.1.2.tgz", "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.1.2.tgz",
"integrity": "sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg==", "integrity": "sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"json5": "^2.2.3" "json5": "^2.2.3"
@ -8734,9 +9106,7 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/fs-extra": { "node_modules/fs-extra": {
"version": "8.1.0", "version": "8.1.0",
@ -8793,6 +9163,27 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/gauge": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
"integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"dependencies": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.3",
"console-control-strings": "^1.1.0",
"has-unicode": "^2.0.1",
"signal-exit": "^3.0.7",
"string-width": "^4.2.3",
"strip-ansi": "^6.0.1",
"wide-align": "^1.1.5"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/gensync": { "node_modules/gensync": {
"version": "1.0.0-beta.2", "version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@ -8887,19 +9278,22 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/getopts": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz",
"integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==",
"license": "MIT"
},
"node_modules/github-from-package": { "node_modules/github-from-package": {
"version": "0.0.0", "version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/glob": { "node_modules/glob": {
"version": "9.3.5", "version": "9.3.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
"integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==",
"dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"fs.realpath": "^1.0.0", "fs.realpath": "^1.0.0",
@ -8938,7 +9332,6 @@
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"balanced-match": "^1.0.0" "balanced-match": "^1.0.0"
@ -8948,7 +9341,6 @@
"version": "8.0.4", "version": "8.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz",
"integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==",
"dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"brace-expansion": "^2.0.1" "brace-expansion": "^2.0.1"
@ -8964,7 +9356,6 @@
"version": "4.2.8", "version": "4.2.8",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
"integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
"dev": true,
"license": "ISC", "license": "ISC",
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@ -9065,6 +9456,36 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
"license": "ISC",
"optional": true
},
"node_modules/hash-base": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz",
"integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.4",
"safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/hash.js": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
"integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"minimalistic-assert": "^1.0.1"
}
},
"node_modules/hasown": { "node_modules/hasown": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@ -9092,6 +9513,17 @@
"hermes-estree": "0.23.1" "hermes-estree": "0.23.1"
} }
}, },
"node_modules/hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
"integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==",
"license": "MIT",
"dependencies": {
"hash.js": "^1.0.3",
"minimalistic-assert": "^1.0.0",
"minimalistic-crypto-utils": "^1.0.1"
}
},
"node_modules/hoist-non-react-statics": { "node_modules/hoist-non-react-statics": {
"version": "3.3.2", "version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@ -9145,6 +9577,13 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
"license": "BSD-2-Clause",
"optional": true
},
"node_modules/http-errors": { "node_modules/http-errors": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@ -9185,11 +9624,17 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/https-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
"integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==",
"license": "MIT"
},
"node_modules/https-proxy-agent": { "node_modules/https-proxy-agent": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"dev": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"agent-base": "6", "agent-base": "6",
@ -9208,6 +9653,16 @@
"node": ">=10.17.0" "node": ">=10.17.0"
} }
}, },
"node_modules/humanize-ms": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
"integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"ms": "^2.0.0"
}
},
"node_modules/hyphenate-style-name": { "node_modules/hyphenate-style-name": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz",
@ -9331,6 +9786,13 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/infer-owner": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
"integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
"license": "ISC",
"optional": true
},
"node_modules/inflight": { "node_modules/inflight": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -9377,6 +9839,15 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/interpret": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
"integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/invariant": { "node_modules/invariant": {
"version": "2.2.4", "version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@ -9386,6 +9857,27 @@
"loose-envify": "^1.0.0" "loose-envify": "^1.0.0"
} }
}, },
"node_modules/ip-address": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
"integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
"license": "MIT",
"optional": true,
"dependencies": {
"jsbn": "1.1.0",
"sprintf-js": "^1.1.3"
},
"engines": {
"node": ">= 12"
}
},
"node_modules/ip-address/node_modules/sprintf-js": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
"license": "BSD-3-Clause",
"optional": true
},
"node_modules/ip-regex": { "node_modules/ip-regex": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
@ -9541,6 +10033,13 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/is-lambda": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
"integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
"license": "MIT",
"optional": true
},
"node_modules/is-nan": { "node_modules/is-nan": {
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz",
@ -9666,6 +10165,12 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"license": "MIT"
},
"node_modules/isexe": { "node_modules/isexe": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -10868,6 +11373,13 @@
"js-yaml": "bin/js-yaml.js" "js-yaml": "bin/js-yaml.js"
} }
}, },
"node_modules/jsbn": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
"integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
"license": "MIT",
"optional": true
},
"node_modules/jsc-android": { "node_modules/jsc-android": {
"version": "250231.0.0", "version": "250231.0.0",
"resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250231.0.0.tgz", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250231.0.0.tgz",
@ -11055,6 +11567,89 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/knex": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/knex/-/knex-3.1.0.tgz",
"integrity": "sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==",
"license": "MIT",
"dependencies": {
"colorette": "2.0.19",
"commander": "^10.0.0",
"debug": "4.3.4",
"escalade": "^3.1.1",
"esm": "^3.2.25",
"get-package-type": "^0.1.0",
"getopts": "2.3.0",
"interpret": "^2.2.0",
"lodash": "^4.17.21",
"pg-connection-string": "2.6.2",
"rechoir": "^0.8.0",
"resolve-from": "^5.0.0",
"tarn": "^3.0.2",
"tildify": "2.0.0"
},
"bin": {
"knex": "bin/cli.js"
},
"engines": {
"node": ">=16"
},
"peerDependenciesMeta": {
"better-sqlite3": {
"optional": true
},
"mysql": {
"optional": true
},
"mysql2": {
"optional": true
},
"pg": {
"optional": true
},
"pg-native": {
"optional": true
},
"sqlite3": {
"optional": true
},
"tedious": {
"optional": true
}
}
},
"node_modules/knex/node_modules/commander": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"license": "MIT",
"engines": {
"node": ">=14"
}
},
"node_modules/knex/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/knex/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"license": "MIT"
},
"node_modules/leven": { "node_modules/leven": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@ -11511,6 +12106,240 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/make-fetch-happen": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
"integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
"license": "ISC",
"optional": true,
"dependencies": {
"agentkeepalive": "^4.1.3",
"cacache": "^15.2.0",
"http-cache-semantics": "^4.1.0",
"http-proxy-agent": "^4.0.1",
"https-proxy-agent": "^5.0.0",
"is-lambda": "^1.0.1",
"lru-cache": "^6.0.0",
"minipass": "^3.1.3",
"minipass-collect": "^1.0.2",
"minipass-fetch": "^1.3.2",
"minipass-flush": "^1.0.5",
"minipass-pipeline": "^1.2.4",
"negotiator": "^0.6.2",
"promise-retry": "^2.0.1",
"socks-proxy-agent": "^6.0.0",
"ssri": "^8.0.0"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/make-fetch-happen/node_modules/@npmcli/fs": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
"integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"@gar/promisify": "^1.0.1",
"semver": "^7.3.5"
}
},
"node_modules/make-fetch-happen/node_modules/@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 6"
}
},
"node_modules/make-fetch-happen/node_modules/cacache": {
"version": "15.3.0",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
"integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"@npmcli/fs": "^1.0.0",
"@npmcli/move-file": "^1.0.1",
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"glob": "^7.1.4",
"infer-owner": "^1.0.4",
"lru-cache": "^6.0.0",
"minipass": "^3.1.1",
"minipass-collect": "^1.0.2",
"minipass-flush": "^1.0.5",
"minipass-pipeline": "^1.2.2",
"mkdirp": "^1.0.3",
"p-map": "^4.0.0",
"promise-inflight": "^1.0.1",
"rimraf": "^3.0.2",
"ssri": "^8.0.1",
"tar": "^6.0.2",
"unique-filename": "^1.1.1"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/make-fetch-happen/node_modules/fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"license": "ISC",
"optional": true,
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/make-fetch-happen/node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"license": "ISC",
"optional": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/make-fetch-happen/node_modules/http-proxy-agent": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
"integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
"license": "MIT",
"optional": true,
"dependencies": {
"@tootallnate/once": "1",
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/make-fetch-happen/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"license": "ISC",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/make-fetch-happen/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/make-fetch-happen/node_modules/minipass-collect": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
"license": "ISC",
"optional": true,
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/make-fetch-happen/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"license": "MIT",
"optional": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/make-fetch-happen/node_modules/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
"license": "ISC",
"optional": true,
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/make-fetch-happen/node_modules/ssri": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
"integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"minipass": "^3.1.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/make-fetch-happen/node_modules/unique-filename": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
"integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"unique-slug": "^2.0.0"
}
},
"node_modules/make-fetch-happen/node_modules/unique-slug": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
"integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
"license": "ISC",
"optional": true,
"dependencies": {
"imurmurhash": "^0.1.4"
}
},
"node_modules/make-fetch-happen/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC",
"optional": true
},
"node_modules/makeerror": { "node_modules/makeerror": {
"version": "1.0.12", "version": "1.0.12",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
@ -11561,6 +12390,17 @@
"node": ">=0.10" "node": ">=0.10"
} }
}, },
"node_modules/md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
"integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
"license": "MIT",
"dependencies": {
"hash-base": "^3.0.0",
"inherits": "^2.0.1",
"safe-buffer": "^5.1.2"
}
},
"node_modules/memoize-one": { "node_modules/memoize-one": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
@ -11595,9 +12435,9 @@
} }
}, },
"node_modules/metro": { "node_modules/metro": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro/-/metro-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro/-/metro-0.81.3.tgz",
"integrity": "sha512-fqRu4fg8ONW7VfqWFMGgKAcOuMzyoQah2azv9Y3VyFXAmG+AoTU6YIFWqAADESCGVWuWEIvxTJhMf3jxU6jwjA==", "integrity": "sha512-upilFs7z1uLKvdzFYHiVKrGT/uC7h7d53R0g/FaJoQvLfA8jQG2V69jeOcGi4wCsFYvl1zBSZvKxpQb0nA3giQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.24.7", "@babel/code-frame": "^7.24.7",
@ -11618,21 +12458,21 @@
"hermes-parser": "0.25.1", "hermes-parser": "0.25.1",
"image-size": "^1.0.2", "image-size": "^1.0.2",
"invariant": "^2.2.4", "invariant": "^2.2.4",
"jest-worker": "^29.6.3", "jest-worker": "^29.7.0",
"jsc-safe-url": "^0.2.2", "jsc-safe-url": "^0.2.2",
"lodash.throttle": "^4.1.1", "lodash.throttle": "^4.1.1",
"metro-babel-transformer": "0.81.1", "metro-babel-transformer": "0.81.3",
"metro-cache": "0.81.1", "metro-cache": "0.81.3",
"metro-cache-key": "0.81.1", "metro-cache-key": "0.81.3",
"metro-config": "0.81.1", "metro-config": "0.81.3",
"metro-core": "0.81.1", "metro-core": "0.81.3",
"metro-file-map": "0.81.1", "metro-file-map": "0.81.3",
"metro-resolver": "0.81.1", "metro-resolver": "0.81.3",
"metro-runtime": "0.81.1", "metro-runtime": "0.81.3",
"metro-source-map": "0.81.1", "metro-source-map": "0.81.3",
"metro-symbolicate": "0.81.1", "metro-symbolicate": "0.81.3",
"metro-transform-plugins": "0.81.1", "metro-transform-plugins": "0.81.3",
"metro-transform-worker": "0.81.1", "metro-transform-worker": "0.81.3",
"mime-types": "^2.1.27", "mime-types": "^2.1.27",
"nullthrows": "^1.1.1", "nullthrows": "^1.1.1",
"serialize-error": "^2.1.0", "serialize-error": "^2.1.0",
@ -11649,9 +12489,9 @@
} }
}, },
"node_modules/metro-babel-transformer": { "node_modules/metro-babel-transformer": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.81.3.tgz",
"integrity": "sha512-JECKDrQaUnDmj0x/Q/c8c5YwsatVx38Lu+BfCwX9fR8bWipAzkvJocBpq5rOAJRDXRgDcPv2VO4Q4nFYrpYNQg==", "integrity": "sha512-ENqtnPy2mQZFOuKrbqHRcAwZuaYe43X+30xIF0xlkLuMyCvc0CsFzrrSK9EqrQwexhVlqaRALb0GQbBMcE/y8g==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
@ -11679,23 +12519,23 @@
} }
}, },
"node_modules/metro-cache": { "node_modules/metro-cache": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.81.3.tgz",
"integrity": "sha512-Uqcmn6sZ+Y0VJHM88VrG5xCvSeU7RnuvmjPmSOpEcyJJBe02QkfHL05MX2ZyGDTyZdbKCzaX0IijrTe4hN3F0Q==", "integrity": "sha512-6UelMQYjlto/79tTXu0vsTxAX4e+Bkf0tgtDL1BNx3wd68pBg8qKIYpJPaUlOIaNUzFXTBDjYwUverkEW0KAtA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"exponential-backoff": "^3.1.1", "exponential-backoff": "^3.1.1",
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"metro-core": "0.81.1" "metro-core": "0.81.3"
}, },
"engines": { "engines": {
"node": ">=18.18" "node": ">=18.18"
} }
}, },
"node_modules/metro-cache-key": { "node_modules/metro-cache-key": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.81.3.tgz",
"integrity": "sha512-5fDaHR1yTvpaQuwMAeEoZGsVyvjrkw9IFAS7WixSPvaNY5YfleqoJICPc6hbXFJjvwCCpwmIYFkjqzR/qJ6yqA==", "integrity": "sha512-KPsPSRUd6uRva7k7k/DqiiD8td7URQWx0RkX/Cj5+bed5zSXEg/XoQA+b+DmMxS5C7TqP61Fh3XvHx6TQRW82A==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6" "flow-enums-runtime": "^0.0.6"
@ -11705,42 +12545,42 @@
} }
}, },
"node_modules/metro-config": { "node_modules/metro-config": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.81.3.tgz",
"integrity": "sha512-VAAJmxsKIZ+Fz5/z1LVgxa32gE6+2TvrDSSx45g85WoX4EtLmdBGP3DSlpQW3DqFUfNHJCGwMLGXpJnxifd08g==", "integrity": "sha512-WpTaT0iQr5juVY50Y/cyacG2ggZqF38VshEQepT+ovPK8E/xUVxlbO5yxLSXUxxUXX3Hka9r6g64+y2WC6c/xQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"connect": "^3.6.5", "connect": "^3.6.5",
"cosmiconfig": "^5.0.5", "cosmiconfig": "^5.0.5",
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"jest-validate": "^29.6.3", "jest-validate": "^29.7.0",
"metro": "0.81.1", "metro": "0.81.3",
"metro-cache": "0.81.1", "metro-cache": "0.81.3",
"metro-core": "0.81.1", "metro-core": "0.81.3",
"metro-runtime": "0.81.1" "metro-runtime": "0.81.3"
}, },
"engines": { "engines": {
"node": ">=18.18" "node": ">=18.18"
} }
}, },
"node_modules/metro-core": { "node_modules/metro-core": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.81.3.tgz",
"integrity": "sha512-4d2/+02IYqOwJs4dmM0dC8hIZqTzgnx2nzN4GTCaXb3Dhtmi/SJ3v6744zZRnithhN4lxf8TTJSHnQV75M7SSA==", "integrity": "sha512-WZ+qohnpvvSWdPj1VJPUrZz+2ik29M+UUpMU6YrmzQUfDyZ6JYHhzlw5WVBtwpt/+2xTsIyrZ2C1fByT/DsLQA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"lodash.throttle": "^4.1.1", "lodash.throttle": "^4.1.1",
"metro-resolver": "0.81.1" "metro-resolver": "0.81.3"
}, },
"engines": { "engines": {
"node": ">=18.18" "node": ">=18.18"
} }
}, },
"node_modules/metro-file-map": { "node_modules/metro-file-map": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.81.3.tgz",
"integrity": "sha512-aY72H2ujmRfFxcsbyh83JgqFF+uQ4HFN1VhV2FmcfQG4s1bGKf2Vbkk+vtZ1+EswcBwDZFbkpvAjN49oqwGzAA==", "integrity": "sha512-F+t4lnVRoauJxtr9xmI4pWIOE77/vl0IrHDGeJSI9cW6LmuqxkpOlZHTKpbs/hMAo6+KhG2JMJACQDvXDLd/GA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"debug": "^2.2.0", "debug": "^2.2.0",
@ -11748,7 +12588,7 @@
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"graceful-fs": "^4.2.4", "graceful-fs": "^4.2.4",
"invariant": "^2.2.4", "invariant": "^2.2.4",
"jest-worker": "^29.6.3", "jest-worker": "^29.7.0",
"micromatch": "^4.0.4", "micromatch": "^4.0.4",
"nullthrows": "^1.1.1", "nullthrows": "^1.1.1",
"walker": "^1.0.7" "walker": "^1.0.7"
@ -11773,9 +12613,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/metro-minify-terser": { "node_modules/metro-minify-terser": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.81.3.tgz",
"integrity": "sha512-p/Qz3NNh1nebSqMlxlUALAnESo6heQrnvgHtAuxufRPtKvghnVDq9hGGex8H7z7YYLsqe42PWdt4JxTA3mgkvg==", "integrity": "sha512-912AYv3OmwcbUwzCdWbdQRk+RV6kXXluHKlhBdYFD3kr4Ece691rzlofU/Mlt9qZrhHtctD5Q8cFqOEf9Z69bQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
@ -11850,9 +12690,9 @@
} }
}, },
"node_modules/metro-resolver": { "node_modules/metro-resolver": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.81.3.tgz",
"integrity": "sha512-E61t6fxRoYRkl6Zo3iUfCKW4DYfum/bLjcejXBMt1y3I7LFkK84TCR/Rs9OAwsMCY/7GOPB4+CREYZOtCC7CNA==", "integrity": "sha512-XnjENY1c6jcsEfFVIjN/8McUIInCVgGxv5eva+9ZWeCTyiAE/L5HPj2ai/Myb349+6QuSMR0dscTkKCnOwWXdw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6" "flow-enums-runtime": "^0.0.6"
@ -11862,9 +12702,9 @@
} }
}, },
"node_modules/metro-runtime": { "node_modules/metro-runtime": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.81.3.tgz",
"integrity": "sha512-pqu5j5d01rjF85V/K8SDDJ0NR3dRp6bE3z5bKVVb5O2Rx0nbR9KreUxYALQCRCcQHaYySqCg5fYbGKBHC295YQ==", "integrity": "sha512-neuGRMC2pgGKIFPbmbrxW41/SmvL7OX4i1LN+saUY2t1cZfxf9haQHUMCGhO3498uEL2N+ulKRSlQrHt6XwGaw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.25.0", "@babel/runtime": "^7.25.0",
@ -11875,9 +12715,9 @@
} }
}, },
"node_modules/metro-source-map": { "node_modules/metro-source-map": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.81.3.tgz",
"integrity": "sha512-1i8ROpNNiga43F0ZixAXoFE/SS3RqcRDCCslpynb+ytym0VI7pkTH1woAN2HI9pczYtPrp3Nq0AjRpsuY35ieA==", "integrity": "sha512-BHJJurmDQRn3hCbBawh/UHzPz3duMpwpE3ofImO2DoWHYzn6nSg/D4wfCN4y14d9fFLE4e0I+BAOX1HWNP4jsw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/traverse": "^7.25.3", "@babel/traverse": "^7.25.3",
@ -11885,9 +12725,9 @@
"@babel/types": "^7.25.2", "@babel/types": "^7.25.2",
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4", "invariant": "^2.2.4",
"metro-symbolicate": "0.81.1", "metro-symbolicate": "0.81.3",
"nullthrows": "^1.1.1", "nullthrows": "^1.1.1",
"ob1": "0.81.1", "ob1": "0.81.3",
"source-map": "^0.5.6", "source-map": "^0.5.6",
"vlq": "^1.0.0" "vlq": "^1.0.0"
}, },
@ -11905,14 +12745,14 @@
} }
}, },
"node_modules/metro-symbolicate": { "node_modules/metro-symbolicate": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.81.3.tgz",
"integrity": "sha512-Lgk0qjEigtFtsM7C0miXITbcV47E1ZYIfB+m/hCraihiwRWkNUQEPCWvqZmwXKSwVE5mXA0EzQtghAvQSjZDxw==", "integrity": "sha512-LQLT6WopQmIz2SDSVh3Lw7nLzF58HpsrPYqRB7RpRXBYhYmPFIjiGaP8qqtKHXczM/5YAOJzpgt8t/OGZgh6Eg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4", "invariant": "^2.2.4",
"metro-source-map": "0.81.1", "metro-source-map": "0.81.3",
"nullthrows": "^1.1.1", "nullthrows": "^1.1.1",
"source-map": "^0.5.6", "source-map": "^0.5.6",
"vlq": "^1.0.0" "vlq": "^1.0.0"
@ -11934,9 +12774,9 @@
} }
}, },
"node_modules/metro-transform-plugins": { "node_modules/metro-transform-plugins": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.81.3.tgz",
"integrity": "sha512-7L1lI44/CyjIoBaORhY9fVkoNe8hrzgxjSCQ/lQlcfrV31cZb7u0RGOQrKmUX7Bw4FpejrB70ArQ7Mse9mk7+Q==", "integrity": "sha512-4JMUXhBB5y4h3dyA272k7T7+U3+J4fSBcct0Y8Yur9ziZB/dK8fieEQg5ZPfEGsgOGI+54zTzOUqga6AgmZSNg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
@ -11951,9 +12791,9 @@
} }
}, },
"node_modules/metro-transform-worker": { "node_modules/metro-transform-worker": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.81.3.tgz",
"integrity": "sha512-M+2hVT3rEy5K7PBmGDgQNq3Zx53TjScOcO/CieyLnCRFtBGWZiSJ2+bLAXXOKyKa/y3bI3i0owxtyxuPGDwbZg==", "integrity": "sha512-KZqm9sVyBKRygUxRm+yP4DguE9R1EEv28KJhIxghNp5dcdVXBYUPe1xHoc3QVdzD9c3tf8JFzA2FBlKTlwMwNg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
@ -11961,13 +12801,13 @@
"@babel/parser": "^7.25.3", "@babel/parser": "^7.25.3",
"@babel/types": "^7.25.2", "@babel/types": "^7.25.2",
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"metro": "0.81.1", "metro": "0.81.3",
"metro-babel-transformer": "0.81.1", "metro-babel-transformer": "0.81.3",
"metro-cache": "0.81.1", "metro-cache": "0.81.3",
"metro-cache-key": "0.81.1", "metro-cache-key": "0.81.3",
"metro-minify-terser": "0.81.1", "metro-minify-terser": "0.81.3",
"metro-source-map": "0.81.1", "metro-source-map": "0.81.3",
"metro-transform-plugins": "0.81.1", "metro-transform-plugins": "0.81.3",
"nullthrows": "^1.1.1" "nullthrows": "^1.1.1"
}, },
"engines": { "engines": {
@ -12065,6 +12905,25 @@
"url": "https://github.com/sponsors/jonschlinkert" "url": "https://github.com/sponsors/jonschlinkert"
} }
}, },
"node_modules/miller-rabin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
"integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.0.0",
"brorand": "^1.0.1"
},
"bin": {
"miller-rabin": "bin/miller-rabin"
}
},
"node_modules/miller-rabin/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/mime": { "node_modules/mime": {
"version": "1.6.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@ -12120,9 +12979,7 @@
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=10" "node": ">=10"
}, },
@ -12140,6 +12997,18 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
"integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
"license": "ISC"
},
"node_modules/minimalistic-crypto-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
"integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==",
"license": "MIT"
},
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@ -12182,6 +13051,44 @@
"node": ">=16 || 14 >=14.17" "node": ">=16 || 14 >=14.17"
} }
}, },
"node_modules/minipass-fetch": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
"integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
"license": "MIT",
"optional": true,
"dependencies": {
"minipass": "^3.1.0",
"minipass-sized": "^1.0.3",
"minizlib": "^2.0.0"
},
"engines": {
"node": ">=8"
},
"optionalDependencies": {
"encoding": "^0.1.12"
}
},
"node_modules/minipass-fetch/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-fetch/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC",
"optional": true
},
"node_modules/minipass-flush": { "node_modules/minipass-flush": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
@ -12242,6 +13149,39 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/minipass-sized": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
"integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
"license": "ISC",
"optional": true,
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-sized/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-sized/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC",
"optional": true
},
"node_modules/minizlib": { "node_modules/minizlib": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
@ -12289,9 +13229,7 @@
"version": "0.5.3", "version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/mrmime": { "node_modules/mrmime": {
"version": "1.0.1", "version": "1.0.1",
@ -12341,9 +13279,7 @@
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
"integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/natural-compare": { "node_modules/natural-compare": {
"version": "1.4.0", "version": "1.4.0",
@ -12383,9 +13319,7 @@
"version": "3.74.0", "version": "3.74.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz",
"integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==", "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"semver": "^7.3.5" "semver": "^7.3.5"
}, },
@ -12397,9 +13331,7 @@
"version": "7.7.1", "version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
"dev": true,
"license": "ISC", "license": "ISC",
"peer": true,
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
}, },
@ -12407,6 +13339,12 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/node-addon-api": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
"license": "MIT"
},
"node_modules/node-dir": { "node_modules/node-dir": {
"version": "0.1.17", "version": "0.1.17",
"resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz",
@ -12470,18 +13408,222 @@
"node": ">= 6.13.0" "node": ">= 6.13.0"
} }
}, },
"node_modules/node-gyp": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
"integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
"license": "MIT",
"optional": true,
"dependencies": {
"env-paths": "^2.2.0",
"glob": "^7.1.4",
"graceful-fs": "^4.2.6",
"make-fetch-happen": "^9.1.0",
"nopt": "^5.0.0",
"npmlog": "^6.0.0",
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"tar": "^6.1.2",
"which": "^2.0.2"
},
"bin": {
"node-gyp": "bin/node-gyp.js"
},
"engines": {
"node": ">= 10.12.0"
}
},
"node_modules/node-gyp/node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"license": "ISC",
"optional": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/node-gyp/node_modules/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
"license": "ISC",
"optional": true,
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/node-int64": { "node_modules/node-int64": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
"integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/node-libs-browser": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
"integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
"license": "MIT",
"dependencies": {
"assert": "^1.1.1",
"browserify-zlib": "^0.2.0",
"buffer": "^4.3.0",
"console-browserify": "^1.1.0",
"constants-browserify": "^1.0.0",
"crypto-browserify": "^3.11.0",
"domain-browser": "^1.1.1",
"events": "^3.0.0",
"https-browserify": "^1.0.0",
"os-browserify": "^0.3.0",
"path-browserify": "0.0.1",
"process": "^0.11.10",
"punycode": "^1.2.4",
"querystring-es3": "^0.2.0",
"readable-stream": "^2.3.3",
"stream-browserify": "^2.0.1",
"stream-http": "^2.7.2",
"string_decoder": "^1.0.0",
"timers-browserify": "^2.0.4",
"tty-browserify": "0.0.0",
"url": "^0.11.0",
"util": "^0.11.0",
"vm-browserify": "^1.0.1"
}
},
"node_modules/node-libs-browser/node_modules/assert": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz",
"integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==",
"license": "MIT",
"dependencies": {
"object.assign": "^4.1.4",
"util": "^0.10.4"
}
},
"node_modules/node-libs-browser/node_modules/assert/node_modules/util": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
"integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
"license": "MIT",
"dependencies": {
"inherits": "2.0.3"
}
},
"node_modules/node-libs-browser/node_modules/buffer": {
"version": "4.9.2",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
"integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
"license": "MIT",
"dependencies": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4",
"isarray": "^1.0.0"
}
},
"node_modules/node-libs-browser/node_modules/inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
"license": "ISC"
},
"node_modules/node-libs-browser/node_modules/punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
"license": "MIT"
},
"node_modules/node-libs-browser/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/node-libs-browser/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/node-libs-browser/node_modules/stream-browserify": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
"integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
"license": "MIT",
"dependencies": {
"inherits": "~2.0.1",
"readable-stream": "^2.0.2"
}
},
"node_modules/node-libs-browser/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/node-libs-browser/node_modules/tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
"integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==",
"license": "MIT"
},
"node_modules/node-libs-browser/node_modules/util": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
"integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
"license": "MIT",
"dependencies": {
"inherits": "2.0.3"
}
},
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.19", "version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"abbrev": "1"
},
"bin": {
"nopt": "bin/nopt.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/normalize-path": { "node_modules/normalize-path": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -12539,6 +13681,23 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/npmlog": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
"integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"dependencies": {
"are-we-there-yet": "^3.0.0",
"console-control-strings": "^1.1.0",
"gauge": "^4.0.3",
"set-blocking": "^2.0.0"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/nullthrows": { "node_modules/nullthrows": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
@ -12553,9 +13712,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/ob1": { "node_modules/ob1": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/ob1/-/ob1-0.81.1.tgz", "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.81.3.tgz",
"integrity": "sha512-1PEbvI+AFvOcgdNcO79FtDI1TUO8S3lhiKOyAiyWQF3sFDDKS+aw2/BZvGlArFnSmqckwOOB9chQuIX0/OahoQ==", "integrity": "sha512-wd8zdH0DWsn2iDVn2zT/QURihcqoc73K8FhNCmQ16qkJaoYJLNb/N+huOwdCgsbNP8Lk/s1+dPnDETx+RzsrWA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6" "flow-enums-runtime": "^0.0.6"
@ -12573,6 +13732,18 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object-is": { "node_modules/object-is": {
"version": "1.1.6", "version": "1.1.6",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
@ -12785,6 +13956,12 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/os-browserify": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
"integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==",
"license": "MIT"
},
"node_modules/os-tmpdir": { "node_modules/os-tmpdir": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@ -12875,6 +14052,29 @@
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"license": "BlueOak-1.0.0" "license": "BlueOak-1.0.0"
}, },
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
"license": "(MIT AND Zlib)"
},
"node_modules/parse-asn1": {
"version": "5.1.7",
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz",
"integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==",
"license": "ISC",
"dependencies": {
"asn1.js": "^4.10.1",
"browserify-aes": "^1.2.0",
"evp_bytestokey": "^1.0.3",
"hash-base": "~3.0",
"pbkdf2": "^3.1.2",
"safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/parse-json": { "node_modules/parse-json": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
@ -12938,6 +14138,12 @@
"cross-spawn": "^7.0.3" "cross-spawn": "^7.0.3"
} }
}, },
"node_modules/path-browserify": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
"integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
"license": "MIT"
},
"node_modules/path-exists": { "node_modules/path-exists": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -13002,6 +14208,28 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/pbkdf2": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
"integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
"license": "MIT",
"dependencies": {
"create-hash": "^1.1.2",
"create-hmac": "^1.1.4",
"ripemd160": "^2.0.1",
"safe-buffer": "^5.0.1",
"sha.js": "^2.4.8"
},
"engines": {
"node": ">=0.12"
}
},
"node_modules/pg-connection-string": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz",
"integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==",
"license": "MIT"
},
"node_modules/picocolors": { "node_modules/picocolors": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@ -13055,7 +14283,6 @@
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz",
"integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"find-up": "^3.0.0" "find-up": "^3.0.0"
@ -13068,7 +14295,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"locate-path": "^3.0.0" "locate-path": "^3.0.0"
@ -13081,7 +14307,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"p-locate": "^3.0.0", "p-locate": "^3.0.0",
@ -13095,7 +14320,6 @@
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"p-try": "^2.0.0" "p-try": "^2.0.0"
@ -13111,7 +14335,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"p-limit": "^2.0.0" "p-limit": "^2.0.0"
@ -13124,7 +14347,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
"integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=4" "node": ">=4"
@ -13218,9 +14440,7 @@
"version": "7.1.3", "version": "7.1.3",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
"integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"detect-libc": "^2.0.0", "detect-libc": "^2.0.0",
"expand-template": "^2.0.3", "expand-template": "^2.0.3",
@ -13246,9 +14466,7 @@
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
"integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
"dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
@ -13300,6 +14518,21 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0" "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
} }
}, },
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"license": "MIT"
},
"node_modules/progress": { "node_modules/progress": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
@ -13318,6 +14551,27 @@
"asap": "~2.0.3" "asap": "~2.0.3"
} }
}, },
"node_modules/promise-inflight": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
"integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
"license": "ISC",
"optional": true
},
"node_modules/promise-retry": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
"integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
"license": "MIT",
"optional": true,
"dependencies": {
"err-code": "^2.0.2",
"retry": "^0.12.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/prompts": { "node_modules/prompts": {
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
@ -13361,6 +14615,26 @@
"url": "https://github.com/sponsors/lupomontero" "url": "https://github.com/sponsors/lupomontero"
} }
}, },
"node_modules/public-encrypt": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
"integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.1.0",
"browserify-rsa": "^4.0.0",
"create-hash": "^1.1.0",
"parse-asn1": "^5.0.0",
"randombytes": "^2.0.1",
"safe-buffer": "^5.1.2"
}
},
"node_modules/public-encrypt/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/pump": { "node_modules/pump": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
@ -13405,6 +14679,21 @@
"qrcode-terminal": "bin/qrcode-terminal.js" "qrcode-terminal": "bin/qrcode-terminal.js"
} }
}, },
"node_modules/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/query-string": { "node_modules/query-string": {
"version": "7.1.3", "version": "7.1.3",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz",
@ -13423,6 +14712,14 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/querystring-es3": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
"integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==",
"engines": {
"node": ">=0.4.x"
}
},
"node_modules/querystringify": { "node_modules/querystringify": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
@ -13463,13 +14760,21 @@
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"safe-buffer": "^5.1.0" "safe-buffer": "^5.1.0"
} }
}, },
"node_modules/randomfill": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
"integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
"license": "MIT",
"dependencies": {
"randombytes": "^2.0.5",
"safe-buffer": "^5.1.0"
}
},
"node_modules/range-parser": { "node_modules/range-parser": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@ -13601,19 +14906,19 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/react-native": { "node_modules/react-native": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.6.tgz", "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.7.tgz",
"integrity": "sha512-AsRi+ud6v6ADH7ZtSOY42kRB4nbM0KtSu450pGO4pDudl4AEK/AF96ai88snb2/VJJSGGa/49QyJVFXxz/qoFg==", "integrity": "sha512-GPJcQeO3qUi1MvuhsC2DC6tH8gJQ4uc4JWPORrdeuCGFWE3QLsN8/hiChTEvJREHLfQSV61YPI8gIOtAQ8c37g==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@jest/create-cache-key-function": "^29.6.3", "@jest/create-cache-key-function": "^29.6.3",
"@react-native/assets-registry": "0.76.6", "@react-native/assets-registry": "0.76.7",
"@react-native/codegen": "0.76.6", "@react-native/codegen": "0.76.7",
"@react-native/community-cli-plugin": "0.76.6", "@react-native/community-cli-plugin": "0.76.7",
"@react-native/gradle-plugin": "0.76.6", "@react-native/gradle-plugin": "0.76.7",
"@react-native/js-polyfills": "0.76.6", "@react-native/js-polyfills": "0.76.7",
"@react-native/normalize-colors": "0.76.6", "@react-native/normalize-colors": "0.76.7",
"@react-native/virtualized-lists": "0.76.6", "@react-native/virtualized-lists": "0.76.7",
"abort-controller": "^3.0.0", "abort-controller": "^3.0.0",
"anser": "^1.4.9", "anser": "^1.4.9",
"ansi-regex": "^5.0.0", "ansi-regex": "^5.0.0",
@ -13837,34 +15142,6 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/react-native/node_modules/@react-native/codegen": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.76.6.tgz",
"integrity": "sha512-BABb3e5G/+hyQYEYi0AODWh2km2d8ERoASZr6Hv90pVXdUHRYR+yxCatX7vSd9rnDUYndqRTzD0hZWAucPNAKg==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.25.3",
"glob": "^7.1.1",
"hermes-parser": "0.23.1",
"invariant": "^2.2.4",
"jscodeshift": "^0.14.0",
"mkdirp": "^0.5.1",
"nullthrows": "^1.1.1",
"yargs": "^17.6.2"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@babel/preset-env": "^7.1.6"
}
},
"node_modules/react-native/node_modules/@react-native/normalize-colors": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.6.tgz",
"integrity": "sha512-1n4udXH2Cla31iA/8eLRdhFHpYUYK1NKWCn4m1Sr9L4SarWKAYuRFliK1fcLvPPALCFoFlWvn8I0ekdUOHMzDQ==",
"license": "MIT"
},
"node_modules/react-native/node_modules/babel-plugin-syntax-hermes-parser": { "node_modules/react-native/node_modules/babel-plugin-syntax-hermes-parser": {
"version": "0.23.1", "version": "0.23.1",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.23.1.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.23.1.tgz",
@ -13988,19 +15265,43 @@
} }
}, },
"node_modules/readable-stream": { "node_modules/readable-stream": {
"version": "3.6.2", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"inherits": "^2.0.3", "abort-controller": "^3.0.0",
"string_decoder": "^1.1.1", "buffer": "^6.0.3",
"util-deprecate": "^1.0.1" "events": "^3.3.0",
"process": "^0.11.10",
"string_decoder": "^1.3.0"
}, },
"engines": { "engines": {
"node": ">= 6" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/readable-stream/node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
} }
}, },
"node_modules/readline": { "node_modules/readline": {
@ -14033,6 +15334,18 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/rechoir": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
"integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
"license": "MIT",
"dependencies": {
"resolve": "^1.20.0"
},
"engines": {
"node": ">= 10.13.0"
}
},
"node_modules/redent": { "node_modules/redent": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
@ -14184,7 +15497,6 @@
"version": "4.1.8", "version": "4.1.8",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
"integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==", "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/resolve": { "node_modules/resolve": {
@ -14257,6 +15569,16 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/reusify": { "node_modules/reusify": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@ -14304,6 +15626,16 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/ripemd160": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
"integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
"license": "MIT",
"dependencies": {
"hash-base": "^3.0.0",
"inherits": "^2.0.1"
}
},
"node_modules/run-parallel": { "node_modules/run-parallel": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@ -14628,6 +15960,13 @@
"integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==", "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"license": "ISC",
"optional": true
},
"node_modules/set-cookie-parser": { "node_modules/set-cookie-parser": {
"version": "2.7.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
@ -14672,6 +16011,19 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/sha.js": {
"version": "2.4.11",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"license": "(MIT AND BSD-3-Clause)",
"dependencies": {
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
},
"bin": {
"sha.js": "bin.js"
}
},
"node_modules/shallow-clone": { "node_modules/shallow-clone": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
@ -14723,6 +16075,78 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/signal-exit": { "node_modules/signal-exit": {
"version": "3.0.7", "version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@ -14733,7 +16157,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
"dev": true,
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@ -14748,14 +16171,12 @@
"url": "https://feross.org/support" "url": "https://feross.org/support"
} }
], ],
"license": "MIT", "license": "MIT"
"peer": true
}, },
"node_modules/simple-get": { "node_modules/simple-get": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
"dev": true,
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@ -14771,7 +16192,6 @@
} }
], ],
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"decompress-response": "^6.0.0", "decompress-response": "^6.0.0",
"once": "^1.3.1", "once": "^1.3.1",
@ -14849,6 +16269,47 @@
"node": ">=8.0.0" "node": ">=8.0.0"
} }
}, },
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/socks": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz",
"integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"ip-address": "^9.0.5",
"smart-buffer": "^4.2.0"
},
"engines": {
"node": ">= 10.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/socks-proxy-agent": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
"integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"agent-base": "^6.0.2",
"debug": "^4.3.3",
"socks": "^2.6.2"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/source-map": { "node_modules/source-map": {
"version": "0.7.4", "version": "0.7.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
@ -14913,6 +16374,36 @@
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"license": "BSD-3-Clause" "license": "BSD-3-Clause"
}, },
"node_modules/sqlite": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/sqlite/-/sqlite-5.1.1.tgz",
"integrity": "sha512-oBkezXa2hnkfuJwUo44Hl9hS3er+YFtueifoajrgidvqsJRQFpc5fKoAkAor1O5ZnLoa28GBScfHXs8j0K358Q==",
"license": "MIT"
},
"node_modules/sqlite3": {
"version": "5.1.7",
"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz",
"integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==",
"hasInstallScript": true,
"license": "BSD-3-Clause",
"dependencies": {
"bindings": "^1.5.0",
"node-addon-api": "^7.0.0",
"prebuild-install": "^7.1.1",
"tar": "^6.1.11"
},
"optionalDependencies": {
"node-gyp": "8.x"
},
"peerDependencies": {
"node-gyp": "8.x"
},
"peerDependenciesMeta": {
"node-gyp": {
"optional": true
}
}
},
"node_modules/ssri": { "node_modules/ssri": {
"version": "10.0.6", "version": "10.0.6",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz",
@ -15025,6 +16516,30 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/stream-browserify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
"integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
"license": "MIT",
"dependencies": {
"inherits": "~2.0.4",
"readable-stream": "^3.5.0"
}
},
"node_modules/stream-browserify/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/stream-buffers": { "node_modules/stream-buffers": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
@ -15034,6 +16549,49 @@
"node": ">= 0.10.0" "node": ">= 0.10.0"
} }
}, },
"node_modules/stream-http": {
"version": "2.8.3",
"resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
"integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
"license": "MIT",
"dependencies": {
"builtin-status-codes": "^3.0.0",
"inherits": "^2.0.1",
"readable-stream": "^2.3.6",
"to-arraybuffer": "^1.0.0",
"xtend": "^4.0.0"
}
},
"node_modules/stream-http/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/stream-http/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/stream-http/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/stream-slice": { "node_modules/stream-slice": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/stream-slice/-/stream-slice-0.1.2.tgz", "resolved": "https://registry.npmjs.org/stream-slice/-/stream-slice-0.1.2.tgz",
@ -15053,9 +16611,7 @@
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"safe-buffer": "~5.2.0" "safe-buffer": "~5.2.0"
} }
@ -15352,9 +16908,7 @@
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz",
"integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"chownr": "^1.1.1", "chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2", "mkdirp-classic": "^0.5.2",
@ -15366,17 +16920,13 @@
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"dev": true, "license": "ISC"
"license": "ISC",
"peer": true
}, },
"node_modules/tar-stream": { "node_modules/tar-stream": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"bl": "^4.0.3", "bl": "^4.0.3",
"end-of-stream": "^1.4.1", "end-of-stream": "^1.4.1",
@ -15388,6 +16938,20 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/tar-stream/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/tar/node_modules/fs-minipass": { "node_modules/tar/node_modules/fs-minipass": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
@ -15439,6 +17003,15 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/tarn": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz",
"integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/temp": { "node_modules/temp": {
"version": "0.8.4", "version": "0.8.4",
"resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz",
@ -15714,6 +17287,27 @@
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/tildify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz",
"integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/timers-browserify": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
"integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
"license": "MIT",
"dependencies": {
"setimmediate": "^1.0.4"
},
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/tmp": { "node_modules/tmp": {
"version": "0.0.33", "version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@ -15732,6 +17326,12 @@
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
"license": "BSD-3-Clause" "license": "BSD-3-Clause"
}, },
"node_modules/to-arraybuffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
"integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==",
"license": "MIT"
},
"node_modules/to-regex-range": { "node_modules/to-regex-range": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@ -15866,13 +17466,17 @@
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD" "license": "0BSD"
}, },
"node_modules/tty-browserify": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
"integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==",
"license": "MIT"
},
"node_modules/tunnel-agent": { "node_modules/tunnel-agent": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"safe-buffer": "^5.0.1" "safe-buffer": "^5.0.1"
}, },
@ -16103,6 +17707,19 @@
"punycode": "^2.1.0" "punycode": "^2.1.0"
} }
}, },
"node_modules/url": {
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz",
"integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
"license": "MIT",
"dependencies": {
"punycode": "^1.4.1",
"qs": "^6.12.3"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/url-parse": { "node_modules/url-parse": {
"version": "1.5.10", "version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
@ -16114,6 +17731,12 @@
"requires-port": "^1.0.0" "requires-port": "^1.0.0"
} }
}, },
"node_modules/url/node_modules/punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
"license": "MIT"
},
"node_modules/use-latest-callback": { "node_modules/use-latest-callback": {
"version": "0.2.3", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.3.tgz", "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.3.tgz",
@ -16149,9 +17772,7 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/utils-merge": { "node_modules/utils-merge": {
"version": "1.0.1", "version": "1.0.1",
@ -16210,6 +17831,12 @@
"integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/vm-browserify": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
"license": "MIT"
},
"node_modules/w3c-xmlserializer": { "node_modules/w3c-xmlserializer": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
@ -16523,6 +18150,16 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/wide-align": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
"license": "ISC",
"optional": true,
"dependencies": {
"string-width": "^1.0.2 || 2 || 3 || 4"
}
},
"node_modules/wonka": { "node_modules/wonka": {
"version": "6.3.4", "version": "6.3.4",
"resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.4.tgz", "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.4.tgz",
@ -16674,6 +18311,15 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"license": "MIT",
"engines": {
"node": ">=0.4"
}
},
"node_modules/y18n": { "node_modules/y18n": {
"version": "5.0.8", "version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

View File

@ -9,13 +9,15 @@
"updateSnapshots": "jest -u --coverage=false", "updateSnapshots": "jest -u --coverage=false",
"start": "expo start", "start": "expo start",
"reset-project": "node ./scripts/reset-project.js", "reset-project": "node ./scripts/reset-project.js",
"android": "expo prebuild --npm -p android", "prebuild:android": "expo prebuild --npm -p android",
"android": "expo run:android",
"ios": "expo prebuild --npm -p android --offline", "ios": "expo prebuild --npm -p android --offline",
"web": "expo start --offline --web", "web": "expo start --offline --web",
"lint": "expo lint" "lint": "expo lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.26.7", "@babel/runtime": "^7.26.7",
"@expo/knex-expo-sqlite-dialect": "^0.0.1",
"@expo/vector-icons": "^14.0.4", "@expo/vector-icons": "^14.0.4",
"@mmomtchev/react-native-settings": "^1.1.0", "@mmomtchev/react-native-settings": "^1.1.0",
"@react-native-async-storage/async-storage": "^2.1.0", "@react-native-async-storage/async-storage": "^2.1.0",
@ -23,9 +25,11 @@
"@react-navigation/bottom-tabs": "^7.2.0", "@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native-stack": "^7.2.0", "@react-navigation/native-stack": "^7.2.0",
"expo": "~52.0.28", "expo": "~52.0.28",
"expo-audio": "~0.3.4",
"expo-background-fetch": "~13.0.5", "expo-background-fetch": "~13.0.5",
"expo-blur": "~14.0.3", "expo-blur": "~14.0.3",
"expo-constants": "~17.0.6", "expo-constants": "~17.0.6",
"expo-crypto": "~14.0.2",
"expo-device": "~7.0.2", "expo-device": "~7.0.2",
"expo-file-system": "^18.0.10", "expo-file-system": "^18.0.10",
"expo-font": "~13.0.3", "expo-font": "~13.0.3",
@ -36,14 +40,14 @@
"expo-screen-orientation": "~8.0.4", "expo-screen-orientation": "~8.0.4",
"expo-sharing": "^13.0.1", "expo-sharing": "^13.0.1",
"expo-splash-screen": "~0.29.21", "expo-splash-screen": "~0.29.21",
"expo-sqlite": "~15.1.2", "expo-sqlite": "^15.1.2",
"expo-status-bar": "~2.0.1", "expo-status-bar": "~2.0.1",
"expo-symbols": "~0.2.2", "expo-symbols": "~0.2.2",
"expo-system-ui": "~4.0.7", "expo-system-ui": "~4.0.7",
"expo-web-browser": "~14.0.2", "expo-web-browser": "~14.0.2",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-native": "0.76.6", "react-native": "^0.76.7",
"react-native-cache": "^2.0.3", "react-native-cache": "^2.0.3",
"react-native-country-flag": "^2.0.2", "react-native-country-flag": "^2.0.2",
"react-native-gesture-handler": "~2.20.2", "react-native-gesture-handler": "~2.20.2",
@ -54,8 +58,19 @@
"react-native-sqlite-storage": "^6.0.1", "react-native-sqlite-storage": "^6.0.1",
"react-native-web": "~0.19.13", "react-native-web": "~0.19.13",
"react-native-webview": "13.12.5", "react-native-webview": "13.12.5",
"readable-stream": "^4.7.0",
"sqlite": "^5.1.1",
"sqlite3": "^5.1.7",
"whisper.rn": "^0.3.9" "whisper.rn": "^0.3.9"
}, },
"codegenConfig": {
"name": "NativeWhisperEngineSpec",
"type": "modules",
"jsSrcsDir": "specs",
"android": {
"javaPackageName": "com.nativewhisperengine"
}
},
"jest": { "jest": {
"preset": "jest-expo", "preset": "jest-expo",
"testPathIgnorePatterns": [ "testPathIgnorePatterns": [
@ -81,12 +96,14 @@
"@types/react-native-sqlite-storage": "^6.0.5", "@types/react-native-sqlite-storage": "^6.0.5",
"@types/react-navigation": "^3.0.8", "@types/react-navigation": "^3.0.8",
"@types/react-test-renderer": "^18.3.1", "@types/react-test-renderer": "^18.3.1",
"@types/readable-stream": "^4.0.18",
"babel-jest": "^29.7.0", "babel-jest": "^29.7.0",
"babel-plugin-module-resolver": "^5.0.2", "babel-plugin-module-resolver": "^5.0.2",
"expo": "~52.0.28", "expo": "~52.0.28",
"expo-sqlite-mock": "^2.0.1", "expo-sqlite-mock": "^2.0.1",
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-expo": "~52.0.3", "jest-expo": "~52.0.3",
"knex": "^3.1.0",
"metro-react-native-babel-preset": "^0.77.0", "metro-react-native-babel-preset": "^0.77.0",
"react-test-renderer": "18.3.1", "react-test-renderer": "18.3.1",
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",

11
specs/WhisperEngine.ts Normal file
View File

@ -0,0 +1,11 @@
import type {TurboModule} from 'react-native';
import {TurboModuleRegistry} from 'react-native';
export interface Spec extends TurboModule {
loadWhisper(path: string): void;
translate() : void;
}
export default TurboModuleRegistry.getEnforcing<Spec>(
'NativeWhisperEngine',
);

BIN
translation_terrace.db Normal file

Binary file not shown.

1
whisper_android Submodule

Submodule whisper_android added at 08b766af19