diff --git a/iut-expo-starter/asyncStorange/deleteFavoriteCityStorage.ts b/iut-expo-starter/asyncStorange/deleteFavoriteCityStorage.ts
new file mode 100644
index 00000000..1042b0ce
--- /dev/null
+++ b/iut-expo-starter/asyncStorange/deleteFavoriteCityStorage.ts
@@ -0,0 +1,9 @@
+import AsyncStorage from "@react-native-async-storage/async-storage";
+
+export const deleteFavoriteCity = async () => {
+ try {
+ await AsyncStorage.removeItem('favorite_city')
+ } catch(e) {
+ console.log("An error occurred", e);
+ }
+ }
\ No newline at end of file
diff --git a/iut-expo-starter/asyncStorange/getFavoriteCityStorage.ts b/iut-expo-starter/asyncStorange/getFavoriteCityStorage.ts
new file mode 100644
index 00000000..42597553
--- /dev/null
+++ b/iut-expo-starter/asyncStorange/getFavoriteCityStorage.ts
@@ -0,0 +1,12 @@
+import AsyncStorage from '@react-native-async-storage/async-storage';
+import { City } from '../data/stub';
+import {FETCH_FAVORITE_CITY} from '../redux/constants';
+
+export const getFavoriteCityStorage = async () => {
+ try {
+ const cityJson = await AsyncStorage.getItem('favorite_city')
+ return cityJson != null ? JSON.parse(cityJson) : null;
+ } catch(e) {
+ console.log("An error occurred", e);
+ }
+}
\ No newline at end of file
diff --git a/iut-expo-starter/asyncStorange/storeFavoriteCity.ts b/iut-expo-starter/asyncStorange/storeFavoriteCity.ts
new file mode 100644
index 00000000..ebef3420
--- /dev/null
+++ b/iut-expo-starter/asyncStorange/storeFavoriteCity.ts
@@ -0,0 +1,11 @@
+import AsyncStorage from "@react-native-async-storage/async-storage";
+import { City } from "../data/stub";
+
+export const storeFavoriteCity = async (city: City | null) => {
+ try {
+ const cityJson = JSON.stringify(city)
+ await AsyncStorage.setItem('favorite_city', cityJson);
+ } catch (e) {
+ console.log("An error occurred", e);
+ }
+}
\ No newline at end of file
diff --git a/iut-expo-starter/components/VilleCompopo.tsx b/iut-expo-starter/components/VilleCompopo.tsx
index 8b341d25..f200b589 100644
--- a/iut-expo-starter/components/VilleCompopo.tsx
+++ b/iut-expo-starter/components/VilleCompopo.tsx
@@ -1,15 +1,28 @@
-import React, { useState, useSyncExternalStore } from "react";
+import React, { useEffect, useState, useSyncExternalStore } from "react";
import { View, StyleSheet, Text, Button, TouchableHighlight, Image } from "react-native";
+import { useDispatch } from "react-redux";
import { City, FAVORITE_CITY_DATA, getCurrentWeather, Weather } from "../data/stub";
+import { addFavoriteCity } from "../redux/actions/addFavoriteCity";
type VilleProps = {
weather: Weather,
- fav: City
+ fav: City | null
}
export function VilleCompopo(props: VilleProps){
+ const dispatch = useDispatch();
+
+
+ async function changeFavoriteCity(city: City | null, already: boolean) {
+ if (already){
+ city = null
+ }
+ dispatch(addFavoriteCity(city))
+ }
+
+ const isFavorite = props.fav != null && props.weather.city.longitude===props.fav.longitude && props.weather.city.latitude===props.fav.latitude
return (
@@ -19,8 +32,8 @@ export function VilleCompopo(props: VilleProps){
{props.weather.city.latitude} - {props.weather.city.longitude}
{props.weather.temperature}
- FAVORITE_CITY_DATA = this.city}*/>
-
+ changeFavoriteCity(props.weather.city, isFavorite)}>
+
diff --git a/iut-expo-starter/node_modules/.yarn-integrity b/iut-expo-starter/node_modules/.yarn-integrity
index c709f2d3..1f591846 100644
--- a/iut-expo-starter/node_modules/.yarn-integrity
+++ b/iut-expo-starter/node_modules/.yarn-integrity
@@ -7,6 +7,7 @@
"linkedModules": [],
"topLevelPatterns": [
"@babel/core@^7.12.9",
+ "@react-native-async-storage/async-storage@^1.17.12",
"@react-navigation/bottom-tabs@^6.5.4",
"@react-navigation/native@^6.1.3",
"@react-navigation/stack@^6.3.12",
@@ -327,6 +328,7 @@
"@nodelib/fs.walk@^1.2.3": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
"@npmcli/fs@^1.0.0": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
"@npmcli/move-file@^1.0.1": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
+ "@react-native-async-storage/async-storage@^1.17.12": "https://registry.yarnpkg.com/@react-native-async-storage/async-storage/-/async-storage-1.17.12.tgz#a39e4df5b06795ce49b2ca5b7ca9b8faadf8e621",
"@react-native-community/cli-clean@^9.2.1": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-9.2.1.tgz",
"@react-native-community/cli-config@^9.2.1": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-9.2.1.tgz",
"@react-native-community/cli-debugger-ui@^9.0.0": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-9.0.0.tgz",
@@ -1154,6 +1156,7 @@
"is-path-in-cwd@^2.0.0": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
"is-path-inside@^2.1.0": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
"is-path-inside@^3.0.2": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "is-plain-obj@^2.1.0": "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287",
"is-plain-object@^2.0.3": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
"is-plain-object@^2.0.4": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
"is-port-reachable@^2.0.1": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-2.0.1.tgz",
@@ -1296,6 +1299,7 @@
"memory-fs@^0.4.1": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
"memory-fs@^0.5.0": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
"merge-descriptors@1.0.1": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "merge-options@^3.0.4": "https://registry.yarnpkg.com/merge-options/-/merge-options-3.0.4.tgz#84709c2aa2a4b24c1981f66c179fe5565cc6dbb7",
"merge-stream@^2.0.0": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"merge2@^1.3.0": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"merge2@^1.4.1": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/LICENSE b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/LICENSE
new file mode 100644
index 00000000..d9021534
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2015-present, Facebook, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/README.md b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/README.md
new file mode 100644
index 00000000..54f26fa9
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/README.md
@@ -0,0 +1,27 @@
+# React Native Async Storage
+
+An asynchronous, unencrypted, persistent, key-value storage system for React Native.
+
+
+## Supported platforms
+
+- iOS
+- Android
+- [Web](https://github.com/react-native-async-storage/async-storage/releases/tag/v1.9.0)
+- [MacOS](https://github.com/react-native-async-storage/async-storage/releases/tag/v1.8.1)
+- [Windows](https://github.com/react-native-async-storage/async-storage/releases/tag/v1.10.0)
+
+
+## Getting Started
+
+Head over to [documentation](https://react-native-async-storage.github.io/async-storage/docs/install) to learn more.
+
+
+## Contribution
+Pull requests are welcome. Please open an issue first to discuss what you would like to change.
+
+See the [CONTRIBUTING](CONTRIBUTING.md) file for more information.
+
+## License
+
+MIT.
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/RNCAsyncStorage.podspec b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/RNCAsyncStorage.podspec
new file mode 100644
index 00000000..5d74402a
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/RNCAsyncStorage.podspec
@@ -0,0 +1,19 @@
+require 'json'
+
+package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
+
+Pod::Spec.new do |s|
+ s.name = "RNCAsyncStorage"
+ s.version = package['version']
+ s.summary = package['description']
+ s.license = package['license']
+
+ s.authors = package['author']
+ s.homepage = package['homepage']
+ s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.14" }
+
+ s.source = { :git => "https://github.com/react-native-async-storage/async-storage.git", :tag => "v#{s.version}" }
+ s.source_files = "ios/**/*.{h,m}"
+
+ s.dependency 'React-Core'
+end
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/build.gradle b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/build.gradle
new file mode 100644
index 00000000..ff1baa45
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/build.gradle
@@ -0,0 +1,146 @@
+import java.nio.file.Paths
+
+def resolveModulePath(packageName) {
+ def basePath = rootDir.toPath().normalize()
+
+ // Node's module resolution algorithm searches up to the root directory,
+ // after which the base path will be null
+ while (basePath) {
+ def candidatePath = Paths.get(basePath.toString(), 'node_modules', packageName)
+ if (candidatePath.toFile().exists()) {
+ return candidatePath.toString()
+ }
+
+ basePath = basePath.getParent()
+ }
+
+ return null
+}
+
+def safeExtGet(prop, fallback) {
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
+}
+
+def getFlagOrDefault(flagName, defaultValue) {
+ rootProject.hasProperty(flagName) ? rootProject.properties[flagName] == "true" : defaultValue
+}
+
+def getVersionOrDefault(String flagName, String defaultVersion) {
+ rootProject.hasProperty(flagName) ? rootProject.properties[flagName] : defaultVersion
+}
+
+configurations {
+ compileClasspath
+}
+
+buildscript {
+ // kotlin version is dictated by rootProject extension or property in gradle.properties
+ ext.asyncStorageKtVersion = rootProject.ext.has('kotlinVersion')
+ ? rootProject.ext['kotlinVersion']
+ : rootProject.hasProperty('AsyncStorage_kotlinVersion')
+ ? rootProject.properties['AsyncStorage_kotlinVersion']
+ : '1.6.10'
+
+ repositories {
+ mavenCentral()
+ google()
+ }
+ dependencies {
+ def projectExampleDir = Paths.get(project.projectDir.getParent(), "example", "android").toString()
+ def rootProjectDir = rootProject.projectDir.getPath()
+ if (projectExampleDir == rootProjectDir) {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$asyncStorageKtVersion"
+ }
+ }
+}
+
+// AsyncStorage has default size of 6MB.
+// This is a sane limit to protect the user from the app storing too much data in the database.
+// This also protects the database from filling up the disk cache and becoming malformed.
+// If you really need bigger size, please keep in mind the potential consequences.
+long dbSizeInMB = 6L
+def newDbSize = rootProject.properties['AsyncStorage_db_size_in_MB']
+if (newDbSize != null && newDbSize.isLong()) {
+ dbSizeInMB = newDbSize.toLong()
+}
+
+// Instead of reusing AsyncTask thread pool, AsyncStorage can use its own executor
+def useDedicatedExecutor = getFlagOrDefault('AsyncStorage_dedicatedExecutor', false)
+
+// Use next storage implementation
+def useNextStorage = getFlagOrDefault("AsyncStorage_useNextStorage", false)
+
+apply plugin: 'com.android.library'
+if (useNextStorage) {
+ apply plugin: 'kotlin-android'
+ apply plugin: 'kotlin-kapt'
+ apply from: './testresults.gradle'
+}
+
+android {
+ compileSdkVersion safeExtGet('compileSdkVersion', 31)
+ defaultConfig {
+ minSdkVersion safeExtGet('minSdkVersion', 21)
+ targetSdkVersion safeExtGet('targetSdkVersion', 31)
+ buildConfigField "Long", "AsyncStorage_db_size", "${dbSizeInMB}L"
+ buildConfigField "boolean", "AsyncStorage_useDedicatedExecutor", "${useDedicatedExecutor}"
+ buildConfigField "boolean", "AsyncStorage_useNextStorage", "${useNextStorage}"
+ }
+ lintOptions {
+ abortOnError false
+ }
+
+ if (useNextStorage) {
+ testOptions {
+ unitTests {
+ returnDefaultValues = true
+ includeAndroidResources = true
+ }
+ }
+ }
+}
+
+repositories {
+ maven {
+ // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
+ url "${resolveModulePath("react-native")}/android"
+ }
+ google()
+ mavenCentral()
+}
+
+dependencies {
+
+ if (useNextStorage) {
+ def room_version = getVersionOrDefault('AsyncStorage_next_roomVersion', '2.4.2')
+ def coroutines_version = "1.6.0"
+ def coroutinesTest_version = "1.6.0"
+ // if we don't provide explicit dependency on reflection, kotlin plugin
+ // would add one automatically, probably a version that is not compatible with
+ // used kotlin
+ def kotlinReflect_version = project.ext.asyncStorageKtVersion
+ def junit_version = "4.13.2"
+ def robolectric_version = "4.7.3"
+ def truth_version = "1.1.3"
+ def androidxtest_version = "1.4.0"
+ def androidtest_junit_version = "1.1.3"
+
+ implementation "androidx.room:room-runtime:$room_version"
+ implementation "androidx.room:room-ktx:$room_version"
+ implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinReflect_version"
+
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
+ kapt "androidx.room:room-compiler:$room_version"
+
+ testImplementation "junit:junit:$junit_version"
+ testImplementation "androidx.test:runner:$androidxtest_version"
+ testImplementation "androidx.test:rules:$androidxtest_version"
+ testImplementation "androidx.test.ext:junit:$androidtest_junit_version"
+ testImplementation "org.robolectric:robolectric:$robolectric_version"
+ testImplementation "com.google.truth:truth:$truth_version"
+ testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesTest_version"
+ }
+
+ //noinspection GradleDynamicVersion
+ implementation 'com.facebook.react:react-native:+' // From node_modules
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/AndroidManifest.xml b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..7e180bd3
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/AndroidManifest.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncLocalStorageUtil.java b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncLocalStorageUtil.java
new file mode 100644
index 00000000..689901f3
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncLocalStorageUtil.java
@@ -0,0 +1,178 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+package com.reactnativecommunity.asyncstorage;
+
+import javax.annotation.Nullable;
+import java.io.File;
+import java.util.Arrays;
+import java.util.Iterator;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Build;
+import android.text.TextUtils;
+import android.util.Log;
+import com.facebook.react.bridge.ReadableArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import static com.reactnativecommunity.asyncstorage.ReactDatabaseSupplier.KEY_COLUMN;
+import static com.reactnativecommunity.asyncstorage.ReactDatabaseSupplier.TABLE_CATALYST;
+import static com.reactnativecommunity.asyncstorage.ReactDatabaseSupplier.VALUE_COLUMN;
+
+/**
+ * Helper for database operations.
+ */
+public class AsyncLocalStorageUtil {
+
+ /**
+ * Build the String required for an SQL select statement:
+ * WHERE key IN (?, ?, ..., ?)
+ * without 'WHERE' and with selectionCount '?'
+ */
+ /* package */ static String buildKeySelection(int selectionCount) {
+ String[] list = new String[selectionCount];
+ Arrays.fill(list, "?");
+ return KEY_COLUMN + " IN (" + TextUtils.join(", ", list) + ")";
+ }
+
+ /**
+ * Build the String[] arguments needed for an SQL selection, i.e.:
+ * {a, b, c}
+ * to be used in the SQL select statement: WHERE key in (?, ?, ?)
+ */
+ /* package */ static String[] buildKeySelectionArgs(ReadableArray keys, int start, int count) {
+ String[] selectionArgs = new String[count];
+ for (int keyIndex = 0; keyIndex < count; keyIndex++) {
+ selectionArgs[keyIndex] = keys.getString(start + keyIndex);
+ }
+ return selectionArgs;
+ }
+
+ /**
+ * Returns the value of the given key, or null if not found.
+ */
+ public static @Nullable String getItemImpl(SQLiteDatabase db, String key) {
+ String[] columns = {VALUE_COLUMN};
+ String[] selectionArgs = {key};
+
+ Cursor cursor = db.query(
+ TABLE_CATALYST,
+ columns,
+ KEY_COLUMN + "=?",
+ selectionArgs,
+ null,
+ null,
+ null);
+
+ try {
+ if (!cursor.moveToFirst()) {
+ return null;
+ } else {
+ return cursor.getString(0);
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ /**
+ * Sets the value for the key given, returns true if successful, false otherwise.
+ */
+ /* package */ static boolean setItemImpl(SQLiteDatabase db, String key, String value) {
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(KEY_COLUMN, key);
+ contentValues.put(VALUE_COLUMN, value);
+
+ long inserted = db.insertWithOnConflict(
+ TABLE_CATALYST,
+ null,
+ contentValues,
+ SQLiteDatabase.CONFLICT_REPLACE);
+
+ return (-1 != inserted);
+ }
+
+ /**
+ * Does the actual merge of the (key, value) pair with the value stored in the database.
+ * NB: This assumes that a database lock is already in effect!
+ * @return the errorCode of the operation
+ */
+ /* package */ static boolean mergeImpl(SQLiteDatabase db, String key, String value)
+ throws JSONException {
+ String oldValue = getItemImpl(db, key);
+ String newValue;
+
+ if (oldValue == null) {
+ newValue = value;
+ } else {
+ JSONObject oldJSON = new JSONObject(oldValue);
+ JSONObject newJSON = new JSONObject(value);
+ deepMergeInto(oldJSON, newJSON);
+ newValue = oldJSON.toString();
+ }
+
+ return setItemImpl(db, key, newValue);
+ }
+
+ /**
+ * Merges two {@link JSONObject}s. The newJSON object will be merged with the oldJSON object by
+ * either overriding its values, or merging them (if the values of the same key in both objects
+ * are of type {@link JSONObject}). oldJSON will contain the result of this merge.
+ */
+ private static void deepMergeInto(JSONObject oldJSON, JSONObject newJSON)
+ throws JSONException {
+ Iterator> keys = newJSON.keys();
+ while (keys.hasNext()) {
+ String key = (String) keys.next();
+
+ JSONObject newJSONObject = newJSON.optJSONObject(key);
+ JSONObject oldJSONObject = oldJSON.optJSONObject(key);
+ if (newJSONObject != null && oldJSONObject != null) {
+ deepMergeInto(oldJSONObject, newJSONObject);
+ oldJSON.put(key, oldJSONObject);
+ } else {
+ oldJSON.put(key, newJSON.get(key));
+ }
+ }
+ }
+ /**
+ * From Pie and up, Android started to use Write-ahead logging (WAL), instead of journal rollback
+ * for atomic commits and rollbacks.
+ * Basically, WAL does not write directly to the database file, rather to the supporting WAL file.
+ * Because of that, migration to the next storage might not be successful, because the content of
+ * RKStorage might be still in WAL file instead. Committing all data from WAL to db file is called
+ * a "checkpoint" and is done automatically (by default) when the WAL file reaches a threshold
+ * size of 1000 pages.
+ * More here: https://sqlite.org/wal.html
+ *
+ * This helper will force checkpoint on RKStorage, if Next storage file does not exists yet.
+ */
+ public static void verifyAndForceSqliteCheckpoint(Context ctx) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
+ Log.i("AsyncStorage_Next", "SQLite checkpoint not required on this API version.");
+ }
+
+ File nextStorageFile = ctx.getDatabasePath("AsyncStorage");
+ File currentStorageFile = ctx.getDatabasePath(ReactDatabaseSupplier.DATABASE_NAME);
+ boolean isCheckpointRequired = !nextStorageFile.exists() && currentStorageFile.exists();
+ if (!isCheckpointRequired) {
+ Log.i("AsyncStorage_Next", "SQLite checkpoint not required.");
+ return;
+ }
+
+ try {
+ ReactDatabaseSupplier supplier = ReactDatabaseSupplier.getInstance(ctx);
+ supplier.get().rawQuery("PRAGMA wal_checkpoint", null).close();
+ supplier.closeDatabase();
+ Log.i("AsyncStorage_Next", "Forcing SQLite checkpoint successful.");
+ } catch (Exception e) {
+ Log.w("AsyncStorage_Next", "Could not force checkpoint on RKStorage, the Next storage might not migrate the data properly: " + e.getMessage());
+ }
+ }
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageErrorUtil.java b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageErrorUtil.java
new file mode 100644
index 00000000..d74a0f11
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageErrorUtil.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+package com.reactnativecommunity.asyncstorage;
+
+import javax.annotation.Nullable;
+
+import com.facebook.react.bridge.Arguments;
+import com.facebook.react.bridge.WritableMap;
+
+/**
+ * Helper class for database errors.
+ */
+public class AsyncStorageErrorUtil {
+
+ /**
+ * Create Error object to be passed back to the JS callback.
+ */
+ /* package */ static WritableMap getError(@Nullable String key, String errorMessage) {
+ WritableMap errorMap = Arguments.createMap();
+ errorMap.putString("message", errorMessage);
+ if (key != null) {
+ errorMap.putString("key", key);
+ }
+ return errorMap;
+ }
+
+ /* package */ static WritableMap getInvalidKeyError(@Nullable String key) {
+ return getError(key, "Invalid key");
+ }
+
+ /* package */ static WritableMap getInvalidValueError(@Nullable String key) {
+ return getError(key, "Invalid Value");
+ }
+
+ /* package */ static WritableMap getDBError(@Nullable String key) {
+ return getError(key, "Database Error");
+ }
+
+
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageExpoMigration.java b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageExpoMigration.java
new file mode 100644
index 00000000..cd79cc09
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageExpoMigration.java
@@ -0,0 +1,154 @@
+package com.reactnativecommunity.asyncstorage;
+
+import android.content.Context;
+import android.os.Build;
+import android.util.Log;
+
+import androidx.annotation.RequiresApi;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+
+// A utility class that migrates a scoped AsyncStorage database to RKStorage.
+// This utility only runs if the RKStorage file has not been created yet.
+public class AsyncStorageExpoMigration {
+ static final String LOG_TAG = "AsyncStorageExpoMigration";
+
+ public static void migrate(Context context) {
+ // Only migrate if the default async storage file does not exist.
+ if (isAsyncStorageDatabaseCreated(context)) {
+ return;
+ }
+
+ ArrayList expoDatabases = getExpoDatabases(context);
+
+ File expoDatabase = getLastModifiedFile(expoDatabases);
+
+ if (expoDatabase == null) {
+ Log.v(LOG_TAG, "No scoped database found");
+ return;
+ }
+
+ try {
+ // Create the storage file
+ ReactDatabaseSupplier.getInstance(context).get();
+ copyFile(new FileInputStream(expoDatabase), new FileOutputStream(context.getDatabasePath(ReactDatabaseSupplier.DATABASE_NAME)));
+ Log.v(LOG_TAG, "Migrated most recently modified database " + expoDatabase.getName() + " to RKStorage");
+ } catch (Exception e) {
+ Log.v(LOG_TAG, "Failed to migrate scoped database " + expoDatabase.getName());
+ e.printStackTrace();
+ return;
+ }
+
+ try {
+ for (File file : expoDatabases) {
+ if (file.delete()) {
+ Log.v(LOG_TAG, "Deleted scoped database " + file.getName());
+ } else {
+ Log.v(LOG_TAG, "Failed to delete scoped database " + file.getName());
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ Log.v(LOG_TAG, "Completed the scoped AsyncStorage migration");
+ }
+
+ private static boolean isAsyncStorageDatabaseCreated(Context context) {
+ return context.getDatabasePath(ReactDatabaseSupplier.DATABASE_NAME).exists();
+ }
+
+ // Find all database files that the user may have created while using Expo.
+ private static ArrayList getExpoDatabases(Context context) {
+ ArrayList scopedDatabases = new ArrayList<>();
+ try {
+ File databaseDirectory = context.getDatabasePath("noop").getParentFile();
+ File[] directoryListing = databaseDirectory.listFiles();
+ if (directoryListing != null) {
+ for (File child : directoryListing) {
+ // Find all databases matching the Expo scoped key, and skip any database journals.
+ if (child.getName().startsWith("RKStorage-scoped-experience-") && !child.getName().endsWith("-journal")) {
+ scopedDatabases.add(child);
+ }
+ }
+ }
+ } catch (Exception e) {
+ // Just in case anything happens catch and print, file system rules can tend to be different across vendors.
+ e.printStackTrace();
+ }
+ return scopedDatabases;
+ }
+
+ // Returns the most recently modified file.
+ // If a user publishes an app with Expo, then changes the slug
+ // and publishes again, a new database will be created.
+ // We want to select the most recent database and migrate it to RKStorage.
+ private static File getLastModifiedFile(ArrayList files) {
+ if (files.size() == 0) {
+ return null;
+ }
+ long lastMod = -1;
+ File lastModFile = null;
+ for (File child : files) {
+ long modTime = getLastModifiedTimeInMillis(child);
+ if (modTime > lastMod) {
+ lastMod = modTime;
+ lastModFile = child;
+ }
+ }
+ if (lastModFile != null) {
+ return lastModFile;
+ }
+
+ return files.get(0);
+ }
+
+ private static long getLastModifiedTimeInMillis(File file) {
+ try {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ return getLastModifiedTimeFromBasicFileAttrs(file);
+ } else {
+ return file.lastModified();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return -1;
+ }
+ }
+
+ @RequiresApi(Build.VERSION_CODES.O)
+ private static long getLastModifiedTimeFromBasicFileAttrs(File file) {
+ try {
+ return Files.readAttributes(file.toPath(), BasicFileAttributes.class).creationTime().toMillis();
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ private static void copyFile(FileInputStream fromFile, FileOutputStream toFile) throws IOException {
+ FileChannel fromChannel = null;
+ FileChannel toChannel = null;
+ try {
+ fromChannel = fromFile.getChannel();
+ toChannel = toFile.getChannel();
+ fromChannel.transferTo(0, fromChannel.size(), toChannel);
+ } finally {
+ try {
+ if (fromChannel != null) {
+ fromChannel.close();
+ }
+ } finally {
+ if (toChannel != null) {
+ toChannel.close();
+ }
+ }
+ }
+ }
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java
new file mode 100644
index 00000000..906008e2
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java
@@ -0,0 +1,424 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+package com.reactnativecommunity.asyncstorage;
+
+import android.database.Cursor;
+import android.database.sqlite.SQLiteStatement;
+import android.os.AsyncTask;
+
+import com.facebook.common.logging.FLog;
+import com.facebook.react.bridge.Arguments;
+import com.facebook.react.bridge.Callback;
+import com.facebook.react.bridge.GuardedAsyncTask;
+import com.facebook.react.bridge.LifecycleEventListener;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.ReactContextBaseJavaModule;
+import com.facebook.react.bridge.ReactMethod;
+import com.facebook.react.bridge.ReadableArray;
+import com.facebook.react.bridge.WritableArray;
+import com.facebook.react.bridge.WritableMap;
+import com.facebook.react.common.ReactConstants;
+import com.facebook.react.common.annotations.VisibleForTesting;
+import com.facebook.react.module.annotations.ReactModule;
+import com.facebook.react.modules.common.ModuleDataCleaner;
+
+import java.util.ArrayDeque;
+import java.util.HashSet;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+@ReactModule(name = AsyncStorageModule.NAME)
+public final class AsyncStorageModule
+ extends ReactContextBaseJavaModule implements ModuleDataCleaner.Cleanable, LifecycleEventListener {
+
+ // changed name to not conflict with AsyncStorage from RN repo
+ public static final String NAME = "RNC_AsyncSQLiteDBStorage";
+
+ // SQL variable number limit, defined by SQLITE_LIMIT_VARIABLE_NUMBER:
+ // https://raw.githubusercontent.com/android/platform_external_sqlite/master/dist/sqlite3.c
+ private static final int MAX_SQL_KEYS = 999;
+
+ private ReactDatabaseSupplier mReactDatabaseSupplier;
+ private boolean mShuttingDown = false;
+
+ private final SerialExecutor executor;
+
+ public AsyncStorageModule(ReactApplicationContext reactContext) {
+ this(
+ reactContext,
+ BuildConfig.AsyncStorage_useDedicatedExecutor
+ ? Executors.newSingleThreadExecutor()
+ : AsyncTask.THREAD_POOL_EXECUTOR
+ );
+ }
+
+ @VisibleForTesting
+ AsyncStorageModule(ReactApplicationContext reactContext, Executor executor) {
+ super(reactContext);
+ // The migration MUST run before the AsyncStorage database is created for the first time.
+ AsyncStorageExpoMigration.migrate(reactContext);
+
+ this.executor = new SerialExecutor(executor);
+ reactContext.addLifecycleEventListener(this);
+ // Creating the database MUST happen after the migration.
+ mReactDatabaseSupplier = ReactDatabaseSupplier.getInstance(reactContext);
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public void initialize() {
+ super.initialize();
+ mShuttingDown = false;
+ }
+
+ @Override
+ public void onCatalystInstanceDestroy() {
+ mShuttingDown = true;
+ }
+
+ @Override
+ public void clearSensitiveData() {
+ // Clear local storage. If fails, crash, since the app is potentially in a bad state and could
+ // cause a privacy violation. We're still not recovering from this well, but at least the error
+ // will be reported to the server.
+ mReactDatabaseSupplier.clearAndCloseDatabase();
+ }
+
+ @Override
+ public void onHostResume() {}
+
+ @Override
+ public void onHostPause() {}
+
+ @Override
+ public void onHostDestroy() {
+ // ensure we close database when activity is destroyed
+ mReactDatabaseSupplier.closeDatabase();
+ }
+
+ /**
+ * Given an array of keys, this returns a map of (key, value) pairs for the keys found, and
+ * (key, null) for the keys that haven't been found.
+ */
+ @ReactMethod
+ public void multiGet(final ReadableArray keys, final Callback callback) {
+ if (keys == null) {
+ callback.invoke(AsyncStorageErrorUtil.getInvalidKeyError(null), null);
+ return;
+ }
+
+ new GuardedAsyncTask(getReactApplicationContext()) {
+ @Override
+ protected void doInBackgroundGuarded(Void... params) {
+ if (!ensureDatabase()) {
+ callback.invoke(AsyncStorageErrorUtil.getDBError(null), null);
+ return;
+ }
+
+ String[] columns = {ReactDatabaseSupplier.KEY_COLUMN, ReactDatabaseSupplier.VALUE_COLUMN};
+ HashSet keysRemaining = new HashSet<>();
+ WritableArray data = Arguments.createArray();
+ for (int keyStart = 0; keyStart < keys.size(); keyStart += MAX_SQL_KEYS) {
+ int keyCount = Math.min(keys.size() - keyStart, MAX_SQL_KEYS);
+ Cursor cursor = mReactDatabaseSupplier.get().query(
+ ReactDatabaseSupplier.TABLE_CATALYST,
+ columns,
+ AsyncLocalStorageUtil.buildKeySelection(keyCount),
+ AsyncLocalStorageUtil.buildKeySelectionArgs(keys, keyStart, keyCount),
+ null,
+ null,
+ null);
+ keysRemaining.clear();
+ try {
+ if (cursor.getCount() != keys.size()) {
+ // some keys have not been found - insert them with null into the final array
+ for (int keyIndex = keyStart; keyIndex < keyStart + keyCount; keyIndex++) {
+ keysRemaining.add(keys.getString(keyIndex));
+ }
+ }
+
+ if (cursor.moveToFirst()) {
+ do {
+ WritableArray row = Arguments.createArray();
+ row.pushString(cursor.getString(0));
+ row.pushString(cursor.getString(1));
+ data.pushArray(row);
+ keysRemaining.remove(cursor.getString(0));
+ } while (cursor.moveToNext());
+ }
+ } catch (Exception e) {
+ FLog.w(ReactConstants.TAG, e.getMessage(), e);
+ callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage()), null);
+ return;
+ } finally {
+ cursor.close();
+ }
+
+ for (String key : keysRemaining) {
+ WritableArray row = Arguments.createArray();
+ row.pushString(key);
+ row.pushNull();
+ data.pushArray(row);
+ }
+ keysRemaining.clear();
+ }
+
+ callback.invoke(null, data);
+ }
+ }.executeOnExecutor(executor);
+ }
+
+ /**
+ * Inserts multiple (key, value) pairs. If one or more of the pairs cannot be inserted, this will
+ * return AsyncLocalStorageFailure, but all other pairs will have been inserted.
+ * The insertion will replace conflicting (key, value) pairs.
+ */
+ @ReactMethod
+ public void multiSet(final ReadableArray keyValueArray, final Callback callback) {
+ if (keyValueArray.size() == 0) {
+ callback.invoke();
+ return;
+ }
+
+ new GuardedAsyncTask(getReactApplicationContext()) {
+ @Override
+ protected void doInBackgroundGuarded(Void... params) {
+ if (!ensureDatabase()) {
+ callback.invoke(AsyncStorageErrorUtil.getDBError(null));
+ return;
+ }
+
+ String sql = "INSERT OR REPLACE INTO " + ReactDatabaseSupplier.TABLE_CATALYST + " VALUES (?, ?);";
+ SQLiteStatement statement = mReactDatabaseSupplier.get().compileStatement(sql);
+ WritableMap error = null;
+ try {
+ mReactDatabaseSupplier.get().beginTransaction();
+ for (int idx=0; idx < keyValueArray.size(); idx++) {
+ if (keyValueArray.getArray(idx).size() != 2) {
+ error = AsyncStorageErrorUtil.getInvalidValueError(null);
+ return;
+ }
+ if (keyValueArray.getArray(idx).getString(0) == null) {
+ error = AsyncStorageErrorUtil.getInvalidKeyError(null);
+ return;
+ }
+ if (keyValueArray.getArray(idx).getString(1) == null) {
+ error = AsyncStorageErrorUtil.getInvalidValueError(null);
+ return;
+ }
+
+ statement.clearBindings();
+ statement.bindString(1, keyValueArray.getArray(idx).getString(0));
+ statement.bindString(2, keyValueArray.getArray(idx).getString(1));
+ statement.execute();
+ }
+ mReactDatabaseSupplier.get().setTransactionSuccessful();
+ } catch (Exception e) {
+ FLog.w(ReactConstants.TAG, e.getMessage(), e);
+ error = AsyncStorageErrorUtil.getError(null, e.getMessage());
+ } finally {
+ try {
+ mReactDatabaseSupplier.get().endTransaction();
+ } catch (Exception e) {
+ FLog.w(ReactConstants.TAG, e.getMessage(), e);
+ if (error == null) {
+ error = AsyncStorageErrorUtil.getError(null, e.getMessage());
+ }
+ }
+ }
+ if (error != null) {
+ callback.invoke(error);
+ } else {
+ callback.invoke();
+ }
+ }
+ }.executeOnExecutor(executor);
+ }
+
+ /**
+ * Removes all rows of the keys given.
+ */
+ @ReactMethod
+ public void multiRemove(final ReadableArray keys, final Callback callback) {
+ if (keys.size() == 0) {
+ callback.invoke();
+ return;
+ }
+
+ new GuardedAsyncTask(getReactApplicationContext()) {
+ @Override
+ protected void doInBackgroundGuarded(Void... params) {
+ if (!ensureDatabase()) {
+ callback.invoke(AsyncStorageErrorUtil.getDBError(null));
+ return;
+ }
+
+ WritableMap error = null;
+ try {
+ mReactDatabaseSupplier.get().beginTransaction();
+ for (int keyStart = 0; keyStart < keys.size(); keyStart += MAX_SQL_KEYS) {
+ int keyCount = Math.min(keys.size() - keyStart, MAX_SQL_KEYS);
+ mReactDatabaseSupplier.get().delete(
+ ReactDatabaseSupplier.TABLE_CATALYST,
+ AsyncLocalStorageUtil.buildKeySelection(keyCount),
+ AsyncLocalStorageUtil.buildKeySelectionArgs(keys, keyStart, keyCount));
+ }
+ mReactDatabaseSupplier.get().setTransactionSuccessful();
+ } catch (Exception e) {
+ FLog.w(ReactConstants.TAG, e.getMessage(), e);
+ error = AsyncStorageErrorUtil.getError(null, e.getMessage());
+ } finally {
+ try {
+ mReactDatabaseSupplier.get().endTransaction();
+ } catch (Exception e) {
+ FLog.w(ReactConstants.TAG, e.getMessage(), e);
+ if (error == null) {
+ error = AsyncStorageErrorUtil.getError(null, e.getMessage());
+ }
+ }
+ }
+ if (error != null) {
+ callback.invoke(error);
+ } else {
+ callback.invoke();
+ }
+ }
+ }.executeOnExecutor(executor);
+ }
+
+ /**
+ * Given an array of (key, value) pairs, this will merge the given values with the stored values
+ * of the given keys, if they exist.
+ */
+ @ReactMethod
+ public void multiMerge(final ReadableArray keyValueArray, final Callback callback) {
+ new GuardedAsyncTask(getReactApplicationContext()) {
+ @Override
+ protected void doInBackgroundGuarded(Void... params) {
+ if (!ensureDatabase()) {
+ callback.invoke(AsyncStorageErrorUtil.getDBError(null));
+ return;
+ }
+ WritableMap error = null;
+ try {
+ mReactDatabaseSupplier.get().beginTransaction();
+ for (int idx = 0; idx < keyValueArray.size(); idx++) {
+ if (keyValueArray.getArray(idx).size() != 2) {
+ error = AsyncStorageErrorUtil.getInvalidValueError(null);
+ return;
+ }
+
+ if (keyValueArray.getArray(idx).getString(0) == null) {
+ error = AsyncStorageErrorUtil.getInvalidKeyError(null);
+ return;
+ }
+
+ if (keyValueArray.getArray(idx).getString(1) == null) {
+ error = AsyncStorageErrorUtil.getInvalidValueError(null);
+ return;
+ }
+
+ if (!AsyncLocalStorageUtil.mergeImpl(
+ mReactDatabaseSupplier.get(),
+ keyValueArray.getArray(idx).getString(0),
+ keyValueArray.getArray(idx).getString(1))) {
+ error = AsyncStorageErrorUtil.getDBError(null);
+ return;
+ }
+ }
+ mReactDatabaseSupplier.get().setTransactionSuccessful();
+ } catch (Exception e) {
+ FLog.w(ReactConstants.TAG, e.getMessage(), e);
+ error = AsyncStorageErrorUtil.getError(null, e.getMessage());
+ } finally {
+ try {
+ mReactDatabaseSupplier.get().endTransaction();
+ } catch (Exception e) {
+ FLog.w(ReactConstants.TAG, e.getMessage(), e);
+ if (error == null) {
+ error = AsyncStorageErrorUtil.getError(null, e.getMessage());
+ }
+ }
+ }
+ if (error != null) {
+ callback.invoke(error);
+ } else {
+ callback.invoke();
+ }
+ }
+ }.executeOnExecutor(executor);
+ }
+
+ /**
+ * Clears the database.
+ */
+ @ReactMethod
+ public void clear(final Callback callback) {
+ new GuardedAsyncTask(getReactApplicationContext()) {
+ @Override
+ protected void doInBackgroundGuarded(Void... params) {
+ if (!mReactDatabaseSupplier.ensureDatabase()) {
+ callback.invoke(AsyncStorageErrorUtil.getDBError(null));
+ return;
+ }
+ try {
+ mReactDatabaseSupplier.clear();
+ callback.invoke();
+ } catch (Exception e) {
+ FLog.w(ReactConstants.TAG, e.getMessage(), e);
+ callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage()));
+ }
+ }
+ }.executeOnExecutor(executor);
+ }
+
+ /**
+ * Returns an array with all keys from the database.
+ */
+ @ReactMethod
+ public void getAllKeys(final Callback callback) {
+ new GuardedAsyncTask(getReactApplicationContext()) {
+ @Override
+ protected void doInBackgroundGuarded(Void... params) {
+ if (!ensureDatabase()) {
+ callback.invoke(AsyncStorageErrorUtil.getDBError(null), null);
+ return;
+ }
+ WritableArray data = Arguments.createArray();
+ String[] columns = {ReactDatabaseSupplier.KEY_COLUMN};
+ Cursor cursor = mReactDatabaseSupplier.get()
+ .query(ReactDatabaseSupplier.TABLE_CATALYST, columns, null, null, null, null, null);
+ try {
+ if (cursor.moveToFirst()) {
+ do {
+ data.pushString(cursor.getString(0));
+ } while (cursor.moveToNext());
+ }
+ } catch (Exception e) {
+ FLog.w(ReactConstants.TAG, e.getMessage(), e);
+ callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage()), null);
+ return;
+ } finally {
+ cursor.close();
+ }
+ callback.invoke(null, data);
+ }
+ }.executeOnExecutor(executor);
+ }
+
+ /**
+ * Verify the database is open for reads and writes.
+ */
+ private boolean ensureDatabase() {
+ return !mShuttingDown && mReactDatabaseSupplier.ensureDatabase();
+ }
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.java b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.java
new file mode 100644
index 00000000..28a78408
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+package com.reactnativecommunity.asyncstorage;
+
+import android.util.Log;
+import com.facebook.react.ReactPackage;
+import com.facebook.react.bridge.JavaScriptModule;
+import com.facebook.react.bridge.NativeModule;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.ReactContext;
+import com.facebook.react.uimanager.ViewManager;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class AsyncStoragePackage implements ReactPackage {
+ @Override
+ public List createNativeModules(ReactApplicationContext reactContext) {
+
+ List moduleList = new ArrayList<>(1);
+
+ if (BuildConfig.AsyncStorage_useNextStorage) {
+ try {
+ Class storageClass = Class.forName("com.reactnativecommunity.asyncstorage.next.StorageModule");
+ NativeModule inst = (NativeModule) storageClass.getDeclaredConstructor(new Class[]{ReactContext.class}).newInstance(reactContext);
+ moduleList.add(inst);
+ AsyncLocalStorageUtil.verifyAndForceSqliteCheckpoint(reactContext);
+ } catch (Exception e) {
+ String message = "Something went wrong when initializing module:"
+ + "\n"
+ + e.getCause().getClass()
+ + "\n"
+ + "Cause:" + e.getCause().getLocalizedMessage();
+ Log.e("AsyncStorage_Next", message);
+ }
+ } else {
+ moduleList.add(new AsyncStorageModule(reactContext));
+ }
+
+ return moduleList;
+ }
+
+ // Deprecated in RN 0.47
+ public List> createJSModules() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public List createViewManagers(ReactApplicationContext reactContext) {
+ return Collections.emptyList();
+ }
+}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java
new file mode 100644
index 00000000..c7c59b0e
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+package com.reactnativecommunity.asyncstorage;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteOpenHelper;
+import com.facebook.common.logging.FLog;
+import com.facebook.react.common.ReactConstants;
+import javax.annotation.Nullable;
+
+/**
+ * Database supplier of the database used by react native. This creates, opens and deletes the
+ * database as necessary.
+ */
+public class ReactDatabaseSupplier extends SQLiteOpenHelper {
+
+ // VisibleForTesting
+ public static final String DATABASE_NAME = "RKStorage";
+
+ private static final int DATABASE_VERSION = 1;
+ private static final int SLEEP_TIME_MS = 30;
+
+ static final String TABLE_CATALYST = "catalystLocalStorage";
+ static final String KEY_COLUMN = "key";
+ static final String VALUE_COLUMN = "value";
+
+ static final String VERSION_TABLE_CREATE =
+ "CREATE TABLE " + TABLE_CATALYST + " (" +
+ KEY_COLUMN + " TEXT PRIMARY KEY, " +
+ VALUE_COLUMN + " TEXT NOT NULL" +
+ ")";
+
+ private static @Nullable ReactDatabaseSupplier sReactDatabaseSupplierInstance;
+
+ private Context mContext;
+ private @Nullable SQLiteDatabase mDb;
+ private long mMaximumDatabaseSize = BuildConfig.AsyncStorage_db_size * 1024L * 1024L;
+
+ private ReactDatabaseSupplier(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ mContext = context;
+ }
+
+ public static ReactDatabaseSupplier getInstance(Context context) {
+ if (sReactDatabaseSupplierInstance == null) {
+ sReactDatabaseSupplierInstance = new ReactDatabaseSupplier(context.getApplicationContext());
+ }
+ return sReactDatabaseSupplierInstance;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(VERSION_TABLE_CREATE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ if (oldVersion != newVersion) {
+ deleteDatabase();
+ onCreate(db);
+ }
+ }
+
+ /**
+ * Verify the database exists and is open.
+ */
+ /* package */ synchronized boolean ensureDatabase() {
+ if (mDb != null && mDb.isOpen()) {
+ return true;
+ }
+ // Sometimes retrieving the database fails. We do 2 retries: first without database deletion
+ // and then with deletion.
+ SQLiteException lastSQLiteException = null;
+ for (int tries = 0; tries < 2; tries++) {
+ try {
+ if (tries > 0) {
+ deleteDatabase();
+ }
+ mDb = getWritableDatabase();
+ break;
+ } catch (SQLiteException e) {
+ lastSQLiteException = e;
+ }
+ // Wait before retrying.
+ try {
+ Thread.sleep(SLEEP_TIME_MS);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ if (mDb == null) {
+ throw lastSQLiteException;
+ }
+ // This is a sane limit to protect the user from the app storing too much data in the database.
+ // This also protects the database from filling up the disk cache and becoming malformed
+ // (endTransaction() calls will throw an exception, not rollback, and leave the db malformed).
+ mDb.setMaximumSize(mMaximumDatabaseSize);
+ return true;
+ }
+
+ /**
+ * Create and/or open the database.
+ */
+ public synchronized SQLiteDatabase get() {
+ ensureDatabase();
+ return mDb;
+ }
+
+ public synchronized void clearAndCloseDatabase() throws RuntimeException {
+ try {
+ clear();
+ closeDatabase();
+ FLog.d(ReactConstants.TAG, "Cleaned " + DATABASE_NAME);
+ } catch (Exception e) {
+ // Clearing the database has failed, delete it instead.
+ if (deleteDatabase()) {
+ FLog.d(ReactConstants.TAG, "Deleted Local Database " + DATABASE_NAME);
+ return;
+ }
+ // Everything failed, throw
+ throw new RuntimeException("Clearing and deleting database " + DATABASE_NAME + " failed");
+ }
+ }
+
+ /* package */ synchronized void clear() {
+ get().delete(TABLE_CATALYST, null, null);
+ }
+
+ /**
+ * Sets the maximum size the database will grow to. The maximum size cannot
+ * be set below the current size.
+ */
+ public synchronized void setMaximumSize(long size) {
+ mMaximumDatabaseSize = size;
+ if (mDb != null) {
+ mDb.setMaximumSize(mMaximumDatabaseSize);
+ }
+ }
+
+ private synchronized boolean deleteDatabase() {
+ closeDatabase();
+ return mContext.deleteDatabase(DATABASE_NAME);
+ }
+
+ public synchronized void closeDatabase() {
+ if (mDb != null && mDb.isOpen()) {
+ mDb.close();
+ mDb = null;
+ }
+ }
+
+ // For testing purposes only!
+ public static void deleteInstance() {
+ sReactDatabaseSupplierInstance = null;
+ }
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/SerialExecutor.java b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/SerialExecutor.java
new file mode 100644
index 00000000..bf46c1e7
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/SerialExecutor.java
@@ -0,0 +1,40 @@
+package com.reactnativecommunity.asyncstorage;
+
+import java.util.ArrayDeque;
+import java.util.concurrent.Executor;
+
+/**
+ * Detox is using this implementation detail in its environment setup,
+ * so in order for Next storage to work, this class has been made public
+ *
+ * Adapted from https://android.googlesource.com/platform/frameworks/base.git/+/1488a3a19d4681a41fb45570c15e14d99db1cb66/core/java/android/os/AsyncTask.java#237
+ */
+public class SerialExecutor implements Executor {
+ private final ArrayDeque mTasks = new ArrayDeque();
+ private Runnable mActive;
+ private final Executor executor;
+
+ public SerialExecutor(Executor executor) {
+ this.executor = executor;
+ }
+
+ public synchronized void execute(final Runnable r) {
+ mTasks.offer(new Runnable() {
+ public void run() {
+ try {
+ r.run();
+ } finally {
+ scheduleNext();
+ }
+ }
+ });
+ if (mActive == null) {
+ scheduleNext();
+ }
+ }
+ synchronized void scheduleNext() {
+ if ((mActive = mTasks.poll()) != null) {
+ executor.execute(mActive);
+ }
+ }
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpers.kt b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpers.kt
new file mode 100644
index 00000000..bb613774
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpers.kt
@@ -0,0 +1,86 @@
+package com.reactnativecommunity.asyncstorage.next
+
+import com.facebook.react.bridge.Arguments
+import com.facebook.react.bridge.ReadableArray
+import org.json.JSONException
+import org.json.JSONObject
+
+fun ReadableArray.toEntryList(): List {
+ val list = mutableListOf()
+ for (keyValue in this.toArrayList()) {
+ if (keyValue !is ArrayList<*> || keyValue.size != 2) {
+ throw AsyncStorageError.invalidKeyValueFormat()
+ }
+ val key = keyValue[0]
+ val value = keyValue[1]
+
+ if (key !is String) {
+ when (key) {
+ null -> throw AsyncStorageError.keyIsNull()
+ else -> throw AsyncStorageError.keyNotString()
+ }
+ }
+
+ if (value !is String) {
+ throw AsyncStorageError.valueNotString(key)
+ }
+
+ list.add(Entry(key, value))
+ }
+ return list
+}
+
+fun ReadableArray.toKeyList(): List {
+ val list = this.toArrayList()
+
+ for (item in list) {
+ if (item !is String) {
+ throw AsyncStorageError.keyNotString()
+ }
+ }
+ return list as List
+}
+
+fun List.toKeyValueArgument(): ReadableArray {
+ val args = Arguments.createArray()
+
+ for (entry in this) {
+ val keyValue = Arguments.createArray()
+ keyValue.pushString(entry.key)
+ keyValue.pushString(entry.value)
+ args.pushArray(keyValue)
+ }
+
+ return args
+}
+
+fun String?.isValidJson(): Boolean {
+ if (this == null) return false
+
+ return try {
+ JSONObject(this)
+ true
+ } catch (e: JSONException) {
+ false
+ }
+}
+
+fun JSONObject.mergeWith(newObject: JSONObject): JSONObject {
+
+ val keys = newObject.keys()
+ val mergedObject = JSONObject(this.toString())
+
+ while (keys.hasNext()) {
+ val key = keys.next()
+ val curValue = this.optJSONObject(key)
+ val newValue = newObject.optJSONObject(key)
+
+ if (curValue != null && newValue != null) {
+ val merged = curValue.mergeWith(newValue)
+ mergedObject.put(key, merged)
+ } else {
+ mergedObject.put(key, newObject.get(key))
+ }
+ }
+ return mergedObject
+}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ErrorHelpers.kt b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ErrorHelpers.kt
new file mode 100644
index 00000000..59549b37
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ErrorHelpers.kt
@@ -0,0 +1,39 @@
+package com.reactnativecommunity.asyncstorage.next
+
+import com.facebook.react.bridge.Arguments
+import com.facebook.react.bridge.Callback
+import kotlinx.coroutines.CoroutineExceptionHandler
+
+internal fun createExceptionHandler(cb: Callback): CoroutineExceptionHandler {
+ return CoroutineExceptionHandler { _, throwable ->
+ val error = Arguments.createMap()
+ if (throwable !is AsyncStorageError) {
+ error.putString(
+ "message", "Unexpected AsyncStorage error: ${throwable.localizedMessage}"
+ )
+ } else {
+ error.putString("message", throwable.errorMessage)
+ }
+
+ cb(error)
+ }
+}
+
+internal class AsyncStorageError private constructor(val errorMessage: String) :
+ Throwable(errorMessage) {
+
+ companion object {
+ fun keyIsNull() = AsyncStorageError("Key cannot be null.")
+
+ fun keyNotString() = AsyncStorageError("Provided key is not string. Only strings are supported as storage key.")
+
+ fun valueNotString(key: String?): AsyncStorageError {
+ val detail = if (key == null) "Provided value" else "Value for key \"$key\""
+ return AsyncStorageError("$detail is not a string. Only strings are supported as a value.")
+ }
+
+ fun invalidKeyValueFormat() =
+ AsyncStorageError("Invalid key-value format. Expected a list of [key, value] list.")
+
+ }
+}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageModule.kt b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageModule.kt
new file mode 100644
index 00000000..ade13167
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageModule.kt
@@ -0,0 +1,90 @@
+package com.reactnativecommunity.asyncstorage.next
+
+import android.content.Context
+import androidx.annotation.VisibleForTesting
+import com.facebook.react.bridge.Arguments
+import com.facebook.react.bridge.Callback
+import com.facebook.react.bridge.ReactContext
+import com.facebook.react.bridge.ReactContextBaseJavaModule
+import com.facebook.react.bridge.ReactMethod
+import com.facebook.react.bridge.ReadableArray
+import com.reactnativecommunity.asyncstorage.SerialExecutor
+import kotlinx.coroutines.CoroutineName
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.asExecutor
+import kotlinx.coroutines.launch
+
+class StorageModule(reactContext: ReactContext) : ReactContextBaseJavaModule(), CoroutineScope {
+ override fun getName() = "RNC_AsyncSQLiteDBStorage"
+
+ // this executor is not used by the module, but it must exists here due to
+ // Detox relying on this implementation detail to run
+ @VisibleForTesting
+ private val executor = SerialExecutor(Dispatchers.Main.asExecutor())
+
+ override val coroutineContext =
+ Dispatchers.IO + CoroutineName("AsyncStorageScope") + SupervisorJob()
+
+ private val storage = StorageSupplier.getInstance(reactContext)
+
+ companion object {
+ @JvmStatic
+ fun getStorageInstance(ctx: Context): AsyncStorageAccess {
+ return StorageSupplier.getInstance(ctx)
+ }
+ }
+
+ @ReactMethod
+ fun multiGet(keys: ReadableArray, cb: Callback) {
+ launch(createExceptionHandler(cb)) {
+ val entries = storage.getValues(keys.toKeyList())
+ cb(null, entries.toKeyValueArgument())
+ }
+ }
+
+ @ReactMethod
+ fun multiSet(keyValueArray: ReadableArray, cb: Callback) {
+ launch(createExceptionHandler(cb)) {
+ val entries = keyValueArray.toEntryList()
+ storage.setValues(entries)
+ cb(null)
+ }
+ }
+
+ @ReactMethod
+ fun multiRemove(keys: ReadableArray, cb: Callback) {
+ launch(createExceptionHandler(cb)) {
+ storage.removeValues(keys.toKeyList())
+ cb(null)
+ }
+ }
+
+ @ReactMethod
+ fun multiMerge(keyValueArray: ReadableArray, cb: Callback) {
+ launch(createExceptionHandler(cb)) {
+ val entries = keyValueArray.toEntryList()
+ storage.mergeValues(entries)
+ cb(null)
+ }
+ }
+
+ @ReactMethod
+ fun getAllKeys(cb: Callback) {
+ launch(createExceptionHandler(cb)) {
+ val keys = storage.getKeys()
+ val result = Arguments.createArray()
+ keys.forEach { result.pushString(it) }
+ cb.invoke(null, result)
+ }
+ }
+
+ @ReactMethod
+ fun clear(cb: Callback) {
+ launch(createExceptionHandler(cb)) {
+ storage.clear()
+ cb(null)
+ }
+ }
+}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageSupplier.kt b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageSupplier.kt
new file mode 100644
index 00000000..e8a0c419
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageSupplier.kt
@@ -0,0 +1,161 @@
+package com.reactnativecommunity.asyncstorage.next
+
+import android.content.Context
+import android.util.Log
+import androidx.room.ColumnInfo
+import androidx.room.Dao
+import androidx.room.Database
+import androidx.room.Entity
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.PrimaryKey
+import androidx.room.Query
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import androidx.room.Transaction
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+import org.json.JSONObject
+
+private const val DATABASE_VERSION = 2
+private const val DATABASE_NAME = "AsyncStorage"
+private const val TABLE_NAME = "Storage"
+private const val COLUMN_KEY = "key"
+private const val COLUMN_VALUE = "value"
+
+
+@Entity(tableName = TABLE_NAME)
+data class Entry(
+ @PrimaryKey @ColumnInfo(name = COLUMN_KEY) val key: String,
+ @ColumnInfo(name = COLUMN_VALUE) val value: String?
+)
+
+@Dao
+internal interface StorageDao {
+
+ @Transaction
+ @Query("SELECT * FROM $TABLE_NAME WHERE `$COLUMN_KEY` IN (:keys)")
+ suspend fun getValues(keys: List): List
+
+ @Transaction
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun setValues(entries: List)
+
+ @Transaction
+ @Query("DELETE FROM $TABLE_NAME WHERE `$COLUMN_KEY` in (:keys)")
+ suspend fun removeValues(keys: List)
+
+ @Transaction
+ suspend fun mergeValues(entries: List) {
+ val currentDbEntries = getValues(entries.map { it.key })
+ val newEntries = mutableListOf()
+
+ entries.forEach { newEntry ->
+ val oldEntry = currentDbEntries.find { it.key == newEntry.key }
+ if (oldEntry?.value == null) {
+ newEntries.add(newEntry)
+ } else if (!oldEntry.value.isValidJson() || !newEntry.value.isValidJson()) {
+ newEntries.add(newEntry)
+ } else {
+ val newValue =
+ JSONObject(oldEntry.value).mergeWith(JSONObject(newEntry.value)).toString()
+ newEntries.add(newEntry.copy(value = newValue))
+ }
+ }
+ setValues(newEntries)
+ }
+
+ @Transaction
+ @Query("SELECT `$COLUMN_KEY` FROM $TABLE_NAME")
+ suspend fun getKeys(): List
+
+ @Transaction
+ @Query("DELETE FROM $TABLE_NAME")
+ suspend fun clear()
+}
+
+
+/**
+ * Previous version of AsyncStorage is violating the SQL standard (based on bug in SQLite),
+ * where PrimaryKey ('key' column) should never be null (https://www.sqlite.org/lang_createtable.html#the_primary_key).
+ * Because of that, we cannot reuse the old DB, because ROOM is guarded against that case (won't compile).
+ *
+ * In order to work around this, two steps are necessary:
+ * - Room DB pre-population from the old database file (https://developer.android.com/training/data-storage/room/prepopulate#from-asset)
+ * - Version migration, so that we can mark 'key' column as NOT-NULL
+ *
+ * This migration will happens only once, when developer enable this feature (when DB is still not created).
+ */
+@Suppress("ClassName")
+private object MIGRATION_TO_NEXT : Migration(1, 2) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ val oldTableName = "catalystLocalStorage" // from ReactDatabaseSupplier
+ database.execSQL("CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`${COLUMN_KEY}` TEXT NOT NULL, `${COLUMN_VALUE}` TEXT, PRIMARY KEY(`${COLUMN_KEY}`));")
+ // even if the old AsyncStorage has checks for not nullable keys
+ // make sure we don't copy any, to not fail migration
+ database.execSQL("DELETE FROM $oldTableName WHERE `${COLUMN_KEY}` IS NULL")
+ database.execSQL(
+ """
+ INSERT INTO $TABLE_NAME (`${COLUMN_KEY}`, `${COLUMN_VALUE}`)
+ SELECT `${COLUMN_KEY}`, `${COLUMN_VALUE}`
+ FROM $oldTableName;
+ """.trimIndent()
+ )
+ Log.e("AsyncStorage_Next", "Migration to Next storage completed.")
+ }
+}
+
+@Database(entities = [Entry::class], version = DATABASE_VERSION, exportSchema = true)
+internal abstract class StorageDb : RoomDatabase() {
+ abstract fun storage(): StorageDao
+
+ companion object {
+ private var instance: StorageDb? = null
+
+ fun getDatabase(context: Context): StorageDb {
+ var inst = instance
+ if (inst != null) {
+ return inst
+ }
+ synchronized(this) {
+ val oldDbFile = context.getDatabasePath("RKStorage")
+ val db = Room.databaseBuilder(
+ context, StorageDb::class.java, DATABASE_NAME
+ )
+ if (oldDbFile.exists()) {
+ // migrate data from old database, if it exists
+ db.createFromFile(oldDbFile).addMigrations(MIGRATION_TO_NEXT)
+ }
+ inst = db.build()
+ instance = inst
+ return instance!!
+ }
+ }
+ }
+}
+
+interface AsyncStorageAccess {
+ suspend fun getValues(keys: List): List
+ suspend fun setValues(entries: List)
+ suspend fun removeValues(keys: List)
+ suspend fun getKeys(): List
+ suspend fun clear()
+ suspend fun mergeValues(entries: List)
+}
+
+class StorageSupplier internal constructor(db: StorageDb) : AsyncStorageAccess {
+ companion object {
+ fun getInstance(ctx: Context): AsyncStorageAccess {
+ return StorageSupplier(StorageDb.getDatabase(ctx))
+ }
+ }
+
+ private val access = db.storage()
+
+ override suspend fun getValues(keys: List) = access.getValues(keys)
+ override suspend fun setValues(entries: List) = access.setValues(entries)
+ override suspend fun removeValues(keys: List) = access.removeValues(keys)
+ override suspend fun mergeValues(entries: List) = access.mergeValues(entries)
+ override suspend fun getKeys() = access.getKeys()
+ override suspend fun clear() = access.clear()
+}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/test/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpersTest.kt b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/test/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpersTest.kt
new file mode 100644
index 00000000..e5943a1c
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/test/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpersTest.kt
@@ -0,0 +1,93 @@
+package com.reactnativecommunity.asyncstorage.next
+
+import com.facebook.react.bridge.JavaOnlyArray
+import com.facebook.react.bridge.ReadableArray
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.assertThrows
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+@RunWith(BlockJUnit4ClassRunner::class)
+class ArgumentHelpersTest {
+
+ @Test
+ fun transformsArgumentsToEntryList() {
+ val args = JavaOnlyArray.of(
+ arrayListOf("key1", "value1"),
+ arrayListOf("key2", "value2"),
+ arrayListOf("key3", "value3")
+ )
+ assertThat(args.toEntryList()).isEqualTo(
+ listOf(
+ Entry("key1", "value1"),
+ Entry("key2", "value2"),
+ Entry("key3", "value3"),
+ )
+ )
+ }
+
+ @Test
+ fun transfersArgumentsToKeyList() {
+ val keyList = listOf("key1", "key2", "key3")
+ val args = keyList.toReadableArray()
+ assertThat(args.toKeyList()).isEqualTo(keyList)
+ }
+
+ @Test
+ fun throwsIfArgumentsNotValidFormat() {
+ val invalid = arrayListOf("invalid")
+ val args = JavaOnlyArray.of(invalid)
+ val error = assertThrows(AsyncStorageError::class.java) {
+ args.toEntryList()
+ }
+
+ assertThat(error is AsyncStorageError).isTrue()
+ assertThat(error).hasMessageThat()
+ .isEqualTo("Invalid key-value format. Expected a list of [key, value] list.")
+ }
+
+ @Test
+ fun throwsIfArgumentKeyIsNullOrNotString() {
+ val argsInvalidNull = JavaOnlyArray.of(arrayListOf(null, "invalid"))
+ val errorArgsInvalidNull = assertThrows(AsyncStorageError::class.java) {
+ argsInvalidNull.toEntryList()
+ }
+ assertThat(errorArgsInvalidNull is AsyncStorageError).isTrue()
+ assertThat(errorArgsInvalidNull).hasMessageThat().isEqualTo("Key cannot be null.")
+
+ val notStringArgs = JavaOnlyArray.of(arrayListOf(123, "invalid"))
+ val errorNotString = assertThrows(AsyncStorageError::class.java) {
+ notStringArgs.toEntryList()
+ }
+ assertThat(errorNotString is AsyncStorageError).isTrue()
+ assertThat(errorNotString).hasMessageThat()
+ .isEqualTo("Provided key is not string. Only strings are supported as storage key.")
+ }
+
+ @Test
+ fun throwsIfArgumentValueNotString() {
+ val invalidArgs = JavaOnlyArray.of(arrayListOf("my_key", 666))
+ val error = assertThrows(AsyncStorageError::class.java) {
+ invalidArgs.toEntryList()
+ }
+ assertThat(error is AsyncStorageError).isTrue()
+ assertThat(error).hasMessageThat()
+ .isEqualTo("Value for key \"my_key\" is not a string. Only strings are supported as a value.")
+ }
+}
+
+fun List.toReadableArray(): ReadableArray {
+ val arr = JavaOnlyArray()
+ forEach {
+ when (it) {
+ null -> arr.pushNull()
+ is Boolean -> arr.pushBoolean(it)
+ is Double -> arr.pushDouble(it)
+ is Int -> arr.pushInt(it)
+ is String -> arr.pushString(it)
+ else -> throw NotImplementedError()
+ }
+ }
+ return arr
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/test/java/com/reactnativecommunity/asyncstorage/next/StorageTest.kt b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/test/java/com/reactnativecommunity/asyncstorage/next/StorageTest.kt
new file mode 100644
index 00000000..5d873e1b
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/src/test/java/com/reactnativecommunity/asyncstorage/next/StorageTest.kt
@@ -0,0 +1,141 @@
+package com.reactnativecommunity.asyncstorage.next
+
+import androidx.room.Room
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
+import org.json.JSONObject
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.random.Random
+
+@ExperimentalCoroutinesApi
+@RunWith(AndroidJUnit4::class)
+class AsyncStorageAccessTest {
+ private lateinit var asyncStorage: AsyncStorageAccess
+ private lateinit var database: StorageDb
+
+ @Before
+ fun setup() {
+ database = Room.inMemoryDatabaseBuilder(
+ InstrumentationRegistry.getInstrumentation().context, StorageDb::class.java
+ ).allowMainThreadQueries().build()
+ asyncStorage = StorageSupplier(database)
+ }
+
+ @After
+ fun tearDown() {
+ database.close()
+ }
+
+ @Test
+ fun performsBasicGetSetRemoveOperations() = runBlocking {
+ val entriesCount = 10
+ val entries = createRandomEntries(entriesCount)
+ val keys = entries.map { it.key }
+ assertThat(asyncStorage.getValues(keys)).hasSize(0)
+ asyncStorage.setValues(entries)
+ assertThat(asyncStorage.getValues(keys)).hasSize(entriesCount)
+ val indicesToRemove = (1..4).map { Random.nextInt(0, entriesCount) }.distinct()
+ val toRemove = entries.filterIndexed { index, _ -> indicesToRemove.contains(index) }
+ asyncStorage.removeValues(toRemove.map { it.key })
+ val currentEntries = asyncStorage.getValues(keys)
+ assertThat(currentEntries).hasSize(entriesCount - toRemove.size)
+ }
+
+ @Test
+ fun readsAllKeysAndClearsDb() = runBlocking {
+ val entries = createRandomEntries(8)
+ val keys = entries.map { it.key }
+ asyncStorage.setValues(entries)
+ val dbKeys = asyncStorage.getKeys()
+ assertThat(dbKeys).isEqualTo(keys)
+ asyncStorage.clear()
+ assertThat(asyncStorage.getValues(keys)).hasSize(0)
+ }
+
+ @Test
+ fun mergesDeeplyTwoValues() = runBlocking {
+ val initialEntry = Entry("key", VALUE_INITIAL)
+ val overrideEntry = Entry("key", VALUE_OVERRIDES)
+ asyncStorage.setValues(listOf(initialEntry))
+ asyncStorage.mergeValues(listOf(overrideEntry))
+ val current = asyncStorage.getValues(listOf("key"))[0]
+ assertThat(current.value).isEqualTo(VALUE_MERGED)
+ }
+
+ @Test
+ fun updatesExistingValues() = runBlocking {
+ val key = "test_key"
+ val value = "test_value"
+ val entries = listOf(Entry(key, value))
+ assertThat(asyncStorage.getValues(listOf(key))).hasSize(0)
+ asyncStorage.setValues(entries)
+ assertThat(asyncStorage.getValues(listOf(key))).isEqualTo(entries)
+ val modifiedEntries = listOf(Entry(key, "updatedValue"))
+ asyncStorage.setValues(modifiedEntries)
+ assertThat(asyncStorage.getValues(listOf(key))).isEqualTo(modifiedEntries)
+ }
+
+
+ // Test Helpers
+ private fun createRandomEntries(count: Int = Random.nextInt(10)): List {
+ val entries = mutableListOf()
+ for (i in 0 until count) {
+ entries.add(Entry("key$i", "value$i"))
+ }
+ return entries
+ }
+
+ private val VALUE_INITIAL = JSONObject(
+ """
+ {
+ "key":"value",
+ "key2":"override",
+ "key3":{
+ "key4":"value4",
+ "key6":{
+ "key7":"value7",
+ "key8":"override"
+ }
+ }
+ }
+""".trimMargin()
+ ).toString()
+
+ private val VALUE_OVERRIDES = JSONObject(
+ """
+ {
+ "key2":"value2",
+ "key3":{
+ "key5":"value5",
+ "key6":{
+ "key8":"value8"
+ }
+ }
+ }
+"""
+ ).toString()
+
+
+ private val VALUE_MERGED = JSONObject(
+ """
+ {
+ "key":"value",
+ "key2":"value2",
+ "key3":{
+ "key4":"value4",
+ "key6":{
+ "key7":"value7",
+ "key8":"value8"
+ },
+ "key5":"value5"
+ }
+ }
+""".trimMargin()
+ ).toString()
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/testresults.gradle b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/testresults.gradle
new file mode 100644
index 00000000..50ad3e8d
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/android/testresults.gradle
@@ -0,0 +1,38 @@
+
+// pretty print test results
+import org.gradle.api.tasks.testing.logging.TestExceptionFormat
+import org.gradle.api.tasks.testing.logging.TestLogEvent
+tasks.withType(Test) {
+ testLogging {
+
+ events TestLogEvent.FAILED,
+ TestLogEvent.PASSED,
+ TestLogEvent.SKIPPED,
+ TestLogEvent.STANDARD_OUT
+ exceptionFormat TestExceptionFormat.FULL
+ showExceptions true
+ showCauses true
+ showStackTraces true
+
+ debug {
+ events TestLogEvent.STARTED,
+ TestLogEvent.FAILED,
+ TestLogEvent.PASSED,
+ TestLogEvent.SKIPPED,
+ TestLogEvent.STANDARD_ERROR,
+ TestLogEvent.STANDARD_OUT
+ exceptionFormat TestExceptionFormat.FULL
+ }
+ info.events = debug.events
+ info.exceptionFormat = debug.exceptionFormat
+
+ afterSuite { desc, result ->
+ if (!desc.parent) { // will match the outermost suite
+ def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} passed, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped)"
+ def startItem = '| ', endItem = ' |'
+ def repeatLength = startItem.length() + output.length() + endItem.length()
+ println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength))
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorage.h b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorage.h
new file mode 100644
index 00000000..5dfac047
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorage.h
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+#import
+
+#import
+#import
+
+#import "RNCAsyncStorageDelegate.h"
+
+/**
+ * A simple, asynchronous, persistent, key-value storage system designed as a
+ * backend to the AsyncStorage JS module, which is modeled after LocalStorage.
+ *
+ * Current implementation stores small values in serialized dictionary and
+ * larger values in separate files. Since we use a serial file queue
+ * `RKFileQueue`, reading/writing from multiple threads should be perceived as
+ * being atomic, unless someone bypasses the `RNCAsyncStorage` API.
+ *
+ * Keys and values must always be strings or an error is returned.
+ */
+@interface RNCAsyncStorage : NSObject
+
+@property (nonatomic, weak, nullable) id delegate;
+
+@property (nonatomic, assign) BOOL clearOnInvalidate;
+
+@property (nonatomic, readonly, getter=isValid) BOOL valid;
+
+// Clear the RNCAsyncStorage data from native code
+- (void)clearAllData;
+
+// For clearing data when the bridge may not exist, e.g. when logging out.
++ (void)clearAllData;
+
+// Grab data from the cache. ResponseBlock result array will have an error at position 0, and an
+// array of arrays at position 1.
+- (void)multiGet:(NSArray *)keys callback:(RCTResponseSenderBlock)callback;
+
+// Add multiple key value pairs to the cache.
+- (void)multiSet:(NSArray *> *)kvPairs
+ callback:(RCTResponseSenderBlock)callback;
+
+// Interface for natively fetching all the keys from the storage data.
+- (void)getAllKeys:(RCTResponseSenderBlock)callback;
+
+@end
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorage.m b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorage.m
new file mode 100644
index 00000000..75c87471
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorage.m
@@ -0,0 +1,898 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+#import "RNCAsyncStorage.h"
+
+#import
+#import
+
+#import
+#import
+#import
+
+static NSString *const RCTStorageDirectory = @"RCTAsyncLocalStorage_V1";
+static NSString *const RCTOldStorageDirectory = @"RNCAsyncLocalStorage_V1";
+static NSString *const RCTExpoStorageDirectory = @"RCTAsyncLocalStorage";
+static NSString *const RCTManifestFileName = @"manifest.json";
+static const NSUInteger RCTInlineValueThreshold = 1024;
+
+#pragma mark - Static helper functions
+
+static NSDictionary *RCTErrorForKey(NSString *key)
+{
+ if (![key isKindOfClass:[NSString class]]) {
+ return RCTMakeAndLogError(@"Invalid key - must be a string. Key: ", key, @{@"key": key});
+ } else if (key.length < 1) {
+ return RCTMakeAndLogError(
+ @"Invalid key - must be at least one character. Key: ", key, @{@"key": key});
+ } else {
+ return nil;
+ }
+}
+
+static BOOL RCTAsyncStorageSetExcludedFromBackup(NSString *path, NSNumber *isExcluded)
+{
+ NSFileManager *fileManager = [[NSFileManager alloc] init];
+
+ BOOL isDir;
+ BOOL exists = [fileManager fileExistsAtPath:path isDirectory:&isDir];
+ BOOL success = false;
+
+ if (isDir && exists) {
+ NSURL *pathUrl = [NSURL fileURLWithPath:path];
+ NSError *error = nil;
+ success = [pathUrl setResourceValue:isExcluded
+ forKey:NSURLIsExcludedFromBackupKey
+ error:&error];
+
+ if (!success) {
+ NSLog(@"Could not exclude AsyncStorage dir from backup %@", error);
+ }
+ }
+ return success;
+}
+
+static void RCTAppendError(NSDictionary *error, NSMutableArray **errors)
+{
+ if (error && errors) {
+ if (!*errors) {
+ *errors = [NSMutableArray new];
+ }
+ [*errors addObject:error];
+ }
+}
+
+static NSArray *RCTMakeErrors(NSArray> *results)
+{
+ NSMutableArray *errors;
+ for (id object in results) {
+ if ([object isKindOfClass:[NSError class]]) {
+ NSError *error = (NSError *)object;
+ NSDictionary *keyError = RCTMakeError(error.localizedDescription, error, nil);
+ RCTAppendError(keyError, &errors);
+ }
+ }
+ return errors;
+}
+
+static NSString *RCTReadFile(NSString *filePath, NSString *key, NSDictionary **errorOut)
+{
+ if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
+ NSError *error;
+ NSStringEncoding encoding;
+ NSString *entryString = [NSString stringWithContentsOfFile:filePath
+ usedEncoding:&encoding
+ error:&error];
+ NSDictionary *extraData = @{@"key": RCTNullIfNil(key)};
+
+ if (error) {
+ if (errorOut) {
+ *errorOut = RCTMakeError(@"Failed to read storage file.", error, extraData);
+ }
+ return nil;
+ }
+
+ if (encoding != NSUTF8StringEncoding) {
+ if (errorOut) {
+ *errorOut =
+ RCTMakeError(@"Incorrect encoding of storage file: ", @(encoding), extraData);
+ }
+ return nil;
+ }
+ return entryString;
+ }
+
+ return nil;
+}
+
+// DO NOT USE
+// This is used internally to migrate data from the old file location to the new one.
+// Please use `RCTCreateStorageDirectoryPath` instead
+static NSString *RCTCreateStorageDirectoryPath_deprecated(NSString *storageDir)
+{
+ NSString *storageDirectoryPath;
+#if TARGET_OS_TV
+ storageDirectoryPath =
+ NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
+#else
+ storageDirectoryPath =
+ NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
+#endif
+ storageDirectoryPath = [storageDirectoryPath stringByAppendingPathComponent:storageDir];
+ return storageDirectoryPath;
+}
+
+static NSString *RCTCreateStorageDirectoryPath(NSString *storageDir)
+{
+ NSString *storageDirectoryPath = @"";
+
+#if TARGET_OS_TV
+ storageDirectoryPath =
+ NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
+#else
+ storageDirectoryPath =
+ NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)
+ .firstObject;
+ // We should use the "Application Support/[bundleID]" folder for persistent data storage that's
+ // hidden from users
+ storageDirectoryPath = [storageDirectoryPath
+ stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]];
+#endif
+
+ // Per Apple's docs, all app content in Application Support must be within a subdirectory of the
+ // app's bundle identifier
+ storageDirectoryPath = [storageDirectoryPath stringByAppendingPathComponent:storageDir];
+
+ return storageDirectoryPath;
+}
+
+static NSString *RCTGetStorageDirectory()
+{
+ static NSString *storageDirectory = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ storageDirectory = RCTCreateStorageDirectoryPath(RCTStorageDirectory);
+ });
+ return storageDirectory;
+}
+
+static NSString *RCTCreateManifestFilePath(NSString *storageDirectory)
+{
+ return [storageDirectory stringByAppendingPathComponent:RCTManifestFileName];
+}
+
+static NSString *RCTGetManifestFilePath()
+{
+ static NSString *manifestFilePath = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ manifestFilePath = RCTCreateManifestFilePath(RCTStorageDirectory);
+ });
+ return manifestFilePath;
+}
+
+// Only merges objects - all other types are just clobbered (including arrays)
+static BOOL RCTMergeRecursive(NSMutableDictionary *destination, NSDictionary *source)
+{
+ BOOL modified = NO;
+ for (NSString *key in source) {
+ id sourceValue = source[key];
+ id destinationValue = destination[key];
+ if ([sourceValue isKindOfClass:[NSDictionary class]]) {
+ if ([destinationValue isKindOfClass:[NSDictionary class]]) {
+ if ([destinationValue classForCoder] != [NSMutableDictionary class]) {
+ destinationValue = [destinationValue mutableCopy];
+ }
+ if (RCTMergeRecursive(destinationValue, sourceValue)) {
+ destination[key] = destinationValue;
+ modified = YES;
+ }
+ } else {
+ destination[key] = [sourceValue copy];
+ modified = YES;
+ }
+ } else if (![source isEqual:destinationValue]) {
+ destination[key] = [sourceValue copy];
+ modified = YES;
+ }
+ }
+ return modified;
+}
+
+static dispatch_queue_t RCTGetMethodQueue()
+{
+ // We want all instances to share the same queue since they will be reading/writing the same
+ // files.
+ static dispatch_queue_t queue;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ queue =
+ dispatch_queue_create("com.facebook.react.AsyncLocalStorageQueue", DISPATCH_QUEUE_SERIAL);
+ });
+ return queue;
+}
+
+static NSCache *RCTGetCache()
+{
+ // We want all instances to share the same cache since they will be reading/writing the same
+ // files.
+ static NSCache *cache;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ cache = [NSCache new];
+ cache.totalCostLimit = 2 * 1024 * 1024; // 2MB
+
+#if !TARGET_OS_OSX
+ // Clear cache in the event of a memory warning
+ [[NSNotificationCenter defaultCenter]
+ addObserverForName:UIApplicationDidReceiveMemoryWarningNotification
+ object:nil
+ queue:nil
+ usingBlock:^(__unused NSNotification *note) {
+ [cache removeAllObjects];
+ }];
+#endif // !TARGET_OS_OSX
+ });
+ return cache;
+}
+
+static BOOL RCTHasCreatedStorageDirectory = NO;
+static NSDictionary *RCTDeleteStorageDirectory()
+{
+ NSError *error;
+ [[NSFileManager defaultManager] removeItemAtPath:RCTGetStorageDirectory() error:&error];
+ RCTHasCreatedStorageDirectory = NO;
+ return error ? RCTMakeError(@"Failed to delete storage directory.", error, nil) : nil;
+}
+
+static NSDate *RCTManifestModificationDate(NSString *manifestFilePath)
+{
+ NSDictionary *attributes =
+ [[NSFileManager defaultManager] attributesOfItemAtPath:manifestFilePath error:nil];
+ return [attributes fileModificationDate];
+}
+
+/**
+ * Creates an NSException used during Storage Directory Migration.
+ */
+static void RCTStorageDirectoryMigrationLogError(NSString *reason, NSError *error)
+{
+ RCTLogWarn(@"%@: %@", reason, error ? error.description : @"");
+}
+
+static void RCTStorageDirectoryCleanupOld(NSString *oldDirectoryPath)
+{
+ NSError *error;
+ if (![[NSFileManager defaultManager] removeItemAtPath:oldDirectoryPath error:&error]) {
+ RCTStorageDirectoryMigrationLogError(
+ @"Failed to remove old storage directory during migration", error);
+ }
+}
+
+static void _createStorageDirectory(NSString *storageDirectory, NSError **error)
+{
+ [[NSFileManager defaultManager] createDirectoryAtPath:storageDirectory
+ withIntermediateDirectories:YES
+ attributes:nil
+ error:error];
+}
+
+static void RCTStorageDirectoryMigrate(NSString *oldDirectoryPath,
+ NSString *newDirectoryPath,
+ BOOL shouldCleanupOldDirectory)
+{
+ NSError *error;
+ // Migrate data by copying old storage directory to new storage directory location
+ if (![[NSFileManager defaultManager] copyItemAtPath:oldDirectoryPath
+ toPath:newDirectoryPath
+ error:&error]) {
+ // the new storage directory "Application Support/[bundleID]/RCTAsyncLocalStorage_V1" seems
+ // unable to migrate because folder "Application Support/[bundleID]" doesn't exist.. create
+ // this folder and attempt folder copying again
+ if (error != nil && error.code == 4 &&
+ [newDirectoryPath isEqualToString:RCTGetStorageDirectory()]) {
+ NSError *error = nil;
+ _createStorageDirectory(RCTCreateStorageDirectoryPath(@""), &error);
+ if (error == nil) {
+ RCTStorageDirectoryMigrate(
+ oldDirectoryPath, newDirectoryPath, shouldCleanupOldDirectory);
+ } else {
+ RCTStorageDirectoryMigrationLogError(
+ @"Failed to create storage directory during migration.", error);
+ }
+ } else {
+ RCTStorageDirectoryMigrationLogError(
+ @"Failed to copy old storage directory to new storage directory location during "
+ @"migration",
+ error);
+ }
+ } else if (shouldCleanupOldDirectory) {
+ // If copying succeeds, remove old storage directory
+ RCTStorageDirectoryCleanupOld(oldDirectoryPath);
+ }
+}
+
+/**
+ * Determine which of RCTOldStorageDirectory or RCTExpoStorageDirectory needs to migrated.
+ * If both exist, we remove the least recently modified and return the most recently modified.
+ * Otherwise, this will return the path to whichever directory exists.
+ * If no directory exists, then return nil.
+ */
+static NSString *RCTGetStoragePathForMigration()
+{
+ BOOL isDir;
+ NSString *oldStoragePath = RCTCreateStorageDirectoryPath_deprecated(RCTOldStorageDirectory);
+ NSString *expoStoragePath = RCTCreateStorageDirectoryPath_deprecated(RCTExpoStorageDirectory);
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ BOOL oldStorageDirectoryExists =
+ [fileManager fileExistsAtPath:oldStoragePath isDirectory:&isDir] && isDir;
+ BOOL expoStorageDirectoryExists =
+ [fileManager fileExistsAtPath:expoStoragePath isDirectory:&isDir] && isDir;
+
+ // Check if both the old storage directory and Expo storage directory exist
+ if (oldStorageDirectoryExists && expoStorageDirectoryExists) {
+ // If the old storage has been modified more recently than Expo storage, then clear Expo
+ // storage. Otherwise, clear the old storage.
+ if ([RCTManifestModificationDate(RCTCreateManifestFilePath(oldStoragePath))
+ compare:RCTManifestModificationDate(RCTCreateManifestFilePath(expoStoragePath))] ==
+ NSOrderedDescending) {
+ RCTStorageDirectoryCleanupOld(expoStoragePath);
+ return oldStoragePath;
+ } else {
+ RCTStorageDirectoryCleanupOld(oldStoragePath);
+ return expoStoragePath;
+ }
+ } else if (oldStorageDirectoryExists) {
+ return oldStoragePath;
+ } else if (expoStorageDirectoryExists) {
+ return expoStoragePath;
+ } else {
+ return nil;
+ }
+}
+
+/**
+ * This check is added to make sure that anyone coming from pre-1.2.2 does not lose cached data.
+ * Check that data is migrated from the old location to the new location
+ * fromStorageDirectory: the directory where the older data lives
+ * toStorageDirectory: the directory where the new data should live
+ * shouldCleanupOldDirectoryAndOverwriteNewDirectory: YES if we should delete the old directory's
+ * contents and overwrite the new directory's contents during the migration to the new directory
+ */
+static void
+RCTStorageDirectoryMigrationCheck(NSString *fromStorageDirectory,
+ NSString *toStorageDirectory,
+ BOOL shouldCleanupOldDirectoryAndOverwriteNewDirectory)
+{
+ NSError *error;
+ BOOL isDir;
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ // If the old directory exists, it means we may need to migrate old data to the new directory
+ if ([fileManager fileExistsAtPath:fromStorageDirectory isDirectory:&isDir] && isDir) {
+ // Check if the new storage directory location already exists
+ if ([fileManager fileExistsAtPath:toStorageDirectory]) {
+ // If new storage location exists, check if the new storage has been modified sooner in
+ // which case we may want to cleanup the old location
+ if ([RCTManifestModificationDate(RCTCreateManifestFilePath(toStorageDirectory))
+ compare:RCTManifestModificationDate(
+ RCTCreateManifestFilePath(fromStorageDirectory))] == 1) {
+ // If new location has been modified more recently, simply clean out old data
+ if (shouldCleanupOldDirectoryAndOverwriteNewDirectory) {
+ RCTStorageDirectoryCleanupOld(fromStorageDirectory);
+ }
+ } else if (shouldCleanupOldDirectoryAndOverwriteNewDirectory) {
+ // If old location has been modified more recently, remove new storage and migrate
+ if (![fileManager removeItemAtPath:toStorageDirectory error:&error]) {
+ RCTStorageDirectoryMigrationLogError(
+ @"Failed to remove new storage directory during migration", error);
+ } else {
+ RCTStorageDirectoryMigrate(fromStorageDirectory,
+ toStorageDirectory,
+ shouldCleanupOldDirectoryAndOverwriteNewDirectory);
+ }
+ }
+ } else {
+ // If new storage location doesn't exist, migrate data
+ RCTStorageDirectoryMigrate(fromStorageDirectory,
+ toStorageDirectory,
+ shouldCleanupOldDirectoryAndOverwriteNewDirectory);
+ }
+ }
+}
+
+#pragma mark - RNCAsyncStorage
+
+@implementation RNCAsyncStorage {
+ BOOL _haveSetup;
+ // The manifest is a dictionary of all keys with small values inlined. Null values indicate
+ // values that are stored in separate files (as opposed to nil values which don't exist). The
+ // manifest is read off disk at startup, and written to disk after all mutations.
+ NSMutableDictionary *_manifest;
+}
+
++ (BOOL)requiresMainQueueSetup
+{
+ return NO;
+}
+
+- (instancetype)init
+{
+ if (!(self = [super init])) {
+ return nil;
+ }
+
+ // Get the path to any old storage directory that needs to be migrated. If multiple exist,
+ // the oldest are removed and the most recently modified is returned.
+ NSString *oldStoragePath = RCTGetStoragePathForMigration();
+ if (oldStoragePath != nil) {
+ // Migrate our deprecated path "Documents/.../RNCAsyncLocalStorage_V1" or
+ // "Documents/.../RCTAsyncLocalStorage" to "Documents/.../RCTAsyncLocalStorage_V1"
+ RCTStorageDirectoryMigrationCheck(
+ oldStoragePath, RCTCreateStorageDirectoryPath_deprecated(RCTStorageDirectory), YES);
+ }
+
+ // Migrate what's in "Documents/.../RCTAsyncLocalStorage_V1" to
+ // "Application Support/[bundleID]/RCTAsyncLocalStorage_V1"
+ RCTStorageDirectoryMigrationCheck(RCTCreateStorageDirectoryPath_deprecated(RCTStorageDirectory),
+ RCTCreateStorageDirectoryPath(RCTStorageDirectory),
+ NO);
+
+ return self;
+}
+
+RCT_EXPORT_MODULE()
+
+- (dispatch_queue_t)methodQueue
+{
+ return RCTGetMethodQueue();
+}
+
+- (void)clearAllData
+{
+ dispatch_async(RCTGetMethodQueue(), ^{
+ [self->_manifest removeAllObjects];
+ [RCTGetCache() removeAllObjects];
+ RCTDeleteStorageDirectory();
+ });
+}
+
++ (void)clearAllData
+{
+ dispatch_async(RCTGetMethodQueue(), ^{
+ [RCTGetCache() removeAllObjects];
+ RCTDeleteStorageDirectory();
+ });
+}
+
+- (void)invalidate
+{
+ if (_clearOnInvalidate) {
+ [RCTGetCache() removeAllObjects];
+ RCTDeleteStorageDirectory();
+ }
+ _clearOnInvalidate = NO;
+ [_manifest removeAllObjects];
+ _haveSetup = NO;
+}
+
+- (BOOL)isValid
+{
+ return _haveSetup;
+}
+
+- (void)dealloc
+{
+ [self invalidate];
+}
+
+- (NSString *)_filePathForKey:(NSString *)key
+{
+ NSString *safeFileName = RCTMD5Hash(key);
+ return [RCTGetStorageDirectory() stringByAppendingPathComponent:safeFileName];
+}
+
+- (NSDictionary *)_ensureSetup
+{
+ RCTAssertThread(RCTGetMethodQueue(), @"Must be executed on storage thread");
+
+#if TARGET_OS_TV
+ RCTLogWarn(
+ @"Persistent storage is not supported on tvOS, your data may be removed at any point.");
+#endif
+
+ NSError *error = nil;
+ if (!RCTHasCreatedStorageDirectory) {
+ _createStorageDirectory(RCTGetStorageDirectory(), &error);
+ if (error) {
+ return RCTMakeError(@"Failed to create storage directory.", error, nil);
+ }
+ RCTHasCreatedStorageDirectory = YES;
+ }
+
+ if (!_haveSetup) {
+ // iCloud backup exclusion
+ NSNumber *isExcludedFromBackup =
+ [[NSBundle mainBundle] objectForInfoDictionaryKey:@"RCTAsyncStorageExcludeFromBackup"];
+ if (isExcludedFromBackup == nil) {
+ // by default, we want to exclude AsyncStorage data from backup
+ isExcludedFromBackup = @YES;
+ }
+ RCTAsyncStorageSetExcludedFromBackup(RCTCreateStorageDirectoryPath(RCTStorageDirectory),
+ isExcludedFromBackup);
+
+ NSDictionary *errorOut = nil;
+ NSString *serialized = RCTReadFile(RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()),
+ RCTManifestFileName,
+ &errorOut);
+ if (!serialized) {
+ if (errorOut) {
+ // We cannot simply create a new manifest in case the file does exist but we have no
+ // access to it. This can happen when data protection is enabled for the app and we
+ // are trying to read the manifest while the device is locked. (The app can be
+ // started by the system even if the device is locked due to e.g. a geofence event.)
+ RCTLogError(
+ @"Could not open the existing manifest, perhaps data protection is "
+ @"enabled?\n\n%@",
+ errorOut);
+ return errorOut;
+ } else {
+ // We can get nil without errors only when the file does not exist.
+ RCTLogTrace(@"Manifest does not exist - creating a new one.\n\n%@", errorOut);
+ _manifest = [NSMutableDictionary new];
+ }
+ } else {
+ _manifest = RCTJSONParseMutable(serialized, &error);
+ if (!_manifest) {
+ RCTLogError(@"Failed to parse manifest - creating a new one.\n\n%@", error);
+ _manifest = [NSMutableDictionary new];
+ }
+ }
+ _haveSetup = YES;
+ }
+
+ return nil;
+}
+
+- (NSDictionary *)_writeManifest:(NSMutableArray **)errors
+{
+ NSError *error;
+ NSString *serialized = RCTJSONStringify(_manifest, &error);
+ [serialized writeToFile:RCTCreateStorageDirectoryPath(RCTGetManifestFilePath())
+ atomically:YES
+ encoding:NSUTF8StringEncoding
+ error:&error];
+ NSDictionary *errorOut;
+ if (error) {
+ errorOut = RCTMakeError(@"Failed to write manifest file.", error, nil);
+ RCTAppendError(errorOut, errors);
+ }
+ return errorOut;
+}
+
+- (NSDictionary *)_appendItemForKey:(NSString *)key
+ toArray:(NSMutableArray *> *)result
+{
+ NSDictionary *errorOut = RCTErrorForKey(key);
+ if (errorOut) {
+ return errorOut;
+ }
+ NSString *value = [self _getValueForKey:key errorOut:&errorOut];
+ [result addObject:@[key, RCTNullIfNil(value)]]; // Insert null if missing or failure.
+ return errorOut;
+}
+
+- (NSString *)_getValueForKey:(NSString *)key errorOut:(NSDictionary **)errorOut
+{
+ NSString *value =
+ _manifest[key]; // nil means missing, null means there may be a data file, else: NSString
+ if (value == (id)kCFNull) {
+ value = [RCTGetCache() objectForKey:key];
+ if (!value) {
+ NSString *filePath = [self _filePathForKey:key];
+ value = RCTReadFile(filePath, key, errorOut);
+ if (value) {
+ [RCTGetCache() setObject:value forKey:key cost:value.length];
+ } else {
+ // file does not exist after all, so remove from manifest (no need to save
+ // manifest immediately though, as cost of checking again next time is negligible)
+ [_manifest removeObjectForKey:key];
+ }
+ }
+ }
+ return value;
+}
+
+- (NSDictionary *)_writeEntry:(NSArray *)entry changedManifest:(BOOL *)changedManifest
+{
+ if (entry.count != 2) {
+ return RCTMakeAndLogError(
+ @"Entries must be arrays of the form [key: string, value: string], got: ", entry, nil);
+ }
+ NSString *key = entry[0];
+ NSDictionary *errorOut = RCTErrorForKey(key);
+ if (errorOut) {
+ return errorOut;
+ }
+ NSString *value = entry[1];
+ NSString *filePath = [self _filePathForKey:key];
+ NSError *error;
+ if (value.length <= RCTInlineValueThreshold) {
+ if (_manifest[key] == (id)kCFNull) {
+ // If the value already existed but wasn't inlined, remove the old file.
+ [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
+ [RCTGetCache() removeObjectForKey:key];
+ }
+ *changedManifest = YES;
+ _manifest[key] = value;
+ return nil;
+ }
+ [value writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
+ [RCTGetCache() setObject:value forKey:key cost:value.length];
+ if (error) {
+ errorOut = RCTMakeError(@"Failed to write value.", error, @{@"key": key});
+ } else if (_manifest[key] != (id)kCFNull) {
+ *changedManifest = YES;
+ _manifest[key] = (id)kCFNull;
+ }
+ return errorOut;
+}
+
+- (void)_multiGet:(NSArray *)keys
+ callback:(RCTResponseSenderBlock)callback
+ getter:(NSString * (^)(NSUInteger i, NSString *key, NSDictionary **errorOut))getValue
+{
+ NSMutableArray *errors;
+ NSMutableArray *> *result = [NSMutableArray arrayWithCapacity:keys.count];
+ for (NSUInteger i = 0; i < keys.count; ++i) {
+ NSString *key = keys[i];
+ id keyError;
+ id value = getValue(i, key, &keyError);
+ [result addObject:@[key, RCTNullIfNil(value)]];
+ RCTAppendError(keyError, &errors);
+ }
+ callback(@[RCTNullIfNil(errors), result]);
+}
+
+- (BOOL)_passthroughDelegate
+{
+ return
+ [self.delegate respondsToSelector:@selector(isPassthrough)] && self.delegate.isPassthrough;
+}
+
+#pragma mark - Exported JS Functions
+
+// clang-format off
+RCT_EXPORT_METHOD(multiGet:(NSArray *)keys
+ callback:(RCTResponseSenderBlock)callback)
+// clang-format on
+{
+ if (self.delegate != nil) {
+ [self.delegate
+ valuesForKeys:keys
+ completion:^(NSArray> *valuesOrErrors) {
+ [self _multiGet:keys
+ callback:callback
+ getter:^NSString *(NSUInteger i, NSString *key, NSDictionary **errorOut) {
+ id valueOrError = valuesOrErrors[i];
+ if ([valueOrError isKindOfClass:[NSError class]]) {
+ NSError *error = (NSError *)valueOrError;
+ NSDictionary *extraData = @{@"key": RCTNullIfNil(key)};
+ *errorOut =
+ RCTMakeError(error.localizedDescription, error, extraData);
+ return nil;
+ } else {
+ return [valueOrError isKindOfClass:[NSString class]]
+ ? (NSString *)valueOrError
+ : nil;
+ }
+ }];
+ }];
+
+ if (![self _passthroughDelegate]) {
+ return;
+ }
+ }
+
+ NSDictionary *errorOut = [self _ensureSetup];
+ if (errorOut) {
+ callback(@[@[errorOut], (id)kCFNull]);
+ return;
+ }
+ [self _multiGet:keys
+ callback:callback
+ getter:^(NSUInteger i, NSString *key, NSDictionary **errorOut) {
+ return [self _getValueForKey:key errorOut:errorOut];
+ }];
+}
+
+// clang-format off
+RCT_EXPORT_METHOD(multiSet:(NSArray *> *)kvPairs
+ callback:(RCTResponseSenderBlock)callback)
+// clang-format on
+{
+ if (self.delegate != nil) {
+ NSMutableArray *keys = [NSMutableArray arrayWithCapacity:kvPairs.count];
+ NSMutableArray *values = [NSMutableArray arrayWithCapacity:kvPairs.count];
+ for (NSArray *entry in kvPairs) {
+ [keys addObject:entry[0]];
+ [values addObject:entry[1]];
+ }
+ [self.delegate setValues:values
+ forKeys:keys
+ completion:^(NSArray> *results) {
+ NSArray *errors = RCTMakeErrors(results);
+ callback(@[RCTNullIfNil(errors)]);
+ }];
+
+ if (![self _passthroughDelegate]) {
+ return;
+ }
+ }
+
+ NSDictionary *errorOut = [self _ensureSetup];
+ if (errorOut) {
+ callback(@[@[errorOut]]);
+ return;
+ }
+ BOOL changedManifest = NO;
+ NSMutableArray *errors;
+ for (NSArray *entry in kvPairs) {
+ NSDictionary *keyError = [self _writeEntry:entry changedManifest:&changedManifest];
+ RCTAppendError(keyError, &errors);
+ }
+ if (changedManifest) {
+ [self _writeManifest:&errors];
+ }
+ callback(@[RCTNullIfNil(errors)]);
+}
+
+// clang-format off
+RCT_EXPORT_METHOD(multiMerge:(NSArray *> *)kvPairs
+ callback:(RCTResponseSenderBlock)callback)
+// clang-format on
+{
+ if (self.delegate != nil) {
+ NSMutableArray *keys = [NSMutableArray arrayWithCapacity:kvPairs.count];
+ NSMutableArray *values = [NSMutableArray arrayWithCapacity:kvPairs.count];
+ for (NSArray *entry in kvPairs) {
+ [keys addObject:entry[0]];
+ [values addObject:entry[1]];
+ }
+ [self.delegate mergeValues:values
+ forKeys:keys
+ completion:^(NSArray> *results) {
+ NSArray *errors = RCTMakeErrors(results);
+ callback(@[RCTNullIfNil(errors)]);
+ }];
+
+ if (![self _passthroughDelegate]) {
+ return;
+ }
+ }
+
+ NSDictionary *errorOut = [self _ensureSetup];
+ if (errorOut) {
+ callback(@[@[errorOut]]);
+ return;
+ }
+ BOOL changedManifest = NO;
+ NSMutableArray *errors;
+ for (__strong NSArray *entry in kvPairs) {
+ NSDictionary *keyError;
+ NSString *value = [self _getValueForKey:entry[0] errorOut:&keyError];
+ if (!keyError) {
+ if (value) {
+ NSError *jsonError;
+ NSMutableDictionary *mergedVal = RCTJSONParseMutable(value, &jsonError);
+ if (RCTMergeRecursive(mergedVal, RCTJSONParse(entry[1], &jsonError))) {
+ entry = @[entry[0], RCTNullIfNil(RCTJSONStringify(mergedVal, NULL))];
+ }
+ if (jsonError) {
+ keyError = RCTJSErrorFromNSError(jsonError);
+ }
+ }
+ if (!keyError) {
+ keyError = [self _writeEntry:entry changedManifest:&changedManifest];
+ }
+ }
+ RCTAppendError(keyError, &errors);
+ }
+ if (changedManifest) {
+ [self _writeManifest:&errors];
+ }
+ callback(@[RCTNullIfNil(errors)]);
+}
+
+// clang-format off
+RCT_EXPORT_METHOD(multiRemove:(NSArray *)keys
+ callback:(RCTResponseSenderBlock)callback)
+// clang-format on
+{
+ if (self.delegate != nil) {
+ [self.delegate removeValuesForKeys:keys
+ completion:^(NSArray> *results) {
+ NSArray *errors = RCTMakeErrors(results);
+ callback(@[RCTNullIfNil(errors)]);
+ }];
+
+ if (![self _passthroughDelegate]) {
+ return;
+ }
+ }
+
+ NSDictionary *errorOut = [self _ensureSetup];
+ if (errorOut) {
+ callback(@[@[errorOut]]);
+ return;
+ }
+ NSMutableArray *errors;
+ BOOL changedManifest = NO;
+ for (NSString *key in keys) {
+ NSDictionary *keyError = RCTErrorForKey(key);
+ if (!keyError) {
+ if (_manifest[key] == (id)kCFNull) {
+ NSString *filePath = [self _filePathForKey:key];
+ [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
+ [RCTGetCache() removeObjectForKey:key];
+ }
+ if (_manifest[key]) {
+ changedManifest = YES;
+ [_manifest removeObjectForKey:key];
+ }
+ }
+ RCTAppendError(keyError, &errors);
+ }
+ if (changedManifest) {
+ [self _writeManifest:&errors];
+ }
+ callback(@[RCTNullIfNil(errors)]);
+}
+
+// clang-format off
+RCT_EXPORT_METHOD(clear:(RCTResponseSenderBlock)callback)
+// clang-format on
+{
+ if (self.delegate != nil) {
+ [self.delegate removeAllValues:^(NSError *error) {
+ NSDictionary *result = nil;
+ if (error != nil) {
+ result = RCTMakeError(error.localizedDescription, error, nil);
+ }
+ callback(@[RCTNullIfNil(result)]);
+ }];
+ return;
+ }
+
+ [_manifest removeAllObjects];
+ [RCTGetCache() removeAllObjects];
+ NSDictionary *error = RCTDeleteStorageDirectory();
+ callback(@[RCTNullIfNil(error)]);
+}
+
+// clang-format off
+RCT_EXPORT_METHOD(getAllKeys:(RCTResponseSenderBlock)callback)
+// clang-format on
+{
+ if (self.delegate != nil) {
+ [self.delegate allKeys:^(NSArray> *keys) {
+ callback(@[(id)kCFNull, keys]);
+ }];
+
+ if (![self _passthroughDelegate]) {
+ return;
+ }
+ }
+
+ NSDictionary *errorOut = [self _ensureSetup];
+ if (errorOut) {
+ callback(@[errorOut, (id)kCFNull]);
+ } else {
+ callback(@[(id)kCFNull, _manifest.allKeys]);
+ }
+}
+
+@end
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorage.xcodeproj/project.pbxproj b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorage.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..667fdff8
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorage.xcodeproj/project.pbxproj
@@ -0,0 +1,283 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1990B97A223993B0009E5EA1 /* RNCAsyncStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = B3E7B5881CC2AC0600A0062D /* RNCAsyncStorage.h */; };
+ 1990B97B223993B0009E5EA1 /* RNCAsyncStorageDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1990B9402233FE3A009E5EA1 /* RNCAsyncStorageDelegate.h */; };
+ 747102F0243FFB7400D4F466 /* RNCAsyncStorage.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B3E7B5881CC2AC0600A0062D /* RNCAsyncStorage.h */; };
+ 747102F1243FFB7400D4F466 /* RNCAsyncStorageDelegate.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1990B9402233FE3A009E5EA1 /* RNCAsyncStorageDelegate.h */; };
+ B3E7B58A1CC2AC0600A0062D /* RNCAsyncStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNCAsyncStorage.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 58B511D91A9E6C8500147676 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "include/$(PRODUCT_NAME)";
+ dstSubfolderSpec = 16;
+ files = (
+ 747102F0243FFB7400D4F466 /* RNCAsyncStorage.h in CopyFiles */,
+ 747102F1243FFB7400D4F466 /* RNCAsyncStorageDelegate.h in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 134814201AA4EA6300B7C361 /* libRNCAsyncStorage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNCAsyncStorage.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1990B9402233FE3A009E5EA1 /* RNCAsyncStorageDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNCAsyncStorageDelegate.h; sourceTree = ""; };
+ B3E7B5881CC2AC0600A0062D /* RNCAsyncStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNCAsyncStorage.h; sourceTree = ""; };
+ B3E7B5891CC2AC0600A0062D /* RNCAsyncStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNCAsyncStorage.m; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 58B511D81A9E6C8500147676 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 134814211AA4EA7D00B7C361 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 134814201AA4EA6300B7C361 /* libRNCAsyncStorage.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 58B511D21A9E6C8500147676 = {
+ isa = PBXGroup;
+ children = (
+ B3E7B5881CC2AC0600A0062D /* RNCAsyncStorage.h */,
+ B3E7B5891CC2AC0600A0062D /* RNCAsyncStorage.m */,
+ 1990B9402233FE3A009E5EA1 /* RNCAsyncStorageDelegate.h */,
+ 134814211AA4EA7D00B7C361 /* Products */,
+ );
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 19F94B1D2239A948006921A9 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1990B97A223993B0009E5EA1 /* RNCAsyncStorage.h in Headers */,
+ 1990B97B223993B0009E5EA1 /* RNCAsyncStorageDelegate.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 58B511DA1A9E6C8500147676 /* RNCAsyncStorage */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCAsyncStorage" */;
+ buildPhases = (
+ 19F94B1D2239A948006921A9 /* Headers */,
+ 58B511D71A9E6C8500147676 /* Sources */,
+ 58B511D81A9E6C8500147676 /* Frameworks */,
+ 58B511D91A9E6C8500147676 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = RNCAsyncStorage;
+ productName = RCTDataManager;
+ productReference = 134814201AA4EA6300B7C361 /* libRNCAsyncStorage.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 58B511D31A9E6C8500147676 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0830;
+ ORGANIZATIONNAME = Facebook;
+ TargetAttributes = {
+ 58B511DA1A9E6C8500147676 = {
+ CreatedOnToolsVersion = 6.1.1;
+ };
+ };
+ };
+ buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCAsyncStorage" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ English,
+ en,
+ );
+ mainGroup = 58B511D21A9E6C8500147676;
+ productRefGroup = 58B511D21A9E6C8500147676;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 58B511DA1A9E6C8500147676 /* RNCAsyncStorage */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 58B511D71A9E6C8500147676 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B3E7B58A1CC2AC0600A0062D /* RNCAsyncStorage.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 58B511ED1A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 58B511EE1A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 58B511F01A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../../React/**",
+ "$(SRCROOT)/../../react-native/React/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = RNCAsyncStorage;
+ SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvsimulator appletvos";
+ };
+ name = Debug;
+ };
+ 58B511F11A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../../React/**",
+ "$(SRCROOT)/../../react-native/React/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = RNCAsyncStorage;
+ SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvsimulator appletvos";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCAsyncStorage" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511ED1A9E6C8500147676 /* Debug */,
+ 58B511EE1A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCAsyncStorage" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511F01A9E6C8500147676 /* Debug */,
+ 58B511F11A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 58B511D31A9E6C8500147676 /* Project object */;
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorageDelegate.h b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorageDelegate.h
new file mode 100644
index 00000000..8298099e
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/ios/RNCAsyncStorageDelegate.h
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef void (^RNCAsyncStorageCompletion)(NSError *_Nullable error);
+typedef void (^RNCAsyncStorageResultCallback)(NSArray> *valuesOrErrors);
+
+@protocol RNCAsyncStorageDelegate
+
+/*!
+ * Returns all keys currently stored. If none, an empty array is returned.
+ * @param block Block to call with result.
+ */
+- (void)allKeys:(RNCAsyncStorageResultCallback)block;
+
+/*!
+ * Merges values with the corresponding values stored at specified keys.
+ * @param values Values to merge.
+ * @param keys Keys to the values that should be merged with.
+ * @param block Block to call with merged result.
+ */
+- (void)mergeValues:(NSArray *)values
+ forKeys:(NSArray *)keys
+ completion:(RNCAsyncStorageResultCallback)block;
+
+/*!
+ * Removes all values from the store.
+ * @param block Block to call with result.
+ */
+- (void)removeAllValues:(RNCAsyncStorageCompletion)block;
+
+/*!
+ * Removes all values associated with specified keys.
+ * @param keys Keys of values to remove.
+ * @param block Block to call with result.
+ */
+- (void)removeValuesForKeys:(NSArray *)keys
+ completion:(RNCAsyncStorageResultCallback)block;
+
+/*!
+ * Sets specified key-value pairs.
+ * @param values Values to set.
+ * @param keys Keys of specified values to set.
+ * @param block Block to call with result.
+ */
+- (void)setValues:(NSArray *)values
+ forKeys:(NSArray *)keys
+ completion:(RNCAsyncStorageResultCallback)block;
+
+/*!
+ * Returns values associated with specified keys.
+ * @param keys Keys of values to return.
+ * @param block Block to call with result.
+ */
+- (void)valuesForKeys:(NSArray *)keys completion:(RNCAsyncStorageResultCallback)block;
+
+@optional
+
+/*!
+ * Returns whether the delegate should be treated as a passthrough.
+ */
+@property (nonatomic, readonly, getter=isPassthrough) BOOL passthrough;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/jest/async-storage-mock.d.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/jest/async-storage-mock.d.ts
new file mode 100644
index 00000000..4cd864a0
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/jest/async-storage-mock.d.ts
@@ -0,0 +1,9 @@
+import type {
+ AsyncStorageHook,
+ AsyncStorageStatic,
+} from '../lib/typescript/types';
+
+export function useAsyncStorage(key: string): AsyncStorageHook;
+
+declare const AsyncStorage: AsyncStorageStatic;
+export default AsyncStorage;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/jest/async-storage-mock.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/jest/async-storage-mock.js
new file mode 100644
index 00000000..32ea76df
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/jest/async-storage-mock.js
@@ -0,0 +1,109 @@
+/**
+ * @format
+ */
+
+const merge = require('merge-options').bind({
+ concatArrays: true,
+ ignoreUndefined: true,
+});
+
+const asMock = {
+ __INTERNAL_MOCK_STORAGE__: {},
+
+ setItem: jest.fn(async (key, value, callback) => {
+ const setResult = await asMock.multiSet([[key, value]], undefined);
+
+ callback && callback(setResult);
+ return setResult;
+ }),
+
+ getItem: jest.fn(async (key, callback) => {
+ const getResult = await asMock.multiGet([key], undefined);
+
+ const result = getResult[0] ? getResult[0][1] : null;
+
+ callback && callback(null, result);
+ return result;
+ }),
+
+ removeItem: jest.fn((key, callback) => asMock.multiRemove([key], callback)),
+ mergeItem: jest.fn((key, value, callback) =>
+ asMock.multiMerge([[key, value]], callback)
+ ),
+
+ clear: jest.fn(_clear),
+ getAllKeys: jest.fn(_getAllKeys),
+ flushGetRequests: jest.fn(),
+
+ multiGet: jest.fn(_multiGet),
+ multiSet: jest.fn(_multiSet),
+ multiRemove: jest.fn(_multiRemove),
+ multiMerge: jest.fn(_multiMerge),
+ useAsyncStorage: jest.fn((key) => {
+ return {
+ getItem: (...args) => asMock.getItem(key, ...args),
+ setItem: (...args) => asMock.setItem(key, ...args),
+ mergeItem: (...args) => asMock.mergeItem(key, ...args),
+ removeItem: (...args) => asMock.removeItem(key, ...args),
+ };
+ }),
+};
+
+async function _multiSet(keyValuePairs, callback) {
+ keyValuePairs.forEach((keyValue) => {
+ const key = keyValue[0];
+
+ asMock.__INTERNAL_MOCK_STORAGE__[key] = keyValue[1];
+ });
+ callback && callback(null);
+ return null;
+}
+
+async function _multiGet(keys, callback) {
+ const values = keys.map((key) => [
+ key,
+ asMock.__INTERNAL_MOCK_STORAGE__[key] || null,
+ ]);
+ callback && callback(null, values);
+
+ return values;
+}
+
+async function _multiRemove(keys, callback) {
+ keys.forEach((key) => {
+ if (asMock.__INTERNAL_MOCK_STORAGE__[key]) {
+ delete asMock.__INTERNAL_MOCK_STORAGE__[key];
+ }
+ });
+
+ callback && callback(null);
+ return null;
+}
+
+async function _clear(callback) {
+ asMock.__INTERNAL_MOCK_STORAGE__ = {};
+
+ callback && callback(null);
+
+ return null;
+}
+
+async function _getAllKeys() {
+ return Object.keys(asMock.__INTERNAL_MOCK_STORAGE__);
+}
+
+async function _multiMerge(keyValuePairs, callback) {
+ keyValuePairs.forEach((keyValue) => {
+ const [key, value] = keyValue;
+ const oldValue = asMock.__INTERNAL_MOCK_STORAGE__[key];
+ asMock.__INTERNAL_MOCK_STORAGE__[key] =
+ oldValue != null
+ ? JSON.stringify(merge(JSON.parse(oldValue), JSON.parse(value)))
+ : value;
+ });
+
+ callback && callback(null);
+ return null;
+}
+
+module.exports = asMock;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.js
new file mode 100644
index 00000000..9ee17945
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.js
@@ -0,0 +1,164 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _mergeOptions = _interopRequireDefault(require("merge-options"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Copyright (c) Nicolas Gallagher.
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+// @ts-ignore Cannot find module 'merge-options' or its corresponding type declarations
+const merge = _mergeOptions.default.bind({
+ concatArrays: true,
+ ignoreUndefined: true
+});
+
+function mergeLocalStorageItem(key, value) {
+ const oldValue = window.localStorage.getItem(key);
+
+ if (oldValue) {
+ const oldObject = JSON.parse(oldValue);
+ const newObject = JSON.parse(value);
+ const nextValue = JSON.stringify(merge(oldObject, newObject));
+ window.localStorage.setItem(key, nextValue);
+ } else {
+ window.localStorage.setItem(key, value);
+ }
+}
+
+function createPromise(getValue, callback) {
+ return new Promise((resolve, reject) => {
+ try {
+ const value = getValue();
+ callback === null || callback === void 0 ? void 0 : callback(null, value);
+ resolve(value);
+ } catch (err) {
+ callback === null || callback === void 0 ? void 0 : callback(err);
+ reject(err);
+ }
+ });
+}
+
+function createPromiseAll(promises, callback, processResult) {
+ return Promise.all(promises).then(result => {
+ const value = (processResult === null || processResult === void 0 ? void 0 : processResult(result)) ?? null;
+ callback === null || callback === void 0 ? void 0 : callback(null, value);
+ return Promise.resolve(value);
+ }, errors => {
+ callback === null || callback === void 0 ? void 0 : callback(errors);
+ return Promise.reject(errors);
+ });
+}
+
+const AsyncStorage = {
+ /**
+ * Fetches `key` value.
+ */
+ getItem: (key, callback) => {
+ return createPromise(() => window.localStorage.getItem(key), callback);
+ },
+
+ /**
+ * Sets `value` for `key`.
+ */
+ setItem: (key, value, callback) => {
+ return createPromise(() => window.localStorage.setItem(key, value), callback);
+ },
+
+ /**
+ * Removes a `key`
+ */
+ removeItem: (key, callback) => {
+ return createPromise(() => window.localStorage.removeItem(key), callback);
+ },
+
+ /**
+ * Merges existing value with input value, assuming they are stringified JSON.
+ */
+ mergeItem: (key, value, callback) => {
+ return createPromise(() => mergeLocalStorageItem(key, value), callback);
+ },
+
+ /**
+ * Erases *all* AsyncStorage for the domain.
+ */
+ clear: callback => {
+ return createPromise(() => window.localStorage.clear(), callback);
+ },
+
+ /**
+ * Gets *all* keys known to the app, for all callers, libraries, etc.
+ */
+ getAllKeys: callback => {
+ return createPromise(() => {
+ const numberOfKeys = window.localStorage.length;
+ const keys = [];
+
+ for (let i = 0; i < numberOfKeys; i += 1) {
+ const key = window.localStorage.key(i) || '';
+ keys.push(key);
+ }
+
+ return keys;
+ }, callback);
+ },
+
+ /**
+ * (stub) Flushes any pending requests using a single batch call to get the data.
+ */
+ flushGetRequests: () => undefined,
+
+ /**
+ * multiGet resolves to an array of key-value pair arrays that matches the
+ * input format of multiSet.
+ *
+ * multiGet(['k1', 'k2']) -> [['k1', 'val1'], ['k2', 'val2']]
+ */
+ multiGet: (keys, callback) => {
+ const promises = keys.map(key => AsyncStorage.getItem(key));
+
+ const processResult = result => result.map((value, i) => [keys[i], value]);
+
+ return createPromiseAll(promises, callback, processResult);
+ },
+
+ /**
+ * Takes an array of key-value array pairs.
+ * multiSet([['k1', 'val1'], ['k2', 'val2']])
+ */
+ multiSet: (keyValuePairs, callback) => {
+ const promises = keyValuePairs.map(item => AsyncStorage.setItem(item[0], item[1]));
+ return createPromiseAll(promises, callback);
+ },
+
+ /**
+ * Delete all the keys in the `keys` array.
+ */
+ multiRemove: (keys, callback) => {
+ const promises = keys.map(key => AsyncStorage.removeItem(key));
+ return createPromiseAll(promises, callback);
+ },
+
+ /**
+ * Takes an array of key-value array pairs and merges them with existing
+ * values, assuming they are stringified JSON.
+ *
+ * multiMerge([['k1', 'val1'], ['k2', 'val2']])
+ */
+ multiMerge: (keyValuePairs, callback) => {
+ const promises = keyValuePairs.map(item => AsyncStorage.mergeItem(item[0], item[1]));
+ return createPromiseAll(promises, callback);
+ }
+};
+var _default = AsyncStorage;
+exports.default = _default;
+//# sourceMappingURL=AsyncStorage.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.js.map
new file mode 100644
index 00000000..c31cfe05
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["merge","mergeOptions","bind","concatArrays","ignoreUndefined","mergeLocalStorageItem","key","value","oldValue","window","localStorage","getItem","oldObject","JSON","parse","newObject","nextValue","stringify","setItem","createPromise","getValue","callback","Promise","resolve","reject","err","createPromiseAll","promises","processResult","all","then","result","errors","AsyncStorage","removeItem","mergeItem","clear","getAllKeys","numberOfKeys","length","keys","i","push","flushGetRequests","undefined","multiGet","map","multiSet","keyValuePairs","item","multiRemove","multiMerge"],"sources":["AsyncStorage.ts"],"sourcesContent":["/**\n * Copyright (c) Nicolas Gallagher.\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n// @ts-ignore Cannot find module 'merge-options' or its corresponding type declarations\nimport mergeOptions from 'merge-options';\nimport type {\n AsyncStorageStatic,\n MultiCallback,\n MultiGetCallback,\n} from './types';\n\nconst merge = mergeOptions.bind({\n concatArrays: true,\n ignoreUndefined: true,\n});\n\nfunction mergeLocalStorageItem(key: string, value: string) {\n const oldValue = window.localStorage.getItem(key);\n if (oldValue) {\n const oldObject = JSON.parse(oldValue);\n const newObject = JSON.parse(value);\n const nextValue = JSON.stringify(merge(oldObject, newObject));\n window.localStorage.setItem(key, nextValue);\n } else {\n window.localStorage.setItem(key, value);\n }\n}\n\nfunction createPromise(\n getValue: () => Result,\n callback?: Callback\n): Promise {\n return new Promise((resolve, reject) => {\n try {\n const value = getValue();\n callback?.(null, value);\n resolve(value);\n } catch (err) {\n callback?.(err);\n reject(err);\n }\n });\n}\n\nfunction createPromiseAll(\n promises: Promise[],\n callback?: MultiCallback | MultiGetCallback,\n processResult?: ResultProcessor\n): Promise {\n return Promise.all(promises).then(\n (result) => {\n const value = processResult?.(result) ?? null;\n callback?.(null, value);\n return Promise.resolve(value);\n },\n (errors) => {\n callback?.(errors);\n return Promise.reject(errors);\n }\n );\n}\n\nconst AsyncStorage: AsyncStorageStatic = {\n /**\n * Fetches `key` value.\n */\n getItem: (key, callback) => {\n return createPromise(() => window.localStorage.getItem(key), callback);\n },\n\n /**\n * Sets `value` for `key`.\n */\n setItem: (key, value, callback) => {\n return createPromise(\n () => window.localStorage.setItem(key, value),\n callback\n );\n },\n\n /**\n * Removes a `key`\n */\n removeItem: (key, callback) => {\n return createPromise(() => window.localStorage.removeItem(key), callback);\n },\n\n /**\n * Merges existing value with input value, assuming they are stringified JSON.\n */\n mergeItem: (key, value, callback) => {\n return createPromise(() => mergeLocalStorageItem(key, value), callback);\n },\n\n /**\n * Erases *all* AsyncStorage for the domain.\n */\n clear: (callback) => {\n return createPromise(() => window.localStorage.clear(), callback);\n },\n\n /**\n * Gets *all* keys known to the app, for all callers, libraries, etc.\n */\n getAllKeys: (callback) => {\n return createPromise(() => {\n const numberOfKeys = window.localStorage.length;\n const keys: string[] = [];\n for (let i = 0; i < numberOfKeys; i += 1) {\n const key = window.localStorage.key(i) || '';\n keys.push(key);\n }\n return keys;\n }, callback);\n },\n\n /**\n * (stub) Flushes any pending requests using a single batch call to get the data.\n */\n flushGetRequests: () => undefined,\n\n /**\n * multiGet resolves to an array of key-value pair arrays that matches the\n * input format of multiSet.\n *\n * multiGet(['k1', 'k2']) -> [['k1', 'val1'], ['k2', 'val2']]\n */\n multiGet: (keys, callback) => {\n const promises = keys.map((key) => AsyncStorage.getItem(key));\n const processResult = (result: string[]) =>\n result.map((value, i) => [keys[i], value]);\n return createPromiseAll(promises, callback, processResult);\n },\n\n /**\n * Takes an array of key-value array pairs.\n * multiSet([['k1', 'val1'], ['k2', 'val2']])\n */\n multiSet: (keyValuePairs, callback) => {\n const promises = keyValuePairs.map((item) =>\n AsyncStorage.setItem(item[0], item[1])\n );\n return createPromiseAll(promises, callback);\n },\n\n /**\n * Delete all the keys in the `keys` array.\n */\n multiRemove: (keys, callback) => {\n const promises = keys.map((key) => AsyncStorage.removeItem(key));\n return createPromiseAll(promises, callback);\n },\n\n /**\n * Takes an array of key-value array pairs and merges them with existing\n * values, assuming they are stringified JSON.\n *\n * multiMerge([['k1', 'val1'], ['k2', 'val2']])\n */\n multiMerge: (keyValuePairs, callback) => {\n const promises = keyValuePairs.map((item) =>\n AsyncStorage.mergeItem(item[0], item[1])\n );\n return createPromiseAll(promises, callback);\n },\n};\n\nexport default AsyncStorage;\n"],"mappings":"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"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.native.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.native.js
new file mode 100644
index 00000000..3ef7f652
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.native.js
@@ -0,0 +1,366 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _helpers = require("./helpers");
+
+var _RCTAsyncStorage = _interopRequireDefault(require("./RCTAsyncStorage"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+if (!_RCTAsyncStorage.default) {
+ throw new Error(`[@RNC/AsyncStorage]: NativeModule: AsyncStorage is null.
+
+To fix this issue try these steps:
+
+ • Rebuild and restart the app.
+
+ • Run the packager with \`--reset-cache\` flag.
+
+ • If you are using CocoaPods on iOS, run \`pod install\` in the \`ios\` directory and then rebuild and re-run the app.
+
+ • If this happens while testing with Jest, check out docs how to integrate AsyncStorage with it: https://react-native-async-storage.github.io/async-storage/docs/advanced/jest
+
+If none of these fix the issue, please open an issue on the Github repository: https://github.com/react-native-async-storage/async-storage/issues
+`);
+}
+/**
+ * `AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value
+ * storage system that is global to the app. It should be used instead of
+ * LocalStorage.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api
+ */
+
+
+const AsyncStorage = (() => {
+ let _getRequests = [];
+ let _getKeys = [];
+ let _immediate = null;
+ return {
+ /**
+ * Fetches an item for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#getitem
+ */
+ getItem: (key, callback) => {
+ return new Promise((resolve, reject) => {
+ (0, _helpers.checkValidInput)(key);
+
+ _RCTAsyncStorage.default.multiGet([key], (errors, result) => {
+ var _result$;
+
+ // Unpack result to get value from [[key,value]]
+ const value = result !== null && result !== void 0 && (_result$ = result[0]) !== null && _result$ !== void 0 && _result$[1] ? result[0][1] : null;
+ const errs = (0, _helpers.convertErrors)(errors);
+ callback === null || callback === void 0 ? void 0 : callback(errs === null || errs === void 0 ? void 0 : errs[0], value);
+
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve(value);
+ }
+ });
+ });
+ },
+
+ /**
+ * Sets the value for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#setitem
+ */
+ setItem: (key, value, callback) => {
+ return new Promise((resolve, reject) => {
+ (0, _helpers.checkValidInput)(key, value);
+
+ _RCTAsyncStorage.default.multiSet([[key, value]], errors => {
+ const errs = (0, _helpers.convertErrors)(errors);
+ callback === null || callback === void 0 ? void 0 : callback(errs === null || errs === void 0 ? void 0 : errs[0]);
+
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Removes an item for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#removeitem
+ */
+ removeItem: (key, callback) => {
+ return new Promise((resolve, reject) => {
+ (0, _helpers.checkValidInput)(key);
+
+ _RCTAsyncStorage.default.multiRemove([key], errors => {
+ const errs = (0, _helpers.convertErrors)(errors);
+ callback === null || callback === void 0 ? void 0 : callback(errs === null || errs === void 0 ? void 0 : errs[0]);
+
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Merges an existing `key` value with an input value, assuming both values
+ * are stringified JSON.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#mergeitem
+ */
+ mergeItem: (key, value, callback) => {
+ return new Promise((resolve, reject) => {
+ (0, _helpers.checkValidInput)(key, value);
+
+ _RCTAsyncStorage.default.multiMerge([[key, value]], errors => {
+ const errs = (0, _helpers.convertErrors)(errors);
+ callback === null || callback === void 0 ? void 0 : callback(errs === null || errs === void 0 ? void 0 : errs[0]);
+
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably
+ * don't want to call this; use `removeItem` or `multiRemove` to clear only
+ * your app's keys.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#clear
+ */
+ clear: callback => {
+ return new Promise((resolve, reject) => {
+ _RCTAsyncStorage.default.clear(error => {
+ const err = (0, _helpers.convertError)(error);
+ callback === null || callback === void 0 ? void 0 : callback(err);
+
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Gets *all* keys known to your app; for all callers, libraries, etc.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#getallkeys
+ */
+ getAllKeys: callback => {
+ return new Promise((resolve, reject) => {
+ _RCTAsyncStorage.default.getAllKeys((error, keys) => {
+ const err = (0, _helpers.convertError)(error);
+ callback === null || callback === void 0 ? void 0 : callback(err, keys);
+
+ if (keys) {
+ resolve(keys);
+ } else {
+ reject(err);
+ }
+ });
+ });
+ },
+
+ /**
+ * The following batched functions are useful for executing a lot of
+ * operations at once, allowing for native optimizations and provide the
+ * convenience of a single callback after all operations are complete.
+ *
+ * These functions return arrays of errors, potentially one for every key.
+ * For key-specific errors, the Error object will have a key property to
+ * indicate which key caused the error.
+ */
+
+ /**
+ * Flushes any pending requests using a single batch call to get the data.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#flushgetrequests
+ * */
+ flushGetRequests: () => {
+ const getRequests = _getRequests;
+ const getKeys = _getKeys;
+ _getRequests = [];
+ _getKeys = [];
+
+ _RCTAsyncStorage.default.multiGet(getKeys, (errors, result) => {
+ // Even though the runtime complexity of this is theoretically worse vs if we used a map,
+ // it's much, much faster in practice for the data sets we deal with (we avoid
+ // allocating result pair arrays). This was heavily benchmarked.
+ //
+ // Is there a way to avoid using the map but fix the bug in this breaking test?
+ // https://github.com/facebook/react-native/commit/8dd8ad76579d7feef34c014d387bf02065692264
+ const map = {};
+ result === null || result === void 0 ? void 0 : result.forEach(_ref => {
+ let [key, value] = _ref;
+ map[key] = value;
+ return value;
+ });
+ const reqLength = getRequests.length;
+ /**
+ * As mentioned few lines above, this method could be called with the array of potential error,
+ * in case of anything goes wrong. The problem is, if any of the batched calls fails
+ * the rest of them would fail too, but the error would be consumed by just one. The rest
+ * would simply return `undefined` as their result, rendering false negatives.
+ *
+ * In order to avoid this situation, in case of any call failing,
+ * the rest of them will be rejected as well (with the same error).
+ */
+
+ const errorList = (0, _helpers.convertErrors)(errors);
+ const error = errorList !== null && errorList !== void 0 && errorList.length ? errorList[0] : null;
+
+ for (let i = 0; i < reqLength; i++) {
+ var _request$callback2, _request$resolve;
+
+ const request = getRequests[i];
+
+ if (error) {
+ var _request$callback, _request$reject;
+
+ (_request$callback = request.callback) === null || _request$callback === void 0 ? void 0 : _request$callback.call(request, errorList);
+ (_request$reject = request.reject) === null || _request$reject === void 0 ? void 0 : _request$reject.call(request, error);
+ continue;
+ }
+
+ const requestResult = request.keys.map(key => [key, map[key]]);
+ (_request$callback2 = request.callback) === null || _request$callback2 === void 0 ? void 0 : _request$callback2.call(request, null, requestResult);
+ (_request$resolve = request.resolve) === null || _request$resolve === void 0 ? void 0 : _request$resolve.call(request, requestResult);
+ }
+ });
+ },
+
+ /**
+ * This allows you to batch the fetching of items given an array of `key`
+ * inputs. Your callback will be invoked with an array of corresponding
+ * key-value pairs found.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiget
+ */
+ multiGet: (keys, callback) => {
+ if (!_immediate) {
+ _immediate = setImmediate(() => {
+ _immediate = null;
+ AsyncStorage.flushGetRequests();
+ });
+ }
+
+ const getRequest = {
+ keys: keys,
+ callback: callback,
+ // do we need this?
+ keyIndex: _getKeys.length,
+ resolve: null,
+ reject: null
+ };
+ const promiseResult = new Promise((resolve, reject) => {
+ getRequest.resolve = resolve;
+ getRequest.reject = reject;
+ });
+
+ _getRequests.push(getRequest); // avoid fetching duplicates
+
+
+ keys.forEach(key => {
+ if (_getKeys.indexOf(key) === -1) {
+ _getKeys.push(key);
+ }
+ });
+ return promiseResult;
+ },
+
+ /**
+ * Use this as a batch operation for storing multiple key-value pairs. When
+ * the operation completes you'll get a single callback with any errors.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiset
+ */
+ multiSet: (keyValuePairs, callback) => {
+ (0, _helpers.checkValidArgs)(keyValuePairs, callback);
+ return new Promise((resolve, reject) => {
+ keyValuePairs.forEach(_ref2 => {
+ let [key, value] = _ref2;
+ (0, _helpers.checkValidInput)(key, value);
+ });
+
+ _RCTAsyncStorage.default.multiSet(keyValuePairs, errors => {
+ const error = (0, _helpers.convertErrors)(errors);
+ callback === null || callback === void 0 ? void 0 : callback(error);
+
+ if (error) {
+ reject(error);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Call this to batch the deletion of all keys in the `keys` array.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiremove
+ */
+ multiRemove: (keys, callback) => {
+ return new Promise((resolve, reject) => {
+ keys.forEach(key => (0, _helpers.checkValidInput)(key));
+
+ _RCTAsyncStorage.default.multiRemove(keys, errors => {
+ const error = (0, _helpers.convertErrors)(errors);
+ callback === null || callback === void 0 ? void 0 : callback(error);
+
+ if (error) {
+ reject(error);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Batch operation to merge in existing and new values for a given set of
+ * keys. This assumes that the values are stringified JSON.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multimerge
+ */
+ multiMerge: (keyValuePairs, callback) => {
+ return new Promise((resolve, reject) => {
+ _RCTAsyncStorage.default.multiMerge(keyValuePairs, errors => {
+ const error = (0, _helpers.convertErrors)(errors);
+ callback === null || callback === void 0 ? void 0 : callback(error);
+
+ if (error) {
+ reject(error);
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+ };
+})();
+
+var _default = AsyncStorage;
+exports.default = _default;
+//# sourceMappingURL=AsyncStorage.native.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.native.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.native.js.map
new file mode 100644
index 00000000..3b745592
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/AsyncStorage.native.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["RCTAsyncStorage","Error","AsyncStorage","_getRequests","_getKeys","_immediate","getItem","key","callback","Promise","resolve","reject","checkValidInput","multiGet","errors","result","value","errs","convertErrors","setItem","multiSet","removeItem","multiRemove","mergeItem","multiMerge","clear","error","err","convertError","getAllKeys","keys","flushGetRequests","getRequests","getKeys","map","forEach","reqLength","length","errorList","i","request","requestResult","setImmediate","getRequest","keyIndex","promiseResult","push","indexOf","keyValuePairs","checkValidArgs"],"sources":["AsyncStorage.native.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport {\n checkValidArgs,\n checkValidInput,\n convertError,\n convertErrors,\n} from './helpers';\nimport RCTAsyncStorage from './RCTAsyncStorage';\nimport type {\n AsyncStorageStatic,\n ErrorLike,\n KeyValuePair,\n MultiRequest,\n} from './types';\n\nif (!RCTAsyncStorage) {\n throw new Error(`[@RNC/AsyncStorage]: NativeModule: AsyncStorage is null.\n\nTo fix this issue try these steps:\n\n • Rebuild and restart the app.\n\n • Run the packager with \\`--reset-cache\\` flag.\n\n • If you are using CocoaPods on iOS, run \\`pod install\\` in the \\`ios\\` directory and then rebuild and re-run the app.\n\n • If this happens while testing with Jest, check out docs how to integrate AsyncStorage with it: https://react-native-async-storage.github.io/async-storage/docs/advanced/jest\n\nIf none of these fix the issue, please open an issue on the Github repository: https://github.com/react-native-async-storage/async-storage/issues\n`);\n}\n\n/**\n * `AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value\n * storage system that is global to the app. It should be used instead of\n * LocalStorage.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api\n */\nconst AsyncStorage = ((): AsyncStorageStatic => {\n let _getRequests: MultiRequest[] = [];\n let _getKeys: string[] = [];\n let _immediate: ReturnType | null = null;\n\n return {\n /**\n * Fetches an item for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#getitem\n */\n getItem: (key, callback) => {\n return new Promise((resolve, reject) => {\n checkValidInput(key);\n RCTAsyncStorage.multiGet(\n [key],\n (errors?: ErrorLike[], result?: string[][]) => {\n // Unpack result to get value from [[key,value]]\n const value = result?.[0]?.[1] ? result[0][1] : null;\n const errs = convertErrors(errors);\n callback?.(errs?.[0], value);\n if (errs) {\n reject(errs[0]);\n } else {\n resolve(value);\n }\n }\n );\n });\n },\n\n /**\n * Sets the value for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#setitem\n */\n setItem: (key, value, callback) => {\n return new Promise((resolve, reject) => {\n checkValidInput(key, value);\n RCTAsyncStorage.multiSet([[key, value]], (errors?: ErrorLike[]) => {\n const errs = convertErrors(errors);\n callback?.(errs?.[0]);\n if (errs) {\n reject(errs[0]);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Removes an item for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#removeitem\n */\n removeItem: (key, callback) => {\n return new Promise((resolve, reject) => {\n checkValidInput(key);\n RCTAsyncStorage.multiRemove([key], (errors?: ErrorLike[]) => {\n const errs = convertErrors(errors);\n callback?.(errs?.[0]);\n if (errs) {\n reject(errs[0]);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Merges an existing `key` value with an input value, assuming both values\n * are stringified JSON.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#mergeitem\n */\n mergeItem: (key, value, callback) => {\n return new Promise((resolve, reject) => {\n checkValidInput(key, value);\n RCTAsyncStorage.multiMerge([[key, value]], (errors?: ErrorLike[]) => {\n const errs = convertErrors(errors);\n callback?.(errs?.[0]);\n if (errs) {\n reject(errs[0]);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably\n * don't want to call this; use `removeItem` or `multiRemove` to clear only\n * your app's keys.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#clear\n */\n clear: (callback) => {\n return new Promise((resolve, reject) => {\n RCTAsyncStorage.clear((error?: ErrorLike) => {\n const err = convertError(error);\n callback?.(err);\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Gets *all* keys known to your app; for all callers, libraries, etc.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#getallkeys\n */\n getAllKeys: (callback) => {\n return new Promise((resolve, reject) => {\n RCTAsyncStorage.getAllKeys((error?: ErrorLike, keys?: string[]) => {\n const err = convertError(error);\n callback?.(err, keys);\n if (keys) {\n resolve(keys);\n } else {\n reject(err);\n }\n });\n });\n },\n\n /**\n * The following batched functions are useful for executing a lot of\n * operations at once, allowing for native optimizations and provide the\n * convenience of a single callback after all operations are complete.\n *\n * These functions return arrays of errors, potentially one for every key.\n * For key-specific errors, the Error object will have a key property to\n * indicate which key caused the error.\n */\n\n /**\n * Flushes any pending requests using a single batch call to get the data.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#flushgetrequests\n * */\n flushGetRequests: () => {\n const getRequests = _getRequests;\n const getKeys = _getKeys;\n\n _getRequests = [];\n _getKeys = [];\n\n RCTAsyncStorage.multiGet(\n getKeys,\n (errors?: ErrorLike[], result?: string[][]) => {\n // Even though the runtime complexity of this is theoretically worse vs if we used a map,\n // it's much, much faster in practice for the data sets we deal with (we avoid\n // allocating result pair arrays). This was heavily benchmarked.\n //\n // Is there a way to avoid using the map but fix the bug in this breaking test?\n // https://github.com/facebook/react-native/commit/8dd8ad76579d7feef34c014d387bf02065692264\n const map: Record = {};\n result?.forEach(([key, value]) => {\n map[key] = value;\n return value;\n });\n const reqLength = getRequests.length;\n\n /**\n * As mentioned few lines above, this method could be called with the array of potential error,\n * in case of anything goes wrong. The problem is, if any of the batched calls fails\n * the rest of them would fail too, but the error would be consumed by just one. The rest\n * would simply return `undefined` as their result, rendering false negatives.\n *\n * In order to avoid this situation, in case of any call failing,\n * the rest of them will be rejected as well (with the same error).\n */\n const errorList = convertErrors(errors);\n const error = errorList?.length ? errorList[0] : null;\n\n for (let i = 0; i < reqLength; i++) {\n const request = getRequests[i];\n if (error) {\n request.callback?.(errorList);\n request.reject?.(error);\n continue;\n }\n const requestResult = request.keys.map((key) => [\n key,\n map[key],\n ]);\n request.callback?.(null, requestResult);\n request.resolve?.(requestResult);\n }\n }\n );\n },\n\n /**\n * This allows you to batch the fetching of items given an array of `key`\n * inputs. Your callback will be invoked with an array of corresponding\n * key-value pairs found.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiget\n */\n multiGet: (keys, callback) => {\n if (!_immediate) {\n _immediate = setImmediate(() => {\n _immediate = null;\n AsyncStorage.flushGetRequests();\n });\n }\n\n const getRequest: MultiRequest = {\n keys: keys,\n callback: callback,\n // do we need this?\n keyIndex: _getKeys.length,\n resolve: null as any,\n reject: null as any,\n };\n\n const promiseResult = new Promise(\n (resolve, reject) => {\n getRequest.resolve = resolve;\n getRequest.reject = reject;\n }\n );\n\n _getRequests.push(getRequest);\n // avoid fetching duplicates\n keys.forEach((key) => {\n if (_getKeys.indexOf(key) === -1) {\n _getKeys.push(key);\n }\n });\n\n return promiseResult;\n },\n\n /**\n * Use this as a batch operation for storing multiple key-value pairs. When\n * the operation completes you'll get a single callback with any errors.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiset\n */\n multiSet: (keyValuePairs, callback) => {\n checkValidArgs(keyValuePairs, callback);\n return new Promise((resolve, reject) => {\n keyValuePairs.forEach(([key, value]) => {\n checkValidInput(key, value);\n });\n\n RCTAsyncStorage.multiSet(keyValuePairs, (errors?: ErrorLike[]) => {\n const error = convertErrors(errors);\n callback?.(error);\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Call this to batch the deletion of all keys in the `keys` array.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiremove\n */\n multiRemove: (keys, callback) => {\n return new Promise((resolve, reject) => {\n keys.forEach((key) => checkValidInput(key));\n\n RCTAsyncStorage.multiRemove(keys, (errors?: ErrorLike[]) => {\n const error = convertErrors(errors);\n callback?.(error);\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Batch operation to merge in existing and new values for a given set of\n * keys. This assumes that the values are stringified JSON.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multimerge\n */\n multiMerge: (keyValuePairs, callback) => {\n return new Promise((resolve, reject) => {\n RCTAsyncStorage.multiMerge(keyValuePairs, (errors?: ErrorLike[]) => {\n const error = convertErrors(errors);\n callback?.(error);\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n },\n };\n})();\n\nexport default AsyncStorage;\n"],"mappings":"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"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/RCTAsyncStorage.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/RCTAsyncStorage.js
new file mode 100644
index 00000000..a52465e0
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/RCTAsyncStorage.js
@@ -0,0 +1,29 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _reactNative = require("react-native");
+
+var _shouldFallbackToLegacyNativeModule = require("./shouldFallbackToLegacyNativeModule");
+
+// @ts-ignore Module '"react-native"' has no exported member 'TurboModuleRegistry'.
+let RCTAsyncStorage = _reactNative.NativeModules['PlatformLocalStorage'] || // Support for external modules, like react-native-windows
+_reactNative.NativeModules['RNC_AsyncSQLiteDBStorage'] || _reactNative.NativeModules['RNCAsyncStorage'];
+
+if (!RCTAsyncStorage && (0, _shouldFallbackToLegacyNativeModule.shouldFallbackToLegacyNativeModule)()) {
+ // TurboModuleRegistry falls back to NativeModules so we don't have to try go
+ // assign NativeModules' counterparts if TurboModuleRegistry would resolve
+ // with undefined.
+ if (_reactNative.TurboModuleRegistry) {
+ RCTAsyncStorage = _reactNative.TurboModuleRegistry.get('AsyncSQLiteDBStorage') || _reactNative.TurboModuleRegistry.get('AsyncLocalStorage');
+ } else {
+ RCTAsyncStorage = _reactNative.NativeModules['AsyncSQLiteDBStorage'] || _reactNative.NativeModules['AsyncLocalStorage'];
+ }
+}
+
+var _default = RCTAsyncStorage;
+exports.default = _default;
+//# sourceMappingURL=RCTAsyncStorage.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/RCTAsyncStorage.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/RCTAsyncStorage.js.map
new file mode 100644
index 00000000..dd5e00db
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/RCTAsyncStorage.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["RCTAsyncStorage","NativeModules","shouldFallbackToLegacyNativeModule","TurboModuleRegistry","get"],"sources":["RCTAsyncStorage.ts"],"sourcesContent":["// @ts-ignore Module '\"react-native\"' has no exported member 'TurboModuleRegistry'.\nimport { NativeModules, TurboModuleRegistry } from 'react-native';\nimport { shouldFallbackToLegacyNativeModule } from './shouldFallbackToLegacyNativeModule';\n\nlet RCTAsyncStorage =\n NativeModules['PlatformLocalStorage'] || // Support for external modules, like react-native-windows\n NativeModules['RNC_AsyncSQLiteDBStorage'] ||\n NativeModules['RNCAsyncStorage'];\n\nif (!RCTAsyncStorage && shouldFallbackToLegacyNativeModule()) {\n // TurboModuleRegistry falls back to NativeModules so we don't have to try go\n // assign NativeModules' counterparts if TurboModuleRegistry would resolve\n // with undefined.\n if (TurboModuleRegistry) {\n RCTAsyncStorage =\n TurboModuleRegistry.get('AsyncSQLiteDBStorage') ||\n TurboModuleRegistry.get('AsyncLocalStorage');\n } else {\n RCTAsyncStorage =\n NativeModules['AsyncSQLiteDBStorage'] ||\n NativeModules['AsyncLocalStorage'];\n }\n}\n\nexport default RCTAsyncStorage;\n"],"mappings":";;;;;;;AACA;;AACA;;AAFA;AAIA,IAAIA,eAAe,GACjBC,0BAAA,CAAc,sBAAd,KAAyC;AACzCA,0BAAA,CAAc,0BAAd,CADA,IAEAA,0BAAA,CAAc,iBAAd,CAHF;;AAKA,IAAI,CAACD,eAAD,IAAoB,IAAAE,sEAAA,GAAxB,EAA8D;EAC5D;EACA;EACA;EACA,IAAIC,gCAAJ,EAAyB;IACvBH,eAAe,GACbG,gCAAA,CAAoBC,GAApB,CAAwB,sBAAxB,KACAD,gCAAA,CAAoBC,GAApB,CAAwB,mBAAxB,CAFF;EAGD,CAJD,MAIO;IACLJ,eAAe,GACbC,0BAAA,CAAc,sBAAd,KACAA,0BAAA,CAAc,mBAAd,CAFF;EAGD;AACF;;eAEcD,e"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/helpers.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/helpers.js
new file mode 100644
index 00000000..83589c26
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/helpers.js
@@ -0,0 +1,69 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.checkValidArgs = checkValidArgs;
+exports.checkValidInput = checkValidInput;
+exports.convertError = convertError;
+exports.convertErrors = convertErrors;
+
+function checkValidArgs(keyValuePairs, callback) {
+ if (!Array.isArray(keyValuePairs) || keyValuePairs.length === 0 || !Array.isArray(keyValuePairs[0])) {
+ throw new Error('[AsyncStorage] Expected array of key-value pairs as first argument to multiSet');
+ }
+
+ if (callback && typeof callback !== 'function') {
+ if (Array.isArray(callback)) {
+ throw new Error('[AsyncStorage] Expected function as second argument to multiSet. Did you forget to wrap key-value pairs in an array for the first argument?');
+ }
+
+ throw new Error('[AsyncStorage] Expected function as second argument to multiSet');
+ }
+}
+
+function checkValidInput() {
+ for (var _len = arguments.length, input = new Array(_len), _key = 0; _key < _len; _key++) {
+ input[_key] = arguments[_key];
+ }
+
+ const [key, value] = input;
+
+ if (typeof key !== 'string') {
+ console.warn(`[AsyncStorage] Using ${typeof key} type for key is not supported. This can lead to unexpected behavior/errors. Use string instead.\nKey passed: ${key}\n`);
+ }
+
+ if (input.length > 1 && typeof value !== 'string') {
+ if (value == null) {
+ throw new Error(`[AsyncStorage] Passing null/undefined as value is not supported. If you want to remove value, Use .removeItem method instead.\nPassed value: ${value}\nPassed key: ${key}\n`);
+ } else {
+ console.warn(`[AsyncStorage] The value for key "${key}" is not a string. This can lead to unexpected behavior/errors. Consider stringifying it.\nPassed value: ${value}\nPassed key: ${key}\n`);
+ }
+ }
+}
+
+function convertError(error) {
+ if (!error) {
+ return null;
+ }
+
+ const out = new Error(error.message);
+ out.key = error.key;
+ return out;
+}
+
+function convertErrors(errs) {
+ const errors = ensureArray(errs);
+ return errors ? errors.map(e => convertError(e)) : null;
+}
+
+function ensureArray(e) {
+ if (Array.isArray(e)) {
+ return e.length === 0 ? null : e;
+ } else if (e) {
+ return [e];
+ } else {
+ return null;
+ }
+}
+//# sourceMappingURL=helpers.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/helpers.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/helpers.js.map
new file mode 100644
index 00000000..addcceee
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/helpers.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["checkValidArgs","keyValuePairs","callback","Array","isArray","length","Error","checkValidInput","input","key","value","console","warn","convertError","error","out","message","convertErrors","errs","errors","ensureArray","map","e"],"sources":["helpers.ts"],"sourcesContent":["import type { ErrorLike } from './types';\n\nexport function checkValidArgs(keyValuePairs: unknown[], callback: unknown) {\n if (\n !Array.isArray(keyValuePairs) ||\n keyValuePairs.length === 0 ||\n !Array.isArray(keyValuePairs[0])\n ) {\n throw new Error(\n '[AsyncStorage] Expected array of key-value pairs as first argument to multiSet'\n );\n }\n\n if (callback && typeof callback !== 'function') {\n if (Array.isArray(callback)) {\n throw new Error(\n '[AsyncStorage] Expected function as second argument to multiSet. Did you forget to wrap key-value pairs in an array for the first argument?'\n );\n }\n\n throw new Error(\n '[AsyncStorage] Expected function as second argument to multiSet'\n );\n }\n}\n\nexport function checkValidInput(...input: unknown[]) {\n const [key, value] = input;\n\n if (typeof key !== 'string') {\n console.warn(\n `[AsyncStorage] Using ${typeof key} type for key is not supported. This can lead to unexpected behavior/errors. Use string instead.\\nKey passed: ${key}\\n`\n );\n }\n\n if (input.length > 1 && typeof value !== 'string') {\n if (value == null) {\n throw new Error(\n `[AsyncStorage] Passing null/undefined as value is not supported. If you want to remove value, Use .removeItem method instead.\\nPassed value: ${value}\\nPassed key: ${key}\\n`\n );\n } else {\n console.warn(\n `[AsyncStorage] The value for key \"${key}\" is not a string. This can lead to unexpected behavior/errors. Consider stringifying it.\\nPassed value: ${value}\\nPassed key: ${key}\\n`\n );\n }\n }\n}\n\nexport function convertError(error?: ErrorLike): Error | null {\n if (!error) {\n return null;\n }\n\n const out = new Error(error.message);\n (out as any).key = error.key;\n return out;\n}\n\nexport function convertErrors(\n errs?: ErrorLike[]\n): ReadonlyArray | null {\n const errors = ensureArray(errs);\n return errors ? errors.map((e) => convertError(e)) : null;\n}\n\nfunction ensureArray(e?: ErrorLike | ErrorLike[]): ErrorLike[] | null {\n if (Array.isArray(e)) {\n return e.length === 0 ? null : e;\n } else if (e) {\n return [e];\n } else {\n return null;\n }\n}\n"],"mappings":";;;;;;;;;;AAEO,SAASA,cAAT,CAAwBC,aAAxB,EAAkDC,QAAlD,EAAqE;EAC1E,IACE,CAACC,KAAK,CAACC,OAAN,CAAcH,aAAd,CAAD,IACAA,aAAa,CAACI,MAAd,KAAyB,CADzB,IAEA,CAACF,KAAK,CAACC,OAAN,CAAcH,aAAa,CAAC,CAAD,CAA3B,CAHH,EAIE;IACA,MAAM,IAAIK,KAAJ,CACJ,gFADI,CAAN;EAGD;;EAED,IAAIJ,QAAQ,IAAI,OAAOA,QAAP,KAAoB,UAApC,EAAgD;IAC9C,IAAIC,KAAK,CAACC,OAAN,CAAcF,QAAd,CAAJ,EAA6B;MAC3B,MAAM,IAAII,KAAJ,CACJ,6IADI,CAAN;IAGD;;IAED,MAAM,IAAIA,KAAJ,CACJ,iEADI,CAAN;EAGD;AACF;;AAEM,SAASC,eAAT,GAA8C;EAAA,kCAAlBC,KAAkB;IAAlBA,KAAkB;EAAA;;EACnD,MAAM,CAACC,GAAD,EAAMC,KAAN,IAAeF,KAArB;;EAEA,IAAI,OAAOC,GAAP,KAAe,QAAnB,EAA6B;IAC3BE,OAAO,CAACC,IAAR,CACG,wBAAuB,OAAOH,GAAI,iHAAgHA,GAAI,IADzJ;EAGD;;EAED,IAAID,KAAK,CAACH,MAAN,GAAe,CAAf,IAAoB,OAAOK,KAAP,KAAiB,QAAzC,EAAmD;IACjD,IAAIA,KAAK,IAAI,IAAb,EAAmB;MACjB,MAAM,IAAIJ,KAAJ,CACH,gJAA+II,KAAM,iBAAgBD,GAAI,IADtK,CAAN;IAGD,CAJD,MAIO;MACLE,OAAO,CAACC,IAAR,CACG,qCAAoCH,GAAI,4GAA2GC,KAAM,iBAAgBD,GAAI,IADhL;IAGD;EACF;AACF;;AAEM,SAASI,YAAT,CAAsBC,KAAtB,EAAuD;EAC5D,IAAI,CAACA,KAAL,EAAY;IACV,OAAO,IAAP;EACD;;EAED,MAAMC,GAAG,GAAG,IAAIT,KAAJ,CAAUQ,KAAK,CAACE,OAAhB,CAAZ;EACCD,GAAD,CAAaN,GAAb,GAAmBK,KAAK,CAACL,GAAzB;EACA,OAAOM,GAAP;AACD;;AAEM,SAASE,aAAT,CACLC,IADK,EAE+B;EACpC,MAAMC,MAAM,GAAGC,WAAW,CAACF,IAAD,CAA1B;EACA,OAAOC,MAAM,GAAGA,MAAM,CAACE,GAAP,CAAYC,CAAD,IAAOT,YAAY,CAACS,CAAD,CAA9B,CAAH,GAAwC,IAArD;AACD;;AAED,SAASF,WAAT,CAAqBE,CAArB,EAAsE;EACpE,IAAInB,KAAK,CAACC,OAAN,CAAckB,CAAd,CAAJ,EAAsB;IACpB,OAAOA,CAAC,CAACjB,MAAF,KAAa,CAAb,GAAiB,IAAjB,GAAwBiB,CAA/B;EACD,CAFD,MAEO,IAAIA,CAAJ,EAAO;IACZ,OAAO,CAACA,CAAD,CAAP;EACD,CAFM,MAEA;IACL,OAAO,IAAP;EACD;AACF"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/hooks.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/hooks.js
new file mode 100644
index 00000000..1e6c171f
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/hooks.js
@@ -0,0 +1,44 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.useAsyncStorage = useAsyncStorage;
+
+var _AsyncStorage = _interopRequireDefault(require("./AsyncStorage"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function useAsyncStorage(key) {
+ return {
+ getItem: function () {
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+
+ return _AsyncStorage.default.getItem(key, ...args);
+ },
+ setItem: function () {
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+ args[_key2] = arguments[_key2];
+ }
+
+ return _AsyncStorage.default.setItem(key, ...args);
+ },
+ mergeItem: function () {
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
+ args[_key3] = arguments[_key3];
+ }
+
+ return _AsyncStorage.default.mergeItem(key, ...args);
+ },
+ removeItem: function () {
+ for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
+ args[_key4] = arguments[_key4];
+ }
+
+ return _AsyncStorage.default.removeItem(key, ...args);
+ }
+ };
+}
+//# sourceMappingURL=hooks.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/hooks.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/hooks.js.map
new file mode 100644
index 00000000..7d5668d0
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/hooks.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["useAsyncStorage","key","getItem","args","AsyncStorage","setItem","mergeItem","removeItem"],"sources":["hooks.ts"],"sourcesContent":["import AsyncStorage from './AsyncStorage';\nimport type { AsyncStorageHook } from './types';\n\nexport function useAsyncStorage(key: string): AsyncStorageHook {\n return {\n getItem: (...args) => AsyncStorage.getItem(key, ...args),\n setItem: (...args) => AsyncStorage.setItem(key, ...args),\n mergeItem: (...args) => AsyncStorage.mergeItem(key, ...args),\n removeItem: (...args) => AsyncStorage.removeItem(key, ...args),\n };\n}\n"],"mappings":";;;;;;;AAAA;;;;AAGO,SAASA,eAAT,CAAyBC,GAAzB,EAAwD;EAC7D,OAAO;IACLC,OAAO,EAAE;MAAA,kCAAIC,IAAJ;QAAIA,IAAJ;MAAA;;MAAA,OAAaC,qBAAA,CAAaF,OAAb,CAAqBD,GAArB,EAA0B,GAAGE,IAA7B,CAAb;IAAA,CADJ;IAELE,OAAO,EAAE;MAAA,mCAAIF,IAAJ;QAAIA,IAAJ;MAAA;;MAAA,OAAaC,qBAAA,CAAaC,OAAb,CAAqBJ,GAArB,EAA0B,GAAGE,IAA7B,CAAb;IAAA,CAFJ;IAGLG,SAAS,EAAE;MAAA,mCAAIH,IAAJ;QAAIA,IAAJ;MAAA;;MAAA,OAAaC,qBAAA,CAAaE,SAAb,CAAuBL,GAAvB,EAA4B,GAAGE,IAA/B,CAAb;IAAA,CAHN;IAILI,UAAU,EAAE;MAAA,mCAAIJ,IAAJ;QAAIA,IAAJ;MAAA;;MAAA,OAAaC,qBAAA,CAAaG,UAAb,CAAwBN,GAAxB,EAA6B,GAAGE,IAAhC,CAAb;IAAA;EAJP,CAAP;AAMD"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/index.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/index.js
new file mode 100644
index 00000000..c4c73b54
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/index.js
@@ -0,0 +1,22 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+Object.defineProperty(exports, "useAsyncStorage", {
+ enumerable: true,
+ get: function () {
+ return _hooks.useAsyncStorage;
+ }
+});
+
+var _AsyncStorage = _interopRequireDefault(require("./AsyncStorage"));
+
+var _hooks = require("./hooks");
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var _default = _AsyncStorage.default;
+exports.default = _default;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/index.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/index.js.map
new file mode 100644
index 00000000..e8464f2f
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/index.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["AsyncStorage"],"sources":["index.ts"],"sourcesContent":["import AsyncStorage from './AsyncStorage';\n\nexport { useAsyncStorage } from './hooks';\n\nexport type { AsyncStorageStatic } from './types';\n\nexport default AsyncStorage;\n"],"mappings":";;;;;;;;;;;;;AAAA;;AAEA;;;;eAIeA,qB"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/shouldFallbackToLegacyNativeModule.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/shouldFallbackToLegacyNativeModule.js
new file mode 100644
index 00000000..f9bf514e
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/shouldFallbackToLegacyNativeModule.js
@@ -0,0 +1,39 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.shouldFallbackToLegacyNativeModule = shouldFallbackToLegacyNativeModule;
+
+var _reactNative = require("react-native");
+
+function shouldFallbackToLegacyNativeModule() {
+ var _NativeModules$Native, _NativeModules$Native2;
+
+ const expoConstants = (_NativeModules$Native = _reactNative.NativeModules['NativeUnimoduleProxy']) === null || _NativeModules$Native === void 0 ? void 0 : (_NativeModules$Native2 = _NativeModules$Native.modulesConstants) === null || _NativeModules$Native2 === void 0 ? void 0 : _NativeModules$Native2.ExponentConstants;
+
+ if (expoConstants) {
+ /**
+ * In SDK <= 39, appOwnership is defined in managed apps but executionEnvironment is not.
+ * In bare React Native apps using expo-constants, appOwnership is never defined, so
+ * isLegacySdkVersion will be false in that context.
+ */
+ const isLegacySdkVersion = expoConstants.appOwnership && !expoConstants.executionEnvironment;
+ /**
+ * Expo managed apps don't include the @react-native-async-storage/async-storage
+ * native modules yet, but the API interface is the same, so we can use the version
+ * exported from React Native still.
+ *
+ * If in future releases (eg: @react-native-async-storage/async-storage >= 2.0.0) this
+ * will likely not be valid anymore, and the package will need to be included in the Expo SDK
+ * to continue to work.
+ */
+
+ if (isLegacySdkVersion || ['storeClient', 'standalone'].includes(expoConstants.executionEnvironment)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+//# sourceMappingURL=shouldFallbackToLegacyNativeModule.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/shouldFallbackToLegacyNativeModule.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/shouldFallbackToLegacyNativeModule.js.map
new file mode 100644
index 00000000..a1342e9b
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/shouldFallbackToLegacyNativeModule.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["shouldFallbackToLegacyNativeModule","expoConstants","NativeModules","modulesConstants","ExponentConstants","isLegacySdkVersion","appOwnership","executionEnvironment","includes"],"sources":["shouldFallbackToLegacyNativeModule.ts"],"sourcesContent":["import { NativeModules } from 'react-native';\n\nexport function shouldFallbackToLegacyNativeModule(): boolean {\n const expoConstants =\n NativeModules['NativeUnimoduleProxy']?.modulesConstants?.ExponentConstants;\n\n if (expoConstants) {\n /**\n * In SDK <= 39, appOwnership is defined in managed apps but executionEnvironment is not.\n * In bare React Native apps using expo-constants, appOwnership is never defined, so\n * isLegacySdkVersion will be false in that context.\n */\n const isLegacySdkVersion =\n expoConstants.appOwnership && !expoConstants.executionEnvironment;\n\n /**\n * Expo managed apps don't include the @react-native-async-storage/async-storage\n * native modules yet, but the API interface is the same, so we can use the version\n * exported from React Native still.\n *\n * If in future releases (eg: @react-native-async-storage/async-storage >= 2.0.0) this\n * will likely not be valid anymore, and the package will need to be included in the Expo SDK\n * to continue to work.\n */\n if (\n isLegacySdkVersion ||\n ['storeClient', 'standalone'].includes(expoConstants.executionEnvironment)\n ) {\n return true;\n }\n }\n\n return false;\n}\n"],"mappings":";;;;;;;AAAA;;AAEO,SAASA,kCAAT,GAAuD;EAAA;;EAC5D,MAAMC,aAAa,4BACjBC,0BAAA,CAAc,sBAAd,CADiB,oFACjB,sBAAuCC,gBADtB,2DACjB,uBAAyDC,iBAD3D;;EAGA,IAAIH,aAAJ,EAAmB;IACjB;AACJ;AACA;AACA;AACA;IACI,MAAMI,kBAAkB,GACtBJ,aAAa,CAACK,YAAd,IAA8B,CAACL,aAAa,CAACM,oBAD/C;IAGA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;IACI,IACEF,kBAAkB,IAClB,CAAC,aAAD,EAAgB,YAAhB,EAA8BG,QAA9B,CAAuCP,aAAa,CAACM,oBAArD,CAFF,EAGE;MACA,OAAO,IAAP;IACD;EACF;;EAED,OAAO,KAAP;AACD"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/types.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/types.js
new file mode 100644
index 00000000..2f0e4146
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/types.js
@@ -0,0 +1,2 @@
+"use strict";
+//# sourceMappingURL=types.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/types.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/types.js.map
new file mode 100644
index 00000000..f5d8ef90
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/commonjs/types.js.map
@@ -0,0 +1 @@
+{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["export type ErrorLike = {\n message: string;\n key: string;\n};\n\nexport type Callback = (error?: Error | null) => void;\n\nexport type CallbackWithResult = (\n error?: Error | null,\n result?: T | null\n) => void;\n\nexport type KeyValuePair = [string, string | null];\n\nexport type MultiCallback = (errors?: readonly (Error | null)[] | null) => void;\n\nexport type MultiGetCallback = (\n errors?: readonly (Error | null)[] | null,\n result?: readonly KeyValuePair[]\n) => void;\n\nexport type MultiRequest = {\n keys: readonly string[];\n callback?: MultiGetCallback;\n keyIndex: number;\n resolve?: (result: readonly KeyValuePair[]) => void;\n reject?: (error?: any) => void;\n};\n\nexport type AsyncStorageHook = {\n getItem: (callback?: CallbackWithResult) => Promise;\n setItem: (value: string, callback?: Callback) => Promise;\n mergeItem: (value: string, callback?: Callback) => Promise;\n removeItem: (callback?: Callback) => Promise;\n};\n\n/**\n * `AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value\n * storage system that is global to the app. It should be used instead of\n * LocalStorage.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api\n */\nexport type AsyncStorageStatic = {\n /**\n * Fetches an item for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#getitem\n */\n getItem: (\n key: string,\n callback?: CallbackWithResult\n ) => Promise;\n\n /**\n * Sets the value for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#setitem\n */\n setItem: (key: string, value: string, callback?: Callback) => Promise;\n\n /**\n * Removes an item for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#removeitem\n */\n removeItem: (key: string, callback?: Callback) => Promise;\n\n /**\n * Merges an existing `key` value with an input value, assuming both values\n * are stringified JSON.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#mergeitem\n */\n mergeItem: (key: string, value: string, callback?: Callback) => Promise;\n\n /**\n * Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably\n * don't want to call this; use `removeItem` or `multiRemove` to clear only\n * your app's keys.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#clear\n */\n clear: (callback?: Callback) => Promise;\n\n /**\n * Gets *all* keys known to your app; for all callers, libraries, etc.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#getallkeys\n */\n getAllKeys: (\n callback?: CallbackWithResult\n ) => Promise;\n\n /**\n * The following batched functions are useful for executing a lot of\n * operations at once, allowing for native optimizations and provide the\n * convenience of a single callback after all operations are complete.\n *\n * These functions return arrays of errors, potentially one for every key.\n * For key-specific errors, the Error object will have a key property to\n * indicate which key caused the error.\n */\n\n /**\n * Flushes any pending requests using a single batch call to get the data.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#flushgetrequests\n * */\n flushGetRequests: () => void;\n\n /**\n * This allows you to batch the fetching of items given an array of `key`\n * inputs. Your callback will be invoked with an array of corresponding\n * key-value pairs found.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiget\n */\n multiGet: (\n keys: readonly string[],\n callback?: MultiGetCallback\n ) => Promise;\n\n /**\n * Use this as a batch operation for storing multiple key-value pairs. When\n * the operation completes you'll get a single callback with any errors.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiset\n */\n multiSet: (\n keyValuePairs: [string, string][],\n callback?: MultiCallback\n ) => Promise;\n\n /**\n * Call this to batch the deletion of all keys in the `keys` array.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiremove\n */\n multiRemove: (\n keys: readonly string[],\n callback?: MultiCallback\n ) => Promise;\n\n /**\n * Batch operation to merge in existing and new values for a given set of\n * keys. This assumes that the values are stringified JSON.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multimerge\n */\n multiMerge: (\n keyValuePairs: [string, string][],\n callback?: MultiCallback\n ) => Promise;\n};\n"],"mappings":""}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.js
new file mode 100644
index 00000000..cc833f85
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.js
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) Nicolas Gallagher.
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+// @ts-ignore Cannot find module 'merge-options' or its corresponding type declarations
+import mergeOptions from 'merge-options';
+const merge = mergeOptions.bind({
+ concatArrays: true,
+ ignoreUndefined: true
+});
+
+function mergeLocalStorageItem(key, value) {
+ const oldValue = window.localStorage.getItem(key);
+
+ if (oldValue) {
+ const oldObject = JSON.parse(oldValue);
+ const newObject = JSON.parse(value);
+ const nextValue = JSON.stringify(merge(oldObject, newObject));
+ window.localStorage.setItem(key, nextValue);
+ } else {
+ window.localStorage.setItem(key, value);
+ }
+}
+
+function createPromise(getValue, callback) {
+ return new Promise((resolve, reject) => {
+ try {
+ const value = getValue();
+ callback === null || callback === void 0 ? void 0 : callback(null, value);
+ resolve(value);
+ } catch (err) {
+ callback === null || callback === void 0 ? void 0 : callback(err);
+ reject(err);
+ }
+ });
+}
+
+function createPromiseAll(promises, callback, processResult) {
+ return Promise.all(promises).then(result => {
+ const value = (processResult === null || processResult === void 0 ? void 0 : processResult(result)) ?? null;
+ callback === null || callback === void 0 ? void 0 : callback(null, value);
+ return Promise.resolve(value);
+ }, errors => {
+ callback === null || callback === void 0 ? void 0 : callback(errors);
+ return Promise.reject(errors);
+ });
+}
+
+const AsyncStorage = {
+ /**
+ * Fetches `key` value.
+ */
+ getItem: (key, callback) => {
+ return createPromise(() => window.localStorage.getItem(key), callback);
+ },
+
+ /**
+ * Sets `value` for `key`.
+ */
+ setItem: (key, value, callback) => {
+ return createPromise(() => window.localStorage.setItem(key, value), callback);
+ },
+
+ /**
+ * Removes a `key`
+ */
+ removeItem: (key, callback) => {
+ return createPromise(() => window.localStorage.removeItem(key), callback);
+ },
+
+ /**
+ * Merges existing value with input value, assuming they are stringified JSON.
+ */
+ mergeItem: (key, value, callback) => {
+ return createPromise(() => mergeLocalStorageItem(key, value), callback);
+ },
+
+ /**
+ * Erases *all* AsyncStorage for the domain.
+ */
+ clear: callback => {
+ return createPromise(() => window.localStorage.clear(), callback);
+ },
+
+ /**
+ * Gets *all* keys known to the app, for all callers, libraries, etc.
+ */
+ getAllKeys: callback => {
+ return createPromise(() => {
+ const numberOfKeys = window.localStorage.length;
+ const keys = [];
+
+ for (let i = 0; i < numberOfKeys; i += 1) {
+ const key = window.localStorage.key(i) || '';
+ keys.push(key);
+ }
+
+ return keys;
+ }, callback);
+ },
+
+ /**
+ * (stub) Flushes any pending requests using a single batch call to get the data.
+ */
+ flushGetRequests: () => undefined,
+
+ /**
+ * multiGet resolves to an array of key-value pair arrays that matches the
+ * input format of multiSet.
+ *
+ * multiGet(['k1', 'k2']) -> [['k1', 'val1'], ['k2', 'val2']]
+ */
+ multiGet: (keys, callback) => {
+ const promises = keys.map(key => AsyncStorage.getItem(key));
+
+ const processResult = result => result.map((value, i) => [keys[i], value]);
+
+ return createPromiseAll(promises, callback, processResult);
+ },
+
+ /**
+ * Takes an array of key-value array pairs.
+ * multiSet([['k1', 'val1'], ['k2', 'val2']])
+ */
+ multiSet: (keyValuePairs, callback) => {
+ const promises = keyValuePairs.map(item => AsyncStorage.setItem(item[0], item[1]));
+ return createPromiseAll(promises, callback);
+ },
+
+ /**
+ * Delete all the keys in the `keys` array.
+ */
+ multiRemove: (keys, callback) => {
+ const promises = keys.map(key => AsyncStorage.removeItem(key));
+ return createPromiseAll(promises, callback);
+ },
+
+ /**
+ * Takes an array of key-value array pairs and merges them with existing
+ * values, assuming they are stringified JSON.
+ *
+ * multiMerge([['k1', 'val1'], ['k2', 'val2']])
+ */
+ multiMerge: (keyValuePairs, callback) => {
+ const promises = keyValuePairs.map(item => AsyncStorage.mergeItem(item[0], item[1]));
+ return createPromiseAll(promises, callback);
+ }
+};
+export default AsyncStorage;
+//# sourceMappingURL=AsyncStorage.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.js.map
new file mode 100644
index 00000000..e769ab5b
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["mergeOptions","merge","bind","concatArrays","ignoreUndefined","mergeLocalStorageItem","key","value","oldValue","window","localStorage","getItem","oldObject","JSON","parse","newObject","nextValue","stringify","setItem","createPromise","getValue","callback","Promise","resolve","reject","err","createPromiseAll","promises","processResult","all","then","result","errors","AsyncStorage","removeItem","mergeItem","clear","getAllKeys","numberOfKeys","length","keys","i","push","flushGetRequests","undefined","multiGet","map","multiSet","keyValuePairs","item","multiRemove","multiMerge"],"sources":["AsyncStorage.ts"],"sourcesContent":["/**\n * Copyright (c) Nicolas Gallagher.\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n// @ts-ignore Cannot find module 'merge-options' or its corresponding type declarations\nimport mergeOptions from 'merge-options';\nimport type {\n AsyncStorageStatic,\n MultiCallback,\n MultiGetCallback,\n} from './types';\n\nconst merge = mergeOptions.bind({\n concatArrays: true,\n ignoreUndefined: true,\n});\n\nfunction mergeLocalStorageItem(key: string, value: string) {\n const oldValue = window.localStorage.getItem(key);\n if (oldValue) {\n const oldObject = JSON.parse(oldValue);\n const newObject = JSON.parse(value);\n const nextValue = JSON.stringify(merge(oldObject, newObject));\n window.localStorage.setItem(key, nextValue);\n } else {\n window.localStorage.setItem(key, value);\n }\n}\n\nfunction createPromise(\n getValue: () => Result,\n callback?: Callback\n): Promise {\n return new Promise((resolve, reject) => {\n try {\n const value = getValue();\n callback?.(null, value);\n resolve(value);\n } catch (err) {\n callback?.(err);\n reject(err);\n }\n });\n}\n\nfunction createPromiseAll(\n promises: Promise[],\n callback?: MultiCallback | MultiGetCallback,\n processResult?: ResultProcessor\n): Promise {\n return Promise.all(promises).then(\n (result) => {\n const value = processResult?.(result) ?? null;\n callback?.(null, value);\n return Promise.resolve(value);\n },\n (errors) => {\n callback?.(errors);\n return Promise.reject(errors);\n }\n );\n}\n\nconst AsyncStorage: AsyncStorageStatic = {\n /**\n * Fetches `key` value.\n */\n getItem: (key, callback) => {\n return createPromise(() => window.localStorage.getItem(key), callback);\n },\n\n /**\n * Sets `value` for `key`.\n */\n setItem: (key, value, callback) => {\n return createPromise(\n () => window.localStorage.setItem(key, value),\n callback\n );\n },\n\n /**\n * Removes a `key`\n */\n removeItem: (key, callback) => {\n return createPromise(() => window.localStorage.removeItem(key), callback);\n },\n\n /**\n * Merges existing value with input value, assuming they are stringified JSON.\n */\n mergeItem: (key, value, callback) => {\n return createPromise(() => mergeLocalStorageItem(key, value), callback);\n },\n\n /**\n * Erases *all* AsyncStorage for the domain.\n */\n clear: (callback) => {\n return createPromise(() => window.localStorage.clear(), callback);\n },\n\n /**\n * Gets *all* keys known to the app, for all callers, libraries, etc.\n */\n getAllKeys: (callback) => {\n return createPromise(() => {\n const numberOfKeys = window.localStorage.length;\n const keys: string[] = [];\n for (let i = 0; i < numberOfKeys; i += 1) {\n const key = window.localStorage.key(i) || '';\n keys.push(key);\n }\n return keys;\n }, callback);\n },\n\n /**\n * (stub) Flushes any pending requests using a single batch call to get the data.\n */\n flushGetRequests: () => undefined,\n\n /**\n * multiGet resolves to an array of key-value pair arrays that matches the\n * input format of multiSet.\n *\n * multiGet(['k1', 'k2']) -> [['k1', 'val1'], ['k2', 'val2']]\n */\n multiGet: (keys, callback) => {\n const promises = keys.map((key) => AsyncStorage.getItem(key));\n const processResult = (result: string[]) =>\n result.map((value, i) => [keys[i], value]);\n return createPromiseAll(promises, callback, processResult);\n },\n\n /**\n * Takes an array of key-value array pairs.\n * multiSet([['k1', 'val1'], ['k2', 'val2']])\n */\n multiSet: (keyValuePairs, callback) => {\n const promises = keyValuePairs.map((item) =>\n AsyncStorage.setItem(item[0], item[1])\n );\n return createPromiseAll(promises, callback);\n },\n\n /**\n * Delete all the keys in the `keys` array.\n */\n multiRemove: (keys, callback) => {\n const promises = keys.map((key) => AsyncStorage.removeItem(key));\n return createPromiseAll(promises, callback);\n },\n\n /**\n * Takes an array of key-value array pairs and merges them with existing\n * values, assuming they are stringified JSON.\n *\n * multiMerge([['k1', 'val1'], ['k2', 'val2']])\n */\n multiMerge: (keyValuePairs, callback) => {\n const promises = keyValuePairs.map((item) =>\n AsyncStorage.mergeItem(item[0], item[1])\n );\n return createPromiseAll(promises, callback);\n },\n};\n\nexport default AsyncStorage;\n"],"mappings":"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"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.native.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.native.js
new file mode 100644
index 00000000..2d6032b1
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.native.js
@@ -0,0 +1,348 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+import { checkValidArgs, checkValidInput, convertError, convertErrors } from './helpers';
+import RCTAsyncStorage from './RCTAsyncStorage';
+
+if (!RCTAsyncStorage) {
+ throw new Error(`[@RNC/AsyncStorage]: NativeModule: AsyncStorage is null.
+
+To fix this issue try these steps:
+
+ • Rebuild and restart the app.
+
+ • Run the packager with \`--reset-cache\` flag.
+
+ • If you are using CocoaPods on iOS, run \`pod install\` in the \`ios\` directory and then rebuild and re-run the app.
+
+ • If this happens while testing with Jest, check out docs how to integrate AsyncStorage with it: https://react-native-async-storage.github.io/async-storage/docs/advanced/jest
+
+If none of these fix the issue, please open an issue on the Github repository: https://github.com/react-native-async-storage/async-storage/issues
+`);
+}
+/**
+ * `AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value
+ * storage system that is global to the app. It should be used instead of
+ * LocalStorage.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api
+ */
+
+
+const AsyncStorage = (() => {
+ let _getRequests = [];
+ let _getKeys = [];
+ let _immediate = null;
+ return {
+ /**
+ * Fetches an item for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#getitem
+ */
+ getItem: (key, callback) => {
+ return new Promise((resolve, reject) => {
+ checkValidInput(key);
+ RCTAsyncStorage.multiGet([key], (errors, result) => {
+ var _result$;
+
+ // Unpack result to get value from [[key,value]]
+ const value = result !== null && result !== void 0 && (_result$ = result[0]) !== null && _result$ !== void 0 && _result$[1] ? result[0][1] : null;
+ const errs = convertErrors(errors);
+ callback === null || callback === void 0 ? void 0 : callback(errs === null || errs === void 0 ? void 0 : errs[0], value);
+
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve(value);
+ }
+ });
+ });
+ },
+
+ /**
+ * Sets the value for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#setitem
+ */
+ setItem: (key, value, callback) => {
+ return new Promise((resolve, reject) => {
+ checkValidInput(key, value);
+ RCTAsyncStorage.multiSet([[key, value]], errors => {
+ const errs = convertErrors(errors);
+ callback === null || callback === void 0 ? void 0 : callback(errs === null || errs === void 0 ? void 0 : errs[0]);
+
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Removes an item for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#removeitem
+ */
+ removeItem: (key, callback) => {
+ return new Promise((resolve, reject) => {
+ checkValidInput(key);
+ RCTAsyncStorage.multiRemove([key], errors => {
+ const errs = convertErrors(errors);
+ callback === null || callback === void 0 ? void 0 : callback(errs === null || errs === void 0 ? void 0 : errs[0]);
+
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Merges an existing `key` value with an input value, assuming both values
+ * are stringified JSON.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#mergeitem
+ */
+ mergeItem: (key, value, callback) => {
+ return new Promise((resolve, reject) => {
+ checkValidInput(key, value);
+ RCTAsyncStorage.multiMerge([[key, value]], errors => {
+ const errs = convertErrors(errors);
+ callback === null || callback === void 0 ? void 0 : callback(errs === null || errs === void 0 ? void 0 : errs[0]);
+
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably
+ * don't want to call this; use `removeItem` or `multiRemove` to clear only
+ * your app's keys.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#clear
+ */
+ clear: callback => {
+ return new Promise((resolve, reject) => {
+ RCTAsyncStorage.clear(error => {
+ const err = convertError(error);
+ callback === null || callback === void 0 ? void 0 : callback(err);
+
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Gets *all* keys known to your app; for all callers, libraries, etc.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#getallkeys
+ */
+ getAllKeys: callback => {
+ return new Promise((resolve, reject) => {
+ RCTAsyncStorage.getAllKeys((error, keys) => {
+ const err = convertError(error);
+ callback === null || callback === void 0 ? void 0 : callback(err, keys);
+
+ if (keys) {
+ resolve(keys);
+ } else {
+ reject(err);
+ }
+ });
+ });
+ },
+
+ /**
+ * The following batched functions are useful for executing a lot of
+ * operations at once, allowing for native optimizations and provide the
+ * convenience of a single callback after all operations are complete.
+ *
+ * These functions return arrays of errors, potentially one for every key.
+ * For key-specific errors, the Error object will have a key property to
+ * indicate which key caused the error.
+ */
+
+ /**
+ * Flushes any pending requests using a single batch call to get the data.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#flushgetrequests
+ * */
+ flushGetRequests: () => {
+ const getRequests = _getRequests;
+ const getKeys = _getKeys;
+ _getRequests = [];
+ _getKeys = [];
+ RCTAsyncStorage.multiGet(getKeys, (errors, result) => {
+ // Even though the runtime complexity of this is theoretically worse vs if we used a map,
+ // it's much, much faster in practice for the data sets we deal with (we avoid
+ // allocating result pair arrays). This was heavily benchmarked.
+ //
+ // Is there a way to avoid using the map but fix the bug in this breaking test?
+ // https://github.com/facebook/react-native/commit/8dd8ad76579d7feef34c014d387bf02065692264
+ const map = {};
+ result === null || result === void 0 ? void 0 : result.forEach(_ref => {
+ let [key, value] = _ref;
+ map[key] = value;
+ return value;
+ });
+ const reqLength = getRequests.length;
+ /**
+ * As mentioned few lines above, this method could be called with the array of potential error,
+ * in case of anything goes wrong. The problem is, if any of the batched calls fails
+ * the rest of them would fail too, but the error would be consumed by just one. The rest
+ * would simply return `undefined` as their result, rendering false negatives.
+ *
+ * In order to avoid this situation, in case of any call failing,
+ * the rest of them will be rejected as well (with the same error).
+ */
+
+ const errorList = convertErrors(errors);
+ const error = errorList !== null && errorList !== void 0 && errorList.length ? errorList[0] : null;
+
+ for (let i = 0; i < reqLength; i++) {
+ var _request$callback2, _request$resolve;
+
+ const request = getRequests[i];
+
+ if (error) {
+ var _request$callback, _request$reject;
+
+ (_request$callback = request.callback) === null || _request$callback === void 0 ? void 0 : _request$callback.call(request, errorList);
+ (_request$reject = request.reject) === null || _request$reject === void 0 ? void 0 : _request$reject.call(request, error);
+ continue;
+ }
+
+ const requestResult = request.keys.map(key => [key, map[key]]);
+ (_request$callback2 = request.callback) === null || _request$callback2 === void 0 ? void 0 : _request$callback2.call(request, null, requestResult);
+ (_request$resolve = request.resolve) === null || _request$resolve === void 0 ? void 0 : _request$resolve.call(request, requestResult);
+ }
+ });
+ },
+
+ /**
+ * This allows you to batch the fetching of items given an array of `key`
+ * inputs. Your callback will be invoked with an array of corresponding
+ * key-value pairs found.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiget
+ */
+ multiGet: (keys, callback) => {
+ if (!_immediate) {
+ _immediate = setImmediate(() => {
+ _immediate = null;
+ AsyncStorage.flushGetRequests();
+ });
+ }
+
+ const getRequest = {
+ keys: keys,
+ callback: callback,
+ // do we need this?
+ keyIndex: _getKeys.length,
+ resolve: null,
+ reject: null
+ };
+ const promiseResult = new Promise((resolve, reject) => {
+ getRequest.resolve = resolve;
+ getRequest.reject = reject;
+ });
+
+ _getRequests.push(getRequest); // avoid fetching duplicates
+
+
+ keys.forEach(key => {
+ if (_getKeys.indexOf(key) === -1) {
+ _getKeys.push(key);
+ }
+ });
+ return promiseResult;
+ },
+
+ /**
+ * Use this as a batch operation for storing multiple key-value pairs. When
+ * the operation completes you'll get a single callback with any errors.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiset
+ */
+ multiSet: (keyValuePairs, callback) => {
+ checkValidArgs(keyValuePairs, callback);
+ return new Promise((resolve, reject) => {
+ keyValuePairs.forEach(_ref2 => {
+ let [key, value] = _ref2;
+ checkValidInput(key, value);
+ });
+ RCTAsyncStorage.multiSet(keyValuePairs, errors => {
+ const error = convertErrors(errors);
+ callback === null || callback === void 0 ? void 0 : callback(error);
+
+ if (error) {
+ reject(error);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Call this to batch the deletion of all keys in the `keys` array.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiremove
+ */
+ multiRemove: (keys, callback) => {
+ return new Promise((resolve, reject) => {
+ keys.forEach(key => checkValidInput(key));
+ RCTAsyncStorage.multiRemove(keys, errors => {
+ const error = convertErrors(errors);
+ callback === null || callback === void 0 ? void 0 : callback(error);
+
+ if (error) {
+ reject(error);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Batch operation to merge in existing and new values for a given set of
+ * keys. This assumes that the values are stringified JSON.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multimerge
+ */
+ multiMerge: (keyValuePairs, callback) => {
+ return new Promise((resolve, reject) => {
+ RCTAsyncStorage.multiMerge(keyValuePairs, errors => {
+ const error = convertErrors(errors);
+ callback === null || callback === void 0 ? void 0 : callback(error);
+
+ if (error) {
+ reject(error);
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+ };
+})();
+
+export default AsyncStorage;
+//# sourceMappingURL=AsyncStorage.native.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.native.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.native.js.map
new file mode 100644
index 00000000..2cbcfe7d
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage.native.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["checkValidArgs","checkValidInput","convertError","convertErrors","RCTAsyncStorage","Error","AsyncStorage","_getRequests","_getKeys","_immediate","getItem","key","callback","Promise","resolve","reject","multiGet","errors","result","value","errs","setItem","multiSet","removeItem","multiRemove","mergeItem","multiMerge","clear","error","err","getAllKeys","keys","flushGetRequests","getRequests","getKeys","map","forEach","reqLength","length","errorList","i","request","requestResult","setImmediate","getRequest","keyIndex","promiseResult","push","indexOf","keyValuePairs"],"sources":["AsyncStorage.native.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport {\n checkValidArgs,\n checkValidInput,\n convertError,\n convertErrors,\n} from './helpers';\nimport RCTAsyncStorage from './RCTAsyncStorage';\nimport type {\n AsyncStorageStatic,\n ErrorLike,\n KeyValuePair,\n MultiRequest,\n} from './types';\n\nif (!RCTAsyncStorage) {\n throw new Error(`[@RNC/AsyncStorage]: NativeModule: AsyncStorage is null.\n\nTo fix this issue try these steps:\n\n • Rebuild and restart the app.\n\n • Run the packager with \\`--reset-cache\\` flag.\n\n • If you are using CocoaPods on iOS, run \\`pod install\\` in the \\`ios\\` directory and then rebuild and re-run the app.\n\n • If this happens while testing with Jest, check out docs how to integrate AsyncStorage with it: https://react-native-async-storage.github.io/async-storage/docs/advanced/jest\n\nIf none of these fix the issue, please open an issue on the Github repository: https://github.com/react-native-async-storage/async-storage/issues\n`);\n}\n\n/**\n * `AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value\n * storage system that is global to the app. It should be used instead of\n * LocalStorage.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api\n */\nconst AsyncStorage = ((): AsyncStorageStatic => {\n let _getRequests: MultiRequest[] = [];\n let _getKeys: string[] = [];\n let _immediate: ReturnType | null = null;\n\n return {\n /**\n * Fetches an item for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#getitem\n */\n getItem: (key, callback) => {\n return new Promise((resolve, reject) => {\n checkValidInput(key);\n RCTAsyncStorage.multiGet(\n [key],\n (errors?: ErrorLike[], result?: string[][]) => {\n // Unpack result to get value from [[key,value]]\n const value = result?.[0]?.[1] ? result[0][1] : null;\n const errs = convertErrors(errors);\n callback?.(errs?.[0], value);\n if (errs) {\n reject(errs[0]);\n } else {\n resolve(value);\n }\n }\n );\n });\n },\n\n /**\n * Sets the value for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#setitem\n */\n setItem: (key, value, callback) => {\n return new Promise((resolve, reject) => {\n checkValidInput(key, value);\n RCTAsyncStorage.multiSet([[key, value]], (errors?: ErrorLike[]) => {\n const errs = convertErrors(errors);\n callback?.(errs?.[0]);\n if (errs) {\n reject(errs[0]);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Removes an item for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#removeitem\n */\n removeItem: (key, callback) => {\n return new Promise((resolve, reject) => {\n checkValidInput(key);\n RCTAsyncStorage.multiRemove([key], (errors?: ErrorLike[]) => {\n const errs = convertErrors(errors);\n callback?.(errs?.[0]);\n if (errs) {\n reject(errs[0]);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Merges an existing `key` value with an input value, assuming both values\n * are stringified JSON.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#mergeitem\n */\n mergeItem: (key, value, callback) => {\n return new Promise((resolve, reject) => {\n checkValidInput(key, value);\n RCTAsyncStorage.multiMerge([[key, value]], (errors?: ErrorLike[]) => {\n const errs = convertErrors(errors);\n callback?.(errs?.[0]);\n if (errs) {\n reject(errs[0]);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably\n * don't want to call this; use `removeItem` or `multiRemove` to clear only\n * your app's keys.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#clear\n */\n clear: (callback) => {\n return new Promise((resolve, reject) => {\n RCTAsyncStorage.clear((error?: ErrorLike) => {\n const err = convertError(error);\n callback?.(err);\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Gets *all* keys known to your app; for all callers, libraries, etc.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#getallkeys\n */\n getAllKeys: (callback) => {\n return new Promise((resolve, reject) => {\n RCTAsyncStorage.getAllKeys((error?: ErrorLike, keys?: string[]) => {\n const err = convertError(error);\n callback?.(err, keys);\n if (keys) {\n resolve(keys);\n } else {\n reject(err);\n }\n });\n });\n },\n\n /**\n * The following batched functions are useful for executing a lot of\n * operations at once, allowing for native optimizations and provide the\n * convenience of a single callback after all operations are complete.\n *\n * These functions return arrays of errors, potentially one for every key.\n * For key-specific errors, the Error object will have a key property to\n * indicate which key caused the error.\n */\n\n /**\n * Flushes any pending requests using a single batch call to get the data.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#flushgetrequests\n * */\n flushGetRequests: () => {\n const getRequests = _getRequests;\n const getKeys = _getKeys;\n\n _getRequests = [];\n _getKeys = [];\n\n RCTAsyncStorage.multiGet(\n getKeys,\n (errors?: ErrorLike[], result?: string[][]) => {\n // Even though the runtime complexity of this is theoretically worse vs if we used a map,\n // it's much, much faster in practice for the data sets we deal with (we avoid\n // allocating result pair arrays). This was heavily benchmarked.\n //\n // Is there a way to avoid using the map but fix the bug in this breaking test?\n // https://github.com/facebook/react-native/commit/8dd8ad76579d7feef34c014d387bf02065692264\n const map: Record = {};\n result?.forEach(([key, value]) => {\n map[key] = value;\n return value;\n });\n const reqLength = getRequests.length;\n\n /**\n * As mentioned few lines above, this method could be called with the array of potential error,\n * in case of anything goes wrong. The problem is, if any of the batched calls fails\n * the rest of them would fail too, but the error would be consumed by just one. The rest\n * would simply return `undefined` as their result, rendering false negatives.\n *\n * In order to avoid this situation, in case of any call failing,\n * the rest of them will be rejected as well (with the same error).\n */\n const errorList = convertErrors(errors);\n const error = errorList?.length ? errorList[0] : null;\n\n for (let i = 0; i < reqLength; i++) {\n const request = getRequests[i];\n if (error) {\n request.callback?.(errorList);\n request.reject?.(error);\n continue;\n }\n const requestResult = request.keys.map((key) => [\n key,\n map[key],\n ]);\n request.callback?.(null, requestResult);\n request.resolve?.(requestResult);\n }\n }\n );\n },\n\n /**\n * This allows you to batch the fetching of items given an array of `key`\n * inputs. Your callback will be invoked with an array of corresponding\n * key-value pairs found.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiget\n */\n multiGet: (keys, callback) => {\n if (!_immediate) {\n _immediate = setImmediate(() => {\n _immediate = null;\n AsyncStorage.flushGetRequests();\n });\n }\n\n const getRequest: MultiRequest = {\n keys: keys,\n callback: callback,\n // do we need this?\n keyIndex: _getKeys.length,\n resolve: null as any,\n reject: null as any,\n };\n\n const promiseResult = new Promise(\n (resolve, reject) => {\n getRequest.resolve = resolve;\n getRequest.reject = reject;\n }\n );\n\n _getRequests.push(getRequest);\n // avoid fetching duplicates\n keys.forEach((key) => {\n if (_getKeys.indexOf(key) === -1) {\n _getKeys.push(key);\n }\n });\n\n return promiseResult;\n },\n\n /**\n * Use this as a batch operation for storing multiple key-value pairs. When\n * the operation completes you'll get a single callback with any errors.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiset\n */\n multiSet: (keyValuePairs, callback) => {\n checkValidArgs(keyValuePairs, callback);\n return new Promise((resolve, reject) => {\n keyValuePairs.forEach(([key, value]) => {\n checkValidInput(key, value);\n });\n\n RCTAsyncStorage.multiSet(keyValuePairs, (errors?: ErrorLike[]) => {\n const error = convertErrors(errors);\n callback?.(error);\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Call this to batch the deletion of all keys in the `keys` array.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiremove\n */\n multiRemove: (keys, callback) => {\n return new Promise((resolve, reject) => {\n keys.forEach((key) => checkValidInput(key));\n\n RCTAsyncStorage.multiRemove(keys, (errors?: ErrorLike[]) => {\n const error = convertErrors(errors);\n callback?.(error);\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n },\n\n /**\n * Batch operation to merge in existing and new values for a given set of\n * keys. This assumes that the values are stringified JSON.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multimerge\n */\n multiMerge: (keyValuePairs, callback) => {\n return new Promise((resolve, reject) => {\n RCTAsyncStorage.multiMerge(keyValuePairs, (errors?: ErrorLike[]) => {\n const error = convertErrors(errors);\n callback?.(error);\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n },\n };\n})();\n\nexport default AsyncStorage;\n"],"mappings":"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"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/RCTAsyncStorage.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/RCTAsyncStorage.js
new file mode 100644
index 00000000..2ee10b4f
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/RCTAsyncStorage.js
@@ -0,0 +1,19 @@
+// @ts-ignore Module '"react-native"' has no exported member 'TurboModuleRegistry'.
+import { NativeModules, TurboModuleRegistry } from 'react-native';
+import { shouldFallbackToLegacyNativeModule } from './shouldFallbackToLegacyNativeModule';
+let RCTAsyncStorage = NativeModules['PlatformLocalStorage'] || // Support for external modules, like react-native-windows
+NativeModules['RNC_AsyncSQLiteDBStorage'] || NativeModules['RNCAsyncStorage'];
+
+if (!RCTAsyncStorage && shouldFallbackToLegacyNativeModule()) {
+ // TurboModuleRegistry falls back to NativeModules so we don't have to try go
+ // assign NativeModules' counterparts if TurboModuleRegistry would resolve
+ // with undefined.
+ if (TurboModuleRegistry) {
+ RCTAsyncStorage = TurboModuleRegistry.get('AsyncSQLiteDBStorage') || TurboModuleRegistry.get('AsyncLocalStorage');
+ } else {
+ RCTAsyncStorage = NativeModules['AsyncSQLiteDBStorage'] || NativeModules['AsyncLocalStorage'];
+ }
+}
+
+export default RCTAsyncStorage;
+//# sourceMappingURL=RCTAsyncStorage.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/RCTAsyncStorage.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/RCTAsyncStorage.js.map
new file mode 100644
index 00000000..34ff9ce6
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/RCTAsyncStorage.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["NativeModules","TurboModuleRegistry","shouldFallbackToLegacyNativeModule","RCTAsyncStorage","get"],"sources":["RCTAsyncStorage.ts"],"sourcesContent":["// @ts-ignore Module '\"react-native\"' has no exported member 'TurboModuleRegistry'.\nimport { NativeModules, TurboModuleRegistry } from 'react-native';\nimport { shouldFallbackToLegacyNativeModule } from './shouldFallbackToLegacyNativeModule';\n\nlet RCTAsyncStorage =\n NativeModules['PlatformLocalStorage'] || // Support for external modules, like react-native-windows\n NativeModules['RNC_AsyncSQLiteDBStorage'] ||\n NativeModules['RNCAsyncStorage'];\n\nif (!RCTAsyncStorage && shouldFallbackToLegacyNativeModule()) {\n // TurboModuleRegistry falls back to NativeModules so we don't have to try go\n // assign NativeModules' counterparts if TurboModuleRegistry would resolve\n // with undefined.\n if (TurboModuleRegistry) {\n RCTAsyncStorage =\n TurboModuleRegistry.get('AsyncSQLiteDBStorage') ||\n TurboModuleRegistry.get('AsyncLocalStorage');\n } else {\n RCTAsyncStorage =\n NativeModules['AsyncSQLiteDBStorage'] ||\n NativeModules['AsyncLocalStorage'];\n }\n}\n\nexport default RCTAsyncStorage;\n"],"mappings":"AAAA;AACA,SAASA,aAAT,EAAwBC,mBAAxB,QAAmD,cAAnD;AACA,SAASC,kCAAT,QAAmD,sCAAnD;AAEA,IAAIC,eAAe,GACjBH,aAAa,CAAC,sBAAD,CAAb,IAAyC;AACzCA,aAAa,CAAC,0BAAD,CADb,IAEAA,aAAa,CAAC,iBAAD,CAHf;;AAKA,IAAI,CAACG,eAAD,IAAoBD,kCAAkC,EAA1D,EAA8D;EAC5D;EACA;EACA;EACA,IAAID,mBAAJ,EAAyB;IACvBE,eAAe,GACbF,mBAAmB,CAACG,GAApB,CAAwB,sBAAxB,KACAH,mBAAmB,CAACG,GAApB,CAAwB,mBAAxB,CAFF;EAGD,CAJD,MAIO;IACLD,eAAe,GACbH,aAAa,CAAC,sBAAD,CAAb,IACAA,aAAa,CAAC,mBAAD,CAFf;EAGD;AACF;;AAED,eAAeG,eAAf"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/helpers.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/helpers.js
new file mode 100644
index 00000000..0752f415
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/helpers.js
@@ -0,0 +1,56 @@
+export function checkValidArgs(keyValuePairs, callback) {
+ if (!Array.isArray(keyValuePairs) || keyValuePairs.length === 0 || !Array.isArray(keyValuePairs[0])) {
+ throw new Error('[AsyncStorage] Expected array of key-value pairs as first argument to multiSet');
+ }
+
+ if (callback && typeof callback !== 'function') {
+ if (Array.isArray(callback)) {
+ throw new Error('[AsyncStorage] Expected function as second argument to multiSet. Did you forget to wrap key-value pairs in an array for the first argument?');
+ }
+
+ throw new Error('[AsyncStorage] Expected function as second argument to multiSet');
+ }
+}
+export function checkValidInput() {
+ for (var _len = arguments.length, input = new Array(_len), _key = 0; _key < _len; _key++) {
+ input[_key] = arguments[_key];
+ }
+
+ const [key, value] = input;
+
+ if (typeof key !== 'string') {
+ console.warn(`[AsyncStorage] Using ${typeof key} type for key is not supported. This can lead to unexpected behavior/errors. Use string instead.\nKey passed: ${key}\n`);
+ }
+
+ if (input.length > 1 && typeof value !== 'string') {
+ if (value == null) {
+ throw new Error(`[AsyncStorage] Passing null/undefined as value is not supported. If you want to remove value, Use .removeItem method instead.\nPassed value: ${value}\nPassed key: ${key}\n`);
+ } else {
+ console.warn(`[AsyncStorage] The value for key "${key}" is not a string. This can lead to unexpected behavior/errors. Consider stringifying it.\nPassed value: ${value}\nPassed key: ${key}\n`);
+ }
+ }
+}
+export function convertError(error) {
+ if (!error) {
+ return null;
+ }
+
+ const out = new Error(error.message);
+ out.key = error.key;
+ return out;
+}
+export function convertErrors(errs) {
+ const errors = ensureArray(errs);
+ return errors ? errors.map(e => convertError(e)) : null;
+}
+
+function ensureArray(e) {
+ if (Array.isArray(e)) {
+ return e.length === 0 ? null : e;
+ } else if (e) {
+ return [e];
+ } else {
+ return null;
+ }
+}
+//# sourceMappingURL=helpers.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/helpers.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/helpers.js.map
new file mode 100644
index 00000000..3f4cf548
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/helpers.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["checkValidArgs","keyValuePairs","callback","Array","isArray","length","Error","checkValidInput","input","key","value","console","warn","convertError","error","out","message","convertErrors","errs","errors","ensureArray","map","e"],"sources":["helpers.ts"],"sourcesContent":["import type { ErrorLike } from './types';\n\nexport function checkValidArgs(keyValuePairs: unknown[], callback: unknown) {\n if (\n !Array.isArray(keyValuePairs) ||\n keyValuePairs.length === 0 ||\n !Array.isArray(keyValuePairs[0])\n ) {\n throw new Error(\n '[AsyncStorage] Expected array of key-value pairs as first argument to multiSet'\n );\n }\n\n if (callback && typeof callback !== 'function') {\n if (Array.isArray(callback)) {\n throw new Error(\n '[AsyncStorage] Expected function as second argument to multiSet. Did you forget to wrap key-value pairs in an array for the first argument?'\n );\n }\n\n throw new Error(\n '[AsyncStorage] Expected function as second argument to multiSet'\n );\n }\n}\n\nexport function checkValidInput(...input: unknown[]) {\n const [key, value] = input;\n\n if (typeof key !== 'string') {\n console.warn(\n `[AsyncStorage] Using ${typeof key} type for key is not supported. This can lead to unexpected behavior/errors. Use string instead.\\nKey passed: ${key}\\n`\n );\n }\n\n if (input.length > 1 && typeof value !== 'string') {\n if (value == null) {\n throw new Error(\n `[AsyncStorage] Passing null/undefined as value is not supported. If you want to remove value, Use .removeItem method instead.\\nPassed value: ${value}\\nPassed key: ${key}\\n`\n );\n } else {\n console.warn(\n `[AsyncStorage] The value for key \"${key}\" is not a string. This can lead to unexpected behavior/errors. Consider stringifying it.\\nPassed value: ${value}\\nPassed key: ${key}\\n`\n );\n }\n }\n}\n\nexport function convertError(error?: ErrorLike): Error | null {\n if (!error) {\n return null;\n }\n\n const out = new Error(error.message);\n (out as any).key = error.key;\n return out;\n}\n\nexport function convertErrors(\n errs?: ErrorLike[]\n): ReadonlyArray | null {\n const errors = ensureArray(errs);\n return errors ? errors.map((e) => convertError(e)) : null;\n}\n\nfunction ensureArray(e?: ErrorLike | ErrorLike[]): ErrorLike[] | null {\n if (Array.isArray(e)) {\n return e.length === 0 ? null : e;\n } else if (e) {\n return [e];\n } else {\n return null;\n }\n}\n"],"mappings":"AAEA,OAAO,SAASA,cAAT,CAAwBC,aAAxB,EAAkDC,QAAlD,EAAqE;EAC1E,IACE,CAACC,KAAK,CAACC,OAAN,CAAcH,aAAd,CAAD,IACAA,aAAa,CAACI,MAAd,KAAyB,CADzB,IAEA,CAACF,KAAK,CAACC,OAAN,CAAcH,aAAa,CAAC,CAAD,CAA3B,CAHH,EAIE;IACA,MAAM,IAAIK,KAAJ,CACJ,gFADI,CAAN;EAGD;;EAED,IAAIJ,QAAQ,IAAI,OAAOA,QAAP,KAAoB,UAApC,EAAgD;IAC9C,IAAIC,KAAK,CAACC,OAAN,CAAcF,QAAd,CAAJ,EAA6B;MAC3B,MAAM,IAAII,KAAJ,CACJ,6IADI,CAAN;IAGD;;IAED,MAAM,IAAIA,KAAJ,CACJ,iEADI,CAAN;EAGD;AACF;AAED,OAAO,SAASC,eAAT,GAA8C;EAAA,kCAAlBC,KAAkB;IAAlBA,KAAkB;EAAA;;EACnD,MAAM,CAACC,GAAD,EAAMC,KAAN,IAAeF,KAArB;;EAEA,IAAI,OAAOC,GAAP,KAAe,QAAnB,EAA6B;IAC3BE,OAAO,CAACC,IAAR,CACG,wBAAuB,OAAOH,GAAI,iHAAgHA,GAAI,IADzJ;EAGD;;EAED,IAAID,KAAK,CAACH,MAAN,GAAe,CAAf,IAAoB,OAAOK,KAAP,KAAiB,QAAzC,EAAmD;IACjD,IAAIA,KAAK,IAAI,IAAb,EAAmB;MACjB,MAAM,IAAIJ,KAAJ,CACH,gJAA+II,KAAM,iBAAgBD,GAAI,IADtK,CAAN;IAGD,CAJD,MAIO;MACLE,OAAO,CAACC,IAAR,CACG,qCAAoCH,GAAI,4GAA2GC,KAAM,iBAAgBD,GAAI,IADhL;IAGD;EACF;AACF;AAED,OAAO,SAASI,YAAT,CAAsBC,KAAtB,EAAuD;EAC5D,IAAI,CAACA,KAAL,EAAY;IACV,OAAO,IAAP;EACD;;EAED,MAAMC,GAAG,GAAG,IAAIT,KAAJ,CAAUQ,KAAK,CAACE,OAAhB,CAAZ;EACCD,GAAD,CAAaN,GAAb,GAAmBK,KAAK,CAACL,GAAzB;EACA,OAAOM,GAAP;AACD;AAED,OAAO,SAASE,aAAT,CACLC,IADK,EAE+B;EACpC,MAAMC,MAAM,GAAGC,WAAW,CAACF,IAAD,CAA1B;EACA,OAAOC,MAAM,GAAGA,MAAM,CAACE,GAAP,CAAYC,CAAD,IAAOT,YAAY,CAACS,CAAD,CAA9B,CAAH,GAAwC,IAArD;AACD;;AAED,SAASF,WAAT,CAAqBE,CAArB,EAAsE;EACpE,IAAInB,KAAK,CAACC,OAAN,CAAckB,CAAd,CAAJ,EAAsB;IACpB,OAAOA,CAAC,CAACjB,MAAF,KAAa,CAAb,GAAiB,IAAjB,GAAwBiB,CAA/B;EACD,CAFD,MAEO,IAAIA,CAAJ,EAAO;IACZ,OAAO,CAACA,CAAD,CAAP;EACD,CAFM,MAEA;IACL,OAAO,IAAP;EACD;AACF"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/hooks.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/hooks.js
new file mode 100644
index 00000000..68fdd4e1
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/hooks.js
@@ -0,0 +1,34 @@
+import AsyncStorage from './AsyncStorage';
+export function useAsyncStorage(key) {
+ return {
+ getItem: function () {
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+
+ return AsyncStorage.getItem(key, ...args);
+ },
+ setItem: function () {
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+ args[_key2] = arguments[_key2];
+ }
+
+ return AsyncStorage.setItem(key, ...args);
+ },
+ mergeItem: function () {
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
+ args[_key3] = arguments[_key3];
+ }
+
+ return AsyncStorage.mergeItem(key, ...args);
+ },
+ removeItem: function () {
+ for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
+ args[_key4] = arguments[_key4];
+ }
+
+ return AsyncStorage.removeItem(key, ...args);
+ }
+ };
+}
+//# sourceMappingURL=hooks.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/hooks.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/hooks.js.map
new file mode 100644
index 00000000..c99bdfd9
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/hooks.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["AsyncStorage","useAsyncStorage","key","getItem","args","setItem","mergeItem","removeItem"],"sources":["hooks.ts"],"sourcesContent":["import AsyncStorage from './AsyncStorage';\nimport type { AsyncStorageHook } from './types';\n\nexport function useAsyncStorage(key: string): AsyncStorageHook {\n return {\n getItem: (...args) => AsyncStorage.getItem(key, ...args),\n setItem: (...args) => AsyncStorage.setItem(key, ...args),\n mergeItem: (...args) => AsyncStorage.mergeItem(key, ...args),\n removeItem: (...args) => AsyncStorage.removeItem(key, ...args),\n };\n}\n"],"mappings":"AAAA,OAAOA,YAAP,MAAyB,gBAAzB;AAGA,OAAO,SAASC,eAAT,CAAyBC,GAAzB,EAAwD;EAC7D,OAAO;IACLC,OAAO,EAAE;MAAA,kCAAIC,IAAJ;QAAIA,IAAJ;MAAA;;MAAA,OAAaJ,YAAY,CAACG,OAAb,CAAqBD,GAArB,EAA0B,GAAGE,IAA7B,CAAb;IAAA,CADJ;IAELC,OAAO,EAAE;MAAA,mCAAID,IAAJ;QAAIA,IAAJ;MAAA;;MAAA,OAAaJ,YAAY,CAACK,OAAb,CAAqBH,GAArB,EAA0B,GAAGE,IAA7B,CAAb;IAAA,CAFJ;IAGLE,SAAS,EAAE;MAAA,mCAAIF,IAAJ;QAAIA,IAAJ;MAAA;;MAAA,OAAaJ,YAAY,CAACM,SAAb,CAAuBJ,GAAvB,EAA4B,GAAGE,IAA/B,CAAb;IAAA,CAHN;IAILG,UAAU,EAAE;MAAA,mCAAIH,IAAJ;QAAIA,IAAJ;MAAA;;MAAA,OAAaJ,YAAY,CAACO,UAAb,CAAwBL,GAAxB,EAA6B,GAAGE,IAAhC,CAAb;IAAA;EAJP,CAAP;AAMD"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/index.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/index.js
new file mode 100644
index 00000000..d7d8dc36
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/index.js
@@ -0,0 +1,4 @@
+import AsyncStorage from './AsyncStorage';
+export { useAsyncStorage } from './hooks';
+export default AsyncStorage;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/index.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/index.js.map
new file mode 100644
index 00000000..0ff7ce56
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/index.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["AsyncStorage","useAsyncStorage"],"sources":["index.ts"],"sourcesContent":["import AsyncStorage from './AsyncStorage';\n\nexport { useAsyncStorage } from './hooks';\n\nexport type { AsyncStorageStatic } from './types';\n\nexport default AsyncStorage;\n"],"mappings":"AAAA,OAAOA,YAAP,MAAyB,gBAAzB;AAEA,SAASC,eAAT,QAAgC,SAAhC;AAIA,eAAeD,YAAf"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/shouldFallbackToLegacyNativeModule.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/shouldFallbackToLegacyNativeModule.js
new file mode 100644
index 00000000..8747fd24
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/shouldFallbackToLegacyNativeModule.js
@@ -0,0 +1,31 @@
+import { NativeModules } from 'react-native';
+export function shouldFallbackToLegacyNativeModule() {
+ var _NativeModules$Native, _NativeModules$Native2;
+
+ const expoConstants = (_NativeModules$Native = NativeModules['NativeUnimoduleProxy']) === null || _NativeModules$Native === void 0 ? void 0 : (_NativeModules$Native2 = _NativeModules$Native.modulesConstants) === null || _NativeModules$Native2 === void 0 ? void 0 : _NativeModules$Native2.ExponentConstants;
+
+ if (expoConstants) {
+ /**
+ * In SDK <= 39, appOwnership is defined in managed apps but executionEnvironment is not.
+ * In bare React Native apps using expo-constants, appOwnership is never defined, so
+ * isLegacySdkVersion will be false in that context.
+ */
+ const isLegacySdkVersion = expoConstants.appOwnership && !expoConstants.executionEnvironment;
+ /**
+ * Expo managed apps don't include the @react-native-async-storage/async-storage
+ * native modules yet, but the API interface is the same, so we can use the version
+ * exported from React Native still.
+ *
+ * If in future releases (eg: @react-native-async-storage/async-storage >= 2.0.0) this
+ * will likely not be valid anymore, and the package will need to be included in the Expo SDK
+ * to continue to work.
+ */
+
+ if (isLegacySdkVersion || ['storeClient', 'standalone'].includes(expoConstants.executionEnvironment)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+//# sourceMappingURL=shouldFallbackToLegacyNativeModule.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/shouldFallbackToLegacyNativeModule.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/shouldFallbackToLegacyNativeModule.js.map
new file mode 100644
index 00000000..cad18493
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/shouldFallbackToLegacyNativeModule.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["NativeModules","shouldFallbackToLegacyNativeModule","expoConstants","modulesConstants","ExponentConstants","isLegacySdkVersion","appOwnership","executionEnvironment","includes"],"sources":["shouldFallbackToLegacyNativeModule.ts"],"sourcesContent":["import { NativeModules } from 'react-native';\n\nexport function shouldFallbackToLegacyNativeModule(): boolean {\n const expoConstants =\n NativeModules['NativeUnimoduleProxy']?.modulesConstants?.ExponentConstants;\n\n if (expoConstants) {\n /**\n * In SDK <= 39, appOwnership is defined in managed apps but executionEnvironment is not.\n * In bare React Native apps using expo-constants, appOwnership is never defined, so\n * isLegacySdkVersion will be false in that context.\n */\n const isLegacySdkVersion =\n expoConstants.appOwnership && !expoConstants.executionEnvironment;\n\n /**\n * Expo managed apps don't include the @react-native-async-storage/async-storage\n * native modules yet, but the API interface is the same, so we can use the version\n * exported from React Native still.\n *\n * If in future releases (eg: @react-native-async-storage/async-storage >= 2.0.0) this\n * will likely not be valid anymore, and the package will need to be included in the Expo SDK\n * to continue to work.\n */\n if (\n isLegacySdkVersion ||\n ['storeClient', 'standalone'].includes(expoConstants.executionEnvironment)\n ) {\n return true;\n }\n }\n\n return false;\n}\n"],"mappings":"AAAA,SAASA,aAAT,QAA8B,cAA9B;AAEA,OAAO,SAASC,kCAAT,GAAuD;EAAA;;EAC5D,MAAMC,aAAa,4BACjBF,aAAa,CAAC,sBAAD,CADI,oFACjB,sBAAuCG,gBADtB,2DACjB,uBAAyDC,iBAD3D;;EAGA,IAAIF,aAAJ,EAAmB;IACjB;AACJ;AACA;AACA;AACA;IACI,MAAMG,kBAAkB,GACtBH,aAAa,CAACI,YAAd,IAA8B,CAACJ,aAAa,CAACK,oBAD/C;IAGA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;IACI,IACEF,kBAAkB,IAClB,CAAC,aAAD,EAAgB,YAAhB,EAA8BG,QAA9B,CAAuCN,aAAa,CAACK,oBAArD,CAFF,EAGE;MACA,OAAO,IAAP;IACD;EACF;;EAED,OAAO,KAAP;AACD"}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/types.js b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/types.js
new file mode 100644
index 00000000..63b2c4ca
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/types.js
@@ -0,0 +1,2 @@
+
+//# sourceMappingURL=types.js.map
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/types.js.map b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/types.js.map
new file mode 100644
index 00000000..f5d8ef90
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/module/types.js.map
@@ -0,0 +1 @@
+{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["export type ErrorLike = {\n message: string;\n key: string;\n};\n\nexport type Callback = (error?: Error | null) => void;\n\nexport type CallbackWithResult = (\n error?: Error | null,\n result?: T | null\n) => void;\n\nexport type KeyValuePair = [string, string | null];\n\nexport type MultiCallback = (errors?: readonly (Error | null)[] | null) => void;\n\nexport type MultiGetCallback = (\n errors?: readonly (Error | null)[] | null,\n result?: readonly KeyValuePair[]\n) => void;\n\nexport type MultiRequest = {\n keys: readonly string[];\n callback?: MultiGetCallback;\n keyIndex: number;\n resolve?: (result: readonly KeyValuePair[]) => void;\n reject?: (error?: any) => void;\n};\n\nexport type AsyncStorageHook = {\n getItem: (callback?: CallbackWithResult) => Promise;\n setItem: (value: string, callback?: Callback) => Promise;\n mergeItem: (value: string, callback?: Callback) => Promise;\n removeItem: (callback?: Callback) => Promise;\n};\n\n/**\n * `AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value\n * storage system that is global to the app. It should be used instead of\n * LocalStorage.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api\n */\nexport type AsyncStorageStatic = {\n /**\n * Fetches an item for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#getitem\n */\n getItem: (\n key: string,\n callback?: CallbackWithResult\n ) => Promise;\n\n /**\n * Sets the value for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#setitem\n */\n setItem: (key: string, value: string, callback?: Callback) => Promise;\n\n /**\n * Removes an item for a `key` and invokes a callback upon completion.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#removeitem\n */\n removeItem: (key: string, callback?: Callback) => Promise;\n\n /**\n * Merges an existing `key` value with an input value, assuming both values\n * are stringified JSON.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#mergeitem\n */\n mergeItem: (key: string, value: string, callback?: Callback) => Promise;\n\n /**\n * Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably\n * don't want to call this; use `removeItem` or `multiRemove` to clear only\n * your app's keys.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#clear\n */\n clear: (callback?: Callback) => Promise;\n\n /**\n * Gets *all* keys known to your app; for all callers, libraries, etc.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#getallkeys\n */\n getAllKeys: (\n callback?: CallbackWithResult\n ) => Promise;\n\n /**\n * The following batched functions are useful for executing a lot of\n * operations at once, allowing for native optimizations and provide the\n * convenience of a single callback after all operations are complete.\n *\n * These functions return arrays of errors, potentially one for every key.\n * For key-specific errors, the Error object will have a key property to\n * indicate which key caused the error.\n */\n\n /**\n * Flushes any pending requests using a single batch call to get the data.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#flushgetrequests\n * */\n flushGetRequests: () => void;\n\n /**\n * This allows you to batch the fetching of items given an array of `key`\n * inputs. Your callback will be invoked with an array of corresponding\n * key-value pairs found.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiget\n */\n multiGet: (\n keys: readonly string[],\n callback?: MultiGetCallback\n ) => Promise;\n\n /**\n * Use this as a batch operation for storing multiple key-value pairs. When\n * the operation completes you'll get a single callback with any errors.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiset\n */\n multiSet: (\n keyValuePairs: [string, string][],\n callback?: MultiCallback\n ) => Promise;\n\n /**\n * Call this to batch the deletion of all keys in the `keys` array.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multiremove\n */\n multiRemove: (\n keys: readonly string[],\n callback?: MultiCallback\n ) => Promise;\n\n /**\n * Batch operation to merge in existing and new values for a given set of\n * keys. This assumes that the values are stringified JSON.\n *\n * See https://react-native-async-storage.github.io/async-storage/docs/api#multimerge\n */\n multiMerge: (\n keyValuePairs: [string, string][],\n callback?: MultiCallback\n ) => Promise;\n};\n"],"mappings":""}
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/AsyncStorage.d.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/AsyncStorage.d.ts
new file mode 100644
index 00000000..05c2756b
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/AsyncStorage.d.ts
@@ -0,0 +1,10 @@
+/**
+ * Copyright (c) Nicolas Gallagher.
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+import type { AsyncStorageStatic } from './types';
+declare const AsyncStorage: AsyncStorageStatic;
+export default AsyncStorage;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/AsyncStorage.native.d.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/AsyncStorage.native.d.ts
new file mode 100644
index 00000000..9ac8a409
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/AsyncStorage.native.d.ts
@@ -0,0 +1,16 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+import type { AsyncStorageStatic } from './types';
+/**
+ * `AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value
+ * storage system that is global to the app. It should be used instead of
+ * LocalStorage.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api
+ */
+declare const AsyncStorage: AsyncStorageStatic;
+export default AsyncStorage;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/RCTAsyncStorage.d.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/RCTAsyncStorage.d.ts
new file mode 100644
index 00000000..c50db5d3
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/RCTAsyncStorage.d.ts
@@ -0,0 +1,2 @@
+declare let RCTAsyncStorage: any;
+export default RCTAsyncStorage;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/helpers.d.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/helpers.d.ts
new file mode 100644
index 00000000..e0f1a2db
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/helpers.d.ts
@@ -0,0 +1,5 @@
+import type { ErrorLike } from './types';
+export declare function checkValidArgs(keyValuePairs: unknown[], callback: unknown): void;
+export declare function checkValidInput(...input: unknown[]): void;
+export declare function convertError(error?: ErrorLike): Error | null;
+export declare function convertErrors(errs?: ErrorLike[]): ReadonlyArray | null;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/hooks.d.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/hooks.d.ts
new file mode 100644
index 00000000..19791679
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/hooks.d.ts
@@ -0,0 +1,2 @@
+import type { AsyncStorageHook } from './types';
+export declare function useAsyncStorage(key: string): AsyncStorageHook;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/index.d.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/index.d.ts
new file mode 100644
index 00000000..fb241527
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/index.d.ts
@@ -0,0 +1,4 @@
+import AsyncStorage from './AsyncStorage';
+export { useAsyncStorage } from './hooks';
+export type { AsyncStorageStatic } from './types';
+export default AsyncStorage;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/shouldFallbackToLegacyNativeModule.d.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/shouldFallbackToLegacyNativeModule.d.ts
new file mode 100644
index 00000000..6a0eaf54
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/shouldFallbackToLegacyNativeModule.d.ts
@@ -0,0 +1 @@
+export declare function shouldFallbackToLegacyNativeModule(): boolean;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/types.d.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/types.d.ts
new file mode 100644
index 00000000..e164ccf0
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/lib/typescript/types.d.ts
@@ -0,0 +1,113 @@
+export declare type ErrorLike = {
+ message: string;
+ key: string;
+};
+export declare type Callback = (error?: Error | null) => void;
+export declare type CallbackWithResult = (error?: Error | null, result?: T | null) => void;
+export declare type KeyValuePair = [string, string | null];
+export declare type MultiCallback = (errors?: readonly (Error | null)[] | null) => void;
+export declare type MultiGetCallback = (errors?: readonly (Error | null)[] | null, result?: readonly KeyValuePair[]) => void;
+export declare type MultiRequest = {
+ keys: readonly string[];
+ callback?: MultiGetCallback;
+ keyIndex: number;
+ resolve?: (result: readonly KeyValuePair[]) => void;
+ reject?: (error?: any) => void;
+};
+export declare type AsyncStorageHook = {
+ getItem: (callback?: CallbackWithResult) => Promise;
+ setItem: (value: string, callback?: Callback) => Promise;
+ mergeItem: (value: string, callback?: Callback) => Promise;
+ removeItem: (callback?: Callback) => Promise;
+};
+/**
+ * `AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value
+ * storage system that is global to the app. It should be used instead of
+ * LocalStorage.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api
+ */
+export declare type AsyncStorageStatic = {
+ /**
+ * Fetches an item for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#getitem
+ */
+ getItem: (key: string, callback?: CallbackWithResult) => Promise;
+ /**
+ * Sets the value for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#setitem
+ */
+ setItem: (key: string, value: string, callback?: Callback) => Promise;
+ /**
+ * Removes an item for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#removeitem
+ */
+ removeItem: (key: string, callback?: Callback) => Promise;
+ /**
+ * Merges an existing `key` value with an input value, assuming both values
+ * are stringified JSON.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#mergeitem
+ */
+ mergeItem: (key: string, value: string, callback?: Callback) => Promise;
+ /**
+ * Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably
+ * don't want to call this; use `removeItem` or `multiRemove` to clear only
+ * your app's keys.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#clear
+ */
+ clear: (callback?: Callback) => Promise;
+ /**
+ * Gets *all* keys known to your app; for all callers, libraries, etc.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#getallkeys
+ */
+ getAllKeys: (callback?: CallbackWithResult) => Promise;
+ /**
+ * The following batched functions are useful for executing a lot of
+ * operations at once, allowing for native optimizations and provide the
+ * convenience of a single callback after all operations are complete.
+ *
+ * These functions return arrays of errors, potentially one for every key.
+ * For key-specific errors, the Error object will have a key property to
+ * indicate which key caused the error.
+ */
+ /**
+ * Flushes any pending requests using a single batch call to get the data.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#flushgetrequests
+ * */
+ flushGetRequests: () => void;
+ /**
+ * This allows you to batch the fetching of items given an array of `key`
+ * inputs. Your callback will be invoked with an array of corresponding
+ * key-value pairs found.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiget
+ */
+ multiGet: (keys: readonly string[], callback?: MultiGetCallback) => Promise;
+ /**
+ * Use this as a batch operation for storing multiple key-value pairs. When
+ * the operation completes you'll get a single callback with any errors.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiset
+ */
+ multiSet: (keyValuePairs: [string, string][], callback?: MultiCallback) => Promise;
+ /**
+ * Call this to batch the deletion of all keys in the `keys` array.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiremove
+ */
+ multiRemove: (keys: readonly string[], callback?: MultiCallback) => Promise;
+ /**
+ * Batch operation to merge in existing and new values for a given set of
+ * keys. This assumes that the values are stringified JSON.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multimerge
+ */
+ multiMerge: (keyValuePairs: [string, string][], callback?: MultiCallback) => Promise;
+};
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/macos/RNCAsyncStorage.xcodeproj/project.pbxproj b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/macos/RNCAsyncStorage.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..8c2f8972
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/macos/RNCAsyncStorage.xcodeproj/project.pbxproj
@@ -0,0 +1,385 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1990B97A223993B0009E5EA1 /* RNCAsyncStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = B3E7B5881CC2AC0600A0062D /* RNCAsyncStorage.h */; };
+ 1990B97B223993B0009E5EA1 /* RNCAsyncStorageDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1990B9402233FE3A009E5EA1 /* RNCAsyncStorageDelegate.h */; };
+ 3893A2E123C509D1009200E3 /* RNCAsyncStorage.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B3E7B5881CC2AC0600A0062D /* RNCAsyncStorage.h */; };
+ 3893A2E223C509D1009200E3 /* RNCAsyncStorageDelegate.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1990B9402233FE3A009E5EA1 /* RNCAsyncStorageDelegate.h */; };
+ 3893A2E523C50AFE009200E3 /* RNCAsyncStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = B3E7B5881CC2AC0600A0062D /* RNCAsyncStorage.h */; };
+ 3893A2E623C50AFE009200E3 /* RNCAsyncStorageDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1990B9402233FE3A009E5EA1 /* RNCAsyncStorageDelegate.h */; };
+ 3893A2E823C50AFE009200E3 /* RNCAsyncStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNCAsyncStorage.m */; };
+ 3893A2EB23C50AFE009200E3 /* RNCAsyncStorage.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B3E7B5881CC2AC0600A0062D /* RNCAsyncStorage.h */; };
+ 3893A2EC23C50AFE009200E3 /* RNCAsyncStorageDelegate.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1990B9402233FE3A009E5EA1 /* RNCAsyncStorageDelegate.h */; };
+ B3E7B58A1CC2AC0600A0062D /* RNCAsyncStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNCAsyncStorage.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 3893A2EA23C50AFE009200E3 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = include/RNCAsyncStorage;
+ dstSubfolderSpec = 16;
+ files = (
+ 3893A2EB23C50AFE009200E3 /* RNCAsyncStorage.h in CopyFiles */,
+ 3893A2EC23C50AFE009200E3 /* RNCAsyncStorageDelegate.h in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 58B511D91A9E6C8500147676 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "include/$(PRODUCT_NAME)";
+ dstSubfolderSpec = 16;
+ files = (
+ 3893A2E123C509D1009200E3 /* RNCAsyncStorage.h in CopyFiles */,
+ 3893A2E223C509D1009200E3 /* RNCAsyncStorageDelegate.h in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 134814201AA4EA6300B7C361 /* libRNCAsyncStorage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNCAsyncStorage.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1990B9402233FE3A009E5EA1 /* RNCAsyncStorageDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNCAsyncStorageDelegate.h; path = ../ios/RNCAsyncStorageDelegate.h; sourceTree = ""; };
+ 3893A2F023C50AFE009200E3 /* libRNCAsyncStorage-macOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRNCAsyncStorage-macOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ B3E7B5881CC2AC0600A0062D /* RNCAsyncStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNCAsyncStorage.h; path = ../ios/RNCAsyncStorage.h; sourceTree = ""; };
+ B3E7B5891CC2AC0600A0062D /* RNCAsyncStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNCAsyncStorage.m; path = ../ios/RNCAsyncStorage.m; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 3893A2E923C50AFE009200E3 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 58B511D81A9E6C8500147676 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 134814211AA4EA7D00B7C361 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 134814201AA4EA6300B7C361 /* libRNCAsyncStorage.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 58B511D21A9E6C8500147676 = {
+ isa = PBXGroup;
+ children = (
+ B3E7B5881CC2AC0600A0062D /* RNCAsyncStorage.h */,
+ B3E7B5891CC2AC0600A0062D /* RNCAsyncStorage.m */,
+ 1990B9402233FE3A009E5EA1 /* RNCAsyncStorageDelegate.h */,
+ 134814211AA4EA7D00B7C361 /* Products */,
+ 3893A2F023C50AFE009200E3 /* libRNCAsyncStorage-macOS.a */,
+ );
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 19F94B1D2239A948006921A9 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1990B97A223993B0009E5EA1 /* RNCAsyncStorage.h in Headers */,
+ 1990B97B223993B0009E5EA1 /* RNCAsyncStorageDelegate.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 3893A2E423C50AFE009200E3 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3893A2E523C50AFE009200E3 /* RNCAsyncStorage.h in Headers */,
+ 3893A2E623C50AFE009200E3 /* RNCAsyncStorageDelegate.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 3893A2E323C50AFE009200E3 /* RNCAsyncStorage-macOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 3893A2ED23C50AFE009200E3 /* Build configuration list for PBXNativeTarget "RNCAsyncStorage-macOS" */;
+ buildPhases = (
+ 3893A2E423C50AFE009200E3 /* Headers */,
+ 3893A2E723C50AFE009200E3 /* Sources */,
+ 3893A2E923C50AFE009200E3 /* Frameworks */,
+ 3893A2EA23C50AFE009200E3 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "RNCAsyncStorage-macOS";
+ productName = RCTDataManager;
+ productReference = 3893A2F023C50AFE009200E3 /* libRNCAsyncStorage-macOS.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+ 58B511DA1A9E6C8500147676 /* RNCAsyncStorage */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCAsyncStorage" */;
+ buildPhases = (
+ 19F94B1D2239A948006921A9 /* Headers */,
+ 58B511D71A9E6C8500147676 /* Sources */,
+ 58B511D81A9E6C8500147676 /* Frameworks */,
+ 58B511D91A9E6C8500147676 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = RNCAsyncStorage;
+ productName = RCTDataManager;
+ productReference = 134814201AA4EA6300B7C361 /* libRNCAsyncStorage.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 58B511D31A9E6C8500147676 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0830;
+ ORGANIZATIONNAME = Facebook;
+ TargetAttributes = {
+ 58B511DA1A9E6C8500147676 = {
+ CreatedOnToolsVersion = 6.1.1;
+ };
+ };
+ };
+ buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCAsyncStorage" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ English,
+ en,
+ );
+ mainGroup = 58B511D21A9E6C8500147676;
+ productRefGroup = 58B511D21A9E6C8500147676;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 58B511DA1A9E6C8500147676 /* RNCAsyncStorage */,
+ 3893A2E323C50AFE009200E3 /* RNCAsyncStorage-macOS */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 3893A2E723C50AFE009200E3 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3893A2E823C50AFE009200E3 /* RNCAsyncStorage.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 58B511D71A9E6C8500147676 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B3E7B58A1CC2AC0600A0062D /* RNCAsyncStorage.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 3893A2EE23C50AFE009200E3 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SRCROOT)/../node_modules/react-native/React/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ };
+ name = Debug;
+ };
+ 3893A2EF23C50AFE009200E3 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SRCROOT)/../node_modules/react-native/React/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ };
+ name = Release;
+ };
+ 58B511ED1A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 58B511EE1A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 58B511F01A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../../React/**",
+ "$(SRCROOT)/../../react-native/React/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = RNCAsyncStorage;
+ SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvsimulator appletvos";
+ };
+ name = Debug;
+ };
+ 58B511F11A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../../React/**",
+ "$(SRCROOT)/../../react-native/React/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = RNCAsyncStorage;
+ SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvsimulator appletvos";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 3893A2ED23C50AFE009200E3 /* Build configuration list for PBXNativeTarget "RNCAsyncStorage-macOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 3893A2EE23C50AFE009200E3 /* Debug */,
+ 3893A2EF23C50AFE009200E3 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCAsyncStorage" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511ED1A9E6C8500147676 /* Debug */,
+ 58B511EE1A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCAsyncStorage" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511F01A9E6C8500147676 /* Debug */,
+ 58B511F11A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 58B511D31A9E6C8500147676 /* Project object */;
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/macos/RNCAsyncStorage.xcodeproj/xcshareddata/xcschemes/RNCAsyncStorage-macOS.xcscheme b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/macos/RNCAsyncStorage.xcodeproj/xcshareddata/xcschemes/RNCAsyncStorage-macOS.xcscheme
new file mode 100644
index 00000000..817e512e
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/macos/RNCAsyncStorage.xcodeproj/xcshareddata/xcschemes/RNCAsyncStorage-macOS.xcscheme
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/macos/RNCAsyncStorage.xcodeproj/xcshareddata/xcschemes/RNCAsyncStorage.xcscheme b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/macos/RNCAsyncStorage.xcodeproj/xcshareddata/xcschemes/RNCAsyncStorage.xcscheme
new file mode 100644
index 00000000..7d809e32
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/macos/RNCAsyncStorage.xcodeproj/xcshareddata/xcschemes/RNCAsyncStorage.xcscheme
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/node_modules/.bin/react-native b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/node_modules/.bin/react-native
new file mode 120000
index 00000000..30f54fcb
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/node_modules/.bin/react-native
@@ -0,0 +1 @@
+../../../../react-native/cli.js
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/package.json b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/package.json
new file mode 100644
index 00000000..016638d2
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/package.json
@@ -0,0 +1,195 @@
+{
+ "name": "@react-native-async-storage/async-storage",
+ "version": "1.17.12",
+ "description": "Asynchronous, persistent, key-value storage system for React Native.",
+ "main": "lib/commonjs/index.js",
+ "module": "lib/module/index.js",
+ "react-native": "src/index.ts",
+ "types": "lib/typescript/index.d.ts",
+ "files": [
+ "RNCAsyncStorage.podspec",
+ "android/build.gradle",
+ "android/src",
+ "android/testresults.gradle",
+ "ios/",
+ "jest/",
+ "lib/",
+ "macos/",
+ "src/",
+ "windows/"
+ ],
+ "author": "Krzysztof Borowy ",
+ "contributors": [
+ "Evan Bacon (https://github.com/evanbacon)",
+ "Tommy Nguyen <4123478+tido64@users.noreply.github.com> (https://github.com/tido64)"
+ ],
+ "homepage": "https://github.com/react-native-async-storage/async-storage#readme",
+ "license": "MIT",
+ "keywords": [
+ "react-native",
+ "react native",
+ "async storage",
+ "asyncstorage",
+ "storage"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/react-native-async-storage/async-storage.git"
+ },
+ "scripts": {
+ "format": "concurrently yarn:format:*",
+ "format:c": "clang-format -i $(git ls-files '*.cpp' '*.h' '*.m' '*.mm')",
+ "format:js": "prettier --write $(git ls-files '*.js' '*.json' '*.md' '*.ts' '*.tsx' '*.yml')",
+ "prepare": "bob build",
+ "start": "react-native start",
+ "start:android": "react-native run-android",
+ "start:ios": "react-native run-ios --project-path example/ios",
+ "start:macos": "react-native run-macos --project-path example/macos --scheme AsyncStorageExample",
+ "start:web": "expo start:web",
+ "start:windows": "install-windows-test-app -p example/windows && react-native run-windows --root example --logging --no-packager --no-telemetry",
+ "build:e2e:android": "scripts/android_e2e.sh 'build'",
+ "build:e2e:ios": "scripts/ios_e2e.sh 'build'",
+ "build:e2e:macos": "scripts/macos_e2e.sh 'build'",
+ "bundle:android": "scripts/android_e2e.sh 'bundle'",
+ "bundle:ios": "scripts/ios_e2e.sh 'bundle'",
+ "bundle:macos": "react-native bundle --entry-file index.ts --platform macos --bundle-output example/index.macos.jsbundle",
+ "test": "concurrently -n lint,ts yarn:test:lint yarn:test:ts",
+ "test:lint": "eslint src/**/*.ts example/**/*.ts jest/*.js",
+ "test:ts": "tsc --project tsconfig.all.json",
+ "test:e2e:android": "detox test -c android.emu.release --maxConcurrency 1",
+ "test:e2e:ios": "detox test -c ios.sim.release --maxConcurrency 1",
+ "test:e2e:macos": "scripts/macos_e2e.sh 'test'"
+ },
+ "dependencies": {
+ "merge-options": "^3.0.4"
+ },
+ "peerDependencies": {
+ "react-native": "^0.0.0-0 || 0.60 - 0.71 || 1000.0.0"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.12.0",
+ "@babel/preset-env": "^7.1.6",
+ "@react-native-community/eslint-config": "^3.0.0",
+ "@semantic-release/changelog": "^6.0.0",
+ "@semantic-release/git": "^10.0.0",
+ "@types/lodash": "^4.14.184",
+ "@types/react": "^17.0.0",
+ "@types/react-native": "^0.68.0",
+ "concurrently": "^6.4.0",
+ "detox": "^19.4.5",
+ "eslint": "^8.0.0",
+ "expo": "^45.0.0",
+ "jest": "^26.6.3",
+ "jest-circus": "^26.6.1",
+ "lodash": "^4.17.21",
+ "prettier": "^2.5.1",
+ "react": "17.0.2",
+ "react-dom": "17.0.2",
+ "react-native": "^0.68.0",
+ "react-native-builder-bob": "^0.18.0",
+ "react-native-macos": "^0.68.0",
+ "react-native-test-app": "^2.3.10",
+ "react-native-web": "^0.17.0",
+ "react-native-windows": "^0.68.0",
+ "react-test-renderer": "17.0.2",
+ "semantic-release": "^19.0.0",
+ "typescript": "^4.5.0"
+ },
+ "packageManager": "yarn@3.4.1",
+ "resolutions": {
+ "npm/chalk": "^4.1.2"
+ },
+ "jest": {
+ "preset": "react-native",
+ "setupFiles": [
+ "./example/jest.setup.js"
+ ]
+ },
+ "detox": {
+ "test-runner": "jest",
+ "runner-config": "example/e2e/config.json",
+ "configurations": {
+ "ios.sim.release": {
+ "binaryPath": "example/ios/build/Build/Products/Release-iphonesimulator/ReactTestApp.app",
+ "type": "ios.simulator",
+ "device": {
+ "type": "iPhone 13"
+ }
+ },
+ "android.emu.release": {
+ "binaryPath": "example/android/app/build/outputs/apk/release/app-release.apk",
+ "testBinaryPath": "example/android/app/build/outputs/apk/androidTest/release/app-release-androidTest.apk",
+ "type": "android.emulator",
+ "device": {
+ "avdName": "E2E_API_30",
+ "utilBinaryPaths": [
+ "/var/tmp/test-butler.apk"
+ ]
+ }
+ },
+ "android.emu.release.next": {
+ "binaryPath": "example/android/app/build/outputs/apk/next/app-next.apk",
+ "testBinaryPath": "example/android/app/build/outputs/apk/androidTest/release/app-release-androidTest.apk",
+ "type": "android.emulator",
+ "device": {
+ "avdName": "E2E_API_30",
+ "utilBinaryPaths": [
+ "/var/tmp/test-butler.apk"
+ ]
+ }
+ }
+ }
+ },
+ "eslintConfig": {
+ "extends": [
+ "@react-native-community",
+ "plugin:jest/recommended"
+ ],
+ "rules": {
+ "dot-notation": "off"
+ }
+ },
+ "prettier": {
+ "endOfLine": "auto",
+ "singleQuote": true,
+ "overrides": [
+ {
+ "files": "*.md",
+ "options": {
+ "proseWrap": "always"
+ }
+ }
+ ]
+ },
+ "react-native-builder-bob": {
+ "source": "src",
+ "output": "lib",
+ "targets": [
+ "commonjs",
+ "module",
+ "typescript"
+ ]
+ },
+ "release": {
+ "branches": [
+ "master"
+ ],
+ "plugins": [
+ "@semantic-release/commit-analyzer",
+ "@semantic-release/release-notes-generator",
+ "@semantic-release/changelog",
+ "@semantic-release/npm",
+ "@semantic-release/github",
+ [
+ "@semantic-release/git",
+ {
+ "assets": [
+ "CHANGELOG.md",
+ "package.json"
+ ],
+ "message": "chore(release): ${nextRelease.version} [skip ci]"
+ }
+ ]
+ ]
+ }
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/AsyncStorage.native.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/AsyncStorage.native.ts
new file mode 100644
index 00000000..f18b0278
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/AsyncStorage.native.ts
@@ -0,0 +1,356 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import {
+ checkValidArgs,
+ checkValidInput,
+ convertError,
+ convertErrors,
+} from './helpers';
+import RCTAsyncStorage from './RCTAsyncStorage';
+import type {
+ AsyncStorageStatic,
+ ErrorLike,
+ KeyValuePair,
+ MultiRequest,
+} from './types';
+
+if (!RCTAsyncStorage) {
+ throw new Error(`[@RNC/AsyncStorage]: NativeModule: AsyncStorage is null.
+
+To fix this issue try these steps:
+
+ • Rebuild and restart the app.
+
+ • Run the packager with \`--reset-cache\` flag.
+
+ • If you are using CocoaPods on iOS, run \`pod install\` in the \`ios\` directory and then rebuild and re-run the app.
+
+ • If this happens while testing with Jest, check out docs how to integrate AsyncStorage with it: https://react-native-async-storage.github.io/async-storage/docs/advanced/jest
+
+If none of these fix the issue, please open an issue on the Github repository: https://github.com/react-native-async-storage/async-storage/issues
+`);
+}
+
+/**
+ * `AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value
+ * storage system that is global to the app. It should be used instead of
+ * LocalStorage.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api
+ */
+const AsyncStorage = ((): AsyncStorageStatic => {
+ let _getRequests: MultiRequest[] = [];
+ let _getKeys: string[] = [];
+ let _immediate: ReturnType | null = null;
+
+ return {
+ /**
+ * Fetches an item for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#getitem
+ */
+ getItem: (key, callback) => {
+ return new Promise((resolve, reject) => {
+ checkValidInput(key);
+ RCTAsyncStorage.multiGet(
+ [key],
+ (errors?: ErrorLike[], result?: string[][]) => {
+ // Unpack result to get value from [[key,value]]
+ const value = result?.[0]?.[1] ? result[0][1] : null;
+ const errs = convertErrors(errors);
+ callback?.(errs?.[0], value);
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve(value);
+ }
+ }
+ );
+ });
+ },
+
+ /**
+ * Sets the value for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#setitem
+ */
+ setItem: (key, value, callback) => {
+ return new Promise((resolve, reject) => {
+ checkValidInput(key, value);
+ RCTAsyncStorage.multiSet([[key, value]], (errors?: ErrorLike[]) => {
+ const errs = convertErrors(errors);
+ callback?.(errs?.[0]);
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Removes an item for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#removeitem
+ */
+ removeItem: (key, callback) => {
+ return new Promise((resolve, reject) => {
+ checkValidInput(key);
+ RCTAsyncStorage.multiRemove([key], (errors?: ErrorLike[]) => {
+ const errs = convertErrors(errors);
+ callback?.(errs?.[0]);
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Merges an existing `key` value with an input value, assuming both values
+ * are stringified JSON.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#mergeitem
+ */
+ mergeItem: (key, value, callback) => {
+ return new Promise((resolve, reject) => {
+ checkValidInput(key, value);
+ RCTAsyncStorage.multiMerge([[key, value]], (errors?: ErrorLike[]) => {
+ const errs = convertErrors(errors);
+ callback?.(errs?.[0]);
+ if (errs) {
+ reject(errs[0]);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably
+ * don't want to call this; use `removeItem` or `multiRemove` to clear only
+ * your app's keys.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#clear
+ */
+ clear: (callback) => {
+ return new Promise((resolve, reject) => {
+ RCTAsyncStorage.clear((error?: ErrorLike) => {
+ const err = convertError(error);
+ callback?.(err);
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Gets *all* keys known to your app; for all callers, libraries, etc.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#getallkeys
+ */
+ getAllKeys: (callback) => {
+ return new Promise((resolve, reject) => {
+ RCTAsyncStorage.getAllKeys((error?: ErrorLike, keys?: string[]) => {
+ const err = convertError(error);
+ callback?.(err, keys);
+ if (keys) {
+ resolve(keys);
+ } else {
+ reject(err);
+ }
+ });
+ });
+ },
+
+ /**
+ * The following batched functions are useful for executing a lot of
+ * operations at once, allowing for native optimizations and provide the
+ * convenience of a single callback after all operations are complete.
+ *
+ * These functions return arrays of errors, potentially one for every key.
+ * For key-specific errors, the Error object will have a key property to
+ * indicate which key caused the error.
+ */
+
+ /**
+ * Flushes any pending requests using a single batch call to get the data.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#flushgetrequests
+ * */
+ flushGetRequests: () => {
+ const getRequests = _getRequests;
+ const getKeys = _getKeys;
+
+ _getRequests = [];
+ _getKeys = [];
+
+ RCTAsyncStorage.multiGet(
+ getKeys,
+ (errors?: ErrorLike[], result?: string[][]) => {
+ // Even though the runtime complexity of this is theoretically worse vs if we used a map,
+ // it's much, much faster in practice for the data sets we deal with (we avoid
+ // allocating result pair arrays). This was heavily benchmarked.
+ //
+ // Is there a way to avoid using the map but fix the bug in this breaking test?
+ // https://github.com/facebook/react-native/commit/8dd8ad76579d7feef34c014d387bf02065692264
+ const map: Record = {};
+ result?.forEach(([key, value]) => {
+ map[key] = value;
+ return value;
+ });
+ const reqLength = getRequests.length;
+
+ /**
+ * As mentioned few lines above, this method could be called with the array of potential error,
+ * in case of anything goes wrong. The problem is, if any of the batched calls fails
+ * the rest of them would fail too, but the error would be consumed by just one. The rest
+ * would simply return `undefined` as their result, rendering false negatives.
+ *
+ * In order to avoid this situation, in case of any call failing,
+ * the rest of them will be rejected as well (with the same error).
+ */
+ const errorList = convertErrors(errors);
+ const error = errorList?.length ? errorList[0] : null;
+
+ for (let i = 0; i < reqLength; i++) {
+ const request = getRequests[i];
+ if (error) {
+ request.callback?.(errorList);
+ request.reject?.(error);
+ continue;
+ }
+ const requestResult = request.keys.map((key) => [
+ key,
+ map[key],
+ ]);
+ request.callback?.(null, requestResult);
+ request.resolve?.(requestResult);
+ }
+ }
+ );
+ },
+
+ /**
+ * This allows you to batch the fetching of items given an array of `key`
+ * inputs. Your callback will be invoked with an array of corresponding
+ * key-value pairs found.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiget
+ */
+ multiGet: (keys, callback) => {
+ if (!_immediate) {
+ _immediate = setImmediate(() => {
+ _immediate = null;
+ AsyncStorage.flushGetRequests();
+ });
+ }
+
+ const getRequest: MultiRequest = {
+ keys: keys,
+ callback: callback,
+ // do we need this?
+ keyIndex: _getKeys.length,
+ resolve: null as any,
+ reject: null as any,
+ };
+
+ const promiseResult = new Promise(
+ (resolve, reject) => {
+ getRequest.resolve = resolve;
+ getRequest.reject = reject;
+ }
+ );
+
+ _getRequests.push(getRequest);
+ // avoid fetching duplicates
+ keys.forEach((key) => {
+ if (_getKeys.indexOf(key) === -1) {
+ _getKeys.push(key);
+ }
+ });
+
+ return promiseResult;
+ },
+
+ /**
+ * Use this as a batch operation for storing multiple key-value pairs. When
+ * the operation completes you'll get a single callback with any errors.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiset
+ */
+ multiSet: (keyValuePairs, callback) => {
+ checkValidArgs(keyValuePairs, callback);
+ return new Promise((resolve, reject) => {
+ keyValuePairs.forEach(([key, value]) => {
+ checkValidInput(key, value);
+ });
+
+ RCTAsyncStorage.multiSet(keyValuePairs, (errors?: ErrorLike[]) => {
+ const error = convertErrors(errors);
+ callback?.(error);
+ if (error) {
+ reject(error);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Call this to batch the deletion of all keys in the `keys` array.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiremove
+ */
+ multiRemove: (keys, callback) => {
+ return new Promise((resolve, reject) => {
+ keys.forEach((key) => checkValidInput(key));
+
+ RCTAsyncStorage.multiRemove(keys, (errors?: ErrorLike[]) => {
+ const error = convertErrors(errors);
+ callback?.(error);
+ if (error) {
+ reject(error);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+
+ /**
+ * Batch operation to merge in existing and new values for a given set of
+ * keys. This assumes that the values are stringified JSON.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multimerge
+ */
+ multiMerge: (keyValuePairs, callback) => {
+ return new Promise((resolve, reject) => {
+ RCTAsyncStorage.multiMerge(keyValuePairs, (errors?: ErrorLike[]) => {
+ const error = convertErrors(errors);
+ callback?.(error);
+ if (error) {
+ reject(error);
+ } else {
+ resolve();
+ }
+ });
+ });
+ },
+ };
+})();
+
+export default AsyncStorage;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/AsyncStorage.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/AsyncStorage.ts
new file mode 100644
index 00000000..a14a75c7
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/AsyncStorage.ts
@@ -0,0 +1,173 @@
+/**
+ * Copyright (c) Nicolas Gallagher.
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+// @ts-ignore Cannot find module 'merge-options' or its corresponding type declarations
+import mergeOptions from 'merge-options';
+import type {
+ AsyncStorageStatic,
+ MultiCallback,
+ MultiGetCallback,
+} from './types';
+
+const merge = mergeOptions.bind({
+ concatArrays: true,
+ ignoreUndefined: true,
+});
+
+function mergeLocalStorageItem(key: string, value: string) {
+ const oldValue = window.localStorage.getItem(key);
+ if (oldValue) {
+ const oldObject = JSON.parse(oldValue);
+ const newObject = JSON.parse(value);
+ const nextValue = JSON.stringify(merge(oldObject, newObject));
+ window.localStorage.setItem(key, nextValue);
+ } else {
+ window.localStorage.setItem(key, value);
+ }
+}
+
+function createPromise(
+ getValue: () => Result,
+ callback?: Callback
+): Promise {
+ return new Promise((resolve, reject) => {
+ try {
+ const value = getValue();
+ callback?.(null, value);
+ resolve(value);
+ } catch (err) {
+ callback?.(err);
+ reject(err);
+ }
+ });
+}
+
+function createPromiseAll(
+ promises: Promise[],
+ callback?: MultiCallback | MultiGetCallback,
+ processResult?: ResultProcessor
+): Promise {
+ return Promise.all(promises).then(
+ (result) => {
+ const value = processResult?.(result) ?? null;
+ callback?.(null, value);
+ return Promise.resolve(value);
+ },
+ (errors) => {
+ callback?.(errors);
+ return Promise.reject(errors);
+ }
+ );
+}
+
+const AsyncStorage: AsyncStorageStatic = {
+ /**
+ * Fetches `key` value.
+ */
+ getItem: (key, callback) => {
+ return createPromise(() => window.localStorage.getItem(key), callback);
+ },
+
+ /**
+ * Sets `value` for `key`.
+ */
+ setItem: (key, value, callback) => {
+ return createPromise(
+ () => window.localStorage.setItem(key, value),
+ callback
+ );
+ },
+
+ /**
+ * Removes a `key`
+ */
+ removeItem: (key, callback) => {
+ return createPromise(() => window.localStorage.removeItem(key), callback);
+ },
+
+ /**
+ * Merges existing value with input value, assuming they are stringified JSON.
+ */
+ mergeItem: (key, value, callback) => {
+ return createPromise(() => mergeLocalStorageItem(key, value), callback);
+ },
+
+ /**
+ * Erases *all* AsyncStorage for the domain.
+ */
+ clear: (callback) => {
+ return createPromise(() => window.localStorage.clear(), callback);
+ },
+
+ /**
+ * Gets *all* keys known to the app, for all callers, libraries, etc.
+ */
+ getAllKeys: (callback) => {
+ return createPromise(() => {
+ const numberOfKeys = window.localStorage.length;
+ const keys: string[] = [];
+ for (let i = 0; i < numberOfKeys; i += 1) {
+ const key = window.localStorage.key(i) || '';
+ keys.push(key);
+ }
+ return keys;
+ }, callback);
+ },
+
+ /**
+ * (stub) Flushes any pending requests using a single batch call to get the data.
+ */
+ flushGetRequests: () => undefined,
+
+ /**
+ * multiGet resolves to an array of key-value pair arrays that matches the
+ * input format of multiSet.
+ *
+ * multiGet(['k1', 'k2']) -> [['k1', 'val1'], ['k2', 'val2']]
+ */
+ multiGet: (keys, callback) => {
+ const promises = keys.map((key) => AsyncStorage.getItem(key));
+ const processResult = (result: string[]) =>
+ result.map((value, i) => [keys[i], value]);
+ return createPromiseAll(promises, callback, processResult);
+ },
+
+ /**
+ * Takes an array of key-value array pairs.
+ * multiSet([['k1', 'val1'], ['k2', 'val2']])
+ */
+ multiSet: (keyValuePairs, callback) => {
+ const promises = keyValuePairs.map((item) =>
+ AsyncStorage.setItem(item[0], item[1])
+ );
+ return createPromiseAll(promises, callback);
+ },
+
+ /**
+ * Delete all the keys in the `keys` array.
+ */
+ multiRemove: (keys, callback) => {
+ const promises = keys.map((key) => AsyncStorage.removeItem(key));
+ return createPromiseAll(promises, callback);
+ },
+
+ /**
+ * Takes an array of key-value array pairs and merges them with existing
+ * values, assuming they are stringified JSON.
+ *
+ * multiMerge([['k1', 'val1'], ['k2', 'val2']])
+ */
+ multiMerge: (keyValuePairs, callback) => {
+ const promises = keyValuePairs.map((item) =>
+ AsyncStorage.mergeItem(item[0], item[1])
+ );
+ return createPromiseAll(promises, callback);
+ },
+};
+
+export default AsyncStorage;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/RCTAsyncStorage.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/RCTAsyncStorage.ts
new file mode 100644
index 00000000..a353a137
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/RCTAsyncStorage.ts
@@ -0,0 +1,25 @@
+// @ts-ignore Module '"react-native"' has no exported member 'TurboModuleRegistry'.
+import { NativeModules, TurboModuleRegistry } from 'react-native';
+import { shouldFallbackToLegacyNativeModule } from './shouldFallbackToLegacyNativeModule';
+
+let RCTAsyncStorage =
+ NativeModules['PlatformLocalStorage'] || // Support for external modules, like react-native-windows
+ NativeModules['RNC_AsyncSQLiteDBStorage'] ||
+ NativeModules['RNCAsyncStorage'];
+
+if (!RCTAsyncStorage && shouldFallbackToLegacyNativeModule()) {
+ // TurboModuleRegistry falls back to NativeModules so we don't have to try go
+ // assign NativeModules' counterparts if TurboModuleRegistry would resolve
+ // with undefined.
+ if (TurboModuleRegistry) {
+ RCTAsyncStorage =
+ TurboModuleRegistry.get('AsyncSQLiteDBStorage') ||
+ TurboModuleRegistry.get('AsyncLocalStorage');
+ } else {
+ RCTAsyncStorage =
+ NativeModules['AsyncSQLiteDBStorage'] ||
+ NativeModules['AsyncLocalStorage'];
+ }
+}
+
+export default RCTAsyncStorage;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/helpers.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/helpers.ts
new file mode 100644
index 00000000..05813774
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/helpers.ts
@@ -0,0 +1,74 @@
+import type { ErrorLike } from './types';
+
+export function checkValidArgs(keyValuePairs: unknown[], callback: unknown) {
+ if (
+ !Array.isArray(keyValuePairs) ||
+ keyValuePairs.length === 0 ||
+ !Array.isArray(keyValuePairs[0])
+ ) {
+ throw new Error(
+ '[AsyncStorage] Expected array of key-value pairs as first argument to multiSet'
+ );
+ }
+
+ if (callback && typeof callback !== 'function') {
+ if (Array.isArray(callback)) {
+ throw new Error(
+ '[AsyncStorage] Expected function as second argument to multiSet. Did you forget to wrap key-value pairs in an array for the first argument?'
+ );
+ }
+
+ throw new Error(
+ '[AsyncStorage] Expected function as second argument to multiSet'
+ );
+ }
+}
+
+export function checkValidInput(...input: unknown[]) {
+ const [key, value] = input;
+
+ if (typeof key !== 'string') {
+ console.warn(
+ `[AsyncStorage] Using ${typeof key} type for key is not supported. This can lead to unexpected behavior/errors. Use string instead.\nKey passed: ${key}\n`
+ );
+ }
+
+ if (input.length > 1 && typeof value !== 'string') {
+ if (value == null) {
+ throw new Error(
+ `[AsyncStorage] Passing null/undefined as value is not supported. If you want to remove value, Use .removeItem method instead.\nPassed value: ${value}\nPassed key: ${key}\n`
+ );
+ } else {
+ console.warn(
+ `[AsyncStorage] The value for key "${key}" is not a string. This can lead to unexpected behavior/errors. Consider stringifying it.\nPassed value: ${value}\nPassed key: ${key}\n`
+ );
+ }
+ }
+}
+
+export function convertError(error?: ErrorLike): Error | null {
+ if (!error) {
+ return null;
+ }
+
+ const out = new Error(error.message);
+ (out as any).key = error.key;
+ return out;
+}
+
+export function convertErrors(
+ errs?: ErrorLike[]
+): ReadonlyArray | null {
+ const errors = ensureArray(errs);
+ return errors ? errors.map((e) => convertError(e)) : null;
+}
+
+function ensureArray(e?: ErrorLike | ErrorLike[]): ErrorLike[] | null {
+ if (Array.isArray(e)) {
+ return e.length === 0 ? null : e;
+ } else if (e) {
+ return [e];
+ } else {
+ return null;
+ }
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/hooks.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/hooks.ts
new file mode 100644
index 00000000..170b4e69
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/hooks.ts
@@ -0,0 +1,11 @@
+import AsyncStorage from './AsyncStorage';
+import type { AsyncStorageHook } from './types';
+
+export function useAsyncStorage(key: string): AsyncStorageHook {
+ return {
+ getItem: (...args) => AsyncStorage.getItem(key, ...args),
+ setItem: (...args) => AsyncStorage.setItem(key, ...args),
+ mergeItem: (...args) => AsyncStorage.mergeItem(key, ...args),
+ removeItem: (...args) => AsyncStorage.removeItem(key, ...args),
+ };
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/index.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/index.ts
new file mode 100644
index 00000000..d45caae4
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/index.ts
@@ -0,0 +1,7 @@
+import AsyncStorage from './AsyncStorage';
+
+export { useAsyncStorage } from './hooks';
+
+export type { AsyncStorageStatic } from './types';
+
+export default AsyncStorage;
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/shouldFallbackToLegacyNativeModule.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/shouldFallbackToLegacyNativeModule.ts
new file mode 100644
index 00000000..9e6ebc4d
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/shouldFallbackToLegacyNativeModule.ts
@@ -0,0 +1,34 @@
+import { NativeModules } from 'react-native';
+
+export function shouldFallbackToLegacyNativeModule(): boolean {
+ const expoConstants =
+ NativeModules['NativeUnimoduleProxy']?.modulesConstants?.ExponentConstants;
+
+ if (expoConstants) {
+ /**
+ * In SDK <= 39, appOwnership is defined in managed apps but executionEnvironment is not.
+ * In bare React Native apps using expo-constants, appOwnership is never defined, so
+ * isLegacySdkVersion will be false in that context.
+ */
+ const isLegacySdkVersion =
+ expoConstants.appOwnership && !expoConstants.executionEnvironment;
+
+ /**
+ * Expo managed apps don't include the @react-native-async-storage/async-storage
+ * native modules yet, but the API interface is the same, so we can use the version
+ * exported from React Native still.
+ *
+ * If in future releases (eg: @react-native-async-storage/async-storage >= 2.0.0) this
+ * will likely not be valid anymore, and the package will need to be included in the Expo SDK
+ * to continue to work.
+ */
+ if (
+ isLegacySdkVersion ||
+ ['storeClient', 'standalone'].includes(expoConstants.executionEnvironment)
+ ) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/types.ts b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/types.ts
new file mode 100644
index 00000000..94cc27f1
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/src/types.ts
@@ -0,0 +1,155 @@
+export type ErrorLike = {
+ message: string;
+ key: string;
+};
+
+export type Callback = (error?: Error | null) => void;
+
+export type CallbackWithResult = (
+ error?: Error | null,
+ result?: T | null
+) => void;
+
+export type KeyValuePair = [string, string | null];
+
+export type MultiCallback = (errors?: readonly (Error | null)[] | null) => void;
+
+export type MultiGetCallback = (
+ errors?: readonly (Error | null)[] | null,
+ result?: readonly KeyValuePair[]
+) => void;
+
+export type MultiRequest = {
+ keys: readonly string[];
+ callback?: MultiGetCallback;
+ keyIndex: number;
+ resolve?: (result: readonly KeyValuePair[]) => void;
+ reject?: (error?: any) => void;
+};
+
+export type AsyncStorageHook = {
+ getItem: (callback?: CallbackWithResult) => Promise;
+ setItem: (value: string, callback?: Callback) => Promise;
+ mergeItem: (value: string, callback?: Callback) => Promise;
+ removeItem: (callback?: Callback) => Promise;
+};
+
+/**
+ * `AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value
+ * storage system that is global to the app. It should be used instead of
+ * LocalStorage.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api
+ */
+export type AsyncStorageStatic = {
+ /**
+ * Fetches an item for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#getitem
+ */
+ getItem: (
+ key: string,
+ callback?: CallbackWithResult
+ ) => Promise;
+
+ /**
+ * Sets the value for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#setitem
+ */
+ setItem: (key: string, value: string, callback?: Callback) => Promise;
+
+ /**
+ * Removes an item for a `key` and invokes a callback upon completion.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#removeitem
+ */
+ removeItem: (key: string, callback?: Callback) => Promise;
+
+ /**
+ * Merges an existing `key` value with an input value, assuming both values
+ * are stringified JSON.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#mergeitem
+ */
+ mergeItem: (key: string, value: string, callback?: Callback) => Promise;
+
+ /**
+ * Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably
+ * don't want to call this; use `removeItem` or `multiRemove` to clear only
+ * your app's keys.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#clear
+ */
+ clear: (callback?: Callback) => Promise;
+
+ /**
+ * Gets *all* keys known to your app; for all callers, libraries, etc.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#getallkeys
+ */
+ getAllKeys: (
+ callback?: CallbackWithResult
+ ) => Promise;
+
+ /**
+ * The following batched functions are useful for executing a lot of
+ * operations at once, allowing for native optimizations and provide the
+ * convenience of a single callback after all operations are complete.
+ *
+ * These functions return arrays of errors, potentially one for every key.
+ * For key-specific errors, the Error object will have a key property to
+ * indicate which key caused the error.
+ */
+
+ /**
+ * Flushes any pending requests using a single batch call to get the data.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#flushgetrequests
+ * */
+ flushGetRequests: () => void;
+
+ /**
+ * This allows you to batch the fetching of items given an array of `key`
+ * inputs. Your callback will be invoked with an array of corresponding
+ * key-value pairs found.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiget
+ */
+ multiGet: (
+ keys: readonly string[],
+ callback?: MultiGetCallback
+ ) => Promise;
+
+ /**
+ * Use this as a batch operation for storing multiple key-value pairs. When
+ * the operation completes you'll get a single callback with any errors.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiset
+ */
+ multiSet: (
+ keyValuePairs: [string, string][],
+ callback?: MultiCallback
+ ) => Promise;
+
+ /**
+ * Call this to batch the deletion of all keys in the `keys` array.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multiremove
+ */
+ multiRemove: (
+ keys: readonly string[],
+ callback?: MultiCallback
+ ) => Promise;
+
+ /**
+ * Batch operation to merge in existing and new values for a given set of
+ * keys. This assumes that the values are stringified JSON.
+ *
+ * See https://react-native-async-storage.github.io/async-storage/docs/api#multimerge
+ */
+ multiMerge: (
+ keyValuePairs: [string, string][],
+ callback?: MultiCallback
+ ) => Promise;
+};
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage.sln b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage.sln
new file mode 100644
index 00000000..097a7b1e
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage.sln
@@ -0,0 +1,172 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30114.105
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactNativeAsyncStorage", "ReactNativeAsyncStorage\ReactNativeAsyncStorage.vcxproj", "{4855D892-E16C-404D-8286-0089E0F7F9C4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReactNative", "ReactNative", "{4F6E56C3-12C5-4457-9239-0ACF0B7150A8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "..\node_modules\react-native-windows\Common\Common.vcxproj", "{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Folly", "..\node_modules\react-native-windows\Folly\Folly.vcxproj", "{A990658C-CE31-4BCC-976F-0FC6B1AF693D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JSI.Universal", "..\node_modules\react-native-windows\JSI\Universal\JSI.Universal.vcxproj", "{A62D504A-16B8-41D2-9F19-E2E86019E5E4}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JSI.Shared", "..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems", "{0CC28589-39E4-4288-B162-97B959F8B843}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra", "..\node_modules\react-native-windows\Chakra\Chakra.vcxitems", "{C38970C0-5FBF-4D69-90D8-CBAC225AE895}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative", "..\node_modules\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj", "{F7D32BD0-2749-483E-9A0D-1635EF7E3136}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Mso", "..\node_modules\react-native-windows\Mso\Mso.vcxitems", "{84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactCommon", "..\node_modules\react-native-windows\ReactCommon\ReactCommon.vcxproj", "{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative.Cxx", "..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems", "{DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative.Shared", "..\node_modules\react-native-windows\Shared\Shared.vcxitems", "{2049DBE9-8D13-42C9-AE4B-413AE38FFFD0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Include", "..\node_modules\react-native-windows\include\Include.vcxitems", "{EF074BA1-2D54-4D49-A28E-5E040B47CD2E}"
+EndProject
+Global
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ ..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{0cc28589-39e4-4288-b162-97b959f8b843}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\Shared\Shared.vcxitems*{2049dbe9-8d13-42c9-ae4b-413ae38fffd0}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\Mso\Mso.vcxitems*{84e05bfa-cbaf-4f0d-bfb6-4ce85742a57e}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{a62d504a-16b8-41d2-9f19-e2e86019e5e4}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{c38970c0-5fbf-4d69-90d8-cbac225ae895}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{da8b35b3-da00-4b02-bde6-6a397b3fd46b}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\include\Include.vcxitems*{ef074ba1-2d54-4d49-a28e-5e040b47cd2e}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Mso\Mso.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM = Release|ARM
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|ARM.ActiveCfg = Debug|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|ARM.Build.0 = Debug|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|ARM64.ActiveCfg = Debug|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x64.ActiveCfg = Debug|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x64.Build.0 = Debug|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x86.ActiveCfg = Debug|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x86.Build.0 = Debug|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|ARM.ActiveCfg = Release|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|ARM.Build.0 = Release|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|ARM64.ActiveCfg = Release|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x64.ActiveCfg = Release|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x64.Build.0 = Release|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x86.ActiveCfg = Release|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x86.Build.0 = Release|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.ActiveCfg = Debug|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.Build.0 = Debug|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.Build.0 = Debug|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.ActiveCfg = Debug|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.Build.0 = Debug|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.ActiveCfg = Debug|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.Build.0 = Debug|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.ActiveCfg = Release|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.Build.0 = Release|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.ActiveCfg = Release|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.Build.0 = Release|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.ActiveCfg = Release|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.ActiveCfg = Debug|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.Build.0 = Debug|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.ActiveCfg = Debug|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.Build.0 = Debug|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.ActiveCfg = Debug|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.Build.0 = Debug|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.ActiveCfg = Release|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.Build.0 = Release|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.Build.0 = Release|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.ActiveCfg = Release|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.ActiveCfg = Debug|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.Build.0 = Debug|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.ActiveCfg = Debug|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.Build.0 = Debug|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.ActiveCfg = Debug|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.Build.0 = Debug|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.ActiveCfg = Release|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.Build.0 = Release|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.Build.0 = Release|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.ActiveCfg = Release|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.Build.0 = Release|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.ActiveCfg = Release|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.Build.0 = Release|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.ActiveCfg = Debug|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.Build.0 = Debug|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.Build.0 = Debug|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.ActiveCfg = Debug|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.Build.0 = Debug|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.ActiveCfg = Debug|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.Build.0 = Debug|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.ActiveCfg = Release|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.Build.0 = Release|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.ActiveCfg = Release|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.Build.0 = Release|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.ActiveCfg = Release|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.Build.0 = Release|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.ActiveCfg = Release|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.Build.0 = Release|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.ActiveCfg = Debug|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.Build.0 = Debug|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.Build.0 = Debug|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.ActiveCfg = Debug|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.Build.0 = Debug|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.ActiveCfg = Release|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.Build.0 = Release|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.Build.0 = Release|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.ActiveCfg = Release|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.Build.0 = Release|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.ActiveCfg = Release|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {0CC28589-39E4-4288-B162-97B959F8B843} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {C38970C0-5FBF-4D69-90D8-CBAC225AE895} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {2049DBE9-8D13-42C9-AE4B-413AE38FFFD0} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {EF074BA1-2D54-4D49-A28E-5E040B47CD2E} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {1F02BFA9-97C8-4ACF-A348-B3166C3BC7EA}
+ EndGlobalSection
+EndGlobal
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/PropertySheet.props b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/PropertySheet.props
new file mode 100644
index 00000000..e34141b0
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/PropertySheet.props
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/ReactNativeAsyncStorage.vcxproj b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/ReactNativeAsyncStorage.vcxproj
new file mode 100644
index 00000000..fb2a1413
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/ReactNativeAsyncStorage.vcxproj
@@ -0,0 +1,172 @@
+
+
+
+
+ true
+ true
+ true
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}
+ ReactNativeAsyncStorage
+ ReactNativeAsyncStorage
+ en-US
+ 16.0
+ true
+ Windows Store
+ 10.0
+ 10.0
+ 10.0.16299.0
+
+
+
+ $([MSBuild]::GetDirectoryNameOfFileAbove($(SolutionDir), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\
+
+
+
+ Debug
+ ARM
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ ARM
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ DynamicLibrary
+ Unicode
+ false
+
+
+ true
+ true
+
+
+ false
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Use
+ pch.h
+ $(IntDir)pch.pch
+ Level4
+ %(AdditionalOptions) /bigobj
+
+ /DWINRT_NO_MAKE_DETECTION %(AdditionalOptions)
+ 28204
+ _WINRT_DLL;%(PreprocessorDefinitions)
+ $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)
+
+
+ Console
+ true
+ ..\code\ReactNativeAsyncStorage.def
+ winsqlite3.lib;%(AdditionalDependencies)
+ winsqlite3.dll;%(DelayLoadDLLs)
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+
+
+
+ ..\code\ReactPackageProvider.idl
+
+
+
+
+
+
+ Create
+
+
+
+ ..\code\ReactPackageProvider.idl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {f7d32bd0-2749-483e-9a0d-1635ef7e3136}
+ false
+
+
+
+
+
+
+
+
+ This project references targets in your node_modules\react-native-windows folder. The missing file is {0}.
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/ReactNativeAsyncStorage.vcxproj.filters b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/ReactNativeAsyncStorage.vcxproj.filters
new file mode 100644
index 00000000..ea4835e8
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/ReactNativeAsyncStorage.vcxproj.filters
@@ -0,0 +1,34 @@
+
+
+
+
+ accd3aa8-1ba0-4223-9bbe-0c431709210b
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {926ab91d-31b4-48c3-b9a4-e681349f27f0}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/packages.config b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/packages.config
new file mode 100644
index 00000000..1447e714
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61.sln b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61.sln
new file mode 100644
index 00000000..78227e19
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61.sln
@@ -0,0 +1,195 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29215.179
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Folly", "..\node_modules\react-native-windows\Folly\Folly.vcxproj", "{A990658C-CE31-4BCC-976F-0FC6B1AF693D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactCommon", "..\node_modules\react-native-windows\ReactCommon\ReactCommon.vcxproj", "{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}"
+ ProjectSection(ProjectDependencies) = postProject
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {A990658C-CE31-4BCC-976F-0FC6B1AF693D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactWindowsCore", "..\node_modules\react-native-windows\ReactWindowsCore\ReactWindowsCore.vcxproj", "{11C084A3-A57C-4296-A679-CAC17B603144}"
+ ProjectSection(ProjectDependencies) = postProject
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {A990658C-CE31-4BCC-976F-0FC6B1AF693D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra", "..\node_modules\react-native-windows\Chakra\Chakra.vcxitems", "{C38970C0-5FBF-4D69-90D8-CBAC225AE895}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative", "..\node_modules\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj", "{F7D32BD0-2749-483E-9A0D-1635EF7E3136}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JSI.Shared", "..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems", "{0CC28589-39E4-4288-B162-97B959F8B843}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JSI.Universal", "..\node_modules\react-native-windows\JSI\Universal\JSI.Universal.vcxproj", "{A62D504A-16B8-41D2-9F19-E2E86019E5E4}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative.Cxx", "..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems", "{DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B}"
+EndProject
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.ReactNative.SharedManaged", "..\node_modules\react-native-windows\Microsoft.ReactNative.SharedManaged\Microsoft.ReactNative.SharedManaged.shproj", "{67A1076F-7790-4203-86EA-4402CCB5E782}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "..\node_modules\react-native-windows\Common\Common.vcxproj", "{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReactNative", "ReactNative", "{5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shared", "..\node_modules\react-native-windows\Shared\Shared.vcxitems", "{2049DBE9-8D13-42C9-AE4B-413AE38FFFD0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Mso", "..\node_modules\react-native-windows\Mso\Mso.vcxitems", "{84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactNativeAsyncStorage61", "ReactNativeAsyncStorage61\ReactNativeAsyncStorage61.vcxproj", "{4855D892-E16C-404D-8286-0089E0F7F9C4}"
+EndProject
+Global
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ ..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{0cc28589-39e4-4288-b162-97b959f8b843}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\Shared\Shared.vcxitems*{2049dbe9-8d13-42c9-ae4b-413ae38fffd0}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{4855d892-e16c-404d-8286-0089e0f7f9c4}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Microsoft.ReactNative.SharedManaged\Microsoft.ReactNative.SharedManaged.projitems*{67a1076f-7790-4203-86ea-4402ccb5e782}*SharedItemsImports = 13
+ ..\node_modules\react-native-windows\Mso\Mso.vcxitems*{84e05bfa-cbaf-4f0d-bfb6-4ce85742a57e}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{a62d504a-16b8-41d2-9f19-e2e86019e5e4}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{c38970c0-5fbf-4d69-90d8-cbac225ae895}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{da8b35b3-da00-4b02-bde6-6a397b3fd46b}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Mso\Mso.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM = Release|ARM
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|ARM.ActiveCfg = Debug|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|ARM.Build.0 = Debug|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|ARM64.ActiveCfg = Debug|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x64.ActiveCfg = Debug|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x64.Build.0 = Debug|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x86.ActiveCfg = Debug|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x86.Build.0 = Debug|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|ARM.ActiveCfg = Release|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|ARM.Build.0 = Release|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|ARM64.ActiveCfg = Release|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x64.ActiveCfg = Release|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x64.Build.0 = Release|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x86.ActiveCfg = Release|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x86.Build.0 = Release|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.ActiveCfg = Debug|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.Build.0 = Debug|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.Build.0 = Debug|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.ActiveCfg = Debug|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.Build.0 = Debug|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.ActiveCfg = Debug|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.Build.0 = Debug|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.ActiveCfg = Release|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.Build.0 = Release|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.ActiveCfg = Release|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.Build.0 = Release|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.ActiveCfg = Release|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.ActiveCfg = Debug|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.Build.0 = Debug|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.ActiveCfg = Debug|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.Build.0 = Debug|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.ActiveCfg = Debug|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.Build.0 = Debug|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.ActiveCfg = Release|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.Build.0 = Release|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.Build.0 = Release|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.ActiveCfg = Release|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.ActiveCfg = Debug|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.Build.0 = Debug|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.ActiveCfg = Debug|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.Build.0 = Debug|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.ActiveCfg = Debug|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.Build.0 = Debug|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.ActiveCfg = Release|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.Build.0 = Release|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.Build.0 = Release|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.ActiveCfg = Release|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.Build.0 = Release|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.ActiveCfg = Release|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.Build.0 = Release|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.ActiveCfg = Debug|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.Build.0 = Debug|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.Build.0 = Debug|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.ActiveCfg = Debug|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.Build.0 = Debug|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.ActiveCfg = Debug|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.Build.0 = Debug|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.ActiveCfg = Release|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.Build.0 = Release|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.ActiveCfg = Release|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.Build.0 = Release|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.ActiveCfg = Release|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.Build.0 = Release|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.ActiveCfg = Release|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.Build.0 = Release|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.ActiveCfg = Debug|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.Build.0 = Debug|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.Build.0 = Debug|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.ActiveCfg = Debug|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.Build.0 = Debug|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.ActiveCfg = Release|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.Build.0 = Release|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.Build.0 = Release|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.ActiveCfg = Release|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.Build.0 = Release|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.ActiveCfg = Release|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.Build.0 = Release|Win32
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.ActiveCfg = Debug|ARM
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.Build.0 = Debug|ARM
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.Build.0 = Debug|ARM64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.ActiveCfg = Debug|x64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.Build.0 = Debug|x64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.ActiveCfg = Debug|Win32
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.Build.0 = Debug|Win32
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.ActiveCfg = Release|ARM
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.Build.0 = Release|ARM
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.ActiveCfg = Release|ARM64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.Build.0 = Release|ARM64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.ActiveCfg = Release|x64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.Build.0 = Release|x64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.ActiveCfg = Release|Win32
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C38970C0-5FBF-4D69-90D8-CBAC225AE895} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
+ {0CC28589-39E4-4288-B162-97B959F8B843} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
+ {DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
+ {67A1076F-7790-4203-86EA-4402CCB5E782} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
+ {11C084A3-A57C-4296-A679-CAC17B603144} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {1F02BFA9-97C8-4ACF-A348-B3166C3BC7EA}
+ EndGlobalSection
+EndGlobal
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/PropertySheet.props b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/PropertySheet.props
new file mode 100644
index 00000000..e34141b0
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/PropertySheet.props
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/ReactNativeAsyncStorage61.vcxproj b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/ReactNativeAsyncStorage61.vcxproj
new file mode 100644
index 00000000..8b67f000
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/ReactNativeAsyncStorage61.vcxproj
@@ -0,0 +1,157 @@
+
+
+
+
+ true
+ true
+ true
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}
+ ReactNativeAsyncStorage61
+ ReactNativeAsyncStorage
+ en-US
+ 14.0
+ true
+ Windows Store
+ 10.0
+ 10.0.18362.0
+ 10.0.15063.0
+
+
+
+ $([MSBuild]::GetDirectoryNameOfFileAbove($(SolutionDir), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\
+
+
+
+ Debug
+ ARM
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ ARM
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ DynamicLibrary
+ v140
+ v141
+ v142
+ Unicode
+ false
+
+
+ true
+ true
+
+
+ false
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Use
+ pch.h
+ $(IntDir)pch.pch
+ Level4
+ %(AdditionalOptions) /bigobj
+
+ /DWINRT_NO_MAKE_DETECTION %(AdditionalOptions)
+ 28204
+ _WINRT_DLL;RNW_61;%(PreprocessorDefinitions)
+ $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)
+
+
+ Console
+ true
+ ..\code\ReactNativeAsyncStorage.def
+ winsqlite3.lib;%(AdditionalDependencies)
+ winsqlite3.dll;%(DelayLoadDLLs)
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+
+
+
+ ..\code\ReactPackageProvider.idl
+
+
+
+
+
+
+ Create
+
+
+
+ ..\code\ReactPackageProvider.idl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {f7d32bd0-2749-483e-9a0d-1635ef7e3136}
+ false
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/ReactNativeAsyncStorage61.vcxproj.filters b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/ReactNativeAsyncStorage61.vcxproj.filters
new file mode 100644
index 00000000..1fa75baa
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/ReactNativeAsyncStorage61.vcxproj.filters
@@ -0,0 +1,34 @@
+
+
+
+
+ accd3aa8-1ba0-4223-9bbe-0c431709210b
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {926ab91d-31b4-48c3-b9a4-e681349f27f0}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/packages.config b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/packages.config
new file mode 100644
index 00000000..790637ce
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage61/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage62.sln b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage62.sln
new file mode 100644
index 00000000..55b596e0
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/ReactNativeAsyncStorage62.sln
@@ -0,0 +1,192 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30114.105
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactNativeAsyncStorage", "ReactNativeAsyncStorage\ReactNativeAsyncStorage.vcxproj", "{4855D892-E16C-404D-8286-0089E0F7F9C4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReactNative", "ReactNative", "{4F6E56C3-12C5-4457-9239-0ACF0B7150A8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "..\node_modules\react-native-windows\Common\Common.vcxproj", "{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Folly", "..\node_modules\react-native-windows\Folly\Folly.vcxproj", "{A990658C-CE31-4BCC-976F-0FC6B1AF693D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JSI.Universal", "..\node_modules\react-native-windows\JSI\Universal\JSI.Universal.vcxproj", "{A62D504A-16B8-41D2-9F19-E2E86019E5E4}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JSI.Shared", "..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems", "{0CC28589-39E4-4288-B162-97B959F8B843}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra", "..\node_modules\react-native-windows\Chakra\Chakra.vcxitems", "{C38970C0-5FBF-4D69-90D8-CBAC225AE895}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative", "..\node_modules\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj", "{F7D32BD0-2749-483E-9A0D-1635EF7E3136}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Mso", "..\node_modules\react-native-windows\Mso\Mso.vcxitems", "{84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactCommon", "..\node_modules\react-native-windows\ReactCommon\ReactCommon.vcxproj", "{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative.Cxx", "..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems", "{DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shared", "..\node_modules\react-native-windows\Shared\Shared.vcxitems", "{2049DBE9-8D13-42C9-AE4B-413AE38FFFD0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactWindowsCore", "..\node_modules\react-native-windows\ReactWindowsCore\ReactWindowsCore.vcxproj", "{11C084A3-A57C-4296-A679-CAC17B603144}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Include", "..\node_modules\react-native-windows\include\Include.vcxitems", "{EF074BA1-2D54-4D49-A28E-5E040B47CD2E}"
+EndProject
+Global
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ ..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{0cc28589-39e4-4288-b162-97b959f8b843}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\ReactWindowsCore\ReactWindowsCore.vcxitems*{11c084a3-a57c-4296-a679-cac17b603144}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Shared\Shared.vcxitems*{2049dbe9-8d13-42c9-ae4b-413ae38fffd0}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\Mso\Mso.vcxitems*{84e05bfa-cbaf-4f0d-bfb6-4ce85742a57e}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{a62d504a-16b8-41d2-9f19-e2e86019e5e4}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{c38970c0-5fbf-4d69-90d8-cbac225ae895}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{da8b35b3-da00-4b02-bde6-6a397b3fd46b}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\include\Include.vcxitems*{ef074ba1-2d54-4d49-a28e-5e040b47cd2e}*SharedItemsImports = 9
+ ..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\JSI\Shared\JSI.Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Mso\Mso.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ ..\node_modules\react-native-windows\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM = Release|ARM
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|ARM.ActiveCfg = Debug|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|ARM.Build.0 = Debug|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|ARM64.ActiveCfg = Debug|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x64.ActiveCfg = Debug|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x64.Build.0 = Debug|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x86.ActiveCfg = Debug|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Debug|x86.Build.0 = Debug|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|ARM.ActiveCfg = Release|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|ARM.Build.0 = Release|ARM
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|ARM64.ActiveCfg = Release|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x64.ActiveCfg = Release|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x64.Build.0 = Release|x64
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x86.ActiveCfg = Release|Win32
+ {4855D892-E16C-404D-8286-0089E0F7F9C4}.Release|x86.Build.0 = Release|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.ActiveCfg = Debug|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.Build.0 = Debug|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.Build.0 = Debug|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.ActiveCfg = Debug|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.Build.0 = Debug|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.ActiveCfg = Debug|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.Build.0 = Debug|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.ActiveCfg = Release|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.Build.0 = Release|ARM
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.ActiveCfg = Release|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.Build.0 = Release|ARM64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.ActiveCfg = Release|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.ActiveCfg = Debug|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.Build.0 = Debug|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.ActiveCfg = Debug|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.Build.0 = Debug|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.ActiveCfg = Debug|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.Build.0 = Debug|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.ActiveCfg = Release|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.Build.0 = Release|ARM
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.Build.0 = Release|ARM64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.ActiveCfg = Release|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.ActiveCfg = Debug|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.Build.0 = Debug|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.ActiveCfg = Debug|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.Build.0 = Debug|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.ActiveCfg = Debug|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.Build.0 = Debug|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.ActiveCfg = Release|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.Build.0 = Release|ARM
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.Build.0 = Release|ARM64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.ActiveCfg = Release|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.Build.0 = Release|x64
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.ActiveCfg = Release|Win32
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.Build.0 = Release|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.ActiveCfg = Debug|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.Build.0 = Debug|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.Build.0 = Debug|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.ActiveCfg = Debug|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.Build.0 = Debug|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.ActiveCfg = Debug|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.Build.0 = Debug|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.ActiveCfg = Release|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.Build.0 = Release|ARM
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.ActiveCfg = Release|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.Build.0 = Release|ARM64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.ActiveCfg = Release|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.Build.0 = Release|x64
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.ActiveCfg = Release|Win32
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.Build.0 = Release|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.ActiveCfg = Debug|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.Build.0 = Debug|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.Build.0 = Debug|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.ActiveCfg = Debug|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.Build.0 = Debug|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.ActiveCfg = Release|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.Build.0 = Release|ARM
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.Build.0 = Release|ARM64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.ActiveCfg = Release|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.Build.0 = Release|x64
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.ActiveCfg = Release|Win32
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.Build.0 = Release|Win32
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.ActiveCfg = Debug|ARM
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.Build.0 = Debug|ARM
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.Build.0 = Debug|ARM64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.ActiveCfg = Debug|x64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.Build.0 = Debug|x64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.ActiveCfg = Debug|Win32
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.Build.0 = Debug|Win32
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.ActiveCfg = Release|ARM
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.Build.0 = Release|ARM
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.ActiveCfg = Release|ARM64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.Build.0 = Release|ARM64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.ActiveCfg = Release|x64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.Build.0 = Release|x64
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.ActiveCfg = Release|Win32
+ {11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {FCA38F3C-7C73-4C47-BE4E-32F77FA8538D} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {A62D504A-16B8-41D2-9F19-E2E86019E5E4} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {0CC28589-39E4-4288-B162-97B959F8B843} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {C38970C0-5FBF-4D69-90D8-CBAC225AE895} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {F7D32BD0-2749-483E-9A0D-1635EF7E3136} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {2049DBE9-8D13-42C9-AE4B-413AE38FFFD0} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {11C084A3-A57C-4296-A679-CAC17B603144} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ {EF074BA1-2D54-4D49-A28E-5E040B47CD2E} = {4F6E56C3-12C5-4457-9239-0ACF0B7150A8}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {1F02BFA9-97C8-4ACF-A348-B3166C3BC7EA}
+ EndGlobalSection
+EndGlobal
diff --git a/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/code/DBStorage.cpp b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/code/DBStorage.cpp
new file mode 100644
index 00000000..87b9bed1
--- /dev/null
+++ b/iut-expo-starter/node_modules/@react-native-async-storage/async-storage/windows/code/DBStorage.cpp
@@ -0,0 +1,599 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+#include "pch.h"
+
+#include "DBStorage.h"
+
+#include
+
+namespace winrt
+{
+ using namespace Microsoft::ReactNative;
+ using namespace Windows::ApplicationModel::Core;
+ using namespace Windows::Data::Json;
+ using namespace Windows::Foundation;
+ using namespace Windows::Storage;
+} // namespace winrt
+
+// All functions below return std::nullopt on error.
+#define CHECK(expr) \
+ if (!(expr)) { \
+ return std::nullopt; \
+ }
+
+// Convenience macro to call CheckSQLiteResult.
+#define CHECK_SQL_OK(expr) CHECK(CheckSQLiteResult(db, m_errorManager, (expr)))
+
+namespace
+{
+ // To implement safe operator& for unique_ptr.
+ template
+ struct UniquePtrSetter {
+ UniquePtrSetter(std::unique_ptr &ptr) noexcept : m_ptr(ptr)
+ {
+ }
+
+ ~UniquePtrSetter()
+ {
+ m_ptr = {m_rawPtr, m_ptr.get_deleter()};
+ }
+
+ operator T **() noexcept
+ {
+ return &m_rawPtr;
+ }
+
+ private:
+ T *m_rawPtr{};
+ std::unique_ptr &m_ptr;
+ };
+
+ template
+ UniquePtrSetter operator&(std::unique_ptr &ptr) noexcept
+ {
+ return UniquePtrSetter(ptr);
+ }
+
+ using ExecCallback = int(SQLITE_CALLBACK *)(void *callbackData,
+ int columnCount,
+ char **columnTexts,
+ char **columnNames);
+
+ // Execute the provided SQLite statement (and optional execCallback & user data
+ // in callbackData). On error, report it to the errorManager and return std::nullopt.
+ std::optional Exec(sqlite3 *db,
+ DBStorage::ErrorManager &errorManager,
+ const char *statement,
+ ExecCallback execCallback = nullptr,
+ void *callbackData = nullptr) noexcept
+ {
+ auto errMsg = std::unique_ptr{nullptr, &sqlite3_free};
+ int rc = sqlite3_exec(db, statement, execCallback, callbackData, &errMsg);
+ if (errMsg) {
+ return errorManager.AddError(errMsg.get());
+ }
+ if (rc != SQLITE_OK) {
+ return errorManager.AddError(sqlite3_errmsg(db));
+ }
+ return true;
+ }
+
+ // Convenience wrapper for using Exec with lambda expressions.
+ template
+ std::optional
+ Exec(sqlite3 *db, DBStorage::ErrorManager &errorManager, const char *statement, Fn &fn) noexcept
+ {
+ return Exec(
+ db,
+ errorManager,
+ statement,
+ [](void *callbackData, int columnCount, char **columnTexts, char **columnNames) {
+ return (*static_cast(callbackData))(columnCount, columnTexts, columnNames);
+ },
+ &fn);
+ }
+
+ // Check that the args collection size is less than SQLITE_LIMIT_VARIABLE_NUMBER, and that
+ // every member of args is not an empty string.
+ // On error, report it to the errorManager and return std::nullopt.
+ std::optional CheckArgs(sqlite3 *db,
+ DBStorage::ErrorManager &errorManager,
+ const std::vector &args) noexcept
+ {
+ int varLimit = sqlite3_limit(db, SQLITE_LIMIT_VARIABLE_NUMBER, -1);
+ auto argCount = args.size();
+ if (argCount > static_cast(std::numeric_limits::max()) ||
+ static_cast(argCount) > varLimit) {
+ char errorMsg[60];
+ sprintf_s(errorMsg, "Too many keys. Maximum supported keys :%d.", varLimit);
+ return errorManager.AddError(errorMsg);
+ }
+ for (int i = 0; i < static_cast(argCount); i++) {
+ if (args[i].empty()) {
+ return errorManager.AddError("The key must be a non-empty string.");
+ }
+ }
+ return true;
+ }
+
+ // RAII object to manage SQLite transaction. On destruction, if
+ // Commit() has not been called, rolls back the transactions.
+ // The provided SQLite connection handle & errorManager must outlive
+ // the Sqlite3Transaction object.
+ struct Sqlite3Transaction {
+ Sqlite3Transaction(sqlite3 *db, DBStorage::ErrorManager &errorManager) noexcept
+ : m_db(db), m_errorManager(errorManager)
+ {
+ if (!Exec(m_db, m_errorManager, "BEGIN TRANSACTION")) {
+ m_db = nullptr;
+ }
+ }
+
+ Sqlite3Transaction(const Sqlite3Transaction &) = delete;
+ Sqlite3Transaction &operator=(const Sqlite3Transaction &) = delete;
+
+ ~Sqlite3Transaction()
+ {
+ Rollback();
+ }
+
+ explicit operator bool() const noexcept
+ {
+ return m_db != nullptr;
+ }
+
+ std::optional Commit() noexcept
+ {
+ if (m_db) {
+ return Exec(std::exchange(m_db, nullptr), m_errorManager, "COMMIT");
+ }
+ return std::nullopt;
+ }
+
+ std::optional Rollback() noexcept
+ {
+ if (m_db) {
+ return Exec(std::exchange(m_db, nullptr), m_errorManager, "ROLLBACK");
+ }
+ return std::nullopt;
+ }
+
+ private:
+ sqlite3 *m_db{};
+ DBStorage::ErrorManager &m_errorManager;
+ };
+
+ // Append argCount variables to prefix in a comma-separated list.
+ std::string MakeSQLiteParameterizedStatement(const char *prefix, int argCount) noexcept
+ {
+ assert(argCount != 0);
+ std::string result(prefix);
+ result.reserve(result.size() + (argCount * 2) + 1);
+ result += '(';
+ for (int x = 0; x < argCount - 1; x++) {
+ result += "?,";
+ }
+ result += "?)";
+ return result;
+ }
+
+ // Check if sqliteResult is SQLITE_OK.
+ // If not, report the error to the errorManager and return std::nullopt.
+ std::optional CheckSQLiteResult(sqlite3 *db,
+ DBStorage::ErrorManager &errorManager,
+ int sqliteResult) noexcept
+ {
+ if (sqliteResult == SQLITE_OK) {
+ return true;
+ } else {
+ return errorManager.AddError(sqlite3_errmsg(db));
+ }
+ }
+
+ using StatementPtr = std::unique_ptr;
+
+ // A convenience wrapper for sqlite3_prepare_v2 function.
+ int PrepareStatement(sqlite3 *db,
+ const std::string &statementText,
+ sqlite3_stmt **statement) noexcept
+ {
+ return sqlite3_prepare_v2(db, statementText.c_str(), -1, statement, nullptr);
+ }
+
+ // A convenience wrapper for sqlite3_bind_text function.
+ int BindString(StatementPtr &statement, int index, const std::string &str) noexcept
+ {
+ return sqlite3_bind_text(statement.get(), index, str.c_str(), -1, SQLITE_TRANSIENT);
+ }
+
+ // Merge source into destination.
+ // It only merges objects - all other types are just clobbered (including arrays).
+ void MergeJsonObjects(winrt::JsonObject const &destination,
+ winrt::JsonObject const &source) noexcept
+ {
+ for (auto keyValue : source) {
+ auto key = keyValue.Key();
+ auto sourceValue = keyValue.Value();
+ if (destination.HasKey(key)) {
+ auto destinationValue = destination.GetNamedValue(key);
+ if (destinationValue.ValueType() == winrt::JsonValueType::Object &&
+ sourceValue.ValueType() == winrt::JsonValueType::Object) {
+ MergeJsonObjects(destinationValue.GetObject(), sourceValue.GetObject());
+ continue;
+ }
+ }
+ destination.SetNamedValue(key, sourceValue);
+ }
+ }
+} // namespace
+
+// Initialize storage. On error, report it to the errorManager and return std::nullopt.
+std::optional
+DBStorage::InitializeStorage(DBStorage::ErrorManager &errorManager) noexcept
+{
+ winrt::slim_lock_guard guard{m_lock};
+ if (m_db) {
+ return m_db.get();
+ }
+
+ std::string path;
+ try {
+ if (auto pathInspectable =
+ winrt::CoreApplication::Properties().TryLookup(s_dbPathProperty)) {
+ path = winrt::to_string(winrt::unbox_value(pathInspectable));
+ } else {
+ auto const localAppDataPath = winrt::ApplicationData::Current().LocalFolder().Path();
+ path = winrt::to_string(localAppDataPath) + "\\AsyncStorage.db";
+ }
+ } catch (const winrt::hresult_error &error) {
+ errorManager.AddError(winrt::to_string(error.message()));
+ return errorManager.AddError(
+ "Please specify 'React-Native-Community-Async-Storage-Database-Path' in "
+ "CoreApplication::Properties");
+ }
+
+ auto db = DatabasePtr{nullptr, &sqlite3_close};
+ if (sqlite3_open_v2(path.c_str(),
+ &db,
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX,
+ nullptr) != SQLITE_OK) {
+ if (db) {
+ return errorManager.AddError(sqlite3_errmsg(db.get()));
+ } else {
+ return errorManager.AddError("Storage database cannot be opened.");
+ }
+ }
+
+ int userVersion = 0;
+ auto getUserVersionCallback =
+ [](void *callbackData, int colomnCount, char **columnTexts, char ** /*columnNames*/) {
+ if (colomnCount < 1) {
+ return 1;
+ }
+ *static_cast(callbackData) = atoi(columnTexts[0]);
+ return SQLITE_OK;
+ };
+
+ CHECK(
+ Exec(db.get(), errorManager, "PRAGMA user_version", getUserVersionCallback, &userVersion));
+
+ if (userVersion == 0) {
+ CHECK(Exec(db.get(),
+ errorManager,
+ "CREATE TABLE IF NOT EXISTS AsyncLocalStorage(key TEXT PRIMARY KEY, value TEXT "
+ "NOT NULL); PRAGMA user_version=1"));
+ }
+
+ m_db = std::move(db);
+ return m_db.get();
+}
+
+DBStorage::~DBStorage()
+{
+ decltype(m_tasks) tasks;
+ {
+ // If there is an in-progress async task, cancel it and wait on the condition_variable for
+ // the async task to acknowledge cancellation by nulling out m_action. Once m_action is
+ // null, it is safe to proceed with closing the DB connection. The DB connection is closed
+ // by the m_db destructor.
+ winrt::slim_lock_guard guard{m_lock};
+ swap(tasks, m_tasks);
+ if (m_action) {
+ m_action.Cancel();
+ m_cv.wait(m_lock, [this]() { return m_action == nullptr; });
+ }
+ }
+}
+
+// Under the lock, add a task to m_tasks and, if no async task is in progress schedule it.
+void DBStorage::AddTask(ErrorManager &errorManager,
+ std::function &&onRun) noexcept
+{
+ winrt::slim_lock_guard guard(m_lock);
+ m_tasks.push_back(std::make_unique(errorManager, std::move(onRun)));
+ if (!m_action) {
+ m_action = RunTasks();
+ }
+}
+
+// On a background thread, while the async task has not been canceled and
+// there are more tasks to do, run the tasks. When there are either no more
+// tasks or cancellation has been requested, set m_action to null to report
+// that and complete the coroutine. N.B., it is important that detecting that
+// m_tasks is empty and acknowledging completion is done atomically; otherwise
+// there would be a race between the background task detecting m_tasks.empty()
+// and AddTask checking the coroutine is running.
+winrt::Windows::Foundation::IAsyncAction DBStorage::RunTasks() noexcept
+{
+ auto cancellationToken = co_await winrt::get_cancellation_token();
+ co_await winrt::resume_background();
+ for (;;) {
+ decltype(m_tasks) tasks;
+ sqlite3 *db{nullptr};
+ {
+ winrt::slim_lock_guard guard(m_lock);
+ if (m_tasks.empty()) {
+ m_action = nullptr;
+ m_cv.notify_all();
+ co_return;
+ }
+ std::swap(tasks, m_tasks);
+ db = m_db.get();
+ }
+
+ for (auto &task : tasks) {
+ if (!cancellationToken()) {
+ task->Run(*this, db);
+ } else {
+ task->Cancel();
+ }
+ }
+ }
+}
+
+// Add new Error to the error list.
+// Return std::nullopt for convenience to other methods that use std::nullopt to indicate error
+// result.
+std::nullopt_t DBStorage::ErrorManager::AddError(std::string &&message) noexcept
+{
+ m_errors.push_back(Error{std::move(message)});
+ return std::nullopt;
+}
+
+bool DBStorage::ErrorManager::HasErrors() const noexcept
+{
+ return !m_errors.empty();
+}
+
+const std::vector &DBStorage::ErrorManager::GetErrorList() const noexcept
+{
+ if (HasErrors()) {
+ return m_errors;
+ }
+ static std::vector s_unknownError{Error{"Unknown error."}};
+ return s_unknownError;
+}
+
+DBStorage::Error DBStorage::ErrorManager::GetCombinedError() const noexcept
+{
+ auto &errors = GetErrorList();
+ if (errors.size() == 1) {
+ return errors[0];
+ }
+
+ std::string combinedMessage;
+ for (const auto &error : errors) {
+ combinedMessage += error.Message + '\n';
+ }
+ return Error{std::move(combinedMessage)};
+}
+
+DBStorage::DBTask::DBTask(DBStorage::ErrorManager &errorManager,
+ std::function &&onRun) noexcept
+ : m_errorManager(errorManager), m_onRun(std::move(onRun))
+{
+}
+
+void DBStorage::DBTask::Run(DBStorage &storage, sqlite3 *db) noexcept
+{
+ if (!db) {
+ // We initialize DB handler on demand to report errors in the task context.
+ if (auto res = storage.InitializeStorage(m_errorManager)) {
+ db = *res;
+ }
+ }
+ if (db) {
+ m_onRun(*this, db);
+ }
+}
+
+void DBStorage::DBTask::Cancel() noexcept
+{
+ m_errorManager.AddError("Task is canceled.");
+}
+
+std::optional>
+DBStorage::DBTask::MultiGet(sqlite3 *db, const std::vector &keys) noexcept
+{
+ CHECK(!m_errorManager.HasErrors());
+ CHECK(CheckArgs(db, m_errorManager, keys));
+
+ auto argCount = static_cast(keys.size());
+ auto sql = MakeSQLiteParameterizedStatement(
+ "SELECT key, value FROM AsyncLocalStorage WHERE key IN ", argCount);
+ auto statement = StatementPtr{nullptr, &sqlite3_finalize};
+ CHECK_SQL_OK(PrepareStatement(db, sql, &statement));
+ for (int i = 0; i < argCount; i++) {
+ CHECK_SQL_OK(BindString(statement, i + 1, keys[i]));
+ }
+
+ std::vector result;
+ for (;;) {
+ auto stepResult = sqlite3_step(statement.get());
+ if (stepResult == SQLITE_DONE) {
+ break;
+ }
+ if (stepResult != SQLITE_ROW) {
+ return m_errorManager.AddError(sqlite3_errmsg(db));
+ }
+
+ auto key = reinterpret_cast(sqlite3_column_text(statement.get(), 0));
+ if (!key) {
+ return m_errorManager.AddError(sqlite3_errmsg(db));
+ }
+ auto value = reinterpret_cast(sqlite3_column_text(statement.get(), 1));
+ if (!value) {
+ return m_errorManager.AddError(sqlite3_errmsg(db));
+ }
+ result.push_back(KeyValue{key, value});
+ }
+ return result;
+}
+
+std::optional DBStorage::DBTask::MultiSet(sqlite3 *db,
+ const std::vector &keyValues) noexcept
+{
+ CHECK(!m_errorManager.HasErrors());
+ if (keyValues.empty()) {
+ return true; // nothing to do
+ }
+
+ Sqlite3Transaction transaction(db, m_errorManager);
+ CHECK(transaction);
+ auto statement = StatementPtr{nullptr, &sqlite3_finalize};
+ CHECK_SQL_OK(
+ PrepareStatement(db, "INSERT OR REPLACE INTO AsyncLocalStorage VALUES(?, ?)", &statement));
+ for (const auto &keyValue : keyValues) {
+ CHECK_SQL_OK(BindString(statement, 1, keyValue.Key));
+ CHECK_SQL_OK(BindString(statement, 2, keyValue.Value));
+ auto rc = sqlite3_step(statement.get());
+ CHECK(rc == SQLITE_DONE || CheckSQLiteResult(db, m_errorManager, rc));
+ CHECK_SQL_OK(sqlite3_reset(statement.get()));
+ }
+ CHECK(transaction.Commit());
+ return true;
+}
+
+std::optional DBStorage::DBTask::MultiMerge(sqlite3 *db,
+ const std::vector