From e76556cf98ad0ecd7c8ade72ee5b04d7578a9337 Mon Sep 17 00:00:00 2001 From: RSMNYS Date: Tue, 28 Nov 2023 08:09:15 +0200 Subject: [PATCH 01/17] Enabled *.mlpackage models usage. (#814) * updated archive_cached_helper to make possible handle mlpackage zip archive. * updated lu script to convert mobileBert to the coreml * updated archive_cache_helper to support mlpackage loading(*.mlpackage.zip) * code cleanup for archive_cache_helper * reverted lu.py script * archive helper code clean --- .../lib/resources/archive_cache_helper.dart | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/flutter/lib/resources/archive_cache_helper.dart b/flutter/lib/resources/archive_cache_helper.dart index 7149c7627..e8c9c0ffc 100644 --- a/flutter/lib/resources/archive_cache_helper.dart +++ b/flutter/lib/resources/archive_cache_helper.dart @@ -41,14 +41,22 @@ class ArchiveCacheHelper { final archive = ZipDecoder().decodeBytes(await File(archivePath).readAsBytes()); - for (final archiveFile in archive) { - final filePath = '${result.path}/${archiveFile.name}'; - final file = await File(filePath).create(recursive: true); - - final data = archiveFile.content as List; - await file.writeAsBytes(data); + var archiveParentPath = result.path; + if (!archive.first.isFile) { + archiveParentPath = result.parent.path; } + for (int i = 0; i < archive.files.length; i++) { + final archiveFile = archive.files[i]; + final itemPath = '$archiveParentPath/${archiveFile.name}'; + if (archiveFile.isFile) { + final file = await File(itemPath).create(recursive: true); + final data = archiveFile.content as List; + await file.writeAsBytes(data); + } else if (i != 0) { + await Directory(itemPath).create(recursive: true); + } + } return result; } catch (e) { await result.delete(recursive: true); From dea1857299ce0ef9e71eb0cd72600dab5b9ac334 Mon Sep 17 00:00:00 2001 From: Anh Date: Tue, 28 Nov 2023 14:20:22 +0700 Subject: [PATCH 02/17] ui: move Privacy Policy and EULA from settings screen to app drawer (#815) Move Privacy Policy and EULA from settings screen to app drawer --- flutter/lib/app_constants.dart | 5 +++++ flutter/lib/l10n/app_en.arb | 2 +- flutter/lib/ui/home/app_drawer.dart | 20 ++++++++++++++------ flutter/lib/ui/settings/settings_screen.dart | 14 -------------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/flutter/lib/app_constants.dart b/flutter/lib/app_constants.dart index cff63e92b..f7d60138f 100644 --- a/flutter/lib/app_constants.dart +++ b/flutter/lib/app_constants.dart @@ -108,3 +108,8 @@ class BackendId { apple, ]; } + +class Url { + static const privacyPolicy = 'https://mlcommons.org/mobile_privacy'; + static const eula = 'https://mlcommons.org/mobile_eula'; +} diff --git a/flutter/lib/l10n/app_en.arb b/flutter/lib/l10n/app_en.arb index 8a2e851c3..55a6a336b 100644 --- a/flutter/lib/l10n/app_en.arb +++ b/flutter/lib/l10n/app_en.arb @@ -63,7 +63,7 @@ "settingsKeepLogsSubtitle": "Keep loadgen logs of future runs.\nThis option doesn't affect past logs.", "settingsCooldown": "Cooldown", "settingsCooldownSubtitle": "Pause minutes before running each benchmark to avoid thermal throttling.", - "settingsPrivacyPolicy": "Privacy policy", + "settingsPrivacyPolicy": "Privacy Policy", "settingsEula": "End User License Agreement", "settingsTaskConfigTitle": "Task configuration", "settingsTaskConfigInternetResource": "downloadable", diff --git a/flutter/lib/ui/home/app_drawer.dart b/flutter/lib/ui/home/app_drawer.dart index e99c26d75..2c6d51553 100644 --- a/flutter/lib/ui/home/app_drawer.dart +++ b/flutter/lib/ui/home/app_drawer.dart @@ -1,5 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/ui/config/config_screen.dart'; @@ -16,12 +19,7 @@ class AppDrawer extends StatelessWidget { final header = buildHeader(context); final menuList = buildMenuList(context); return Drawer( - // Add a ListView to the drawer. This ensures the user can scroll - // through the options in the drawer if there isn't enough vertical - // space to fit everything. - child: ListView( - // Important: Remove any padding from the ListView. - padding: EdgeInsets.zero, + child: Column( children: [header] + menuList, ), ); @@ -107,6 +105,16 @@ class AppDrawer extends StatelessWidget { )); }, ), + const Spacer(), + const Divider(), + ListTile( + title: Text(l10n.settingsPrivacyPolicy), + onTap: () => launchUrl(Uri.parse(Url.privacyPolicy)), + ), + ListTile( + title: Text(l10n.settingsEula), + onTap: () => launchUrl(Uri.parse(Url.eula)), + ), ]; } } diff --git a/flutter/lib/ui/settings/settings_screen.dart b/flutter/lib/ui/settings/settings_screen.dart index edfc9c75c..dc29b08b6 100644 --- a/flutter/lib/ui/settings/settings_screen.dart +++ b/flutter/lib/ui/settings/settings_screen.dart @@ -3,7 +3,6 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; import 'package:mlperfbench/benchmark/run_mode.dart'; import 'package:mlperfbench/benchmark/state.dart'; @@ -171,19 +170,6 @@ class _SettingsScreen extends State { const Divider(), crashlyticsSwitch, const Divider(), - ListTile( - title: Text(l10n.settingsPrivacyPolicy), - trailing: const Icon(Icons.chevron_right), - onTap: () => - launchUrl(Uri.parse('https://mlcommons.org/mobile_privacy')), - ), - ListTile( - title: Text(l10n.settingsEula), - trailing: const Icon(Icons.chevron_right), - onTap: () => - launchUrl(Uri.parse('https://mlcommons.org/mobile_eula')), - ), - const Divider(), ListTile( title: Padding( padding: const EdgeInsets.only(bottom: 5), From fda755fe5598830259ae792b219a095814afe70a Mon Sep 17 00:00:00 2001 From: Anh Date: Tue, 12 Dec 2023 13:32:22 +0700 Subject: [PATCH 03/17] ui: new resource loading screen (#823) * Pass loading progress and path to front end * Add new resource loading screen * Clean up and refactor start screen --- flutter/integration_test/utils.dart | 2 +- flutter/lib/benchmark/state.dart | 3 +- flutter/lib/l10n/app_en.arb | 2 +- flutter/lib/resources/cache_manager.dart | 13 +- flutter/lib/resources/resource_manager.dart | 20 ++- ...een.dart => benchmark_running_screen.dart} | 10 +- ...creen.dart => benchmark_start_screen.dart} | 21 +-- .../lib/ui/home/resource_loading_screen.dart | 127 ++++++++++++++++++ flutter/lib/ui/home/result_screen.dart | 7 +- flutter/lib/ui/root/main_screen.dart | 13 +- .../test/resources/cache_manager_test.dart | 2 +- 11 files changed, 174 insertions(+), 46 deletions(-) rename flutter/lib/ui/home/{progress_screen.dart => benchmark_running_screen.dart} (94%) rename flutter/lib/ui/home/{start_screen.dart => benchmark_start_screen.dart} (92%) create mode 100644 flutter/lib/ui/home/resource_loading_screen.dart diff --git a/flutter/integration_test/utils.dart b/flutter/integration_test/utils.dart index ac9704885..295cedce9 100644 --- a/flutter/integration_test/utils.dart +++ b/flutter/integration_test/utils.dart @@ -2,7 +2,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mlperfbench/ui/home/start_screen.dart'; +import 'package:mlperfbench/ui/home/benchmark_start_screen.dart'; import 'package:provider/provider.dart'; import 'package:mlperfbench/benchmark/state.dart'; diff --git a/flutter/lib/benchmark/state.dart b/flutter/lib/benchmark/state.dart index 8e39ddb7e..25628f13a 100644 --- a/flutter/lib/benchmark/state.dart +++ b/flutter/lib/benchmark/state.dart @@ -48,7 +48,8 @@ class BenchmarkState extends ChangeNotifier { bool? _doneRunning; // Only if [state] == [BenchmarkStateEnum.downloading] - String get downloadingProgress => resourceManager.progress; + String get loadingPath => resourceManager.loadingPath; + double get loadingProgress => resourceManager.loadingProgress; ExtendedResult? lastResult; diff --git a/flutter/lib/l10n/app_en.arb b/flutter/lib/l10n/app_en.arb index 55a6a336b..897df2ba3 100644 --- a/flutter/lib/l10n/app_en.arb +++ b/flutter/lib/l10n/app_en.arb @@ -21,7 +21,7 @@ "unsupportedBackendError": "Error message", "unsupportedTryAnotherDevice": "Please try the app on another device", - "mainScreenLoading": "Loading content...", + "mainScreenLoading": "Loading Content", "mainScreenGo": "GO", "mainScreenMeasureTitle": "Measure your device performance for:", "mainScreenWaitFinish": "Wait for benchmark to finish", diff --git a/flutter/lib/resources/cache_manager.dart b/flutter/lib/resources/cache_manager.dart index 2ec3c1c0d..ec8276349 100644 --- a/flutter/lib/resources/cache_manager.dart +++ b/flutter/lib/resources/cache_manager.dart @@ -81,8 +81,8 @@ class CacheManager { return deleteLoadedResources(currentResources, atLeastDaysOld); } - Future cache(List urls, void Function(double) reportProgress, - bool purgeOldCache) async { + Future cache(List urls, + void Function(double, String) reportProgress, bool purgeOldCache) async { final resourcesToDownload = []; _resourcesMap = {}; @@ -118,17 +118,18 @@ class CacheManager { } Future _download( - List urls, void Function(double) reportProgress) async { + List urls, void Function(double, String) reportProgress) async { var progress = 0.0; for (var url in urls) { + progress += 0.1 / urls.length; + reportProgress(progress, url); if (isResourceAnArchive(url)) { _resourcesMap[url] = await archiveCacheHelper.get(url, true); } else { _resourcesMap[url] = await fileCacheHelper.get(url, true); } - - progress += 1.0 / urls.length; - reportProgress(progress); + progress += 0.9 / urls.length; + reportProgress(progress, url); } } } diff --git a/flutter/lib/resources/resource_manager.dart b/flutter/lib/resources/resource_manager.dart index f7ac2591a..2ac507311 100644 --- a/flutter/lib/resources/resource_manager.dart +++ b/flutter/lib/resources/resource_manager.dart @@ -21,7 +21,8 @@ class ResourceManager { final Store store; bool _done = false; - String _progressString = '0%'; + String _loadingPath = ''; + double _loadingProgress = 0.0; late final String applicationDirectory; late final String _loadedResourcesDir; @@ -33,8 +34,12 @@ class ResourceManager { bool get done => _done; - String get progress { - return _progressString; + double get loadingProgress { + return _loadingProgress; + } + + String get loadingPath { + return _loadingPath; } String get(String uri) { @@ -87,7 +92,8 @@ class ResourceManager { Future handleResources( List resources, bool purgeOldCache) async { - _progressString = '0%'; + _loadingPath = ''; + _loadingProgress = 0.0; _done = false; _onUpdate(); @@ -102,8 +108,10 @@ class ResourceManager { } final internetPaths = internetResources.map((e) => e.path).toList(); - await cacheManager.cache(internetPaths, (double val) { - _progressString = '${(val * 100).round()}%'; + await cacheManager.cache(internetPaths, + (double currentProgress, String currentPath) { + _loadingProgress = currentProgress; + _loadingPath = currentPath; _onUpdate(); }, purgeOldCache); diff --git a/flutter/lib/ui/home/progress_screen.dart b/flutter/lib/ui/home/benchmark_running_screen.dart similarity index 94% rename from flutter/lib/ui/home/progress_screen.dart rename to flutter/lib/ui/home/benchmark_running_screen.dart index 052d4bec8..cf5e83847 100644 --- a/flutter/lib/ui/home/progress_screen.dart +++ b/flutter/lib/ui/home/benchmark_running_screen.dart @@ -10,17 +10,17 @@ import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/ui/home/progress_circles.dart'; import 'package:mlperfbench/ui/time_utils.dart'; -class ProgressScreen extends StatefulWidget { +class BenchmarkRunningScreen extends StatefulWidget { static final GlobalKey scaffoldKey = GlobalKey(); - const ProgressScreen({Key? key}) : super(key: key); + const BenchmarkRunningScreen({Key? key}) : super(key: key); @override - State createState() => _ProgressScreenState(); + State createState() => _BenchmarkRunningScreenState(); } -class _ProgressScreenState extends State { +class _BenchmarkRunningScreenState extends State { static const double progressCircleEdgeSize = 150; late final Timer _timer; @@ -172,7 +172,7 @@ class _ProgressScreenState extends State { ); return Scaffold( - key: ProgressScreen.scaffoldKey, + key: BenchmarkRunningScreen.scaffoldKey, body: Container( decoration: backgroundGradient, child: Column( diff --git a/flutter/lib/ui/home/start_screen.dart b/flutter/lib/ui/home/benchmark_start_screen.dart similarity index 92% rename from flutter/lib/ui/home/start_screen.dart rename to flutter/lib/ui/home/benchmark_start_screen.dart index fe7080795..a29daab02 100644 --- a/flutter/lib/ui/home/start_screen.dart +++ b/flutter/lib/ui/home/benchmark_start_screen.dart @@ -20,8 +20,8 @@ class MainKeys { static const String goButton = 'goButton'; } -class StartScreen extends StatelessWidget { - const StartScreen({Key? key}) : super(key: key); +class BenchmarkStartScreen extends StatelessWidget { + const BenchmarkStartScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -61,13 +61,11 @@ class StartScreen extends StatelessWidget { Widget _getContainer(BuildContext context, BenchmarkStateEnum state) { if (state == BenchmarkStateEnum.aborting) { return _waitContainer(context); - } - - if (state == BenchmarkStateEnum.waiting) { + } else if (state == BenchmarkStateEnum.waiting) { return _goContainer(context); + } else { + throw 'Unknown BenchmarkState: ${state.name}'; } - - return _downloadContainer(context); } Widget _waitContainer(BuildContext context) { @@ -128,15 +126,6 @@ class StartScreen extends StatelessWidget { }), ); } - - Widget _downloadContainer(BuildContext context) { - final stringResources = AppLocalizations.of(context); - final textLabel = Text(context.watch().downloadingProgress, - style: const TextStyle(color: AppColors.lightText, fontSize: 40)); - - return _circleContainerWithContent( - context, textLabel, stringResources.mainScreenLoading); - } } class MyPaintBottom extends CustomPainter { diff --git a/flutter/lib/ui/home/resource_loading_screen.dart b/flutter/lib/ui/home/resource_loading_screen.dart new file mode 100644 index 000000000..1f54c2c29 --- /dev/null +++ b/flutter/lib/ui/home/resource_loading_screen.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; + +import 'package:provider/provider.dart'; + +import 'package:mlperfbench/app_constants.dart'; +import 'package:mlperfbench/benchmark/state.dart'; +import 'package:mlperfbench/localizations/app_localizations.dart'; + +class ResourceLoadingScreen extends StatefulWidget { + const ResourceLoadingScreen({super.key}); + + @override + State createState() => _ResourceLoadingScreenState(); +} + +class _ResourceLoadingScreenState extends State { + static const double progressCircleEdgeSize = 150; + + @override + Widget build(BuildContext context) { + final state = context.watch(); + final l10n = AppLocalizations.of(context); + final loadingProgressText = '${(state.loadingProgress * 100).round()}%'; + + final progressCircle = Stack( + alignment: AlignmentDirectional.center, + children: [ + Center( + child: Container( + width: progressCircleEdgeSize, + height: progressCircleEdgeSize, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + colors: AppColors.progressCircleGradient, + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + offset: Offset(15, 15), + blurRadius: 10, + ) + ], + ), + child: Center( + child: Text( + loadingProgressText, + style: const TextStyle( + fontWeight: FontWeight.bold, + color: AppColors.lightText, + ), + textScaleFactor: 2, + ), + ), + ), + ), + Center( + child: Container( + width: MediaQuery.of(context).size.width * 0.35, + alignment: Alignment.center, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: AppColors.progressCircle, + boxShadow: [ + BoxShadow( + color: Colors.black12, + offset: Offset(15, 15), + blurRadius: 10, + ) + ], + ), + ), + ), + ], + ); + + final statusText = Padding( + padding: const EdgeInsets.fromLTRB(20, 40, 20, 20), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + l10n.mainScreenLoading, + style: const TextStyle( + color: AppColors.lightText, + fontSize: 16, + ), + ), + const SizedBox(height: 20), + Text( + state.loadingPath, + style: const TextStyle( + fontWeight: FontWeight.w300, + color: AppColors.lightText, + fontSize: 12, + ), + ), + ], + ), + ); + + final backgroundGradient = BoxDecoration( + gradient: LinearGradient( + colors: AppColors.progressScreenGradient, + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ); + + return Scaffold( + body: Container( + decoration: backgroundGradient, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + progressCircle, + statusText, + ], + ), + ), + ); + } +} diff --git a/flutter/lib/ui/home/result_screen.dart b/flutter/lib/ui/home/result_screen.dart index 3e588c455..396e16bc2 100644 --- a/flutter/lib/ui/home/result_screen.dart +++ b/flutter/lib/ui/home/result_screen.dart @@ -11,11 +11,11 @@ import 'package:mlperfbench/store.dart'; import 'package:mlperfbench/ui/confirm_dialog.dart'; import 'package:mlperfbench/ui/error_dialog.dart'; import 'package:mlperfbench/ui/home/app_drawer.dart'; +import 'package:mlperfbench/ui/home/benchmark_running_screen.dart'; +import 'package:mlperfbench/ui/home/benchmark_start_screen.dart'; import 'package:mlperfbench/ui/home/list_of_benchmark_items.dart'; -import 'package:mlperfbench/ui/home/progress_screen.dart'; import 'package:mlperfbench/ui/home/result_circle.dart'; import 'package:mlperfbench/ui/home/share_button.dart'; -import 'package:mlperfbench/ui/home/start_screen.dart'; import 'package:mlperfbench/ui/icons.dart' as app_icons; import 'package:mlperfbench/ui/page_constraints.dart'; @@ -376,7 +376,8 @@ class _ResultScreenState extends State print(t); // current context may no longer be valid if runBenchmarks requested progress screen await showErrorDialog( - ProgressScreen.scaffoldKey.currentContext ?? context, + BenchmarkRunningScreen.scaffoldKey.currentContext ?? + context, ['${l10n.runFail}:', e.toString()]); return; } diff --git a/flutter/lib/ui/root/main_screen.dart b/flutter/lib/ui/root/main_screen.dart index 7aeb3fc08..aa604f598 100644 --- a/flutter/lib/ui/root/main_screen.dart +++ b/flutter/lib/ui/root/main_screen.dart @@ -3,9 +3,10 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:mlperfbench/benchmark/state.dart'; -import 'package:mlperfbench/ui/home/progress_screen.dart'; +import 'package:mlperfbench/ui/home/benchmark_running_screen.dart'; +import 'package:mlperfbench/ui/home/benchmark_start_screen.dart'; +import 'package:mlperfbench/ui/home/resource_loading_screen.dart'; import 'package:mlperfbench/ui/home/result_screen.dart'; -import 'package:mlperfbench/ui/home/start_screen.dart'; import 'package:mlperfbench/ui/root/resource_error_screen.dart'; class MainScreen extends StatelessWidget { @@ -21,13 +22,13 @@ class MainScreen extends StatelessWidget { switch (state.state) { case BenchmarkStateEnum.downloading: - return const StartScreen(); + return const ResourceLoadingScreen(); case BenchmarkStateEnum.waiting: - return const StartScreen(); + return const BenchmarkStartScreen(); case BenchmarkStateEnum.aborting: - return const StartScreen(); + return const BenchmarkStartScreen(); case BenchmarkStateEnum.running: - return const ProgressScreen(); + return const BenchmarkRunningScreen(); case BenchmarkStateEnum.done: return const ResultScreen(); } diff --git a/flutter/test/resources/cache_manager_test.dart b/flutter/test/resources/cache_manager_test.dart index fdd49ef6f..6f5da8e02 100644 --- a/flutter/test/resources/cache_manager_test.dart +++ b/flutter/test/resources/cache_manager_test.dart @@ -15,7 +15,7 @@ void main() async { setUp(() async { manager = CacheManager('/tmp/resources'); - await manager.cache(paths, (val) {}, true); + await manager.cache(paths, (val, str) {}, true); }); test('get', () async { From 1f95824a30d6ad9bd0aeaed0ce6005982a643419 Mon Sep 17 00:00:00 2001 From: Anh Date: Tue, 12 Dec 2023 14:04:11 +0700 Subject: [PATCH 04/17] chore: make Firebase Crashlytics optional (#818) * Set mappingFileUploadEnabled to false by default * Add flag FIREBASE_CRASHLYTICS_ENABLED * Add flag FIREBASE_CRASHLYTICS_ENABLED for iOS build * Update docs * Add flag FIREBASE_CRASHLYTICS_ENABLED for Android build * Cleanup * Update docs * Make dart-define var name UPPER_CASE * Hide send crash log switch if FIREBASE_CRASHLYTICS_ENABLED is false * Use true/false for FIREBASE_CRASHLYTICS_ENABLED * Wrap dart-define constants in DartDefine class --- .github/cloudbuild/android-build.yaml | 2 ++ .github/workflows/app-build.yml | 1 + .github/workflows/ios-tests.yml | 1 + docs/build-and-run.md | 4 +-- docs/custom-tasks.md | 4 +-- docs/environment-setup/env-setup-firebase.md | 12 +++++++++ flutter/android/android-docker.mk | 1 + flutter/android/android.mk | 1 + flutter/android/app/build.gradle | 9 +++++++ flutter/autostart-run.sh | 2 +- flutter/flutter.mk | 13 +++++++--- flutter/ios/Runner.xcodeproj/project.pbxproj | 2 +- flutter/ios/ci_scripts/ci_post_clone.sh | 2 +- flutter/lib/app_constants.dart | 25 +++++++++++-------- flutter/lib/benchmark/benchmark.dart | 2 +- flutter/lib/build_info.dart | 4 +-- flutter/lib/resources/resource_manager.dart | 8 +++--- flutter/lib/state/task_runner.dart | 2 +- flutter/lib/ui/home/result_screen.dart | 4 ++- flutter/lib/ui/settings/data_folder_type.dart | 3 ++- flutter/lib/ui/settings/settings_screen.dart | 3 ++- .../lib/ui/settings/task_config_screen.dart | 10 ++++---- flutter/windows/windows.mk | 1 + 23 files changed, 79 insertions(+), 37 deletions(-) diff --git a/.github/cloudbuild/android-build.yaml b/.github/cloudbuild/android-build.yaml index 0387f778f..d42e89be8 100644 --- a/.github/cloudbuild/android-build.yaml +++ b/.github/cloudbuild/android-build.yaml @@ -101,6 +101,7 @@ steps: - FIREBASE_STORAGE_BUCKET=$_FIREBASE_STORAGE_BUCKET - FIREBASE_CI_USER_EMAIL=$_FIREBASE_CI_USER_EMAIL - FIREBASE_CI_USER_PASSWORD=$_FIREBASE_CI_USER_PASSWORD + - FIREBASE_CRASHLYTICS_ENABLED=true args: - -xc - | @@ -141,6 +142,7 @@ steps: - FIREBASE_STORAGE_BUCKET=$_FIREBASE_STORAGE_BUCKET - FIREBASE_CI_USER_EMAIL=$_FIREBASE_CI_USER_EMAIL - FIREBASE_CI_USER_PASSWORD=$_FIREBASE_CI_USER_PASSWORD + - FIREBASE_CRASHLYTICS_ENABLED=true args: - -xc - | diff --git a/.github/workflows/app-build.yml b/.github/workflows/app-build.yml index 23bd28b00..4a374632f 100644 --- a/.github/workflows/app-build.yml +++ b/.github/workflows/app-build.yml @@ -103,6 +103,7 @@ jobs: FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.FIREBASE_MESSAGING_SENDER_ID }} FIREBASE_DATABASE_URL: ${{ secrets.FIREBASE_DATABASE_URL }} FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} + FIREBASE_CRASHLYTICS_ENABLED: true OFFICIAL_BUILD: true FLUTTER_BUILD_NUMBER: ${{ github.run_number }} WITH_TFLITE: 1 diff --git a/.github/workflows/ios-tests.yml b/.github/workflows/ios-tests.yml index 2c34df63e..a93796c6d 100644 --- a/.github/workflows/ios-tests.yml +++ b/.github/workflows/ios-tests.yml @@ -31,6 +31,7 @@ jobs: FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} FIREBASE_CI_USER_EMAIL: ${{ secrets.FIREBASE_CI_USER_EMAIL }} FIREBASE_CI_USER_PASSWORD: ${{ secrets.FIREBASE_CI_USER_PASSWORD }} + FIREBASE_CRASHLYTICS_ENABLED: true steps: - name: Checkout uses: actions/checkout@v3 diff --git a/docs/build-and-run.md b/docs/build-and-run.md index 061d40fbb..e6b7bad0d 100644 --- a/docs/build-and-run.md +++ b/docs/build-and-run.md @@ -43,7 +43,7 @@ If you want to run or debug the Flutter app for any platform using graphical use you can use [VS Code with Flutter extension](https://docs.flutter.dev/get-started/editor?tab=vscode). If you want to test something without spending a lot of time on the benchmark, -you can use flag `--dart-define=fast-mode=true` to speed up the benchmark. +you can use flag `--dart-define=FAST_MODE=true` to speed up the benchmark. You should not evaluate performance when using this flag. Add `WITH_=1` to make commands to build the the app with backends. @@ -59,7 +59,7 @@ The app is built with an unofficial UI (different color and text) by default. To build with an official UI, you need to set * the environment variable `OFFICIAL_BUILD=true` if `make` is used (e.g. `OFFICIAL_BUILD=true make flutter/android/apk`), or -* the argument `--dart-define=official-build=true` if `flutter` is used (e.g. `flutter build apk --dart-define=official-build=true`). +* the argument `--dart-define=OFFICIAL_BUILD=true` if `flutter` is used (e.g. `flutter build apk --dart-define=OFFICIAL_BUILD=true`). When making a release build you must specify `OFFICIAL_BUILD` and `FLUTTER_BUILD_NUMBER` environment variables, otherwise the build will fail. This is a requirement for `flutter/android/release`, `docker/flutter/android/release`, `flutter/ios/release` make targets. diff --git a/docs/custom-tasks.md b/docs/custom-tasks.md index 9ec1b1fa8..6e7a0b8f8 100644 --- a/docs/custom-tasks.md +++ b/docs/custom-tasks.md @@ -59,13 +59,13 @@ Absolute path is only available for the task config path. All local resources in You can change the data folder without using graphical interface. -Use `--dart-define=default-data-folder=` to specify the folder you want to use. +Use `--dart-define=FLUTTER_DATA_FOLDER=` to specify the folder you want to use. It will still be possible to choose a different folder via UI but the app will use specified folder by default. If you build the app using makefile commands, use `FLUTTER_DATA_FOLDER` environment variable. For example: `make flutter/test/integration FLUTTER_CACHE_FOLDER=/my/folder/path` You can also override app cache folder. -Use `--dart-define=default-cache-folder=` for manual build or `FLUTTER_CACHE_FOLDER` env for makefile script. +Use `--dart-define=FLUTTER_CACHE_FOLDER=` for manual build or `FLUTTER_CACHE_FOLDER` env for makefile script. Note that it's impossible to change the cache folder from the UI. These options are intended for CI use, and possibly for internal testing. diff --git a/docs/environment-setup/env-setup-firebase.md b/docs/environment-setup/env-setup-firebase.md index 788cf6a5b..3ddca469f 100644 --- a/docs/environment-setup/env-setup-firebase.md +++ b/docs/environment-setup/env-setup-firebase.md @@ -28,4 +28,16 @@ FIREBASE_DATABASE_URL=foo FIREBASE_STORAGE_BUCKET=foo ``` +**Note about Firebase Crashlytics**: + +By default, we disable the upload of mapping file (in Android build) or debug symbol (dSYM) file in iOS build +as described +in [Get readable crash reports in the Crashlytics dashboard](https://firebase.google.com/docs/crashlytics/get-deobfuscated-reports?platform=flutter). + +To enable it, you need to set the environment variable: + +```shell +export FIREBASE_CRASHLYTICS_ENABLED=true +``` + That's it! You can now run the app with your own Firebase project. diff --git a/flutter/android/android-docker.mk b/flutter/android/android-docker.mk index e4ec041e8..61a9c8ae3 100644 --- a/flutter/android/android-docker.mk +++ b/flutter/android/android-docker.mk @@ -43,6 +43,7 @@ flutter_common_docker_flags= \ --env WITH_MEDIATEK=${WITH_MEDIATEK} \ --env proxy_bazel_args=${proxy_bazel_args} \ --env OFFICIAL_BUILD=${OFFICIAL_BUILD} \ + --env FIREBASE_CRASHLYTICS_ENABLED=${FIREBASE_CRASHLYTICS_ENABLED} \ --env FLUTTER_BUILD_NUMBER=${FLUTTER_BUILD_NUMBER} \ --env FLUTTER_FORCE_PUB_GET=1 \ --env FLUTTER_DATA_FOLDER=${FLUTTER_DATA_FOLDER} \ diff --git a/flutter/android/android.mk b/flutter/android/android.mk index 74f171010..65c3084a4 100644 --- a/flutter/android/android.mk +++ b/flutter/android/android.mk @@ -73,6 +73,7 @@ flutter/android/apk: mkdir -p $$(dirname ${flutter_android_apk_release_path}) cd flutter && ${_start_args} flutter --no-version-check build apk \ ${flutter_official_build_arg} \ + ${flutter_firebase_crashlytics_arg} \ ${flutter_build_number_arg} \ ${flutter_folder_args} cp -f flutter/build/app/outputs/flutter-apk/app-release.apk ${flutter_android_apk_release_path} diff --git a/flutter/android/app/build.gradle b/flutter/android/app/build.gradle index 58219a995..d57733e54 100644 --- a/flutter/android/app/build.gradle +++ b/flutter/android/app/build.gradle @@ -59,6 +59,15 @@ android { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug + + // By default we do not upload mapping file to Firebase + firebaseCrashlytics { + if (System.env['FIREBASE_CRASHLYTICS_ENABLED'] == 'true') { + mappingFileUploadEnabled true + } else { + mappingFileUploadEnabled false + } + } } } } diff --git a/flutter/autostart-run.sh b/flutter/autostart-run.sh index 286c9f4d5..92295b7d3 100644 --- a/flutter/autostart-run.sh +++ b/flutter/autostart-run.sh @@ -58,7 +58,7 @@ mkdir -p "$OUTPUT_LOG_PATH" echo "building and running the app... (this will take a while, see log file for intermediate results)" flutter run \ --dart-define=autostart=true \ - --dart-define=official-build=$official_build \ + --dart-define=OFFICIAL_BUILD=$official_build \ --dart-define=submission=$submission_mode \ --dart-define=resultsStringMark=resultsStringMark \ --dart-define=terminalStringMark=terminalStringMark \ diff --git a/flutter/flutter.mk b/flutter/flutter.mk index e143b2e1c..4c69aed02 100644 --- a/flutter/flutter.mk +++ b/flutter/flutter.mk @@ -35,7 +35,7 @@ flutter/check-release-env: flutter/check/official-build flutter/check/build-numb flutter/test: flutter/test/unit flutter/test/integration OFFICIAL_BUILD?=false -flutter_official_build_arg=--dart-define=official-build=${OFFICIAL_BUILD} +flutter_official_build_arg=--dart-define=OFFICIAL_BUILD=${OFFICIAL_BUILD} .PHONY: flutter/check/official-build flutter/check/official-build: @[ "$$OFFICIAL_BUILD" = "true" ] || [ "$$OFFICIAL_BUILD" = "false" ] \ @@ -52,17 +52,20 @@ flutter/check/build-number: || (echo FLUTTER_BUILD_NUMBER env must be explicitly set; exit 1) ifneq (${FLUTTER_DATA_FOLDER},) -flutter_data_folder_arg="--dart-define=default-data-folder=${FLUTTER_DATA_FOLDER}" +flutter_data_folder_arg="--dart-define=FLUTTER_DATA_FOLDER=${FLUTTER_DATA_FOLDER}" else flutter_data_folder_arg= endif ifneq (${FLUTTER_CACHE_FOLDER},) -flutter_cache_folder_arg="--dart-define=default-cache-folder=${FLUTTER_CACHE_FOLDER}" +flutter_cache_folder_arg="--dart-define=FLUTTER_CACHE_FOLDER=${FLUTTER_CACHE_FOLDER}" else flutter_cache_folder_arg= endif flutter_folder_args=${flutter_data_folder_arg} ${flutter_cache_folder_arg} +FIREBASE_CRASHLYTICS_ENABLED?=false +flutter_firebase_crashlytics_arg="--dart-define=FIREBASE_CRASHLYTICS_ENABLED=${FIREBASE_CRASHLYTICS_ENABLED}" + FIREBASE_ENV_FILE?=flutter/lib/firebase/firebase_options.env -include ${FIREBASE_ENV_FILE} export @@ -181,6 +184,7 @@ flutter/test/integration: integration_test/first_test.dart \ ${flutter_test_device_arg} \ ${flutter_official_build_arg} \ + ${flutter_firebase_crashlytics_arg} \ ${flutter_perf_test_arg} \ ${flutter_folder_args} @@ -191,7 +195,8 @@ flutter/run: run \ ${flutter_folder_args} \ ${flutter_test_device_arg} \ - ${flutter_official_build_arg} + ${flutter_official_build_arg} \ + ${flutter_firebase_crashlytics_arg} .PHONY: flutter/clean flutter/clean: diff --git a/flutter/ios/Runner.xcodeproj/project.pbxproj b/flutter/ios/Runner.xcodeproj/project.pbxproj index c02037e32..01693d78e 100644 --- a/flutter/ios/Runner.xcodeproj/project.pbxproj +++ b/flutter/ios/Runner.xcodeproj/project.pbxproj @@ -379,7 +379,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Upload dSYM files\n\"${PODS_ROOT}/FirebaseCrashlytics/run\" \\\n -gsp \"${PROJECT_DIR}/Runner/GoogleService-Info.plist\" \\\n -p ios \\\n \"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}\"\n"; + shellScript = "# By default we do not upload debug symbol (dSYM file) to Firebase\nif [ \"${FIREBASE_CRASHLYTICS_ENABLED}\" = \"true\" ]; then\n \"${PODS_ROOT}/FirebaseCrashlytics/run\" \\\n -gsp \"${PROJECT_DIR}/Runner/GoogleService-Info.plist\" \\\n -p ios \\\n \"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}\"\nfi\n"; }; D5A11810053EEA7778D10F3D /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; diff --git a/flutter/ios/ci_scripts/ci_post_clone.sh b/flutter/ios/ci_scripts/ci_post_clone.sh index 4e45ca96e..3c791a712 100755 --- a/flutter/ios/ci_scripts/ci_post_clone.sh +++ b/flutter/ios/ci_scripts/ci_post_clone.sh @@ -101,7 +101,7 @@ if [ $runner = $XCODE_CLOUD ]; then if [ "$CI_XCODEBUILD_ACTION" = "build-for-testing" ]; then cd "$MC_REPO_HOME"/flutter && flutter build ios --config-only integration_test/first_test.dart else - cd "$MC_REPO_HOME"/flutter && flutter build ios --config-only --dart-define=official-build="$OFFICIAL_BUILD" --build-number "$CI_BUILD_NUMBER" + cd "$MC_REPO_HOME"/flutter && flutter build ios --config-only --dart-define=OFFICIAL_BUILD="$OFFICIAL_BUILD" --build-number "$CI_BUILD_NUMBER" fi fi diff --git a/flutter/lib/app_constants.dart b/flutter/lib/app_constants.dart index f7d60138f..e8defae41 100644 --- a/flutter/lib/app_constants.dart +++ b/flutter/lib/app_constants.dart @@ -1,12 +1,17 @@ import 'package:flutter/material.dart'; -const isOfficialBuild = - bool.fromEnvironment('official-build', defaultValue: false); - -const isFastMode = bool.fromEnvironment('fast-mode', defaultValue: false); - -const defaultCacheFolder = String.fromEnvironment('default-cache-folder'); -const defaultDataFolder = String.fromEnvironment('default-data-folder'); +class DartDefine { + static const isOfficialBuild = + bool.fromEnvironment('OFFICIAL_BUILD', defaultValue: false); + static const firebaseCrashlyticsEnabled = + bool.fromEnvironment('FIREBASE_CRASHLYTICS_ENABLED', defaultValue: false); + static const isFastMode = + bool.fromEnvironment('FAST_MODE', defaultValue: false); + static const defaultCacheFolder = + String.fromEnvironment('FLUTTER_CACHE_FOLDER'); + static const defaultDataFolder = + String.fromEnvironment('FLUTTER_DATA_FOLDER'); +} class AppColors { static const lightText = Colors.white; @@ -17,11 +22,11 @@ class AppColors { static const dialogBackground = Colors.white; static const snackBarBackground = Color(0xFFEDEDED); static const appBarBackground = - isOfficialBuild ? Color(0xFF31A3E2) : Colors.brown; + DartDefine.isOfficialBuild ? Color(0xFF31A3E2) : Colors.brown; static const appBarIcon = Colors.white; - static List get mainScreenGradient => isOfficialBuild + static List get mainScreenGradient => DartDefine.isOfficialBuild ? [ const Color(0xFF31A3E2), const Color(0xFF31A3E2), @@ -44,7 +49,7 @@ class AppColors { const Color(0xFF0DB526), // 0DB526 ]; - static List get progressScreenGradient => isOfficialBuild + static List get progressScreenGradient => DartDefine.isOfficialBuild ? [const Color(0xff3189E2), const Color(0xff0B4A7F)] : [Colors.brown.shade400, Colors.brown]; diff --git a/flutter/lib/benchmark/benchmark.dart b/flutter/lib/benchmark/benchmark.dart index 8a1e42252..4efa484d4 100644 --- a/flutter/lib/benchmark/benchmark.dart +++ b/flutter/lib/benchmark/benchmark.dart @@ -77,7 +77,7 @@ class Benchmark { if (testMinDuration != 0) { minQueryCount = testMinQueryCount; minDuration = testMinDuration.toDouble(); - } else if (isFastMode) { + } else if (DartDefine.isFastMode) { minQueryCount = 8; minDuration = 1.0; } else { diff --git a/flutter/lib/build_info.dart b/flutter/lib/build_info.dart index b919587fb..eb4f06679 100644 --- a/flutter/lib/build_info.dart +++ b/flutter/lib/build_info.dart @@ -21,8 +21,8 @@ class BuildInfoHelper { version: packageInfo.version, buildNumber: packageInfo.buildNumber, buildDate: DateTime.now(), - officialReleaseFlag: isOfficialBuild, - devTestFlag: isFastMode, + officialReleaseFlag: DartDefine.isOfficialBuild, + devTestFlag: DartDefine.isFastMode, backendList: BackendInfoHelper().getBackendsList(), gitBranch: GeneratedBuildInfo.gitBranch, gitCommit: GeneratedBuildInfo.gitCommit, diff --git a/flutter/lib/resources/resource_manager.dart b/flutter/lib/resources/resource_manager.dart index 2ac507311..15858131d 100644 --- a/flutter/lib/resources/resource_manager.dart +++ b/flutter/lib/resources/resource_manager.dart @@ -62,8 +62,8 @@ class ResourceManager { String getDataFolder() { switch (parseDataFolderType(store.dataFolderType)) { case DataFolderType.default_: - if (defaultDataFolder.isNotEmpty) { - return defaultDataFolder; + if (DartDefine.defaultDataFolder.isNotEmpty) { + return DartDefine.defaultDataFolder; } else { return applicationDirectory; } @@ -152,8 +152,8 @@ class ResourceManager { Future initSystemPaths() async { applicationDirectory = await getApplicationDirectory(); await Directory(applicationDirectory).create(recursive: true); - if (defaultCacheFolder.isNotEmpty) { - _loadedResourcesDir = defaultCacheFolder; + if (DartDefine.defaultCacheFolder.isNotEmpty) { + _loadedResourcesDir = DartDefine.defaultCacheFolder; } else { _loadedResourcesDir = '$applicationDirectory/$_loadedResourcesDirName'; } diff --git a/flutter/lib/state/task_runner.dart b/flutter/lib/state/task_runner.dart index 5460b7d51..fa9f1306a 100644 --- a/flutter/lib/state/task_runner.dart +++ b/flutter/lib/state/task_runner.dart @@ -94,7 +94,7 @@ class TaskRunner { late final Duration cooldownDuration; if (store.testMode) { cooldownDuration = Duration(seconds: store.testCooldown); - } else if (isFastMode) { + } else if (DartDefine.isFastMode) { cooldownDuration = const Duration(seconds: 1); } else { cooldownDuration = Duration(minutes: store.cooldownDuration); diff --git a/flutter/lib/ui/home/result_screen.dart b/flutter/lib/ui/home/result_screen.dart index 396e16bc2..a013a6e52 100644 --- a/flutter/lib/ui/home/result_screen.dart +++ b/flutter/lib/ui/home/result_screen.dart @@ -404,7 +404,9 @@ class _ResultScreenState extends State title = _screenMode == _ScreenMode.performance ? l10n.resultsTitlePerformance : l10n.resultsTitleAccuracy; - title = isOfficialBuild ? title : '${l10n.resultsTitleUnverified} $title'; + title = DartDefine.isOfficialBuild + ? title + : '${l10n.resultsTitleUnverified} $title'; return Scaffold( appBar: AppBar(title: Text(title)), diff --git a/flutter/lib/ui/settings/data_folder_type.dart b/flutter/lib/ui/settings/data_folder_type.dart index 2a8e0b597..f0f57c8a0 100644 --- a/flutter/lib/ui/settings/data_folder_type.dart +++ b/flutter/lib/ui/settings/data_folder_type.dart @@ -3,7 +3,8 @@ import 'package:mlperfbench/app_constants.dart'; enum DataFolderType { default_, appFolder, custom } DataFolderType parseDataFolderType(String value) { - if (value == DataFolderType.appFolder.name && defaultDataFolder.isNotEmpty) { + if (value == DataFolderType.appFolder.name && + DartDefine.defaultDataFolder.isNotEmpty) { // if defaultDataFolder is empty then default_ and appFolder value means the same, // so it doesn't make sense to have them as separate values return DataFolderType.appFolder; diff --git a/flutter/lib/ui/settings/settings_screen.dart b/flutter/lib/ui/settings/settings_screen.dart index dc29b08b6..7a7915d00 100644 --- a/flutter/lib/ui/settings/settings_screen.dart +++ b/flutter/lib/ui/settings/settings_screen.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/run_mode.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/build_info.dart'; @@ -70,7 +71,7 @@ class _SettingsScreen extends State { } Widget crashlyticsSwitch; - if (FirebaseManager.enabled) { + if (FirebaseManager.enabled && DartDefine.firebaseCrashlyticsEnabled) { crashlyticsSwitch = ListTile( title: Padding( padding: const EdgeInsets.only(bottom: 5), diff --git a/flutter/lib/ui/settings/task_config_screen.dart b/flutter/lib/ui/settings/task_config_screen.dart index b6167d551..06b4ba2a8 100644 --- a/flutter/lib/ui/settings/task_config_screen.dart +++ b/flutter/lib/ui/settings/task_config_screen.dart @@ -40,7 +40,7 @@ class _DataFolderSelectorHelper { items.add(dataFolderTitle); items.add(_makeDefaultOption()); - if (defaultDataFolder.isNotEmpty) { + if (DartDefine.defaultDataFolder.isNotEmpty) { items.add(_makeAppFolderOption()); } items.add(_makeCustomOption()); @@ -58,10 +58,10 @@ class _DataFolderSelectorHelper { Widget _makeDefaultOption() { late final String defaultOptionSubtitle; - if (defaultDataFolder.isEmpty) { + if (DartDefine.defaultDataFolder.isEmpty) { defaultOptionSubtitle = l10n.settingsTaskDataFolderApp; } else { - defaultOptionSubtitle = defaultDataFolder; + defaultOptionSubtitle = DartDefine.defaultDataFolder; } return ListTile( title: Text(l10n.settingsTaskDataFolderDefault), @@ -201,7 +201,7 @@ class TaskConfigScreen extends StatelessWidget { } Widget _makeCacheFolderNotice(AppLocalizations l10n) { - if (defaultCacheFolder.isEmpty) { + if (DartDefine.defaultCacheFolder.isEmpty) { return const SizedBox.shrink(); } return Column( @@ -218,7 +218,7 @@ class TaskConfigScreen extends StatelessWidget { ListTile( enabled: false, title: Text(l10n.settingsTaskCacheFolderDefault), - subtitle: const Text(defaultCacheFolder), + subtitle: const Text(DartDefine.defaultCacheFolder), leading: const Radio( value: true, groupValue: true, diff --git a/flutter/windows/windows.mk b/flutter/windows/windows.mk index 2764f34b3..2072fb2f8 100644 --- a/flutter/windows/windows.mk +++ b/flutter/windows/windows.mk @@ -65,6 +65,7 @@ flutter/windows/release/build: rm -rf flutter/build/windows/runner/Release cd flutter && ${_start_args} flutter --no-version-check build windows --no-pub \ ${flutter_official_build_arg} \ + ${flutter_firebase_crashlytics_arg} \ ${flutter_build_number_arg} \ ${flutter_folder_args} From 046d4877d483eb5dd6a1a9f519e7c7a78973a0b9 Mon Sep 17 00:00:00 2001 From: AhmedTElthakeb <38337765+AhmedTElthakeb@users.noreply.github.com> Date: Mon, 18 Dec 2023 22:03:58 -0800 Subject: [PATCH 05/17] minor config update for Samsung backend (#816) minor config update --- .../samsung/lib/public/include/mbe_config_2400.pbtxt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mobile_back_samsung/samsung/lib/public/include/mbe_config_2400.pbtxt b/mobile_back_samsung/samsung/lib/public/include/mbe_config_2400.pbtxt index 1e992a134..8a004fc88 100644 --- a/mobile_back_samsung/samsung/lib/public/include/mbe_config_2400.pbtxt +++ b/mobile_back_samsung/samsung/lib/public/include/mbe_config_2400.pbtxt @@ -121,7 +121,7 @@ benchmark_setting { accelerator_desc: "NPU" custom_setting { id: "preset" - value: "1005" + value: "100005" } custom_setting { id: "i_type" From f1c3a14f704e5229debd22b7bcebe1d2909973e8 Mon Sep 17 00:00:00 2001 From: Anh Date: Tue, 19 Dec 2023 13:19:47 +0700 Subject: [PATCH 06/17] chore: increase app version to 4.0.0 (#825) Change app version to 4.0 --- flutter/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 4e7c9383f..c23650174 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -7,7 +7,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # version format: +. # Note: build_number will be set by CI using the CLI option --build-number -version: 3.1.1+1 +version: 4.0.0+1 environment: sdk: ">=2.18.0 <3.0.0" From 2269e32d9b60d2f5c17045afb1c0972dbf2df65d Mon Sep 17 00:00:00 2001 From: Anh Date: Tue, 19 Dec 2023 13:20:30 +0700 Subject: [PATCH 07/17] ui: new benchmark start screen (#826) * Integrate BenchmarkConfigScreen into BenchmarkStartScreen * Add BenchmarkInfoButton * Show selected benchmark count * Rename ResultScreen to BenchmarkResultScreen * Fix logic of test again button * Disable config screen in aborting state * Integrate flutter_common into flutter directory * Rename directory test to unit_test * Remove deprecated splash screen --- docs/result-spec.md | 2 +- .../android/app/src/main/AndroidManifest.xml | 7 - flutter/flutter.mk | 17 +- .../integration_test/expected_throughput.dart | 4 +- flutter/integration_test/first_test.dart | 6 +- flutter/integration_test/utils.dart | 4 +- flutter/ios/Podfile.lock | 2 +- flutter/lib/app_constants.dart | 1 + flutter/lib/backend/bridge/ffi_run.dart | 2 +- flutter/lib/backend/bridge/run_result.dart | 2 +- flutter/lib/backend/list.dart | 3 +- flutter/lib/benchmark/benchmark.dart | 2 +- flutter/lib/benchmark/run_info.dart | 3 +- flutter/lib/benchmark/state.dart | 8 +- flutter/lib/build_info.dart | 2 +- .../lib/data/benchmarks_data_provider.dart | 8 +- .../lib/data/build_info/build_info.dart | 0 .../lib/data/environment/env_android.dart | 0 .../lib/data/environment/env_ios.dart | 0 .../lib/data/environment/env_windows.dart | 0 .../data/environment/environment_info.dart | 6 +- .../lib/data/extended_result.dart | 8 +- .../edit_json_schema.main.dart | 0 .../generation_helpers/sample_generator.dart | 24 +- .../write_json_sample.main.dart | 4 +- .../lib/data/meta_info.dart | 0 .../lib/data/result_filter.dart | 8 +- .../lib/data/result_sort.dart | 2 +- .../lib/data/results/backend_info.dart | 0 .../lib/data/results/backend_settings.dart | 4 +- .../data/results/backend_settings_extra.dart | 0 .../lib/data/results/benchmark_result.dart | 6 +- .../lib/data/results/dataset_info.dart | 0 .../lib/data/string_constants.dart | 0 flutter/lib/device_info.dart | 8 +- flutter/lib/firebase/firebase_manager.dart | 2 +- flutter/lib/l10n/app_en.arb | 2 +- .../lib/resources/export_result_helper.dart | 11 +- flutter/lib/resources/result_manager.dart | 8 +- flutter/lib/state/task_runner.dart | 6 +- .../lib/ui/history/result_details_screen.dart | 4 +- .../lib/ui/history/result_filter_screen.dart | 4 +- flutter/lib/ui/history/result_list_item.dart | 5 +- .../lib/ui/history/result_list_screen.dart | 6 +- .../lib/ui/history/run_details_screen.dart | 5 +- flutter/lib/ui/history/utils.dart | 4 +- flutter/lib/ui/home/app_drawer.dart | 14 - .../benchmark_config_screen.dart} | 59 +- .../lib/ui/home/benchmark_info_button.dart | 83 +++ ...reen.dart => benchmark_result_screen.dart} | 43 +- .../lib/ui/home/benchmark_start_screen.dart | 50 +- .../lib/ui/home/list_of_benchmark_items.dart | 104 --- flutter/lib/ui/root/main_screen.dart | 4 +- flutter/pubspec.lock | 323 ++++++++- flutter/pubspec.yaml | 13 +- .../backend/loadgen_info_test.dart | 0 .../benchmark/benchmark_store_test.dart | 0 .../data/benchmark_result_test.dart | 2 +- .../data/extended_result_unittest.json | 0 .../unit_test}/data/result_filter_test.dart | 10 +- .../unit_test}/data/result_sort_test.dart | 6 +- .../unit_test}/data/serialization_test.dart | 6 +- .../resources/cache_manager_test.dart | 0 flutter_common/.gitignore | 75 --- flutter_common/.metadata | 10 - flutter_common/README.md | 3 - flutter_common/analysis_options.yaml | 15 - flutter_common/pubspec.lock | 637 ------------------ flutter_common/pubspec.yaml | 33 - tools/formatter/format.mk | 9 +- 70 files changed, 585 insertions(+), 1114 deletions(-) rename {flutter_common => flutter}/lib/data/benchmarks_data_provider.dart (63%) rename {flutter_common => flutter}/lib/data/build_info/build_info.dart (100%) rename {flutter_common => flutter}/lib/data/environment/env_android.dart (100%) rename {flutter_common => flutter}/lib/data/environment/env_ios.dart (100%) rename {flutter_common => flutter}/lib/data/environment/env_windows.dart (100%) rename {flutter_common => flutter}/lib/data/environment/environment_info.dart (88%) rename {flutter_common => flutter}/lib/data/extended_result.dart (69%) rename {flutter_common => flutter}/lib/data/generation_helpers/edit_json_schema.main.dart (100%) rename {flutter_common => flutter}/lib/data/generation_helpers/sample_generator.dart (81%) rename {flutter_common => flutter}/lib/data/generation_helpers/write_json_sample.main.dart (86%) rename {flutter_common => flutter}/lib/data/meta_info.dart (100%) rename {flutter_common => flutter}/lib/data/result_filter.dart (92%) rename {flutter_common => flutter}/lib/data/result_sort.dart (95%) rename {flutter_common => flutter}/lib/data/results/backend_info.dart (100%) rename {flutter_common => flutter}/lib/data/results/backend_settings.dart (86%) rename {flutter_common => flutter}/lib/data/results/backend_settings_extra.dart (100%) rename {flutter_common => flutter}/lib/data/results/benchmark_result.dart (95%) rename {flutter_common => flutter}/lib/data/results/dataset_info.dart (100%) rename flutter_common/lib/constants.dart => flutter/lib/data/string_constants.dart (100%) rename flutter/lib/ui/{config/config_screen.dart => home/benchmark_config_screen.dart} (63%) create mode 100644 flutter/lib/ui/home/benchmark_info_button.dart rename flutter/lib/ui/home/{result_screen.dart => benchmark_result_screen.dart} (89%) delete mode 100644 flutter/lib/ui/home/list_of_benchmark_items.dart rename flutter/{test => unit_test}/backend/loadgen_info_test.dart (100%) rename flutter/{test => unit_test}/benchmark/benchmark_store_test.dart (100%) rename {flutter_common/test => flutter/unit_test}/data/benchmark_result_test.dart (95%) rename {flutter_common/test => flutter/unit_test}/data/extended_result_unittest.json (100%) rename {flutter_common/test => flutter/unit_test}/data/result_filter_test.dart (92%) rename {flutter_common/test => flutter/unit_test}/data/result_sort_test.dart (92%) rename {flutter_common/test => flutter/unit_test}/data/serialization_test.dart (87%) rename flutter/{test => unit_test}/resources/cache_manager_test.dart (100%) delete mode 100644 flutter_common/.gitignore delete mode 100644 flutter_common/.metadata delete mode 100644 flutter_common/README.md delete mode 100644 flutter_common/analysis_options.yaml delete mode 100644 flutter_common/pubspec.lock delete mode 100644 flutter_common/pubspec.yaml diff --git a/docs/result-spec.md b/docs/result-spec.md index b653df8b1..e1a1bfa84 100644 --- a/docs/result-spec.md +++ b/docs/result-spec.md @@ -5,7 +5,7 @@ This file explains the full format for results generated by this app. This format is used when saving results locally on device, when uploading them to the online database, and when fetching them from the online database. -Here is an example result file: [extended_result_unittest.json](../flutter_common/test/data/extended_result_unittest.json) +Here is an example result file: [extended_result_unittest.json](../flutter/unit_test/data/extended_result_unittest.json) ## General structure diff --git a/flutter/android/app/src/main/AndroidManifest.xml b/flutter/android/app/src/main/AndroidManifest.xml index c1aea4a16..1070ef98e 100644 --- a/flutter/android/app/src/main/AndroidManifest.xml +++ b/flutter/android/app/src/main/AndroidManifest.xml @@ -54,13 +54,6 @@ to determine the Window background behind the Flutter UI. --> - - diff --git a/flutter/flutter.mk b/flutter/flutter.mk index 4c69aed02..8001193fd 100644 --- a/flutter/flutter.mk +++ b/flutter/flutter.mk @@ -93,7 +93,7 @@ flutter/backend-list: RESULT_JSON_SAMPLE_PATH?=output/extended_result_example.json .PHONY: flutter/result/gen-extended-sample flutter/result/gen-extended-sample: - cd flutter_common && \ + cd flutter && \ ${_start_args} dart run \ --define=jsonFileName=../${RESULT_JSON_SAMPLE_PATH} \ lib/data/generation_helpers/write_json_sample.main.dart @@ -105,14 +105,17 @@ flutter/result/gen-schema: flutter/result/gen-extended-sample quicktype ${RESULT_JSON_SAMPLE_PATH} \ --lang schema \ --out ${RESULT_JSON_SCHEMA_PATH} - cd flutter_common && \ + cd flutter && \ ${_start_args} dart run \ --define=schemaPath=../${RESULT_JSON_SCHEMA_PATH} \ lib/data/generation_helpers/edit_json_schema.main.dart .PHONY: flutter/result/json flutter/result/json: - cd flutter_common && ${_start_args} flutter --no-version-check pub run \ + @echo "Generate .g.dart files for the @JsonSerializable annotation" + @# https://github.com/dart-lang/build/issues/2835#issuecomment-1047849076 + cd flutter && ${_start_args} flutter packages pub get + cd flutter && ${_start_args} flutter --no-version-check pub run \ build_runner build --delete-conflicting-outputs .PHONY: flutter/build-info @@ -157,9 +160,7 @@ flutter/set-windows-build-number: .PHONY: flutter/pub flutter/pub: [ -z "${FLUTTER_FORCE_PUB_GET}" ] || rm -rf output/flutter/pub - make \ - output/flutter/pub/flutter.stamp \ - output/flutter/pub/flutter_common.stamp + make output/flutter/pub/flutter.stamp [ -z "${FLUTTER_FORCE_PUB_GET}" ] || rm -rf output/flutter/pub output/flutter/pub/%.stamp: %/pubspec.yaml cd $(shell basename $@ .stamp) && ${_start_args} flutter --no-version-check pub get @@ -168,8 +169,7 @@ output/flutter/pub/%.stamp: %/pubspec.yaml .PHONY: flutter/test/unit flutter/test/unit: - cd flutter && ${_start_args} flutter --no-version-check test --no-pub test -r expanded - cd flutter_common && ${_start_args} flutter --no-version-check test --no-pub test -r expanded + cd flutter && ${_start_args} flutter --no-version-check test --no-pub unit_test/* -r expanded ifneq (${FLUTTER_TEST_DEVICE},) flutter_test_device_arg=--device-id "${FLUTTER_TEST_DEVICE}" @@ -201,6 +201,5 @@ flutter/run: .PHONY: flutter/clean flutter/clean: cd flutter && ${_start_args} flutter --no-version-check clean - cd flutter_common && ${_start_args} flutter --no-version-check clean rm -rf output/flutter/pub diff --git a/flutter/integration_test/expected_throughput.dart b/flutter/integration_test/expected_throughput.dart index 0c943e5f4..e36c88ba7 100644 --- a/flutter/integration_test/expected_throughput.dart +++ b/flutter/integration_test/expected_throughput.dart @@ -52,7 +52,7 @@ const Map> _objectDetection = { _kIphoneOnMacbookM1: Interval(min: 9, max: 16), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 1.5, max: 4), + _kIphoneOnGitHubAction: Interval(min: 1.0, max: 4), }, _kPixelBackend: { _kPixel6: Interval(min: 300, max: 490), @@ -104,7 +104,7 @@ const Map> _imageClassificationOffline = { _kIphoneOnMacbookM1: Interval(min: 30, max: 45), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 3, max: 15), + _kIphoneOnGitHubAction: Interval(min: 3, max: 20), }, _kPixelBackend: { _kPixel6: Interval(min: 1000, max: 1700), diff --git a/flutter/integration_test/first_test.dart b/flutter/integration_test/first_test.dart index afa115e8e..920ebe1ae 100644 --- a/flutter/integration_test/first_test.dart +++ b/flutter/integration_test/first_test.dart @@ -3,9 +3,9 @@ import 'package:integration_test/integration_test.dart'; import 'package:mlperfbench/benchmark/run_mode.dart'; import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/store.dart'; -import 'package:mlperfbench_common/data/environment/environment_info.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/environment/environment_info.dart'; +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'expected_accuracy.dart'; diff --git a/flutter/integration_test/utils.dart b/flutter/integration_test/utils.dart index 295cedce9..e08c2d0ab 100644 --- a/flutter/integration_test/utils.dart +++ b/flutter/integration_test/utils.dart @@ -6,8 +6,8 @@ import 'package:mlperfbench/ui/home/benchmark_start_screen.dart'; import 'package:provider/provider.dart'; import 'package:mlperfbench/benchmark/state.dart'; -import 'package:mlperfbench/ui/home/result_screen.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; +import 'package:mlperfbench/ui/home/benchmark_result_screen.dart'; +import 'package:mlperfbench/data/extended_result.dart'; import 'package:mlperfbench/resources/result_manager.dart' as result_manager; import 'package:mlperfbench/resources/resource_manager.dart' as resource_manager; diff --git a/flutter/ios/Podfile.lock b/flutter/ios/Podfile.lock index 81311c4bc..252aa2f93 100644 --- a/flutter/ios/Podfile.lock +++ b/flutter/ios/Podfile.lock @@ -252,6 +252,6 @@ SPEC CHECKSUMS: url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f -PODFILE CHECKSUM: 00cc1108992a37101ac41f0db0bdc6d05d92ccab +PODFILE CHECKSUM: 7efefa9b0888bed7351e3ede8a076c7bd0e778fa COCOAPODS: 1.12.1 diff --git a/flutter/lib/app_constants.dart b/flutter/lib/app_constants.dart index e8defae41..923ace391 100644 --- a/flutter/lib/app_constants.dart +++ b/flutter/lib/app_constants.dart @@ -18,6 +18,7 @@ class AppColors { static const lightRedText = Color.fromARGB(255, 255, 120, 100); static const darkText = Colors.black; static const darkRedText = Colors.red; + static const darBlue = Color(0xFF0B3A61); static const dialogBackground = Colors.white; static const snackBarBackground = Color(0xFFEDEDED); diff --git a/flutter/lib/backend/bridge/ffi_run.dart b/flutter/lib/backend/bridge/ffi_run.dart index 1f9ef9382..6655201b3 100644 --- a/flutter/lib/backend/bridge/ffi_run.dart +++ b/flutter/lib/backend/bridge/ffi_run.dart @@ -3,11 +3,11 @@ import 'dart:ffi'; import 'package:ffi/ffi.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; import 'package:mlperfbench/backend/bridge/handle.dart'; import 'package:mlperfbench/backend/bridge/run_result.dart'; import 'package:mlperfbench/backend/bridge/run_settings.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; class _RunIn extends Struct { external Pointer backend_model_path; diff --git a/flutter/lib/backend/bridge/run_result.dart b/flutter/lib/backend/bridge/run_result.dart index 6c9a91358..d1c94de01 100644 --- a/flutter/lib/backend/bridge/run_result.dart +++ b/flutter/lib/backend/bridge/run_result.dart @@ -1,4 +1,4 @@ -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; class NativeRunResult { final Accuracy? accuracy1; diff --git a/flutter/lib/backend/list.dart b/flutter/lib/backend/list.dart index 42b3185dd..42d98d3a5 100644 --- a/flutter/lib/backend/list.dart +++ b/flutter/lib/backend/list.dart @@ -1,8 +1,7 @@ import 'dart:io' show Platform; -import 'package:mlperfbench_common/data/environment/environment_info.dart'; - import 'package:mlperfbench/backend/bridge/ffi_match.dart'; +import 'package:mlperfbench/data/environment/environment_info.dart'; import 'package:mlperfbench/device_info.dart'; import 'package:mlperfbench/protos/backend_setting.pb.dart' as pb; diff --git a/flutter/lib/benchmark/benchmark.dart b/flutter/lib/benchmark/benchmark.dart index 4efa484d4..01a2941cf 100644 --- a/flutter/lib/benchmark/benchmark.dart +++ b/flutter/lib/benchmark/benchmark.dart @@ -1,10 +1,10 @@ import 'package:collection/collection.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/backend/bridge/run_settings.dart'; import 'package:mlperfbench/benchmark/info.dart'; import 'package:mlperfbench/benchmark/run_mode.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; import 'package:mlperfbench/device_info.dart'; import 'package:mlperfbench/protos/backend_setting.pb.dart' as pb; import 'package:mlperfbench/protos/mlperf_task.pb.dart' as pb; diff --git a/flutter/lib/benchmark/run_info.dart b/flutter/lib/benchmark/run_info.dart index becd86d1e..3636603b8 100644 --- a/flutter/lib/benchmark/run_info.dart +++ b/flutter/lib/benchmark/run_info.dart @@ -1,8 +1,7 @@ -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; - import 'package:mlperfbench/backend/bridge/run_result.dart'; import 'package:mlperfbench/backend/bridge/run_settings.dart'; import 'package:mlperfbench/backend/loadgen_info.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; class RunInfo { final RunSettings settings; diff --git a/flutter/lib/benchmark/state.dart b/flutter/lib/benchmark/state.dart index 25628f13a..54fd730d6 100644 --- a/flutter/lib/benchmark/state.dart +++ b/flutter/lib/benchmark/state.dart @@ -7,7 +7,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart' show ChangeNotifier; import 'package:flutter/material.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; import 'package:wakelock/wakelock.dart'; import 'package:mlperfbench/backend/bridge/isolate.dart'; @@ -15,6 +14,7 @@ import 'package:mlperfbench/backend/list.dart'; import 'package:mlperfbench/benchmark/benchmark.dart'; import 'package:mlperfbench/board_decoder.dart'; import 'package:mlperfbench/build_info.dart'; +import 'package:mlperfbench/data/extended_result.dart'; import 'package:mlperfbench/resources/config_manager.dart'; import 'package:mlperfbench/resources/resource_manager.dart'; import 'package:mlperfbench/resources/validation_helper.dart'; @@ -229,6 +229,12 @@ class BenchmarkState extends ChangeNotifier { throw StateError('unreachable'); } + Future resetBenchmarkState() async { + _doneRunning = null; + resetCurrentResults(); + notifyListeners(); + } + Future runBenchmarks() async { assert(resourceManager.done, 'Resource manager is not done.'); assert(_doneRunning != false, '_doneRunning is false'); diff --git a/flutter/lib/build_info.dart b/flutter/lib/build_info.dart index eb4f06679..1dd97ae5d 100644 --- a/flutter/lib/build_info.dart +++ b/flutter/lib/build_info.dart @@ -1,8 +1,8 @@ -import 'package:mlperfbench_common/data/build_info/build_info.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/backend/list.dart'; +import 'package:mlperfbench/data/build_info/build_info.dart'; part 'build_info.gen.dart'; diff --git a/flutter_common/lib/data/benchmarks_data_provider.dart b/flutter/lib/data/benchmarks_data_provider.dart similarity index 63% rename from flutter_common/lib/data/benchmarks_data_provider.dart rename to flutter/lib/data/benchmarks_data_provider.dart index 8cf3114ec..c7bd2bf0c 100644 --- a/flutter_common/lib/data/benchmarks_data_provider.dart +++ b/flutter/lib/data/benchmarks_data_provider.dart @@ -1,7 +1,7 @@ -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/result_filter.dart'; -import 'package:mlperfbench_common/data/result_sort.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/result_filter.dart'; +import 'package:mlperfbench/data/result_sort.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; class BenchmarksDataProvider { List results; diff --git a/flutter_common/lib/data/build_info/build_info.dart b/flutter/lib/data/build_info/build_info.dart similarity index 100% rename from flutter_common/lib/data/build_info/build_info.dart rename to flutter/lib/data/build_info/build_info.dart diff --git a/flutter_common/lib/data/environment/env_android.dart b/flutter/lib/data/environment/env_android.dart similarity index 100% rename from flutter_common/lib/data/environment/env_android.dart rename to flutter/lib/data/environment/env_android.dart diff --git a/flutter_common/lib/data/environment/env_ios.dart b/flutter/lib/data/environment/env_ios.dart similarity index 100% rename from flutter_common/lib/data/environment/env_ios.dart rename to flutter/lib/data/environment/env_ios.dart diff --git a/flutter_common/lib/data/environment/env_windows.dart b/flutter/lib/data/environment/env_windows.dart similarity index 100% rename from flutter_common/lib/data/environment/env_windows.dart rename to flutter/lib/data/environment/env_windows.dart diff --git a/flutter_common/lib/data/environment/environment_info.dart b/flutter/lib/data/environment/environment_info.dart similarity index 88% rename from flutter_common/lib/data/environment/environment_info.dart rename to flutter/lib/data/environment/environment_info.dart index fcd50ef24..89e50a180 100644 --- a/flutter_common/lib/data/environment/environment_info.dart +++ b/flutter/lib/data/environment/environment_info.dart @@ -1,8 +1,8 @@ import 'package:json_annotation/json_annotation.dart'; -import 'package:mlperfbench_common/data/environment/env_android.dart'; -import 'package:mlperfbench_common/data/environment/env_ios.dart'; -import 'package:mlperfbench_common/data/environment/env_windows.dart'; +import 'package:mlperfbench/data/environment/env_android.dart'; +import 'package:mlperfbench/data/environment/env_ios.dart'; +import 'package:mlperfbench/data/environment/env_windows.dart'; part 'environment_info.g.dart'; diff --git a/flutter_common/lib/data/extended_result.dart b/flutter/lib/data/extended_result.dart similarity index 69% rename from flutter_common/lib/data/extended_result.dart rename to flutter/lib/data/extended_result.dart index bd3cfa8b9..8c9d4d04a 100644 --- a/flutter_common/lib/data/extended_result.dart +++ b/flutter/lib/data/extended_result.dart @@ -1,9 +1,9 @@ import 'package:json_annotation/json_annotation.dart'; -import 'package:mlperfbench_common/data/build_info/build_info.dart'; -import 'package:mlperfbench_common/data/environment/environment_info.dart'; -import 'package:mlperfbench_common/data/meta_info.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/build_info/build_info.dart'; +import 'package:mlperfbench/data/environment/environment_info.dart'; +import 'package:mlperfbench/data/meta_info.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; part 'extended_result.g.dart'; diff --git a/flutter_common/lib/data/generation_helpers/edit_json_schema.main.dart b/flutter/lib/data/generation_helpers/edit_json_schema.main.dart similarity index 100% rename from flutter_common/lib/data/generation_helpers/edit_json_schema.main.dart rename to flutter/lib/data/generation_helpers/edit_json_schema.main.dart diff --git a/flutter_common/lib/data/generation_helpers/sample_generator.dart b/flutter/lib/data/generation_helpers/sample_generator.dart similarity index 81% rename from flutter_common/lib/data/generation_helpers/sample_generator.dart rename to flutter/lib/data/generation_helpers/sample_generator.dart index d0faa0da8..db63da831 100644 --- a/flutter_common/lib/data/generation_helpers/sample_generator.dart +++ b/flutter/lib/data/generation_helpers/sample_generator.dart @@ -1,17 +1,17 @@ import 'package:uuid/uuid.dart'; -import 'package:mlperfbench_common/data/build_info/build_info.dart'; -import 'package:mlperfbench_common/data/environment/env_android.dart'; -import 'package:mlperfbench_common/data/environment/env_ios.dart'; -import 'package:mlperfbench_common/data/environment/env_windows.dart'; -import 'package:mlperfbench_common/data/environment/environment_info.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/meta_info.dart'; -import 'package:mlperfbench_common/data/results/backend_info.dart'; -import 'package:mlperfbench_common/data/results/backend_settings.dart'; -import 'package:mlperfbench_common/data/results/backend_settings_extra.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; -import 'package:mlperfbench_common/data/results/dataset_info.dart'; +import 'package:mlperfbench/data/build_info/build_info.dart'; +import 'package:mlperfbench/data/environment/env_android.dart'; +import 'package:mlperfbench/data/environment/env_ios.dart'; +import 'package:mlperfbench/data/environment/env_windows.dart'; +import 'package:mlperfbench/data/environment/environment_info.dart'; +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/meta_info.dart'; +import 'package:mlperfbench/data/results/backend_info.dart'; +import 'package:mlperfbench/data/results/backend_settings.dart'; +import 'package:mlperfbench/data/results/backend_settings_extra.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/results/dataset_info.dart'; /// Generates sample data. /// diff --git a/flutter_common/lib/data/generation_helpers/write_json_sample.main.dart b/flutter/lib/data/generation_helpers/write_json_sample.main.dart similarity index 86% rename from flutter_common/lib/data/generation_helpers/write_json_sample.main.dart rename to flutter/lib/data/generation_helpers/write_json_sample.main.dart index 1caeb36e8..8842668c7 100644 --- a/flutter_common/lib/data/generation_helpers/write_json_sample.main.dart +++ b/flutter/lib/data/generation_helpers/write_json_sample.main.dart @@ -1,8 +1,8 @@ import 'dart:convert'; import 'dart:io'; -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/generation_helpers/sample_generator.dart'; +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/generation_helpers/sample_generator.dart'; // // This file generates a sample of result data and writes it into specified place. diff --git a/flutter_common/lib/data/meta_info.dart b/flutter/lib/data/meta_info.dart similarity index 100% rename from flutter_common/lib/data/meta_info.dart rename to flutter/lib/data/meta_info.dart diff --git a/flutter_common/lib/data/result_filter.dart b/flutter/lib/data/result_filter.dart similarity index 92% rename from flutter_common/lib/data/result_filter.dart rename to flutter/lib/data/result_filter.dart index 483bf7fea..909e8816b 100644 --- a/flutter_common/lib/data/result_filter.dart +++ b/flutter/lib/data/result_filter.dart @@ -1,9 +1,9 @@ import 'package:json_annotation/json_annotation.dart'; -import 'package:mlperfbench_common/constants.dart'; -import 'package:mlperfbench_common/data/environment/environment_info.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/environment/environment_info.dart'; +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/string_constants.dart'; part 'result_filter.g.dart'; diff --git a/flutter_common/lib/data/result_sort.dart b/flutter/lib/data/result_sort.dart similarity index 95% rename from flutter_common/lib/data/result_sort.dart rename to flutter/lib/data/result_sort.dart index 5276294ed..2c4b1b2de 100644 --- a/flutter_common/lib/data/result_sort.dart +++ b/flutter/lib/data/result_sort.dart @@ -1,4 +1,4 @@ -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; enum SortByEnum { dateAsc, dateDesc, taskThroughputAsc, taskThroughputDesc } diff --git a/flutter_common/lib/data/results/backend_info.dart b/flutter/lib/data/results/backend_info.dart similarity index 100% rename from flutter_common/lib/data/results/backend_info.dart rename to flutter/lib/data/results/backend_info.dart diff --git a/flutter_common/lib/data/results/backend_settings.dart b/flutter/lib/data/results/backend_settings.dart similarity index 86% rename from flutter_common/lib/data/results/backend_settings.dart rename to flutter/lib/data/results/backend_settings.dart index 3d08b483a..62d37aa91 100644 --- a/flutter_common/lib/data/results/backend_settings.dart +++ b/flutter/lib/data/results/backend_settings.dart @@ -1,7 +1,7 @@ import 'package:json_annotation/json_annotation.dart'; -import 'package:mlperfbench_common/constants.dart'; -import 'package:mlperfbench_common/data/results/backend_settings_extra.dart'; +import 'package:mlperfbench/data/results/backend_settings_extra.dart'; +import 'package:mlperfbench/data/string_constants.dart'; part 'backend_settings.g.dart'; diff --git a/flutter_common/lib/data/results/backend_settings_extra.dart b/flutter/lib/data/results/backend_settings_extra.dart similarity index 100% rename from flutter_common/lib/data/results/backend_settings_extra.dart rename to flutter/lib/data/results/backend_settings_extra.dart diff --git a/flutter_common/lib/data/results/benchmark_result.dart b/flutter/lib/data/results/benchmark_result.dart similarity index 95% rename from flutter_common/lib/data/results/benchmark_result.dart rename to flutter/lib/data/results/benchmark_result.dart index 0c7502b82..1ca982a09 100644 --- a/flutter_common/lib/data/results/benchmark_result.dart +++ b/flutter/lib/data/results/benchmark_result.dart @@ -1,8 +1,8 @@ import 'package:json_annotation/json_annotation.dart'; -import 'package:mlperfbench_common/data/results/backend_info.dart'; -import 'package:mlperfbench_common/data/results/backend_settings.dart'; -import 'package:mlperfbench_common/data/results/dataset_info.dart'; +import 'package:mlperfbench/data/results/backend_info.dart'; +import 'package:mlperfbench/data/results/backend_settings.dart'; +import 'package:mlperfbench/data/results/dataset_info.dart'; part 'benchmark_result.g.dart'; diff --git a/flutter_common/lib/data/results/dataset_info.dart b/flutter/lib/data/results/dataset_info.dart similarity index 100% rename from flutter_common/lib/data/results/dataset_info.dart rename to flutter/lib/data/results/dataset_info.dart diff --git a/flutter_common/lib/constants.dart b/flutter/lib/data/string_constants.dart similarity index 100% rename from flutter_common/lib/constants.dart rename to flutter/lib/data/string_constants.dart diff --git a/flutter/lib/device_info.dart b/flutter/lib/device_info.dart index 8f2c31bb2..6afd427ad 100644 --- a/flutter/lib/device_info.dart +++ b/flutter/lib/device_info.dart @@ -4,13 +4,13 @@ import 'package:flutter/services.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:device_marketing_names/device_marketing_names.dart'; -import 'package:mlperfbench_common/data/environment/env_android.dart'; -import 'package:mlperfbench_common/data/environment/env_ios.dart'; -import 'package:mlperfbench_common/data/environment/env_windows.dart'; -import 'package:mlperfbench_common/data/environment/environment_info.dart'; import 'package:process_run/shell.dart'; import 'package:mlperfbench/backend/bridge/ffi_cpuinfo.dart'; +import 'package:mlperfbench/data/environment/env_android.dart'; +import 'package:mlperfbench/data/environment/env_ios.dart'; +import 'package:mlperfbench/data/environment/env_windows.dart'; +import 'package:mlperfbench/data/environment/environment_info.dart'; class DeviceInfo { final EnvironmentInfo envInfo; diff --git a/flutter/lib/firebase/firebase_manager.dart b/flutter/lib/firebase/firebase_manager.dart index bca490368..e3edf8922 100644 --- a/flutter/lib/firebase/firebase_manager.dart +++ b/flutter/lib/firebase/firebase_manager.dart @@ -5,8 +5,8 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:firebase_ui_auth/firebase_ui_auth.dart'; import 'package:intl/intl.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; +import 'package:mlperfbench/data/extended_result.dart'; import 'package:mlperfbench/firebase/firebase_auth_service.dart'; import 'package:mlperfbench/firebase/firebase_crashlytics_service.dart'; import 'package:mlperfbench/firebase/firebase_options.gen.dart'; diff --git a/flutter/lib/l10n/app_en.arb b/flutter/lib/l10n/app_en.arb index 897df2ba3..d65fce7da 100644 --- a/flutter/lib/l10n/app_en.arb +++ b/flutter/lib/l10n/app_en.arb @@ -6,7 +6,6 @@ "menuHome": "MLPerf Mobile", "menuHistory": "History", - "menuBenchmarkConfiguration": "Benchmark Configuration", "menuSettings": "Settings", "menuAbout": "About", "menuProfile": "Profile", @@ -25,6 +24,7 @@ "mainScreenGo": "GO", "mainScreenMeasureTitle": "Measure your device performance for:", "mainScreenWaitFinish": "Wait for benchmark to finish", + "mainScreenBenchmarkSelected": "Benchmarks (/ selected)", "progressMeasuring": "Measuring...", "progressDontClose": "Don't close the app!", diff --git a/flutter/lib/resources/export_result_helper.dart b/flutter/lib/resources/export_result_helper.dart index 45fc8e55e..ad67624c2 100644 --- a/flutter/lib/resources/export_result_helper.dart +++ b/flutter/lib/resources/export_result_helper.dart @@ -1,15 +1,14 @@ -import 'package:mlperfbench_common/data/results/backend_info.dart'; -import 'package:mlperfbench_common/data/results/backend_settings.dart'; -import 'package:mlperfbench_common/data/results/backend_settings_extra.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; -import 'package:mlperfbench_common/data/results/dataset_info.dart'; - import 'package:mlperfbench/backend/bridge/run_result.dart'; import 'package:mlperfbench/backend/list.dart'; import 'package:mlperfbench/backend/loadgen_info.dart'; import 'package:mlperfbench/benchmark/benchmark.dart'; import 'package:mlperfbench/benchmark/run_info.dart'; import 'package:mlperfbench/benchmark/run_mode.dart'; +import 'package:mlperfbench/data/results/backend_info.dart'; +import 'package:mlperfbench/data/results/backend_settings.dart'; +import 'package:mlperfbench/data/results/backend_settings_extra.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/results/dataset_info.dart'; import 'package:mlperfbench/protos/backend_setting.pb.dart' as pb; class ResultHelper { diff --git a/flutter/lib/resources/result_manager.dart b/flutter/lib/resources/result_manager.dart index bf6b2c372..6481c3f74 100644 --- a/flutter/lib/resources/result_manager.dart +++ b/flutter/lib/resources/result_manager.dart @@ -2,12 +2,12 @@ import 'dart:convert'; import 'dart:io'; import 'package:intl/intl.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/result_filter.dart'; -import 'package:mlperfbench_common/data/result_sort.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; import 'package:mlperfbench/benchmark/benchmark.dart'; +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/result_filter.dart'; +import 'package:mlperfbench/data/result_sort.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/resources/utils.dart'; diff --git a/flutter/lib/state/task_runner.dart b/flutter/lib/state/task_runner.dart index fa9f1306a..8e034aba9 100644 --- a/flutter/lib/state/task_runner.dart +++ b/flutter/lib/state/task_runner.dart @@ -2,9 +2,6 @@ import 'dart:io'; import 'dart:math'; import 'package:async/async.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/meta_info.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; import 'package:uuid/uuid.dart'; import 'package:worker_manager/worker_manager.dart'; @@ -19,6 +16,9 @@ import 'package:mlperfbench/benchmark/info.dart'; import 'package:mlperfbench/benchmark/run_info.dart'; import 'package:mlperfbench/benchmark/run_mode.dart'; import 'package:mlperfbench/build_info.dart'; +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/meta_info.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; import 'package:mlperfbench/device_info.dart'; import 'package:mlperfbench/protos/backend_setting.pb.dart' as pb; import 'package:mlperfbench/resources/export_result_helper.dart'; diff --git a/flutter/lib/ui/history/result_details_screen.dart b/flutter/lib/ui/history/result_details_screen.dart index 7d568bcd7..7a9fc6844 100644 --- a/flutter/lib/ui/history/result_details_screen.dart +++ b/flutter/lib/ui/history/result_details_screen.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; import 'package:provider/provider.dart'; import 'package:mlperfbench/benchmark/state.dart'; +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/ui/confirm_dialog.dart'; import 'package:mlperfbench/ui/history/run_details_screen.dart'; diff --git a/flutter/lib/ui/history/result_filter_screen.dart b/flutter/lib/ui/history/result_filter_screen.dart index 305299c45..82f993be2 100644 --- a/flutter/lib/ui/history/result_filter_screen.dart +++ b/flutter/lib/ui/history/result_filter_screen.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; -import 'package:mlperfbench_common/data/environment/environment_info.dart'; -import 'package:mlperfbench_common/data/result_filter.dart'; import 'package:provider/provider.dart'; import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/state.dart'; +import 'package:mlperfbench/data/environment/environment_info.dart'; +import 'package:mlperfbench/data/result_filter.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/resources/result_manager.dart'; diff --git a/flutter/lib/ui/history/result_list_item.dart b/flutter/lib/ui/history/result_list_item.dart index a0bf27ed2..aed746ac7 100644 --- a/flutter/lib/ui/history/result_list_item.dart +++ b/flutter/lib/ui/history/result_list_item.dart @@ -1,8 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; - +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; import 'package:mlperfbench/ui/history/list_item.dart'; import 'package:mlperfbench/ui/time_utils.dart'; diff --git a/flutter/lib/ui/history/result_list_screen.dart b/flutter/lib/ui/history/result_list_screen.dart index e438b6c4a..2540dbb61 100644 --- a/flutter/lib/ui/history/result_list_screen.dart +++ b/flutter/lib/ui/history/result_list_screen.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:mlperfbench_common/data/benchmarks_data_provider.dart'; -import 'package:mlperfbench_common/data/result_sort.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; import 'package:provider/provider.dart'; import 'package:mlperfbench/benchmark/state.dart'; +import 'package:mlperfbench/data/benchmarks_data_provider.dart'; +import 'package:mlperfbench/data/result_sort.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/ui/history/list_item.dart'; import 'package:mlperfbench/ui/history/result_filter_screen.dart'; diff --git a/flutter/lib/ui/history/run_details_screen.dart b/flutter/lib/ui/history/run_details_screen.dart index f1c9df15e..ca894f40c 100644 --- a/flutter/lib/ui/history/run_details_screen.dart +++ b/flutter/lib/ui/history/run_details_screen.dart @@ -1,8 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; -import 'package:mlperfbench_common/data/results/dataset_info.dart'; - +import 'package:mlperfbench/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/results/dataset_info.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/ui/history/utils.dart'; import 'package:mlperfbench/ui/time_utils.dart'; diff --git a/flutter/lib/ui/history/utils.dart b/flutter/lib/ui/history/utils.dart index 6cfe4d397..3ca326908 100644 --- a/flutter/lib/ui/history/utils.dart +++ b/flutter/lib/ui/history/utils.dart @@ -2,11 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:bot_toast/bot_toast.dart'; -import 'package:mlperfbench_common/data/environment/env_android.dart'; -import 'package:mlperfbench_common/data/environment/environment_info.dart'; import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/state.dart'; +import 'package:mlperfbench/data/environment/env_android.dart'; +import 'package:mlperfbench/data/environment/environment_info.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; class HistoryHelperUtils { diff --git a/flutter/lib/ui/home/app_drawer.dart b/flutter/lib/ui/home/app_drawer.dart index 2c6d51553..3854adcbe 100644 --- a/flutter/lib/ui/home/app_drawer.dart +++ b/flutter/lib/ui/home/app_drawer.dart @@ -5,7 +5,6 @@ import 'package:url_launcher/url_launcher.dart'; import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; -import 'package:mlperfbench/ui/config/config_screen.dart'; import 'package:mlperfbench/ui/history/result_list_screen.dart'; import 'package:mlperfbench/ui/home/user_profile.dart'; import 'package:mlperfbench/ui/settings/about_screen.dart'; @@ -67,19 +66,6 @@ class AppDrawer extends StatelessWidget { ); }, ), - ListTile( - leading: const Icon(Icons.tune), - title: Text(l10n.menuBenchmarkConfiguration), - onTap: () { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const ConfigScreen(), - ), - ); - }, - ), ListTile( leading: const Icon(Icons.settings), title: Text(l10n.menuSettings), diff --git a/flutter/lib/ui/config/config_screen.dart b/flutter/lib/ui/home/benchmark_config_screen.dart similarity index 63% rename from flutter/lib/ui/config/config_screen.dart rename to flutter/lib/ui/home/benchmark_config_screen.dart index 605bc1302..d0935d775 100644 --- a/flutter/lib/ui/config/config_screen.dart +++ b/flutter/lib/ui/home/benchmark_config_screen.dart @@ -3,19 +3,22 @@ import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; import 'package:provider/provider.dart'; +import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/benchmark.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/home/benchmark_info_button.dart'; -class ConfigScreen extends StatefulWidget { - const ConfigScreen({Key? key}) : super(key: key); +class BenchmarkConfigScreen extends StatefulWidget { + const BenchmarkConfigScreen({Key? key}) : super(key: key); @override - State createState() => _ConfigScreen(); + State createState() => _BenchmarkConfigScreen(); } -class _ConfigScreen extends State { +class _BenchmarkConfigScreen extends State { late BenchmarkState state; + late AppLocalizations l10n; late double pictureEdgeSize; @override @@ -27,8 +30,8 @@ class _ConfigScreen extends State { @override Widget build(BuildContext context) { state = context.watch(); + l10n = AppLocalizations.of(context); pictureEdgeSize = 0.1 * MediaQuery.of(context).size.width; - final l10n = AppLocalizations.of(context); final childrenList = []; for (var benchmark in state.benchmarks) { @@ -37,14 +40,39 @@ class _ConfigScreen extends State { } return Scaffold( - appBar: AppBar(title: Text(l10n.menuBenchmarkConfiguration)), - body: ListView( - padding: const EdgeInsets.fromLTRB(8, 20, 8, 20), - children: childrenList, + backgroundColor: Colors.transparent, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(32.0), + child: AppBar( + shape: Border.all(color: AppColors.darBlue), + backgroundColor: AppColors.darBlue, + elevation: 0, + title: _header(), + ), + ), + body: Container( + color: Colors.white, + child: ListView( + padding: const EdgeInsets.fromLTRB(0, 20, 0, 20), + children: childrenList, + ), ), ); } + Widget _header() { + final selectedCount = + state.benchmarks.where((e) => e.isActive).length.toString(); + final totalCount = state.benchmarks.length.toString(); + final title = l10n.mainScreenBenchmarkSelected + .replaceAll('', selectedCount) + .replaceAll('', totalCount); + return Text(title, + style: Theme.of(context).textTheme.titleSmall!.copyWith( + color: Theme.of(context).colorScheme.onPrimary, + )); + } + Widget _listTile(Benchmark benchmark) { return ListTile( leading: SizedBox( @@ -60,7 +88,14 @@ class _ConfigScreen extends State { _delegateChoice(benchmark), ], ), - trailing: _activeToggle(benchmark), + trailing: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + _activeToggle(benchmark), + _infoButton(benchmark), + ], + ), ); } @@ -86,6 +121,10 @@ class _ConfigScreen extends State { ); } + Widget _infoButton(Benchmark benchmark) { + return BenchmarkInfoButton(benchmark: benchmark); + } + Widget _delegateChoice(Benchmark benchmark) { final selected = benchmark.benchmarkSettings.delegateSelected; final choices = benchmark.benchmarkSettings.delegateChoice diff --git a/flutter/lib/ui/home/benchmark_info_button.dart b/flutter/lib/ui/home/benchmark_info_button.dart new file mode 100644 index 000000000..bfcbcd7cd --- /dev/null +++ b/flutter/lib/ui/home/benchmark_info_button.dart @@ -0,0 +1,83 @@ +import 'package:flutter/material.dart'; + +import 'package:mlperfbench/benchmark/benchmark.dart'; +import 'package:mlperfbench/localizations/app_localizations.dart'; + +class BenchmarkInfoButton extends StatelessWidget { + final Benchmark benchmark; + + const BenchmarkInfoButton({Key? key, required this.benchmark}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return IconButton( + icon: const Icon(Icons.info_outline), + onPressed: () { + _showBottomSheet(context, benchmark); + }, + ); + } + + void _showBottomSheet(BuildContext context, Benchmark benchmark) { + final stringResources = AppLocalizations.of(context); + + final info = benchmark.info.getLocalizedInfo(stringResources); + + showModalBottomSheet( + context: context, + isDismissible: false, + enableDrag: false, + isScrollControlled: true, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), + builder: (context) => Wrap( + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(20, 20, 20, 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Flexible( + flex: 5, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + benchmark.taskConfig.name, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28, + ), + ), + ], + ), + ), + Flexible( + flex: 1, + child: Container( + alignment: Alignment.topRight, + child: IconButton( + splashRadius: 24, + onPressed: () => Navigator.pop(context), + icon: const Icon(Icons.close, color: Colors.grey), + ), + ), + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(20, 0, 20, 40), + child: Text( + info.detailsContent, + style: const TextStyle(fontSize: 16), + ), + ), + ], + ), + ); + } +} diff --git a/flutter/lib/ui/home/result_screen.dart b/flutter/lib/ui/home/benchmark_result_screen.dart similarity index 89% rename from flutter/lib/ui/home/result_screen.dart rename to flutter/lib/ui/home/benchmark_result_screen.dart index a013a6e52..63fbf07c4 100644 --- a/flutter/lib/ui/home/result_screen.dart +++ b/flutter/lib/ui/home/benchmark_result_screen.dart @@ -7,13 +7,11 @@ import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/benchmark.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; -import 'package:mlperfbench/store.dart'; -import 'package:mlperfbench/ui/confirm_dialog.dart'; import 'package:mlperfbench/ui/error_dialog.dart'; import 'package:mlperfbench/ui/home/app_drawer.dart'; +import 'package:mlperfbench/ui/home/benchmark_info_button.dart'; import 'package:mlperfbench/ui/home/benchmark_running_screen.dart'; import 'package:mlperfbench/ui/home/benchmark_start_screen.dart'; -import 'package:mlperfbench/ui/home/list_of_benchmark_items.dart'; import 'package:mlperfbench/ui/home/result_circle.dart'; import 'package:mlperfbench/ui/home/share_button.dart'; import 'package:mlperfbench/ui/icons.dart' as app_icons; @@ -21,11 +19,11 @@ import 'package:mlperfbench/ui/page_constraints.dart'; enum _ScreenMode { performance, accuracy } -class ResultScreen extends StatefulWidget { - const ResultScreen({Key? key}) : super(key: key); +class BenchmarkResultScreen extends StatefulWidget { + const BenchmarkResultScreen({Key? key}) : super(key: key); @override - State createState() => _ResultScreenState(); + State createState() => _BenchmarkResultScreenState(); } class ResultKeys { @@ -33,7 +31,7 @@ class ResultKeys { static const String scrollResultsButton = 'scrollResultsButton'; } -class _ResultScreenState extends State +class _BenchmarkResultScreenState extends State with SingleTickerProviderStateMixin { late final TabController _tabController; _ScreenMode _screenMode = _ScreenMode.performance; @@ -141,7 +139,6 @@ class _ResultScreenState extends State ), ], ), - const Icon(Icons.chevron_right, color: Colors.grey), ], ), ], @@ -190,7 +187,7 @@ class _ResultScreenState extends State crossAxisAlignment: CrossAxisAlignment.start, children: rowChildren, ), - onTap: () => showBenchmarkInfoBottomSheet(context, benchmark), + trailing: BenchmarkInfoButton(benchmark: benchmark), ), const Divider() ], @@ -265,7 +262,6 @@ class _ResultScreenState extends State @override Widget build(BuildContext context) { final state = context.watch(); - final store = context.watch(); final l10n = AppLocalizations.of(context); final scrollController = ScrollController(); @@ -345,33 +341,8 @@ class _ResultScreenState extends State child: TextButton( style: buttonStyle, onPressed: () async { - // TODO (anhappdev) Refactor the code here to avoid duplicated code. - // The checks before calling state.runBenchmarks() in main_screen and result_screen are similar. - final wrongPathError = await state.validator - .validateExternalResourcesDirectory( - l10n.dialogContentMissingFiles); - if (wrongPathError.isNotEmpty) { - if (!mounted) return; - await showErrorDialog(context, [wrongPathError]); - return; - } - if (store.offlineMode) { - final offlineError = await state.validator - .validateOfflineMode(l10n.dialogContentOfflineWarning); - if (offlineError.isNotEmpty) { - if (!mounted) return; - switch (await showConfirmDialog(context, offlineError)) { - case ConfirmDialogAction.ok: - break; - case ConfirmDialogAction.cancel: - return; - default: - break; - } - } - } try { - await state.runBenchmarks(); + await state.resetBenchmarkState(); } catch (e, t) { print(t); // current context may no longer be valid if runBenchmarks requested progress screen diff --git a/flutter/lib/ui/home/benchmark_start_screen.dart b/flutter/lib/ui/home/benchmark_start_screen.dart index a29daab02..306d1c1cb 100644 --- a/flutter/lib/ui/home/benchmark_start_screen.dart +++ b/flutter/lib/ui/home/benchmark_start_screen.dart @@ -12,7 +12,7 @@ import 'package:mlperfbench/store.dart'; import 'package:mlperfbench/ui/confirm_dialog.dart'; import 'package:mlperfbench/ui/error_dialog.dart'; import 'package:mlperfbench/ui/home/app_drawer.dart'; -import 'package:mlperfbench/ui/home/list_of_benchmark_items.dart'; +import 'package:mlperfbench/ui/home/benchmark_config_screen.dart'; import 'package:mlperfbench/ui/icons.dart'; class MainKeys { @@ -29,29 +29,27 @@ class BenchmarkStartScreen extends StatelessWidget { final l10n = AppLocalizations.of(context); return Scaffold( + backgroundColor: AppColors.darBlue, appBar: AppBar(title: Text(l10n.menuHome)), drawer: const AppDrawer(), body: SafeArea( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Expanded(flex: 6, child: _getContainer(context, state.state)), - Padding( - padding: const EdgeInsets.all(30), - child: Text( - l10n.mainScreenMeasureTitle, - style: const TextStyle( - fontSize: 16, - color: AppColors.darkText, - ), - ), + Expanded( + flex: 35, + child: _getContainer(context, state.state), ), Expanded( - flex: 5, + flex: 65, child: Align( - alignment: Alignment.topCenter, - child: createListOfBenchmarkItemsWidgets(context, state)), - ), + alignment: Alignment.topCenter, + child: AbsorbPointer( + absorbing: state.state != BenchmarkStateEnum.waiting, + child: const BenchmarkConfigScreen(), + ), + ), + ) ], ), ), @@ -69,25 +67,22 @@ class BenchmarkStartScreen extends StatelessWidget { } Widget _waitContainer(BuildContext context) { - final stringResources = AppLocalizations.of(context); + final l10n = AppLocalizations.of(context); return _circleContainerWithContent( - context, AppIcons.waiting, stringResources.mainScreenWaitFinish); + context, AppIcons.waiting, l10n.mainScreenWaitFinish); } Widget _goContainer(BuildContext context) { final state = context.watch(); final store = context.watch(); - final stringResources = AppLocalizations.of(context); + final l10n = AppLocalizations.of(context); return CustomPaint( painter: MyPaintBottom(), child: GoButtonGradient(() async { - // TODO (anhappdev) Refactor the code here to avoid duplicated code. - // The checks before calling state.runBenchmarks() in main_screen and result_screen are similar. final wrongPathError = await state.validator - .validateExternalResourcesDirectory( - stringResources.dialogContentMissingFiles); + .validateExternalResourcesDirectory(l10n.dialogContentMissingFiles); if (wrongPathError.isNotEmpty) { // Workaround for Dart linter bug. See https://github.com/dart-lang/linter/issues/4007 // ignore: use_build_context_synchronously @@ -97,7 +92,7 @@ class BenchmarkStartScreen extends StatelessWidget { } if (store.offlineMode) { final offlineError = await state.validator - .validateOfflineMode(stringResources.dialogContentOfflineWarning); + .validateOfflineMode(l10n.dialogContentOfflineWarning); if (offlineError.isNotEmpty) { // Workaround for Dart linter bug. See https://github.com/dart-lang/linter/issues/4007 // ignore: use_build_context_synchronously @@ -119,8 +114,7 @@ class BenchmarkStartScreen extends StatelessWidget { // Workaround for Dart linter bug. See https://github.com/dart-lang/linter/issues/4007 // ignore: use_build_context_synchronously if (!context.mounted) return; - await showErrorDialog( - context, ['${stringResources.runFail}:', e.toString()]); + await showErrorDialog(context, ['${l10n.runFail}:', e.toString()]); return; } }), @@ -153,7 +147,7 @@ class GoButtonGradient extends StatelessWidget { @override Widget build(BuildContext context) { - final stringResources = AppLocalizations.of(context); + final l10n = AppLocalizations.of(context); var decoration = BoxDecoration( shape: BoxShape.circle, @@ -173,7 +167,7 @@ class GoButtonGradient extends StatelessWidget { return Container( decoration: decoration, - width: MediaQuery.of(context).size.width * 0.35, + width: MediaQuery.of(context).size.width * 0.32, child: MaterialButton( key: const Key(MainKeys.goButton), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, @@ -181,7 +175,7 @@ class GoButtonGradient extends StatelessWidget { shape: const CircleBorder(), onPressed: onPressed, child: Text( - stringResources.mainScreenGo, + l10n.mainScreenGo, style: const TextStyle( color: AppColors.lightText, fontSize: 40, diff --git a/flutter/lib/ui/home/list_of_benchmark_items.dart b/flutter/lib/ui/home/list_of_benchmark_items.dart deleted file mode 100644 index 642b0023e..000000000 --- a/flutter/lib/ui/home/list_of_benchmark_items.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:mlperfbench/benchmark/benchmark.dart'; -import 'package:mlperfbench/benchmark/state.dart'; -import 'package:mlperfbench/localizations/app_localizations.dart'; - -ListView createListOfBenchmarkItemsWidgets( - BuildContext context, BenchmarkState state) { - final list = []; - final pictureEdgeSize = 0.08 * MediaQuery.of(context).size.width; - - for (final benchmark in state.benchmarks) { - list.add( - InkWell( - onTap: () => showBenchmarkInfoBottomSheet( - context, - benchmark, - ), - child: Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(40, 10, 20, 10), - child: SizedBox( - width: pictureEdgeSize, - height: pictureEdgeSize, - child: benchmark.info.icon, - ), - ), - Text(benchmark.taskConfig.name), - const Icon( - Icons.chevron_right, - color: Colors.grey, - ), - ], - ), - ), - ); - } - return ListView(padding: const EdgeInsets.only(left: 20), children: list); -} - -void showBenchmarkInfoBottomSheet(BuildContext context, Benchmark benchmark) { - final stringResources = AppLocalizations.of(context); - - final info = benchmark.info.getLocalizedInfo(stringResources); - - showModalBottomSheet( - context: context, - isDismissible: false, - enableDrag: false, - isScrollControlled: true, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), - builder: (context) => Wrap( - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(20, 20, 20, 20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Flexible( - flex: 5, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - benchmark.taskConfig.name, - textAlign: TextAlign.left, - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 28, - ), - ), - ], - ), - ), - Flexible( - flex: 1, - child: Container( - alignment: Alignment.topRight, - child: IconButton( - splashRadius: 24, - onPressed: () => Navigator.pop(context), - icon: const Icon(Icons.close, color: Colors.grey), - ), - ), - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(20, 0, 20, 40), - child: Text( - info.detailsContent, - style: const TextStyle(fontSize: 16), - ), - ), - ], - ), - ); -} diff --git a/flutter/lib/ui/root/main_screen.dart b/flutter/lib/ui/root/main_screen.dart index aa604f598..5f95d6acd 100644 --- a/flutter/lib/ui/root/main_screen.dart +++ b/flutter/lib/ui/root/main_screen.dart @@ -3,10 +3,10 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:mlperfbench/benchmark/state.dart'; +import 'package:mlperfbench/ui/home/benchmark_result_screen.dart'; import 'package:mlperfbench/ui/home/benchmark_running_screen.dart'; import 'package:mlperfbench/ui/home/benchmark_start_screen.dart'; import 'package:mlperfbench/ui/home/resource_loading_screen.dart'; -import 'package:mlperfbench/ui/home/result_screen.dart'; import 'package:mlperfbench/ui/root/resource_error_screen.dart'; class MainScreen extends StatelessWidget { @@ -30,7 +30,7 @@ class MainScreen extends StatelessWidget { case BenchmarkStateEnum.running: return const BenchmarkRunningScreen(); case BenchmarkStateEnum.done: - return const ResultScreen(); + return const BenchmarkResultScreen(); } } } diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index 3a295e429..4d8a56d75 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + url: "https://pub.dev" + source: hosted + version: "61.0.0" _flutterfire_internals: dependency: transitive description: @@ -9,6 +17,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.5" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + url: "https://pub.dev" + source: hosted + version: "5.13.0" archive: dependency: "direct main" description: @@ -49,6 +65,70 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.4" + build: + dependency: transitive + description: + name: build + sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" + url: "https://pub.dev" + source: hosted + version: "2.3.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "757153e5d9cd88253cb13f28c2fb55a537dc31fefd98137549895b5beb7c6169" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "0713a05b0386bd97f9e63e78108805a4feca5898a4b821d6610857f10c91e975" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727 + url: "https://pub.dev" + source: hosted + version: "2.3.3" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: "0671ad4162ed510b70d0eb4ad6354c249f8429cab4ae7a4cec86bbc2886eb76e" + url: "https://pub.dev" + source: hosted + version: "7.2.7+1" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "69acb7007eb2a31dc901512bfe0f7b767168be34cb734835d54c070bfa74c1b2" + url: "https://pub.dev" + source: hosted + version: "8.8.0" characters: dependency: transitive description: @@ -89,6 +169,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "1be9be30396d7e4c0db42c35ea6ccd7cc6a1e19916b5dc64d6ac216b5544d677" + url: "https://pub.dev" + source: hosted + version: "4.7.0" collection: dependency: "direct main" description: @@ -97,6 +185,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.0" + color: + dependency: transitive + description: + name: color + sha256: ddcdf1b3badd7008233f5acffaf20ca9f5dc2cd0172b75f68f24526a5f5725cb + url: "https://pub.dev" + source: hosted + version: "3.0.0" convert: dependency: transitive description: @@ -129,6 +225,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + dartx: + dependency: transitive + description: + name: dartx + sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244" + url: "https://pub.dev" + source: hosted + version: "1.2.0" desktop_webview_auth: dependency: transitive description: @@ -157,10 +269,10 @@ packages: dependency: "direct main" description: name: device_marketing_names - sha256: "070dbc8f1482fc9db3eaf0f5cad90a066424a996b4c9e475ac3144d1ad0bfb8f" + sha256: b881e282abaf98b92aad6d856edf8e75276508fe1fac26aa206ab6db47a8ccd5 url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "0.7.1" email_validator: dependency: transitive description: @@ -355,6 +467,22 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_gen_core: + dependency: transitive + description: + name: flutter_gen_core + sha256: "8b4ff1d45d125e576e26ea99d15e0419bb3c45b53696e022880866b78bb6b830" + url: "https://pub.dev" + source: hosted + version: "5.3.2" + flutter_gen_runner: + dependency: "direct dev" + description: + name: flutter_gen_runner + sha256: fd197f8c657e79313d53d3934de602ebe604ba722a84c88ae3a43cd90428c67a + url: "https://pub.dev" + source: hosted + version: "5.3.2" flutter_launcher_icons: dependency: "direct dev" description: @@ -410,19 +538,51 @@ packages: description: flutter source: sdk version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + url: "https://pub.dev" + source: hosted + version: "3.2.0" fuchsia_remote_debug_protocol: dependency: transitive description: flutter source: sdk version: "0.0.0" - http: + glob: dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + graphs: + dependency: transitive + description: + name: graphs + sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + url: "https://pub.dev" + source: hosted + version: "2.3.1" + http: + dependency: "direct main" description: name: http sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" url: "https://pub.dev" source: hosted version: "0.13.6" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" http_parser: dependency: transitive description: @@ -460,6 +620,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.17.0" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" js: dependency: transitive description: @@ -469,13 +637,21 @@ packages: source: hosted version: "0.6.5" json_annotation: - dependency: transitive + dependency: "direct main" description: name: json_annotation sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 url: "https://pub.dev" source: hosted version: "4.8.1" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + sha256: "43793352f90efa5d8b251893a63d767b2f7c833120e3cc02adad55eefec04dc7" + url: "https://pub.dev" + source: hosted + version: "6.6.2" lints: dependency: transitive description: @@ -484,6 +660,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" + source: hosted + version: "1.2.0" markdown: dependency: transitive description: @@ -524,13 +708,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" - mlperfbench_common: - dependency: "direct main" - description: - path: "../flutter_common" - relative: true - source: path - version: "0.0.1" nested: dependency: transitive description: @@ -539,6 +716,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" package_info_plus: dependency: "direct main" description: @@ -631,18 +816,18 @@ packages: dependency: "direct main" description: name: permission_handler - sha256: "63e5216aae014a72fe9579ccd027323395ce7a98271d9defa9d57320d001af81" + sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8" url: "https://pub.dev" source: hosted - version: "10.4.3" + version: "11.0.1" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: "2ffaf52a21f64ac9b35fe7369bb9533edbd4f698e5604db8645b1064ff4cf221" + sha256: f9fddd3b46109bd69ff3f9efa5006d2d309b7aec0f3c1c5637a60a2d5659e76e url: "https://pub.dev" source: hosted - version: "10.3.3" + version: "11.1.0" permission_handler_apple: dependency: transitive description: @@ -655,10 +840,10 @@ packages: dependency: transitive description: name: permission_handler_platform_interface - sha256: "7c6b1500385dd1d2ca61bb89e2488ca178e274a69144d26bbd65e33eae7c02a9" + sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4" url: "https://pub.dev" source: hosted - version: "3.11.3" + version: "3.12.0" permission_handler_windows: dependency: transitive description: @@ -699,6 +884,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.7.3" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" process: dependency: transitive description: @@ -747,6 +940,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.dev" + source: hosted + version: "1.2.3" quiver: dependency: "direct main" description: @@ -775,10 +976,10 @@ packages: dependency: transitive description: name: share_plus_platform_interface - sha256: "357412af4178d8e11d14f41723f80f12caea54cf0d5cd29af9dcdab85d58aea7" + sha256: df08bc3a07d01f5ea47b45d03ffcba1fa9cd5370fb44b3f38c70e42cced0f956 url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.3.1" shared_preferences: dependency: "direct main" description: @@ -835,11 +1036,43 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" + shelf: + dependency: transitive + description: + name: shelf + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" + source: hosted + version: "1.4.1" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + url: "https://pub.dev" + source: hosted + version: "1.0.4" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "373f96cf5a8744bc9816c1ff41cf5391bbdbe3d7a96fe98c622b6738a8a7bd33" + url: "https://pub.dev" + source: hosted + version: "1.3.2" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" + url: "https://pub.dev" + source: hosted + version: "1.3.4" source_span: dependency: transitive description: @@ -848,6 +1081,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" stack_trace: dependency: transitive description: @@ -864,6 +1105,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" string_scanner: dependency: transitive description: @@ -904,6 +1153,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.16" + time: + dependency: transitive + description: + name: time + sha256: "83427e11d9072e038364a5e4da559e85869b227cf699a541be0da74f14140124" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + timing: + dependency: transitive + description: + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" + source: hosted + version: "1.0.1" tint: dependency: transitive description: @@ -1004,10 +1269,10 @@ packages: dependency: "direct main" description: name: uuid - sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" + sha256: b715b8d3858b6fa9f68f87d20d98830283628014750c2b09b6f516c1da4af2a7 url: "https://pub.dev" source: hosted - version: "3.0.7" + version: "4.1.0" vector_graphics: dependency: transitive description: @@ -1088,6 +1353,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.1" + watcher: + dependency: transitive + description: + name: watcher + sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + url: "https://pub.dev" + source: hosted + version: "2.4.0" webdriver: dependency: transitive description: diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index c23650174..9f3a4d28c 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -29,29 +29,29 @@ dependencies: quiver: ^3.2.1 url_launcher: ^6.1.11 wakelock: ^0.6.2 - uuid: ^3.0.7 + uuid: ^4.1.0 package_info_plus: ^3.1.2 share_plus: ^6.3.4 - mlperfbench_common: - path: ../flutter_common crypto: ^3.0.2 tuple: ^2.0.2 bot_toast: ^4.0.4 process_run: ^0.13.0 - device_marketing_names: ^0.6.7 + device_marketing_names: ^0.7.1 file_picker: ^5.2.10 worker_manager: ^5.0.3 ffi: ^2.0.2 async: ^2.10.0 archive: ^3.3.9 intl: ^0.17.0 - permission_handler: ^10.4.3 + permission_handler: ^11.0.1 flutter_markdown: ^0.6.15 firebase_core: ^2.15.0 firebase_storage: ^11.2.5 firebase_auth: ^4.7.2 firebase_ui_auth: ^1.6.2 firebase_crashlytics: ^3.3.5 + http: ^0.13.6 + json_annotation: ^4.8.1 dev_dependencies: flutter_test: @@ -63,6 +63,9 @@ dev_dependencies: flutter_lints: ^2.0.2 pedantic: ^1.11.0 protoc_plugin: ^21.0.2 + json_serializable: ^6.6.2 + build_runner: ^2.3.3 + flutter_gen_runner: ^5.3.2 dependency_overrides: # https://github.com/mlcommons/mobile_app_open/issues/777 diff --git a/flutter/test/backend/loadgen_info_test.dart b/flutter/unit_test/backend/loadgen_info_test.dart similarity index 100% rename from flutter/test/backend/loadgen_info_test.dart rename to flutter/unit_test/backend/loadgen_info_test.dart diff --git a/flutter/test/benchmark/benchmark_store_test.dart b/flutter/unit_test/benchmark/benchmark_store_test.dart similarity index 100% rename from flutter/test/benchmark/benchmark_store_test.dart rename to flutter/unit_test/benchmark/benchmark_store_test.dart diff --git a/flutter_common/test/data/benchmark_result_test.dart b/flutter/unit_test/data/benchmark_result_test.dart similarity index 95% rename from flutter_common/test/data/benchmark_result_test.dart rename to flutter/unit_test/data/benchmark_result_test.dart index 4c76d8623..946252625 100644 --- a/flutter_common/test/data/benchmark_result_test.dart +++ b/flutter/unit_test/data/benchmark_result_test.dart @@ -1,6 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; void main() { group('Accuracy', () { diff --git a/flutter_common/test/data/extended_result_unittest.json b/flutter/unit_test/data/extended_result_unittest.json similarity index 100% rename from flutter_common/test/data/extended_result_unittest.json rename to flutter/unit_test/data/extended_result_unittest.json diff --git a/flutter_common/test/data/result_filter_test.dart b/flutter/unit_test/data/result_filter_test.dart similarity index 92% rename from flutter_common/test/data/result_filter_test.dart rename to flutter/unit_test/data/result_filter_test.dart index 147824870..73586c262 100644 --- a/flutter_common/test/data/result_filter_test.dart +++ b/flutter/unit_test/data/result_filter_test.dart @@ -3,14 +3,14 @@ import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mlperfbench_common/data/environment/environment_info.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/result_filter.dart'; -import 'package:mlperfbench_common/data/results/benchmark_result.dart'; +import 'package:mlperfbench/data/environment/environment_info.dart'; +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/result_filter.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; void main() { group('ResultFilter', () { - const file = 'test/data/extended_result_unittest.json'; + const file = 'unit_test/data/extended_result_unittest.json'; final jsonString = File(file).readAsStringSync(); final data = jsonDecode(jsonString) as Map; final result = ExtendedResult.fromJson(data); diff --git a/flutter_common/test/data/result_sort_test.dart b/flutter/unit_test/data/result_sort_test.dart similarity index 92% rename from flutter_common/test/data/result_sort_test.dart rename to flutter/unit_test/data/result_sort_test.dart index 7ddc0ec3f..847c36972 100644 --- a/flutter_common/test/data/result_sort_test.dart +++ b/flutter/unit_test/data/result_sort_test.dart @@ -3,12 +3,12 @@ import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/result_sort.dart'; +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/result_sort.dart'; void main() { group('ResultSort', () { - const file = 'test/data/extended_result_unittest.json'; + const file = 'unit_test/data/extended_result_unittest.json'; final jsonString = File(file).readAsStringSync(); final data = jsonDecode(jsonString) as Map; final result = ExtendedResult.fromJson(data); diff --git a/flutter_common/test/data/serialization_test.dart b/flutter/unit_test/data/serialization_test.dart similarity index 87% rename from flutter_common/test/data/serialization_test.dart rename to flutter/unit_test/data/serialization_test.dart index b4805f2c0..40f9ebbb2 100644 --- a/flutter_common/test/data/serialization_test.dart +++ b/flutter/unit_test/data/serialization_test.dart @@ -3,8 +3,8 @@ import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mlperfbench_common/data/extended_result.dart'; -import 'package:mlperfbench_common/data/results/backend_info.dart'; +import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/results/backend_info.dart'; void main() { group('json serialization', () { @@ -42,7 +42,7 @@ void main() { }, throwsA(isA())); }); test('full result parsing', () async { - final file = File('test/data/extended_result_unittest.json'); + final file = File('unit_test/data/extended_result_unittest.json'); final jsonString = await file.readAsString(); final data = jsonDecode(jsonString) as Map; ExtendedResult.fromJson(data); diff --git a/flutter/test/resources/cache_manager_test.dart b/flutter/unit_test/resources/cache_manager_test.dart similarity index 100% rename from flutter/test/resources/cache_manager_test.dart rename to flutter/unit_test/resources/cache_manager_test.dart diff --git a/flutter_common/.gitignore b/flutter_common/.gitignore deleted file mode 100644 index a247422ef..000000000 --- a/flutter_common/.gitignore +++ /dev/null @@ -1,75 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.packages -.pub-cache/ -.pub/ -build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Flutter.podspec -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/ephemeral -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 diff --git a/flutter_common/.metadata b/flutter_common/.metadata deleted file mode 100644 index f2e0b179f..000000000 --- a/flutter_common/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 4cc385b4b84ac2f816d939a49ea1f328c4e0b48e - channel: unknown - -project_type: package diff --git a/flutter_common/README.md b/flutter_common/README.md deleted file mode 100644 index 9f8f5e837..000000000 --- a/flutter_common/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Flutter common code - -This folder contains common Flutter code used by the mobile Flutter app at [flutter](../flutter). diff --git a/flutter_common/analysis_options.yaml b/flutter_common/analysis_options.yaml deleted file mode 100644 index c4dcfc036..000000000 --- a/flutter_common/analysis_options.yaml +++ /dev/null @@ -1,15 +0,0 @@ -include: package:flutter_lints/flutter.yaml - -analyzer: - language: - strict-casts: true - -linter: - # https://dart.dev/tools/linter-rules - rules: - avoid_print: false - prefer_single_quotes: true - prefer_function_declarations_over_variables: false - always_use_package_imports: true - unawaited_futures: true - avoid_void_async: true diff --git a/flutter_common/pubspec.lock b/flutter_common/pubspec.lock deleted file mode 100644 index fa9e5efa0..000000000 --- a/flutter_common/pubspec.lock +++ /dev/null @@ -1,637 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a - url: "https://pub.dev" - source: hosted - version: "61.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 - url: "https://pub.dev" - source: hosted - version: "5.13.0" - args: - dependency: transitive - description: - name: args - sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 - url: "https://pub.dev" - source: hosted - version: "2.4.2" - async: - dependency: transitive - description: - name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 - url: "https://pub.dev" - source: hosted - version: "2.10.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - build: - dependency: transitive - description: - name: build - sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" - url: "https://pub.dev" - source: hosted - version: "2.3.1" - build_config: - dependency: transitive - description: - name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 - url: "https://pub.dev" - source: hosted - version: "1.1.1" - build_daemon: - dependency: transitive - description: - name: build_daemon - sha256: "757153e5d9cd88253cb13f28c2fb55a537dc31fefd98137549895b5beb7c6169" - url: "https://pub.dev" - source: hosted - version: "3.1.1" - build_resolvers: - dependency: transitive - description: - name: build_resolvers - sha256: "6c4dd11d05d056e76320b828a1db0fc01ccd376922526f8e9d6c796a5adbac20" - url: "https://pub.dev" - source: hosted - version: "2.2.1" - build_runner: - dependency: "direct dev" - description: - name: build_runner - sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727 - url: "https://pub.dev" - source: hosted - version: "2.3.3" - build_runner_core: - dependency: transitive - description: - name: build_runner_core - sha256: "0671ad4162ed510b70d0eb4ad6354c249f8429cab4ae7a4cec86bbc2886eb76e" - url: "https://pub.dev" - source: hosted - version: "7.2.7+1" - built_collection: - dependency: transitive - description: - name: built_collection - sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" - url: "https://pub.dev" - source: hosted - version: "5.1.1" - built_value: - dependency: transitive - description: - name: built_value - sha256: "598a2a682e2a7a90f08ba39c0aaa9374c5112340f0a2e275f61b59389543d166" - url: "https://pub.dev" - source: hosted - version: "8.6.1" - characters: - dependency: transitive - description: - name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c - url: "https://pub.dev" - source: hosted - version: "1.2.1" - checked_yaml: - dependency: transitive - description: - name: checked_yaml - sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff - url: "https://pub.dev" - source: hosted - version: "2.0.3" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - code_builder: - dependency: transitive - description: - name: code_builder - sha256: "4ad01d6e56db961d29661561effde45e519939fdaeb46c351275b182eac70189" - url: "https://pub.dev" - source: hosted - version: "4.5.0" - collection: - dependency: transitive - description: - name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 - url: "https://pub.dev" - source: hosted - version: "1.17.0" - convert: - dependency: transitive - description: - name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" - url: "https://pub.dev" - source: hosted - version: "3.1.1" - crypto: - dependency: transitive - description: - name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab - url: "https://pub.dev" - source: hosted - version: "3.0.3" - dart_style: - dependency: transitive - description: - name: dart_style - sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" - url: "https://pub.dev" - source: hosted - version: "2.3.2" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - ffi: - dependency: transitive - description: - name: ffi - sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 - url: "https://pub.dev" - source: hosted - version: "2.0.2" - file: - dependency: transitive - description: - name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" - url: "https://pub.dev" - source: hosted - version: "6.1.4" - fixnum: - dependency: transitive - description: - name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - frontend_server_client: - dependency: transitive - description: - name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" - url: "https://pub.dev" - source: hosted - version: "3.2.0" - glob: - dependency: transitive - description: - name: glob - sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - graphs: - dependency: transitive - description: - name: graphs - sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 - url: "https://pub.dev" - source: hosted - version: "2.3.1" - http: - dependency: "direct main" - description: - name: http - sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" - url: "https://pub.dev" - source: hosted - version: "0.13.6" - http_multi_server: - dependency: transitive - description: - name: http_multi_server - sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - import_sorter: - dependency: "direct main" - description: - name: import_sorter - sha256: eb15738ccead84e62c31e0208ea4e3104415efcd4972b86906ca64a1187d0836 - url: "https://pub.dev" - source: hosted - version: "4.6.0" - io: - dependency: transitive - description: - name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" - url: "https://pub.dev" - source: hosted - version: "1.0.4" - js: - dependency: transitive - description: - name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" - url: "https://pub.dev" - source: hosted - version: "0.6.5" - json_annotation: - dependency: "direct main" - description: - name: json_annotation - sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 - url: "https://pub.dev" - source: hosted - version: "4.8.1" - json_serializable: - dependency: "direct dev" - description: - name: json_serializable - sha256: "43793352f90efa5d8b251893a63d767b2f7c833120e3cc02adad55eefec04dc7" - url: "https://pub.dev" - source: hosted - version: "6.6.2" - lints: - dependency: transitive - description: - name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - logging: - dependency: transitive - description: - name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - matcher: - dependency: transitive - description: - name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" - url: "https://pub.dev" - source: hosted - version: "0.12.13" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 - url: "https://pub.dev" - source: hosted - version: "0.2.0" - meta: - dependency: transitive - description: - name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" - url: "https://pub.dev" - source: hosted - version: "1.8.0" - mime: - dependency: transitive - description: - name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e - url: "https://pub.dev" - source: hosted - version: "1.0.4" - package_config: - dependency: transitive - description: - name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - path: - dependency: transitive - description: - name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b - url: "https://pub.dev" - source: hosted - version: "1.8.2" - path_provider: - dependency: "direct main" - description: - name: path_provider - sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2" - url: "https://pub.dev" - source: hosted - version: "2.0.15" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86" - url: "https://pub.dev" - source: hosted - version: "2.0.27" - path_provider_foundation: - dependency: transitive - description: - name: path_provider_foundation - sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297" - url: "https://pub.dev" - source: hosted - version: "2.2.4" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 - url: "https://pub.dev" - source: hosted - version: "2.1.11" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - sha256: bced5679c7df11190e1ddc35f3222c858f328fff85c3942e46e7f5589bf9eb84 - url: "https://pub.dev" - source: hosted - version: "2.1.0" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96" - url: "https://pub.dev" - source: hosted - version: "2.1.7" - platform: - dependency: transitive - description: - name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd" - url: "https://pub.dev" - source: hosted - version: "2.1.5" - pool: - dependency: transitive - description: - name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" - url: "https://pub.dev" - source: hosted - version: "1.5.1" - pub_semver: - dependency: transitive - description: - name: pub_semver - sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - pubspec_parse: - dependency: transitive - description: - name: pubspec_parse - sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 - url: "https://pub.dev" - source: hosted - version: "1.2.3" - shelf: - dependency: transitive - description: - name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 - url: "https://pub.dev" - source: hosted - version: "1.4.1" - shelf_web_socket: - dependency: transitive - description: - name: shelf_web_socket - sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" - url: "https://pub.dev" - source: hosted - version: "1.0.4" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_gen: - dependency: transitive - description: - name: source_gen - sha256: "373f96cf5a8744bc9816c1ff41cf5391bbdbe3d7a96fe98c622b6738a8a7bd33" - url: "https://pub.dev" - source: hosted - version: "1.3.2" - source_helper: - dependency: transitive - description: - name: source_helper - sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" - url: "https://pub.dev" - source: hosted - version: "1.3.4" - source_span: - dependency: transitive - description: - name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 - url: "https://pub.dev" - source: hosted - version: "1.9.1" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - stream_transform: - dependency: transitive - description: - name: stream_transform - sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 - url: "https://pub.dev" - source: hosted - version: "0.4.16" - timing: - dependency: transitive - description: - name: timing - sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" - url: "https://pub.dev" - source: hosted - version: "1.0.1" - tint: - dependency: transitive - description: - name: tint - sha256: "9652d9a589f4536d5e392cf790263d120474f15da3cf1bee7f1fdb31b4de5f46" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c - url: "https://pub.dev" - source: hosted - version: "1.3.2" - uuid: - dependency: "direct main" - description: - name: uuid - sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" - url: "https://pub.dev" - source: hosted - version: "3.0.7" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - watcher: - dependency: transitive - description: - name: watcher - sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b - url: "https://pub.dev" - source: hosted - version: "2.4.0" - win32: - dependency: transitive - description: - name: win32 - sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" - url: "https://pub.dev" - source: hosted - version: "4.1.4" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - sha256: e0b1147eec179d3911f1f19b59206448f78195ca1d20514134e10641b7d7fbff - url: "https://pub.dev" - source: hosted - version: "1.0.1" - yaml: - dependency: transitive - description: - name: yaml - sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" - url: "https://pub.dev" - source: hosted - version: "3.1.2" -sdks: - dart: ">=2.19.0 <3.0.0" - flutter: ">=3.7.1" diff --git a/flutter_common/pubspec.yaml b/flutter_common/pubspec.yaml deleted file mode 100644 index 69b3c77ed..000000000 --- a/flutter_common/pubspec.yaml +++ /dev/null @@ -1,33 +0,0 @@ -name: mlperfbench_common -description: A new Flutter package project. -version: 0.0.1 -# homepage: - -environment: - sdk: ">=2.18.0 <3.0.0" - flutter: ">=3.7.1 <3.8.0" - -dependencies: - flutter: - sdk: flutter - http: ^0.13.6 - import_sorter: ^4.6.0 - json_annotation: ^4.8.1 - path_provider: ^2.0.15 - uuid: ^3.0.7 - -dev_dependencies: - flutter_test: - sdk: flutter - flutter_lints: ^2.0.2 - json_serializable: ^6.6.2 - build_runner: ^2.3.3 - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - -import_sorter: - comments: false diff --git a/tools/formatter/format.mk b/tools/formatter/format.mk index e7f17a132..b2cdfff56 100644 --- a/tools/formatter/format.mk +++ b/tools/formatter/format.mk @@ -14,13 +14,11 @@ format/clang: .PHONY: format/dart/pub-get format/dart/pub-get: cd flutter && ${_start_args} dart pub get - cd flutter_common && ${_start_args} dart pub get .PHONY: format/dart format/dart: format/dart/pub-get cd flutter && ${_start_args} dart run import_sorter:main - cd flutter_common && ${_start_args} dart run import_sorter:main - dart format flutter flutter_common + dart format flutter .PHONY: format/swift format/swift: @@ -56,9 +54,8 @@ lint/clang: .PHONY: lint/dart lint/dart: format/dart/pub-get cd flutter && ${_start_args} dart run import_sorter:main --exit-if-changed - cd flutter_common && ${_start_args} dart run import_sorter:main --exit-if-changed - dart format --output=none --set-exit-if-changed flutter flutter_common - dart analyze --fatal-infos flutter flutter_common + dart format --output=none --set-exit-if-changed flutter + dart analyze --fatal-infos flutter .PHONY: lint/yaml lint/yaml: From 2d543a3275d61cad4e4e51cec86bdd00c2608490 Mon Sep 17 00:00:00 2001 From: Anh Date: Thu, 28 Dec 2023 16:55:22 +0700 Subject: [PATCH 08/17] ui: new settings screen (#828) * Refactor settings_screen.dart * Integrate task config into settings screen * Disable task config choice if only one config is available * Use localized name for run mode * Fix issue with Xcode Cloud build --- flutter/ios/ci_scripts/ci_post_clone.sh | 1 - flutter/lib/benchmark/run_mode.dart | 12 + flutter/lib/l10n/app_en.arb | 8 +- .../lib/ui/root/resource_error_screen.dart | 27 +- flutter/lib/ui/settings/settings_screen.dart | 333 ++++++++++-------- ...g_screen.dart => task_config_section.dart} | 132 ++++--- 6 files changed, 285 insertions(+), 228 deletions(-) rename flutter/lib/ui/settings/{task_config_screen.dart => task_config_section.dart} (86%) diff --git a/flutter/ios/ci_scripts/ci_post_clone.sh b/flutter/ios/ci_scripts/ci_post_clone.sh index 3c791a712..f72c88282 100755 --- a/flutter/ios/ci_scripts/ci_post_clone.sh +++ b/flutter/ios/ci_scripts/ci_post_clone.sh @@ -64,7 +64,6 @@ echo "$MC_LOG_PREFIX protobuf version:" && protoc --version brew install cocoapods || brew install cocoapods || brew install cocoapods echo "$MC_LOG_PREFIX cocoapods version:" && pod --version -brew install python@3.11 || brew link --overwrite python@3.11 echo "$MC_LOG_PREFIX python version:" && python3 --version python3 -m pip install --upgrade pip python3 -m pip install \ diff --git a/flutter/lib/benchmark/run_mode.dart b/flutter/lib/benchmark/run_mode.dart index 478fe0cce..4d509c6ea 100644 --- a/flutter/lib/benchmark/run_mode.dart +++ b/flutter/lib/benchmark/run_mode.dart @@ -1,3 +1,4 @@ +import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/protos/mlperf_task.pb.dart' as pb; class BenchmarkRunMode { @@ -73,4 +74,15 @@ extension BenchmarkRunModeEnumExtension on BenchmarkRunModeEnum { return true; } } + + String localizedName(AppLocalizations l10n) { + switch (this) { + case BenchmarkRunModeEnum.performanceOnly: + return l10n.benchModePerformanceOnly; + case BenchmarkRunModeEnum.accuracyOnly: + return l10n.benchModeAccuracyOnly; + case BenchmarkRunModeEnum.submissionRun: + return l10n.benchModeSubmissionRun; + } + } } diff --git a/flutter/lib/l10n/app_en.arb b/flutter/lib/l10n/app_en.arb index d65fce7da..5881a688c 100644 --- a/flutter/lib/l10n/app_en.arb +++ b/flutter/lib/l10n/app_en.arb @@ -95,6 +95,10 @@ "dialogContentMissingFiles": "Selected datasets directory does not contain files for following benchmarks:", "dialogContentChecksumError": "The following files failed checksum validation:", + + "benchModePerformanceOnly": "Performance Only", + "benchModeAccuracyOnly": "Accuracy Only", + "benchModeSubmissionRun": "Submission Run", "benchNameImageClassification": "Image Classification", "benchNameObjectDetection": "Object detection", "benchNameImageSegmentation": "Image Segmentation", @@ -118,8 +122,8 @@ "progressScreenCooldown": "Remaining time: ", "resourceErrorMessage": "Some resources failed to load.\nIf you didn't change config from default you can try clearing the cache.\nIf you use a custom configuration file ensure that it has correct structure or switch back to default config.", - "resourceErrorSwitchToDefault": "Select Task config", - "resourceErrorCurrentConfig": "Current config file: ", + "resourceErrorSelectTaskFile": "Update task configuration", + "resourceErrorCurrentConfig": "Current task config file: ", "resourceErrorRereadConfig": "I have fixed current config, try again", "resourceErrorFail": "Config failed to load", diff --git a/flutter/lib/ui/root/resource_error_screen.dart b/flutter/lib/ui/root/resource_error_screen.dart index 94cb32fda..809902e09 100644 --- a/flutter/lib/ui/root/resource_error_screen.dart +++ b/flutter/lib/ui/root/resource_error_screen.dart @@ -9,14 +9,14 @@ import 'package:mlperfbench/store.dart'; import 'package:mlperfbench/ui/error_dialog.dart'; import 'package:mlperfbench/ui/icons.dart' show AppIcons; import 'package:mlperfbench/ui/page_constraints.dart'; -import 'package:mlperfbench/ui/settings/task_config_screen.dart'; +import 'package:mlperfbench/ui/settings/task_config_section.dart'; class ResourceErrorScreen extends StatelessWidget { const ResourceErrorScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - final stringResources = AppLocalizations.of(context); + final l10n = AppLocalizations.of(context); final state = context.watch(); final store = context.watch(); @@ -54,7 +54,7 @@ class ResourceErrorScreen extends StatelessWidget { ), ), Text( - stringResources.resourceErrorMessage, + l10n.resourceErrorMessage, textAlign: TextAlign.center, style: const TextStyle( fontSize: 15, @@ -62,7 +62,7 @@ class ResourceErrorScreen extends StatelessWidget { ), ), Text( - '${stringResources.resourceErrorCurrentConfig} ${state.configManager.configLocation}', + '${l10n.resourceErrorCurrentConfig} ${state.configManager.configLocation}', textAlign: TextAlign.center, style: const TextStyle( fontSize: 15, @@ -73,7 +73,7 @@ class ResourceErrorScreen extends StatelessWidget { onPressed: () { state.clearCache(); }, - child: Text(stringResources.settingsClearCache), + child: Text(l10n.settingsClearCache), ), TextButton( onPressed: () async { @@ -82,12 +82,14 @@ class ResourceErrorScreen extends StatelessWidget { // Workaround for Dart linter bug. See https://github.com/dart-lang/linter/issues/4007 // ignore: use_build_context_synchronously if (!context.mounted) return; - await Navigator.of(context).push(MaterialPageRoute( + await Navigator.of(context).push( + MaterialPageRoute( builder: (context) => - TaskConfigScreen(taskConfigs))); + TaskConfigErrorScreen(configs: taskConfigs), + ), + ); }, - child: - Text(stringResources.resourceErrorSwitchToDefault), + child: Text(l10n.resourceErrorSelectTaskFile), ), TextButton( onPressed: () async { @@ -98,12 +100,11 @@ class ResourceErrorScreen extends StatelessWidget { } catch (e, trace) { print("can't change task config: $e"); print(trace); - await showErrorDialog(context, [ - '${stringResources.resourceErrorFail}: ${e.toString()}' - ]); + await showErrorDialog(context, + ['${l10n.resourceErrorFail}: ${e.toString()}']); } }, - child: Text(stringResources.resourceErrorRereadConfig), + child: Text(l10n.resourceErrorRereadConfig), ), ], ), diff --git a/flutter/lib/ui/settings/settings_screen.dart b/flutter/lib/ui/settings/settings_screen.dart index 7a7915d00..f87311eed 100644 --- a/flutter/lib/ui/settings/settings_screen.dart +++ b/flutter/lib/ui/settings/settings_screen.dart @@ -10,10 +10,10 @@ import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/build_info.dart'; import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/resources/config_manager.dart'; import 'package:mlperfbench/store.dart'; import 'package:mlperfbench/ui/confirm_dialog.dart'; -import 'package:mlperfbench/ui/settings/snack_bar.dart'; -import 'package:mlperfbench/ui/settings/task_config_screen.dart'; +import 'package:mlperfbench/ui/settings/task_config_section.dart'; class SettingsScreen extends StatefulWidget { const SettingsScreen({Key? key}) : super(key: key); @@ -23,34 +23,184 @@ class SettingsScreen extends StatefulWidget { } class _SettingsScreen extends State { - bool _isSnackBarShowing = false; - - void _showUnableSpecifyConfigurationMessage( - BuildContext context, AppLocalizations stringResources) { - if (!_isSnackBarShowing) { - final snackBar = - getSnackBar(stringResources.settingsUnableSpecifyConfiguration); - - ScaffoldMessenger.of(context) - .showSnackBar(snackBar) - .closed - .whenComplete(() => setState(() { - _isSnackBarShowing = false; - })); - - setState(() { - _isSnackBarShowing = true; - }); - } - } + late AppLocalizations l10n; + late BenchmarkState state; + late Store store; @override Widget build(BuildContext context) { - final store = context.watch(); - final state = context.watch(); - final l10n = AppLocalizations.of(context); + store = context.watch(); + state = context.watch(); + l10n = AppLocalizations.of(context); + + Widget artificialLoadSwitch = _artificialLoadSwitch(); + Widget crashlyticsSwitch = _crashlyticsSwitch(); + Widget runModeDropdown = _runModeDropdown(); + Widget offlineModeSwitch = _offlineModeSwitch(); + Widget keepLogSwitch = _keepLogSwitch(); + Widget cooldownSwitch = _cooldownSwitch(); + Widget cooldownSlider = _cooldownSlider(); + Widget clearCacheButton = _clearCacheButton(context); + Widget versionText = _versionText(); + Widget taskConfig = _taskConfig(context); + + return Scaffold( + appBar: AppBar(title: Text(l10n.menuSettings)), + body: SafeArea( + child: ListView( + padding: const EdgeInsets.only(top: 20), + children: [ + runModeDropdown, + offlineModeSwitch, + keepLogSwitch, + artificialLoadSwitch, + cooldownSwitch, + cooldownSlider, + const Divider(), + crashlyticsSwitch, + taskConfig, + const Divider(), + clearCacheButton, + const Divider(), + versionText, + const SizedBox(height: 20) + ], + ))); + } + + Widget _taskConfig(BuildContext context) { + final taskConfigs = state.configManager.getConfigs(); + return FutureBuilder>( + future: taskConfigs, + builder: (BuildContext context, + AsyncSnapshot> snapshot) { + if (snapshot.hasData && snapshot.data != null) { + return TaskConfigSection(snapshot.data!); + } else { + return const Text('Loading data'); + } + }, + ); + } + + Widget _versionText() { final buildInfo = BuildInfoHelper.info; + return Text( + 'Version: ${buildInfo.version} | Build: ${buildInfo.buildNumber}', + textAlign: TextAlign.center, + ); + } + + Widget _clearCacheButton(BuildContext context) { + return TextButton( + style: TextButton.styleFrom( + textStyle: const TextStyle(fontSize: 20), + ), + onPressed: () async { + switch ( + await showConfirmDialog(context, l10n.settingsClearCacheConfirm)) { + case ConfirmDialogAction.ok: + await state.clearCache(); + if (!mounted) return; + Navigator.pop(context); + break; + case ConfirmDialogAction.cancel: + break; + default: + break; + } + }, + child: Text(l10n.settingsClearCache), + ); + } + + Widget _cooldownSlider() { + return Slider( + value: store.cooldownDuration.toDouble(), + min: 1, + max: 10, + divisions: 9, + label: store.cooldownDuration.toString(), + onChanged: store.cooldown + ? (double value) { + setState(() { + store.cooldownDuration = value.toInt(); + }); + } + : null, + ); + } + Widget _cooldownSwitch() { + return ListTile( + title: Padding( + padding: const EdgeInsets.only(bottom: 5), + child: Text(l10n.settingsCooldown), + ), + subtitle: Text(l10n.settingsCooldownSubtitle + .replaceAll('', store.cooldownDuration.toString())), + trailing: Switch( + value: store.cooldown, + onChanged: (flag) { + store.cooldown = flag; + }), + ); + } + + Widget _keepLogSwitch() { + return ListTile( + title: Padding( + padding: const EdgeInsets.only(bottom: 5), + child: Text(l10n.settingsKeepLogs), + ), + subtitle: Text(l10n.settingsKeepLogsSubtitle), + trailing: Switch( + value: store.keepLogs, + onChanged: (flag) { + store.keepLogs = flag; + }, + ), + ); + } + + Widget _offlineModeSwitch() { + return ListTile( + title: Padding( + padding: const EdgeInsets.only(bottom: 5), + child: Text(l10n.settingsOffline), + ), + subtitle: Text(l10n.settingsOfflineSubtitle), + trailing: Switch( + value: store.offlineMode, + onChanged: (flag) { + store.offlineMode = flag; + }, + ), + ); + } + + Widget _runModeDropdown() { + return ListTile( + title: Padding( + padding: const EdgeInsets.only(bottom: 5), + child: Text(l10n.settingsRunMode), + ), + subtitle: Text(l10n.settingsRunModeSubtitle), + trailing: DropdownButton( + value: store.selectedBenchmarkRunMode, + items: BenchmarkRunModeEnum.values + .map((runMode) => DropdownMenuItem( + value: runMode, + child: Text(runMode.localizedName(l10n)), + )) + .toList(), + onChanged: (value) => setState(() { + store.selectedBenchmarkRunMode = value!; + })), + ); + } + + Widget _artificialLoadSwitch() { Widget artificialLoadSwitch; if (Platform.isIOS) { artificialLoadSwitch = ListTile( @@ -69,7 +219,10 @@ class _SettingsScreen extends State { } else { artificialLoadSwitch = const SizedBox(width: 0, height: 0); } + return artificialLoadSwitch; + } + Widget _crashlyticsSwitch() { Widget crashlyticsSwitch; if (FirebaseManager.enabled && DartDefine.firebaseCrashlyticsEnabled) { crashlyticsSwitch = ListTile( @@ -89,134 +242,6 @@ class _SettingsScreen extends State { } else { crashlyticsSwitch = const SizedBox(width: 0, height: 0); } - - return Scaffold( - appBar: AppBar(title: Text(l10n.menuSettings)), - body: SafeArea( - child: ListView( - padding: const EdgeInsets.only(top: 20), - children: [ - ListTile( - title: Padding( - padding: const EdgeInsets.only(bottom: 5), - child: Text(l10n.settingsRunMode), - ), - subtitle: Text(l10n.settingsRunModeSubtitle), - trailing: DropdownButton( - value: store.selectedBenchmarkRunMode, - items: BenchmarkRunModeEnum.values - .map((runMode) => DropdownMenuItem( - value: runMode, - child: Text(runMode.name), - )) - .toList(), - onChanged: (value) => setState(() { - store.selectedBenchmarkRunMode = value!; - })), - ), - ListTile( - title: Padding( - padding: const EdgeInsets.only(bottom: 5), - child: Text(l10n.settingsOffline), - ), - subtitle: Text(l10n.settingsOfflineSubtitle), - trailing: Switch( - value: store.offlineMode, - onChanged: (flag) { - store.offlineMode = flag; - }, - ), - ), - ListTile( - title: Padding( - padding: const EdgeInsets.only(bottom: 5), - child: Text(l10n.settingsKeepLogs), - ), - subtitle: Text(l10n.settingsKeepLogsSubtitle), - trailing: Switch( - value: store.keepLogs, - onChanged: (flag) { - store.keepLogs = flag; - }, - ), - ), - artificialLoadSwitch, - ListTile( - title: Padding( - padding: const EdgeInsets.only(bottom: 5), - child: Text(l10n.settingsCooldown), - ), - subtitle: Text(l10n.settingsCooldownSubtitle.replaceAll( - '', store.cooldownDuration.toString())), - trailing: Switch( - value: store.cooldown, - onChanged: (flag) { - store.cooldown = flag; - }), - ), - Slider( - value: store.cooldownDuration.toDouble(), - min: 1, - max: 10, - divisions: 9, - label: store.cooldownDuration.toString(), - onChanged: store.cooldown - ? (double value) { - setState(() { - store.cooldownDuration = value.toInt(); - }); - } - : null, - ), - const Divider(), - crashlyticsSwitch, - const Divider(), - ListTile( - title: Padding( - padding: const EdgeInsets.only(bottom: 5), - child: Text(l10n.settingsTaskConfigTitle), - ), - trailing: const Icon(Icons.chevron_right), - onTap: () async { - if (state.state == BenchmarkStateEnum.done || - state.state == BenchmarkStateEnum.waiting) { - final taskConfigs = await state.configManager.getConfigs(); - - if (!mounted) return; - await Navigator.of(context).push(MaterialPageRoute( - builder: (context) => TaskConfigScreen(taskConfigs))); - } else { - _showUnableSpecifyConfigurationMessage(context, l10n); - } - }, - ), - const Divider(), - TextButton( - style: TextButton.styleFrom( - textStyle: const TextStyle(fontSize: 20), - ), - onPressed: () async { - switch (await showConfirmDialog( - context, l10n.settingsClearCacheConfirm)) { - case ConfirmDialogAction.ok: - await state.clearCache(); - if (!mounted) return; - Navigator.pop(context); - break; - case ConfirmDialogAction.cancel: - break; - default: - break; - } - }, - child: Text(l10n.settingsClearCache), - ), - const Divider(), - Text( - 'Version: ${buildInfo.version} | Build: ${buildInfo.buildNumber}', - textAlign: TextAlign.center, - ) - ], - ))); + return crashlyticsSwitch; } } diff --git a/flutter/lib/ui/settings/task_config_screen.dart b/flutter/lib/ui/settings/task_config_section.dart similarity index 86% rename from flutter/lib/ui/settings/task_config_screen.dart rename to flutter/lib/ui/settings/task_config_section.dart index 06b4ba2a8..93c23ffd7 100644 --- a/flutter/lib/ui/settings/task_config_screen.dart +++ b/flutter/lib/ui/settings/task_config_section.dart @@ -158,29 +158,74 @@ class _DataFolderSelectorHelper { } } -class TaskConfigScreen extends StatelessWidget { +class TaskConfigSection extends StatelessWidget { final List _configs; - const TaskConfigScreen(this._configs, {Key? key}) : super(key: key); + const TaskConfigSection(this._configs, {Key? key}) : super(key: key); - Card getOptionPattern( + @override + Widget build(BuildContext context) { + final l10n = AppLocalizations.of(context); + final store = context.watch(); + final state = context.watch(); + List items = []; + items.add(ListTile( + leading: Text( + l10n.settingsTaskConfigTitle, + style: Theme.of(context).textTheme.headlineSmall, + ), + )); + items.addAll( + _configs.map( + (c) => _getConfigChoice(context, c, store.chosenConfigurationName), + ), + ); + // On ios you need to properly request access to a folder outside of the app folder + // but file_picker plugin doesn't do it. + // see the following link for details: + // https://github.com/mlcommons/mobile_app_open/pull/562#discussion_r992167655 + if (!Platform.isIOS) { + items.addAll([ + _makeCacheFolderNotice(l10n), + _DataFolderSelectorHelper(context).build(), + const Divider(), + ListTile( + title: Text(l10n.settingsTaskDataFolderSelected), + subtitle: Text(state.resourceManager.getDataFolder())), + ]); + } + + // On Android we need MANAGE_EXTERNAL_STORAGE permission + // see https://github.com/mlcommons/mobile_app_open/issues/702 + if (Platform.isAndroid) { + items.add(const ManageFilePermissionWidget()); + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: items, + ); + } + + Widget _getConfigChoice( BuildContext context, TaskConfigDescription configuration, String chosenConfigName, ) { - final stringResources = AppLocalizations.of(context); + final l10n = AppLocalizations.of(context); final state = context.watch(); - final wasChosen = chosenConfigName == configuration.name; + final isSelected = chosenConfigName == configuration.name; - return Card( + return AbsorbPointer( + absorbing: _configs.length <= 1, child: ListTile( - selected: wasChosen, + selected: isSelected, title: Padding( padding: const EdgeInsets.only(bottom: 5), child: Text(configuration.name), ), subtitle: Text(configuration.path), - trailing: Text(configuration.getType(stringResources)), + trailing: Text(configuration.getType(l10n)), onTap: () async { try { await state.setTaskConfig(name: configuration.name); @@ -190,10 +235,10 @@ class TaskConfigScreen extends StatelessWidget { Navigator.of(context).popUntil((route) => route.isFirst); await state.loadResources(); } catch (e) { - await showErrorDialog(context, [ - stringResources.settingsTaskConfigError, - e.toString() - ]); + await showErrorDialog( + context, + [l10n.settingsTaskConfigError, e.toString()], + ); } }, ), @@ -228,52 +273,6 @@ class TaskConfigScreen extends StatelessWidget { ], ); } - - @override - Widget build(BuildContext context) { - final l10n = AppLocalizations.of(context); - final store = context.watch(); - final state = context.watch(); - List items = []; - items.addAll(_configs.map((c) => getOptionPattern( - context, - c, - store.chosenConfigurationName, - ))); - // On ios you need to properly request access to a folder outside of the app folder - // but file_picker plugin doesn't do it. - // see the following link for details: - // https://github.com/mlcommons/mobile_app_open/pull/562#discussion_r992167655 - if (!Platform.isIOS) { - items.addAll([ - _makeCacheFolderNotice(l10n), - _DataFolderSelectorHelper(context).build(), - const Divider(), - ListTile( - title: Text(l10n.settingsTaskDataFolderSelected), - subtitle: Text(state.resourceManager.getDataFolder())), - const Divider(), - ]); - } - - // On Android we need MANAGE_EXTERNAL_STORAGE permission - // see https://github.com/mlcommons/mobile_app_open/issues/702 - if (Platform.isAndroid) { - items.addAll([ - const ManageFilePermissionWidget(), - const Divider(), - ]); - } - - return Scaffold( - appBar: AppBar( - title: Text(l10n.settingsTaskConfigTitle), - ), - body: ListView( - children: items, - ), - ); - } } class ManageFilePermissionWidget extends StatefulWidget { @@ -316,3 +315,20 @@ class _ManageFilePermissionWidgetState ); } } + +class TaskConfigErrorScreen extends StatelessWidget { + final List configs; + + const TaskConfigErrorScreen({required this.configs, super.key}); + + @override + Widget build(BuildContext context) { + final l10n = AppLocalizations.of(context); + return Scaffold( + appBar: AppBar( + title: Text(l10n.resourceErrorSelectTaskFile), + ), + body: TaskConfigSection(configs), + ); + } +} From 5cd40c20f60f9210151e14ea8a0cf2704379cc72 Mon Sep 17 00:00:00 2001 From: Anh Date: Tue, 2 Jan 2024 13:09:34 +0700 Subject: [PATCH 09/17] ui: new result screen (#829) * Remove score overview section * Remove header "detail result" with scroll to bottom arrow * Use gradient background color for summary section * Refactor benchmark_result_screen.dart * Fix issue with Xcode Cloud build * Refactor benchmark_start_screen.dart * Refactor sharing section * Refactor makeModelDescription * Refactor sharing section * Show error dialog when no benchmark selected * Handle case when result list is empty * Delete last result on screen * Improve error dialog * Redesign benchmark result screen * Update integration test * Fix overflow issue with accuracy score * Refactor benchmark_result_screen.dart * Refactor benchmark_config_screen.dart * Add space between rows --- flutter/integration_test/utils.dart | 15 +- flutter/lib/app_constants.dart | 21 +- .../data/environment/environment_info.dart | 21 + flutter/lib/data/result_filter.dart | 3 + flutter/lib/l10n/app_en.arb | 8 +- flutter/lib/resources/result_manager.dart | 10 + flutter/lib/ui/error_dialog.dart | 68 ++- .../lib/ui/history/result_details_screen.dart | 2 +- flutter/lib/ui/history/utils.dart | 21 - .../lib/ui/home/benchmark_config_screen.dart | 50 +- .../lib/ui/home/benchmark_result_screen.dart | 569 ++++++++---------- .../lib/ui/home/benchmark_start_screen.dart | 281 ++++----- flutter/lib/ui/home/share_button.dart | 156 +++-- flutter/lib/ui/home/shared_styles.dart | 14 + .../unit_test/data/result_filter_test.dart | 7 + 15 files changed, 613 insertions(+), 633 deletions(-) create mode 100644 flutter/lib/ui/home/shared_styles.dart diff --git a/flutter/integration_test/utils.dart b/flutter/integration_test/utils.dart index e08c2d0ab..d78c9faa8 100644 --- a/flutter/integration_test/utils.dart +++ b/flutter/integration_test/utils.dart @@ -2,11 +2,10 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mlperfbench/ui/home/benchmark_start_screen.dart'; +import 'package:mlperfbench/app_constants.dart'; import 'package:provider/provider.dart'; import 'package:mlperfbench/benchmark/state.dart'; -import 'package:mlperfbench/ui/home/benchmark_result_screen.dart'; import 'package:mlperfbench/data/extended_result.dart'; import 'package:mlperfbench/resources/result_manager.dart' as result_manager; import 'package:mlperfbench/resources/resource_manager.dart' @@ -56,21 +55,21 @@ Future validateSettings(WidgetTester tester) async { } Future runBenchmarks(WidgetTester tester) async { - const runTimeLimitMinutes = 30; const downloadTimeLimitMinutes = 20; + const runTimeLimitMinutes = 30; var goButtonIsPresented = await waitFor( - tester, downloadTimeLimitMinutes, const Key(MainKeys.goButton)); + tester, downloadTimeLimitMinutes, const Key(WidgetKeys.goButton)); expect(goButtonIsPresented, true, reason: 'Problems with downloading of datasets or models'); - final goButton = find.byKey(const Key(MainKeys.goButton)); + final goButton = find.byKey(const Key(WidgetKeys.goButton)); await tester.tap(goButton); - var scrollButtonIsPresented = await waitFor( - tester, runTimeLimitMinutes, const Key(ResultKeys.scrollResultsButton)); + var totalScoreIsPresented = await waitFor( + tester, runTimeLimitMinutes, const Key(WidgetKeys.totalScoreCircle)); - expect(scrollButtonIsPresented, true, reason: 'Test results were not found'); + expect(totalScoreIsPresented, true, reason: 'Result screen is not presented'); } Future obtainResult() async { diff --git a/flutter/lib/app_constants.dart b/flutter/lib/app_constants.dart index 923ace391..dc47364c6 100644 --- a/flutter/lib/app_constants.dart +++ b/flutter/lib/app_constants.dart @@ -13,12 +13,22 @@ class DartDefine { String.fromEnvironment('FLUTTER_DATA_FOLDER'); } +class WidgetKeys { + // list of widget keys that need to be accessed in the test code + static const String goButton = 'goButton'; + static const String totalScoreCircle = 'totalScoreCircle'; +} + class AppColors { static const lightText = Colors.white; static const lightRedText = Color.fromARGB(255, 255, 120, 100); static const darkText = Colors.black; + static const resultValid = Colors.indigo; + static const resultInvalid = Colors.red; static const darkRedText = Colors.red; - static const darBlue = Color(0xFF0B3A61); + static const lightBlue = Color(0XFF2C92CB); + static const darkBlue = Color(0xFF0B3A61); + static const mediumBlue = Color(0xFF135384); static const dialogBackground = Colors.white; static const snackBarBackground = Color(0xFFEDEDED); @@ -45,11 +55,6 @@ class AppColors { static const runBenchmarkRectangle = Color(0xFF0DB526); - static List get runBenchmarkCircleGradient => [ - Color.lerp(const Color(0xFF0DB526), Colors.white, 0.65)!, - const Color(0xFF0DB526), // 0DB526 - ]; - static List get progressScreenGradient => DartDefine.isOfficialBuild ? [const Color(0xff3189E2), const Color(0xff0B4A7F)] : [Colors.brown.shade400, Colors.brown]; @@ -79,6 +84,10 @@ class AppColors { static Color get shareTextButton => Colors.blue.shade900; } +class WidgetSizes { + static const circleWidthFactor = 0.32; +} + class BenchmarkId { static const imageClassification = 'image_classification'; static const objectDetection = 'object_detection'; diff --git a/flutter/lib/data/environment/environment_info.dart b/flutter/lib/data/environment/environment_info.dart index 89e50a180..87e26d81d 100644 --- a/flutter/lib/data/environment/environment_info.dart +++ b/flutter/lib/data/environment/environment_info.dart @@ -46,6 +46,27 @@ class EnvironmentInfo { _$EnvironmentInfoFromJson(json); Map toJson() => _$EnvironmentInfoToJson(this); + + String get modelDescription { + switch (platform) { + case EnvPlatform.android: + final android = value.android; + if (android == null) { + return 'Unknown Android device'; + } + return '${android.manufacturer} ${android.modelName}'; + case EnvPlatform.ios: + final ios = value.ios; + if (ios == null) { + return 'Unknown iOS device'; + } + return 'Apple ${ios.modelName}'; + case EnvPlatform.windows: + return 'PC'; + default: + return ''; + } + } } @JsonSerializable(fieldRename: FieldRename.snake) diff --git a/flutter/lib/data/result_filter.dart b/flutter/lib/data/result_filter.dart index 909e8816b..959d4aafe 100644 --- a/flutter/lib/data/result_filter.dart +++ b/flutter/lib/data/result_filter.dart @@ -21,6 +21,9 @@ class ResultFilter { ResultFilter(); bool match(ExtendedResult result) { + if (result.results.isEmpty) { + return false; + } String? resultDeviceModel; String? resultManufacturer; String? resultSoc; diff --git a/flutter/lib/l10n/app_en.arb b/flutter/lib/l10n/app_en.arb index 5881a688c..ab7ff97d5 100644 --- a/flutter/lib/l10n/app_en.arb +++ b/flutter/lib/l10n/app_en.arb @@ -36,9 +36,7 @@ "resultsTitleAccuracy": "Results", "resultsTabTitlePerformance": "Performance", "resultsTabTitleAccuracy": "Accuracy", - "resultsTitleDetails": "Detailed Results", - "resultsButtonTestAgain": "Test Again", - "resultsButtonShare": "Share This Result", + "resultsDeleteConfirm": "Delete this results?", "resultsNotAvailable": "N/A", "resultsBatchSize": "Batches: ", @@ -86,7 +84,8 @@ "settingsClearCacheConfirm": "All loaded resources will be deleted and downloaded again. Continue?", "settingsUnableSpecifyConfiguration": "Could not specify until benchmarks is running or content is loading", - "dialogTitleError": "Errors", + "dialogTitleWarning": "Warning", + "dialogTitleError": "Error", "dialogTitleSuccess": "Success", "dialogOk": "Ok", "dialogCancel": "Cancel", @@ -94,6 +93,7 @@ "dialogContentOfflineWarning": "Offline mode is enabled but following internet resources are defined in the configuration. Do you want to continue?", "dialogContentMissingFiles": "Selected datasets directory does not contain files for following benchmarks:", "dialogContentChecksumError": "The following files failed checksum validation:", + "dialogContentNoSelectedBenchmarkError": "Please select at least one benchmark.", "benchModePerformanceOnly": "Performance Only", diff --git a/flutter/lib/resources/result_manager.dart b/flutter/lib/resources/result_manager.dart index 6481c3f74..0c7caa478 100644 --- a/flutter/lib/resources/result_manager.dart +++ b/flutter/lib/resources/result_manager.dart @@ -82,6 +82,16 @@ class ResultManager { return File('${_resultsDir.path}/$_submissionFileName'); } + Future deleteLastResult() async { + if (localResults.isNotEmpty) { + await deleteResult(localResults.last); + } + final submissionFile = getSubmissionFile(); + if (await submissionFile.exists()) { + await submissionFile.delete(); + } + } + ExtendedResult getLastResult() { return localResults.last; } diff --git a/flutter/lib/ui/error_dialog.dart b/flutter/lib/ui/error_dialog.dart index 795470bc9..1691e5745 100644 --- a/flutter/lib/ui/error_dialog.dart +++ b/flutter/lib/ui/error_dialog.dart @@ -1,14 +1,30 @@ import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; - import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; -import 'package:mlperfbench/ui/icons.dart'; -Future showPopupDialog(BuildContext context, String header, - SvgPicture? icon, List errors) async { - final stringResources = AppLocalizations.of(context); +enum DialogTypeEnum { error, warning, success } + +Future _showPopupDialog(BuildContext context, DialogTypeEnum type, + String title, List messages) async { + final l10n = AppLocalizations.of(context); + + Icon? icon; + Color titleColor; + switch (type) { + case DialogTypeEnum.error: + icon = const Icon(Icons.error, color: Colors.red); + titleColor = Colors.red; + break; + case DialogTypeEnum.warning: + icon = const Icon(Icons.warning, color: Colors.yellow); + titleColor = Colors.yellow; + break; + case DialogTypeEnum.success: + icon = const Icon(Icons.done, color: Colors.green); + titleColor = Colors.green; + break; + } await showDialog( context: context, @@ -18,15 +34,17 @@ Future showPopupDialog(BuildContext context, String header, backgroundColor: AppColors.dialogBackground, titlePadding: const EdgeInsets.all(10), contentPadding: const EdgeInsets.fromLTRB(15, 10, 10, 10), - title: - Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text(header), - Align(alignment: Alignment.topRight, child: icon), - ]), + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(title, style: TextStyle(color: titleColor)), + Align(alignment: Alignment.topRight, child: icon), + ], + ), content: SingleChildScrollView( child: ListBody( children: [ - ...errors.map((e) => Text( + ...messages.map((e) => Text( e, style: const TextStyle(fontSize: 14), )) @@ -36,22 +54,30 @@ Future showPopupDialog(BuildContext context, String header, actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), - child: Text(stringResources.dialogOk)) + child: Text(l10n.dialogOk)) ], ); }, ); } -Future showErrorDialog(BuildContext context, List errors) async { - final stringResources = AppLocalizations.of(context); - await showPopupDialog( - context, stringResources.dialogTitleError, AppIcons.error, errors); +Future showWarningDialog( + BuildContext context, List messages) async { + final l10n = AppLocalizations.of(context); + await _showPopupDialog( + context, DialogTypeEnum.warning, l10n.dialogTitleWarning, messages); +} + +Future showErrorDialog( + BuildContext context, List messages) async { + final l10n = AppLocalizations.of(context); + await _showPopupDialog( + context, DialogTypeEnum.error, l10n.dialogTitleError, messages); } Future showSuccessDialog( - BuildContext context, List errors) async { - final stringResources = AppLocalizations.of(context); - await showPopupDialog( - context, stringResources.dialogTitleSuccess, null, errors); + BuildContext context, List messages) async { + final l10n = AppLocalizations.of(context); + await _showPopupDialog( + context, DialogTypeEnum.success, l10n.dialogTitleSuccess, messages); } diff --git a/flutter/lib/ui/history/result_details_screen.dart b/flutter/lib/ui/history/result_details_screen.dart index 7a9fc6844..4e141ae2a 100644 --- a/flutter/lib/ui/history/result_details_screen.dart +++ b/flutter/lib/ui/history/result_details_screen.dart @@ -75,7 +75,7 @@ class _DetailsScreen extends State { .replaceFirst('', appVersionType); final utils = HistoryHelperUtils(l10n); - final modelDescription = utils.makeModelDescription(res.environmentInfo); + final modelDescription = res.environmentInfo.modelDescription; final socDescription = utils.makeSocName(state, res.environmentInfo); return [ diff --git a/flutter/lib/ui/history/utils.dart b/flutter/lib/ui/history/utils.dart index 3ca326908..132d89dc7 100644 --- a/flutter/lib/ui/history/utils.dart +++ b/flutter/lib/ui/history/utils.dart @@ -129,27 +129,6 @@ class HistoryHelperUtils { ); } - String makeModelDescription(EnvironmentInfo info) { - switch (info.platform) { - case EnvPlatform.android: - final android = info.value.android; - if (android == null) { - return 'Unknown Android device'; - } - return '${android.manufacturer} ${android.modelName}'; - case EnvPlatform.ios: - final ios = info.value.ios; - if (ios == null) { - return 'Unknown iOS device'; - } - return 'Apple ${ios.modelName}'; - case EnvPlatform.windows: - return 'PC'; - default: - return ''; - } - } - String makeSocName(BenchmarkState state, EnvironmentInfo info) { switch (info.platform) { case EnvPlatform.android: diff --git a/flutter/lib/ui/home/benchmark_config_screen.dart b/flutter/lib/ui/home/benchmark_config_screen.dart index d0935d775..4f39fb580 100644 --- a/flutter/lib/ui/home/benchmark_config_screen.dart +++ b/flutter/lib/ui/home/benchmark_config_screen.dart @@ -19,7 +19,6 @@ class BenchmarkConfigScreen extends StatefulWidget { class _BenchmarkConfigScreen extends State { late BenchmarkState state; late AppLocalizations l10n; - late double pictureEdgeSize; @override void dispose() { @@ -31,7 +30,6 @@ class _BenchmarkConfigScreen extends State { Widget build(BuildContext context) { state = context.watch(); l10n = AppLocalizations.of(context); - pictureEdgeSize = 0.1 * MediaQuery.of(context).size.width; final childrenList = []; for (var benchmark in state.benchmarks) { @@ -44,8 +42,8 @@ class _BenchmarkConfigScreen extends State { appBar: PreferredSize( preferredSize: const Size.fromHeight(32.0), child: AppBar( - shape: Border.all(color: AppColors.darBlue), - backgroundColor: AppColors.darBlue, + shape: Border.all(color: AppColors.darkBlue), + backgroundColor: AppColors.darkBlue, elevation: 0, title: _header(), ), @@ -74,27 +72,36 @@ class _BenchmarkConfigScreen extends State { } Widget _listTile(Benchmark benchmark) { + final leadingWidth = 0.12 * MediaQuery.of(context).size.width; + final subtitleWidth = 0.70 * MediaQuery.of(context).size.width; + final trailingWidth = 0.28 * MediaQuery.of(context).size.width; return ListTile( leading: SizedBox( - width: pictureEdgeSize, - height: pictureEdgeSize, + width: leadingWidth, + height: leadingWidth, child: benchmark.info.icon), title: _name(benchmark), - subtitle: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _description(benchmark), - _delegateChoice(benchmark), - ], + subtitle: SizedBox( + width: subtitleWidth, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _backendDescription(benchmark), + _delegateChoice(benchmark), + ], + ), ), - trailing: Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - _activeToggle(benchmark), - _infoButton(benchmark), - ], + trailing: SizedBox( + width: trailingWidth, + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _activeToggle(benchmark), + _infoButton(benchmark), + ], + ), ), ); } @@ -103,7 +110,7 @@ class _BenchmarkConfigScreen extends State { return Text(benchmark.info.taskName); } - Widget _description(Benchmark benchmark) { + Widget _backendDescription(Benchmark benchmark) { return Padding( padding: const EdgeInsets.only(top: 8), child: Text(benchmark.backendRequestDescription), @@ -154,6 +161,7 @@ class _BenchmarkConfigScreen extends State { })); return Row( mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, children: [ const Text('Delegate:'), const SizedBox(width: 4), diff --git a/flutter/lib/ui/home/benchmark_result_screen.dart b/flutter/lib/ui/home/benchmark_result_screen.dart index 63fbf07c4..475b0a2c3 100644 --- a/flutter/lib/ui/home/benchmark_result_screen.dart +++ b/flutter/lib/ui/home/benchmark_result_screen.dart @@ -1,21 +1,19 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:quiver/iterables.dart'; import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/benchmark.dart'; import 'package:mlperfbench/benchmark/state.dart'; +import 'package:mlperfbench/device_info.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; -import 'package:mlperfbench/ui/error_dialog.dart'; +import 'package:mlperfbench/ui/confirm_dialog.dart'; import 'package:mlperfbench/ui/home/app_drawer.dart'; import 'package:mlperfbench/ui/home/benchmark_info_button.dart'; -import 'package:mlperfbench/ui/home/benchmark_running_screen.dart'; -import 'package:mlperfbench/ui/home/benchmark_start_screen.dart'; import 'package:mlperfbench/ui/home/result_circle.dart'; import 'package:mlperfbench/ui/home/share_button.dart'; -import 'package:mlperfbench/ui/icons.dart' as app_icons; -import 'package:mlperfbench/ui/page_constraints.dart'; +import 'package:mlperfbench/ui/home/shared_styles.dart'; +import 'package:mlperfbench/ui/time_utils.dart'; enum _ScreenMode { performance, accuracy } @@ -26,20 +24,18 @@ class BenchmarkResultScreen extends StatefulWidget { State createState() => _BenchmarkResultScreenState(); } -class ResultKeys { - // list of widget keys that need to be accessed in the test code - static const String scrollResultsButton = 'scrollResultsButton'; -} - class _BenchmarkResultScreenState extends State with SingleTickerProviderStateMixin { - late final TabController _tabController; _ScreenMode _screenMode = _ScreenMode.performance; + late final TabController _tabController; + + late AppLocalizations l10n; + late BenchmarkState state; + @override void initState() { super.initState(); - _tabController = TabController(vsync: this, length: 2); _tabController.addListener(() { if (_tabController.indexIsChanging) { @@ -60,20 +56,161 @@ class _BenchmarkResultScreenState extends State super.dispose(); } - Column _createListOfBenchmarkResultBottomWidgets( - BuildContext context, BenchmarkState state) { - final list = []; - final l10n = AppLocalizations.of(context); - final pictureEdgeSize = 0.08 * MediaQuery.of(context).size.width; + @override + Widget build(BuildContext context) { + state = context.watch(); + l10n = AppLocalizations.of(context); + + String title; + title = _screenMode == _ScreenMode.performance + ? l10n.resultsTitlePerformance + : l10n.resultsTitleAccuracy; + title = DartDefine.isOfficialBuild + ? title + : '${l10n.resultsTitleUnverified} $title'; + + return Scaffold( + appBar: AppBar( + title: Text(title), + bottom: PreferredSize( + preferredSize: const Size.fromHeight(56.0), + child: _sharingSection(), + ), + ), + drawer: const AppDrawer(), + body: LayoutBuilder( + builder: (context, constraint) { + return SingleChildScrollView( + physics: const ClampingScrollPhysics(), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _totalScoreSection(), + const SizedBox(height: 20), + _detailSection(), + ], + ), + ); + }, + ), + ); + } + Widget _sharingSection() { + final lastResult = state.lastResult; + Text deviceInfoText; + Text benchmarkDateText; + if (lastResult != null) { + deviceInfoText = Text(lastResult.environmentInfo.modelDescription); + benchmarkDateText = Text(formatDateTime(lastResult.meta.creationDate)); + } else { + deviceInfoText = Text(DeviceInfo.instance.envInfo.modelDescription); + benchmarkDateText = const Text(''); + } + final infoSection = Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + deviceInfoText, + const SizedBox(height: 4), + benchmarkDateText, + ], + ); + Widget testAgainButton = IconButton( + icon: const Icon(Icons.restart_alt), + color: Colors.white, + onPressed: () async { + await state.resetBenchmarkState(); + }, + ); + Widget deleteResultButton = IconButton( + icon: const Icon(Icons.delete), + color: Colors.white, + onPressed: () async { + if (!context.mounted) return; + switch (await showConfirmDialog(context, l10n.resultsDeleteConfirm)) { + case ConfirmDialogAction.ok: + await state.resourceManager.resultManager.deleteLastResult(); + await state.resetBenchmarkState(); + break; + case ConfirmDialogAction.cancel: + return; + default: + break; + } + }, + ); + return Container( + padding: const EdgeInsets.fromLTRB(20, 8, 10, 8), + color: AppColors.mediumBlue, + child: DefaultTextStyle.merge( + style: const TextStyle(color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + infoSection, + const Spacer(), + testAgainButton, + deleteResultButton, + const ShareButton() + ], + ), + ), + ); + } + + Widget _totalScoreSection() { + return Container( + decoration: mainLinearGradientDecoration, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + TabBar( + controller: _tabController, + indicator: const UnderlineTabIndicator(), + indicatorSize: TabBarIndicatorSize.label, + tabs: [ + Tab(text: l10n.resultsTabTitlePerformance), + Tab(text: l10n.resultsTabTitleAccuracy), + ], + ), + ResultCircle( + key: const Key(WidgetKeys.totalScoreCircle), + state.result, + ), + ], + ), + ); + } + + Widget _detailSection() { + final children = []; for (final benchmark in state.benchmarks) { - late final String? resultText; - late final double? progressBarValue; - late final String? resultText2; - late final double? progressBarValue2; - late final BenchmarkResult? benchmarkResult; - late final bool resultIsValid; - if (_screenMode == _ScreenMode.performance) { + final row = _benchmarkResultRow(benchmark); + children.add(row); + children.add(const Divider()); + } + return Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: children, + ); + } + + Widget _benchmarkResultRow(Benchmark benchmark) { + final leadingWidth = 0.12 * MediaQuery.of(context).size.width; + final subtitleWidth = 0.70 * MediaQuery.of(context).size.width; + final trailingWidth = 0.28 * MediaQuery.of(context).size.width; + late final String? resultText; + late final double? progressBarValue; + late final String? resultText2; + late final double? progressBarValue2; + late final BenchmarkResult? benchmarkResult; + late final bool resultIsValid; + switch (_screenMode) { + case _ScreenMode.performance: benchmarkResult = benchmark.performanceModeResult; final throughput = benchmarkResult?.throughput; resultText = throughput?.toUIString(); @@ -82,7 +219,8 @@ class _BenchmarkResultScreenState extends State resultText2 = null; progressBarValue2 = null; resultIsValid = benchmarkResult?.validity ?? false; - } else if (_screenMode == _ScreenMode.accuracy) { + break; + case _ScreenMode.accuracy: benchmarkResult = benchmark.accuracyModeResult; resultText = benchmarkResult?.accuracy?.formatted; progressBarValue = benchmarkResult?.accuracy?.normalized; @@ -92,310 +230,109 @@ class _BenchmarkResultScreenState extends State (benchmarkResult?.accuracy?.normalized ?? -1.0) >= 0.0 && (benchmarkResult?.accuracy?.normalized ?? -1.0) <= 1.0 && (benchmarkResult?.accuracy2?.normalized ?? -1.0) <= 1.0; + break; + } + final perfResult = benchmark.performanceModeResult; + var backendInfo = l10n.na; + if (perfResult != null) { + final backendName = perfResult.backendName; + final delegateName = perfResult.delegateName; + final acceleratorName = perfResult.acceleratorName; + backendInfo = '$backendName | $delegateName | $acceleratorName'; + } + var subtitleColumnChildren = []; + subtitleColumnChildren.add(const SizedBox(height: 4)); + final resultTextStyle = TextStyle( + color: resultIsValid ? AppColors.resultValid : AppColors.resultInvalid, + fontSize: 18.0, + fontWeight: FontWeight.bold, + ); + final benchmarkScore = Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(resultText ?? l10n.na, style: resultTextStyle), + if (resultText2 != null) Text(resultText2, style: resultTextStyle), + ], + ); + final backendInfoRow = Text(backendInfo); + subtitleColumnChildren.add(backendInfoRow); + subtitleColumnChildren.add(const SizedBox(height: 8)); + + if (benchmark.info.isOffline) { + String batchSize; + if (resultText == null) { + batchSize = l10n.na; } else { - continue; + batchSize = benchmarkResult?.batchSize.toString() ?? ''; } - final perfResult = benchmark.performanceModeResult; - var backendInfo = l10n.na; - if (perfResult != null) { - final backendName = perfResult.backendName; - final delegateName = perfResult.delegateName; - final acceleratorName = perfResult.acceleratorName; - backendInfo = '$backendName | $delegateName | $acceleratorName'; - } - var rowChildren = []; - rowChildren.add(Row( + final batchSizeRow = Row( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Padding( - padding: const EdgeInsets.only(bottom: 5), - child: Text(backendInfo)), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Column( - children: [ - Text( - resultText ?? l10n.na, - style: TextStyle( - color: resultIsValid - ? AppColors.darkText - : AppColors.darkRedText, - fontSize: 16.0, - fontWeight: FontWeight.bold, - ), - ), - if (resultText2 != null) - Text( - resultText2, - style: TextStyle( - color: resultIsValid - ? AppColors.darkText - : AppColors.darkRedText, - fontSize: 16.0, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - ], + Text( + l10n.resultsBatchSize.replaceAll('', batchSize), + style: const TextStyle( + color: Colors.grey, + fontSize: 14.0, + ), ), ], - )); - if (benchmark.info.isOffline) { - String batchSize; - if (resultText == null) { - batchSize = l10n.na; - } else { - batchSize = benchmarkResult?.batchSize.toString() ?? ''; - } - - rowChildren.add(Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - l10n.resultsBatchSize.replaceAll('', batchSize), - style: const TextStyle( - color: Colors.grey, - fontSize: 14.0, - ), - ), - ], - )); - } - rowChildren.add(FractionallySizedBox( - widthFactor: 0.9, child: BlueProgressLine(progressBarValue ?? 0.0))); - if (progressBarValue2 != null) { - rowChildren.add(FractionallySizedBox( - widthFactor: 0.9, child: BlueProgressLine(progressBarValue2))); - } - list.add( - Column( - children: [ - ListTile( - minVerticalPadding: 0, - leading: SizedBox( - width: pictureEdgeSize, - height: pictureEdgeSize, - child: benchmark.info.icon), - title: Padding( - padding: const EdgeInsets.fromLTRB(0, 5, 0, 5), - child: Text(benchmark.taskConfig.name), - ), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: rowChildren, - ), - trailing: BenchmarkInfoButton(benchmark: benchmark), - ), - const Divider() - ], - ), ); + subtitleColumnChildren.add(batchSizeRow); + subtitleColumnChildren.add(const SizedBox(height: 8)); } - return Column(children: list); - } - - List _createListOfBenchmarkResultTopWidgets( - BenchmarkState state, BuildContext context) { - final l10n = AppLocalizations.of(context); - final widgets = state.benchmarks.map((benchmark) { - final result = _screenMode == _ScreenMode.performance - ? benchmark.performanceModeResult - : benchmark.accuracyModeResult; - final text = _screenMode == _ScreenMode.performance - ? result?.throughput?.toUIString() - : result?.accuracy?.toUIString(); - final text2 = _screenMode == _ScreenMode.performance - ? null - : result?.accuracy2?.toUIString(); - final resultIsValid = _screenMode == _ScreenMode.performance - ? (result?.validity ?? false) - : ((result?.accuracy?.normalized ?? -1.0) >= 0.0 && - (result?.accuracy?.normalized ?? -1.0) <= 1.0 && - (result?.accuracy2?.normalized ?? -1.0) <= 1.0); - return Padding( - padding: const EdgeInsets.only(bottom: 10), - child: - Column(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - Padding( - padding: const EdgeInsets.only(bottom: 8), - child: Text( - benchmark.taskConfig.name.split(' ').join('\n').toUpperCase(), - textAlign: TextAlign.center, - style: - const TextStyle(fontSize: 12.0, color: AppColors.lightText), - ), - ), - Text( - text ?? l10n.na, - style: TextStyle( - fontSize: 32.0, - color: resultIsValid - ? AppColors.lightText - : AppColors.lightRedText, - fontWeight: FontWeight.bold), - ), - if (text2 != null) - Text( - text2, - style: TextStyle( - fontSize: 32.0, - color: resultIsValid - ? AppColors.lightText - : AppColors.lightRedText, - fontWeight: FontWeight.bold), - ), - ]), - ); - }); - - return partition(widgets, 3) - .map((row) => Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: row, - )) - .toList(); - } - - @override - Widget build(BuildContext context) { - final state = context.watch(); - final l10n = AppLocalizations.of(context); - final scrollController = ScrollController(); - final resultsPage = Column( - children: [ - Expanded( - child: CustomPaint( - painter: MyPaintBottom(), - child: Column( - children: [ - SizedBox( - width: MediaQuery.of(context).size.width * 0.75, - child: TabBar( - controller: _tabController, - indicator: const UnderlineTabIndicator(), - indicatorSize: TabBarIndicatorSize.label, - tabs: [ - Tab(text: l10n.resultsTabTitlePerformance), - Tab(text: l10n.resultsTabTitleAccuracy), - ], - ), - ), - Expanded( - child: ResultCircle(state.result), - ), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: - _createListOfBenchmarkResultTopWidgets(state, context), - ), - ), - ], - ), - ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(30, 20, 30, 20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - l10n.resultsTitleDetails, - textAlign: TextAlign.left, - style: const TextStyle( - fontSize: 17.0, fontWeight: FontWeight.bold), - ), - IconButton( - key: const Key(ResultKeys.scrollResultsButton), - icon: app_icons.AppIcons.arrow, - onPressed: () { - scrollController.animateTo( - scrollController.position.maxScrollExtent, - duration: const Duration(milliseconds: 200), - curve: Curves.ease); - }) - ], - ), - ), - ], + final progressBarRow = FractionallySizedBox( + widthFactor: 0.9, + child: BlueProgressLine(progressBarValue ?? 0.0), ); + subtitleColumnChildren.add(progressBarRow); - final minimumShareButtonWidth = MediaQuery.of(context).size.width - 40; - final buttonStyle = ButtonStyle( - backgroundColor: - MaterialStateProperty.all(AppColors.runBenchmarkRectangle), - shape: MaterialStateProperty.all(RoundedRectangleBorder( - borderRadius: BorderRadius.circular(14.0), - side: const BorderSide(color: Colors.white))), - minimumSize: - MaterialStateProperty.all(Size(minimumShareButtonWidth, 0))); + if (progressBarValue2 != null) { + final progressBarRow2 = FractionallySizedBox( + widthFactor: 0.9, + child: BlueProgressLine(progressBarValue2), + ); + subtitleColumnChildren.add(progressBarRow2); + } - final detailedResultsPage = Column(children: [ - _createListOfBenchmarkResultBottomWidgets(context, state), - Padding( - padding: const EdgeInsets.fromLTRB(10, 10, 10, 10), - child: TextButton( - style: buttonStyle, - onPressed: () async { - try { - await state.resetBenchmarkState(); - } catch (e, t) { - print(t); - // current context may no longer be valid if runBenchmarks requested progress screen - await showErrorDialog( - BenchmarkRunningScreen.scaffoldKey.currentContext ?? - context, - ['${l10n.runFail}:', e.toString()]); - return; - } - }, - child: Padding( - padding: const EdgeInsets.fromLTRB(0, 10, 0, 10), - child: Text( - l10n.resultsButtonTestAgain, - style: const TextStyle( - fontSize: 20.0, - color: AppColors.lightText, - ), - ), - ), - )), - const Padding( - padding: EdgeInsets.fromLTRB(10, 10, 10, 10), - child: ShareButton(), + return ListTile( + contentPadding: const EdgeInsets.fromLTRB(10, 0, 10, 0), + minVerticalPadding: 0, + leading: SizedBox( + width: leadingWidth, + height: leadingWidth, + child: benchmark.info.icon), + title: SizedBox( + width: subtitleWidth, + child: Text(benchmark.taskConfig.name), ), - const SizedBox(height: 20) - ]); - - String title; - title = _screenMode == _ScreenMode.performance - ? l10n.resultsTitlePerformance - : l10n.resultsTitleAccuracy; - title = DartDefine.isOfficialBuild - ? title - : '${l10n.resultsTitleUnverified} $title'; - - return Scaffold( - appBar: AppBar(title: Text(title)), - drawer: const AppDrawer(), - body: LayoutBuilder( - builder: (context, constraint) { - return SingleChildScrollView( - physics: const ClampingScrollPhysics(), - controller: scrollController, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - getPageWidget(constraint, resultsPage), - getPageWidget(constraint, detailedResultsPage) - ], + subtitle: SizedBox( + width: subtitleWidth, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: subtitleColumnChildren, + ), + ), + trailing: SizedBox( + width: trailingWidth, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Flexible( + flex: 7, + fit: FlexFit.tight, + child: benchmarkScore, ), - ); - }, + Flexible( + flex: 3, + fit: FlexFit.tight, + child: BenchmarkInfoButton(benchmark: benchmark), + ), + ], + ), ), ); } diff --git a/flutter/lib/ui/home/benchmark_start_screen.dart b/flutter/lib/ui/home/benchmark_start_screen.dart index 306d1c1cb..8128dff6e 100644 --- a/flutter/lib/ui/home/benchmark_start_screen.dart +++ b/flutter/lib/ui/home/benchmark_start_screen.dart @@ -1,6 +1,3 @@ -import 'dart:math'; - -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -13,13 +10,9 @@ import 'package:mlperfbench/ui/confirm_dialog.dart'; import 'package:mlperfbench/ui/error_dialog.dart'; import 'package:mlperfbench/ui/home/app_drawer.dart'; import 'package:mlperfbench/ui/home/benchmark_config_screen.dart'; +import 'package:mlperfbench/ui/home/shared_styles.dart'; import 'package:mlperfbench/ui/icons.dart'; -class MainKeys { - // list of widget keys that need to be accessed in the test code - static const String goButton = 'goButton'; -} - class BenchmarkStartScreen extends StatelessWidget { const BenchmarkStartScreen({Key? key}) : super(key: key); @@ -29,16 +22,17 @@ class BenchmarkStartScreen extends StatelessWidget { final l10n = AppLocalizations.of(context); return Scaffold( - backgroundColor: AppColors.darBlue, + backgroundColor: AppColors.darkBlue, appBar: AppBar(title: Text(l10n.menuHome)), drawer: const AppDrawer(), body: SafeArea( child: Column( mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( flex: 35, - child: _getContainer(context, state.state), + child: _getTopContainer(context, state.state), ), Expanded( flex: 65, @@ -56,7 +50,7 @@ class BenchmarkStartScreen extends StatelessWidget { ); } - Widget _getContainer(BuildContext context, BenchmarkStateEnum state) { + Widget _getTopContainer(BuildContext context, BenchmarkStateEnum state) { if (state == BenchmarkStateEnum.aborting) { return _waitContainer(context); } else if (state == BenchmarkStateEnum.waiting) { @@ -68,160 +62,135 @@ class BenchmarkStartScreen extends StatelessWidget { Widget _waitContainer(BuildContext context) { final l10n = AppLocalizations.of(context); - - return _circleContainerWithContent( - context, AppIcons.waiting, l10n.mainScreenWaitFinish); + final circleWidth = + MediaQuery.of(context).size.width * WidgetSizes.circleWidthFactor; + + return Stack( + alignment: Alignment.topCenter, + children: [ + Container( + width: MediaQuery.of(context).size.width, + alignment: Alignment.center, + decoration: mainLinearGradientDecoration, + ), + Padding( + padding: const EdgeInsets.all(20), + child: Text( + l10n.mainScreenWaitFinish, + style: const TextStyle(color: AppColors.lightText, fontSize: 15), + ), + ), + Stack( + children: [ + Container( + width: circleWidth, + alignment: Alignment.center, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: AppColors.progressCircle, + boxShadow: [ + BoxShadow( + color: Colors.black12, + offset: Offset(15, 15), + blurRadius: 10, + ) + ], + ), + ), + Container( + width: circleWidth, + alignment: Alignment.center, + child: AppIcons.waiting, + ) + ], + ) + ], + ); } Widget _goContainer(BuildContext context) { final state = context.watch(); final store = context.watch(); final l10n = AppLocalizations.of(context); - - return CustomPaint( - painter: MyPaintBottom(), - child: GoButtonGradient(() async { - final wrongPathError = await state.validator - .validateExternalResourcesDirectory(l10n.dialogContentMissingFiles); - if (wrongPathError.isNotEmpty) { - // Workaround for Dart linter bug. See https://github.com/dart-lang/linter/issues/4007 - // ignore: use_build_context_synchronously - if (!context.mounted) return; - await showErrorDialog(context, [wrongPathError]); - return; - } - if (store.offlineMode) { - final offlineError = await state.validator - .validateOfflineMode(l10n.dialogContentOfflineWarning); - if (offlineError.isNotEmpty) { - // Workaround for Dart linter bug. See https://github.com/dart-lang/linter/issues/4007 - // ignore: use_build_context_synchronously - if (!context.mounted) return; - switch (await showConfirmDialog(context, offlineError)) { - case ConfirmDialogAction.ok: - break; - case ConfirmDialogAction.cancel: + final circleWidth = + MediaQuery.of(context).size.width * WidgetSizes.circleWidthFactor; + + return Stack( + alignment: Alignment.topCenter, + children: [ + Container( + width: MediaQuery.of(context).size.width, + alignment: Alignment.center, + decoration: mainLinearGradientDecoration, + ), + Container( + alignment: Alignment.center, + child: ElevatedButton( + key: const Key(WidgetKeys.goButton), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green, + shape: const CircleBorder(), + minimumSize: Size.fromWidth(circleWidth)), + child: Text( + l10n.mainScreenGo, + style: const TextStyle( + color: AppColors.lightText, + fontSize: 40, + ), + ), + onPressed: () async { + final wrongPathError = await state.validator + .validateExternalResourcesDirectory( + l10n.dialogContentMissingFiles); + if (wrongPathError.isNotEmpty) { + // Workaround for Dart linter bug. See https://github.com/dart-lang/linter/issues/4007 + // ignore: use_build_context_synchronously + if (!context.mounted) return; + await showErrorDialog(context, [wrongPathError]); return; - default: - break; - } - } - } - try { - await state.runBenchmarks(); - } catch (e, t) { - print(t); - // Workaround for Dart linter bug. See https://github.com/dart-lang/linter/issues/4007 - // ignore: use_build_context_synchronously - if (!context.mounted) return; - await showErrorDialog(context, ['${l10n.runFail}:', e.toString()]); - return; - } - }), - ); - } -} - -class MyPaintBottom extends CustomPainter { - @override - void paint(Canvas canvas, Size size) { - final rect = - Rect.fromCircle(center: Offset(size.width / 2, 0), radius: size.height); - final paint = Paint() - ..shader = LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomLeft, - colors: AppColors.mainScreenGradient, - ).createShader(rect); - canvas.drawArc(rect, 0, pi, true, paint); - } // paint - - @override - bool shouldRepaint(MyPaintBottom oldDelegate) => false; -} - -class GoButtonGradient extends StatelessWidget { - final AsyncCallback onPressed; - - const GoButtonGradient(this.onPressed, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final l10n = AppLocalizations.of(context); - - var decoration = BoxDecoration( - shape: BoxShape.circle, - gradient: LinearGradient( - colors: AppColors.runBenchmarkCircleGradient, - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - boxShadow: const [ - BoxShadow( - color: Colors.black12, - offset: Offset(15, 15), - blurRadius: 10, - ) - ], - ); - - return Container( - decoration: decoration, - width: MediaQuery.of(context).size.width * 0.32, - child: MaterialButton( - key: const Key(MainKeys.goButton), - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - splashColor: Colors.black, - shape: const CircleBorder(), - onPressed: onPressed, - child: Text( - l10n.mainScreenGo, - style: const TextStyle( - color: AppColors.lightText, - fontSize: 40, + } + if (store.offlineMode) { + final offlineError = await state.validator + .validateOfflineMode(l10n.dialogContentOfflineWarning); + if (offlineError.isNotEmpty) { + // Workaround for Dart linter bug. See https://github.com/dart-lang/linter/issues/4007 + // ignore: use_build_context_synchronously + if (!context.mounted) return; + switch (await showConfirmDialog(context, offlineError)) { + case ConfirmDialogAction.ok: + break; + case ConfirmDialogAction.cancel: + return; + default: + break; + } + } + } + final selectedCount = + state.benchmarks.where((e) => e.isActive).length; + if (selectedCount < 1) { + // Workaround for Dart linter bug. See https://github.com/dart-lang/linter/issues/4007 + // ignore: use_build_context_synchronously + if (!context.mounted) return; + await showErrorDialog( + context, [l10n.dialogContentNoSelectedBenchmarkError]); + return; + } + try { + await state.runBenchmarks(); + } catch (e, t) { + print(t); + // Workaround for Dart linter bug. See https://github.com/dart-lang/linter/issues/4007 + // ignore: use_build_context_synchronously + if (!context.mounted) return; + await showErrorDialog( + context, ['${l10n.runFail}:', e.toString()]); + return; + } + }, ), ), - ), + ], ); } } - -Widget _circleContainerWithContent( - BuildContext context, Widget contentInCircle, String label) { - return CustomPaint( - painter: MyPaintBottom(), - child: Stack(alignment: Alignment.topCenter, children: [ - Padding( - padding: const EdgeInsets.all(20), - child: Text( - label, - style: const TextStyle(color: AppColors.lightText, fontSize: 15), - ), - ), - Stack( - children: [ - Container( - width: MediaQuery.of(context).size.width * 0.35, - alignment: Alignment.center, - decoration: const BoxDecoration( - shape: BoxShape.circle, - color: AppColors.progressCircle, - boxShadow: [ - BoxShadow( - color: Colors.black12, - offset: Offset(15, 15), - blurRadius: 10, - ) - ], - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.35, - alignment: Alignment.center, - child: contentInCircle, - ) - ], - ) - ]), - ); -} diff --git a/flutter/lib/ui/home/share_button.dart b/flutter/lib/ui/home/share_button.dart index 5db45fdb6..0648a17a5 100644 --- a/flutter/lib/ui/home/share_button.dart +++ b/flutter/lib/ui/home/share_button.dart @@ -11,14 +11,34 @@ import 'package:mlperfbench/ui/home/user_profile.dart'; enum _ShareDestination { local, cloud } -class ShareButton extends StatefulWidget { +class ShareButton extends StatelessWidget { const ShareButton({Key? key}) : super(key: key); @override - State createState() => _ShareButton(); + Widget build(BuildContext context) { + return IconButton( + icon: const Icon(Icons.share), + color: Colors.white, + onPressed: () { + showModalBottomSheet( + context: context, + builder: (_) => Wrap( + children: const [ShareBottomSheet()], + ), + ); + }, + ); + } } -class _ShareButton extends State { +class ShareBottomSheet extends StatefulWidget { + const ShareBottomSheet({Key? key}) : super(key: key); + + @override + State createState() => _ShareButton(); +} + +class _ShareButton extends State { late BenchmarkState state; late AppLocalizations l10n; bool _isSharing = false; @@ -29,16 +49,7 @@ class _ShareButton extends State { state = context.watch(); l10n = AppLocalizations.of(context); return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - _buildShareButton(context), - const SizedBox(height: 16.0), - _isSharing ? _buildProgressIndicator() : Container(), - const SizedBox(height: 16.0), - Text(_shareStatus), - ], - ), + child: _buildShareModal(context), ); } @@ -67,74 +78,61 @@ class _ShareButton extends State { } } - Widget _buildShareButton(BuildContext context) { - return TextButton( - onPressed: () { - showModalBottomSheet( - context: context, - builder: (context) { - return Padding( - padding: const EdgeInsets.fromLTRB(16, 20, 16, 40), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - TextButton( - onPressed: () { - Navigator.of(context).pop(); - _handleSharing(_ShareDestination.local); - }, - child: Row( - children: [ - const Icon(Icons.share), - const SizedBox(width: 20), - Text( - l10n.shareButtonOther, - style: TextStyle( - color: AppColors.shareTextButton, - fontSize: 18, - ), - ), - ], - ), + Padding _buildShareModal(BuildContext context) { + return Padding( + padding: const EdgeInsets.fromLTRB(16, 20, 16, 10), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + TextButton( + onPressed: () { + _handleSharing(_ShareDestination.local); + }, + child: Row( + children: [ + const Icon(Icons.share), + const SizedBox(width: 20), + Text( + l10n.shareButtonOther, + style: TextStyle( + color: AppColors.shareTextButton, + fontSize: 18, ), - TextButton( - onPressed: () { - if (!FirebaseManager.enabled) { - return; - } - if (!FirebaseManager.instance.isSignedIn) { - _buildProfileModal(context); - return; - } - Navigator.of(context).pop(); - _handleSharing(_ShareDestination.cloud); - }, - child: Row( - children: [ - const Icon(Icons.cloud_upload), - const SizedBox(width: 20), - Text( - l10n.shareButtonMLCommons, - style: TextStyle( - color: AppColors.shareTextButton, - fontSize: 18, - ), - ), - ], - ), + ), + ], + ), + ), + TextButton( + onPressed: () { + if (!FirebaseManager.enabled) { + return; + } + if (!FirebaseManager.instance.isSignedIn) { + _buildProfileModal(context); + return; + } + _handleSharing(_ShareDestination.cloud); + }, + child: Row( + children: [ + const Icon(Icons.cloud_upload), + const SizedBox(width: 20), + Text( + l10n.shareButtonMLCommons, + style: TextStyle( + color: AppColors.shareTextButton, + fontSize: 18, ), - ], - ), - ); - }, - ); - }, - child: Text( - l10n.resultsButtonShare, - style: TextStyle( - color: AppColors.shareTextButton, - fontSize: 18, - ), + ), + ], + ), + ), + SizedBox( + height: 40, + child: _isSharing ? _buildProgressIndicator() : Text(_shareStatus), + ), + ], ), ); } diff --git a/flutter/lib/ui/home/shared_styles.dart b/flutter/lib/ui/home/shared_styles.dart new file mode 100644 index 000000000..dc1568dab --- /dev/null +++ b/flutter/lib/ui/home/shared_styles.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; + +import 'package:mlperfbench/app_constants.dart'; + +const mainLinearGradientDecoration = BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + AppColors.lightBlue, + AppColors.darkBlue, + ], + ), +); diff --git a/flutter/unit_test/data/result_filter_test.dart b/flutter/unit_test/data/result_filter_test.dart index 73586c262..143e6458a 100644 --- a/flutter/unit_test/data/result_filter_test.dart +++ b/flutter/unit_test/data/result_filter_test.dart @@ -122,5 +122,12 @@ void main() { final filter = ResultFilter(); expect(filter.anyFilterActive, isFalse); }); + + test('empty result list', () { + final filter = ResultFilter(); + final emptyResult = ExtendedResult.fromJson(data); + emptyResult.results.clear(); + expect(filter.match(emptyResult), isFalse); + }); }); } From b6e902ddff3b125062171e52c31ff5e02236d3be Mon Sep 17 00:00:00 2001 From: Anh Date: Tue, 9 Jan 2024 13:32:07 +0700 Subject: [PATCH 10/17] ui: new history screen (#832) * Add class BenchmarkIcons * Show benchmark icon in history list * Minor change * Cleanup and renaming for more clarity * Add apply filter button * Add icon to sort menu * Make all popup have rounded corners --- flutter/ios/ci_scripts/ci_post_clone.sh | 2 +- flutter/lib/app_constants.dart | 3 +- flutter/lib/benchmark/info.dart | 23 +-- flutter/lib/l10n/app_en.arb | 7 +- ...rt => benchmark_export_result_screen.dart} | 11 +- ...creen.dart => extended_result_screen.dart} | 13 +- ...screen.dart => history_filter_screen.dart} | 15 +- flutter/lib/ui/history/history_list_item.dart | 105 ++++++++++++ .../lib/ui/history/history_list_screen.dart | 155 ++++++++++++++++++ flutter/lib/ui/history/result_list_item.dart | 83 ---------- .../lib/ui/history/result_list_screen.dart | 120 -------------- flutter/lib/ui/home/app_drawer.dart | 4 +- .../lib/ui/home/benchmark_config_screen.dart | 1 + flutter/lib/ui/icons.dart | 29 ++++ flutter/lib/ui/root/app.dart | 5 + flutter/lib/ui/settings/settings_screen.dart | 1 + 16 files changed, 334 insertions(+), 243 deletions(-) rename flutter/lib/ui/history/{run_details_screen.dart => benchmark_export_result_screen.dart} (91%) rename flutter/lib/ui/history/{result_details_screen.dart => extended_result_screen.dart} (91%) rename flutter/lib/ui/history/{result_filter_screen.dart => history_filter_screen.dart} (95%) create mode 100644 flutter/lib/ui/history/history_list_item.dart create mode 100644 flutter/lib/ui/history/history_list_screen.dart delete mode 100644 flutter/lib/ui/history/result_list_item.dart delete mode 100644 flutter/lib/ui/history/result_list_screen.dart diff --git a/flutter/ios/ci_scripts/ci_post_clone.sh b/flutter/ios/ci_scripts/ci_post_clone.sh index f72c88282..468d9b4a7 100755 --- a/flutter/ios/ci_scripts/ci_post_clone.sh +++ b/flutter/ios/ci_scripts/ci_post_clone.sh @@ -31,7 +31,7 @@ if [ -n "$CI_DERIVED_DATA_PATH" ]; then CACHE_BUCKET=xcodecloud-bazel-ios---mobile-app-build-290400 # Required that a secret env existed in the XCode Cloud workflow # with key=GC_CREDS and value= - GC_CREDS_FILE=$CI_WORKSPACE/mobile-app-build-290400-1b26aafa8afd.json + GC_CREDS_FILE=$CI_PRIMARY_REPOSITORY_PATH/mobile-app-build-290400-1b26aafa8afd.json echo "$GC_CREDS" | base64 --decode >"$GC_CREDS_FILE" export BAZEL_OUTPUT_ROOT_ARG="--output_user_root=$MC_BUILD_HOME/bazel" export BAZEL_CACHE_ARG="--remote_cache=https://storage.googleapis.com/$CACHE_BUCKET --google_credentials=$GC_CREDS_FILE" diff --git a/flutter/lib/app_constants.dart b/flutter/lib/app_constants.dart index dc47364c6..25df61d09 100644 --- a/flutter/lib/app_constants.dart +++ b/flutter/lib/app_constants.dart @@ -33,7 +33,7 @@ class AppColors { static const dialogBackground = Colors.white; static const snackBarBackground = Color(0xFFEDEDED); static const appBarBackground = - DartDefine.isOfficialBuild ? Color(0xFF31A3E2) : Colors.brown; + DartDefine.isOfficialBuild ? Color(0xFF166299) : Colors.brown; static const appBarIcon = Colors.white; @@ -86,6 +86,7 @@ class AppColors { class WidgetSizes { static const circleWidthFactor = 0.32; + static const borderRadius = 8.0; } class BenchmarkId { diff --git a/flutter/lib/benchmark/info.dart b/flutter/lib/benchmark/info.dart index 13589386e..48fc80c1c 100644 --- a/flutter/lib/benchmark/info.dart +++ b/flutter/lib/benchmark/info.dart @@ -72,29 +72,10 @@ class BenchmarkInfo { double get maxThroughput => task.maxThroughput; - Widget get icon => _benchmarkIcons[task.id] ?? AppIcons.logo; + Widget get icon => BenchmarkIcons.getDarkIcon(task.id); - Widget get iconWhite => _benchmarkIconsWhite[task.id] ?? AppIcons.logo; + Widget get iconWhite => BenchmarkIcons.getLightIcon(task.id); @override String toString() => 'Benchmark:${task.id}'; } - -final _benchmarkIcons = { - BenchmarkId.imageClassification: AppIcons.imageClassification, - BenchmarkId.objectDetection: AppIcons.objectDetection, - BenchmarkId.imageSegmentationV2: AppIcons.imageSegmentation, - BenchmarkId.naturalLanguageProcessing: AppIcons.languageProcessing, - BenchmarkId.superResolution: AppIcons.superResolution, - BenchmarkId.imageClassificationOffline: AppIcons.imageClassificationOffline, -}; - -final _benchmarkIconsWhite = { - BenchmarkId.imageClassification: AppIcons.imageClassificationWhite, - BenchmarkId.objectDetection: AppIcons.objectDetectionWhite, - BenchmarkId.imageSegmentationV2: AppIcons.imageSegmentationWhite, - BenchmarkId.naturalLanguageProcessing: AppIcons.languageProcessingWhite, - BenchmarkId.superResolution: AppIcons.superResolutionWhite, - BenchmarkId.imageClassificationOffline: - AppIcons.imageClassificationOfflineWhite, -}; diff --git a/flutter/lib/l10n/app_en.arb b/flutter/lib/l10n/app_en.arb index ab7ff97d5..80c05afa6 100644 --- a/flutter/lib/l10n/app_en.arb +++ b/flutter/lib/l10n/app_en.arb @@ -142,6 +142,7 @@ "historyFilterTitle": "Filters", "historyFilterClear": "Clear Filters", + "historyFilterApply": "Apply Filters", "historyFilterCreationDate": "Creation Date", "historyFilterPlatform": "Platform", "historyFilterBenchmarkID": "Benchmark ID", @@ -150,10 +151,8 @@ "historyFilterManufacturer": "Manufacturer", "historyFilterSoC": "SoC", "historySortBy": "Sort by", - "historySortByDateAsc": "Date: from oldest to most recent", - "historySortByDateDesc": "Date: from most recent to oldest", - "historySortByTaskThroughputDesc": "Task throughput: from highest to lowest", - "historySortByTaskThroughputAsc": "Task throughput: from lowest to highest", + "historySortByDate": "Date", + "historySortByTaskThroughput": "Task Throughput", "historyDetailsTitle": "Result details", "historyDetailsBuildTypeDebug": "debug build", diff --git a/flutter/lib/ui/history/run_details_screen.dart b/flutter/lib/ui/history/benchmark_export_result_screen.dart similarity index 91% rename from flutter/lib/ui/history/run_details_screen.dart rename to flutter/lib/ui/history/benchmark_export_result_screen.dart index ca894f40c..e262434a9 100644 --- a/flutter/lib/ui/history/run_details_screen.dart +++ b/flutter/lib/ui/history/benchmark_export_result_screen.dart @@ -6,16 +6,19 @@ import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/ui/history/utils.dart'; import 'package:mlperfbench/ui/time_utils.dart'; -class RunDetailsScreen extends StatefulWidget { +class BenchmarkExportResultScreen extends StatefulWidget { final BenchmarkExportResult result; - const RunDetailsScreen({Key? key, required this.result}) : super(key: key); + const BenchmarkExportResultScreen({Key? key, required this.result}) + : super(key: key); @override - State createState() => _RunDetailsScreen(); + State createState() => + _BenchmarkExportResultScreenState(); } -class _RunDetailsScreen extends State { +class _BenchmarkExportResultScreenState + extends State { late AppLocalizations l10n; late HistoryHelperUtils helper; diff --git a/flutter/lib/ui/history/result_details_screen.dart b/flutter/lib/ui/history/extended_result_screen.dart similarity index 91% rename from flutter/lib/ui/history/result_details_screen.dart rename to flutter/lib/ui/history/extended_result_screen.dart index 4e141ae2a..255c1895b 100644 --- a/flutter/lib/ui/history/result_details_screen.dart +++ b/flutter/lib/ui/history/extended_result_screen.dart @@ -7,20 +7,21 @@ import 'package:mlperfbench/data/extended_result.dart'; import 'package:mlperfbench/data/results/benchmark_result.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/ui/confirm_dialog.dart'; -import 'package:mlperfbench/ui/history/run_details_screen.dart'; +import 'package:mlperfbench/ui/history/benchmark_export_result_screen.dart'; import 'package:mlperfbench/ui/history/utils.dart'; import 'package:mlperfbench/ui/time_utils.dart'; -class DetailsScreen extends StatefulWidget { +class ExtendedResultScreen extends StatefulWidget { final ExtendedResult result; - const DetailsScreen({Key? key, required this.result}) : super(key: key); + const ExtendedResultScreen({Key? key, required this.result}) + : super(key: key); @override - State createState() => _DetailsScreen(); + State createState() => _ExtendedResultScreenState(); } -class _DetailsScreen extends State { +class _ExtendedResultScreenState extends State { late AppLocalizations l10n; late HistoryHelperUtils helper; late BenchmarkState state; @@ -126,7 +127,7 @@ class _DetailsScreen extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => RunDetailsScreen(result: runInfo), + builder: (context) => BenchmarkExportResultScreen(result: runInfo), ), ); }, diff --git a/flutter/lib/ui/history/result_filter_screen.dart b/flutter/lib/ui/history/history_filter_screen.dart similarity index 95% rename from flutter/lib/ui/history/result_filter_screen.dart rename to flutter/lib/ui/history/history_filter_screen.dart index 82f993be2..94273b355 100644 --- a/flutter/lib/ui/history/result_filter_screen.dart +++ b/flutter/lib/ui/history/history_filter_screen.dart @@ -31,7 +31,10 @@ class _ResultFilterScreenState extends State { return Scaffold( appBar: AppBar( title: Text(l10n.historyFilterTitle), - actions: [_clearFilterButton(state.resourceManager.resultManager)], + actions: [ + _applyFilterButton(), + _clearFilterButton(state.resourceManager.resultManager), + ], ), body: Padding( padding: const EdgeInsets.all(8.0), @@ -187,6 +190,16 @@ class _ResultFilterScreenState extends State { ); } + Widget _applyFilterButton() { + return IconButton( + icon: const Icon(Icons.done), + tooltip: l10n.historyFilterApply, + onPressed: () { + Navigator.pop(context); + }, + ); + } + Widget _clearFilterButton(ResultManager resultManager) { return IconButton( icon: const Icon(Icons.clear), diff --git a/flutter/lib/ui/history/history_list_item.dart b/flutter/lib/ui/history/history_list_item.dart new file mode 100644 index 000000000..b34e81032 --- /dev/null +++ b/flutter/lib/ui/history/history_list_item.dart @@ -0,0 +1,105 @@ +import 'package:flutter/material.dart'; + +import 'package:mlperfbench/app_constants.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; +import 'package:mlperfbench/ui/history/list_item.dart'; +import 'package:mlperfbench/ui/icons.dart'; +import 'package:mlperfbench/ui/time_utils.dart'; + +class HistoryListItem implements ListItem { + final BenchmarkExportResult item; + final void Function()? tapHandler; + + HistoryListItem(this.item, this.tapHandler); + + @override + Widget build(BuildContext context) { + final leadingWidth = 0.08 * MediaQuery.of(context).size.width; + final subtitleWidth = 0.64 * MediaQuery.of(context).size.width; + final trailingWidth = 0.28 * MediaQuery.of(context).size.width; + return ListTile( + contentPadding: const EdgeInsets.fromLTRB(10, 8, 10, 16), + minVerticalPadding: 0, + leading: SizedBox( + width: leadingWidth, + height: leadingWidth, + child: BenchmarkIcons.getDarkIcon(item.benchmarkId), + ), + title: SizedBox( + width: subtitleWidth, + child: Text( + item.benchmarkName, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ), + subtitle: SizedBox( + width: subtitleWidth, + child: Text( + '${itemAdditionalInfo()}\n${itemDateTime()}', + style: const TextStyle(fontWeight: FontWeight.normal, height: 1.4), + ), + ), + trailing: SizedBox( + width: trailingWidth, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Flexible( + flex: 8, + fit: FlexFit.tight, + child: Text( + itemScore(), + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16.0, + color: AppColors.resultValid, + ), + ), + ), + const Flexible( + flex: 2, + fit: FlexFit.tight, + child: Icon(Icons.chevron_right), + ), + ], + )), + onTap: tapHandler, + ); + } + + String itemScore() { + final throughput = item.performanceRun?.throughput; + final accuracy = item.accuracyRun?.accuracy; + var throughputString = 'n/a'; + var accuracyString = 'n/a'; + if (throughput != null) { + throughputString = throughput.toUIString(); + } + if (accuracy != null) { + accuracyString = accuracy.formatted; + } + return '$throughputString\n$accuracyString'; + } + + String itemDateTime() { + final prDateTime = item.performanceRun?.startDatetime; + final arDateTime = item.accuracyRun?.startDatetime; + if (prDateTime != null) { + return formatDateTime(prDateTime); + } else if (arDateTime != null) { + return formatDateTime(arDateTime); + } else { + return 'unknown'; + } + } + + String itemAdditionalInfo() { + final backendName = item.backendInfo.backendName; + final delegateName = item.backendSettings.delegate; + final acceleratorName = item.backendInfo.acceleratorName; + // This matched the UI in ResultScreen._createListOfBenchmarkResultBottomWidgets() + final backendInfo = '$backendName | $delegateName | $acceleratorName'; + return backendInfo; + } +} diff --git a/flutter/lib/ui/history/history_list_screen.dart b/flutter/lib/ui/history/history_list_screen.dart new file mode 100644 index 000000000..e2f066f38 --- /dev/null +++ b/flutter/lib/ui/history/history_list_screen.dart @@ -0,0 +1,155 @@ +import 'package:flutter/material.dart'; + +import 'package:provider/provider.dart'; + +import 'package:mlperfbench/benchmark/state.dart'; +import 'package:mlperfbench/data/benchmarks_data_provider.dart'; +import 'package:mlperfbench/data/result_filter.dart'; +import 'package:mlperfbench/data/result_sort.dart'; +import 'package:mlperfbench/data/results/benchmark_result.dart'; +import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/history/benchmark_export_result_screen.dart'; +import 'package:mlperfbench/ui/history/history_filter_screen.dart'; +import 'package:mlperfbench/ui/history/history_list_item.dart'; +import 'package:mlperfbench/ui/history/list_item.dart'; + +class HistoryListScreen extends StatefulWidget { + const HistoryListScreen({Key? key}) : super(key: key); + + @override + State createState() => _HistoryListScreenState(); +} + +class _HistoryListScreenState extends State { + late AppLocalizations l10n; + + @override + Widget build(BuildContext context) { + final state = context.watch(); + l10n = AppLocalizations.of(context); + final localResults = state.resourceManager.resultManager.localResults; + final remoteResults = state.resourceManager.resultManager.remoteResults; + final filter = state.resourceManager.resultManager.resultFilter; + final sort = state.resourceManager.resultManager.resultSort; + final results = localResults + remoteResults; + final resultsDataProvider = BenchmarksDataProvider(results); + + List resultItems = + resultsDataProvider.resultItems(filter, sort); + + List itemsList = _listItems(resultItems); + + return Scaffold( + appBar: AppBar( + title: Text(l10n.menuHistory), + actions: [ + _sortButton(sort), + _filterButton(filter), + ], + ), + body: ListView.separated( + controller: ScrollController(), + padding: const EdgeInsets.only(top: 20, bottom: 20), + itemCount: itemsList.length, + separatorBuilder: (context, index) => const Divider(), + itemBuilder: (context, index) { + final item = itemsList[index]; + return item.build(context); + }, + ), + ); + } + + PopupMenuButton _sortButton(ResultSort sort) { + return PopupMenuButton( + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context).size.width, + ), + initialValue: sort.sortBy, + onSelected: (SortByEnum item) { + setState(() { + sort.sortBy = item; + }); + }, + icon: const Icon(Icons.sort), + itemBuilder: (context) { + return [ + PopupMenuItem( + value: SortByEnum.dateDesc, + child: ListTile( + contentPadding: const EdgeInsets.fromLTRB(4, 0, 4, 0), + minLeadingWidth: 32, + leading: const Icon(Icons.date_range), + trailing: const Icon(Icons.south), + title: Text(l10n.historySortByDate), + ), + ), + PopupMenuItem( + value: SortByEnum.dateAsc, + child: ListTile( + contentPadding: const EdgeInsets.fromLTRB(4, 0, 4, 0), + minLeadingWidth: 32, + leading: const Icon(Icons.date_range), + trailing: const Icon(Icons.north), + title: Text(l10n.historySortByDate), + ), + ), + const PopupMenuDivider(), + PopupMenuItem( + value: SortByEnum.taskThroughputDesc, + child: ListTile( + contentPadding: const EdgeInsets.fromLTRB(4, 0, 4, 0), + minLeadingWidth: 32, + leading: const Icon(Icons.speed), + trailing: const Icon(Icons.south), + title: Text(l10n.historySortByTaskThroughput), + ), + ), + PopupMenuItem( + value: SortByEnum.taskThroughputAsc, + child: ListTile( + contentPadding: const EdgeInsets.fromLTRB(4, 0, 4, 0), + minLeadingWidth: 32, + leading: const Icon(Icons.speed), + trailing: const Icon(Icons.north), + title: Text(l10n.historySortByTaskThroughput), + ), + ), + ]; + }, + ); + } + + Widget _filterButton(ResultFilter filter) { + return IconButton( + icon: Icon( + filter.anyFilterActive ? Icons.filter_list : Icons.filter_list_off), + tooltip: l10n.historyFilterTitle, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const ResultFilterScreen(), + ), + ).then((value) => setState(() {})); + }, + ); + } + + List _listItems(List resultItems) { + return resultItems.map((resultItem) { + return _benchmarkListItem(resultItem); + }).toList(); + } + + ListItem _benchmarkListItem(BenchmarkExportResult item) { + return HistoryListItem(item, () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => BenchmarkExportResultScreen(result: item), + ), + ).then((value) => setState(() {})); + }); + } +} diff --git a/flutter/lib/ui/history/result_list_item.dart b/flutter/lib/ui/history/result_list_item.dart deleted file mode 100644 index aed746ac7..000000000 --- a/flutter/lib/ui/history/result_list_item.dart +++ /dev/null @@ -1,83 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:mlperfbench/data/extended_result.dart'; -import 'package:mlperfbench/data/results/benchmark_result.dart'; -import 'package:mlperfbench/ui/history/list_item.dart'; -import 'package:mlperfbench/ui/time_utils.dart'; - -class ExtendedResultListItem implements ListItem { - final ExtendedResult item; - final void Function()? tapHandler; - - ExtendedResultListItem(this.item, this.tapHandler); - - @override - Widget build(BuildContext context) { - return ListTile( - title: Text( - formatDateTime(item.meta.creationDate.toLocal()), - style: const TextStyle(fontWeight: FontWeight.bold), - ), - subtitle: Text(item.meta.uuid), - onTap: tapHandler, - ); - } -} - -class BenchmarkListItem implements ListItem { - final BenchmarkExportResult item; - final void Function()? tapHandler; - - BenchmarkListItem(this.item, this.tapHandler); - - @override - Widget build(BuildContext context) => ListTile( - title: Text( - item.benchmarkName, - style: const TextStyle(fontWeight: FontWeight.bold), - ), - subtitle: Text( - '${itemAdditionalInfo()}\n${itemDateTime()}', - style: const TextStyle(fontWeight: FontWeight.normal, height: 1.4), - ), - trailing: Text( - itemScore(), - style: const TextStyle(fontWeight: FontWeight.bold), - ), - isThreeLine: true, - onTap: tapHandler, - ); - - String itemScore() { - final throughput = item.performanceRun?.throughput; - final accuracy = item.accuracyRun?.accuracy; - if (throughput != null) { - return throughput.toUIString(); - } else if (accuracy != null) { - return accuracy.formatted; - } else { - return 'unknown'; - } - } - - String itemDateTime() { - final prDateTime = item.performanceRun?.startDatetime; - final arDateTime = item.accuracyRun?.startDatetime; - if (prDateTime != null) { - return formatDateTime(prDateTime); - } else if (arDateTime != null) { - return formatDateTime(arDateTime); - } else { - return 'unknown'; - } - } - - String itemAdditionalInfo() { - final backendName = item.backendInfo.backendName; - final delegateName = item.backendSettings.delegate; - final acceleratorName = item.backendInfo.acceleratorName; - // This matched the UI in ResultScreen._createListOfBenchmarkResultBottomWidgets() - final backendInfo = '$backendName | $delegateName | $acceleratorName'; - return backendInfo; - } -} diff --git a/flutter/lib/ui/history/result_list_screen.dart b/flutter/lib/ui/history/result_list_screen.dart deleted file mode 100644 index 2540dbb61..000000000 --- a/flutter/lib/ui/history/result_list_screen.dart +++ /dev/null @@ -1,120 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:provider/provider.dart'; - -import 'package:mlperfbench/benchmark/state.dart'; -import 'package:mlperfbench/data/benchmarks_data_provider.dart'; -import 'package:mlperfbench/data/result_sort.dart'; -import 'package:mlperfbench/data/results/benchmark_result.dart'; -import 'package:mlperfbench/localizations/app_localizations.dart'; -import 'package:mlperfbench/ui/history/list_item.dart'; -import 'package:mlperfbench/ui/history/result_filter_screen.dart'; -import 'package:mlperfbench/ui/history/result_list_item.dart'; -import 'package:mlperfbench/ui/history/run_details_screen.dart'; - -class ResultListScreen extends StatefulWidget { - const ResultListScreen({Key? key}) : super(key: key); - - @override - State createState() { - return _ResultListScreenState(); - } -} - -class _ResultListScreenState extends State { - @override - Widget build(BuildContext context) { - final state = context.watch(); - final l10n = AppLocalizations.of(context); - final localResults = state.resourceManager.resultManager.localResults; - final remoteResults = state.resourceManager.resultManager.remoteResults; - final filter = state.resourceManager.resultManager.resultFilter; - final sort = state.resourceManager.resultManager.resultSort; - final results = localResults + remoteResults; - final resultsDataProvider = BenchmarksDataProvider(results); - - List resultItems = - resultsDataProvider.resultItems(filter, sort); - - List itemsList = _listItems(resultItems); - - return Scaffold( - appBar: AppBar(title: Text(l10n.menuHistory), actions: [ - PopupMenuButton( - constraints: BoxConstraints( - maxWidth: MediaQuery.of(context).size.width, - ), - initialValue: sort.sortBy, - onSelected: (SortByEnum item) { - setState(() { - sort.sortBy = item; - }); - }, - icon: const Icon(Icons.sort), - itemBuilder: (context) { - return [ - PopupMenuItem( - value: SortByEnum.dateDesc, - child: Text(l10n.historySortByDateDesc), - ), - PopupMenuItem( - value: SortByEnum.dateAsc, - child: Text(l10n.historySortByDateAsc), - ), - const PopupMenuDivider(), - PopupMenuItem( - value: SortByEnum.taskThroughputDesc, - child: Text(l10n.historySortByTaskThroughputDesc), - ), - PopupMenuItem( - value: SortByEnum.taskThroughputAsc, - child: Text(l10n.historySortByTaskThroughputAsc), - ), - ]; - }, - ), - IconButton( - icon: Icon(filter.anyFilterActive - ? Icons.filter_list - : Icons.filter_list_off), - tooltip: l10n.historyFilterTitle, - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const ResultFilterScreen(), - ), - ).then((value) => setState(() {})); - }, - ) - ]), - body: ListView.separated( - controller: ScrollController(), - padding: const EdgeInsets.only(top: 0, bottom: 0), - itemCount: itemsList.length, - separatorBuilder: (context, index) => const Divider(), - itemBuilder: (context, index) { - final item = itemsList[index]; - return item.build(context); - }, - ), - ); - } - - List _listItems(List resultItems) { - return resultItems.map((resultItem) { - return _benchmarkListItem(resultItem); - }).toList(); - } - - ListItem _benchmarkListItem(BenchmarkExportResult item) { - return BenchmarkListItem(item, () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => RunDetailsScreen(result: item), - ), - ).then((value) => setState(() {})); - }); - } -} diff --git a/flutter/lib/ui/home/app_drawer.dart b/flutter/lib/ui/home/app_drawer.dart index 3854adcbe..b490aab20 100644 --- a/flutter/lib/ui/home/app_drawer.dart +++ b/flutter/lib/ui/home/app_drawer.dart @@ -5,7 +5,7 @@ import 'package:url_launcher/url_launcher.dart'; import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; -import 'package:mlperfbench/ui/history/result_list_screen.dart'; +import 'package:mlperfbench/ui/history/history_list_screen.dart'; import 'package:mlperfbench/ui/home/user_profile.dart'; import 'package:mlperfbench/ui/settings/about_screen.dart'; import 'package:mlperfbench/ui/settings/settings_screen.dart'; @@ -61,7 +61,7 @@ class AppDrawer extends StatelessWidget { Navigator.push( context, MaterialPageRoute( - builder: (context) => const ResultListScreen(), + builder: (context) => const HistoryListScreen(), ), ); }, diff --git a/flutter/lib/ui/home/benchmark_config_screen.dart b/flutter/lib/ui/home/benchmark_config_screen.dart index 4f39fb580..9d3c571cd 100644 --- a/flutter/lib/ui/home/benchmark_config_screen.dart +++ b/flutter/lib/ui/home/benchmark_config_screen.dart @@ -148,6 +148,7 @@ class _BenchmarkConfigScreen extends State { throw 'delegate_selected=$selected must be one of delegate_choice=$choices'; } final dropDownButton = DropdownButton( + borderRadius: BorderRadius.circular(WidgetSizes.borderRadius), underline: const SizedBox(), value: selected, items: choices diff --git a/flutter/lib/ui/icons.dart b/flutter/lib/ui/icons.dart index f72ac2780..078c16d26 100644 --- a/flutter/lib/ui/icons.dart +++ b/flutter/lib/ui/icons.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:mlperfbench/app_constants.dart'; + class AppIcons { static SvgPicture _pSvgWhite(String name) { const colorFilter = ColorFilter.mode(Colors.white, BlendMode.srcIn); @@ -56,3 +58,30 @@ class AppIcons { image: AssetImage('assets/splash.png'), fit: BoxFit.fill); } } + +class BenchmarkIcons { + static final darkSet = { + BenchmarkId.imageClassification: AppIcons.imageClassification, + BenchmarkId.objectDetection: AppIcons.objectDetection, + BenchmarkId.imageSegmentationV2: AppIcons.imageSegmentation, + BenchmarkId.naturalLanguageProcessing: AppIcons.languageProcessing, + BenchmarkId.superResolution: AppIcons.superResolution, + BenchmarkId.imageClassificationOffline: AppIcons.imageClassificationOffline, + }; + + static final lightSet = { + BenchmarkId.imageClassification: AppIcons.imageClassificationWhite, + BenchmarkId.objectDetection: AppIcons.objectDetectionWhite, + BenchmarkId.imageSegmentationV2: AppIcons.imageSegmentationWhite, + BenchmarkId.naturalLanguageProcessing: AppIcons.languageProcessingWhite, + BenchmarkId.superResolution: AppIcons.superResolutionWhite, + BenchmarkId.imageClassificationOffline: + AppIcons.imageClassificationOfflineWhite, + }; + + static Widget getDarkIcon(String benchmarkId) => + darkSet[benchmarkId] ?? AppIcons.logo; + + static Widget getLightIcon(String benchmarkId) => + lightSet[benchmarkId] ?? AppIcons.logo; +} diff --git a/flutter/lib/ui/root/app.dart b/flutter/lib/ui/root/app.dart index 6e2d6f422..091e77368 100644 --- a/flutter/lib/ui/root/app.dart +++ b/flutter/lib/ui/root/app.dart @@ -25,6 +25,11 @@ class MyApp extends StatelessWidget { backgroundColor: AppColors.appBarBackground, iconTheme: IconThemeData(color: AppColors.appBarIcon), ), + popupMenuTheme: PopupMenuThemeData( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(WidgetSizes.borderRadius), + ), + ), ), builder: BotToastInit(), navigatorObservers: [BotToastNavigatorObserver()], diff --git a/flutter/lib/ui/settings/settings_screen.dart b/flutter/lib/ui/settings/settings_screen.dart index f87311eed..426f0fa67 100644 --- a/flutter/lib/ui/settings/settings_screen.dart +++ b/flutter/lib/ui/settings/settings_screen.dart @@ -187,6 +187,7 @@ class _SettingsScreen extends State { ), subtitle: Text(l10n.settingsRunModeSubtitle), trailing: DropdownButton( + borderRadius: BorderRadius.circular(WidgetSizes.borderRadius), value: store.selectedBenchmarkRunMode, items: BenchmarkRunModeEnum.values .map((runMode) => DropdownMenuItem( From 8257dca9b7f30521a9de5bde0de56728c8cd704a Mon Sep 17 00:00:00 2001 From: Anh Date: Tue, 16 Jan 2024 13:19:45 +0700 Subject: [PATCH 11/17] feat: delete linked uploaded results when user is deleted (#835) * Update env-setup-firebase.md * Show user UID in profile screen * Set default display name for Anonymous user. * Refactor user_profile.dart * Show user creation time * Format Markdown files --- docs/environment-setup/env-setup-firebase.md | 12 +- .../lib/firebase/firebase_auth_service.dart | 4 +- flutter/lib/l10n/app_en.arb | 2 + flutter/lib/ui/home/app_drawer.dart | 2 +- flutter/lib/ui/home/share_button.dart | 2 +- flutter/lib/ui/home/user_profile.dart | 127 ++++++++++++++---- 6 files changed, 120 insertions(+), 29 deletions(-) diff --git a/docs/environment-setup/env-setup-firebase.md b/docs/environment-setup/env-setup-firebase.md index 3ddca469f..e3db1e413 100644 --- a/docs/environment-setup/env-setup-firebase.md +++ b/docs/environment-setup/env-setup-firebase.md @@ -1,4 +1,6 @@ -# Firebase setup guide +# Firebase Setup Guide + +## Firebase Authentication and Storage This app is configured to use Firebase for authentication and storage. A Firebase project is required to build the iOS or Android app. @@ -28,7 +30,7 @@ FIREBASE_DATABASE_URL=foo FIREBASE_STORAGE_BUCKET=foo ``` -**Note about Firebase Crashlytics**: +## Firebase Crashlytics By default, we disable the upload of mapping file (in Android build) or debug symbol (dSYM) file in iOS build as described @@ -41,3 +43,9 @@ export FIREBASE_CRASHLYTICS_ENABLED=true ``` That's it! You can now run the app with your own Firebase project. + +## Firebase Extension + +Following Firebase extensions are recommended to use when you set up your own Firebase project: + +* [Delete User Data](https://extensions.dev/extensions/firebase/delete-user-data) diff --git a/flutter/lib/firebase/firebase_auth_service.dart b/flutter/lib/firebase/firebase_auth_service.dart index 9033aef1f..5a9aa5b26 100644 --- a/flutter/lib/firebase/firebase_auth_service.dart +++ b/flutter/lib/firebase/firebase_auth_service.dart @@ -19,7 +19,9 @@ class FirebaseAuthService { Future signInAnonymously() async { final userCredential = await firebaseAuth.signInAnonymously(); - return _getUserFromCredential(userCredential); + final user = await _getUserFromCredential(userCredential); + await user.updateDisplayName('Anonymous'); + return user; } Future signIn({required String email, required String password}) async { diff --git a/flutter/lib/l10n/app_en.arb b/flutter/lib/l10n/app_en.arb index 80c05afa6..b2ff70e87 100644 --- a/flutter/lib/l10n/app_en.arb +++ b/flutter/lib/l10n/app_en.arb @@ -15,6 +15,8 @@ "userSignInAnonymously": "Sign in anonymously", "userSignInEmailPassword": "Sign in with email/password", "userProfile": "User Profile", + "userId": "User ID", + "userCreated": "Created", "unsupportedMainMessage": "This device is not yet supported.", "unsupportedBackendError": "Error message", diff --git a/flutter/lib/ui/home/app_drawer.dart b/flutter/lib/ui/home/app_drawer.dart index b490aab20..55c71209c 100644 --- a/flutter/lib/ui/home/app_drawer.dart +++ b/flutter/lib/ui/home/app_drawer.dart @@ -38,7 +38,7 @@ class AppDrawer extends StatelessWidget { child: ListView( children: [ appTitle, - const UserProfile(), + const UserProfileSection(), ], ), ); diff --git a/flutter/lib/ui/home/share_button.dart b/flutter/lib/ui/home/share_button.dart index 0648a17a5..f85259dd5 100644 --- a/flutter/lib/ui/home/share_button.dart +++ b/flutter/lib/ui/home/share_button.dart @@ -161,7 +161,7 @@ class _ShareButton extends State { const SizedBox(height: 20), Text(l10n.uploadRequiredSignedIn), const SizedBox(height: 20), - const UserProfile(), + const UserProfileSection(), ], ), ); diff --git a/flutter/lib/ui/home/user_profile.dart b/flutter/lib/ui/home/user_profile.dart index 06c43dc08..102281213 100644 --- a/flutter/lib/ui/home/user_profile.dart +++ b/flutter/lib/ui/home/user_profile.dart @@ -7,17 +7,18 @@ import 'package:provider/provider.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/time_utils.dart'; -class UserProfile extends StatefulWidget { - const UserProfile({Key? key}) : super(key: key); +class UserProfileSection extends StatefulWidget { + const UserProfileSection({Key? key}) : super(key: key); @override State createState() { - return _UserProfileState(); + return _UserProfileSectionState(); } } -class _UserProfileState extends State { +class _UserProfileSectionState extends State { late BenchmarkState state; late AppLocalizations l10n; @@ -27,9 +28,9 @@ class _UserProfileState extends State { l10n = AppLocalizations.of(context); final currentUser = FirebaseAuth.instance.currentUser; - final signInWithEmailButton = _buildSignInWithEmailButton(context); - final signInAnonymouslyButton = _buildSignInAnonymouslyButton(context); - final profileButton = _buildProfileButton(context); + final signInWithEmailButton = _buildSignInWithEmailButton(); + final signInAnonymouslyButton = _buildSignInAnonymouslyButton(); + final profileButton = _buildProfileButton(); List children = []; if (currentUser == null) { @@ -52,7 +53,7 @@ class _UserProfileState extends State { ); } - Widget _buildSignInAnonymouslyButton(BuildContext context) { + Widget _buildSignInAnonymouslyButton() { return ElevatedButton( onPressed: () { FirebaseManager.instance.signInAnonymously(); @@ -62,7 +63,7 @@ class _UserProfileState extends State { ); } - Widget _buildSignInWithEmailButton(BuildContext context) { + Widget _buildSignInWithEmailButton() { final resultManager = state.resourceManager.resultManager; final signInScreenActions = [ AuthStateChangeAction((context, state) { @@ -102,28 +103,15 @@ class _UserProfileState extends State { return signInButton; } - Widget _buildProfileButton(BuildContext context) { - final resultManager = state.resourceManager.resultManager; - var profileScreenActions = [ - SignedOutAction((context) { - resultManager.clearRemoteResult(); - Navigator.pop(context); - }) - ]; + Widget _buildProfileButton() { final profileButton = ElevatedButton( onPressed: () { - // FirebaseManager.instance.auth.signOut(); Navigator.pop(context); Navigator.push( context, MaterialPageRoute( builder: (context) { - return Scaffold( - appBar: AppBar(title: Text(l10n.menuProfile)), - body: ProfileScreen( - providers: FirebaseManager.instance.authProviders, - actions: profileScreenActions, - )); + return const UserProfileScreen(); }, ), ); @@ -133,3 +121,94 @@ class _UserProfileState extends State { return profileButton; } } + +class UserProfileScreen extends StatefulWidget { + const UserProfileScreen({Key? key}) : super(key: key); + + @override + State createState() { + return _UserProfileScreenState(); + } +} + +class _UserProfileScreenState extends State { + late AppLocalizations l10n; + late BenchmarkState state; + + @override + Widget build(BuildContext context) { + l10n = AppLocalizations.of(context); + state = context.watch(); + final resultManager = state.resourceManager.resultManager; + var profileScreenActions = [ + SignedOutAction((context) { + resultManager.clearRemoteResult(); + Navigator.pop(context); + }) + ]; + return Scaffold( + appBar: AppBar(title: Text(l10n.menuProfile)), + body: ProfileScreen( + providers: FirebaseManager.instance.authProviders, + actions: profileScreenActions, + children: [ + const Divider(), + const SizedBox(height: 8), + _buildUserInfoSection(), + const SizedBox(height: 8), + const Divider(), + ], + ), + ); + } + + Widget _buildUserInfoSection() { + final currentUser = FirebaseAuth.instance.currentUser; + if (currentUser == null) { + return Text(l10n.unknown); + } + List children = []; + final titleTextStyle = Theme.of(context).textTheme.titleMedium; + final subtitleTextStyle = Theme.of(context) + .textTheme + .titleMedium + ?.copyWith(color: Colors.black.withOpacity(0.6)); + final email = currentUser.email; + if (email != null) { + children.add(Text(email, style: titleTextStyle)); + } + if (currentUser.isAnonymous) { + children.add(Text(l10n.userAnonymousUser, style: titleTextStyle)); + } + children.add(const Divider()); + + final userId = Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(l10n.userId, style: titleTextStyle), + Text(currentUser.uid, style: subtitleTextStyle), + ], + ); + children.add(userId); + + final creationTime = currentUser.metadata.creationTime; + if (creationTime != null) { + final creationTimeRow = Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(l10n.userCreated, style: titleTextStyle), + Text(formatDateTime(creationTime), style: subtitleTextStyle), + ], + ); + children.add(creationTimeRow); + } + + return Wrap( + spacing: 12, + runSpacing: 12, + children: children, + ); + } +} From 15efcffbfd05b071a876da4ad0bc5496292744c9 Mon Sep 17 00:00:00 2001 From: Anh Date: Tue, 23 Jan 2024 13:48:10 +0700 Subject: [PATCH 12/17] ui: new run progress screen (#838) * Move info section in benchmark_start_screen to top * Refactor benchmark_running_screen.dart * Show task list * Update circle content * New progress circle * Show progress circle in task list * Update title based on progress * Update design for cooldown pause * Update aborting phase * Cleanup * Fix animation issue * Fix rendering issue on small screen * Fix integration test --- .github/workflows/ios-tests.yml | 2 +- .../integration_test/expected_throughput.dart | 8 +- flutter/integration_test/utils.dart | 18 +- flutter/lib/app_constants.dart | 2 +- flutter/lib/benchmark/state.dart | 5 + flutter/lib/device_info.dart | 1 + flutter/lib/l10n/app_en.arb | 14 +- flutter/lib/main.dart | 5 +- flutter/lib/state/task_runner.dart | 16 +- ...een.dart => benchmark_config_section.dart} | 96 ++--- .../lib/ui/home/benchmark_result_screen.dart | 12 +- .../lib/ui/home/benchmark_running_screen.dart | 391 +++++++++++++----- .../lib/ui/home/benchmark_start_screen.dart | 118 +++--- .../gradient_circular_progress_indicator.dart | 106 +++++ flutter/lib/ui/home/progress_circles.dart | 105 ++--- flutter/lib/ui/root/main_screen.dart | 2 +- 16 files changed, 562 insertions(+), 339 deletions(-) rename flutter/lib/ui/home/{benchmark_config_screen.dart => benchmark_config_section.dart} (56%) create mode 100644 flutter/lib/ui/home/gradient_circular_progress_indicator.dart diff --git a/.github/workflows/ios-tests.yml b/.github/workflows/ios-tests.yml index a93796c6d..27d135845 100644 --- a/.github/workflows/ios-tests.yml +++ b/.github/workflows/ios-tests.yml @@ -31,7 +31,7 @@ jobs: FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} FIREBASE_CI_USER_EMAIL: ${{ secrets.FIREBASE_CI_USER_EMAIL }} FIREBASE_CI_USER_PASSWORD: ${{ secrets.FIREBASE_CI_USER_PASSWORD }} - FIREBASE_CRASHLYTICS_ENABLED: true + FIREBASE_CRASHLYTICS_ENABLED: false steps: - name: Checkout uses: actions/checkout@v3 diff --git a/flutter/integration_test/expected_throughput.dart b/flutter/integration_test/expected_throughput.dart index e36c88ba7..af87142f1 100644 --- a/flutter/integration_test/expected_throughput.dart +++ b/flutter/integration_test/expected_throughput.dart @@ -65,11 +65,11 @@ const Map> _imageSegmentation = { _kCloudBuildX28: Interval(min: 0.5, max: 4), _kRyzen5600: Interval(min: 5, max: 7), _kPixel5: Interval(min: 25, max: 40), - _kIphoneOnGitHubAction: Interval(min: 0.5, max: 2.5), + _kIphoneOnGitHubAction: Interval(min: 0.4, max: 2.5), _kIphoneOnMacbookM1: Interval(min: 3, max: 6), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 0.5, max: 2.5), + _kIphoneOnGitHubAction: Interval(min: 0.4, max: 2.5), }, _kPixelBackend: { _kPixel6: Interval(min: 100, max: 180), @@ -82,11 +82,11 @@ const Map> _naturalLanguageProcessing = { _kCloudBuildX28: Interval(min: 0.5, max: 1.3), _kRyzen5600: Interval(min: 2.8, max: 3.2), _kPixel5: Interval(min: 2.3, max: 3.0), - _kIphoneOnGitHubAction: Interval(min: 0.3, max: 1), + _kIphoneOnGitHubAction: Interval(min: 0.2, max: 1), _kIphoneOnMacbookM1: Interval(min: 1.8, max: 3), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 0.3, max: 1), + _kIphoneOnGitHubAction: Interval(min: 0.2, max: 1), }, _kPixelBackend: { // pixel some time finish this task in 4 seconds, not sure why. diff --git a/flutter/integration_test/utils.dart b/flutter/integration_test/utils.dart index d78c9faa8..21b78e2dc 100644 --- a/flutter/integration_test/utils.dart +++ b/flutter/integration_test/utils.dart @@ -55,11 +55,11 @@ Future validateSettings(WidgetTester tester) async { } Future runBenchmarks(WidgetTester tester) async { - const downloadTimeLimitMinutes = 20; - const runTimeLimitMinutes = 30; + const downloadTimeout = 20 * 60; // 20 minutes + const runBenchmarkTimeout = 30 * 60; // 30 minutes - var goButtonIsPresented = await waitFor( - tester, downloadTimeLimitMinutes, const Key(WidgetKeys.goButton)); + var goButtonIsPresented = + await waitFor(tester, downloadTimeout, const Key(WidgetKeys.goButton)); expect(goButtonIsPresented, true, reason: 'Problems with downloading of datasets or models'); @@ -67,7 +67,7 @@ Future runBenchmarks(WidgetTester tester) async { await tester.tap(goButton); var totalScoreIsPresented = await waitFor( - tester, runTimeLimitMinutes, const Key(WidgetKeys.totalScoreCircle)); + tester, runBenchmarkTimeout, const Key(WidgetKeys.totalScoreCircle)); expect(totalScoreIsPresented, true, reason: 'Result screen is not presented'); } @@ -80,13 +80,11 @@ Future obtainResult() async { return rm.getLastResult(); } -Future waitFor(WidgetTester tester, int timeLimitMinutes, Key key) async { +Future waitFor(WidgetTester tester, int timeout, Key key) async { var element = false; - for (var counter = 0; - counter < timeLimitMinutes * Duration.secondsPerMinute; - counter++) { - await tester.pumpAndSettle(const Duration(seconds: 1)); + for (var counter = 0; counter < timeout; counter++) { + await tester.pump(const Duration(seconds: 1)); final searchResult = find.byKey(key); if (tester.any(searchResult)) { diff --git a/flutter/lib/app_constants.dart b/flutter/lib/app_constants.dart index 25df61d09..552460d0e 100644 --- a/flutter/lib/app_constants.dart +++ b/flutter/lib/app_constants.dart @@ -27,8 +27,8 @@ class AppColors { static const resultInvalid = Colors.red; static const darkRedText = Colors.red; static const lightBlue = Color(0XFF2C92CB); - static const darkBlue = Color(0xFF0B3A61); static const mediumBlue = Color(0xFF135384); + static const darkBlue = Color(0xFF0B3A61); static const dialogBackground = Colors.white; static const snackBarBackground = Color(0xFFEDEDED); diff --git a/flutter/lib/benchmark/state.dart b/flutter/lib/benchmark/state.dart index 54fd730d6..ab1509d84 100644 --- a/flutter/lib/benchmark/state.dart +++ b/flutter/lib/benchmark/state.dart @@ -310,4 +310,9 @@ class BenchmarkState extends ChangeNotifier { _doneRunning = null; } } + + @override + void notifyListeners() { + super.notifyListeners(); + } } diff --git a/flutter/lib/device_info.dart b/flutter/lib/device_info.dart index 6afd427ad..0d88f41c6 100644 --- a/flutter/lib/device_info.dart +++ b/flutter/lib/device_info.dart @@ -25,6 +25,7 @@ class DeviceInfo { static Future staticInit() async { instance = await createFromEnvironment(); + print('Device: ${instance.envInfo.modelDescription}'); } static Future createFromEnvironment() async { diff --git a/flutter/lib/l10n/app_en.arb b/flutter/lib/l10n/app_en.arb index b2ff70e87..3624f60f0 100644 --- a/flutter/lib/l10n/app_en.arb +++ b/flutter/lib/l10n/app_en.arb @@ -25,13 +25,16 @@ "mainScreenLoading": "Loading Content", "mainScreenGo": "GO", "mainScreenMeasureTitle": "Measure your device performance for:", - "mainScreenWaitFinish": "Wait for benchmark to finish", "mainScreenBenchmarkSelected": "Benchmarks (/ selected)", - "progressMeasuring": "Measuring...", + "progressPerformance": "Performance", + "progressAccuracy": "Accuracy", "progressDontClose": "Don't close the app!", "progressCancel": "Cancel", - "progressCooldown": "Cooldown pause", + "progressCooldown": "Cooldown Pause", + "progressRemainingTime": "Remaining Time", + "progressAborting": "Aborting", + "progressWaiting": "Wait for current benchmark to finish!", "resultsTitleUnverified": "Unverified", "resultsTitlePerformance": "Results (qps)", @@ -118,11 +121,6 @@ "benchInfoLanguageProcessingDesc": "Question Answering finds the best answer to an input question based on a body of text, and is commonly employed in applications such as virtual assistants and chatbots. The reference model, MobileBERT, is evaluated on the Stanford Question Answering Dataset (SQUAD) v1.1 Dev-mini. The task requires a minimum F1-score of 87.4% (93% of FP32 F1-score of 93.08%).\n\nMobileBERT is a streamlined, mobile-optimized version of the larger BERT_LARGE network. It features bottleneck structures and a carefully designed balance between self-attention and feed-forward networks. While BERT is task-agnostic and can be applied to various downstream natural language processing tasks, the MobileBERT variant used in MLPerf is specifically fine-tuned for question answering.", "benchInfoSuperResolutionDesc": "Image Super Resolution (SR) upscales a lower resolution input into a higher resolution output image, enhancing the quality and detail. It is a common task in many mobile applications such as digital zoom. The reference model, EDSR F32B5, is a lightweight member of the Enhanced Deep Super Resolution (EDSR) family that is trained for 2X super resolution on the DIV2K dataset with bicubic downsampling and tested on the OpenSR test-set which comprises 25 selected 1920x1080 HDR images. The benchmark requires a minimum accuracy of 33 dB Peak Signal to Noise Ratio (PSNR) relative to a 33.58 dB accuracy with FP32.\n\nThe EDSR family of models demonstrated excellent performance by winning a super resolution challenge at CVPR 2017. The EDSR F32B5 reference model features five EDSR blocks, each with 32 feature maps. The EDSR block is a simple residual block consisting of a residual connection on one branch and a convolution-ReLU-convolution on the other branch. The final upsampling layer is a depth-to-space operator, which facilitates the x2 super resolution process.", - "progressScreenNamePerformance": " (performance)", - "progressScreenNameAccuracy": " (accuracy)", - "progressScreenStage": "Stage progress: %", - "progressScreenCooldown": "Remaining time: ", - "resourceErrorMessage": "Some resources failed to load.\nIf you didn't change config from default you can try clearing the cache.\nIf you use a custom configuration file ensure that it has correct structure or switch back to default config.", "resourceErrorSelectTaskFile": "Update task configuration", "resourceErrorCurrentConfig": "Current task config file: ", diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index fd631ec50..e5d857173 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; +import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/backend/unsupported_device_exception.dart'; import 'package:mlperfbench/benchmark/run_mode.dart'; import 'package:mlperfbench/benchmark/state.dart'; @@ -39,7 +40,9 @@ Future launchUi() async { final benchmarkState = await BenchmarkState.create(store); if (FirebaseManager.enabled) { await FirebaseManager.instance.initialize(); - FirebaseManager.instance.configureCrashlytics(store.crashlyticsEnabled); + if (DartDefine.firebaseCrashlyticsEnabled && store.crashlyticsEnabled) { + FirebaseManager.instance.configureCrashlytics(true); + } } if (const bool.fromEnvironment('autostart', defaultValue: false)) { assert(const bool.hasEnvironment('resultsStringMark')); diff --git a/flutter/lib/state/task_runner.dart b/flutter/lib/state/task_runner.dart index 8e034aba9..653e47940 100644 --- a/flutter/lib/state/task_runner.dart +++ b/flutter/lib/state/task_runner.dart @@ -28,7 +28,10 @@ import 'package:mlperfbench/store.dart'; class ProgressInfo { bool cooldown = false; bool accuracy = false; - BenchmarkInfo? info; + BenchmarkInfo? currentBenchmark; + List completedBenchmarks = []; + List activeBenchmarks = []; + late BenchmarkRunModeEnum runMode; int totalStages = 0; int currentStage = 0; double cooldownDuration = 0; @@ -45,7 +48,7 @@ class TaskRunner { final BridgeIsolate backendBridge; final BackendInfo backendInfo; - ProgressInfo progressInfo = ProgressInfo(); + late ProgressInfo progressInfo; bool aborting = false; CancelableOperation? _cooldownOperation; @@ -90,6 +93,7 @@ class TaskRunner { Future runBenchmarks( BenchmarkStore benchmarkStore, String currentLogDir) async { + progressInfo = ProgressInfo(); final cooldown = store.cooldown; late final Duration cooldownDuration; if (store.testMode) { @@ -105,6 +109,7 @@ class TaskRunner { final resultHelpers = []; for (final benchmark in activeBenchmarks) { + progressInfo.activeBenchmarks.add(benchmark.info); final resultHelper = ResultHelper( benchmark: benchmark, backendInfo: backendInfo, @@ -113,6 +118,7 @@ class TaskRunner { resultHelpers.add(resultHelper); } + progressInfo.runMode = store.selectedBenchmarkRunMode; switch (store.selectedBenchmarkRunMode) { case BenchmarkRunModeEnum.performanceOnly: progressInfo.totalStages = activeBenchmarks.length; @@ -131,6 +137,7 @@ class TaskRunner { var first = true; // run all benchmarks in performance mode first + progressInfo.completedBenchmarks.clear(); for (final benchmark in activeBenchmarks) { if (aborting) break; if (!store.selectedBenchmarkRunMode.doPerformanceRun) break; @@ -156,6 +163,7 @@ class TaskRunner { } // then in accuracy mode + progressInfo.completedBenchmarks.clear(); for (final benchmark in activeBenchmarks) { if (aborting) break; if (!store.selectedBenchmarkRunMode.doAccuracyRun) break; @@ -186,7 +194,7 @@ class TaskRunner { Future runBenchmark(ResultHelper resultHelper, BenchmarkRunMode mode, String currentLogDir) async { final benchmark = resultHelper.benchmark; - progressInfo.info = benchmark.info; + progressInfo.currentBenchmark = benchmark.info; progressInfo.currentStage++; if (mode == perfMode) { @@ -275,6 +283,8 @@ class TaskRunner { } else { throw 'Unknown BenchmarkRunMode: $mode'; } + progressInfo.completedBenchmarks.add(benchmark.info); + progressInfo.currentBenchmark = null; } } diff --git a/flutter/lib/ui/home/benchmark_config_screen.dart b/flutter/lib/ui/home/benchmark_config_section.dart similarity index 56% rename from flutter/lib/ui/home/benchmark_config_screen.dart rename to flutter/lib/ui/home/benchmark_config_section.dart index 9d3c571cd..1d82fa7e7 100644 --- a/flutter/lib/ui/home/benchmark_config_screen.dart +++ b/flutter/lib/ui/home/benchmark_config_section.dart @@ -9,14 +9,14 @@ import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/ui/home/benchmark_info_button.dart'; -class BenchmarkConfigScreen extends StatefulWidget { - const BenchmarkConfigScreen({Key? key}) : super(key: key); +class BenchmarkConfigSection extends StatefulWidget { + const BenchmarkConfigSection({Key? key}) : super(key: key); @override - State createState() => _BenchmarkConfigScreen(); + State createState() => _BenchmarkConfigSectionState(); } -class _BenchmarkConfigScreen extends State { +class _BenchmarkConfigSectionState extends State { late BenchmarkState state; late AppLocalizations l10n; @@ -37,44 +37,19 @@ class _BenchmarkConfigScreen extends State { childrenList.add(const Divider(height: 20)); } - return Scaffold( - backgroundColor: Colors.transparent, - appBar: PreferredSize( - preferredSize: const Size.fromHeight(32.0), - child: AppBar( - shape: Border.all(color: AppColors.darkBlue), - backgroundColor: AppColors.darkBlue, - elevation: 0, - title: _header(), - ), - ), - body: Container( - color: Colors.white, - child: ListView( - padding: const EdgeInsets.fromLTRB(0, 20, 0, 20), - children: childrenList, - ), + return Container( + color: Colors.white, + child: ListView( + padding: const EdgeInsets.fromLTRB(0, 20, 0, 20), + children: childrenList, ), ); } - Widget _header() { - final selectedCount = - state.benchmarks.where((e) => e.isActive).length.toString(); - final totalCount = state.benchmarks.length.toString(); - final title = l10n.mainScreenBenchmarkSelected - .replaceAll('', selectedCount) - .replaceAll('', totalCount); - return Text(title, - style: Theme.of(context).textTheme.titleSmall!.copyWith( - color: Theme.of(context).colorScheme.onPrimary, - )); - } - Widget _listTile(Benchmark benchmark) { - final leadingWidth = 0.12 * MediaQuery.of(context).size.width; + final leadingWidth = 0.10 * MediaQuery.of(context).size.width; final subtitleWidth = 0.70 * MediaQuery.of(context).size.width; - final trailingWidth = 0.28 * MediaQuery.of(context).size.width; + final trailingWidth = 0.20 * MediaQuery.of(context).size.width; return ListTile( leading: SizedBox( width: leadingWidth, @@ -98,8 +73,8 @@ class _BenchmarkConfigScreen extends State { mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ - _activeToggle(benchmark), - _infoButton(benchmark), + Expanded(flex: 2, child: _activeToggle(benchmark)), + Expanded(flex: 1, child: _infoButton(benchmark)), ], ), ), @@ -113,7 +88,10 @@ class _BenchmarkConfigScreen extends State { Widget _backendDescription(Benchmark benchmark) { return Padding( padding: const EdgeInsets.only(top: 8), - child: Text(benchmark.backendRequestDescription), + child: Text( + benchmark.backendRequestDescription, + style: Theme.of(context).textTheme.labelLarge, + ), ); } @@ -123,6 +101,7 @@ class _BenchmarkConfigScreen extends State { onChanged: (flag) { setState(() { benchmark.isActive = flag; + state.notifyListeners(); }); }, ); @@ -147,27 +126,24 @@ class _BenchmarkConfigScreen extends State { if (!choices.contains(selected)) { throw 'delegate_selected=$selected must be one of delegate_choice=$choices'; } - final dropDownButton = DropdownButton( - borderRadius: BorderRadius.circular(WidgetSizes.borderRadius), - underline: const SizedBox(), - value: selected, - items: choices - .map((item) => DropdownMenuItem( - value: item, - child: Text(item), - )) - .toList(), - onChanged: (value) => setState(() { - benchmark.benchmarkSettings.delegateSelected = value!; - })); - return Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Text('Delegate:'), - const SizedBox(width: 4), - dropDownButton, - ], + return DropdownButton( + isExpanded: true, + isDense: false, + borderRadius: BorderRadius.circular(WidgetSizes.borderRadius), + underline: const SizedBox(), + value: selected, + items: choices + .map((item) => DropdownMenuItem( + value: item, + child: Text( + 'Delegate: $item', + style: Theme.of(context).textTheme.labelLarge, + ), + )) + .toList(), + onChanged: (value) => setState(() { + benchmark.benchmarkSettings.delegateSelected = value!; + }), ); } } diff --git a/flutter/lib/ui/home/benchmark_result_screen.dart b/flutter/lib/ui/home/benchmark_result_screen.dart index 475b0a2c3..216682f1c 100644 --- a/flutter/lib/ui/home/benchmark_result_screen.dart +++ b/flutter/lib/ui/home/benchmark_result_screen.dart @@ -76,6 +76,7 @@ class _BenchmarkResultScreenState extends State preferredSize: const Size.fromHeight(56.0), child: _sharingSection(), ), + backgroundColor: AppColors.lightBlue, ), drawer: const AppDrawer(), body: LayoutBuilder( @@ -105,7 +106,7 @@ class _BenchmarkResultScreenState extends State benchmarkDateText = Text(formatDateTime(lastResult.meta.creationDate)); } else { deviceInfoText = Text(DeviceInfo.instance.envInfo.modelDescription); - benchmarkDateText = const Text(''); + benchmarkDateText = Text(l10n.na); } final infoSection = Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -149,11 +150,10 @@ class _BenchmarkResultScreenState extends State mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center, children: [ - infoSection, - const Spacer(), - testAgainButton, - deleteResultButton, - const ShareButton() + Expanded(flex: 70, child: infoSection), + Expanded(flex: 10, child: testAgainButton), + Expanded(flex: 10, child: deleteResultButton), + const Expanded(flex: 10, child: ShareButton()), ], ), ), diff --git a/flutter/lib/ui/home/benchmark_running_screen.dart b/flutter/lib/ui/home/benchmark_running_screen.dart index cf5e83847..d63b0150b 100644 --- a/flutter/lib/ui/home/benchmark_running_screen.dart +++ b/flutter/lib/ui/home/benchmark_running_screen.dart @@ -1,13 +1,19 @@ import 'dart:async'; +import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:collection/collection.dart'; import 'package:provider/provider.dart'; import 'package:mlperfbench/app_constants.dart'; +import 'package:mlperfbench/benchmark/info.dart'; +import 'package:mlperfbench/benchmark/run_mode.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/state/task_runner.dart'; import 'package:mlperfbench/ui/home/progress_circles.dart'; +import 'package:mlperfbench/ui/icons.dart'; import 'package:mlperfbench/ui/time_utils.dart'; class BenchmarkRunningScreen extends StatefulWidget { @@ -21,14 +27,15 @@ class BenchmarkRunningScreen extends StatefulWidget { } class _BenchmarkRunningScreenState extends State { - static const double progressCircleEdgeSize = 150; - late final Timer _timer; + late BenchmarkState state; + late AppLocalizations l10n; + late ProgressInfo progress; @override Widget build(BuildContext context) { - final state = context.watch(); - final l10n = AppLocalizations.of(context); - final progress = state.taskRunner.progressInfo; + state = context.watch(); + l10n = AppLocalizations.of(context); + progress = state.taskRunner.progressInfo; final backgroundGradient = BoxDecoration( gradient: LinearGradient( @@ -37,114 +44,243 @@ class _BenchmarkRunningScreenState extends State { end: Alignment.bottomCenter, ), ); - final title = Padding( - padding: const EdgeInsets.fromLTRB(40, 80, 20, 40), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - l10n.progressMeasuring, - style: const TextStyle( - fontWeight: FontWeight.bold, - color: AppColors.lightText, - fontSize: 30, + + return Scaffold( + key: BenchmarkRunningScreen.scaffoldKey, + body: Container( + decoration: backgroundGradient, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded(flex: 14, child: _title()), + const SizedBox(height: 20), + Expanded(flex: 30, child: _circle()), + const SizedBox(height: 20), + Expanded(flex: 40, child: _taskList()), + const SizedBox(height: 20), + Expanded(flex: 16, child: _footer()), + ], + ), + ), + ); + } + + Widget _title() { + // The TaskRunner always run all benchmarks in performance mode first then in accuracy mode. + var runModeStage = '1/1'; + if (progress.runMode == BenchmarkRunModeEnum.submissionRun) { + runModeStage = progress.accuracy ? '2/2' : '1/2'; + } + var runModeName = + progress.accuracy ? l10n.progressAccuracy : l10n.progressPerformance; + return Padding( + padding: const EdgeInsets.fromLTRB(40, 48, 40, 4), + child: Text( + '($runModeStage) $runModeName', + style: const TextStyle( + fontWeight: FontWeight.w500, + color: AppColors.lightText, + fontSize: 20, + ), + )); + } + + Widget _circle() { + var containerWidth = 0.50 * MediaQuery.of(context).size.width; + containerWidth = max(containerWidth, 160); + containerWidth = min(containerWidth, 240); + return Stack( + alignment: AlignmentDirectional.center, + children: [ + Container( + width: containerWidth, + height: containerWidth, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + colors: AppColors.progressCircleGradient, + begin: Alignment.topCenter, + end: Alignment.bottomCenter, ), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + offset: Offset(15, 15), + blurRadius: 10, + ) + ], ), - Text( - l10n.progressDontClose, - style: const TextStyle( - color: AppColors.lightText, - fontSize: 17, + child: ClipOval( + child: Padding( + padding: const EdgeInsets.all(4), + child: _circleContent(), ), ), - ], - ), + ), + InfiniteProgressCircle( + size: containerWidth + 20, + strokeWidth: 6.0, + ), + ], ); - final circle = Stack( - alignment: AlignmentDirectional.centerStart, - children: [ - Center( + } + + Widget _circleContent() { + Widget? topWidget; + String taskNameString; + const textStyle = TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: AppColors.lightText, + ); + if (progress.cooldown) { + topWidget = Text( + l10n.progressCooldown, + textAlign: TextAlign.center, + style: textStyle, + ); + taskNameString = l10n.progressRemainingTime; + } else { + topWidget = SizedBox( + width: 32, + height: 32, + child: progress.currentBenchmark!.iconWhite, + ); + taskNameString = progress.currentBenchmark!.taskName; + } + + return Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Expanded( + flex: 3, child: Container( - width: progressCircleEdgeSize, - height: progressCircleEdgeSize, - decoration: BoxDecoration( - shape: BoxShape.circle, - gradient: LinearGradient( - colors: AppColors.progressCircleGradient, - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - boxShadow: const [ - BoxShadow( - color: Colors.black12, - offset: Offset(15, 15), - blurRadius: 10, - ) - ], - ), - child: Center( - child: Text( - '${progress.currentStage.toString()}/${progress.totalStages.toString()}', - style: const TextStyle( - fontWeight: FontWeight.bold, - color: AppColors.lightText, - ), - textScaleFactor: 3, - ), - ), + alignment: Alignment.bottomCenter, + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 40), + child: topWidget, + ), + ), + Expanded( + flex: 4, + child: Container( + alignment: Alignment.center, + child: _StageProgressText(), ), ), - const Center( - child: ProgressCircles( - Size(progressCircleEdgeSize + 40, progressCircleEdgeSize + 40), + Expanded( + flex: 3, + child: Container( + alignment: Alignment.topCenter, + padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 20), + child: Text( + taskNameString, + textAlign: TextAlign.center, + style: textStyle, + ), ), ), ], ); - final namedIcon = Column(children: [ - Padding( - padding: const EdgeInsets.fromLTRB(20, 10, 20, 20), - child: SizedBox( - width: 100, - height: 100, - child: progress.cooldown ? null : progress.info!.iconWhite, - ), + } + + Widget _taskList() { + final childrenList = []; + progress.activeBenchmarks.forEachIndexed((idx, benchmark) { + childrenList.add(_listTile(benchmark, idx % 2 == 0)); + }); + return Material( + type: MaterialType.transparency, + child: ListView( + shrinkWrap: true, + children: childrenList, ), - Padding( - padding: const EdgeInsets.fromLTRB(20, 10, 20, 10), + ); + } + + Widget _listTile(BenchmarkInfo benchmarkInfo, bool isEven) { + final leadingWidth = 0.16 * MediaQuery.of(context).size.width; + final titleWidth = 0.60 * MediaQuery.of(context).size.width; + const trailingWidth = 24.0; + Widget? doneIcon; + if (progress.currentBenchmark?.taskName == benchmarkInfo.taskName) { + doneIcon = const InfiniteProgressCircle( + size: trailingWidth, + strokeWidth: 2, + ); + } else if (progress.completedBenchmarks.contains(benchmarkInfo)) { + doneIcon = const Icon( + Icons.check_circle, + size: trailingWidth, + color: Colors.green, + ); + } + return ListTile( + contentPadding: const EdgeInsets.symmetric(vertical: 0, horizontal: 32), + tileColor: isEven ? AppColors.mediumBlue : Colors.transparent, + textColor: AppColors.lightText, + dense: true, + minVerticalPadding: 0, + leading: SizedBox( + width: leadingWidth * 0.4, + height: leadingWidth * 0.4, + child: benchmarkInfo.iconWhite), + title: SizedBox( + width: titleWidth, child: Text( - progress.cooldown - ? l10n.progressCooldown - : (progress.accuracy - ? l10n.progressScreenNameAccuracy - : l10n.progressScreenNamePerformance) - .replaceFirst('', progress.info!.taskName), + benchmarkInfo.taskName, style: const TextStyle( + fontSize: 14, fontWeight: FontWeight.bold, - color: AppColors.lightText, ), ), ), - Text( - progress.cooldown - ? l10n.progressScreenCooldown.replaceAll( - '', - formatDuration( - progress.cooldownDuration * (1.0 - progress.stageProgress))) - : l10n.progressScreenStage.replaceFirst( - '', - (progress.stageProgress * 100) - .round() - .clamp(0, 100) - .toString()), - style: const TextStyle( - fontWeight: FontWeight.bold, + trailing: SizedBox( + width: trailingWidth, + height: trailingWidth, + child: doneIcon, + ), + ); + } + + Widget _footer() { + if (state.state == BenchmarkStateEnum.aborting) { + return _abortingHint(); + } else { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded(flex: 4, child: _footerText()), + Expanded(flex: 6, child: _cancelButton()), + ], + ); + } + } + + Widget _footerText() { + return Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + const Icon( + Icons.warning, color: AppColors.lightText, ), - ), - ]); - final cancelButton = Padding( + const SizedBox(width: 8), + Text( + l10n.progressDontClose, + style: const TextStyle( + color: AppColors.lightText, + fontSize: 17, + ), + ) + ], + ); + } + + Widget _cancelButton() { + return Padding( padding: const EdgeInsets.fromLTRB(20, 10, 20, 20), child: TextButton( style: ButtonStyle( @@ -170,27 +306,55 @@ class _BenchmarkRunningScreenState extends State { ), ), ); + } - return Scaffold( - key: BenchmarkRunningScreen.scaffoldKey, - body: Container( - decoration: backgroundGradient, - child: Column( + Widget _abortingHint() { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - title, - circle, - namedIcon, - cancelButton, + Container( + width: 18, + alignment: Alignment.center, + child: AppIcons.waiting, + ), + const SizedBox(width: 8), + Text( + l10n.progressAborting, + style: const TextStyle( + fontSize: 18, + color: AppColors.lightText, + ), + ) ], ), - ), + Text( + l10n.progressWaiting, + style: const TextStyle( + fontSize: 14, + color: AppColors.lightText, + ), + ), + ], ); } +} + +class _StageProgressText extends StatefulWidget { + @override + _StageProgressTextState createState() => _StageProgressTextState(); +} + +class _StageProgressTextState extends State<_StageProgressText> { + late final Timer _timer; @override void initState() { + // UI should update every 1 second to refresh stageProgress _timer = Timer.periodic(const Duration(seconds: 1), (_) => setState(() {})); super.initState(); } @@ -200,4 +364,25 @@ class _BenchmarkRunningScreenState extends State { _timer.cancel(); super.dispose(); } + + @override + Widget build(BuildContext context) { + final state = context.watch(); + final progress = state.taskRunner.progressInfo; + String progressStr; + if (progress.cooldown) { + progressStr = formatDuration( + progress.cooldownDuration * (1.0 - progress.stageProgress)); + } else { + progressStr = '${(progress.stageProgress * 100).round().clamp(0, 100)}%'; + } + return Text( + progressStr, + style: const TextStyle( + fontSize: 54, + fontWeight: FontWeight.bold, + color: AppColors.lightText, + ), + ); + } } diff --git a/flutter/lib/ui/home/benchmark_start_screen.dart b/flutter/lib/ui/home/benchmark_start_screen.dart index 8128dff6e..ba58eedd6 100644 --- a/flutter/lib/ui/home/benchmark_start_screen.dart +++ b/flutter/lib/ui/home/benchmark_start_screen.dart @@ -4,26 +4,38 @@ import 'package:provider/provider.dart'; import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/state.dart'; +import 'package:mlperfbench/device_info.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/store.dart'; import 'package:mlperfbench/ui/confirm_dialog.dart'; import 'package:mlperfbench/ui/error_dialog.dart'; import 'package:mlperfbench/ui/home/app_drawer.dart'; -import 'package:mlperfbench/ui/home/benchmark_config_screen.dart'; +import 'package:mlperfbench/ui/home/benchmark_config_section.dart'; import 'package:mlperfbench/ui/home/shared_styles.dart'; -import 'package:mlperfbench/ui/icons.dart'; -class BenchmarkStartScreen extends StatelessWidget { +class BenchmarkStartScreen extends StatefulWidget { const BenchmarkStartScreen({Key? key}) : super(key: key); + @override + State createState() => _BenchmarkStartScreenState(); +} + +class _BenchmarkStartScreenState extends State { + late BenchmarkState state; + late Store store; + late AppLocalizations l10n; + @override Widget build(BuildContext context) { - final state = context.watch(); - final l10n = AppLocalizations.of(context); + state = context.watch(); + store = context.watch(); + l10n = AppLocalizations.of(context); return Scaffold( - backgroundColor: AppColors.darkBlue, - appBar: AppBar(title: Text(l10n.menuHome)), + appBar: AppBar( + title: Text(l10n.menuHome), + backgroundColor: AppColors.lightBlue, + ), drawer: const AppDrawer(), body: SafeArea( child: Column( @@ -31,16 +43,20 @@ class BenchmarkStartScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( - flex: 35, - child: _getTopContainer(context, state.state), + flex: 32, + child: _goButtonSection(context), + ), + Expanded( + flex: 8, + child: _infoSection(), ), Expanded( - flex: 65, + flex: 60, child: Align( alignment: Alignment.topCenter, child: AbsorbPointer( absorbing: state.state != BenchmarkStateEnum.waiting, - child: const BenchmarkConfigScreen(), + child: const BenchmarkConfigSection(), ), ), ) @@ -50,68 +66,34 @@ class BenchmarkStartScreen extends StatelessWidget { ); } - Widget _getTopContainer(BuildContext context, BenchmarkStateEnum state) { - if (state == BenchmarkStateEnum.aborting) { - return _waitContainer(context); - } else if (state == BenchmarkStateEnum.waiting) { - return _goContainer(context); - } else { - throw 'Unknown BenchmarkState: ${state.name}'; - } - } - - Widget _waitContainer(BuildContext context) { - final l10n = AppLocalizations.of(context); - final circleWidth = - MediaQuery.of(context).size.width * WidgetSizes.circleWidthFactor; - - return Stack( - alignment: Alignment.topCenter, - children: [ - Container( - width: MediaQuery.of(context).size.width, - alignment: Alignment.center, - decoration: mainLinearGradientDecoration, - ), - Padding( - padding: const EdgeInsets.all(20), - child: Text( - l10n.mainScreenWaitFinish, - style: const TextStyle(color: AppColors.lightText, fontSize: 15), - ), - ), - Stack( + Widget _infoSection() { + final selectedCount = + state.benchmarks.where((e) => e.isActive).length.toString(); + final totalCount = state.benchmarks.length.toString(); + final selectedBenchmarkText = l10n.mainScreenBenchmarkSelected + .replaceAll('', selectedCount) + .replaceAll('', totalCount); + var deviceDescription = DeviceInfo.instance.envInfo.modelDescription; + return Container( + padding: const EdgeInsets.fromLTRB(20, 8, 10, 8), + width: double.infinity, + color: AppColors.mediumBlue, + child: DefaultTextStyle.merge( + style: const TextStyle(color: Colors.white, fontSize: 14), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Container( - width: circleWidth, - alignment: Alignment.center, - decoration: const BoxDecoration( - shape: BoxShape.circle, - color: AppColors.progressCircle, - boxShadow: [ - BoxShadow( - color: Colors.black12, - offset: Offset(15, 15), - blurRadius: 10, - ) - ], - ), - ), - Container( - width: circleWidth, - alignment: Alignment.center, - child: AppIcons.waiting, - ) + Expanded(flex: 1, child: Text(deviceDescription)), + const SizedBox(height: 4), + Expanded(flex: 1, child: Text(selectedBenchmarkText)) ], - ) - ], + ), + ), ); } - Widget _goContainer(BuildContext context) { - final state = context.watch(); - final store = context.watch(); - final l10n = AppLocalizations.of(context); + Widget _goButtonSection(BuildContext context) { final circleWidth = MediaQuery.of(context).size.width * WidgetSizes.circleWidthFactor; diff --git a/flutter/lib/ui/home/gradient_circular_progress_indicator.dart b/flutter/lib/ui/home/gradient_circular_progress_indicator.dart new file mode 100644 index 000000000..9fa879ce4 --- /dev/null +++ b/flutter/lib/ui/home/gradient_circular_progress_indicator.dart @@ -0,0 +1,106 @@ +// Source: https://github.com/mryadavdilip/gradient_circular_progress_indicator/blob/e3621c0744bd1b88b00ae4e6a6068c8197789ef6/lib/gradient_circular_progress_indicator.dart + +import 'dart:math'; + +import 'package:flutter/material.dart'; + +class GradientCircularProgressIndicator extends StatelessWidget { + /// progress value between or equal to 0 and 1 (0 <= progress <= 1) + final double progress; + final Gradient gradient; + + /// default background Colors.transparent + final Color? backgroundColor; + + /// default stroke is (size of child divided by 10) + final double? stroke; + + /// default size is size of child + final double? size; + final Widget? child; + + const GradientCircularProgressIndicator({ + super.key, + required this.progress, + required this.gradient, + this.backgroundColor, + this.stroke, + this.size, + this.child, + }); + + @override + Widget build(BuildContext context) { + return CustomPaint( + size: size != null ? Size(size!, size!) : MediaQuery.of(context).size, + painter: _GradientCircularProgressPainter( + progress: progress, + gradient: gradient, + backgroundColor: backgroundColor ?? Colors.transparent, + stroke: stroke), + child: SizedBox( + height: size, + width: size, + child: child, + ), + ); + } +} + +class _GradientCircularProgressPainter extends CustomPainter { + final double progress; + final Gradient gradient; + final Color backgroundColor; // New parameter for background color + final double? stroke; + + _GradientCircularProgressPainter({ + required this.progress, + required this.gradient, + required this.backgroundColor, + this.stroke, + }); + + @override + void paint(Canvas canvas, Size size) { + final center = Offset(size.width / 2, size.height / 2); + final radius = size.width / 2; + const startAngle = -pi / 2; + const fullSweepAngle = 2 * pi; + final progressSweepAngle = 2 * pi * progress; + + final backgroundPaint = Paint() + ..color = backgroundColor // Set the background color + ..style = PaintingStyle.stroke + ..strokeWidth = stroke ?? size.width / 10; + + final gradientPaint = Paint() + ..shader = + gradient.createShader(Rect.fromCircle(center: center, radius: radius)) + ..strokeCap = StrokeCap.round + ..style = PaintingStyle.stroke + ..strokeWidth = stroke ?? size.width / 10; + + // Draw the background arc + canvas.drawArc( + Rect.fromCircle(center: center, radius: radius), + startAngle + progressSweepAngle, + fullSweepAngle - progressSweepAngle, + false, + backgroundPaint, + ); + + // Draw the gradient arc + canvas.drawArc( + Rect.fromCircle(center: center, radius: radius), + startAngle, + progressSweepAngle, + false, + gradientPaint, + ); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + return true; + } +} diff --git a/flutter/lib/ui/home/progress_circles.dart b/flutter/lib/ui/home/progress_circles.dart index b3f658bac..b22a86d7b 100644 --- a/flutter/lib/ui/home/progress_circles.dart +++ b/flutter/lib/ui/home/progress_circles.dart @@ -1,95 +1,54 @@ -import 'dart:async'; -import 'dart:math'; - import 'package:flutter/material.dart'; -class ProgressCircles extends StatefulWidget { - final Size _size; +import 'package:mlperfbench/ui/home/gradient_circular_progress_indicator.dart'; + +class InfiniteProgressCircle extends StatefulWidget { + final double size; + final double strokeWidth; - const ProgressCircles(this._size, {Key? key}) : super(key: key); + const InfiniteProgressCircle( + {Key? key, required this.size, required this.strokeWidth}) + : super(key: key); @override - State createState() => _ProgressCirclesState(); + State createState() => _InfiniteProgressCircleState(); } -class _ProgressCirclesState extends State { - static const circlesCount = 10; - - late final Timer _timer; - - bool _increase = true; - int _startCircleNumber = 0; - int _endCircleNumber = 1; - - void _updateState() { - if (_increase) { - if (_startCircleNumber == circlesCount) { - _startCircleNumber = 0; - _endCircleNumber = 1; - } else { - _endCircleNumber++; - } - - if (_endCircleNumber == circlesCount) { - _increase = false; - } - } else { - _startCircleNumber++; - - if (_startCircleNumber == circlesCount) { - _increase = true; - } - } - } +class _InfiniteProgressCircleState extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; @override void initState() { - _timer = Timer.periodic( - const Duration(seconds: 1), - (_) => setState(_updateState), - ); + _controller = + AnimationController(vsync: this, duration: const Duration(seconds: 2)); + _controller.addListener(() => setState(() {})); + _controller.repeat(); super.initState(); } @override void dispose() { - _timer.cancel(); + _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { - return CustomPaint( - size: widget._size, - painter: _ProgressCirclesPaint(_startCircleNumber, _endCircleNumber)); + return RotationTransition( + turns: Tween(begin: 0.0, end: 1.0).animate(_controller), + child: GradientCircularProgressIndicator( + progress: 1.0, + // Specify the progress value between 0 and 1 + gradient: const LinearGradient( + colors: [Colors.white, Colors.white, Colors.white10, Colors.white10], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + backgroundColor: Colors.transparent, + stroke: widget.strokeWidth, + size: widget.size, + ), + ); } } - -class _ProgressCirclesPaint extends CustomPainter { - final int _startCircleNumber; - final int _endCircleNumber; - - _ProgressCirclesPaint(this._startCircleNumber, this._endCircleNumber); - - final double circleRadius = 10; - final Paint _paintLine = Paint() - ..color = Colors.white - ..style = PaintingStyle.fill; - final double pi = 3.1415926535897932; - - @override - void paint(Canvas canvas, Size size) { - for (var i = _startCircleNumber; i < _endCircleNumber; i++) { - final currentDegree = - 2 * pi * ((i) / _ProgressCirclesState.circlesCount) + pi / 2; - final x = (size.width + size.height * cos(currentDegree)) / 2; - final y = (size.height + size.width * sin(currentDegree)) / 2; - canvas.drawCircle(Offset(x, y), circleRadius, _paintLine); - } - } // paint - - @override - bool shouldRepaint(_ProgressCirclesPaint old) => - old._endCircleNumber != _endCircleNumber || - old._startCircleNumber != _startCircleNumber; -} diff --git a/flutter/lib/ui/root/main_screen.dart b/flutter/lib/ui/root/main_screen.dart index 5f95d6acd..565fc5a15 100644 --- a/flutter/lib/ui/root/main_screen.dart +++ b/flutter/lib/ui/root/main_screen.dart @@ -26,7 +26,7 @@ class MainScreen extends StatelessWidget { case BenchmarkStateEnum.waiting: return const BenchmarkStartScreen(); case BenchmarkStateEnum.aborting: - return const BenchmarkStartScreen(); + return const BenchmarkRunningScreen(); case BenchmarkStateEnum.running: return const BenchmarkRunningScreen(); case BenchmarkStateEnum.done: From 5098b071e1d3b73db736cce786c3ee1741f1dfb2 Mon Sep 17 00:00:00 2001 From: RSMNYS Date: Tue, 23 Jan 2024 10:19:06 +0200 Subject: [PATCH 13/17] feat: add benchmark results web viewer (#833) * web-ui initial commit * updated .gitignore * 1. code cleanup; 2. worked on the filtering; * code cleanup * code cleanup * fixed null filter * 1. code cleanup; 2. UI adjustments; * worked on the UI (WIP) * code cleanup * code cleanup * worked on the filters UI (WIP) * code cleanup * worked on the filters (WIP) * code cleanup * added benchmark filtering option; * added backend filter * 1. added logout functionality; 2. code cleanup * code cleanup * worked on the filters * worked on the filtering * worked on the filters * make use of env variables for the firebase config * - added error handling on the login page; - added loading indicator on the benchmarks page; - code cleanup; * code cleanup * Add GitHub action for web deployment (#831) * Add GitHub action * Add GitHub action * Add GitHub action * Add GitHub action * Add GitHub action * Temporary delete other GitHub workflows * Use env for web-deploy-preview.yml * Use env for Firebase settings * Deploy to preview and live depend on branch * Fix Markdown linter errors * Revert "Temporary delete other GitHub workflows" This reverts commit dea1c65a9de520a7c4eb9dc1224e69ea32431127. * Update docs * lint fixes, code format, code cleanup * ci: update web deployment workflow (#834) * Update web-deploy.yml * Update README.md * directories renaming * updated github workflows for the react app * Rename benchmarks_web_viewer to react in README.md * code cleanup * code cleanup * fixed sonar issues * Update name, description and logo * Cleanup --------- Co-authored-by: Anh --- .github/workflows/web-deploy.yml | 47 + .gitignore | 4 - README.md | 3 +- flutter/.gitignore | 3 + react/.gitignore | 30 + react/README.md | 57 + react/additional-declarations.d.ts | 8 + react/cors.json | 7 + react/firebase.json | 23 + react/package.json | 82 + react/public/favicon.ico | Bin 0 -> 15086 bytes react/public/index.html | 43 + react/public/logo192.png | Bin 0 -> 5606 bytes react/public/logo512.png | Bin 0 -> 15541 bytes react/public/manifest.json | 25 + react/public/robots.txt | 0 react/src/App.css | 38 + react/src/App.test.tsx | 9 + react/src/App.tsx | 28 + react/src/AppQueryClient.tsx | 29 + react/src/assets/MLCommonsLogo.svg | 1 + .../assets/icons/ic_image_classification.svg | 1 + .../icons/ic_image_classification_offline.svg | 22 + .../ic_image_classification_offline_white.svg | 22 + .../assets/icons/ic_image_segmentation.svg | 23 + .../assets/icons/ic_language_processing.svg | 1 + .../src/assets/icons/ic_object_detection.svg | 1 + .../icons/ic_offline_image_classification.svg | 1 + .../src/assets/icons/ic_super_resolution.svg | 13 + react/src/constants/breakpoints.ts | 12 + react/src/constants/constants.ts | 45 + react/src/constants/moduleTypes.ts | 5 + react/src/constants/sidebarLinks.ts | 9 + react/src/firebase-config.ts | 16 + react/src/index.css | 13 + react/src/index.tsx | 19 + react/src/modules/Router.tsx | 45 + .../modules/auth/components/Login.page.tsx | 164 + .../modules/auth/hooks/useLoginMutation.ts | 43 + .../modules/auth/hooks/useLogoutMutation.ts | 22 + react/src/modules/auth/hooks/useUser.ts | 8 + react/src/modules/auth/models/user.model.ts | 4 + .../src/modules/auth/services/authService.ts | 8 + .../components/BenchmarkDrawerContent.tsx | 119 + .../components/BenchmarkList.page.tsx | 44 + .../components/BenchmarkTableDrawer.tsx | 52 + .../benchmarks/components/BenchmarksTable.tsx | 21 + .../modules/benchmarks/hooks/useBenchmarks.ts | 57 + .../benchmarks/models/benchmarks.model.ts | 118 + .../services/benchmarksDataService.ts | 49 + .../services/benchmarksTableDataSource.ts | 77 + .../filters/components/BackendFilter.tsx | 44 + .../filters/components/BenchmarkIdFilter.tsx | 44 + .../modules/filters/components/DateFilter.tsx | 59 + .../filters/components/DeviceModelFilter.tsx | 40 + .../filters/components/FiltersForm.tsx | 139 + .../filters/components/FiltersModal.tsx | 41 + .../filters/components/ManufacturerFilter.tsx | 40 + .../filters/components/PlatformFilter.tsx | 44 + .../modules/filters/components/SoCFilter.tsx | 40 + react/src/modules/filters/hooks/useFilters.ts | 25 + .../modules/filters/models/filters.model.ts | 125 + .../modules/filters/store/filters.store.ts | 25 + .../src/modules/main/components/Main.page.tsx | 26 + .../modules/main/components/MainContent.tsx | 17 + .../modules/main/components/MenuContent.tsx | 95 + .../main/components/ResponsiveMenuHeader.tsx | 126 + .../components/TabletNavigationDrawer.tsx | 62 + react/src/reportWebVitals.ts | 15 + react/src/services/firebaseAuthService.ts | 20 + react/src/services/firebaseStorageService.ts | 26 + react/src/setupTests.ts | 5 + react/src/sharedComponents/CenterSpinner.tsx | 18 + react/src/sharedComponents/DataTable.tsx | 94 + react/src/store/index.ts | 27 + react/src/styles/theme.ts | 20 + react/src/utilities/timeUtils.ts | 25 + react/src/utilities/utilities.ts | 25 + react/tsconfig.json | 20 + react/yarn.lock | 11801 ++++++++++++++++ 80 files changed, 14554 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/web-deploy.yml create mode 100644 react/.gitignore create mode 100644 react/README.md create mode 100644 react/additional-declarations.d.ts create mode 100644 react/cors.json create mode 100644 react/firebase.json create mode 100644 react/package.json create mode 100644 react/public/favicon.ico create mode 100644 react/public/index.html create mode 100644 react/public/logo192.png create mode 100644 react/public/logo512.png create mode 100644 react/public/manifest.json create mode 100644 react/public/robots.txt create mode 100644 react/src/App.css create mode 100644 react/src/App.test.tsx create mode 100644 react/src/App.tsx create mode 100644 react/src/AppQueryClient.tsx create mode 100644 react/src/assets/MLCommonsLogo.svg create mode 100644 react/src/assets/icons/ic_image_classification.svg create mode 100644 react/src/assets/icons/ic_image_classification_offline.svg create mode 100644 react/src/assets/icons/ic_image_classification_offline_white.svg create mode 100644 react/src/assets/icons/ic_image_segmentation.svg create mode 100644 react/src/assets/icons/ic_language_processing.svg create mode 100644 react/src/assets/icons/ic_object_detection.svg create mode 100644 react/src/assets/icons/ic_offline_image_classification.svg create mode 100644 react/src/assets/icons/ic_super_resolution.svg create mode 100644 react/src/constants/breakpoints.ts create mode 100644 react/src/constants/constants.ts create mode 100644 react/src/constants/moduleTypes.ts create mode 100644 react/src/constants/sidebarLinks.ts create mode 100644 react/src/firebase-config.ts create mode 100644 react/src/index.css create mode 100644 react/src/index.tsx create mode 100644 react/src/modules/Router.tsx create mode 100644 react/src/modules/auth/components/Login.page.tsx create mode 100644 react/src/modules/auth/hooks/useLoginMutation.ts create mode 100644 react/src/modules/auth/hooks/useLogoutMutation.ts create mode 100644 react/src/modules/auth/hooks/useUser.ts create mode 100644 react/src/modules/auth/models/user.model.ts create mode 100644 react/src/modules/auth/services/authService.ts create mode 100644 react/src/modules/benchmarks/components/BenchmarkDrawerContent.tsx create mode 100644 react/src/modules/benchmarks/components/BenchmarkList.page.tsx create mode 100644 react/src/modules/benchmarks/components/BenchmarkTableDrawer.tsx create mode 100644 react/src/modules/benchmarks/components/BenchmarksTable.tsx create mode 100644 react/src/modules/benchmarks/hooks/useBenchmarks.ts create mode 100644 react/src/modules/benchmarks/models/benchmarks.model.ts create mode 100644 react/src/modules/benchmarks/services/benchmarksDataService.ts create mode 100644 react/src/modules/benchmarks/services/benchmarksTableDataSource.ts create mode 100644 react/src/modules/filters/components/BackendFilter.tsx create mode 100644 react/src/modules/filters/components/BenchmarkIdFilter.tsx create mode 100644 react/src/modules/filters/components/DateFilter.tsx create mode 100644 react/src/modules/filters/components/DeviceModelFilter.tsx create mode 100644 react/src/modules/filters/components/FiltersForm.tsx create mode 100644 react/src/modules/filters/components/FiltersModal.tsx create mode 100644 react/src/modules/filters/components/ManufacturerFilter.tsx create mode 100644 react/src/modules/filters/components/PlatformFilter.tsx create mode 100644 react/src/modules/filters/components/SoCFilter.tsx create mode 100644 react/src/modules/filters/hooks/useFilters.ts create mode 100644 react/src/modules/filters/models/filters.model.ts create mode 100644 react/src/modules/filters/store/filters.store.ts create mode 100644 react/src/modules/main/components/Main.page.tsx create mode 100644 react/src/modules/main/components/MainContent.tsx create mode 100644 react/src/modules/main/components/MenuContent.tsx create mode 100644 react/src/modules/main/components/ResponsiveMenuHeader.tsx create mode 100644 react/src/modules/main/components/TabletNavigationDrawer.tsx create mode 100644 react/src/reportWebVitals.ts create mode 100644 react/src/services/firebaseAuthService.ts create mode 100644 react/src/services/firebaseStorageService.ts create mode 100644 react/src/setupTests.ts create mode 100644 react/src/sharedComponents/CenterSpinner.tsx create mode 100644 react/src/sharedComponents/DataTable.tsx create mode 100644 react/src/store/index.ts create mode 100644 react/src/styles/theme.ts create mode 100644 react/src/utilities/timeUtils.ts create mode 100644 react/src/utilities/utilities.ts create mode 100644 react/tsconfig.json create mode 100644 react/yarn.lock diff --git a/.github/workflows/web-deploy.yml b/.github/workflows/web-deploy.yml new file mode 100644 index 000000000..b58ef6857 --- /dev/null +++ b/.github/workflows/web-deploy.yml @@ -0,0 +1,47 @@ +name: Web Deploy + +on: + push: + branches: [ master, submission-v* ] + paths: [ 'react/**' ] + pull_request: + types: [ opened, synchronize, reopened ] + paths: [ 'react/**' ] + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build website + env: + REACT_APP_FIREBASE_WEB_API_KEY: ${{ secrets.FIREBASE_WEB_API_KEY }} + REACT_APP_FIREBASE_WEB_AUTH_DOMAIN: ${{ secrets.FIREBASE_WEB_AUTH_DOMAIN }} + REACT_APP_FIREBASE_WEB_APP_ID: ${{ secrets.FIREBASE_WEB_APP_ID }} + REACT_APP_FIREBASE_WEB_MEASUREMENT_ID: ${{ secrets.FIREBASE_WEB_MEASUREMENT_ID }} + REACT_APP_FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }} + REACT_APP_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.FIREBASE_MESSAGING_SENDER_ID }} + REACT_APP_FIREBASE_DATABASE_URL: ${{ secrets.FIREBASE_DATABASE_URL }} + REACT_APP_FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} + run: | + cd ./react + yarn install --immutable --immutable-cache --check-cache + yarn build + - uses: FirebaseExtended/action-hosting-deploy@v0 + name: Deploy to Firebase Hosting on Preview channel + if: github.ref != 'refs/heads/master' + with: + repoToken: "${{ secrets.GITHUB_TOKEN }}" + firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_MOBILE_APP_BUILD }}" + projectId: mobile-app-build-290400 + entryPoint: "./react" + expires: 30d + - uses: FirebaseExtended/action-hosting-deploy@v0 + name: Deploy to Firebase Hosting on Live channel + if: github.ref == 'refs/heads/master' + with: + repoToken: "${{ secrets.GITHUB_TOKEN }}" + firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_MOBILE_APP_BUILD }}" + projectId: mobile-app-build-290400 + entryPoint: "./react" + channelId: live diff --git a/.gitignore b/.gitignore index 3a592a04d..17e98e56c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,3 @@ __pycache__/ *.log *.iml *.env - -*.g.dart -*.gen.dart -*.gen.h diff --git a/README.md b/README.md index ab3f1b6f3..b9abbf710 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,8 @@ frameworks contributed by the broader MLPerf community. * [datasets](./datasets) - Contains scripts to prepare test and calibration data used for accuracy evaluation and model quantization * [docs](./docs) - contains documentation -* [flutter](./flutter) - Contains the Flutter (cross-platform) version of the app +* [flutter](./flutter) - Contains the Flutter (iOS/Android/Windows) version of the app (for running the benchmarks on a certain device) +* [react](./react) - Contains the React version of the app (for viewing the benchmark results on a website) * [mobile_back_apple](./mobile_back_apple) - Apple (Core ML) backend for iOS * [mobile_back_pixel](./mobile_back_pixel) - Google Pixel backend for Android * [mobile_back_qti](./mobile_back_qti) - QTI backend for Android diff --git a/flutter/.gitignore b/flutter/.gitignore index c5a9877cb..b41f03b24 100644 --- a/flutter/.gitignore +++ b/flutter/.gitignore @@ -13,6 +13,9 @@ lib/firebase/firebase_options.gen.dart .pub-cache/ .pub/ /build/ +*.g.dart +*.gen.dart +*.gen.h # Web related lib/generated_plugin_registrant.dart diff --git a/react/.gitignore b/react/.gitignore new file mode 100644 index 000000000..d16fbfb37 --- /dev/null +++ b/react/.gitignore @@ -0,0 +1,30 @@ + +# env +firebase.env +.firebaserc + +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +.firebase \ No newline at end of file diff --git a/react/README.md b/react/README.md new file mode 100644 index 000000000..93780cf60 --- /dev/null +++ b/react/README.md @@ -0,0 +1,57 @@ +# Web App + +This directory contains the React web app for viewing the submitted benchmark results. + +## Update Firebase configuration + +You need to use your own Firebase project to run this web app. + +1. First create a `firebase.env` + + ```shell + touch firebase.env + ``` + +1. Then copy and paste this to the `firebase.env` file you just created. + Remember to update the dummy values with your Firebase project settings. + + ```dotenv + export REACT_APP_FIREBASE_WEB_API_KEY=abc + export REACT_APP_FIREBASE_WEB_AUTH_DOMAIN=abc + export REACT_APP_FIREBASE_WEB_APP_ID=abc + export REACT_APP_FIREBASE_WEB_MEASUREMENT_ID=abc + + export REACT_APP_FIREBASE_PROJECT_ID=abc + export REACT_APP_FIREBASE_MESSAGING_SENDER_ID=abc + export REACT_APP_FIREBASE_DATABASE_URL=abc + export REACT_APP_FIREBASE_STORAGE_BUCKET=abc + ``` + +1. Import the env vars into your shell + + ```shell + source firebase.env + ``` + +## Run and deploy the app to Firebase Hosting + +To deploy the app using Firebase Hosting please +visit [Get started with Firebase Hosting](https://firebase.google.com/docs/hosting/quickstart) for more +information. + +You will need [Firebase CLI](https://firebase.google.com/docs/cli#install_the_firebase_cli) for the following commands. + +To run the web app locally: + +```shell +yarn build +firebase serve --only hosting --project +``` + +To deploy the web app to Firebase Hosting + +```shell +firebase deploy --only hosting --project +``` + +To enable CORS: diff --git a/react/additional-declarations.d.ts b/react/additional-declarations.d.ts new file mode 100644 index 000000000..c6f84684a --- /dev/null +++ b/react/additional-declarations.d.ts @@ -0,0 +1,8 @@ +declare module "*.svg" { + import React = require("react"); + export const ReactComponent: React.FunctionComponent< + React.SVGProps + >; + const src: string; + export default src; +} diff --git a/react/cors.json b/react/cors.json new file mode 100644 index 000000000..697bb6afe --- /dev/null +++ b/react/cors.json @@ -0,0 +1,7 @@ +[ + { + "origin": ["*"], + "method": ["GET"], + "maxAgeSeconds": 3600 + } +] diff --git a/react/firebase.json b/react/firebase.json new file mode 100644 index 000000000..48502f6aa --- /dev/null +++ b/react/firebase.json @@ -0,0 +1,23 @@ +{ + "hosting": { + "public": "build", + "headers": [ + { + "source": "**/*", + "headers": [ + { + "key": "Access-Control-Allow-Origin", + "value": "*" + } + ] + } + ], + "rewrites": [ + { + "source": "**", + "destination": "/index.html" + } + ], + "ignore": ["firebase.json", "**/.*", "**/node_modules/**"] + } +} diff --git a/react/package.json b/react/package.json new file mode 100644 index 000000000..476d72ad2 --- /dev/null +++ b/react/package.json @@ -0,0 +1,82 @@ +{ + "name": "ml-commons-results-viewer", + "version": "0.1.0", + "private": true, + "dependencies": { + "@chakra-ui/icons": "^2.1.1", + "@chakra-ui/react": "^2.8.2", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@hookform/error-message": "^2.0.1", + "@hookform/resolvers": "^3.3.2", + "@react-firebase/auth": "^0.2.10", + "@react-native-async-storage/async-storage": "^1.21.0", + "@reduxjs/toolkit": "^2.0.1", + "@tanstack/query-async-storage-persister": "^5.12.1", + "@tanstack/react-query": "^5.12.2", + "@tanstack/react-query-devtools": "^5.13.3", + "@tanstack/react-query-persist-client": "^5.12.2", + "@tanstack/react-table": "^8.11.0", + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "@types/jest": "^27.5.2", + "@types/node": "^16.18.66", + "@types/ramda": "^0.29.9", + "@types/react": "^18.2.39", + "@types/react-dom": "^18.2.17", + "axios": "^1.6.2", + "date-fns": "^2.30.0", + "firebase": "^10.7.0", + "framer-motion": "^10.16.12", + "ramda": "^0.29.1", + "react": "^18.2.0", + "react-date-picker": "^8.4.0", + "react-dom": "^18.2.0", + "react-hook-form": "^7.48.2", + "react-icons": "^4.12.0", + "react-redux": "^9.0.4", + "react-router-dom": "^6.20.0", + "react-scripts": "5.0.1", + "react-table": "^7.8.0", + "redux-persist": "^6.0.0", + "typescript": "^4.9.5", + "web-vitals": "^2.1.4", + "yup": "^1.3.3" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject", + "check-types": "tsc --pretty --noEmit", + "check-format": "prettier --check .", + "check-lint": "eslint . --ext ts --ext tsx --ext js", + "format": "prettier --write ." + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ], + "ignorePatterns": [ + "build" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "devDependencies": { + "@babel/plugin-proposal-private-property-in-object": "^7.21.11", + "prettier": "^3.1.0" + } +} diff --git a/react/public/favicon.ico b/react/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e51da5ba9bb4dd26886cca3e38d1ac1ea36a1d18 GIT binary patch literal 15086 zcmeHOX-||_6n?Eu+L$)=ACx9-HEq+{O%p#g{njsIrZ#V$CSj0v@jXqOuW4FP(6jVxO*2W}YzbK&@~WnVONF^oN1ABg3o~EQyFmX^$9wFQ- z?C-?+h!J+^An}dD(?NC-QxSFGJaD~#B3v#!-Ka_gULgGIbQ9c3Uaq5jr}T7-a@|;` zo6t`3`os6#Nt{45V1a-I0v7oHS-@(wqOb4y=a%uVt}dl$M@I*mo0}EeY&P`v_9`B3 z1(vbyz`%eiVtR0J&{559x1+zGN1KTyj&bbRG34gvIy%nG%tS;)1nTSSv0=jotXZ=L zYuB#DjT<*`?bMF;x*k4!7>$jMj(R6foIplKh9f;u z5!!3lu3fly?;Z*Z3sGELjN7+wW6PE;C@(KZaBwhka&k~zT@B9D$&)7$9UYC%&Q3KC zoTqi`*5UZ^`YlMUc89y z+qWzEDF^34r_-lTWAWm}SigQf_U+pTqtS?^OP4Br*$?Z}&Z}3ihS_XZ%_u+1IDZpO zy8O$RFGo~V6gbb6XWO=IZsk99>XceroR8hRcjN5Yvp96<5W>U5Rr^hwHmNyWwrm+9 zBO{TTnyU0!vSbN1Zrq5xyu1ljfwtjVq09{p4QOj?!^)K_)w<{UVZ5%c&M_v}Pgq!( zT5Htt(xppky;E=MUshIzo}M1H9`*ggIa;w|1$OS-iIS2Mw70jTw6s+18?MRm5@kqB zOLKI?{m3=c)YOESm>Bh4(F+X*18C!|TeqrtXl-rPi(VRDy?PZPAt7MMea1bOkdWZg z_e(o?Ng?N8IO%!%_fRiqKJ7~$UZ&S^7xJ5IGMUs~Vmp3I^)cMl59AG5fVS%H9{MfQ zZ8A7Gfa>B*R24nM;K0yt66>|LHleGtL$Br+p{?7BN=uoGEKQY95%uFoh*&uX6;D!C zSxa*R((c|wPS!p7UFdPCKa~la%?gXT#6^VmMhi}D`x?J2dINEx-@KUV5u>%vgqtU};cR~iuAO0$!Zcyv9CS$AapB*{FySkJYU?^9gQg~n{rp&Wg3{?v(f zZkBcb^hpM4Oa-8xy~E~7uRGPD)!K=ICz)!07Cp_A_3{LHIqA4-xFLKU6&1yP|2^;P z>qTvi8TpSN;?YBcV(L^|Yw@dZ&S-PZ-%YL~a^N>~G;0OQ0~QEaAYg$hv4HEreM&^| zdQd*7P3&dgYf-#vSSqc;g2qgZxaG3CP(1Ehk*I||}|Fb!u4k5za6aKm%DnvH=I=IL_OpgzwoO}AQ zus?iT`FKc-oqhrz3(s(t*UrS-n%2(nElo2pocTNqW!j|$GXgZ41wvUt>}Fu-WKZ4B zy4~rg6(szXu)|MFe7QyRB}HLSRaI3A2V!}5cQ>-LvlXtUk?1*hKRH6-@jjB&j$`1P*^Fkdfg^R zjvP^A5>q9HN<26;G!$pfoKdpUCd4bf#eJzi@z4DHeAPFx#G^-#I>u-G)~#D=Y+~mu zr*8n;oj-qGVUm0I?p4?>=Y+WWSn)>MtEHtyVWf<6u4!vx`CJzy&dIrR=M-+wcSv`b z9%Z3Dh|6-$oUwG(i4Xn|dz`3u(thd78IOCKk%+?de?*HxS?8_tzHIRb7xh$qyR93| zO+!CdgM#@H`-uEu4r)qd@0AqbLHg}U#h-{L@x5Hfh`QPuVE8i(Nq=ldZdNMta?>4U zp6WK%`pr#sf|ZyZZ}zlFL1r>ajhTX{O#V+f@z=WAO2Kq;U@XW&_M^MV7TmH;@K;|F zu}R{lWZED=0SkC(fvG-!K6mi(Qh{+aYmv5R$I*VgO?lt^RJeG&9eL57KK2Wq-2uOm zc!?K%c-w?yFB*0SrX9`+^CLbP?^NuwL74Z=FZ8j^n)aGOUJ^om_!`5pIHp;~<~s$S zC4z(FZcqTMPOcQ=Z1g26dm}d6m9{lxMWN6VGG4;@419{0PRh_#qz>5B#Tij_YV|MMq0L za#OFMv?$kOKWCeqJsRq(#b##o_>u3E8@rEZ{n9DzZ#R98HH-W9{bzl6;^4-8!+kq9 LRNg$jCAR$!3DxM* literal 0 HcmV?d00001 diff --git a/react/public/index.html b/react/public/index.html new file mode 100644 index 000000000..e5ab064a4 --- /dev/null +++ b/react/public/index.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + MLPerf Mobile + + + +
+ + + diff --git a/react/public/logo192.png b/react/public/logo192.png new file mode 100644 index 0000000000000000000000000000000000000000..f86fe57e759d121dd05669f806493e8e75fdd1f5 GIT binary patch literal 5606 zcmds5=R2HD-`=odwb&pb;$}BkL>HpBjow>?)uWf_y#-lBP4pH-kLZ?&2ofcW#YT@7 z(V}-&=eh3p+xy}92cF*^yK~I!%rP_PoagzQ>x$9QQl=tjBnN>&RH`ZpdO-Q@-!Fs+ z_?>M#*8vK!y}YJ82vqlm;=+mqsKcyP^fW=BKm-UBh6aJofTplj5XeUW1X{NQfh00P zAbR(AUv#B_KW;u(S5^RB|ND90T9yK|kb0|XDw3|=pdn_bvTe!$2GT{VD##o7Pi^G} zxYLd0f3r9~oEb3HK+q;r!pW2&6GU*82WgdpjDpPmI>;M+^%di8PkCy2aP{Oq>gwgg z$!A_f?=sxvPEji>Vbj*kd(euj zFKkhV<#N6Q?7`7XLX)FQ zT=LT6?>IxmvO3A(*7aPtSDx}AQO@j4+uTQ!)uQE`U7?` zHmR?|XvoC7Qw3D3TtE9Jz+T6X8f>vK!VgVSj$ZPcT3q4}#>kCZS}U-V(a?f|wZqX= zqq6T??1LohKF!rlCfzTZHPUmlth59cj>iFZ{KaRhLc#1w-YuDCvSXVv9-+9D<81GS zXsc?Is)#TsP4@KE5o3aRMU0QojM9QJEZsI|daC=1nM-kCuwO-pJ^tw*y;$Eoxl;AH_@XR)kwy#ag16jNei_4fURpVQN`)1sebr3+r0gm>^v z+hJl@@2HX~sp}0JB|P#E{@$L~c9QYrW&7|@9P|O?&}FY9GE2YfB5LvT>Z^b}w~bAW zpBsyfkN;^RI%=MI-eSg;VQ-{|UAppMvY2(4ZL3*dIT)}a9H$2l#-}zaQb3Vaxu3#Y zQy~TB87=rNErC_*T(+jj6FL< zZ00mPq}5c`SmgDSRy+|S&ZN}J#}|!S)PFB0@N2^xj!yMFrAr}uB>Yk!_|Rn}|M)tv ztr=rcGie=wiM!$=hL3J|l0JlLI794Td6>UNPId$V1UMUbFn| z>!UweH!W(fS1*MzSCMzrm-NWt#S>1&bRwg2(fm;NpnK5O#P7>{yAg6wbgw0Y&-bB? zy%4|sj+cf8O+GC*L%HEGFL{lnaQi{+-`E;ak}ui_TJ{|GW9-L4- z1#^@8$MdPniEDtCDX{e z1*8WH1n#%h#c|5KeiAO0NLywS|KOYqGvmjxVcPFbura22oX%5vlM<^|GAhuj2{^YXxMCEzSUev$Xdu#X3spB07W80hNHrBQB&Yud|MrKa;b<>=wI~Od z8eUYbztX8OY3pnHNx4)_hzUA1*nl$!hR(<8;_-T@CAHG1m{w zr$Z$ECe5LjXIGc!_;=#gP1CQw!&H;W$jG#%_PX@7rA4kPsIYdNMHtM%>QK?V`$^mR zwz{@9%e?Wt`{$1zKUP<}ZqGEIo}LcHbk}dzSz{Cbku06qcvfSco0KHjArO!!>$5)k zM)rz8n}B$tz@6o6m|uot6r zUOqnNYq~i1_0e)%27lbNuqHh{y$Mfxb#?Xc-@hXwBD%U1&~LTMg61RXZ!t?5>FU2Ux#d-{l;NCEaC+Fmt7#Ilma~0?~OjMfz z^CjG3I|Io>AK32k-sv0S=v($&PQdtrm-xN7iQQtd;HT{`TNz>LOQ8zkK=9 zgH29O9>@`mYrcg)AjbUYDG89ud-v|$_V#vb(D7Y5xZg$ofatNPbVyCoJyr}mCyO1$PaC8SJQ6oA*ah3q%RbVs>b=-FNSxH=e8Xj8mGb=cl!JL-Nh~@ z?ek*{pBfrg8)JTWFUGPkVMRnla-{<5tE&g+-FKyc8{XgkEPW%R%-me*RYkH0OUz_o zP>{Z!UIU63$w@~pA}TsDF>!o&$Uqroi%XADq(Q#6owO8SfPg!6F<*_-kIpZdu(!bl z1`p50g+tB`7Z#rHmC^H=e$e6c^zvc}T!lw>?)`a1-G_C}iY9|Yk*nXriPh72dhz(3 zrhMB;x3<&Lx;jC_+pLgBQ76Ax{@ON4(+p{e=94;s@uu!|Qs!H1Z z&$rk++~ZXy_QC{<1uYj1psQls-PY5;Ip#HfD}%XdX=zDP2!8&Zt){v0HE(HYX!%?UK5O+rgy237XZT}``GEEz6XlBc9>H@1k9a> zS)4=w1#%_*2D3#fEKvC}A!k1ep427e3^{11snL*-MhkC8ba`A>S{ggOg3q68@pJROoU+3xqRfH0Yu*ez z^kBj&_9d!x6T#`oBil|E;_^e!xSmsMj&S{7c#mc~0Dw$4xg7^ypJb5at+29)Cr$%P z?2e;XO&)b>WK2-viRZZ+cfymf6k?dSG6_#de3|VMBNfUSU}t9s?8pNKm4jUFc2bLr zi^tLPD?#db&H-$dP*sYGijR(Os zaC77O`$yNj+po?xfGp76IXpZJaOIhy;o~bo8wNXko^;YjRTL^a)AsE0D&(9H)09&9 zA>qEL%t8O7q`^BWy{Q0Psi_Ut*jwqg#_6+7ZWdNn1*_n*MePzOQU#IH3Si9rteQ?1 z-~_h>5h7(RLG-sJ1A>9F?P%Pj{gROL`DJGmRd;tc6E=yh+_1v>C?lqhUZvci+N|Xh z5Eu+C+?%jDxxc>;_)UGi&>QS4XmYQO^F+0#ws!k$5g#uv@0~k$k}Tkm2-``E&{Ov0 zt=nK-0|U0l+1WWctg{6edpyu-YeIx0P3>8=X~5ax+SC+k??gR=kJq9t_|MKDK<1Mx z)pCQ6BWn@g-y57^aYGN&)QVy*8BgkJ6b__ht$)NntuTBs*Ot2ykhgNYIq5au5vfvA zUt3%I`LjRMkIj!2|3V-pk94}Z=yd#%+O zDL+PZnZuF*w1M?516qQ>TV`FGrn@hDdwVw~YMwnz6STN*3oNwe>%Lks<@)OC>tG=B z0O2(PjbikOLkDmO>4Jxy8iC$!4i2xkT}n8ej@HK>+4aAEF*EAq6B>FIMRmWh)!SGVivDhyDe32G zXqb-l=p5!95@F6Rb@I21{7m*>}~7x%FqPK|*N_&+=X45*<& z*yC+=Yiny|rOUzJ0pjT~^P1!Ju?kex`187%A)nlWOn2a6Fx6ju&7En*wl# zSAU*b*pw8*2}KxI_y9KeM0#7P$Yb$G0?s0bmq*PJrxUdZ0zlokJl4#)DMMS(EbHp83YAi5MwVjC-Cd&=kp#+NW18?0G;(-VNaZ?z8vI8jiT58cbH&H9C!b4LDHpf1sM&*w`4_ zE-ND9GyBEI4kNywW?o~@P+C!;4#*~|`*~fZMSJK}gX2OBZ~*h}zqSaKm6bjl;|aUw zN>4_-0d8q&B@Q{H_Sy(#X_OnpHvYZ1xUkO;@x44dT3cJYWCX{=#28jQg`x`!3$ZLO zgW1M}lG&(kzRGNt+5JXbQc_|qQgbi**H`+#d;WZ8UyAk0>+9>4%u{!z=4NJQhK8)_ zj7qg~r*_iO$O7OF;w~l?Jgr$YwCXK-5%3iL3G0?Ob&Dx1`Q+mpR0CX z69*MC-Y4Sp`3$_JWcOAy^0u+^ww18nn4+AV_#9>FzG+l2lUZMp{HbT3V$+H1`<=iDD}Unof9^Hfa5ZEStg z)lJ#VU&Q0?G9__gr{gARIL4K{#M{rrmojNzBWVc#=#^p7H%*(GX4Leobqx!qBzYff zER0Up@sy7mN7vE57JWu@{b67)kvPw!eyC?0-FVq&pRqHEIy?uyc)HQ(GanIOy5Yjv zL!4u;9`{Fdp;>qc#Lov&uCOW^VM3T(pg8L+hh%#cqx0(O_<$nY6-(>h7Duk?A z9Spyj2ccPV^h7Ne^f4XAS#nYxj7f4*D5PXZ!Nqxx+XzyhmjgqW;V{p z37zk8*-l`fJsh2F?{m@W_SpjuA>oXkO#&>9^hI~EqfM>ztru{4CoygiT&K#UqZF;1 zk|QtM|8Y<@IKH#b1veXm>thqH-_r-7_uF@MGp6TVTwQ9ksj7RZ_4!y9^sGa(NRx*@ zs$!@8&KaTDKcS6CR%6^UMm!+FL`X43&Q9psNhfsnjgGEwWBIRr@lJXuo2SHtubI|r zT#*=ll0%!^*320$h=U+Cz!KZLdK&rrchx~;v8^i&X}Fy?EJvn9u{5#Bv|OqvzH?g? z@c--R2Y#>bA@s5S@)kD~ z7Up)_ZZ6@KS=SdnknCW4c*n`q@>8q1XdNLfFBXE9Gjdj-ww7E=YdtNEvc0{If5y;! z%#zzAKc68b+>P8XFbLs?MTg^GURT#xlUvjfF#pxkEkS#pFEnd>w#e4nx>A7Gr-kz{Br1EXkxqoe#bO7*Ll zG%@!OG-6wVc2;&xFGqUUw_#+7&W{7c3-fvOT1a(8%zyY8i0wrJEKBkfa!pNXbF)o- zcD%HNq@;|v0wtzd9TFOHOvJygd6(&e0;^SXhLx0OD3w|+cWs|^-NFc09Y1Xx#2X3} za{X>vwUwpz25M?;fI3E3#79o7tm6&wJPivWf{@yuhO@eIvY=qM)#C#L@z|K8LdQe* zCEp7(YEm&msz12&?6d_#twy;0%AbECNPQAN-E{c2>t&;xA6a&mkzvY>&Lp1M9N!l~2W`LB z?_J$}RWqqGXBV==hGfC0EZyB1! zEH#^$x@KH{z5E-^Ex0u=j{l313CH|A?o$fO;5_A+$D_;3rUAl{tBYHLo6fIz#;m!e zJvnuTWh`IWno6l@CTntS&6V`((eY#Je}r=R`8Mm%glUs|2~!u^yhhuWD`kh{36UAQ zclzRZn$G^?$B~f=K3nTAEr#b#KQm|RlKke3*>#Qg_bAZ%^Lgzo0huW^N!hkkU#xRR!pSp;E7$-eddA#QH2>Pi_Nvx3-PYkL(F zVzyVll}%I%xN5H7Op=RFwocOKR47tvMdug{iX*-e;+9#rPJUXbs=|0~$(77rGn!OT z@W4==wrBUT3%cP1J8EPEty+^>mfQ`ga3>ozrD$ds&=3~gQKlR&t^ zWeg=KdF+0@|0Z@e0lokC7q_040wN6AQh&)AvSwlW`DA(jy65b4fOzIl+2;dv7Mp{^ zV*>otUNQ+e9i6|rMK?(X|Iv|YUU_XW~~V~K%;SaoQGr(z6C zOy8XU0UaIdBju9yy6a(!L93Nju8lSJJC@ygLQOQR-Gj43wF~JDHz<2v4)H8iYQ~6B zZ$1e|;b0&neyr|J7nTrU1>80<*F?Qb(|MQH8aOGIY|d#pbi{s@DYtB3{#VD(XO)R) zt6~eM+Qanv?em%ETt#VC3-a1R`Cp|mLdwevN~$=bdR$8yePmH6-zX&F7Da)t+q<7w zVjrz+H`W|wVhzkaw0(4KrGmxT%krPHa|+QjNE5mx=b`Jj53kiI^H@%wteh^VykcfB z*1~5kVH{vM%dr}v#u?`3F14QC#ammyi(gb^zwR`P^`0*$k8kREFig~m?F$wE?o+_;9~aDx1C@= zPd!|!ypM3xDF}5H1Hpa=2iuCAf^NZ!ol_@P#H0B9Y_TdTB&7}*|cs0hh`S}Io@P$H= z_8arADO2YsKi)q-tbZ+norx;+aW~O0Et|;?I))7{vHPpxXmfX+JA_U^=<(Fzwd`w{ z2*Zx`ZSIPSJ)RwD1=O)dQcV(B_R-4p#KzdGwUrQQ7M|+ERCJYx!giL0k>_de)KuS! zeV~(ZI>}0kR?S027J z^^utxAV}EzYUAnxgK1u?Lxzpd+Sryyb#}H&Af6InAWHkzw=4Kh8Zm#(@A$7-hxPIP zl%TJr>CC86y*LV*IQnMatQ0QLLuw-0t+GWd9Jv z8!CvCD6&;8B)e(+g44>;MRUcx)`(cLw7C2D`%EWw##dXX+T0r=yU#l6W!!~){#d$J zysGHD|L?%VCelTR1rw148A-Zza(0GqBBNB;ZfwS${c*WzoP^iy{5LgJVr8BxA-4JV zhaHOJWyZCk#~swk?W=`WmQ;hoi9!{B)&Z5sxzs{~KSF4**Y4i+W(k)=so0tZqeNuy zaLl^TSjw+nj5{hvoDQ4H=gQxd)!( z_`}k2w62x*k&4U*%-IgRU%X7{*WhKN&P`uq=@>JGW# zruwX|k7pe@Mf&fGEUa;{n#U+KH1j*>9X*-z`i3iSHebg;pl(T)7G(#_pQyL>8*=1n zGH(~_SD3k07o0WNb&8-%v$DrY&MD>{Et`#$JKM|-c{R%$y8A}S&K+p6G=`@}Ex5_0 z+OOPcxeCF)jf0KWZd1y92cQ_W)Toy~e%P9%wMkX4KB`Z>W`4G8^n~XzQ?76AQVNhM zD@(F3)4X0lE>Azp#VL_(M&U{^VIiL87LKoP@0T6~jOu?$mftSc2~>}4a?4*9X%hBb zbBtsCiGQ$uLOay?=$E5U?Q{uasJxAhZHem_>6pIBM3uFu(DoUfKY^*q(!}m;Jpl{cHV%MLojGNQR zNY-Y^*~W%2=Fq5ar!eNL#0?NL=mmOuFGJ+-YGpEe(Tha-b*Y8wUc@+Fx}A zmgbMp%Be9s|H_sv=MlaykdhkVZM6#@)%;h#1I_fufS@2S5Vv-Yyc!q~R)dxe+zts3 z7u;uLRXfM0Q$?J&i`%IK_DRJDWlvh?pR_IJ1S+eS3|Xo$xvtgvYsBxnd1srp3Xv+n z-n?sHTx~$4>ZZhgAyU@juRWw}I+*F}+_%x`qh1%gk%tuA?+s+TQ5YMpP#9r=z{w&V zKQ$6w?U1fZ#$Tn~8$M?+;VC1N0s9j$&^#kjJMOk&AJ_J!rj*Xl_&X?DJg_jnNMi*{$E|IONft ze&xkje9n<%Z7FtgBkVbuCi_QMx`H7&xsh#P5R^PiTww?Z|MmD;k3&RZ+^?q;2#-%$ z8y8b(?>ehz$v<%jdpLyaRLglD;2>AG1;%x@n-W>~buEnDVl@`E+s0*eM3F=0p*qwCa(>9{3na zkK)dX{0T{bUpdug`MkNAo?hcLhSO>|7U_x7^+NhZ_BY>NLL?* z4e(^^{moRY5O1_VSy&iI8QUc&t5{#_49$8YjCg~z8`y@_?69wRraK3 zgUBTvP-m0Od~@2vu;7{7YX6##20His?}y|+81otV-(&ujRSg?hk2>dVNOE4WdDO`f zovpd;pGjQmtqHh+1w_|8i}8RxI4uhq`aL3;l3$Qjg-g1w%E>o9RlvZ&!XWnA`%dCg z8)hObvGAcEQlfZ}8d*J75rPK%2zA{r0!AeWsr1E=S0s8Le##-fuo~Ta>t4`D9U8hH0!<4CAn1Mri=N?qoq#!HF1i2B zx6<^BC21lL=@V>&AZR$>#6<})yew#LdsiLcTqieeniLn{n_jo=(uEmbcG1S!*&SuMtLgEHZSaP>oPQ=RCJyR+) zQWv7Zf^EsnNt)_B#|p6iw|6CH+%c`$98O-FaEz|-wLS?e%MyGRKeV+I%8|`|a5zF<$uA%z zbTYrI)J0$D-uqnX%1?+tS#YN3v?I3v_m<^r@g2rV9l;m7bEzuIbFQOIQrr1aJ*j*w zW60&|;DU!BhWaS)$rQ2t{B4?ur5SiditrKzGMA@3HLv=ApBfKr9m(qd@iHU1aNsG& zl+?ZaVIh8#-G3H+%qR5n9c)IsJ960G#&%}r9@e_WqohNho{Dl@j-bXE+b~={2d>fW zrR$>fG3*tFozcq|BTopl_5vvA3Jj4wtf?m?t5js6Z5h|doX6f8-FWa5LD!5Vo-@nM zH9Qh|Dz`mmRnl5_lWpfkY<=PQ(7cPtkwlSHT1-0C_@r%idv9n#&@vQt^00#EOZ6LA zChB_^iyeGT>boyK=XuKvd{i+FxcAdRH$$XL*Ev8zOI!V2Typ63Z-n?v4#76xe*Rlp ztJidIr^X39f60;$w3&Eefp!7EfHCwiS>S-O>16+S{FRMDJdsDj`_2ND?1R37t0{Nl ze>49gUsKye8ERCuZkStFg1+}=u3`dDjUzPLLSV9b5N^ejjqV(9VRyOYB4v&4=y_hjN?ER(spjiy>A z{!I+#d?Z1Khckx0*8h@SSlBSIyyLcESI?ZFjMr_>MIP4o&YF8Qn)B;+NFrbiFoHSo zFEoP0GmR5(IZOOCAtNcPK` zcjhlFEVSWH0YTs0-QC$4h8{3yBega+|5#8k!^`sMQQ?OVqWJ@o_LL#b4m)!lH%M6i zth;~-@%}x#@A;|w?!xl^$x-@;Zd3G32z9Yu(}rVBR!zY5S4{MDbS9>zk<=nS|61NA zB_(l2h=k58*z->Lpx5mhkLd|$pIy*m~>SU9X zl9KxP;NBjNl9m<(Uclf7R*?9%zD&GHiC&X!`DkcpXj?eh6Mm1(ZJj8}c87e$jHw3C z!}am%23=N3lvK9E!P@BRNC_(oOXSGm?8amr1XsXmA$-!7L=u%h5EmbBJMq=wSM0-p z+K!@vg5yKqi^C^ozwIeWPCAAPUn-{ZZXeA?*-bYJ@$vDom@&k3z~{FYQtWhV9Or#n z4gC!gySln+oEBO18tcD)C1q!`PE}acvTN8MdZ{P5D`-|d?k%jhi8$J*+k{2iyhVJl z@Hji!PvNnP@0^#Hmv1^-x7(boOGrsUU*4ODLBZ?GTx%GKp6}VKkY;wHw(t=>-$~2L zHgrrFhF9kU+R%S}+0qyLdKW`8_7fMG%`-#~DL7!7MRn?&qpZ!8Ur-eZG)X2z4o@uY$5Ne;LZKtMb-@o55iqz1*9+kA@ z@_nqTI*8zz`sy$%)fLrMX03DintV&dp!Qk4)Mb5aZ*Ol#M6CY{bDitv)a4%j8Wyb4 zo?1MUS5;NDvMSv3+?;CYEc+~*TQ+JP5fR}}GdMgJ^h#j~loC)` z8=Io$8BqjbQC{9c!{L%9n@>16aBtiQDVK#?Z^AnPFE7w5tE(4VAtG~& ziy`hP0oRR*(Q-4i*W1NoyQVXjzAVWY21Tmh<$#I)G?apF_Q2i;cQ%^3F! z7QN!kk3z=D&iCg&mx#Ja6}5P7G~W@!@Ulpg%jfi{_d>VH=WL?JDf8k0eRewv`QQd7 zjrg?hg*WW1ZwaKL>*2;^)9E~GNRbGQv%~3jJ2m>z3lz%X{PdV1-R*v=gie!>P8L^H zc6N4Fmf_KrZ|g344IZyZeQx#aCa~yuob8YJ9+YQ1)+od37L&-StGkRYUl!o#SA)uxb zaQQ5riGziCjeyFTKP@vsJ%0b#Yx{i5@QN$XdmQWlNTB}7DCtN_KKGruFRIJKMOvN* zYuB*@&WQi=Za@{y;1$jC78e#i&+?z{labPzMnI2n2)SK}f z)==wg@y!r7=!Y=}K!K^TF#skN{+UOE&um-7?qbj8<~mcHY&Q6PmX(@!E#vU+kENtR*NVdmtPs+CJLsxW$vY&D>&oS2$AM^9hq<_|np|Du1? zO*PYm)VIk~n;j^7 zc7dt|<2&n?yrhrm<2+l+j?(>VpV`oG_NUYckSSjwExN;abaWKLCFJlAt7kVeIvbJf z7yOPf6gFAV`(*FkdHi^_-6qU_a8H)*15~fi(M*VKwZIfHnX0CyrZsoU)7Q|z4^+tJhRzIK_%ug~XC^)|Q!xLjZ7wSPF+J?g<7ECr_@&ZVUH46~mW03W4dg*dHvt`(|1$Gc8R*Ox&HwZuDoRdDn|^ z7S7{_EOlxebNkHac#Cs$C6TS+;o&Bo@nm?xy=!dM<3jxD`F&WNbHzG!RlXPJHse+J zt@_c;ki!Bl%v1S^jCWYHd7T!zw$Kc`kyh5$g036d5)uKIxltq55H$PM^KfJRPw8yS zTcZAvY-mc#`3glE<@A>~#ye`@B99QdWArAy#YUjrA(P>Du)&~ZrEIQdxoLL<1rKnF z%cS$zx2(}F9h)Qn?%dz;zm47=C%RK+u#DI0=Qo-)2Ii-E|KUEaUEe z{QAnZD(lhPg(=Ci?NQW19-LG8T(auS@kLtIRaI58hkvH)-FG1ipm&BZxRx?oRgc4v zS{fP}T3Qsz`Q&)mlBgUD&B7tgqG2FP|Ni~ko^3ZXHfF;k+KgI^0%KnzewG&kpu%M2 z6C#`g0UEUiC4n7~c{tXW`2@1Npr9Z#Jm13OWN&#OU$IHA&6=Bmfx*?))rvE@?|mmy(m5^qKWmi3UG9G+zj+j&sAmu%HCtsfzR;EQ1c(C=8>*6( z{S(OJ$$IzloE+L%q6QOV8CIo808F|Eb$_HBB9;$UeXf50DJ|8S%H++xl#O`ub)ZYc_aNULc7z)#d%0XTEx) zT{4OeEGzl>_%!kd@R?{CLzy05zSehDgTzs4moIt;tmM4Ko(xv@Rks!~1YRM`$7{En zhl1Ps&BDe4db8;QuyfX%Df^vfknLU9(yH0z*{O4!j$e)(swId@b*$NGIu`7w_`wDa7A?Tl0Zp}TOpyxBH z*AArp^o6c271IIh#SSaA*Opk~%ZqnF?WV$Jt12rSc7F><@Vw|=++ClnBO%($dX0D! z06Tnsjuj(z3`_|666xkjlqpl(r$d{y0N%(OW)Jl{iCDD!&-LU==JJ=Nt+0h(J60=5l{rLR@JN(n?hcoN%MX@#ls-H zmZ>`djqc`(4qObJ5pVZ^=>G2Cl`Zevk`CX(9<)1v9Pk8+7-HT5-R4XWc=e^y`fz}9 zsL{S%7}ROZQ8#%GbEW2YX7rc5X`Z|xq+s#wy#jmRpFeNz^t}Oie5#-j*=HWh_(Deq z_Ge>@m5{m9XQzV!CKPp;6yfMk^GvUtF_heX3k{g(y7q@X=Y~{pty2^w-|h2Ok8f|E z6B83d&P7=}v4pkuds6mobqwLQ>A|; zLIMKl?c@22M057x&o8MD5Y&;75Vd}+TS)vB|y?yD_M{rSVleocG~ za2oK*6g5?KS!p&A(A8M zb7kc|?0D?gJm{Q2r*#^=Gz=4Daiq=6%)GrDo?=vLJ}yNDj;~MEIGOP_G|J|32njWO z_(1dMQKw;PplSSxS0l8FOwLjYR$a=oJsd;W1u)Ou z-Q58KF7ka(7~awcp#|EWc?C!)zkz(Yzr9KYYzHd*W{*!zww9!1&{M?%Ir=B$5gi>J zXAPH;#mHD0wA_c@0+bc%c`!B>nX7cHuPkF;UIRG|!i-Yb>uW)Q%!xUuOkwAx-r85I zhUX~tqG7t{@yr@!v@r9%ULri~br&=UP`in*C@rnkeGh!>W{{}=8(j-*_V5r=<)&eWm`3JSi}7WAa44N0{aIB^xS5G<~tJ(M&h z78Vy-VPS+g_LS{x;d`~Oi0I{x>YC7XB~9nG_4O0W&ca8;uWGdW@lB+%OPdsBiquGu zNM@}n>))w-5)G46OTlospT)T1T#HY^9jF$&UXs{3KL!b6evaCF34yvs?FA>gQ`6&Q z!R`m6W(*3cynh@#d&eOKdon~=bxeN*UO%g}0s}$YW6;RO<$%@qxDyPApaFqTFBqX6 zpYO0&O0tgzPmQRuwXl0)jjVR zRF%`{8yF>W?zZ?l?Y5m4XtNC8^J8J^yRovl-}Oa1754}c5>}A@R>Pm&0cq%1dZDB* zdk55*XGNAH<>B#ShF-0+%)cX`pc-HZu(75JFah~ppQur;B~d9EIjoM)XrAG9oO{#K zRQ6r}Pop;)9HDEklB(31p@_?9a4s8w?{n1~{`PxIeZ-H{0{KKVl7}oO8@=mVhD0zO zYbK02_T3z#sp!Fb*z@p~`;9~U_Xm5$oa6DzP$9K8s;at|@@(ob{bjNCXp?VK3+{gA zLEya=1g)%@*`mN^y%Q**WkcAwB|EDlfL72Vvh}XeE~A7F)UkM$`O|DW;~)3yWkQmN zk+8PSWvf?Os>ZJBgjjsjece~OXy`A2z~d_%Iyv3#d9IfyAaE(ZEr8!$O;IL!aJ$hLteV>u7p$+H-LVnn%Vp3*LrKEPQd7FH!&!`{|;Xrsf!t zqTnru7)e>#UjvFFk4sm`I?JH4B7KHc&4VgYU;2mxuV3^x8w`KefL%HQ)=l?IyViL* zjJ5G7M&y_%InO;^#QyI$=yrU1K2OCB2&6T@ROhHS>Cmkzm9D145z zr#o4U!AW;4D?LDoG`QZnUQkkEXJN6t*?`v!j7*YGz15r(QXX|5vF73l{t0J-9T*Zu ze+a@oj@qf{5A&}+!z04mmq_kj(5Z8g>5`7?oL3Y+p4;LajAWkC>%F!LhTA1kI`ORh z^hwsxl{?`3ySO;wd6qKB9K+IQmrWh?GibKZqnC+t^m6nJ_?Y@ff(L($fL;hWFTH!3 z1ZZ=*;o21A_TpWKv2vcAMxD#!jlp1f1A`erEpe;)!?s;79i6nNTW*5sm;Lw`10pmF z^rCZ8a4>ef$%840KbDmT)x`J1)xN&L%Rmoc(&o9IocSzYZveatBGFxPx*|e~3s4Ip zK92Mb84gxX0s;BfG^g6w`1qCAqAeKu97$|t>71ljIX}}Yq>@6nmP9>L`tl3uG|(M)$igdANWe?;jXI+@i|%si{$gT?7BNT{uu?^UiHV)n zuxM4Sy_cqX>pCedQaDuWb-ZJi?oQwJnHcL{GJ1owf7$t#D*};3h;aCz!gNVAc6J<> zTdz=Yf;NDbS}?TYHsU>)Wx>zI^$ObjWdJ}?JhL`SVKz<+2oH`N`%N4rgd{mmOHNC!~hXtzilD|=OH5y$AdVFf?DVUsHiR{^j&p~=j)V?bGuK&jMt{AQ) z3ao+KMW9)yDDnau~O;BpgrFA9n#4mUYU@k8@ z)|)=^ch%$7Ut$aI!K@||43?} z3pMogM1w0Qe6}|L)&=^84gd&Peqb4#uTP)bSXfxpiy%nfUmoD!u)5$M5c+euJk z4V{A{Bhbbdq2Y<<-@1Ih;XSX{(H8hDhPM%5I)dzlE=RTez*v0XO$vSIUgYEXEx{k&i_> z>hWg&c?&c=&E+@yRZK_|SWL29 zo?8Y__%j^DGb9KIK=TOK$61o7!GEn`)i&eYf+QwIYIWA59Lw|1FiryC2Jt2Wa0Re7C!g?#fDtN(k!aNPSB9L?Ex|ayYV>`h%;w}mrqv@!XRo8R9QkvSE z^CaFQIWH_URM&kzZu)G)6+%cls1O6?bvxj5m+3CpJ|Vj?Nt_l+Vq#*xC3(5I1~<|S zKDez{j{MUJc^?AwzyPT7z+(Ky)vH&5H@`i;<99`=a0s?@-L9te^z`(xR#hM$Ke(8= z4Gj%tWsZzvEGOlF4A3uR1T|4e6YdmNo!U8Pe$V=+13=MNsodw@8~AMDUXvey*%Aot z^@1%)7VJcq8ggl zj2C9_>OQA@LPEl!4-SY!FxF(de7jND7=-rZ2&;1&bt zEY@xCfX{%ESp!oR4_l%|uLw*LIF@Z|Yy18C_X|u2Q>7-bcahT!DoNDw@iAVrimK|d zS0h@aTAdjN*9Q3TlTRiTvgEbfmLh`#1=xX-#*<&R)w_ZvN(H#MxR*fz=O``||f8HyIEfpcmL$9hqMJ3sX|H-VdgX9{wY@@6|B{_ppl^A8_B1eTcr24CW1 zTEQMbkky~>9{{LOw&&*O_rP%=q=9CU%aX|7L<5cCc}G6VnFMv^8DWYE;og8fIH>?tWJ<;f*+z_FB@w^6`%eQ<5yToUy5 zQ&iWlU&&ln!*d-mv#QknG>EJp4q%f@!1>$AYNa|ev_6>Mw$88=vK5X7latBoCRt)S zU_dxrHR4WrP#i~t6Of$9&zPAha7%D`R}dZ_!xDpp$Ts@=Y>DWOq=Q@VyC5GOf9CJV z< zFcJM<7ueVtTbR24zc1i>9bEz!y!22}cUCfRrLlLkGqtcbp>cM%H=(hxcQ!&G+)`(E z@NgW|7#V*lc6Q0kDbJZ e@7V`g7Q_n4E$1C^t~j^_LPk>IX|cGz|NjD6BQ6jC literal 0 HcmV?d00001 diff --git a/react/public/manifest.json b/react/public/manifest.json new file mode 100644 index 000000000..77e70d6b0 --- /dev/null +++ b/react/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "MLPerf Mobile", + "name": "MLPerf Mobile", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/react/public/robots.txt b/react/public/robots.txt new file mode 100644 index 000000000..e69de29bb diff --git a/react/src/App.css b/react/src/App.css new file mode 100644 index 000000000..74b5e0534 --- /dev/null +++ b/react/src/App.css @@ -0,0 +1,38 @@ +.App { + text-align: center; +} + +.App-logo { + height: 40vmin; + pointer-events: none; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/react/src/App.test.tsx b/react/src/App.test.tsx new file mode 100644 index 000000000..d76787ed6 --- /dev/null +++ b/react/src/App.test.tsx @@ -0,0 +1,9 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import App from "./App"; + +test("renders learn react link", () => { + render(); + const linkElement = screen.getByText(/learn react/i); + expect(linkElement).toBeInTheDocument(); +}); diff --git a/react/src/App.tsx b/react/src/App.tsx new file mode 100644 index 000000000..0b4782ff6 --- /dev/null +++ b/react/src/App.tsx @@ -0,0 +1,28 @@ +import React from "react"; +import { ChakraProvider } from "@chakra-ui/react"; +import { BrowserRouter } from "react-router-dom"; +import "./App.css"; +import theme from "./styles/theme"; +import Router from "./modules/Router"; +import AppQueryClient from "./AppQueryClient"; +import store, { persistedStore } from "./store"; +import { Provider as ReduxProvider } from "react-redux"; +import { PersistGate } from "redux-persist/integration/react"; + +function App() { + return ( + + + + + + + + + + + + ); +} + +export default App; diff --git a/react/src/AppQueryClient.tsx b/react/src/AppQueryClient.tsx new file mode 100644 index 000000000..e908b6120 --- /dev/null +++ b/react/src/AppQueryClient.tsx @@ -0,0 +1,29 @@ +import AsyncStorage from "@react-native-async-storage/async-storage"; +import { QueryClient } from "@tanstack/react-query"; +import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client"; +import { createAsyncStoragePersister } from "@tanstack/query-async-storage-persister"; + +function AppQueryClient({ children }: any) { + const queryClient = new QueryClient({ + defaultOptions: { + queries: { + gcTime: 1000 * 60 * 60 * 24, // 24 hours + }, + }, + }); + + const asyncStoragePersister = createAsyncStoragePersister({ + storage: AsyncStorage, + }); + + return ( + + {children} + + ); +} + +export default AppQueryClient; diff --git a/react/src/assets/MLCommonsLogo.svg b/react/src/assets/MLCommonsLogo.svg new file mode 100644 index 000000000..e09abb4ff --- /dev/null +++ b/react/src/assets/MLCommonsLogo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/react/src/assets/icons/ic_image_classification.svg b/react/src/assets/icons/ic_image_classification.svg new file mode 100644 index 000000000..b02ac5bdd --- /dev/null +++ b/react/src/assets/icons/ic_image_classification.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/react/src/assets/icons/ic_image_classification_offline.svg b/react/src/assets/icons/ic_image_classification_offline.svg new file mode 100644 index 000000000..e3bba115c --- /dev/null +++ b/react/src/assets/icons/ic_image_classification_offline.svg @@ -0,0 +1,22 @@ + + + + + + diff --git a/react/src/assets/icons/ic_image_classification_offline_white.svg b/react/src/assets/icons/ic_image_classification_offline_white.svg new file mode 100644 index 000000000..2455d1f8e --- /dev/null +++ b/react/src/assets/icons/ic_image_classification_offline_white.svg @@ -0,0 +1,22 @@ + + + + + + diff --git a/react/src/assets/icons/ic_image_segmentation.svg b/react/src/assets/icons/ic_image_segmentation.svg new file mode 100644 index 000000000..4c5f897c9 --- /dev/null +++ b/react/src/assets/icons/ic_image_segmentation.svg @@ -0,0 +1,23 @@ + + + + + + diff --git a/react/src/assets/icons/ic_language_processing.svg b/react/src/assets/icons/ic_language_processing.svg new file mode 100644 index 000000000..ddacf9ceb --- /dev/null +++ b/react/src/assets/icons/ic_language_processing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/react/src/assets/icons/ic_object_detection.svg b/react/src/assets/icons/ic_object_detection.svg new file mode 100644 index 000000000..c22c94092 --- /dev/null +++ b/react/src/assets/icons/ic_object_detection.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/react/src/assets/icons/ic_offline_image_classification.svg b/react/src/assets/icons/ic_offline_image_classification.svg new file mode 100644 index 000000000..20441ae49 --- /dev/null +++ b/react/src/assets/icons/ic_offline_image_classification.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/react/src/assets/icons/ic_super_resolution.svg b/react/src/assets/icons/ic_super_resolution.svg new file mode 100644 index 000000000..56caf7a9c --- /dev/null +++ b/react/src/assets/icons/ic_super_resolution.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/react/src/constants/breakpoints.ts b/react/src/constants/breakpoints.ts new file mode 100644 index 000000000..8f968426f --- /dev/null +++ b/react/src/constants/breakpoints.ts @@ -0,0 +1,12 @@ +const breakpoints = { + sm: "30em", // 480px + c_525: "525px", //525px + csm: "39em", // 624px + md: "48em", // 768px + lg: "62em", // 992px + xl: "80em", // 1280px + "2xl": "96em", // 1536px + "3xl": "1600px", +}; + +export default breakpoints; diff --git a/react/src/constants/constants.ts b/react/src/constants/constants.ts new file mode 100644 index 000000000..d08bdb681 --- /dev/null +++ b/react/src/constants/constants.ts @@ -0,0 +1,45 @@ +export const QUERY_KEY = { + BENCHMARKS: "benchmarks", + USER: "user", +}; + +export class StringValue { + static unknown: string = "unknown"; + static apple: string = "Apple"; +} + +export class BenchmarkId { + static readonly imageClassification = "image_classification"; + static readonly objectDetection = "object_detection"; + static readonly imageSegmentationV2 = "image_segmentation_v2"; + static readonly naturalLanguageProcessing = "natural_language_processing"; + static readonly imageClassificationOffline = "image_classification_offline"; + static readonly superResolution = "super_resolution"; + + static readonly allIds = [ + BenchmarkId.imageClassification, + BenchmarkId.objectDetection, + BenchmarkId.imageSegmentationV2, + BenchmarkId.naturalLanguageProcessing, + BenchmarkId.imageClassificationOffline, + BenchmarkId.superResolution, + ]; +} + +export class BackendId { + static readonly tflite = "libtflitebackend"; + static readonly pixel = "libtflitepixelbackend"; + static readonly mediatek = "libtfliteneuronbackend"; + static readonly samsung = "libsamsungbackend"; + static readonly qti = "libqtibackend"; + static readonly apple = "libcoremlbackend"; + + static readonly allIds = [ + BackendId.tflite, + BackendId.pixel, + BackendId.mediatek, + BackendId.samsung, + BackendId.qti, + BackendId.apple, + ]; +} diff --git a/react/src/constants/moduleTypes.ts b/react/src/constants/moduleTypes.ts new file mode 100644 index 000000000..3effa4cf5 --- /dev/null +++ b/react/src/constants/moduleTypes.ts @@ -0,0 +1,5 @@ +const enum ModuleTypes { + benchmarks = "benchmarks", +} + +export default ModuleTypes; diff --git a/react/src/constants/sidebarLinks.ts b/react/src/constants/sidebarLinks.ts new file mode 100644 index 000000000..2e5a3b69a --- /dev/null +++ b/react/src/constants/sidebarLinks.ts @@ -0,0 +1,9 @@ +const sidebarLinks = { + BENCHMARKS: { + module: "benchmarks", + path: "benchmarks", + label: "BENCHMARKS", + }, +}; + +export default sidebarLinks; diff --git a/react/src/firebase-config.ts b/react/src/firebase-config.ts new file mode 100644 index 000000000..a46f1abf2 --- /dev/null +++ b/react/src/firebase-config.ts @@ -0,0 +1,16 @@ +import { initializeApp } from "firebase/app"; + +const firebaseConfig = { + apiKey: process.env['REACT_APP_FIREBASE_WEB_API_KEY'], + authDomain: process.env['REACT_APP_FIREBASE_WEB_AUTH_DOMAIN'], + databaseURL: process.env['REACT_APP_FIREBASE_DATABASE_URL'], + projectId: process.env['REACT_APP_FIREBASE_PROJECT_ID'], + storageBucket: process.env['REACT_APP_FIREBASE_STORAGE_BUCKET'], + messagingSenderId: process.env['REACT_APP_FIREBASE_MESSAGING_SENDER_ID'], + appId: process.env['REACT_APP_FIREBASE_WEB_APP_ID'], + measurementId: process.env['REACT_APP_FIREBASE_WEB_MEASUREMENT_ID'], +}; + +const app = initializeApp(firebaseConfig); + +export { app }; diff --git a/react/src/index.css b/react/src/index.css new file mode 100644 index 000000000..4a1df4db7 --- /dev/null +++ b/react/src/index.css @@ -0,0 +1,13 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", + "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", + monospace; +} diff --git a/react/src/index.tsx b/react/src/index.tsx new file mode 100644 index 000000000..4fa2a47f5 --- /dev/null +++ b/react/src/index.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./App"; +import reportWebVitals from "./reportWebVitals"; + +const root = ReactDOM.createRoot( + document.getElementById("root") as HTMLElement, +); +root.render( + + + , +); + +// If you want to start measuring performance in your app, pass a function +// to log results (for example: reportWebVitals(console.log)) +// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals +reportWebVitals(); diff --git a/react/src/modules/Router.tsx b/react/src/modules/Router.tsx new file mode 100644 index 000000000..daa6633f2 --- /dev/null +++ b/react/src/modules/Router.tsx @@ -0,0 +1,45 @@ +import * as React from "react"; +import { Navigate, Route, Routes } from "react-router-dom"; +import { PropsWithChildren, Suspense } from "react"; +import CenterSpinner from "../sharedComponents/CenterSpinner"; +import { useUser } from "./auth/hooks/useUser"; +import { useIsRestoring } from "@tanstack/react-query"; + +const Login = React.lazy(() => import("./auth/components/Login.page")); + +const BenchmarkList = React.lazy( + () => import("./benchmarks/components/BenchmarkList.page"), +); +const Main = React.lazy(() => import("./main/components/Main.page")); + +const GuardedRoute = ({ children }: PropsWithChildren) => { + const user = useUser(); + const isRestoring = useIsRestoring(); + if (isRestoring) return ; + if (!user) return ; + return <>{children}; +}; + +const Router = () => { + return ( + + + } /> + + +
+ + } + > + } /> + } /> + + + + ); +}; + +export default Router; diff --git a/react/src/modules/auth/components/Login.page.tsx b/react/src/modules/auth/components/Login.page.tsx new file mode 100644 index 000000000..c39ee5b53 --- /dev/null +++ b/react/src/modules/auth/components/Login.page.tsx @@ -0,0 +1,164 @@ +import { + Box, + Flex, + Text, + Input, + Button, + InputGroup, + InputRightElement, + chakra, + Icon, +} from "@chakra-ui/react"; +import * as yup from "yup"; +import { useForm } from "react-hook-form"; +import { yupResolver } from "@hookform/resolvers/yup"; + +import { useState } from "react"; +import { FiEye, FiEyeOff } from "react-icons/fi"; +import { useLoginMutation } from "../hooks/useLoginMutation"; +import { ReactComponent as MLCommonsLogo } from "../../../assets/MLCommonsLogo.svg"; + +export type FormValTypes = { + email: string; + password: string; +}; + +const initialValues = { + email: "", + password: "", +}; + +const schema = yup.object().shape({ + email: yup.string().required("Email is a required field"), + password: yup.string().required("Password is a required field"), +}); + +const LoginPage = () => { + const { mutate, isPending } = useLoginMutation(); + const [show, setShow] = useState(false); + + const handleClick = () => setShow(!show); + + const hookFormVals = useForm({ + resolver: yupResolver(schema), + defaultValues: initialValues, + }); + const { register, handleSubmit, formState } = hookFormVals; + const { errors } = formState as any; + + const onSubmit = async (formData: FormValTypes) => { + mutate(formData); + }; + + const renderErr = (errKey: string) => { + const message = errors[errKey]?.message; + + return ( + + {message} + + ); + }; + + return ( + + + + + + + + + + v.trim(), + })} + /> + {errors?.email?.message && renderErr("email")} + + {/* ====== */} + + + + + + {errors?.password?.message && renderErr("password")} + + + {/**/} + {/* */} + {/**/} + + + + + + + + ); +}; + +export default LoginPage; diff --git a/react/src/modules/auth/hooks/useLoginMutation.ts b/react/src/modules/auth/hooks/useLoginMutation.ts new file mode 100644 index 000000000..af3326c10 --- /dev/null +++ b/react/src/modules/auth/hooks/useLoginMutation.ts @@ -0,0 +1,43 @@ +import { loginUser } from "../services/authService"; +import { useNavigate } from "react-router-dom"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { QUERY_KEY } from "../../../constants/constants"; +import { useToast } from "@chakra-ui/react"; + +export type FormValTypes = { + email: string; + password: string; +}; + +const signIn = async (formData: FormValTypes) => { + const body = { + ...formData, + }; + return await loginUser(body.email, body.password); +}; + +export const useLoginMutation = () => { + const navigate = useNavigate(); + const queryClient = useQueryClient(); + const toast = useToast(); + + return useMutation({ + mutationFn: signIn, + onSuccess(response) { + const user = response; + if (user) { + queryClient.setQueryData([QUERY_KEY.USER], user); + navigate("/benchmarks"); + } + }, + onError(error) { + toast({ + title: "Login Error", + description: "Login Failed.", + status: "error", + duration: 4000, + isClosable: true, + }); + }, + }); +}; diff --git a/react/src/modules/auth/hooks/useLogoutMutation.ts b/react/src/modules/auth/hooks/useLogoutMutation.ts new file mode 100644 index 000000000..4d65e6e72 --- /dev/null +++ b/react/src/modules/auth/hooks/useLogoutMutation.ts @@ -0,0 +1,22 @@ +import { logoutUser } from "../services/authService"; +import { useNavigate } from "react-router-dom"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { QUERY_KEY } from "../../../constants/constants"; + +const logOut = async () => { + return await logoutUser(); +}; + +export const useLogoutMutation = () => { + const navigate = useNavigate(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: logOut, + onSuccess(response) { + console.log("Successfully logout"); + queryClient.setQueryData([QUERY_KEY.USER], null); + navigate("/auth/sign-in"); + }, + }); +}; diff --git a/react/src/modules/auth/hooks/useUser.ts b/react/src/modules/auth/hooks/useUser.ts new file mode 100644 index 000000000..a4e87bd00 --- /dev/null +++ b/react/src/modules/auth/hooks/useUser.ts @@ -0,0 +1,8 @@ +import { useQueryClient } from "@tanstack/react-query"; +import { QUERY_KEY } from "../../../constants/constants"; +import { UserType } from "../models/user.model"; + +export const useUser = (): UserType | undefined => { + const queryClient = useQueryClient(); + return queryClient.getQueryData([QUERY_KEY.USER]); +}; diff --git a/react/src/modules/auth/models/user.model.ts b/react/src/modules/auth/models/user.model.ts new file mode 100644 index 000000000..aea390454 --- /dev/null +++ b/react/src/modules/auth/models/user.model.ts @@ -0,0 +1,4 @@ +export type UserType = { + email: string; + uid: string; +}; diff --git a/react/src/modules/auth/services/authService.ts b/react/src/modules/auth/services/authService.ts new file mode 100644 index 000000000..da50e43ea --- /dev/null +++ b/react/src/modules/auth/services/authService.ts @@ -0,0 +1,8 @@ +import { logOut, signIn } from "../../../services/firebaseAuthService"; +export const loginUser = async (email: string, password: string) => { + return signIn(email, password); +}; + +export const logoutUser = async () => { + return logOut(); +}; diff --git a/react/src/modules/benchmarks/components/BenchmarkDrawerContent.tsx b/react/src/modules/benchmarks/components/BenchmarkDrawerContent.tsx new file mode 100644 index 000000000..e32a7e9cd --- /dev/null +++ b/react/src/modules/benchmarks/components/BenchmarkDrawerContent.tsx @@ -0,0 +1,119 @@ +import { BenchmarkRun, Result } from "../models/benchmarks.model"; +import { Box, Divider, Heading, Icon, List, ListItem } from "@chakra-ui/react"; +import { useUser } from "../../auth/hooks/useUser"; +import { useBenchmarks } from "../hooks/useBenchmarks"; +import { GrClose } from "react-icons/gr"; + +type Props = { + onClose: any; + benchmarkId: string; +}; + +const BenchmarkDrawerContent = ({ onClose, benchmarkId }: Props) => { + const user = useUser(); + const { getBenchmarkById } = useBenchmarks(user?.uid); + + const benchmark = getBenchmarkById(benchmarkId); + + const makeBody = (benchmark: Result) => { + const mainInfo = makeMainInfo(benchmark); + const performanceRun = benchmark.performance_run + ? makePerformanceInfo(benchmark.performance_run) + : [makeSubHeader("N/A")]; + const accuracyRun = benchmark.accuracy_run + ? makeAccuracyInfo(benchmark.accuracy_run) + : [makeSubHeader("N/A")]; + return [ + ...mainInfo, + , + makeHeader("Perf", "Performance run"), + ...performanceRun, + , + makeHeader("Accuracy", "Accuracy run"), + ...accuracyRun, + ]; + }; + + const makeMainInfo = (res: Result) => { + return [ + makeInfo("Benchmark Name", res.benchmark_name), + makeInfo("Scenario", res.loadgen_scenario), + makeInfo("Backend Name", res.backend_info.backend_name), + makeInfo("Vendor Name", res.backend_info.backend_name), + makeInfo("Delegate", res.backend_settings.delegate), + makeInfo("Accelerator", res.backend_info.accelerator_name), + res.loadgen_scenario === "Offline" && + makeInfo("Batch Size", res.backend_settings.batch_size.toString()), + ]; + }; + + const makePerformanceInfo = (perf: BenchmarkRun) => { + return [ + makeInfo("QPS", perf.throughput?.value ?? "N/A"), + makeInfo( + "Run is valid", + perf.loadgen_info?.validity.toString() ?? "false", + ), + makeInfo("Duration", formatDuration(perf.measured_duration)), + makeInfo("Samples count", perf.measured_samples.toString()), + makeInfo("Dataset Type", perf.dataset.type), + makeInfo("Dataset Name", perf.dataset.name), + ]; + }; + + const makeAccuracyInfo = (accuracy: BenchmarkRun) => { + return [ + makeInfo("Accuracy", accuracy.accuracy?.formatted ?? "N/A"), + makeInfo("Duration", formatDuration(accuracy.measured_duration)), + makeInfo("Samples", accuracy.measured_samples.toString()), + makeInfo("Dataset Type", accuracy.dataset.type), + makeInfo("Dataset Name", accuracy.dataset.name), + ]; + }; + + const makeInfo = (label: string, value: string | number) => ( + + {label}: {value} + + ); + + const makeHeader = (title: string, translationKey: string) => ( + + {translationKey} + + ); + + const makeSubHeader = (translationKey: string) => ( + + {translationKey} + + ); + + const formatDuration = (seconds: number) => { + // Implement formatDuration function as per your requirements + return `${seconds} seconds`; // Placeholder implementation + }; + + const onCloseDrawer = (e: React.SyntheticEvent) => { + e.stopPropagation(); + onClose(); + }; + + return ( + + {benchmark?.benchmark_name} + {benchmark && {makeBody(benchmark)}} + + + ); +}; + +export default BenchmarkDrawerContent; diff --git a/react/src/modules/benchmarks/components/BenchmarkList.page.tsx b/react/src/modules/benchmarks/components/BenchmarkList.page.tsx new file mode 100644 index 000000000..719b8c29a --- /dev/null +++ b/react/src/modules/benchmarks/components/BenchmarkList.page.tsx @@ -0,0 +1,44 @@ +import { useBenchmarks } from "../hooks/useBenchmarks"; +import { ChakraProvider, useDisclosure } from "@chakra-ui/react"; +import React, { useState } from "react"; +import { useUser } from "../../auth/hooks/useUser"; +import BenchmarkTableDrawer from "./BenchmarkTableDrawer"; +import BenchmarksTable from "./BenchmarksTable"; +import { BenchmarkResultItem } from "../models/benchmarks.model"; +import CenterSpinner from "../../../sharedComponents/CenterSpinner"; + +const BenchmarkListPage = () => { + const { isOpen, onClose, onOpen } = useDisclosure(); + + const user = useUser(); + const { benchmarks, isLoading } = useBenchmarks(user?.uid); + + const [benchmarkId, setBenchmarkId] = useState(); + const onInternalClose = () => { + setBenchmarkId(null); + onClose(); + }; + + const onInternalOpen = (data: BenchmarkResultItem) => { + setBenchmarkId(data.id); + onOpen(); + }; + + return ( + + {benchmarks && ( + + )} + {isLoading && } + {benchmarkId && ( + + )} + + ); +}; + +export default BenchmarkListPage; diff --git a/react/src/modules/benchmarks/components/BenchmarkTableDrawer.tsx b/react/src/modules/benchmarks/components/BenchmarkTableDrawer.tsx new file mode 100644 index 000000000..bfde846ee --- /dev/null +++ b/react/src/modules/benchmarks/components/BenchmarkTableDrawer.tsx @@ -0,0 +1,52 @@ +import React from "react"; + +import { Flex, type FlexProps } from "@chakra-ui/react"; +import { motion } from "framer-motion"; +import BenchmarkDrawerContent from "./BenchmarkDrawerContent"; + +const MotionFlex = motion(Flex); + +type Props = { + isOpen: boolean; + onClose: () => void; + benchmarkId: string; +}; + +const BenchmarkTableDrawer = ({ isOpen, onClose, benchmarkId }: Props) => { + const drawerRef = React.useRef(null); + + const getDrawerContents = () => { + return ( + + ); + }; + + return ( + + {getDrawerContents()} + + ); +}; + +export default BenchmarkTableDrawer; diff --git a/react/src/modules/benchmarks/components/BenchmarksTable.tsx b/react/src/modules/benchmarks/components/BenchmarksTable.tsx new file mode 100644 index 000000000..f072333c5 --- /dev/null +++ b/react/src/modules/benchmarks/components/BenchmarksTable.tsx @@ -0,0 +1,21 @@ +import { DataTable } from "../../../sharedComponents/DataTable"; +import * as benchmarkTableDataSource from "../services/benchmarksTableDataSource"; +import React from "react"; +import { BenchmarkResultItem, Result } from "../models/benchmarks.model"; + +type BenchmarksTableProps = { + data: Result[]; + onClick: (data: BenchmarkResultItem) => void; +}; + +const BenchmarksTable = ({ data, onClick }: BenchmarksTableProps) => { + return ( + + ); +}; + +export default BenchmarksTable; diff --git a/react/src/modules/benchmarks/hooks/useBenchmarks.ts b/react/src/modules/benchmarks/hooks/useBenchmarks.ts new file mode 100644 index 000000000..e44756d0a --- /dev/null +++ b/react/src/modules/benchmarks/hooks/useBenchmarks.ts @@ -0,0 +1,57 @@ +import * as benchmarksDataService from "../services/benchmarksDataService"; +import { + keepPreviousData, + useQuery, + useQueryClient, +} from "@tanstack/react-query"; +import { BenchmarkResult, Result } from "../models/benchmarks.model"; +import { QUERY_KEY } from "../../../constants/constants"; +import { useFilters } from "../../filters/hooks/useFilters"; + +export const useBenchmarks = (userId: string | undefined) => { + const queryClient = useQueryClient(); + const { resultFilter } = useFilters(); + const benchmarkResults: BenchmarkResult[] | undefined = + queryClient.getQueryData([QUERY_KEY.BENCHMARKS, userId]); + + const { + data: benchmarks, + isLoading, + error, + } = useQuery({ + queryFn: ({ queryKey }) => + benchmarksDataService.downloadResults(userId, benchmarkResults), + queryKey: [QUERY_KEY.BENCHMARKS, userId], + select: (data) => { + return data + .map((benchmarkResult) => { + // Check if the filter matches, or if no filter is set + if (resultFilter ? resultFilter.match(benchmarkResult) : true) { + // Expand each result with the platform and id property + return benchmarkResult.results.map((result) => ({ + ...result, + platform: benchmarkResult.environment_info.platform, + id: `${composeId(result)}`, + })); + } + return []; + }) + .filter((results) => results.length > 0) + .flat() + .filter((result) => resultFilter.matchBenchmark(result)); + }, + placeholderData: keepPreviousData, + }); + + const getBenchmarkById = (id: string) => { + return benchmarks?.find((benchmark) => benchmark.id === id); + }; + + return { benchmarks, getBenchmarkById, isLoading, error }; +}; + +const composeId = (item: Result) => { + const prDate = item.performance_run?.start_datetime; + const arDate = item.accuracy_run?.start_datetime; + return `${item.benchmark_id}_${prDate || arDate}`; +}; diff --git a/react/src/modules/benchmarks/models/benchmarks.model.ts b/react/src/modules/benchmarks/models/benchmarks.model.ts new file mode 100644 index 000000000..07be9db01 --- /dev/null +++ b/react/src/modules/benchmarks/models/benchmarks.model.ts @@ -0,0 +1,118 @@ +export type BenchmarkResultItem = { + id: string; + benchmarkId: string; + benchmarkName?: string; + backendName?: string; + delegateName?: string; + acceleratorName?: string; + date?: string; + score?: string; + platform?: string; +}; + +export type BenchmarkResult = { + meta: Meta; + results: Result[]; + environment_info: EnvironmentInfo; + build_info: BuildInfo; +}; + +export type Meta = { + uuid: string; + upload_date: string; + creation_date: string; +}; + +export type Result = { + id: string; + benchmark_id: string; + benchmark_name: string; + loadgen_scenario: string; + backend_settings: BackendSettings; + backend_info: BackendInfo; + performance_run: BenchmarkRun; + accuracy_run: BenchmarkRun; + min_duration: number; + min_samples: number; + platform: string; +}; + +export type BackendSettings = { + accelerator_code: string; + accelerator_desc: string; + framework: string; + delegate: string; + model_path: string; + batch_size: string; + extra_settings: [any]; +}; + +export type BackendInfo = { + filename: string; + vendor_name: string; + backend_name: string; + accelerator_name: string; +}; + +export type BenchmarkRun = { + throughput: Throughput; + accuracy: Accuracy; + dataset: DataSet; + measured_duration: number; + measured_samples: number; + start_datetime: string; + loadgen_info: any; +}; + +export type Throughput = { + value: number; +}; + +export type Accuracy = { + normilezed: number; + formatted: string; +}; + +export type DataSet = { + name: string; + type: string; + data_path: string; + groundtruth_path: string; +}; + +export type EnvironmentInfo = { + platform: string; + value: { + android: { + os_version: string; + manufacturer: string; + model_code: string; + model_name: string; + board_code: string; + proc_cpuinfo_soc_name: string; + props: any[]; + }; + ios: { + os_version: string; + model_code: string; + model_name: string; + soc_name: string; + }; + windows: { + os_version: string; + cpu_full_name: string; + }; + }; +}; + +export type BuildInfo = { + version: string; + build_number: string; + build_date: string; + official_release_flag: boolean; + dev_test_flag: boolean; + backend_list: string[]; + git_branch: string; + git_commit: string; + git_dirty_flag: string; +}; diff --git a/react/src/modules/benchmarks/services/benchmarksDataService.ts b/react/src/modules/benchmarks/services/benchmarksDataService.ts new file mode 100644 index 000000000..b43d762d7 --- /dev/null +++ b/react/src/modules/benchmarks/services/benchmarksDataService.ts @@ -0,0 +1,49 @@ +import * as firebaseStorageService from "../../../services/firebaseStorageService"; +import axios from "axios"; +import { convertBlobToJson } from "../../../utilities/utilities"; +import { BenchmarkResult } from "../models/benchmarks.model"; + +export const listResults = async (userId: string | undefined) => { + if (userId) { + return firebaseStorageService.listItems(`user/${userId}/result`); + } + return Promise.resolve(null); +}; + +export const downloadResults = async ( + userId: string | undefined, + benchmarkResults: BenchmarkResult[] | undefined, +) => { + const results: BenchmarkResult[] = benchmarkResults + ? [...benchmarkResults] + : []; + if (userId) { + const items = await firebaseStorageService.listItems( + `user/${userId}/result`, + ); + const benchmarkResultsIds = benchmarkResults?.map( + (benchmarkResult) => benchmarkResult.meta.uuid, + ); + for (const item of items) { + const resultUuid = item.name.replace(".json", "").split("_")[1]; + if (benchmarkResultsIds?.includes(resultUuid)) { + continue; + } + const itemUrl = await firebaseStorageService.getDownloadUrl(item.path); + const jsonObj = await downloadFile(itemUrl); + results.push(jsonObj as BenchmarkResult); + } + } + return results; +}; + +const downloadFile = async (fileUrl: string) => { + axios.defaults.headers.post["Access-Control-Allow-Origin"] = "*"; + return axios + .get(fileUrl, { + responseType: "blob", + }) + .then((result) => { + return convertBlobToJson(result.data); + }); +}; diff --git a/react/src/modules/benchmarks/services/benchmarksTableDataSource.ts b/react/src/modules/benchmarks/services/benchmarksTableDataSource.ts new file mode 100644 index 000000000..21030b7c1 --- /dev/null +++ b/react/src/modules/benchmarks/services/benchmarksTableDataSource.ts @@ -0,0 +1,77 @@ +import { BenchmarkResultItem, Result } from "../models/benchmarks.model"; +import { formatDateTime } from "../../../utilities/timeUtils"; +import { createColumnHelper } from "@tanstack/react-table"; + +const itemScore = (item: Result) => { + const throughput = item.performance_run?.throughput; + const accuracy = item.accuracy_run?.accuracy; + if (throughput != null) { + return throughput.value.toFixed(2); + } + if (accuracy != null) { + return accuracy.formatted; + } + return "unknown"; +}; + +const itemDateTime = (item: Result) => { + const prDateTime = item.performance_run?.start_datetime; + const arDateTime = item.accuracy_run?.start_datetime; + if (prDateTime != null) { + return formatDateTime(new Date(prDateTime)); + } + if (arDateTime != null) { + return formatDateTime(new Date(arDateTime)); + } + return "unknown"; +}; + +export const data = (items: Result[]): BenchmarkResultItem[] => { + return items?.map((item) => { + return { + id: item.id, + benchmarkId: item.benchmark_id, + benchmarkName: item.benchmark_name, + backendName: item.backend_info.backend_name, + delegateName: item.backend_settings.delegate, + acceleratorName: item.backend_info.accelerator_name, + date: itemDateTime(item), + score: itemScore(item), + platform: item.platform, + }; + }); +}; + +export const columns = () => { + const columnHelper = createColumnHelper(); + return [ + columnHelper.accessor("platform", { + cell: (info) => info.getValue(), + header: "Platform", + }), + columnHelper.accessor("benchmarkName", { + cell: (info) => info.getValue(), + header: "Benchmark Name", + }), + columnHelper.accessor("backendName", { + cell: (info) => info.getValue(), + header: "Backend Name", + }), + columnHelper.accessor("delegateName", { + cell: (info) => info.getValue(), + header: "Delegate Name", + }), + columnHelper.accessor("acceleratorName", { + cell: (info) => info.getValue(), + header: "Accelerator Name", + }), + columnHelper.accessor("date", { + cell: (info) => info.getValue(), + header: "Date", + }), + columnHelper.accessor("score", { + cell: (info) => info.getValue(), + header: "Item Score", + }), + ]; +}; diff --git a/react/src/modules/filters/components/BackendFilter.tsx b/react/src/modules/filters/components/BackendFilter.tsx new file mode 100644 index 000000000..5e61566e7 --- /dev/null +++ b/react/src/modules/filters/components/BackendFilter.tsx @@ -0,0 +1,44 @@ +import React from "react"; +import { Select, Flex, Text, SimpleGrid } from "@chakra-ui/react"; +import { Controller, Control, UseFormRegister } from "react-hook-form"; +import { ResultFilterType } from "../models/filters.model"; +import { BackendId } from "../../../constants/constants"; + +type Props = { + control: Control; + register: UseFormRegister; + renderErr: any; +}; + +const BackendFilter = ({ control, register, renderErr }: Props) => { + return ( + + + Backend: + + + { + return ( + + ); + }} + /> + + + ); +}; + +export default BackendFilter; diff --git a/react/src/modules/filters/components/BenchmarkIdFilter.tsx b/react/src/modules/filters/components/BenchmarkIdFilter.tsx new file mode 100644 index 000000000..c9c52855d --- /dev/null +++ b/react/src/modules/filters/components/BenchmarkIdFilter.tsx @@ -0,0 +1,44 @@ +import React from "react"; +import { Select, Flex, Text, SimpleGrid } from "@chakra-ui/react"; +import { Controller, Control, UseFormRegister } from "react-hook-form"; +import { ResultFilterType } from "../models/filters.model"; +import { BenchmarkId } from "../../../constants/constants"; + +type Props = { + control: Control; + register: UseFormRegister; + renderErr: any; +}; + +const BenchmarkIdFilter = ({ control, register }: Props) => { + return ( + + + Benchmark: + + + { + return ( + + ); + }} + /> + + + ); +}; + +export default BenchmarkIdFilter; diff --git a/react/src/modules/filters/components/DateFilter.tsx b/react/src/modules/filters/components/DateFilter.tsx new file mode 100644 index 000000000..87750cd95 --- /dev/null +++ b/react/src/modules/filters/components/DateFilter.tsx @@ -0,0 +1,59 @@ +import { Control, Controller } from "react-hook-form"; +import { ResultFilterType } from "../models/filters.model"; +import { Flex, SimpleGrid, Text } from "@chakra-ui/react"; +import DatePicker from "react-date-picker"; +import React from "react"; +import { css } from "@emotion/react"; + +type Props = { + control: Control; + renderErr: any; +}; + +const DateFilter = ({ control, renderErr }: Props) => { + return ( + + + From Creation Date: + + + { + const { value, onChange } = field; + return ( + onChange(newDate)} + /> + ); + }} + /> + {renderErr("localStartDate")} + + + ); +}; + +export default DateFilter; + +const datePickerWrapperStyles = css` + .react-date-picker__wrapper { + /* border: 0px !important; */ + /* border-top: 0px; */ + border: 0px !important; + border-bottom: 1px solid #cbd8f1 !important; + height: 40px; + text-indent: 10px; + } + .date-filter { + background: #e4ecfc; + border: 1px solid #cbd8f1; + box-sizing: border-box; + border-radius: 40px; + } +`; diff --git a/react/src/modules/filters/components/DeviceModelFilter.tsx b/react/src/modules/filters/components/DeviceModelFilter.tsx new file mode 100644 index 000000000..f8b0526f4 --- /dev/null +++ b/react/src/modules/filters/components/DeviceModelFilter.tsx @@ -0,0 +1,40 @@ +import React from "react"; +import { Flex, Text, SimpleGrid, Input } from "@chakra-ui/react"; +import { Controller, Control, UseFormRegister } from "react-hook-form"; +import { ResultFilterType } from "../models/filters.model"; + +type Props = { + control: Control; + register: UseFormRegister; + renderErr: any; +}; + +const DeviceModelFilter = ({ control, register, renderErr }: Props) => { + return ( + + + Device Model: + + + { + return ( + + ); + }} + /> + + + ); +}; + +export default DeviceModelFilter; diff --git a/react/src/modules/filters/components/FiltersForm.tsx b/react/src/modules/filters/components/FiltersForm.tsx new file mode 100644 index 000000000..b86af17a5 --- /dev/null +++ b/react/src/modules/filters/components/FiltersForm.tsx @@ -0,0 +1,139 @@ +import { Button, Flex, Text } from "@chakra-ui/react"; +import React from "react"; +import { useForm } from "react-hook-form"; +import { yupResolver } from "@hookform/resolvers/yup"; +import * as yup from "yup"; +import { partialRight } from "ramda"; +import { ResultFilter, ResultFilterType } from "../models/filters.model"; +import { useFilters } from "../hooks/useFilters"; +import PlatformFilter from "./PlatformFilter"; +import DateFilter from "./DateFilter"; +import BenchmarkIdFilter from "./BenchmarkIdFilter"; +import BackendFilter from "./BackendFilter"; +import DeviceModelFilter from "./DeviceModelFilter"; +import ManufacturerFilter from "./ManufacturerFilter"; +import SoCFilter from "./SoCFilter"; + +const schema = yup.object().shape({ + fromCreationDate: yup.date().nullable(), + toCreationDate: yup.date().nullable(), + platform: yup.string().nullable(), + deviceModel: yup.string().nullable(), + backend: yup.string().nullable(), + manufacturer: yup.string().nullable(), + soc: yup.string().nullable(), + benchmarkId: yup.string().nullable(), +}); + +type Props = { + onClose: () => void; +}; + +const FiltersForm = ({ onClose }: Props) => { + const { resultFilter, setResultFilter } = useFilters(); + const { handleSubmit, control, formState, register, reset } = + useForm({ + resolver: yupResolver(schema), + defaultValues: { + fromCreationDate: resultFilter.fromCreationDate, + toCreationDate: resultFilter.toCreationDate, + platform: resultFilter.platform, + deviceModel: resultFilter.deviceModel, + backend: resultFilter.backend, + manufacturer: resultFilter.manufacturer, + soc: resultFilter.soc, + benchmarkId: resultFilter.benchmarkId, + }, + }); + + const renderInputErr = ( + errKey: string, + errors: any, + styles?: Record, + ) => { + const message = errors[errKey]?.message; + return ( + message && ( + + {message} + + ) + ); + }; + + const { errors } = formState; + const renderErr = partialRight(renderInputErr, [errors]); + + const onFormReset = () => { + const formValues = { + fromCreationDate: null, + toCreationDate: null, + platform: null, + deviceModel: null, + backend: null, + manufacturer: null, + soc: null, + benchmarkId: null, + }; + reset(formValues); + setResultFilter(new ResultFilter(formValues)); + }; + const onSubmit = (formValues: ResultFilterType) => { + setResultFilter(new ResultFilter(formValues)); + onClose(); + }; + + return ( + +
+ + + + + + + + + + + + +
+ ); +}; +export default FiltersForm; diff --git a/react/src/modules/filters/components/FiltersModal.tsx b/react/src/modules/filters/components/FiltersModal.tsx new file mode 100644 index 000000000..0944153ae --- /dev/null +++ b/react/src/modules/filters/components/FiltersModal.tsx @@ -0,0 +1,41 @@ +import { + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalBody, + ModalCloseButton, +} from "@chakra-ui/react"; + +import FiltersForm from "./FiltersForm"; + +type Props = { + disclosureProps: any; +}; + +const FiltersModal = ({ disclosureProps }: Props) => { + const { onClose, isOpen } = disclosureProps; + + return ( + + + + + Benchmark Filters + + + + + + + + ); +}; + +export default FiltersModal; diff --git a/react/src/modules/filters/components/ManufacturerFilter.tsx b/react/src/modules/filters/components/ManufacturerFilter.tsx new file mode 100644 index 000000000..1110d0388 --- /dev/null +++ b/react/src/modules/filters/components/ManufacturerFilter.tsx @@ -0,0 +1,40 @@ +import React from "react"; +import { Flex, Text, SimpleGrid, Input } from "@chakra-ui/react"; +import { Controller, Control, UseFormRegister } from "react-hook-form"; +import { ResultFilterType } from "../models/filters.model"; + +type Props = { + control: Control; + register: UseFormRegister; + renderErr: any; +}; + +const ManufacturerFilter = ({ control, register, renderErr }: Props) => { + return ( + + + Manufacturer: + + + { + return ( + + ); + }} + /> + + + ); +}; + +export default ManufacturerFilter; diff --git a/react/src/modules/filters/components/PlatformFilter.tsx b/react/src/modules/filters/components/PlatformFilter.tsx new file mode 100644 index 000000000..c1578c481 --- /dev/null +++ b/react/src/modules/filters/components/PlatformFilter.tsx @@ -0,0 +1,44 @@ +import React from "react"; +import { Select, Flex, Text, SimpleGrid } from "@chakra-ui/react"; +import { Controller, Control, UseFormRegister } from "react-hook-form"; +import { Platform, ResultFilterType } from "../models/filters.model"; + +type Props = { + control: Control; + register: UseFormRegister; + renderErr: any; +}; + +const PlatformFilter = ({ control, register, renderErr }: Props) => { + return ( + + + Platform: + + + { + return ( + + ); + }} + /> + {renderErr("localStartDate")} + + + ); +}; + +export default PlatformFilter; diff --git a/react/src/modules/filters/components/SoCFilter.tsx b/react/src/modules/filters/components/SoCFilter.tsx new file mode 100644 index 000000000..c919d0ca8 --- /dev/null +++ b/react/src/modules/filters/components/SoCFilter.tsx @@ -0,0 +1,40 @@ +import React from "react"; +import { Flex, Text, SimpleGrid, Input } from "@chakra-ui/react"; +import { Controller, Control, UseFormRegister } from "react-hook-form"; +import { ResultFilterType } from "../models/filters.model"; + +type Props = { + control: Control; + register: UseFormRegister; + renderErr: any; +}; + +const SoCFilter = ({ control, register, renderErr }: Props) => { + return ( + + + SoC: + + + { + return ( + + ); + }} + /> + + + ); +}; + +export default SoCFilter; diff --git a/react/src/modules/filters/hooks/useFilters.ts b/react/src/modules/filters/hooks/useFilters.ts new file mode 100644 index 000000000..3a5865375 --- /dev/null +++ b/react/src/modules/filters/hooks/useFilters.ts @@ -0,0 +1,25 @@ +import { useDispatch, useSelector } from "react-redux"; +import { ResultFilter, ResultFilterType } from "../models/filters.model"; +import { filtersSlice, selectFilters } from "../store/filters.store"; + +export const useFilters = () => { + const dispatch = useDispatch(); + const actions = filtersSlice.actions; + + const { setFilters } = actions; + + const resultFilter = new ResultFilter(useSelector(selectFilters) || {}); + + const isFilterActive = Object.values(resultFilter).some( + (value) => value !== null, + ); + + const setResultFilter = (resultFilter: ResultFilterType) => + dispatch(setFilters(resultFilter)); + + return { + isFilterActive, + resultFilter, + setResultFilter, + }; +}; diff --git a/react/src/modules/filters/models/filters.model.ts b/react/src/modules/filters/models/filters.model.ts new file mode 100644 index 000000000..a9c01ec59 --- /dev/null +++ b/react/src/modules/filters/models/filters.model.ts @@ -0,0 +1,125 @@ +import { + BenchmarkResult, + EnvironmentInfo, + Result, +} from "../../benchmarks/models/benchmarks.model"; +import { StringValue } from "../../../constants/constants"; + +export enum Platform { + Android = "android", + iOS = "ios", + Windows = "windows", +} + +export interface ResultFilterType { + fromCreationDate?: Date | null; + toCreationDate?: Date | null; + platform?: string | null; + deviceModel?: string | null; + backend?: string | null; + manufacturer?: string | null; + soc?: string | null; + benchmarkId?: string | null; +} + +export class ResultFilter implements ResultFilterType { + fromCreationDate: Date | null; + toCreationDate: Date | null; + platform: string | null; + deviceModel: string | null; + backend: string | null; + manufacturer: string | null; + soc: string | null; + benchmarkId: string | null; + + constructor(filter: ResultFilterType = {}) { + this.fromCreationDate = filter.fromCreationDate ?? null; + this.toCreationDate = filter.toCreationDate ?? null; + this.platform = filter.platform ?? null; + this.deviceModel = filter.deviceModel ?? null; + this.backend = filter.backend ?? null; + this.manufacturer = filter.manufacturer ?? null; + this.soc = filter.soc ?? null; + this.benchmarkId = filter.benchmarkId ?? null; + } + + match(result: BenchmarkResult) { + const { deviceModel, manufacturer, soc } = this.getDeviceDetails( + result.environment_info, + ); + const resultCreationDate = new Date(result.meta.creation_date); + const resultBackend = result.results[0].backend_info.filename; + + const platformMatches = + this.platform === null || + this.platform === result.environment_info.platform; + const backendMatches = + this.backend === null || this.backend === resultBackend; + + return ( + this.isDateWithinRange( + resultCreationDate, + this.fromCreationDate, + this.toCreationDate, + ) && + platformMatches && + this.stringMatches(deviceModel, this.deviceModel) && + this.stringMatches(manufacturer, this.manufacturer) && + this.stringMatches(soc, this.soc) && + backendMatches + ); + } + + getDeviceDetails(envInfo: EnvironmentInfo) { + switch (envInfo.platform) { + case Platform.Android: + return { + deviceModel: envInfo.value.android?.model_name ?? StringValue.unknown, + manufacturer: + envInfo.value.android?.manufacturer ?? StringValue.unknown, + soc: + envInfo.value.android?.proc_cpuinfo_soc_name ?? StringValue.unknown, + }; + case Platform.iOS: + return { + deviceModel: envInfo.value.ios?.model_name ?? StringValue.unknown, + manufacturer: "Apple", + soc: envInfo.value.ios?.soc_name ?? StringValue.unknown, + }; + case Platform.Windows: + return { + deviceModel: + envInfo.value.windows?.cpu_full_name ?? StringValue.unknown, + manufacturer: StringValue.unknown, + soc: envInfo.value.windows?.cpu_full_name ?? StringValue.unknown, + }; + default: + return { + deviceModel: StringValue.unknown, + manufacturer: StringValue.unknown, + soc: StringValue.unknown, + }; + } + } + + // Helper function for date comparison + isDateWithinRange(date: Date, fromDate: Date | null, toDate: Date | null) { + const oneDay = 24 * 60 * 60 * 1000; + const toDateAdjusted = toDate ? new Date(toDate.getTime() + oneDay) : null; + return ( + (!fromDate || date > fromDate) && + (!toDateAdjusted || date < toDateAdjusted) + ); + } + + // Helper function for string matching + stringMatches(value: string, pattern: string | null) { + return value.toLowerCase().includes((pattern ?? "").toLowerCase()); + } + + matchBenchmark(result: Result): boolean { + return this.benchmarkId == null + ? true + : result.benchmark_id === this.benchmarkId; + } +} diff --git a/react/src/modules/filters/store/filters.store.ts b/react/src/modules/filters/store/filters.store.ts new file mode 100644 index 000000000..dbd98a8f1 --- /dev/null +++ b/react/src/modules/filters/store/filters.store.ts @@ -0,0 +1,25 @@ +import { createSlice, PayloadAction } from "@reduxjs/toolkit"; +import { ResultFilterType } from "../models/filters.model"; + +interface FiltersState { + resultFilter: ResultFilterType | null; +} + +const initialState: FiltersState = { + resultFilter: null, +}; + +export const filtersSlice = createSlice({ + name: "filtersState", + initialState, + reducers: { + setFilters: (state, { payload }: PayloadAction) => { + state.resultFilter = payload; + }, + }, +}); + +export const filtersReducer = filtersSlice.reducer; + +export const selectFilters = (state: any): ResultFilterType => + state.filtersState.resultFilter; diff --git a/react/src/modules/main/components/Main.page.tsx b/react/src/modules/main/components/Main.page.tsx new file mode 100644 index 000000000..f14a7dcf6 --- /dev/null +++ b/react/src/modules/main/components/Main.page.tsx @@ -0,0 +1,26 @@ +import { Box } from "@chakra-ui/react"; + +import React from "react"; + +import MainContent from "./MainContent"; +import MenuContent from "./MenuContent"; + +const Main = () => { + const menuFlexStyle = { + flexDir: "column", + minW: { base: "15%", lg: "220px" }, + display: { base: "none", xl: "flex" }, + fontWeight: "bold", + overflowY: "hidden", + }; + return ( + + + + + + + ); +}; + +export default Main; diff --git a/react/src/modules/main/components/MainContent.tsx b/react/src/modules/main/components/MainContent.tsx new file mode 100644 index 000000000..9e5cbdd5f --- /dev/null +++ b/react/src/modules/main/components/MainContent.tsx @@ -0,0 +1,17 @@ +import { Flex, useDisclosure } from "@chakra-ui/react"; +import { Outlet } from "react-router-dom"; +import React from "react"; +import ResponsiveMenuHeader from "./ResponsiveMenuHeader"; + +const MainContentWithHeader = () => { + const { onToggle, isOpen } = useDisclosure(); + + return ( + + + + + ); +}; + +export default MainContentWithHeader; diff --git a/react/src/modules/main/components/MenuContent.tsx b/react/src/modules/main/components/MenuContent.tsx new file mode 100644 index 000000000..5be117fe0 --- /dev/null +++ b/react/src/modules/main/components/MenuContent.tsx @@ -0,0 +1,95 @@ +import { + Accordion, + AccordionButton, + AccordionItem, + Flex, + HStack, + Icon, + Text, +} from "@chakra-ui/react"; +import ModuleTypes from "../../../constants/moduleTypes"; +import { Link, useLocation } from "react-router-dom"; +import sidebarLinks from "../../../constants/sidebarLinks"; +import theme from "../../../styles/theme"; +import React from "react"; + +import { ReactComponent as MLCommonsLogo } from "../../../assets/MLCommonsLogo.svg"; +import { useLogoutMutation } from "../../auth/hooks/useLogoutMutation"; + +type Props = { + flexStyle: any; +}; + +const MenuContent = ({ flexStyle }: Props) => { + const { pathname: currPath } = useLocation(); + const currModule = currPath.split("/")[1]; + const { mutate: logout } = useLogoutMutation(); + + const onLogout = () => { + console.log("onLogout"); + logout(); + }; + + const getBgColor = (moduleType: string) => { + return currModule === moduleType ? hoverColor : "transparent"; + }; + const hoverColor = "#E3EBFC"; + + return ( + + + + + + + + + + + Benchmarks + + + + + + + + Logout + + + + + Version: {1.0} + + + + ); +}; + +export default MenuContent; diff --git a/react/src/modules/main/components/ResponsiveMenuHeader.tsx b/react/src/modules/main/components/ResponsiveMenuHeader.tsx new file mode 100644 index 000000000..48e9151c0 --- /dev/null +++ b/react/src/modules/main/components/ResponsiveMenuHeader.tsx @@ -0,0 +1,126 @@ +import { useState, useEffect } from "react"; +import { + Flex, + useDisclosure, + useMediaQuery, + Box, + IconButton, +} from "@chakra-ui/react"; +import ChakraBreakpoints from "../../../constants/breakpoints"; +import { useLocation } from "react-router-dom"; +import { css } from "@emotion/react"; +import sidebarLinks from "../../../constants/sidebarLinks"; +import TabletNavigationDrawer from "./TabletNavigationDrawer"; +import { FaFilter } from "react-icons/fa"; +import FiltersModal from "../../filters/components/FiltersModal"; +import { useFilters } from "../../filters/hooks/useFilters"; + +type Props = { + onToggle: () => void; + isOpen: boolean; +}; + +const getOptions = (currPath: string) => { + const sideBarLinksVals = Object.values(sidebarLinks); + const pathString = currPath.slice(1); + const currentLink = sideBarLinksVals.find((item) => { + const { path } = item; + if (path === pathString) return true; + return null; + }); + const currentModule = currentLink?.module; + return sideBarLinksVals.reduce( + (acc: { value: string; label: string }[], curr: any) => { + const { label, path, module } = curr; + if (currentModule === module) { + acc = [...acc, { value: path, label }]; + } + return acc; + }, + [], + ); +}; + +const ResponsiveMenuHeader = ({ onToggle, isOpen }: Props) => { + const { pathname: currPath } = useLocation(); + + const options = getOptions(currPath); + + const matchedPath = options.find( + (item) => item?.value === currPath?.slice(1), + ); + const initVal = matchedPath?.value ?? options[0]?.value; + + const [currSelectVal, setCurrSelectVal] = useState(initVal); + + const { isFilterActive } = useFilters(); + + useEffect(() => { + if (currSelectVal !== initVal) { + setCurrSelectVal(initVal); + } + }, [currPath, currSelectVal, initVal]); + + const [isBelowXl] = useMediaQuery(`(max-width: ${ChakraBreakpoints.xl})`); + + const isDrawerVisible = isBelowXl; + + const disclosureProps = useDisclosure(); + const { onOpen } = disclosureProps; + + type FilterIconProps = { + onClick: any; + }; + + const FilterIcon = ({ onClick }: FilterIconProps) => { + return ( + + } + onClick={onOpen} + aria-label="Filter" + variant="ghost" + color={isFilterActive ? "blue" : "gray"} + /> + + ); + }; + + const renderFullHeader = () => ( + + + + {isDrawerVisible ? ( + + {" "} + + + ) : null} + + ); + + return renderFullHeader(); +}; + +export default ResponsiveMenuHeader; diff --git a/react/src/modules/main/components/TabletNavigationDrawer.tsx b/react/src/modules/main/components/TabletNavigationDrawer.tsx new file mode 100644 index 000000000..724a670f2 --- /dev/null +++ b/react/src/modules/main/components/TabletNavigationDrawer.tsx @@ -0,0 +1,62 @@ +import React from "react"; +import { + Drawer, + DrawerBody, + DrawerFooter, + DrawerOverlay, + DrawerContent, + useDisclosure, + Button, + Icon, + IconButton, +} from "@chakra-ui/react"; +import { GiHamburgerMenu } from "react-icons/gi"; +import MenuContent from "./MenuContent"; + +const TabletNavigationDrawer = () => { + const { isOpen, onOpen, onClose } = useDisclosure(); + + const menuFlexStyle = { + flexDir: "column", + w: "100%", + display: "flex", + bg: "#fff", + pb: "20px", + fontSize: "30px", + fontWeight: "bold", + overflowY: "hidden", + }; + + return ( + <> + } + /> + + + + + + + + + + + + + + ); +}; + +export default TabletNavigationDrawer; diff --git a/react/src/reportWebVitals.ts b/react/src/reportWebVitals.ts new file mode 100644 index 000000000..5fa3583b7 --- /dev/null +++ b/react/src/reportWebVitals.ts @@ -0,0 +1,15 @@ +import { ReportHandler } from "web-vitals"; + +const reportWebVitals = (onPerfEntry?: ReportHandler) => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/react/src/services/firebaseAuthService.ts b/react/src/services/firebaseAuthService.ts new file mode 100644 index 000000000..c33c46191 --- /dev/null +++ b/react/src/services/firebaseAuthService.ts @@ -0,0 +1,20 @@ +import { getAuth, signInWithEmailAndPassword, signOut } from "firebase/auth"; +import { app } from "../firebase-config"; + +const auth = getAuth(app); + +const signIn = async (email: string, password: string) => { + return signInWithEmailAndPassword(auth, email, password).then( + (userCredential) => { + // Signed in + const userObj = userCredential.user; + return { email: userObj.email || "", uid: userObj.uid }; + }, + ); +}; + +const logOut = async () => { + return signOut(auth); +}; + +export { signIn, logOut }; diff --git a/react/src/services/firebaseStorageService.ts b/react/src/services/firebaseStorageService.ts new file mode 100644 index 000000000..e0ce2c954 --- /dev/null +++ b/react/src/services/firebaseStorageService.ts @@ -0,0 +1,26 @@ +import { ref, listAll, getDownloadURL, getStorage } from "firebase/storage"; +import { app } from "../firebase-config"; + +const storage = getStorage(app); + +const listItems = async (path: string) => { + const listRef = ref(storage, path); + return listAll(listRef) + .then((res) => { + return res.items.map((item) => { + return { + name: item.name, + path: item.fullPath, + }; + }); + }) + .catch((error) => { + return []; + }); +}; + +const getDownloadUrl = async (itemPath: string) => { + return getDownloadURL(ref(storage, itemPath)); +}; + +export { listItems, getDownloadUrl }; diff --git a/react/src/setupTests.ts b/react/src/setupTests.ts new file mode 100644 index 000000000..1dd407a63 --- /dev/null +++ b/react/src/setupTests.ts @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import "@testing-library/jest-dom"; diff --git a/react/src/sharedComponents/CenterSpinner.tsx b/react/src/sharedComponents/CenterSpinner.tsx new file mode 100644 index 000000000..f8c3c2f56 --- /dev/null +++ b/react/src/sharedComponents/CenterSpinner.tsx @@ -0,0 +1,18 @@ +import { Flex, CircularProgress } from "@chakra-ui/react"; + +type Props = { + color?: string; + [key: string]: unknown; +}; + +const CenterSpinner = ({ color, ...rest }: Props) => ( + + + +); + +export default CenterSpinner; diff --git a/react/src/sharedComponents/DataTable.tsx b/react/src/sharedComponents/DataTable.tsx new file mode 100644 index 000000000..e39652b91 --- /dev/null +++ b/react/src/sharedComponents/DataTable.tsx @@ -0,0 +1,94 @@ +import * as React from "react"; +import { Table, Thead, Tbody, Tr, Th, Td, chakra } from "@chakra-ui/react"; +import { TriangleDownIcon, TriangleUpIcon } from "@chakra-ui/icons"; +import { + useReactTable, + flexRender, + getCoreRowModel, + ColumnDef, + SortingState, + getSortedRowModel, +} from "@tanstack/react-table"; + +export type DataTableProps = { + data: Data[]; + columns: ColumnDef[]; + onClick: (data: Data) => void; +}; + +export function DataTable({ + data, + columns, + onClick, +}: Readonly>) { + const [sorting, setSorting] = React.useState([]); + const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + onSortingChange: setSorting, + getSortedRowModel: getSortedRowModel(), + state: { + sorting, + }, + }); + + const renderSortIcon = (isSorted: string | boolean) => { + if (isSorted) { + return isSorted === "desc" ? ( + + ) : ( + + ); + } + return null; + }; + + return ( + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + const meta: any = header.column.columnDef.meta; + return ( + + ); + })} + + ))} + + + {table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => { + const meta: any = cell.column.columnDef.meta; + return ( + + ); + })} + + ))} + +
+ {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + + {renderSortIcon(header.column.getIsSorted())} + +
onClick(row.original)} + > + {flexRender(cell.column.columnDef.cell, cell.getContext())} +
+ ); +} diff --git a/react/src/store/index.ts b/react/src/store/index.ts new file mode 100644 index 000000000..6d53133d0 --- /dev/null +++ b/react/src/store/index.ts @@ -0,0 +1,27 @@ +import { configureStore, combineReducers } from "@reduxjs/toolkit"; +import storage from "redux-persist/lib/storage"; +import { persistReducer, persistStore } from "redux-persist"; +import { filtersReducer } from "../modules/filters/store/filters.store"; + +const rootReducer = combineReducers({ + filtersState: filtersReducer, +}); + +const persistConfig = { + key: "root", + storage, +}; + +const persistedReducer = persistReducer(persistConfig, rootReducer); + +export const store = configureStore({ + reducer: persistedReducer, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware({ + serializableCheck: false, + }), +}); + +export const persistedStore = persistStore(store); + +export default store; diff --git a/react/src/styles/theme.ts b/react/src/styles/theme.ts new file mode 100644 index 000000000..cd68f6fb4 --- /dev/null +++ b/react/src/styles/theme.ts @@ -0,0 +1,20 @@ +import { extendTheme } from "@chakra-ui/react"; + +const theme = extendTheme({ + fonts: { + heading: "Montserrat, sans-serif", + body: "Open Sans, sans-serif", + }, + colors: { + brand: { + panelBg: "#E4ECFC", + purpleGradient: "linear(136.13deg, #4B21D6 -93.1%, #9536A6 125.01%)", + yellowGradient: + "linear-gradient(109.5deg, #EFA537 -138.01%, #F8DB68 109.9%)", + goldGradient: + "linear-gradient(99.36deg, #EFA537 -39.65%, #F8DB68 71.68%)", + }, + }, +}); + +export default theme; diff --git a/react/src/utilities/timeUtils.ts b/react/src/utilities/timeUtils.ts new file mode 100644 index 000000000..92efdf43f --- /dev/null +++ b/react/src/utilities/timeUtils.ts @@ -0,0 +1,25 @@ +import { format } from "date-fns"; + +function formatDuration(seconds: number): string { + let intSeconds = Math.ceil(seconds); + let minutes = Math.floor(intSeconds / 60); + intSeconds -= minutes * 60; + const hours = Math.floor(minutes / 60); + minutes -= hours * 60; + + const tokens: string[] = []; + if (hours !== 0) { + tokens.push(hours.toString().padStart(2, "0")); + } + tokens.push(minutes.toString().padStart(2, "0")); + tokens.push(intSeconds.toString().padStart(2, "0")); + + return tokens.join(":"); +} + +function formatDateTime(value: Date): string { + const dateFormat = "yyyy-MM-dd HH:mm:ss"; + return format(value, dateFormat); +} + +export { formatDuration, formatDateTime }; diff --git a/react/src/utilities/utilities.ts b/react/src/utilities/utilities.ts new file mode 100644 index 000000000..ecd5001cf --- /dev/null +++ b/react/src/utilities/utilities.ts @@ -0,0 +1,25 @@ +const convertBlobToJson = (blob: Blob) => { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => { + if (reader.result) { + try { + const result = JSON.parse(reader.result as string); + resolve(result); + } catch (error) { + console.error("Error parsing JSON:", error); + reject(error); + } + } + return null; + }; + + reader.onerror = (error) => { + reject(error); + }; + + reader.readAsText(blob); + }); +}; + +export { convertBlobToJson }; diff --git a/react/tsconfig.json b/react/tsconfig.json new file mode 100644 index 000000000..330969b76 --- /dev/null +++ b/react/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" + }, + "include": ["src", "additional-declarations.d.ts"] +} diff --git a/react/yarn.lock b/react/yarn.lock new file mode 100644 index 000000000..bf4574a99 --- /dev/null +++ b/react/yarn.lock @@ -0,0 +1,11801 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@adobe/css-tools@^4.0.1": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.2.tgz#a6abc715fb6884851fca9dad37fc34739a04fd11" + integrity sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw== + +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@apideck/better-ajv-errors@^0.3.1": + version "0.3.6" + resolved "https://registry.yarnpkg.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz#957d4c28e886a64a8141f7522783be65733ff097" + integrity sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA== + dependencies: + json-schema "^0.4.0" + jsonpointer "^5.0.0" + leven "^3.1.0" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.8.3": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.3", "@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== + +"@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.5.tgz#6e23f2acbcb77ad283c5ed141f824fd9f70101c7" + integrity sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.5" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.5" + "@babel/parser" "^7.23.5" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.5" + "@babel/types" "^7.23.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/eslint-parser@^7.16.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.23.3.tgz#7bf0db1c53b54da0c8a12627373554a0828479ca" + integrity sha512-9bTuNlyx7oSstodm1cR1bECj4fkiknsDa1YniISkJemMY3DGhJNYBECbe6QD/q54mp2J8VO66jW3/7uP//iFCw== + dependencies: + "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" + eslint-visitor-keys "^2.1.0" + semver "^6.3.1" + +"@babel/generator@^7.23.5", "@babel/generator@^7.7.2": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.5.tgz#17d0a1ea6b62f351d281350a5f80b87a810c4755" + integrity sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA== + dependencies: + "@babel/types" "^7.23.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" + integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.6": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" + integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.15" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz#2a8792357008ae9ce8c0f2b78b9f646ac96b314b" + integrity sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" + integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz#a71c10f7146d809f4a256c373f462d9bba8cf6ba" + integrity sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug== + dependencies: + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" + integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== + dependencies: + "@babel/types" "^7.23.0" + +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-remap-async-to-generator@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" + integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-wrap-function" "^7.22.20" + +"@babel/helper-replace-supers@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" + integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.22.15", "@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + +"@babel/helper-wrap-function@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" + integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/types" "^7.22.19" + +"@babel/helpers@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.5.tgz#52f522840df8f1a848d06ea6a79b79eefa72401e" + integrity sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.5" + "@babel/types" "^7.23.5" + +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.5.tgz#37dee97c4752af148e1d38c34b856b2507660563" + integrity sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz#5cd1c87ba9380d0afb78469292c954fee5d2411a" + integrity sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz#f6652bb16b94f8f9c20c50941e16e9756898dc5d" + integrity sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.23.3" + +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz#20c60d4639d18f7da8602548512e9d3a4c8d7098" + integrity sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-proposal-class-properties@^7.16.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-decorators@^7.16.4": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.5.tgz#eeaa49d0dc9229aec4d23378653738cdc5a3ea0a" + integrity sha512-6IsY8jOeWibsengGlWIezp7cuZEFzNlAghFpzh9wiZwhQ42/hRcPnY/QV9HJoKTlujupinSlnQPiEy/u2C1ZfQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.23.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/plugin-syntax-decorators" "^7.23.3" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.16.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" + integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-optional-chaining@^7.16.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" + integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.16.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" + integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + +"@babel/plugin-proposal-private-property-in-object@^7.21.11": + version "7.21.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz#69d597086b6760c4126525cfa154f34631ff272c" + integrity sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.21.0" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-decorators@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.23.3.tgz#a1d351d6c25bfdcf2e16f99b039101bc0ffcb0ca" + integrity sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-flow@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz#084564e0f3cc21ea6c70c44cff984a1c0509729a" + integrity sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-assertions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz#9c05a7f592982aff1a2768260ad84bcd3f0c77fc" + integrity sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-attributes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz#992aee922cf04512461d7dae3ff6951b90a2dc06" + integrity sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-meta@^7.10.4", "@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" + integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.23.3", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" + integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-arrow-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz#94c6dcfd731af90f27a79509f9ab7fb2120fc38b" + integrity sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-async-generator-functions@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz#93ac8e3531f347fba519b4703f9ff2a75c6ae27a" + integrity sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-transform-async-to-generator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz#d1f513c7a8a506d43f47df2bf25f9254b0b051fa" + integrity sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw== + dependencies: + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" + +"@babel/plugin-transform-block-scoped-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz#fe1177d715fb569663095e04f3598525d98e8c77" + integrity sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-block-scoping@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz#b2d38589531c6c80fbe25e6b58e763622d2d3cf5" + integrity sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz#35c377db11ca92a785a718b6aa4e3ed1eb65dc48" + integrity sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-static-block@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz#2a202c8787a8964dd11dfcedf994d36bfc844ab5" + integrity sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-transform-classes@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz#e7a75f815e0c534cc4c9a39c56636c84fc0d64f2" + integrity sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-split-export-declaration" "^7.22.6" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz#652e69561fcc9d2b50ba4f7ac7f60dcf65e86474" + integrity sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.15" + +"@babel/plugin-transform-destructuring@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz#8c9ee68228b12ae3dff986e56ed1ba4f3c446311" + integrity sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-dotall-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz#3f7af6054882ede89c378d0cf889b854a993da50" + integrity sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-duplicate-keys@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz#664706ca0a5dfe8d066537f99032fc1dc8b720ce" + integrity sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-dynamic-import@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz#c7629e7254011ac3630d47d7f34ddd40ca535143" + integrity sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-transform-exponentiation-operator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz#ea0d978f6b9232ba4722f3dbecdd18f450babd18" + integrity sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-export-namespace-from@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz#084c7b25e9a5c8271e987a08cf85807b80283191" + integrity sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-transform-flow-strip-types@^7.16.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz#cfa7ca159cc3306fab526fc67091556b51af26ff" + integrity sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-flow" "^7.23.3" + +"@babel/plugin-transform-for-of@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz#afe115ff0fbce735e02868d41489093c63e15559" + integrity sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-function-name@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz#8f424fcd862bf84cb9a1a6b42bc2f47ed630f8dc" + integrity sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw== + dependencies: + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-json-strings@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz#a871d9b6bd171976efad2e43e694c961ffa3714d" + integrity sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-transform-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz#8214665f00506ead73de157eba233e7381f3beb4" + integrity sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-logical-assignment-operators@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz#e599f82c51d55fac725f62ce55d3a0886279ecb5" + integrity sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz#e37b3f0502289f477ac0e776b05a833d853cabcc" + integrity sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-modules-amd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz#e19b55436a1416829df0a1afc495deedfae17f7d" + integrity sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-modules-commonjs@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz#661ae831b9577e52be57dd8356b734f9700b53b4" + integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + +"@babel/plugin-transform-modules-systemjs@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz#fa7e62248931cb15b9404f8052581c302dd9de81" + integrity sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ== + dependencies: + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/plugin-transform-modules-umd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz#5d4395fccd071dfefe6585a4411aa7d6b7d769e9" + integrity sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-new-target@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz#5491bb78ed6ac87e990957cea367eab781c4d980" + integrity sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz#45556aad123fc6e52189ea749e33ce090637346e" + integrity sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-transform-numeric-separator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz#03d08e3691e405804ecdd19dd278a40cca531f29" + integrity sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-transform-object-rest-spread@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz#2b9c2d26bf62710460bdc0d1730d4f1048361b83" + integrity sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g== + dependencies: + "@babel/compat-data" "^7.23.3" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.23.3" + +"@babel/plugin-transform-object-super@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz#81fdb636dcb306dd2e4e8fd80db5b2362ed2ebcd" + integrity sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + +"@babel/plugin-transform-optional-catch-binding@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz#318066de6dacce7d92fa244ae475aa8d91778017" + integrity sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-transform-optional-chaining@^7.23.3", "@babel/plugin-transform-optional-chaining@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz#6acf61203bdfc4de9d4e52e64490aeb3e52bd017" + integrity sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz#83ef5d1baf4b1072fa6e54b2b0999a7b2527e2af" + integrity sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-methods@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz#b2d7a3c97e278bfe59137a978d53b2c2e038c0e4" + integrity sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-property-in-object@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz#3ec711d05d6608fd173d9b8de39872d8dbf68bf5" + integrity sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz#54518f14ac4755d22b92162e4a852d308a560875" + integrity sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-react-constant-elements@^7.12.1": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz#5efc001d07ef0f7da0d73c3a86c132f73d28e43c" + integrity sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-react-display-name@^7.16.0", "@babel/plugin-transform-react-display-name@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz#70529f034dd1e561045ad3c8152a267f0d7b6200" + integrity sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-react-jsx-development@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz#e716b6edbef972a92165cd69d92f1255f7e73e87" + integrity sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.22.5" + +"@babel/plugin-transform-react-jsx@^7.22.15", "@babel/plugin-transform-react-jsx@^7.22.5": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz#393f99185110cea87184ea47bcb4a7b0c2e39312" + integrity sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/types" "^7.23.4" + +"@babel/plugin-transform-react-pure-annotations@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz#fabedbdb8ee40edf5da96f3ecfc6958e3783b93c" + integrity sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-regenerator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz#141afd4a2057298602069fce7f2dc5173e6c561c" + integrity sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.2" + +"@babel/plugin-transform-reserved-words@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz#4130dcee12bd3dd5705c587947eb715da12efac8" + integrity sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-runtime@^7.16.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.4.tgz#5132b388580002fc5cb7c84eccfb968acdc231cb" + integrity sha512-ITwqpb6V4btwUG0YJR82o2QvmWrLgDnx/p2A3CTPYGaRgULkDiC0DRA2C4jlRB9uXGUEfaSS/IGHfVW+ohzYDw== + dependencies: + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + babel-plugin-polyfill-corejs2 "^0.4.6" + babel-plugin-polyfill-corejs3 "^0.8.5" + babel-plugin-polyfill-regenerator "^0.5.3" + semver "^6.3.1" + +"@babel/plugin-transform-shorthand-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz#97d82a39b0e0c24f8a981568a8ed851745f59210" + integrity sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-spread@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz#41d17aacb12bde55168403c6f2d6bdca563d362c" + integrity sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + +"@babel/plugin-transform-sticky-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz#dec45588ab4a723cb579c609b294a3d1bd22ff04" + integrity sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-template-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz#5f0f028eb14e50b5d0f76be57f90045757539d07" + integrity sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-typeof-symbol@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz#9dfab97acc87495c0c449014eb9c547d8966bca4" + integrity sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-typescript@^7.23.3": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.5.tgz#83da13ef62a1ebddf2872487527094b31c9adb84" + integrity sha512-2fMkXEJkrmwgu2Bsv1Saxgj30IXZdJ+84lQcKKI7sm719oXs0BBw2ZENKdJdR1PjWndgLCEBNXJOri0fk7RYQA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.23.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.23.3" + +"@babel/plugin-transform-unicode-escapes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz#1f66d16cab01fab98d784867d24f70c1ca65b925" + integrity sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-property-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz#19e234129e5ffa7205010feec0d94c251083d7ad" + integrity sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz#26897708d8f42654ca4ce1b73e96140fbad879dc" + integrity sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-sets-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz#4fb6f0a719c2c5859d11f6b55a050cc987f3799e" + integrity sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.4": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.5.tgz#350a3aedfa9f119ad045b068886457e895ba0ca1" + integrity sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.23.3" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.23.3" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.23.3" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.23.3" + "@babel/plugin-syntax-import-attributes" "^7.23.3" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.23.3" + "@babel/plugin-transform-async-generator-functions" "^7.23.4" + "@babel/plugin-transform-async-to-generator" "^7.23.3" + "@babel/plugin-transform-block-scoped-functions" "^7.23.3" + "@babel/plugin-transform-block-scoping" "^7.23.4" + "@babel/plugin-transform-class-properties" "^7.23.3" + "@babel/plugin-transform-class-static-block" "^7.23.4" + "@babel/plugin-transform-classes" "^7.23.5" + "@babel/plugin-transform-computed-properties" "^7.23.3" + "@babel/plugin-transform-destructuring" "^7.23.3" + "@babel/plugin-transform-dotall-regex" "^7.23.3" + "@babel/plugin-transform-duplicate-keys" "^7.23.3" + "@babel/plugin-transform-dynamic-import" "^7.23.4" + "@babel/plugin-transform-exponentiation-operator" "^7.23.3" + "@babel/plugin-transform-export-namespace-from" "^7.23.4" + "@babel/plugin-transform-for-of" "^7.23.3" + "@babel/plugin-transform-function-name" "^7.23.3" + "@babel/plugin-transform-json-strings" "^7.23.4" + "@babel/plugin-transform-literals" "^7.23.3" + "@babel/plugin-transform-logical-assignment-operators" "^7.23.4" + "@babel/plugin-transform-member-expression-literals" "^7.23.3" + "@babel/plugin-transform-modules-amd" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-modules-systemjs" "^7.23.3" + "@babel/plugin-transform-modules-umd" "^7.23.3" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.23.3" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.23.4" + "@babel/plugin-transform-numeric-separator" "^7.23.4" + "@babel/plugin-transform-object-rest-spread" "^7.23.4" + "@babel/plugin-transform-object-super" "^7.23.3" + "@babel/plugin-transform-optional-catch-binding" "^7.23.4" + "@babel/plugin-transform-optional-chaining" "^7.23.4" + "@babel/plugin-transform-parameters" "^7.23.3" + "@babel/plugin-transform-private-methods" "^7.23.3" + "@babel/plugin-transform-private-property-in-object" "^7.23.4" + "@babel/plugin-transform-property-literals" "^7.23.3" + "@babel/plugin-transform-regenerator" "^7.23.3" + "@babel/plugin-transform-reserved-words" "^7.23.3" + "@babel/plugin-transform-shorthand-properties" "^7.23.3" + "@babel/plugin-transform-spread" "^7.23.3" + "@babel/plugin-transform-sticky-regex" "^7.23.3" + "@babel/plugin-transform-template-literals" "^7.23.3" + "@babel/plugin-transform-typeof-symbol" "^7.23.3" + "@babel/plugin-transform-unicode-escapes" "^7.23.3" + "@babel/plugin-transform-unicode-property-regex" "^7.23.3" + "@babel/plugin-transform-unicode-regex" "^7.23.3" + "@babel/plugin-transform-unicode-sets-regex" "^7.23.3" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.6" + babel-plugin-polyfill-corejs3 "^0.8.5" + babel-plugin-polyfill-regenerator "^0.5.3" + core-js-compat "^3.31.0" + semver "^6.3.1" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-react@^7.12.5", "@babel/preset-react@^7.16.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.23.3.tgz#f73ca07e7590f977db07eb54dbe46538cc015709" + integrity sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-transform-react-display-name" "^7.23.3" + "@babel/plugin-transform-react-jsx" "^7.22.15" + "@babel/plugin-transform-react-jsx-development" "^7.22.5" + "@babel/plugin-transform-react-pure-annotations" "^7.23.3" + +"@babel/preset-typescript@^7.16.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz#14534b34ed5b6d435aa05f1ae1c5e7adcc01d913" + integrity sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-typescript" "^7.23.3" + +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.5.tgz#11edb98f8aeec529b82b211028177679144242db" + integrity sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.22.15", "@babel/template@^7.3.3": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/traverse@^7.23.5", "@babel/traverse@^7.7.2": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.5.tgz#f546bf9aba9ef2b042c0e00d245990c15508e7ec" + integrity sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.5" + "@babel/types" "^7.23.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.4", "@babel/types@^7.23.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.5.tgz#48d730a00c95109fa4393352705954d74fb5b602" + integrity sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@chakra-ui/accordion@2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/accordion/-/accordion-2.3.1.tgz#a326509e286a5c4e8478de9bc2b4b05017039e6b" + integrity sha512-FSXRm8iClFyU+gVaXisOSEw0/4Q+qZbFRiuhIAkVU6Boj0FxAMrlo9a8AV5TuF77rgaHytCdHk0Ng+cyUijrag== + dependencies: + "@chakra-ui/descendant" "3.1.0" + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/transition" "2.1.0" + +"@chakra-ui/alert@2.2.2": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/alert/-/alert-2.2.2.tgz#aeba951d120c7c6e69d5f515a695ad6e4db43ffe" + integrity sha512-jHg4LYMRNOJH830ViLuicjb3F+v6iriE/2G5T+Sd0Hna04nukNJ1MxUmBPE+vI22me2dIflfelu2v9wdB6Pojw== + dependencies: + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/spinner" "2.1.0" + +"@chakra-ui/anatomy@2.2.2": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/anatomy/-/anatomy-2.2.2.tgz#2d0e14cba2534d92077ca28abf8c183b6e27897b" + integrity sha512-MV6D4VLRIHr4PkW4zMyqfrNS1mPlCTiCXwvYGtDFQYr+xHFfonhAuf9WjsSc0nyp2m0OdkSLnzmVKkZFLo25Tg== + +"@chakra-ui/avatar@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/avatar/-/avatar-2.3.0.tgz#f018a2714d1e3ba5970bcf66558887925fdfccf4" + integrity sha512-8gKSyLfygnaotbJbDMHDiJoF38OHXUYVme4gGxZ1fLnQEdPVEaIWfH+NndIjOM0z8S+YEFnT9KyGMUtvPrBk3g== + dependencies: + "@chakra-ui/image" "2.1.0" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/breadcrumb@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/breadcrumb/-/breadcrumb-2.2.0.tgz#751bc48498f3c403f97b5d9aae528ebfd405ef48" + integrity sha512-4cWCG24flYBxjruRi4RJREWTGF74L/KzI2CognAW/d/zWR0CjiScuJhf37Am3LFbCySP6WSoyBOtTIoTA4yLEA== + dependencies: + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/breakpoint-utils@2.0.8": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@chakra-ui/breakpoint-utils/-/breakpoint-utils-2.0.8.tgz#750d3712668b69f6e8917b45915cee0e08688eed" + integrity sha512-Pq32MlEX9fwb5j5xx8s18zJMARNHlQZH2VH1RZgfgRDpp7DcEgtRW5AInfN5CfqdHLO1dGxA7I3MqEuL5JnIsA== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/button@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/button/-/button-2.1.0.tgz#623ed32cc92fc8e52492923e9924791fc6f25447" + integrity sha512-95CplwlRKmmUXkdEp/21VkEWgnwcx2TOBG6NfYlsuLBDHSLlo5FKIiE2oSi4zXc4TLcopGcWPNcm/NDaSC5pvA== + dependencies: + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/spinner" "2.1.0" + +"@chakra-ui/card@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/card/-/card-2.2.0.tgz#b5e59dc51c171fced76ea76bf26088803b8bc184" + integrity sha512-xUB/k5MURj4CtPAhdSoXZidUbm8j3hci9vnc+eZJVDqhDOShNlD6QeniQNRPRys4lWAQLCbFcrwL29C8naDi6g== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/checkbox@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/checkbox/-/checkbox-2.3.2.tgz#4ecb14a2f57b7470d1a58542ca4691c3b105bfa1" + integrity sha512-85g38JIXMEv6M+AcyIGLh7igNtfpAN6KGQFYxY9tBj0eWvWk4NKQxvqqyVta0bSAyIl1rixNIIezNpNWk2iO4g== + dependencies: + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-callback-ref" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/visually-hidden" "2.2.0" + "@zag-js/focus-visible" "0.16.0" + +"@chakra-ui/clickable@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/clickable/-/clickable-2.1.0.tgz#800fa8d10cf45a41fc50a3df32c679a3ce1921c3" + integrity sha512-flRA/ClPUGPYabu+/GLREZVZr9j2uyyazCAUHAdrTUEdDYCr31SVGhgh7dgKdtq23bOvAQJpIJjw/0Bs0WvbXw== + dependencies: + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/close-button@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/close-button/-/close-button-2.1.1.tgz#995b245c56eb41465a71d8667840c238618a7b66" + integrity sha512-gnpENKOanKexswSVpVz7ojZEALl2x5qjLYNqSQGbxz+aP9sOXPfUS56ebyBrre7T7exuWGiFeRwnM0oVeGPaiw== + dependencies: + "@chakra-ui/icon" "3.2.0" + +"@chakra-ui/color-mode@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/color-mode/-/color-mode-2.2.0.tgz#828d47234c74ba2fb4c5dd63a63331aead20b9f6" + integrity sha512-niTEA8PALtMWRI9wJ4LL0CSBDo8NBfLNp4GD6/0hstcm3IlbBHTVKxN6HwSaoNYfphDQLxCjT4yG+0BJA5tFpg== + dependencies: + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + +"@chakra-ui/control-box@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/control-box/-/control-box-2.1.0.tgz#0f4586797b3154c02463bc5c106782e70c88f04f" + integrity sha512-gVrRDyXFdMd8E7rulL0SKeoljkLQiPITFnsyMO8EFHNZ+AHt5wK4LIguYVEq88APqAGZGfHFWXr79RYrNiE3Mg== + +"@chakra-ui/counter@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/counter/-/counter-2.1.0.tgz#e413a2f1093a18f847bb7aa240117fde788a59e6" + integrity sha512-s6hZAEcWT5zzjNz2JIWUBzRubo9la/oof1W7EKZVVfPYHERnl5e16FmBC79Yfq8p09LQ+aqFKm/etYoJMMgghw== + dependencies: + "@chakra-ui/number-utils" "2.0.7" + "@chakra-ui/react-use-callback-ref" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/css-reset@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/css-reset/-/css-reset-2.3.0.tgz#83e3160a9c2a12431cad0ee27ebfbf3aedc5c9c7" + integrity sha512-cQwwBy5O0jzvl0K7PLTLgp8ijqLPKyuEMiDXwYzl95seD3AoeuoCLyzZcJtVqaUZ573PiBdAbY/IlZcwDOItWg== + +"@chakra-ui/descendant@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/descendant/-/descendant-3.1.0.tgz#f3b80ed13ffc4bf1d615b3ed5541bd0905375cca" + integrity sha512-VxCIAir08g5w27klLyi7PVo8BxhW4tgU/lxQyujkmi4zx7hT9ZdrcQLAted/dAa+aSIZ14S1oV0Q9lGjsAdxUQ== + dependencies: + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + +"@chakra-ui/dom-utils@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/dom-utils/-/dom-utils-2.1.0.tgz#d15df89e458ef19756db04c7cfd084eb552454f0" + integrity sha512-ZmF2qRa1QZ0CMLU8M1zCfmw29DmPNtfjR9iTo74U5FPr3i1aoAh7fbJ4qAlZ197Xw9eAW28tvzQuoVWeL5C7fQ== + +"@chakra-ui/editable@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/editable/-/editable-3.1.0.tgz#065783c2e3389c3bb9ab0582cb50d38e1dc00fa1" + integrity sha512-j2JLrUL9wgg4YA6jLlbU88370eCRyor7DZQD9lzpY95tSOXpTljeg3uF9eOmDnCs6fxp3zDWIfkgMm/ExhcGTg== + dependencies: + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-callback-ref" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-focus-on-pointer-down" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/event-utils@2.0.8": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@chakra-ui/event-utils/-/event-utils-2.0.8.tgz#e6439ba200825a2f15d8f1973d267d1c00a6d1b4" + integrity sha512-IGM/yGUHS+8TOQrZGpAKOJl/xGBrmRYJrmbHfUE7zrG3PpQyXvbLDP1M+RggkCFVgHlJi2wpYIf0QtQlU0XZfw== + +"@chakra-ui/focus-lock@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/focus-lock/-/focus-lock-2.1.0.tgz#580e5450fe85356987b9a246abaff8333369c667" + integrity sha512-EmGx4PhWGjm4dpjRqM4Aa+rCWBxP+Rq8Uc/nAVnD4YVqkEhBkrPTpui2lnjsuxqNaZ24fIAZ10cF1hlpemte/w== + dependencies: + "@chakra-ui/dom-utils" "2.1.0" + react-focus-lock "^2.9.4" + +"@chakra-ui/form-control@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/form-control/-/form-control-2.2.0.tgz#69c771d6406ddac8ab357ae88446cc11827656a4" + integrity sha512-wehLC1t4fafCVJ2RvJQT2jyqsAwX7KymmiGqBu7nQoQz8ApTkGABWpo/QwDh3F/dBLrouHDoOvGmYTqft3Mirw== + dependencies: + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/hooks@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/hooks/-/hooks-2.2.1.tgz#b86ce5eeaaab877ddcb11a50842d1227306ace28" + integrity sha512-RQbTnzl6b1tBjbDPf9zGRo9rf/pQMholsOudTxjy4i9GfTfz6kgp5ValGjQm2z7ng6Z31N1cnjZ1AlSzQ//ZfQ== + dependencies: + "@chakra-ui/react-utils" "2.0.12" + "@chakra-ui/utils" "2.0.15" + compute-scroll-into-view "3.0.3" + copy-to-clipboard "3.3.3" + +"@chakra-ui/icon@3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/icon/-/icon-3.2.0.tgz#92b9454aa0d561b4994bcd6a1b3bb1fdd5c67bef" + integrity sha512-xxjGLvlX2Ys4H0iHrI16t74rG9EBcpFvJ3Y3B7KMQTrnW34Kf7Da/UC8J67Gtx85mTHW020ml85SVPKORWNNKQ== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/icons@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/icons/-/icons-2.1.1.tgz#58ff0f9e703f2f4f89debd600ce4e438f43f9c9a" + integrity sha512-3p30hdo4LlRZTT5CwoAJq3G9fHI0wDc0pBaMHj4SUn0yomO+RcDRlzhdXqdr5cVnzax44sqXJVnf3oQG0eI+4g== + dependencies: + "@chakra-ui/icon" "3.2.0" + +"@chakra-ui/image@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/image/-/image-2.1.0.tgz#6c205f1ca148e3bf58345b0b5d4eb3d959eb9f87" + integrity sha512-bskumBYKLiLMySIWDGcz0+D9Th0jPvmX6xnRMs4o92tT3Od/bW26lahmV2a2Op2ItXeCmRMY+XxJH5Gy1i46VA== + dependencies: + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/input@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/input/-/input-2.1.2.tgz#0cad49ec372f8f21f2f4f1db365f34b9a708ff9d" + integrity sha512-GiBbb3EqAA8Ph43yGa6Mc+kUPjh4Spmxp1Pkelr8qtudpc3p2PJOOebLpd90mcqw8UePPa+l6YhhPtp6o0irhw== + dependencies: + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/object-utils" "2.1.0" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/layout@2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/layout/-/layout-2.3.1.tgz#0601c5eb91555d24a7015a7c9d4e01fed2698557" + integrity sha512-nXuZ6WRbq0WdgnRgLw+QuxWAHuhDtVX8ElWqcTK+cSMFg/52eVP47czYBE5F35YhnoW2XBwfNoNgZ7+e8Z01Rg== + dependencies: + "@chakra-ui/breakpoint-utils" "2.0.8" + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/object-utils" "2.1.0" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/lazy-utils@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/lazy-utils/-/lazy-utils-2.0.5.tgz#363c3fa1d421362790b416ffa595acb835e1ae5b" + integrity sha512-UULqw7FBvcckQk2n3iPO56TMJvDsNv0FKZI6PlUNJVaGsPbsYxK/8IQ60vZgaTVPtVcjY6BE+y6zg8u9HOqpyg== + +"@chakra-ui/live-region@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/live-region/-/live-region-2.1.0.tgz#02b4b1d997075f19a7a9a87187e08c72e82ef0dd" + integrity sha512-ZOxFXwtaLIsXjqnszYYrVuswBhnIHHP+XIgK1vC6DePKtyK590Wg+0J0slDwThUAd4MSSIUa/nNX84x1GMphWw== + +"@chakra-ui/media-query@3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/media-query/-/media-query-3.3.0.tgz#40f9151dedb6a7af9df3be0474b59a799c92c619" + integrity sha512-IsTGgFLoICVoPRp9ykOgqmdMotJG0CnPsKvGQeSFOB/dZfIujdVb14TYxDU4+MURXry1MhJ7LzZhv+Ml7cr8/g== + dependencies: + "@chakra-ui/breakpoint-utils" "2.0.8" + "@chakra-ui/react-env" "3.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/menu@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/menu/-/menu-2.2.1.tgz#7d9810d435f6b40fa72ed867a33b88a1ef75073f" + integrity sha512-lJS7XEObzJxsOwWQh7yfG4H8FzFPRP5hVPN/CL+JzytEINCSBvsCDHrYPQGp7jzpCi8vnTqQQGQe0f8dwnXd2g== + dependencies: + "@chakra-ui/clickable" "2.1.0" + "@chakra-ui/descendant" "3.1.0" + "@chakra-ui/lazy-utils" "2.0.5" + "@chakra-ui/popper" "3.1.0" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-animation-state" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-disclosure" "2.1.0" + "@chakra-ui/react-use-focus-effect" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-outside-click" "2.2.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/transition" "2.1.0" + +"@chakra-ui/modal@2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/modal/-/modal-2.3.1.tgz#524dc32b6b4f545b54ae531dbf6c74e1052ee794" + integrity sha512-TQv1ZaiJMZN+rR9DK0snx/OPwmtaGH1HbZtlYt4W4s6CzyK541fxLRTjIXfEzIGpvNW+b6VFuFjbcR78p4DEoQ== + dependencies: + "@chakra-ui/close-button" "2.1.1" + "@chakra-ui/focus-lock" "2.1.0" + "@chakra-ui/portal" "2.1.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/transition" "2.1.0" + aria-hidden "^1.2.3" + react-remove-scroll "^2.5.6" + +"@chakra-ui/number-input@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/number-input/-/number-input-2.1.2.tgz#dda9095fba6a4b89212332db02831b94120da163" + integrity sha512-pfOdX02sqUN0qC2ysuvgVDiws7xZ20XDIlcNhva55Jgm095xjm8eVdIBfNm3SFbSUNxyXvLTW/YQanX74tKmuA== + dependencies: + "@chakra-ui/counter" "2.1.0" + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-callback-ref" "2.1.0" + "@chakra-ui/react-use-event-listener" "2.1.0" + "@chakra-ui/react-use-interval" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/number-utils@2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/number-utils/-/number-utils-2.0.7.tgz#aaee979ca2fb1923a0373a91619473811315db11" + integrity sha512-yOGxBjXNvLTBvQyhMDqGU0Oj26s91mbAlqKHiuw737AXHt0aPllOthVUqQMeaYLwLCjGMg0jtI7JReRzyi94Dg== + +"@chakra-ui/object-utils@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/object-utils/-/object-utils-2.1.0.tgz#a4ecf9cea92f1de09f5531f53ffdc41e0b19b6c3" + integrity sha512-tgIZOgLHaoti5PYGPTwK3t/cqtcycW0owaiOXoZOcpwwX/vlVb+H1jFsQyWiiwQVPt9RkoSLtxzXamx+aHH+bQ== + +"@chakra-ui/pin-input@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/pin-input/-/pin-input-2.1.0.tgz#61e6bbf909ec510634307b2861c4f1891a9f8d81" + integrity sha512-x4vBqLStDxJFMt+jdAHHS8jbh294O53CPQJoL4g228P513rHylV/uPscYUHrVJXRxsHfRztQO9k45jjTYaPRMw== + dependencies: + "@chakra-ui/descendant" "3.1.0" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/popover@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/popover/-/popover-2.2.1.tgz#89cfd29817abcd204da570073c0f2b4d8072c3a3" + integrity sha512-K+2ai2dD0ljvJnlrzesCDT9mNzLifE3noGKZ3QwLqd/K34Ym1W/0aL1ERSynrcG78NKoXS54SdEzkhCZ4Gn/Zg== + dependencies: + "@chakra-ui/close-button" "2.1.1" + "@chakra-ui/lazy-utils" "2.0.5" + "@chakra-ui/popper" "3.1.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-animation-state" "2.1.0" + "@chakra-ui/react-use-disclosure" "2.1.0" + "@chakra-ui/react-use-focus-effect" "2.1.0" + "@chakra-ui/react-use-focus-on-pointer-down" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/popper@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/popper/-/popper-3.1.0.tgz#92a9180c6894763af3b22a6003f9a9d958fe2659" + integrity sha512-ciDdpdYbeFG7og6/6J8lkTFxsSvwTdMLFkpVylAF6VNC22jssiWfquj2eyD4rJnzkRFPvIWJq8hvbfhsm+AjSg== + dependencies: + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@popperjs/core" "^2.9.3" + +"@chakra-ui/portal@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/portal/-/portal-2.1.0.tgz#9e7f57424d7041738b6563cac80134561080bd27" + integrity sha512-9q9KWf6SArEcIq1gGofNcFPSWEyl+MfJjEUg/un1SMlQjaROOh3zYr+6JAwvcORiX7tyHosnmWC3d3wI2aPSQg== + dependencies: + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + +"@chakra-ui/progress@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/progress/-/progress-2.2.0.tgz#67444ea9779631d7c8395b2c9c78e5634f994999" + integrity sha512-qUXuKbuhN60EzDD9mHR7B67D7p/ZqNS2Aze4Pbl1qGGZfulPW0PY8Rof32qDtttDQBkzQIzFGE8d9QpAemToIQ== + dependencies: + "@chakra-ui/react-context" "2.1.0" + +"@chakra-ui/provider@2.4.2": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/provider/-/provider-2.4.2.tgz#92cb10b6a7df0720e3fa62716dc7cd872ae3ea3d" + integrity sha512-w0Tef5ZCJK1mlJorcSjItCSbyvVuqpvyWdxZiVQmE6fvSJR83wZof42ux0+sfWD+I7rHSfj+f9nzhNaEWClysw== + dependencies: + "@chakra-ui/css-reset" "2.3.0" + "@chakra-ui/portal" "2.1.0" + "@chakra-ui/react-env" "3.1.0" + "@chakra-ui/system" "2.6.2" + "@chakra-ui/utils" "2.0.15" + +"@chakra-ui/radio@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/radio/-/radio-2.1.2.tgz#66db19c61a2e628aaf5e727027f7c3b4006ea898" + integrity sha512-n10M46wJrMGbonaghvSRnZ9ToTv/q76Szz284gv4QUWvyljQACcGrXIONUnQ3BIwbOfkRqSk7Xl/JgZtVfll+w== + dependencies: + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@zag-js/focus-visible" "0.16.0" + +"@chakra-ui/react-children-utils@2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-children-utils/-/react-children-utils-2.0.6.tgz#6c480c6a60678fcb75cb7d57107c7a79e5179b92" + integrity sha512-QVR2RC7QsOsbWwEnq9YduhpqSFnZGvjjGREV8ygKi8ADhXh93C8azLECCUVgRJF2Wc+So1fgxmjLcbZfY2VmBA== + +"@chakra-ui/react-context@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-context/-/react-context-2.1.0.tgz#4858be1d5ff1c8ac0a0ec088d93a3b7f1cbbff99" + integrity sha512-iahyStvzQ4AOwKwdPReLGfDesGG+vWJfEsn0X/NoGph/SkN+HXtv2sCfYFFR9k7bb+Kvc6YfpLlSuLvKMHi2+w== + +"@chakra-ui/react-env@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-env/-/react-env-3.1.0.tgz#7d3c1c05a501bb369524d9f3d38c9325eb16ab50" + integrity sha512-Vr96GV2LNBth3+IKzr/rq1IcnkXv+MLmwjQH6C8BRtn3sNskgDFD5vLkVXcEhagzZMCh8FR3V/bzZPojBOyNhw== + dependencies: + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + +"@chakra-ui/react-types@2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-types/-/react-types-2.0.7.tgz#799c166a44882b23059c8f510eac9bd5d0869ac4" + integrity sha512-12zv2qIZ8EHwiytggtGvo4iLT0APris7T0qaAWqzpUGS0cdUtR8W+V1BJ5Ocq+7tA6dzQ/7+w5hmXih61TuhWQ== + +"@chakra-ui/react-use-animation-state@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-animation-state/-/react-use-animation-state-2.1.0.tgz#eab661fbafd96804fe867b0df0c27e78feefe6e2" + integrity sha512-CFZkQU3gmDBwhqy0vC1ryf90BVHxVN8cTLpSyCpdmExUEtSEInSCGMydj2fvn7QXsz/za8JNdO2xxgJwxpLMtg== + dependencies: + "@chakra-ui/dom-utils" "2.1.0" + "@chakra-ui/react-use-event-listener" "2.1.0" + +"@chakra-ui/react-use-callback-ref@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.1.0.tgz#a508085f4d9e7d84d4ceffdf5f41745c9ac451d7" + integrity sha512-efnJrBtGDa4YaxDzDE90EnKD3Vkh5a1t3w7PhnRQmsphLy3g2UieasoKTlT2Hn118TwDjIv5ZjHJW6HbzXA9wQ== + +"@chakra-ui/react-use-controllable-state@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-controllable-state/-/react-use-controllable-state-2.1.0.tgz#8fb6fa2f45d0c04173582ae8297e604ffdb9c7d9" + integrity sha512-QR/8fKNokxZUs4PfxjXuwl0fj/d71WPrmLJvEpCTkHjnzu7LnYvzoe2wB867IdooQJL0G1zBxl0Dq+6W1P3jpg== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-disclosure@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-disclosure/-/react-use-disclosure-2.1.0.tgz#90093eaf45db1bea7a6851dd0ce5cdb3eb66f90a" + integrity sha512-Ax4pmxA9LBGMyEZJhhUZobg9C0t3qFE4jVF1tGBsrLDcdBeLR9fwOogIPY9Hf0/wqSlAryAimICbr5hkpa5GSw== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-event-listener@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.1.0.tgz#afea2645bd9b38f754fc2b8eb858f9bb22385ded" + integrity sha512-U5greryDLS8ISP69DKDsYcsXRtAdnTQT+jjIlRYZ49K/XhUR/AqVZCK5BkR1spTDmO9H8SPhgeNKI70ODuDU/Q== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-focus-effect@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-focus-effect/-/react-use-focus-effect-2.1.0.tgz#963fb790370dfadd51d12666ff2da60706f53a2a" + integrity sha512-xzVboNy7J64xveLcxTIJ3jv+lUJKDwRM7Szwn9tNzUIPD94O3qwjV7DDCUzN2490nSYDF4OBMt/wuDBtaR3kUQ== + dependencies: + "@chakra-ui/dom-utils" "2.1.0" + "@chakra-ui/react-use-event-listener" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + +"@chakra-ui/react-use-focus-on-pointer-down@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-focus-on-pointer-down/-/react-use-focus-on-pointer-down-2.1.0.tgz#2fbcf6bc7d06d97606747e231a908d5c387ca0cc" + integrity sha512-2jzrUZ+aiCG/cfanrolsnSMDykCAbv9EK/4iUyZno6BYb3vziucmvgKuoXbMPAzWNtwUwtuMhkby8rc61Ue+Lg== + dependencies: + "@chakra-ui/react-use-event-listener" "2.1.0" + +"@chakra-ui/react-use-interval@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-interval/-/react-use-interval-2.1.0.tgz#2602c097b3ab74b6644812e4f5efaad621218d98" + integrity sha512-8iWj+I/+A0J08pgEXP1J1flcvhLBHkk0ln7ZvGIyXiEyM6XagOTJpwNhiu+Bmk59t3HoV/VyvyJTa+44sEApuw== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-latest-ref@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-latest-ref/-/react-use-latest-ref-2.1.0.tgz#d1e926130102566ece1d39f8a48ed125e0c8441a" + integrity sha512-m0kxuIYqoYB0va9Z2aW4xP/5b7BzlDeWwyXCH6QpT2PpW3/281L3hLCm1G0eOUcdVlayqrQqOeD6Mglq+5/xoQ== + +"@chakra-ui/react-use-merge-refs@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.1.0.tgz#c0c233527abdbea9a1348269c192012205762314" + integrity sha512-lERa6AWF1cjEtWSGjxWTaSMvneccnAVH4V4ozh8SYiN9fSPZLlSG3kNxfNzdFvMEhM7dnP60vynF7WjGdTgQbQ== + +"@chakra-ui/react-use-outside-click@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-outside-click/-/react-use-outside-click-2.2.0.tgz#5570b772a255f6f02b69e967127397c1b5fa3d3c" + integrity sha512-PNX+s/JEaMneijbgAM4iFL+f3m1ga9+6QK0E5Yh4s8KZJQ/bLwZzdhMz8J/+mL+XEXQ5J0N8ivZN28B82N1kNw== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-pan-event@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-pan-event/-/react-use-pan-event-2.1.0.tgz#51c21bc3c0e9e73d1faef5ea4f7e3c3d071a2758" + integrity sha512-xmL2qOHiXqfcj0q7ZK5s9UjTh4Gz0/gL9jcWPA6GVf+A0Od5imEDa/Vz+533yQKWiNSm1QGrIj0eJAokc7O4fg== + dependencies: + "@chakra-ui/event-utils" "2.0.8" + "@chakra-ui/react-use-latest-ref" "2.1.0" + framesync "6.1.2" + +"@chakra-ui/react-use-previous@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-previous/-/react-use-previous-2.1.0.tgz#f6046e6f7398b1e8d7e66ff7ebb8d61c92a2d3d0" + integrity sha512-pjxGwue1hX8AFcmjZ2XfrQtIJgqbTF3Qs1Dy3d1krC77dEsiCUbQ9GzOBfDc8pfd60DrB5N2tg5JyHbypqh0Sg== + +"@chakra-ui/react-use-safe-layout-effect@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.1.0.tgz#3a95f0ba6fd5d2d0aa14919160f2c825f13e686f" + integrity sha512-Knbrrx/bcPwVS1TorFdzrK/zWA8yuU/eaXDkNj24IrKoRlQrSBFarcgAEzlCHtzuhufP3OULPkELTzz91b0tCw== + +"@chakra-ui/react-use-size@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-size/-/react-use-size-2.1.0.tgz#fcf3070eaade8b4a84af8ce5341c4d5ca0a42bec" + integrity sha512-tbLqrQhbnqOjzTaMlYytp7wY8BW1JpL78iG7Ru1DlV4EWGiAmXFGvtnEt9HftU0NJ0aJyjgymkxfVGI55/1Z4A== + dependencies: + "@zag-js/element-size" "0.10.5" + +"@chakra-ui/react-use-timeout@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-timeout/-/react-use-timeout-2.1.0.tgz#24415f54267d7241a3c1d36a5cae4d472834cef7" + integrity sha512-cFN0sobKMM9hXUhyCofx3/Mjlzah6ADaEl/AXl5Y+GawB5rgedgAcu2ErAgarEkwvsKdP6c68CKjQ9dmTQlJxQ== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.1.0" + +"@chakra-ui/react-use-update-effect@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.1.0.tgz#5c57cd1f50c2a6a8119e0f57f69510723d69884b" + integrity sha512-ND4Q23tETaR2Qd3zwCKYOOS1dfssojPLJMLvUtUbW5M9uW1ejYWgGUobeAiOVfSplownG8QYMmHTP86p/v0lbA== + +"@chakra-ui/react-utils@2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-utils/-/react-utils-2.0.12.tgz#d6b773b9a5b2e51dce61f51ac8a0e9a0f534f479" + integrity sha512-GbSfVb283+YA3kA8w8xWmzbjNWk14uhNpntnipHCftBibl0lxtQ9YqMFQLwuFOO0U2gYVocszqqDWX+XNKq9hw== + dependencies: + "@chakra-ui/utils" "2.0.15" + +"@chakra-ui/react@^2.8.2": + version "2.8.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/react/-/react-2.8.2.tgz#94d692fb35e4447748c5bfd73d8d38a746193c7d" + integrity sha512-Hn0moyxxyCDKuR9ywYpqgX8dvjqwu9ArwpIb9wHNYjnODETjLwazgNIliCVBRcJvysGRiV51U2/JtJVrpeCjUQ== + dependencies: + "@chakra-ui/accordion" "2.3.1" + "@chakra-ui/alert" "2.2.2" + "@chakra-ui/avatar" "2.3.0" + "@chakra-ui/breadcrumb" "2.2.0" + "@chakra-ui/button" "2.1.0" + "@chakra-ui/card" "2.2.0" + "@chakra-ui/checkbox" "2.3.2" + "@chakra-ui/close-button" "2.1.1" + "@chakra-ui/control-box" "2.1.0" + "@chakra-ui/counter" "2.1.0" + "@chakra-ui/css-reset" "2.3.0" + "@chakra-ui/editable" "3.1.0" + "@chakra-ui/focus-lock" "2.1.0" + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/hooks" "2.2.1" + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/image" "2.1.0" + "@chakra-ui/input" "2.1.2" + "@chakra-ui/layout" "2.3.1" + "@chakra-ui/live-region" "2.1.0" + "@chakra-ui/media-query" "3.3.0" + "@chakra-ui/menu" "2.2.1" + "@chakra-ui/modal" "2.3.1" + "@chakra-ui/number-input" "2.1.2" + "@chakra-ui/pin-input" "2.1.0" + "@chakra-ui/popover" "2.2.1" + "@chakra-ui/popper" "3.1.0" + "@chakra-ui/portal" "2.1.0" + "@chakra-ui/progress" "2.2.0" + "@chakra-ui/provider" "2.4.2" + "@chakra-ui/radio" "2.1.2" + "@chakra-ui/react-env" "3.1.0" + "@chakra-ui/select" "2.1.2" + "@chakra-ui/skeleton" "2.1.0" + "@chakra-ui/skip-nav" "2.1.0" + "@chakra-ui/slider" "2.1.0" + "@chakra-ui/spinner" "2.1.0" + "@chakra-ui/stat" "2.1.1" + "@chakra-ui/stepper" "2.3.1" + "@chakra-ui/styled-system" "2.9.2" + "@chakra-ui/switch" "2.1.2" + "@chakra-ui/system" "2.6.2" + "@chakra-ui/table" "2.1.0" + "@chakra-ui/tabs" "3.0.0" + "@chakra-ui/tag" "3.1.1" + "@chakra-ui/textarea" "2.1.2" + "@chakra-ui/theme" "3.3.1" + "@chakra-ui/theme-utils" "2.0.21" + "@chakra-ui/toast" "7.0.2" + "@chakra-ui/tooltip" "2.3.1" + "@chakra-ui/transition" "2.1.0" + "@chakra-ui/utils" "2.0.15" + "@chakra-ui/visually-hidden" "2.2.0" + +"@chakra-ui/select@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/select/-/select-2.1.2.tgz#f57d6cec0559373c32094fd4a5abd32855829264" + integrity sha512-ZwCb7LqKCVLJhru3DXvKXpZ7Pbu1TDZ7N0PdQ0Zj1oyVLJyrpef1u9HR5u0amOpqcH++Ugt0f5JSmirjNlctjA== + dependencies: + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/shared-utils@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/shared-utils/-/shared-utils-2.0.5.tgz#cb2b49705e113853647f1822142619570feba081" + integrity sha512-4/Wur0FqDov7Y0nCXl7HbHzCg4aq86h+SXdoUeuCMD3dSj7dpsVnStLYhng1vxvlbUnLpdF4oz5Myt3i/a7N3Q== + +"@chakra-ui/skeleton@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/skeleton/-/skeleton-2.1.0.tgz#e3b25dd3afa330029d6d63be0f7cb8d44ad25531" + integrity sha512-JNRuMPpdZGd6zFVKjVQ0iusu3tXAdI29n4ZENYwAJEMf/fN0l12sVeirOxkJ7oEL0yOx2AgEYFSKdbcAgfUsAQ== + dependencies: + "@chakra-ui/media-query" "3.3.0" + "@chakra-ui/react-use-previous" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/skip-nav@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/skip-nav/-/skip-nav-2.1.0.tgz#cac27eecc6eded1e83c8f0cf7445d727739cb325" + integrity sha512-Hk+FG+vadBSH0/7hwp9LJnLjkO0RPGnx7gBJWI4/SpoJf3e4tZlWYtwGj0toYY4aGKl93jVghuwGbDBEMoHDug== + +"@chakra-ui/slider@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/slider/-/slider-2.1.0.tgz#1caeed18761ba2a390777418cc9389ba25e39bce" + integrity sha512-lUOBcLMCnFZiA/s2NONXhELJh6sY5WtbRykPtclGfynqqOo47lwWJx+VP7xaeuhDOPcWSSecWc9Y1BfPOCz9cQ== + dependencies: + "@chakra-ui/number-utils" "2.0.7" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-callback-ref" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-latest-ref" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-pan-event" "2.1.0" + "@chakra-ui/react-use-size" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + +"@chakra-ui/spinner@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/spinner/-/spinner-2.1.0.tgz#aa24a3d692c6ac90714e0f0f82c76c12c78c8e60" + integrity sha512-hczbnoXt+MMv/d3gE+hjQhmkzLiKuoTo42YhUG7Bs9OSv2lg1fZHW1fGNRFP3wTi6OIbD044U1P9HK+AOgFH3g== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/stat@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/stat/-/stat-2.1.1.tgz#a204ba915795345996a16c79794d84826d7dcc2d" + integrity sha512-LDn0d/LXQNbAn2KaR3F1zivsZCewY4Jsy1qShmfBMKwn6rI8yVlbvu6SiA3OpHS0FhxbsZxQI6HefEoIgtqY6Q== + dependencies: + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/stepper@2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/stepper/-/stepper-2.3.1.tgz#a0a0b73e147f202ab4e51cae55dad45489cc89fd" + integrity sha512-ky77lZbW60zYkSXhYz7kbItUpAQfEdycT0Q4bkHLxfqbuiGMf8OmgZOQkOB9uM4v0zPwy2HXhe0vq4Dd0xa55Q== + dependencies: + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/styled-system@2.9.2": + version "2.9.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.9.2.tgz#898ab63da560a4a014f7b05fa7767e8c76da6d2f" + integrity sha512-To/Z92oHpIE+4nk11uVMWqo2GGRS86coeMmjxtpnErmWRdLcp1WVCVRAvn+ZwpLiNR+reWFr2FFqJRsREuZdAg== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + csstype "^3.1.2" + lodash.mergewith "4.6.2" + +"@chakra-ui/switch@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/switch/-/switch-2.1.2.tgz#f7c6878d8126bfac8fa3b939079f1017c21b7479" + integrity sha512-pgmi/CC+E1v31FcnQhsSGjJnOE2OcND4cKPyTE+0F+bmGm48Q/b5UmKD9Y+CmZsrt/7V3h8KNczowupfuBfIHA== + dependencies: + "@chakra-ui/checkbox" "2.3.2" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/system@2.6.2": + version "2.6.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/system/-/system-2.6.2.tgz#528ec955bd6a7f74da46470ee8225b1e2c80a78b" + integrity sha512-EGtpoEjLrUu4W1fHD+a62XR+hzC5YfsWm+6lO0Kybcga3yYEij9beegO0jZgug27V+Rf7vns95VPVP6mFd/DEQ== + dependencies: + "@chakra-ui/color-mode" "2.2.0" + "@chakra-ui/object-utils" "2.1.0" + "@chakra-ui/react-utils" "2.0.12" + "@chakra-ui/styled-system" "2.9.2" + "@chakra-ui/theme-utils" "2.0.21" + "@chakra-ui/utils" "2.0.15" + react-fast-compare "3.2.2" + +"@chakra-ui/table@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/table/-/table-2.1.0.tgz#20dce14c5e4d70dc7c6c0e87cce9b05907ff8c50" + integrity sha512-o5OrjoHCh5uCLdiUb0Oc0vq9rIAeHSIRScc2ExTC9Qg/uVZl2ygLrjToCaKfaaKl1oQexIeAcZDKvPG8tVkHyQ== + dependencies: + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/tabs@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/tabs/-/tabs-3.0.0.tgz#854c06880af26158d7c72881c4b5e0453f6c485d" + integrity sha512-6Mlclp8L9lqXmsGWF5q5gmemZXOiOYuh0SGT/7PgJVNPz3LXREXlXg2an4MBUD8W5oTkduCX+3KTMCwRrVrDYw== + dependencies: + "@chakra-ui/clickable" "2.1.0" + "@chakra-ui/descendant" "3.1.0" + "@chakra-ui/lazy-utils" "2.0.5" + "@chakra-ui/react-children-utils" "2.0.6" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-controllable-state" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/react-use-safe-layout-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/tag@3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/tag/-/tag-3.1.1.tgz#d05284b6549a84d3a08e57eec57df3ad0eebd882" + integrity sha512-Bdel79Dv86Hnge2PKOU+t8H28nm/7Y3cKd4Kfk9k3lOpUh4+nkSGe58dhRzht59lEqa4N9waCgQiBdkydjvBXQ== + dependencies: + "@chakra-ui/icon" "3.2.0" + "@chakra-ui/react-context" "2.1.0" + +"@chakra-ui/textarea@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/textarea/-/textarea-2.1.2.tgz#30f8af0e233cec2dee79d527450c6586e7122eff" + integrity sha512-ip7tvklVCZUb2fOHDb23qPy/Fr2mzDOGdkrpbNi50hDCiV4hFX02jdQJdi3ydHZUyVgZVBKPOJ+lT9i7sKA2wA== + dependencies: + "@chakra-ui/form-control" "2.2.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/theme-tools@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme-tools/-/theme-tools-2.1.2.tgz#913be05879cd816c546993ccb9ff7615f85ff69f" + integrity sha512-Qdj8ajF9kxY4gLrq7gA+Azp8CtFHGO9tWMN2wfF9aQNgG9AuMhPrUzMq9AMQ0MXiYcgNq/FD3eegB43nHVmXVA== + dependencies: + "@chakra-ui/anatomy" "2.2.2" + "@chakra-ui/shared-utils" "2.0.5" + color2k "^2.0.2" + +"@chakra-ui/theme-utils@2.0.21": + version "2.0.21" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme-utils/-/theme-utils-2.0.21.tgz#da7ed541a5241a8ed0384eb14f37fa9b998382cf" + integrity sha512-FjH5LJbT794r0+VSCXB3lT4aubI24bLLRWB+CuRKHijRvsOg717bRdUN/N1fEmEpFnRVrbewttWh/OQs0EWpWw== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/styled-system" "2.9.2" + "@chakra-ui/theme" "3.3.1" + lodash.mergewith "4.6.2" + +"@chakra-ui/theme@3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme/-/theme-3.3.1.tgz#75c6cd0b5c70c0aa955068274ee4780f299bd8a4" + integrity sha512-Hft/VaT8GYnItGCBbgWd75ICrIrIFrR7lVOhV/dQnqtfGqsVDlrztbSErvMkoPKt0UgAkd9/o44jmZ6X4U2nZQ== + dependencies: + "@chakra-ui/anatomy" "2.2.2" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/theme-tools" "2.1.2" + +"@chakra-ui/toast@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/toast/-/toast-7.0.2.tgz#d1c396bbfced12e22b010899731fd8cc294d53ec" + integrity sha512-yvRP8jFKRs/YnkuE41BVTq9nB2v/KDRmje9u6dgDmE5+1bFt3bwjdf9gVbif4u5Ve7F7BGk5E093ARRVtvLvXA== + dependencies: + "@chakra-ui/alert" "2.2.2" + "@chakra-ui/close-button" "2.1.1" + "@chakra-ui/portal" "2.1.0" + "@chakra-ui/react-context" "2.1.0" + "@chakra-ui/react-use-timeout" "2.1.0" + "@chakra-ui/react-use-update-effect" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + "@chakra-ui/styled-system" "2.9.2" + "@chakra-ui/theme" "3.3.1" + +"@chakra-ui/tooltip@2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/tooltip/-/tooltip-2.3.1.tgz#29fb8508a37bb6b20ab8dbb32bca6cd59b098796" + integrity sha512-Rh39GBn/bL4kZpuEMPPRwYNnccRCL+w9OqamWHIB3Qboxs6h8cOyXfIdGxjo72lvhu1QI/a4KFqkM3St+WfC0A== + dependencies: + "@chakra-ui/dom-utils" "2.1.0" + "@chakra-ui/popper" "3.1.0" + "@chakra-ui/portal" "2.1.0" + "@chakra-ui/react-types" "2.0.7" + "@chakra-ui/react-use-disclosure" "2.1.0" + "@chakra-ui/react-use-event-listener" "2.1.0" + "@chakra-ui/react-use-merge-refs" "2.1.0" + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/transition@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/transition/-/transition-2.1.0.tgz#c8e95564f7ab356e78119780037bae5ad150c7b3" + integrity sha512-orkT6T/Dt+/+kVwJNy7zwJ+U2xAZ3EU7M3XCs45RBvUnZDr/u9vdmaM/3D/rOpmQJWgQBwKPJleUXrYWUagEDQ== + dependencies: + "@chakra-ui/shared-utils" "2.0.5" + +"@chakra-ui/utils@2.0.15": + version "2.0.15" + resolved "https://registry.yarnpkg.com/@chakra-ui/utils/-/utils-2.0.15.tgz#bd800b1cff30eb5a5e8c36fa039f49984b4c5e4a" + integrity sha512-El4+jL0WSaYYs+rJbuYFDbjmfCcfGDmRY95GO4xwzit6YAPZBLcR65rOEwLps+XWluZTy1xdMrusg/hW0c1aAA== + dependencies: + "@types/lodash.mergewith" "4.6.7" + css-box-model "1.2.1" + framesync "6.1.2" + lodash.mergewith "4.6.2" + +"@chakra-ui/visually-hidden@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/visually-hidden/-/visually-hidden-2.2.0.tgz#9b0ecef8f01263ab808ba3bda7b36a0d91b4d5c1" + integrity sha512-KmKDg01SrQ7VbTD3+cPWf/UfpF5MSwm3v7MWi0n5t8HnnadT13MF0MJCDSXbBWnzLv1ZKJ6zlyAOeARWX+DpjQ== + +"@csstools/normalize.css@*": + version "12.0.0" + resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz#a9583a75c3f150667771f30b60d9f059473e62c4" + integrity sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg== + +"@csstools/postcss-cascade-layers@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz#8a997edf97d34071dd2e37ea6022447dd9e795ad" + integrity sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA== + dependencies: + "@csstools/selector-specificity" "^2.0.2" + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-color-function@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz#2bd36ab34f82d0497cfacdc9b18d34b5e6f64b6b" + integrity sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-font-format-keywords@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz#677b34e9e88ae997a67283311657973150e8b16a" + integrity sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-hwb-function@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz#ab54a9fce0ac102c754854769962f2422ae8aa8b" + integrity sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-ic-unit@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz#28237d812a124d1a16a5acc5c3832b040b303e58" + integrity sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-is-pseudo-class@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz#846ae6c0d5a1eaa878fce352c544f9c295509cd1" + integrity sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA== + dependencies: + "@csstools/selector-specificity" "^2.0.0" + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-nested-calc@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz#d7e9d1d0d3d15cf5ac891b16028af2a1044d0c26" + integrity sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-normalize-display-values@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz#15da54a36e867b3ac5163ee12c1d7f82d4d612c3" + integrity sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-oklab-function@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz#88cee0fbc8d6df27079ebd2fa016ee261eecf844" + integrity sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-progressive-custom-properties@^1.1.0", "@csstools/postcss-progressive-custom-properties@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz#542292558384361776b45c85226b9a3a34f276fa" + integrity sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-stepped-value-functions@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz#f8772c3681cc2befed695e2b0b1d68e22f08c4f4" + integrity sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-text-decoration-shorthand@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz#ea96cfbc87d921eca914d3ad29340d9bcc4c953f" + integrity sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-trigonometric-functions@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz#94d3e4774c36d35dcdc88ce091336cb770d32756" + integrity sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-unset-value@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz#c99bb70e2cdc7312948d1eb41df2412330b81f77" + integrity sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g== + +"@csstools/selector-specificity@^2.0.0", "@csstools/selector-specificity@^2.0.2": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz#2cbcf822bf3764c9658c4d2e568bd0c0cb748016" + integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== + +"@emotion/babel-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" + integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/serialize" "^1.1.2" + babel-plugin-macros "^3.1.0" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" + stylis "4.2.0" + +"@emotion/cache@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" + +"@emotion/hash@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" + integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== + +"@emotion/is-prop-valid@^0.8.2": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + +"@emotion/is-prop-valid@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" + integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== + dependencies: + "@emotion/memoize" "^0.8.1" + +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== + +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + +"@emotion/react@^11.11.1": + version "11.11.1" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.1.tgz#b2c36afac95b184f73b08da8c214fdf861fa4157" + integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + hoist-non-react-statics "^3.3.1" + +"@emotion/serialize@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51" + integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA== + dependencies: + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/unitless" "^0.8.1" + "@emotion/utils" "^1.2.1" + csstype "^3.0.2" + +"@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== + +"@emotion/styled@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" + integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/is-prop-valid" "^1.2.1" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + +"@emotion/unitless@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== + +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== + +"@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== + +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== + +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== + +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.55.0": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.55.0.tgz#b721d52060f369aa259cf97392403cb9ce892ec6" + integrity sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA== + +"@fastify/busboy@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff" + integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA== + +"@firebase/analytics-compat@0.2.6": + version "0.2.6" + resolved "https://registry.yarnpkg.com/@firebase/analytics-compat/-/analytics-compat-0.2.6.tgz#50063978c42f13eb800e037e96ac4b17236841f4" + integrity sha512-4MqpVLFkGK7NJf/5wPEEP7ePBJatwYpyjgJ+wQHQGHfzaCDgntOnl9rL2vbVGGKCnRqWtZDIWhctB86UWXaX2Q== + dependencies: + "@firebase/analytics" "0.10.0" + "@firebase/analytics-types" "0.8.0" + "@firebase/component" "0.6.4" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/analytics-types@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@firebase/analytics-types/-/analytics-types-0.8.0.tgz#551e744a29adbc07f557306530a2ec86add6d410" + integrity sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw== + +"@firebase/analytics@0.10.0": + version "0.10.0" + resolved "https://registry.yarnpkg.com/@firebase/analytics/-/analytics-0.10.0.tgz#9c6986acd573c6c6189ffb52d0fd63c775db26d7" + integrity sha512-Locv8gAqx0e+GX/0SI3dzmBY5e9kjVDtD+3zCFLJ0tH2hJwuCAiL+5WkHuxKj92rqQj/rvkBUCfA1ewlX2hehg== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/installations" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/app-check-compat@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@firebase/app-check-compat/-/app-check-compat-0.3.8.tgz#b71d324c27d49f2a9cab7c5aeab84e1350bd87a9" + integrity sha512-EaETtChR4UgMokJFw+r6jfcIyCTUZSe0a6ivF37D9MxlG9G3wzK1COyXgxoX96GzXmDPc2aubX4PxCrdVHhrnA== + dependencies: + "@firebase/app-check" "0.8.1" + "@firebase/app-check-types" "0.5.0" + "@firebase/component" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/app-check-interop-types@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz#b27ea1397cb80427f729e4bbf3a562f2052955c4" + integrity sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg== + +"@firebase/app-check-types@0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@firebase/app-check-types/-/app-check-types-0.5.0.tgz#1b02826213d7ce6a1cf773c329b46ea1c67064f4" + integrity sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ== + +"@firebase/app-check@0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@firebase/app-check/-/app-check-0.8.1.tgz#df335c896552d76783b06a6be0fc2ff1bc423f03" + integrity sha512-zi3vbM5tb/eGRWyiqf+1DXbxFu9Q07dnm46rweodgUpH9B8svxYkHfNwYWx7F5mjHU70SQDuaojH1We5ws9OKA== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/app-compat@0.2.25": + version "0.2.25" + resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.2.25.tgz#214bfd602994966ed765247ba8f6948b9eb0985e" + integrity sha512-B/JtCp1FsTuzlh1tIGQpYM2AXps21/zlzpFsk5LRsROOTRhBcR2N45AyaONPFD06C0yS0Tw19foxADzHyOSC3A== + dependencies: + "@firebase/app" "0.9.25" + "@firebase/component" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/app-types@0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.9.0.tgz#35b5c568341e9e263b29b3d2ba0e9cfc9ec7f01e" + integrity sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q== + +"@firebase/app@0.9.25": + version "0.9.25" + resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.9.25.tgz#411607c9d11f2d2d66c9b1a0de2ffa6d1232261c" + integrity sha512-fX22gL5USXhOK21Hlh3oTeOzQZ6th6S2JrjXNEpBARmwzuUkqmVGVdsOCIFYIsLpK0dQE3o8xZnLrRg5wnzZ/g== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.3" + idb "7.1.1" + tslib "^2.1.0" + +"@firebase/auth-compat@0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.5.1.tgz#2a8a3ce05520bfa1e73f8c2caa1c9eb81d2df25e" + integrity sha512-rgDZnrDoekRvtzXVji8Z61wxxkof6pTkjYEkybILrjM8tGP9tx4xa9qGpF4ax3AzF+rKr7mIa9NnoXEK4UNqmQ== + dependencies: + "@firebase/auth" "1.5.1" + "@firebase/auth-types" "0.12.0" + "@firebase/component" "0.6.4" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + undici "5.26.5" + +"@firebase/auth-interop-types@0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz#78884f24fa539e34a06c03612c75f222fcc33742" + integrity sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg== + +"@firebase/auth-types@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.12.0.tgz#f28e1b68ac3b208ad02a15854c585be6da3e8e79" + integrity sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA== + +"@firebase/auth@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-1.5.1.tgz#214718a45cbdf6bdbe5086e92a70d1a0fea61962" + integrity sha512-sVi7rq2YneLGJFqHa5S6nDfCHix9yuVV3RLhj/pWPlB4a36ofXal4E6PJwpeMc8uLjWEr1aovYN1jkXWNB6Avw== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + undici "5.26.5" + +"@firebase/component@0.6.4": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.6.4.tgz#8981a6818bd730a7554aa5e0516ffc9b1ae3f33d" + integrity sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA== + dependencies: + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/database-compat@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-1.0.2.tgz#be6e91fcac6cb392fb7f9285e065c115c810ae5f" + integrity sha512-09ryJnXDvuycsxn8aXBzLhBTuCos3HEnCOBWY6hosxfYlNCGnLvG8YMlbSAt5eNhf7/00B095AEfDsdrrLjxqA== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/database" "1.0.2" + "@firebase/database-types" "1.0.0" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/database-types@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-1.0.0.tgz#3f7f71c2c3fd1e29d15fce513f14dae2e7543f2a" + integrity sha512-SjnXStoE0Q56HcFgNQ+9SsmJc0c8TqGARdI/T44KXy+Ets3r6x/ivhQozT66bMnCEjJRywYoxNurRTMlZF8VNg== + dependencies: + "@firebase/app-types" "0.9.0" + "@firebase/util" "1.9.3" + +"@firebase/database@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@firebase/database/-/database-1.0.2.tgz#2d13768f7920715065cc8c65d96cc38179008c13" + integrity sha512-8X6NBJgUQzDz0xQVaCISoOLINKat594N2eBbMR3Mu/MH/ei4WM+aAMlsNzngF22eljXu1SILP5G3evkyvsG3Ng== + dependencies: + "@firebase/app-check-interop-types" "0.3.0" + "@firebase/auth-interop-types" "0.2.1" + "@firebase/component" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.3" + faye-websocket "0.11.4" + tslib "^2.1.0" + +"@firebase/firestore-compat@0.3.23": + version "0.3.23" + resolved "https://registry.yarnpkg.com/@firebase/firestore-compat/-/firestore-compat-0.3.23.tgz#7d17831edc384a2f889cae6ddec52373f6741c4a" + integrity sha512-uUTBiP0GLVBETaOCfB11d33OWB8x1r2G1Xrl0sRK3Va0N5LJ/GRvKVSGfM7VScj+ypeHe8RpdwKoCqLpN1e+uA== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/firestore" "4.4.0" + "@firebase/firestore-types" "3.0.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/firestore-types@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@firebase/firestore-types/-/firestore-types-3.0.0.tgz#f3440d5a1cc2a722d361b24cefb62ca8b3577af3" + integrity sha512-Meg4cIezHo9zLamw0ymFYBD4SMjLb+ZXIbuN7T7ddXN6MGoICmOTq3/ltdCGoDCS2u+H1XJs2u/cYp75jsX9Qw== + +"@firebase/firestore@4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-4.4.0.tgz#c90c65c270538c34a6271827f20d67244f121933" + integrity sha512-VeDXD9PUjvcWY1tInBOMTIu2pijR3YYy+QAe5cxCo1Q1vW+aA/mpQHhebPM1J6b4Zd1MuUh8xpBRvH9ujKR56A== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.3" + "@firebase/webchannel-wrapper" "0.10.5" + "@grpc/grpc-js" "~1.9.0" + "@grpc/proto-loader" "^0.7.8" + tslib "^2.1.0" + undici "5.26.5" + +"@firebase/functions-compat@0.3.6": + version "0.3.6" + resolved "https://registry.yarnpkg.com/@firebase/functions-compat/-/functions-compat-0.3.6.tgz#7074b88c4a56e6a4adc61bd692e2a872bd62b196" + integrity sha512-RQpO3yuHtnkqLqExuAT2d0u3zh8SDbeBYK5EwSCBKI9mjrFeJRXBnd3pEG+x5SxGJLy56/5pQf73mwt0OuH5yg== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/functions" "0.11.0" + "@firebase/functions-types" "0.6.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/functions-types@0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@firebase/functions-types/-/functions-types-0.6.0.tgz#ccd7000dc6fc668f5acb4e6a6a042a877a555ef2" + integrity sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw== + +"@firebase/functions@0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.11.0.tgz#ce48ba39be7ec4cd20eb449616868e8c2bee4a8a" + integrity sha512-n1PZxKnJ++k73Q8khTPwihlbeKo6emnGzE0hX6QVQJsMq82y/XKmNpw2t/q30VJgwaia3ZXU1fd1C5wHncL+Zg== + dependencies: + "@firebase/app-check-interop-types" "0.3.0" + "@firebase/auth-interop-types" "0.2.1" + "@firebase/component" "0.6.4" + "@firebase/messaging-interop-types" "0.2.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + undici "5.26.5" + +"@firebase/installations-compat@0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@firebase/installations-compat/-/installations-compat-0.2.4.tgz#b5557c897b4cd3635a59887a8bf69c3731aaa952" + integrity sha512-LI9dYjp0aT9Njkn9U4JRrDqQ6KXeAmFbRC0E7jI7+hxl5YmRWysq5qgQl22hcWpTk+cm3es66d/apoDU/A9n6Q== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/installations" "0.6.4" + "@firebase/installations-types" "0.5.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/installations-types@0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@firebase/installations-types/-/installations-types-0.5.0.tgz#2adad64755cd33648519b573ec7ec30f21fb5354" + integrity sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg== + +"@firebase/installations@0.6.4": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.6.4.tgz#20382e33e6062ac5eff4bede8e468ed4c367609e" + integrity sha512-u5y88rtsp7NYkCHC3ElbFBrPtieUybZluXyzl7+4BsIz4sqb4vSAuwHEUgCgCeaQhvsnxDEU6icly8U9zsJigA== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/util" "1.9.3" + idb "7.0.1" + tslib "^2.1.0" + +"@firebase/logger@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.4.0.tgz#15ecc03c452525f9d47318ad9491b81d1810f113" + integrity sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA== + dependencies: + tslib "^2.1.0" + +"@firebase/messaging-compat@0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@firebase/messaging-compat/-/messaging-compat-0.2.5.tgz#9be03c70eac8f6f6c93f3fc804fe345bd05dcf57" + integrity sha512-qHQZxm4hEG8/HFU/ls5/bU+rpnlPDoZoqi3ATMeb6s4hovYV9+PfV5I7ZrKV5eFFv47Hx1PWLe5uPnS4e7gMwQ== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/messaging" "0.12.5" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/messaging-interop-types@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz#6056f8904a696bf0f7fdcf5f2ca8f008e8f6b064" + integrity sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ== + +"@firebase/messaging@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.12.5.tgz#59c84353974f851887b8a4b0e43e26560213d0e7" + integrity sha512-i/rrEI2k9ueFhdIr8KQsptWGskrsnkC5TkohCTrJKz9P0C/PbNv14IAMkwhMJTqIur5VwuOnrUkc9Kdz7awekw== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/installations" "0.6.4" + "@firebase/messaging-interop-types" "0.2.0" + "@firebase/util" "1.9.3" + idb "7.1.1" + tslib "^2.1.0" + +"@firebase/performance-compat@0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.2.4.tgz#95cbf32057b5d9f0c75d804bc50e6ed3ba486274" + integrity sha512-nnHUb8uP9G8islzcld/k6Bg5RhX62VpbAb/Anj7IXs/hp32Eb2LqFPZK4sy3pKkBUO5wcrlRWQa6wKOxqlUqsg== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/performance" "0.6.4" + "@firebase/performance-types" "0.2.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/performance-types@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@firebase/performance-types/-/performance-types-0.2.0.tgz#400685f7a3455970817136d9b48ce07a4b9562ff" + integrity sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA== + +"@firebase/performance@0.6.4": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.6.4.tgz#0ad766bfcfab4f386f4fe0bef43bbcf505015069" + integrity sha512-HfTn/bd8mfy/61vEqaBelNiNnvAbUtME2S25A67Nb34zVuCSCRIX4SseXY6zBnOFj3oLisaEqhVcJmVPAej67g== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/installations" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/remote-config-compat@0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@firebase/remote-config-compat/-/remote-config-compat-0.2.4.tgz#1f494c81a6c9560b1f9ca1b4fbd4bbbe47cf4776" + integrity sha512-FKiki53jZirrDFkBHglB3C07j5wBpitAaj8kLME6g8Mx+aq7u9P7qfmuSRytiOItADhWUj7O1JIv7n9q87SuwA== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/remote-config" "0.4.4" + "@firebase/remote-config-types" "0.3.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/remote-config-types@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz#689900dcdb3e5c059e8499b29db393e4e51314b4" + integrity sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA== + +"@firebase/remote-config@0.4.4": + version "0.4.4" + resolved "https://registry.yarnpkg.com/@firebase/remote-config/-/remote-config-0.4.4.tgz#6a496117054de58744bc9f382d2a6d1e14060c65" + integrity sha512-x1ioTHGX8ZwDSTOVp8PBLv2/wfwKzb4pxi0gFezS5GCJwbLlloUH4YYZHHS83IPxnua8b6l0IXUaWd0RgbWwzQ== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/installations" "0.6.4" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/storage-compat@0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@firebase/storage-compat/-/storage-compat-0.3.3.tgz#9c670cd7bf37733bd5f4235e97a5f5dc2c3d9c7e" + integrity sha512-WNtjYPhpOA1nKcRu5lIodX0wZtP8pI0VxDJnk6lr+av7QZNS1s6zvr+ERDTve+Qu4Hq/ZnNaf3kBEQR2ccXn6A== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/storage" "0.12.0" + "@firebase/storage-types" "0.8.0" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + +"@firebase/storage-types@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@firebase/storage-types/-/storage-types-0.8.0.tgz#f1e40a5361d59240b6e84fac7fbbbb622bfaf707" + integrity sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg== + +"@firebase/storage@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.12.0.tgz#de23aca9a6504b3b08281c93111e655f15b7f566" + integrity sha512-SGs02Y/mmWBRsqZiYLpv4Sf7uZYZzMWVNN+aKiDqPsFBCzD6hLvGkXz+u98KAl8FqcjgB8BtSu01wm4pm76KHA== + dependencies: + "@firebase/component" "0.6.4" + "@firebase/util" "1.9.3" + tslib "^2.1.0" + undici "5.26.5" + +"@firebase/util@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.9.3.tgz#45458dd5cd02d90e55c656e84adf6f3decf4b7ed" + integrity sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA== + dependencies: + tslib "^2.1.0" + +"@firebase/webchannel-wrapper@0.10.5": + version "0.10.5" + resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.10.5.tgz#cd9897680d0a2f1bce8d8c23a590e5874f4617c5" + integrity sha512-eSkJsnhBWv5kCTSU1tSUVl9mpFu+5NXXunZc83le8GMjMlsWwQArSc7cJJ4yl+aDFY0NGLi0AjZWMn1axOrkRg== + +"@grpc/grpc-js@~1.9.0": + version "1.9.12" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.9.12.tgz#a45b23a7d9ee1eadc9fa8fe480e27edbc6544cdd" + integrity sha512-Um5MBuge32TS3lAKX02PGCnFM4xPT996yLgZNb5H03pn6NyJ4Iwn5YcPq6Jj9yxGRk7WOgaZFtVRH5iTdYBeUg== + dependencies: + "@grpc/proto-loader" "^0.7.8" + "@types/node" ">=12.12.47" + +"@grpc/proto-loader@^0.7.8": + version "0.7.10" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.7.10.tgz#6bf26742b1b54d0a473067743da5d3189d06d720" + integrity sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ== + dependencies: + lodash.camelcase "^4.3.0" + long "^5.0.0" + protobufjs "^7.2.4" + yargs "^17.7.2" + +"@hookform/error-message@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@hookform/error-message/-/error-message-2.0.1.tgz#6a37419106e13664ad6a29c9dae699ae6cd276b8" + integrity sha512-U410sAr92xgxT1idlu9WWOVjndxLdgPUHEB8Schr27C9eh7/xUnITWpCMF93s+lGiG++D4JnbSnrb5A21AdSNg== + +"@hookform/resolvers@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-3.3.2.tgz#5c40f06fe8137390b071d961c66d27ee8f76f3bc" + integrity sha512-Tw+GGPnBp+5DOsSg4ek3LCPgkBOuOgS5DsDV7qsWNH9LZc433kgsWICjlsh2J9p04H2K66hsXPPb9qn9ILdUtA== + +"@humanwhocodes/config-array@^0.11.13": + version "0.11.13" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" + integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== + dependencies: + "@humanwhocodes/object-schema" "^2.0.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" + integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" + integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + +"@jest/console@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" + integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + slash "^3.0.0" + +"@jest/core@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" + integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/reporters" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^27.5.1" + jest-config "^27.5.1" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-resolve-dependencies "^27.5.1" + jest-runner "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + jest-watcher "^27.5.1" + micromatch "^4.0.4" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" + integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== + dependencies: + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== + dependencies: + jest-get-type "^29.6.3" + +"@jest/fake-timers@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" + integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== + dependencies: + "@jest/types" "^27.5.1" + "@sinonjs/fake-timers" "^8.0.1" + "@types/node" "*" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +"@jest/globals@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" + integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/types" "^27.5.1" + expect "^27.5.1" + +"@jest/reporters@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" + integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-haste-map "^27.5.1" + jest-resolve "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.1.0" + +"@jest/schemas@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" + integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== + dependencies: + "@sinclair/typebox" "^0.24.1" + +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/source-map@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" + integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.9" + source-map "^0.6.0" + +"@jest/test-result@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" + integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== + dependencies: + "@jest/console" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-result@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" + integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== + dependencies: + "@jest/console" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" + integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== + dependencies: + "@jest/test-result" "^27.5.1" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-runtime "^27.5.1" + +"@jest/transform@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" + integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.5.1" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-regex-util "^27.5.1" + jest-util "^27.5.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + +"@jest/types@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" + integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== + dependencies: + "@jest/schemas" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.3": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + +"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": + version "5.1.1-v1" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" + integrity sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg== + dependencies: + eslint-scope "5.1.1" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pmmmwh/react-refresh-webpack-plugin@^0.5.3": + version "0.5.11" + resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz#7c2268cedaa0644d677e8c4f377bc8fb304f714a" + integrity sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ== + dependencies: + ansi-html-community "^0.0.8" + common-path-prefix "^3.0.0" + core-js-pure "^3.23.3" + error-stack-parser "^2.0.6" + find-up "^5.0.0" + html-entities "^2.1.0" + loader-utils "^2.0.4" + schema-utils "^3.0.0" + source-map "^0.7.3" + +"@popperjs/core@^2.9.3": + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + +"@react-firebase/auth@^0.2.10": + version "0.2.10" + resolved "https://registry.yarnpkg.com/@react-firebase/auth/-/auth-0.2.10.tgz#1f58a6c9dd7f89ec1ca03d0620929f1a6bac9c82" + integrity sha512-qeRv96HI5Y3nPRwO3Zi4QnYYeJstVu8lDih+QQbTeuadUUngchGw5Tp7dseOY5u3q/+e+kF2hV7BUkfYt7FS8g== + dependencies: + lodash.get "^4.4.2" + render-and-add-props "^0.5.0" + +"@react-native-async-storage/async-storage@^1.21.0": + version "1.21.0" + resolved "https://registry.yarnpkg.com/@react-native-async-storage/async-storage/-/async-storage-1.21.0.tgz#d7e370028e228ab84637016ceeb495878b7a44c8" + integrity sha512-JL0w36KuFHFCvnbOXRekqVAUplmOyT/OuCQkogo6X98MtpSaJOKEAeZnYO8JB0U/RIEixZaGI5px73YbRm/oag== + dependencies: + merge-options "^3.0.4" + +"@reduxjs/toolkit@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-2.0.1.tgz#0a5233c1e35c1941b03aece39cceade3467a1062" + integrity sha512-fxIjrR9934cmS8YXIGd9e7s1XRsEU++aFc9DVNMFMRTM5Vtsg2DCRMj21eslGtDt43IUf9bJL3h5bwUlZleibA== + dependencies: + immer "^10.0.3" + redux "^5.0.0" + redux-thunk "^3.1.0" + reselect "^5.0.1" + +"@remix-run/router@1.13.1": + version "1.13.1" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.13.1.tgz#07e2a8006f23a3bc898b3f317e0a58cc8076b86e" + integrity sha512-so+DHzZKsoOcoXrILB4rqDkMDy7NLMErRdOxvzvOKb507YINKUP4Di+shbTZDhSE/pBZ+vr7XGIpcOO0VLSA+Q== + +"@rollup/plugin-babel@^5.2.0": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" + integrity sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@rollup/pluginutils" "^3.1.0" + +"@rollup/plugin-node-resolve@^11.2.1": + version "11.2.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60" + integrity sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.19.0" + +"@rollup/plugin-replace@^2.4.1": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz#a2d539314fbc77c244858faa523012825068510a" + integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + magic-string "^0.25.7" + +"@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + +"@rushstack/eslint-patch@^1.1.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.6.0.tgz#1898e7a7b943680d757417a47fb10f5fcc230b39" + integrity sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA== + +"@sinclair/typebox@^0.24.1": + version "0.24.51" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@sinonjs/commons@^1.7.0": + version "1.8.6" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" + integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@surma/rollup-plugin-off-main-thread@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz#ee34985952ca21558ab0d952f00298ad2190c053" + integrity sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ== + dependencies: + ejs "^3.1.6" + json5 "^2.2.0" + magic-string "^0.25.0" + string.prototype.matchall "^4.0.6" + +"@svgr/babel-plugin-add-jsx-attribute@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz#81ef61947bb268eb9d50523446f9c638fb355906" + integrity sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg== + +"@svgr/babel-plugin-remove-jsx-attribute@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz#6b2c770c95c874654fd5e1d5ef475b78a0a962ef" + integrity sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg== + +"@svgr/babel-plugin-remove-jsx-empty-expression@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz#25621a8915ed7ad70da6cea3d0a6dbc2ea933efd" + integrity sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA== + +"@svgr/babel-plugin-replace-jsx-attribute-value@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz#0b221fc57f9fcd10e91fe219e2cd0dd03145a897" + integrity sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ== + +"@svgr/babel-plugin-svg-dynamic-title@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz#139b546dd0c3186b6e5db4fefc26cb0baea729d7" + integrity sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg== + +"@svgr/babel-plugin-svg-em-dimensions@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz#6543f69526632a133ce5cabab965deeaea2234a0" + integrity sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw== + +"@svgr/babel-plugin-transform-react-native-svg@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz#00bf9a7a73f1cad3948cdab1f8dfb774750f8c80" + integrity sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q== + +"@svgr/babel-plugin-transform-svg-component@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz#583a5e2a193e214da2f3afeb0b9e8d3250126b4a" + integrity sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ== + +"@svgr/babel-preset@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-5.5.0.tgz#8af54f3e0a8add7b1e2b0fcd5a882c55393df327" + integrity sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "^5.4.0" + "@svgr/babel-plugin-remove-jsx-attribute" "^5.4.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "^5.0.1" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^5.0.1" + "@svgr/babel-plugin-svg-dynamic-title" "^5.4.0" + "@svgr/babel-plugin-svg-em-dimensions" "^5.4.0" + "@svgr/babel-plugin-transform-react-native-svg" "^5.4.0" + "@svgr/babel-plugin-transform-svg-component" "^5.5.0" + +"@svgr/core@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-5.5.0.tgz#82e826b8715d71083120fe8f2492ec7d7874a579" + integrity sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ== + dependencies: + "@svgr/plugin-jsx" "^5.5.0" + camelcase "^6.2.0" + cosmiconfig "^7.0.0" + +"@svgr/hast-util-to-babel-ast@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz#5ee52a9c2533f73e63f8f22b779f93cd432a5461" + integrity sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ== + dependencies: + "@babel/types" "^7.12.6" + +"@svgr/plugin-jsx@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz#1aa8cd798a1db7173ac043466d7b52236b369000" + integrity sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA== + dependencies: + "@babel/core" "^7.12.3" + "@svgr/babel-preset" "^5.5.0" + "@svgr/hast-util-to-babel-ast" "^5.5.0" + svg-parser "^2.0.2" + +"@svgr/plugin-svgo@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz#02da55d85320549324e201c7b2e53bf431fcc246" + integrity sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ== + dependencies: + cosmiconfig "^7.0.0" + deepmerge "^4.2.2" + svgo "^1.2.2" + +"@svgr/webpack@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-5.5.0.tgz#aae858ee579f5fa8ce6c3166ef56c6a1b381b640" + integrity sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g== + dependencies: + "@babel/core" "^7.12.3" + "@babel/plugin-transform-react-constant-elements" "^7.12.1" + "@babel/preset-env" "^7.12.1" + "@babel/preset-react" "^7.12.5" + "@svgr/core" "^5.5.0" + "@svgr/plugin-jsx" "^5.5.0" + "@svgr/plugin-svgo" "^5.5.0" + loader-utils "^2.0.0" + +"@tanstack/query-async-storage-persister@^5.12.1": + version "5.13.4" + resolved "https://registry.yarnpkg.com/@tanstack/query-async-storage-persister/-/query-async-storage-persister-5.13.4.tgz#cf69694098cbcfbbf90ef32a8d23d97566148196" + integrity sha512-08UPpnNRPYKWS6+guSdpcbADzHyfBA6jq0kTe5jPFZjejSrbOr1lq/b9/pJtTgcGGBwPRPAbdqm15CjNBl9NxA== + dependencies: + "@tanstack/query-persist-client-core" "5.13.4" + +"@tanstack/query-core@5.13.4": + version "5.13.4" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.13.4.tgz#50ecd3f721dfb0859528fbb8863268bee24145f0" + integrity sha512-8+rJucXvC/xlr4OrxHhEIob/cTlbT4fgmz1VsvB0D12FRStKaXeLORNGcOhSAynRd2NL74SV/Qq0IIb4DedLcA== + +"@tanstack/query-devtools@5.13.3": + version "5.13.3" + resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.13.3.tgz#aeaa0c78cb25094172152a8d9551bf9896bcac29" + integrity sha512-1acztPKZexvM9Ns2T0aq4rMVSDA3VGdB73KF7zT/KNVl6VfnBvs24wuIRVSPZKqyZznZTzT3/DzcpntYqg9hmw== + +"@tanstack/query-persist-client-core@5.13.4": + version "5.13.4" + resolved "https://registry.yarnpkg.com/@tanstack/query-persist-client-core/-/query-persist-client-core-5.13.4.tgz#ea50e64281ae4b243eecc20b03ef9542fc5c6a44" + integrity sha512-a2NxXmp9dYr97dMHAD33fWeWfxTggBP8QenJj77XU0qnWTVCk7OYMa8FT75JmrtwhNLqTaZZDbz07r5e/Uogug== + dependencies: + "@tanstack/query-core" "5.13.4" + +"@tanstack/react-query-devtools@^5.13.3": + version "5.13.4" + resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.13.4.tgz#146f730cbd2929d408c1a20a3bc4312122817f4f" + integrity sha512-htYzfOrE6vucBCRrVLxW8qEg8mfC5UaMJMiFPgbv5yH3zoHtJSjVZP7fcvgTp3RwFKBr1IOQ9yHLTjSSXemS7A== + dependencies: + "@tanstack/query-devtools" "5.13.3" + +"@tanstack/react-query-persist-client@^5.12.2": + version "5.13.4" + resolved "https://registry.yarnpkg.com/@tanstack/react-query-persist-client/-/react-query-persist-client-5.13.4.tgz#2be6c3c7c459af28c87a50453cc1d1f40c275478" + integrity sha512-EAYMaQuc87MIXKLtUjw4Nc/CF2v7n5+dKs6mjoWe3DTa1/nFkOfUaXAwik8mvv2g92riQNskGsfeWKqdvuNejQ== + dependencies: + "@tanstack/query-persist-client-core" "5.13.4" + +"@tanstack/react-query@^5.12.2": + version "5.13.4" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.13.4.tgz#1a2b93a7319f3abd13461b5c5c7cf4eac369f567" + integrity sha512-3HjvkFFriEQwffUXtKHPiwkfFXUGbs46YATTzzyK1+Pw6Ekd3kwzS50e45qdamWuEXmXxyo5S1zp534LdFG0Rw== + dependencies: + "@tanstack/query-core" "5.13.4" + +"@tanstack/react-table@^8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.11.0.tgz#14fe04434b34d6d2f22ccde1f5df63a9b2fcae78" + integrity sha512-47wdYFlsbJlR6qt4F38nTGo93E6wNkXlN8t1TUI5SpSGiewx+KzBayMjfud3LgqbPLYYcpHby/tGkIF3tR8Upg== + dependencies: + "@tanstack/table-core" "8.11.0" + +"@tanstack/table-core@8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.11.0.tgz#70e15c706ccf5c5980c52d341ced5d38d0909a6a" + integrity sha512-7SC8/v6cXbUriOs2UISN8Jho3ttnA8cRZgusLn15b8meb28prHnWg4t4oNSHIR3rYn0g7iiIg+pax2CtBnyffg== + +"@testing-library/dom@^8.5.0": + version "8.20.1" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.1.tgz#2e52a32e46fc88369eef7eef634ac2a192decd9f" + integrity sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^5.0.1" + aria-query "5.1.3" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.5.0" + pretty-format "^27.0.2" + +"@testing-library/jest-dom@^5.17.0": + version "5.17.0" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz#5e97c8f9a15ccf4656da00fecab505728de81e0c" + integrity sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg== + dependencies: + "@adobe/css-tools" "^4.0.1" + "@babel/runtime" "^7.9.2" + "@types/testing-library__jest-dom" "^5.9.1" + aria-query "^5.0.0" + chalk "^3.0.0" + css.escape "^1.5.1" + dom-accessibility-api "^0.5.6" + lodash "^4.17.15" + redent "^3.0.0" + +"@testing-library/react@^13.4.0": + version "13.4.0" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.4.0.tgz#6a31e3bf5951615593ad984e96b9e5e2d9380966" + integrity sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw== + dependencies: + "@babel/runtime" "^7.12.5" + "@testing-library/dom" "^8.5.0" + "@types/react-dom" "^18.0.0" + +"@testing-library/user-event@^13.5.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.5.0.tgz#69d77007f1e124d55314a2b73fd204b333b13295" + integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== + dependencies: + "@babel/runtime" "^7.12.5" + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@types/aria-query@^5.0.1": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" + integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== + +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.7" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.7.tgz#a7aebf15c7bc0eb9abd638bdb5c0b8700399c9d0" + integrity sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.20.4" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.4.tgz#ec2c06fed6549df8bc0eb4615b683749a4a92e1b" + integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== + dependencies: + "@babel/types" "^7.20.7" + +"@types/body-parser@*": + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" + integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" + integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*", "@types/eslint@^7.29.0 || ^8.4.1": + version "8.44.8" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.8.tgz#f4fe1dab9b3d3dd98082d4b9f80e59ab40f1261c" + integrity sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": + version "4.17.41" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz#5077defa630c2e8d28aa9ffc2c01c157c305bef6" + integrity sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/graceful-fs@^4.1.2": + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== + dependencies: + "@types/node" "*" + +"@types/html-minifier-terser@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" + integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== + +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + +"@types/http-proxy@^1.17.8": + version "1.17.14" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec" + integrity sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/istanbul-lib-report@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@*": + version "29.5.11" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.11.tgz#0c13aa0da7d0929f078ab080ae5d4ced80fa2f2c" + integrity sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + +"@types/jest@^27.5.2": + version "27.5.2" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c" + integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA== + dependencies: + jest-matcher-utils "^27.0.0" + pretty-format "^27.0.0" + +"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/lodash.mergewith@4.6.7": + version "4.6.7" + resolved "https://registry.yarnpkg.com/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz#eaa65aa5872abdd282f271eae447b115b2757212" + integrity sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.14.202" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" + integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== + +"@types/mime@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" + integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== + +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== + +"@types/node-forge@^1.3.0": + version "1.3.10" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.10.tgz#62a19d4f75a8b03290578c2b04f294b1a5a71b07" + integrity sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw== + dependencies: + "@types/node" "*" + +"@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0": + version "20.10.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.4.tgz#b246fd84d55d5b1b71bf51f964bd514409347198" + integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg== + dependencies: + undici-types "~5.26.4" + +"@types/node@^16.18.66": + version "16.18.68" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.68.tgz#3155f64a961b3d8d10246c80657f9a7292e3421a" + integrity sha512-sG3hPIQwJLoewrN7cr0dwEy+yF5nD4D/4FxtQpFciRD/xwUzgD+G05uxZHv5mhfXo4F9Jkp13jjn0CC2q325sg== + +"@types/parse-json@^4.0.0": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== + +"@types/prettier@^2.1.5": + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== + +"@types/prop-types@*": + version "15.7.11" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" + integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== + +"@types/q@^1.5.1": + version "1.5.8" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.8.tgz#95f6c6a08f2ad868ba230ead1d2d7f7be3db3837" + integrity sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw== + +"@types/qs@*": + version "6.9.10" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.10.tgz#0af26845b5067e1c9a622658a51f60a3934d51e8" + integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== + +"@types/ramda@^0.29.9": + version "0.29.9" + resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.29.9.tgz#a4c1a9d056249268ffe16c2f6d198e42c2fc994a" + integrity sha512-X3yEG6tQCWBcUAql+RPC/O1Hm9BSU+MXu2wJnCETuAgUlrEDwTA1kIOdEEE4YXDtf0zfQLHa9CCE7WYp9kqPIQ== + dependencies: + types-ramda "^0.29.6" + +"@types/range-parser@*": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== + +"@types/react-calendar@^3.0.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@types/react-calendar/-/react-calendar-3.9.0.tgz#b345707c9b593331a48963514f3e30ce0b3ca195" + integrity sha512-KpAu1MKAGFw5hNwlDnWsHWqI9i/igAB+8jH97YV7QpC2v7rlwNEU5i6VMFb73lGRacuejM/Zd2LklnEzkFV3XA== + dependencies: + "@types/react" "*" + +"@types/react-dom@^18.0.0", "@types/react-dom@^18.2.17": + version "18.2.17" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.17.tgz#375c55fab4ae671bd98448dcfa153268d01d6f64" + integrity sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^18.2.39": + version "18.2.43" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.43.tgz#c58e5abe241e6f71f60ce30e2a9aceb9d3a2a374" + integrity sha512-nvOV01ZdBdd/KW6FahSbcNplt2jCJfyWdTos61RYHV+FVv5L/g9AOX1bmbVcWcLFL8+KHQfh1zVIQrud6ihyQA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/resolve@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== + dependencies: + "@types/node" "*" + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/scheduler@*": + version "0.16.8" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== + +"@types/semver@^7.3.12": + version "7.5.6" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" + integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== + +"@types/send@*": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-index@^1.9.1": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" + integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.15.5" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" + integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== + dependencies: + "@types/http-errors" "*" + "@types/mime" "*" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.36" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" + integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== + dependencies: + "@types/node" "*" + +"@types/stack-utils@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== + +"@types/testing-library__jest-dom@^5.9.1": + version "5.14.9" + resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz#0fb1e6a0278d87b6737db55af5967570b67cb466" + integrity sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw== + dependencies: + "@types/jest" "*" + +"@types/trusted-types@^2.0.2": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" + integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== + +"@types/use-sync-external-store@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" + integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== + +"@types/ws@^8.5.5": + version "8.5.10" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== + dependencies: + "@types/node" "*" + +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== + +"@types/yargs@^16.0.0": + version "16.0.9" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.9.tgz#ba506215e45f7707e6cbcaf386981155b7ab956e" + integrity sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA== + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs@^17.0.8": + version "17.0.32" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== + dependencies: + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@^5.5.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@^5.0.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz#14559bf73383a308026b427a4a6129bae2146741" + integrity sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw== + dependencies: + "@typescript-eslint/utils" "5.62.0" + +"@typescript-eslint/parser@^5.5.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== + dependencies: + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + +"@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== + dependencies: + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== + +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.58.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + eslint-scope "^5.1.1" + semver "^7.3.7" + +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== + dependencies: + "@typescript-eslint/types" "5.62.0" + eslint-visitor-keys "^3.3.0" + +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + +"@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== + +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== + +"@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + +"@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + +"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@xtuc/long" "4.2.2" + +"@wojtekmaj/date-utils@^1.0.2", "@wojtekmaj/date-utils@^1.0.3": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@wojtekmaj/date-utils/-/date-utils-1.5.1.tgz#c3cd67177ac781cfa5736219d702a55a2aea5f2b" + integrity sha512-+i7+JmNiE/3c9FKxzWFi2IjRJ+KzZl1QPu6QNrsgaa2MuBgXvUy4gA1TVzf/JMdIIloB76xSKikTWuyYAIVLww== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +"@zag-js/dom-query@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@zag-js/dom-query/-/dom-query-0.16.0.tgz#bca46bcd78f78c900064478646d95f9781ed098e" + integrity sha512-Oqhd6+biWyKnhKwFFuZrrf6lxBz2tX2pRQe6grUnYwO6HJ8BcbqZomy2lpOdr+3itlaUqx+Ywj5E5ZZDr/LBfQ== + +"@zag-js/element-size@0.10.5": + version "0.10.5" + resolved "https://registry.yarnpkg.com/@zag-js/element-size/-/element-size-0.10.5.tgz#a24bad2eeb7e2c8709e32be5336e158e1a1a174f" + integrity sha512-uQre5IidULANvVkNOBQ1tfgwTQcGl4hliPSe69Fct1VfYb2Fd0jdAcGzqQgPhfrXFpR62MxLPB7erxJ/ngtL8w== + +"@zag-js/focus-visible@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@zag-js/focus-visible/-/focus-visible-0.16.0.tgz#c9e53e3dbab0f2649d04a489bb379f5800f4f069" + integrity sha512-a7U/HSopvQbrDU4GLerpqiMcHKEkQkNPeDZJWz38cw/6Upunh41GjHetq5TB84hxyCaDzJ6q2nEdNoBQfC0FKA== + dependencies: + "@zag-js/dom-query" "0.16.0" + +abab@^2.0.3, abab@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.2.4, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.11.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== + +address@^1.0.1, address@^1.1.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" + integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== + +adjust-sourcemap-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz#fc4a0fd080f7d10471f30a7320f25560ade28c99" + integrity sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A== + dependencies: + loader-utils "^2.0.0" + regex-parser "^2.2.11" + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.6.0, ajv@^8.9.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-escapes@^4.2.1, ansi-escapes@^4.3.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@^3.0.3, anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +aria-hidden@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.3.tgz#14aeb7fb692bbb72d69bebfa47279c1fd725e954" + integrity sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ== + dependencies: + tslib "^2.0.0" + +aria-query@5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" + integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== + dependencies: + deep-equal "^2.0.5" + +aria-query@^5.0.0, aria-query@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-flatten@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-includes@^3.1.6, array-includes@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" + integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-string "^1.0.7" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.findlastindex@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" + integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + +array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.reduce@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz#63149931808c5fc1e1354814923d92d45f7d96d5" + integrity sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.7" + +array.prototype.tosorted@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz#620eff7442503d66c799d95503f82b475745cefd" + integrity sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + +arraybuffer.prototype.slice@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" + integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + +asap@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== + +ast-types-flow@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" + integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== + +async@^3.2.3: + version "3.2.5" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== + +asynciterator.prototype@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz#8c5df0514936cdd133604dfcc9d3fb93f09b2b62" + integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== + dependencies: + has-symbols "^1.0.3" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +autoprefixer@^10.4.13: + version "10.4.16" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.16.tgz#fad1411024d8670880bdece3970aa72e3572feb8" + integrity sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ== + dependencies: + browserslist "^4.21.10" + caniuse-lite "^1.0.30001538" + fraction.js "^4.3.6" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +axe-core@=4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" + integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== + +axios@^1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" + integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + +axobject-query@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" + integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== + dependencies: + dequal "^2.0.3" + +babel-jest@^27.4.2, babel-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== + dependencies: + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-loader@^8.2.3: + version "8.3.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" + integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== + dependencies: + find-cache-dir "^3.3.1" + loader-utils "^2.0.0" + make-dir "^3.1.0" + schema-utils "^2.6.5" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + +babel-plugin-macros@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== + dependencies: + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" + +babel-plugin-named-asset-import@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz#6b7fa43c59229685368683c28bc9734f24524cc2" + integrity sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q== + +babel-plugin-polyfill-corejs2@^0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz#b2df0251d8e99f229a8e60fc4efa9a68b41c8313" + integrity sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.3" + semver "^6.3.1" + +babel-plugin-polyfill-corejs3@^0.8.5: + version "0.8.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz#25c2d20002da91fe328ff89095c85a391d6856cf" + integrity sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.3" + core-js-compat "^3.33.1" + +babel-plugin-polyfill-regenerator@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz#d4c49e4b44614607c13fb769bcd85c72bb26a4a5" + integrity sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.3" + +babel-plugin-transform-react-remove-prop-types@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" + integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== + dependencies: + babel-plugin-jest-hoist "^27.5.1" + babel-preset-current-node-syntax "^1.0.0" + +babel-preset-react-app@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz#ed6005a20a24f2c88521809fa9aea99903751584" + integrity sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg== + dependencies: + "@babel/core" "^7.16.0" + "@babel/plugin-proposal-class-properties" "^7.16.0" + "@babel/plugin-proposal-decorators" "^7.16.4" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.0" + "@babel/plugin-proposal-numeric-separator" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.0" + "@babel/plugin-proposal-private-methods" "^7.16.0" + "@babel/plugin-transform-flow-strip-types" "^7.16.0" + "@babel/plugin-transform-react-display-name" "^7.16.0" + "@babel/plugin-transform-runtime" "^7.16.4" + "@babel/preset-env" "^7.16.4" + "@babel/preset-react" "^7.16.0" + "@babel/preset-typescript" "^7.16.0" + "@babel/runtime" "^7.16.3" + babel-plugin-macros "^3.1.0" + babel-plugin-transform-react-remove-prop-types "^0.4.24" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +bfj@^7.0.2: + version "7.1.0" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.1.0.tgz#c5177d522103f9040e1b12980fe8c38cf41d3f8b" + integrity sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw== + dependencies: + bluebird "^3.7.2" + check-types "^11.2.3" + hoopy "^0.1.4" + jsonpath "^1.1.1" + tryer "^1.0.1" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour-service@^1.0.11: + version "1.1.1" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.1.tgz#960948fa0e0153f5d26743ab15baf8e33752c135" + integrity sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg== + dependencies: + array-flatten "^2.1.2" + dns-equal "^1.0.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.9, browserslist@^4.22.2: + version "4.22.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" + integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== + dependencies: + caniuse-lite "^1.0.30001565" + electron-to-chromium "^1.4.601" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +builtin-modules@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0, camelcase@^6.2.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001565: + version "1.0.30001566" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz#61a8e17caf3752e3e426d4239c549ebbb37fef0d" + integrity sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA== + +case-sensitive-paths-webpack-plugin@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" + integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== + +chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +char-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-2.0.1.tgz#6dafdb25f9d3349914079f010ba8d0e6ff9cd01e" + integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw== + +check-types@^11.2.3: + version "11.2.3" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.3.tgz#1ffdf68faae4e941fce252840b1787b8edc93b71" + integrity sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg== + +chokidar@^3.4.2, chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +ci-info@^3.2.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + +cjs-module-lexer@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + +clean-css@^5.2.2: + version "5.3.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" + integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== + dependencies: + source-map "~0.6.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +collect-v8-coverage@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color2k@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/color2k/-/color2k-2.0.3.tgz#a771244f6b6285541c82aa65ff0a0c624046e533" + integrity sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog== + +colord@^2.9.1: + version "2.9.3" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" + integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== + +colorette@^2.0.10: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +common-path-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" + integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== + +common-tags@^1.8.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +compute-scroll-into-view@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-3.0.3.tgz#c418900a5c56e2b04b885b54995df164535962b1" + integrity sha512-nadqwNxghAGTamwIqQSG433W6OADZx2vCo3UXHNrzTRHK/htu+7+L0zhjEoaeaQVNAi3YgqWDv8+tzf0hRfR+A== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +confusing-browser-globals@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" + integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== + +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +copy-to-clipboard@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" + integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== + dependencies: + toggle-selection "^1.0.6" + +core-js-compat@^3.31.0, core-js-compat@^3.33.1: + version "3.34.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.34.0.tgz#61a4931a13c52f8f08d924522bba65f8c94a5f17" + integrity sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA== + dependencies: + browserslist "^4.22.2" + +core-js-pure@^3.23.3: + version "3.34.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.34.0.tgz#981e462500708664c91b827a75b011f04a8134a0" + integrity sha512-pmhivkYXkymswFfbXsANmBAewXx86UBfmagP+w0wkK06kLsLlTK5oQmsURPivzMkIBQiYq2cjamcZExIwlFQIg== + +core-js@^3.19.2: + version "3.34.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.34.0.tgz#5705e6ad5982678612e96987d05b27c6c7c274a5" + integrity sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + +cosmiconfig@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + +css-blank-pseudo@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz#36523b01c12a25d812df343a32c322d2a2324561" + integrity sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ== + dependencies: + postcss-selector-parser "^6.0.9" + +css-box-model@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1" + integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw== + dependencies: + tiny-invariant "^1.0.6" + +css-declaration-sorter@^6.3.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" + integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g== + +css-has-pseudo@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz#57f6be91ca242d5c9020ee3e51bbb5b89fc7af73" + integrity sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw== + dependencies: + postcss-selector-parser "^6.0.9" + +css-loader@^6.5.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.8.1.tgz#0f8f52699f60f5e679eab4ec0fcd68b8e8a50a88" + integrity sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.21" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.3" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.8" + +css-minimizer-webpack-plugin@^3.2.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz#ab78f781ced9181992fe7b6e4f3422e76429878f" + integrity sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q== + dependencies: + cssnano "^5.0.6" + jest-worker "^27.0.2" + postcss "^8.3.5" + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + +css-prefers-color-scheme@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz#ca8a22e5992c10a5b9d315155e7caee625903349" + integrity sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA== + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-select@^4.1.3: + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== + dependencies: + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-tree@1.0.0-alpha.37: + version "1.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== + dependencies: + mdn-data "2.0.4" + source-map "^0.6.1" + +css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-what@^3.2.1: + version "3.4.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" + integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== + +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== + +cssdb@^7.1.0: + version "7.9.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.9.0.tgz#d42d8269ff3d3e1c366280ab1f9f6207057b262c" + integrity sha512-WPMT9seTQq6fPAa1yN4zjgZZeoTriSN2LqW9C+otjar12DQIWA4LuSfFrvFJiKp4oD0xIk1vumDLw8K9ur4NBw== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-default@^5.2.14: + version "5.2.14" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8" + integrity sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A== + dependencies: + css-declaration-sorter "^6.3.1" + cssnano-utils "^3.1.0" + postcss-calc "^8.2.3" + postcss-colormin "^5.3.1" + postcss-convert-values "^5.1.3" + postcss-discard-comments "^5.1.2" + postcss-discard-duplicates "^5.1.0" + postcss-discard-empty "^5.1.1" + postcss-discard-overridden "^5.1.0" + postcss-merge-longhand "^5.1.7" + postcss-merge-rules "^5.1.4" + postcss-minify-font-values "^5.1.0" + postcss-minify-gradients "^5.1.1" + postcss-minify-params "^5.1.4" + postcss-minify-selectors "^5.2.1" + postcss-normalize-charset "^5.1.0" + postcss-normalize-display-values "^5.1.0" + postcss-normalize-positions "^5.1.1" + postcss-normalize-repeat-style "^5.1.1" + postcss-normalize-string "^5.1.0" + postcss-normalize-timing-functions "^5.1.0" + postcss-normalize-unicode "^5.1.1" + postcss-normalize-url "^5.1.0" + postcss-normalize-whitespace "^5.1.1" + postcss-ordered-values "^5.1.3" + postcss-reduce-initial "^5.1.2" + postcss-reduce-transforms "^5.1.0" + postcss-svgo "^5.1.0" + postcss-unique-selectors "^5.1.1" + +cssnano-utils@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" + integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== + +cssnano@^5.0.6: + version "5.1.15" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf" + integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw== + dependencies: + cssnano-preset-default "^5.2.14" + lilconfig "^2.0.3" + yaml "^1.10.2" + +csso@^4.0.2, csso@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + +csstype@^3.0.2, csstype@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +damerau-levenshtein@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" + integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== + +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + +date-fns@^2.30.0: + version "2.30.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== + dependencies: + "@babel/runtime" "^7.21.0" + +debug@2.6.9, debug@^2.6.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decimal.js@^10.2.1: + version "10.4.3" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== + +deep-equal@^2.0.5: + version "2.2.3" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1" + integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.5" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.2" + is-arguments "^1.1.1" + is-array-buffer "^3.0.2" + is-date-object "^1.0.5" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.13" + +deep-is@^0.1.3, deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-data-property@^1.0.1, define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +dequal@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-element-overflow@^1.4.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/detect-element-overflow/-/detect-element-overflow-1.4.2.tgz#2e48509e5aa07647f4335b5f4f52c146b92f99c5" + integrity sha512-4m6cVOtvm/GJLjo7WFkPfwXoEIIbM7GQwIh4WEa4g7IsNi1YzwUsGL5ApNLrrHL29bHeNeQ+/iZhw+YHqgE2Fw== + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +detect-port-alt@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" + integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +didyoumean@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + +diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== + +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + +dns-packet@^5.2.2: + version "5.6.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" + integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: + version "0.5.16" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== + +dom-converter@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== + dependencies: + webidl-conversions "^5.0.0" + +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" + integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== + +duplexer@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +ejs@^3.1.6: + version "3.1.9" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" + integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== + dependencies: + jake "^10.8.5" + +electron-to-chromium@^1.4.601: + version "1.4.609" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.609.tgz#5790a70aaa96de232501b56e14b64d17aff93988" + integrity sha512-ihiCP7PJmjoGNuLpl7TjNA8pCQWu09vGyjlPYw1Rqww4gvNuCcmvl+44G+2QyJ6S2K4o+wbTS++Xz0YN8Q9ERw== + +emittery@^0.10.2: + version "0.10.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" + integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== + +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +enhanced-resolve@^5.15.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +error-stack-parser@^2.0.6: + version "2.1.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" + integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== + dependencies: + stackframe "^1.3.4" + +es-abstract@^1.17.2, es-abstract@^1.22.1: + version "1.22.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" + integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== + dependencies: + array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.2" + available-typed-arrays "^1.0.5" + call-bind "^1.0.5" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.2" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.12" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + safe-array-concat "^1.0.1" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.8" + string.prototype.trimend "^1.0.7" + string.prototype.trimstart "^1.0.7" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.13" + +es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + +es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + is-arguments "^1.1.1" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.7" + isarray "^2.0.5" + stop-iteration-iterator "^1.0.0" + +es-iterator-helpers@^1.0.12, es-iterator-helpers@^1.0.15: + version "1.0.15" + resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40" + integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== + dependencies: + asynciterator.prototype "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.1" + es-abstract "^1.22.1" + es-set-tostringtag "^2.0.1" + function-bind "^1.1.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + iterator.prototype "^1.1.2" + safe-array-concat "^1.0.1" + +es-module-lexer@^1.2.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.4.1.tgz#41ea21b43908fe6a287ffcbe4300f790555331f5" + integrity sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w== + +es-set-tostringtag@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" + integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== + dependencies: + get-intrinsic "^1.2.2" + has-tostringtag "^1.0.0" + hasown "^2.0.0" + +es-shim-unscopables@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== + dependencies: + hasown "^2.0.0" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escodegen@^1.8.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +escodegen@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionalDependencies: + source-map "~0.6.1" + +eslint-config-react-app@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz#73ba3929978001c5c86274c017ea57eb5fa644b4" + integrity sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA== + dependencies: + "@babel/core" "^7.16.0" + "@babel/eslint-parser" "^7.16.3" + "@rushstack/eslint-patch" "^1.1.0" + "@typescript-eslint/eslint-plugin" "^5.5.0" + "@typescript-eslint/parser" "^5.5.0" + babel-preset-react-app "^10.0.1" + confusing-browser-globals "^1.0.11" + eslint-plugin-flowtype "^8.0.3" + eslint-plugin-import "^2.25.3" + eslint-plugin-jest "^25.3.0" + eslint-plugin-jsx-a11y "^6.5.1" + eslint-plugin-react "^7.27.1" + eslint-plugin-react-hooks "^4.3.0" + eslint-plugin-testing-library "^5.0.1" + +eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== + dependencies: + debug "^3.2.7" + is-core-module "^2.13.0" + resolve "^1.22.4" + +eslint-module-utils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== + dependencies: + debug "^3.2.7" + +eslint-plugin-flowtype@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz#e1557e37118f24734aa3122e7536a038d34a4912" + integrity sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ== + dependencies: + lodash "^4.17.21" + string-natural-compare "^3.0.1" + +eslint-plugin-import@^2.25.3: + version "2.29.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155" + integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg== + dependencies: + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" + debug "^3.2.7" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.8.0" + hasown "^2.0.0" + is-core-module "^2.13.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" + semver "^6.3.1" + tsconfig-paths "^3.14.2" + +eslint-plugin-jest@^25.3.0: + version "25.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz#ff4ac97520b53a96187bad9c9814e7d00de09a6a" + integrity sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ== + dependencies: + "@typescript-eslint/experimental-utils" "^5.0.0" + +eslint-plugin-jsx-a11y@^6.5.1: + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz#2fa9c701d44fcd722b7c771ec322432857fcbad2" + integrity sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA== + dependencies: + "@babel/runtime" "^7.23.2" + aria-query "^5.3.0" + array-includes "^3.1.7" + array.prototype.flatmap "^1.3.2" + ast-types-flow "^0.0.8" + axe-core "=4.7.0" + axobject-query "^3.2.1" + damerau-levenshtein "^1.0.8" + emoji-regex "^9.2.2" + es-iterator-helpers "^1.0.15" + hasown "^2.0.0" + jsx-ast-utils "^3.3.5" + language-tags "^1.0.9" + minimatch "^3.1.2" + object.entries "^1.1.7" + object.fromentries "^2.0.7" + +eslint-plugin-react-hooks@^4.3.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" + integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + +eslint-plugin-react@^7.27.1: + version "7.33.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608" + integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== + dependencies: + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" + array.prototype.tosorted "^1.1.1" + doctrine "^2.1.0" + es-iterator-helpers "^1.0.12" + estraverse "^5.3.0" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" + object.hasown "^1.1.2" + object.values "^1.1.6" + prop-types "^15.8.1" + resolve "^2.0.0-next.4" + semver "^6.3.1" + string.prototype.matchall "^4.0.8" + +eslint-plugin-testing-library@^5.0.1: + version "5.11.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz#5b46cdae96d4a78918711c0b4792f90088e62d20" + integrity sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw== + dependencies: + "@typescript-eslint/utils" "^5.58.0" + +eslint-scope@5.1.1, eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint-webpack-plugin@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz#1978cdb9edc461e4b0195a20da950cf57988347c" + integrity sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w== + dependencies: + "@types/eslint" "^7.29.0 || ^8.4.1" + jest-worker "^28.0.2" + micromatch "^4.0.5" + normalize-path "^3.0.0" + schema-utils "^4.0.0" + +eslint@^8.3.0: + version "8.55.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.55.0.tgz#078cb7b847d66f2c254ea1794fa395bf8e7e03f8" + integrity sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.55.0" + "@humanwhocodes/config-array" "^0.11.13" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esprima@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.2.tgz#76a0fd66fcfe154fd292667dc264019750b1657b" + integrity sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A== + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== + dependencies: + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + +expect@^29.0.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== + dependencies: + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + +express@^4.17.3: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.9, fast-glob@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +faye-websocket@0.11.4, faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + +filesize@^8.0.6: + version "8.0.7" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-8.0.7.tgz#695e70d80f4e47012c132d57a059e80c6b580bd8" + integrity sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +firebase@^10.7.0: + version "10.7.1" + resolved "https://registry.yarnpkg.com/firebase/-/firebase-10.7.1.tgz#71fa17a10146f388746ecc216a3e1e477a7bf9b5" + integrity sha512-Mlt7y7zQ43FtKp4SCyYie3tnrOL3UMF2XXiV4ZXMrC0d0wtcOYmABuybhkJpJCKILpdekxr39wjnaai0DZlWFg== + dependencies: + "@firebase/analytics" "0.10.0" + "@firebase/analytics-compat" "0.2.6" + "@firebase/app" "0.9.25" + "@firebase/app-check" "0.8.1" + "@firebase/app-check-compat" "0.3.8" + "@firebase/app-compat" "0.2.25" + "@firebase/app-types" "0.9.0" + "@firebase/auth" "1.5.1" + "@firebase/auth-compat" "0.5.1" + "@firebase/database" "1.0.2" + "@firebase/database-compat" "1.0.2" + "@firebase/firestore" "4.4.0" + "@firebase/firestore-compat" "0.3.23" + "@firebase/functions" "0.11.0" + "@firebase/functions-compat" "0.3.6" + "@firebase/installations" "0.6.4" + "@firebase/installations-compat" "0.2.4" + "@firebase/messaging" "0.12.5" + "@firebase/messaging-compat" "0.2.5" + "@firebase/performance" "0.6.4" + "@firebase/performance-compat" "0.2.4" + "@firebase/remote-config" "0.4.4" + "@firebase/remote-config-compat" "0.2.4" + "@firebase/storage" "0.12.0" + "@firebase/storage-compat" "0.3.3" + "@firebase/util" "1.9.3" + +flat-cache@^3.0.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.3" + rimraf "^3.0.2" + +flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== + +focus-lock@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-1.0.0.tgz#2c50d8ce59d3d6608cda2672be9e65812459206c" + integrity sha512-a8Ge6cdKh9za/GZR/qtigTAk7SrGore56EFcoMshClsh7FLk1zwszc/ltuMfKhx56qeuyL/jWQ4J4axou0iJ9w== + dependencies: + tslib "^2.0.3" + +follow-redirects@^1.0.0, follow-redirects@^1.15.0: + version "1.15.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" + integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +fork-ts-checker-webpack-plugin@^6.5.0: + version "6.5.3" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" + integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== + dependencies: + "@babel/code-frame" "^7.8.3" + "@types/json-schema" "^7.0.5" + chalk "^4.1.0" + chokidar "^3.4.2" + cosmiconfig "^6.0.0" + deepmerge "^4.2.2" + fs-extra "^9.0.0" + glob "^7.1.6" + memfs "^3.1.2" + minimatch "^3.0.4" + schema-utils "2.7.0" + semver "^7.3.2" + tapable "^1.0.0" + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fraction.js@^4.3.6: + version "4.3.7" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7" + integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== + +framer-motion@^10.16.12: + version "10.16.16" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-10.16.16.tgz#a10a03e1190a717109163cfff212a84c8ad11b0c" + integrity sha512-je6j91rd7NmUX7L1XHouwJ4v3R+SO4umso2LUcgOct3rHZ0PajZ80ETYZTajzEXEl9DlKyzjyt4AvGQ+lrebOw== + dependencies: + tslib "^2.4.0" + optionalDependencies: + "@emotion/is-prop-valid" "^0.8.2" + +framesync@6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.1.2.tgz#755eff2fb5b8f3b4d2b266dd18121b300aefea27" + integrity sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g== + dependencies: + tslib "2.4.0" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-extra@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^9.0.0, fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-monkey@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.5.tgz#fe450175f0db0d7ea758102e1d84096acb925788" + integrity sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^2.3.2, fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.1, function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + +functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +get-user-locale@^1.2.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/get-user-locale/-/get-user-locale-1.5.1.tgz#18a9ba2cfeed0e713ea00968efa75d620523a5ea" + integrity sha512-WiNpoFRcHn1qxP9VabQljzGwkAQDrcpqUtaP0rNBEkFxJdh4f3tik6MfZsMYZc+UgQJdGCxWEjL9wnCUlRQXag== + dependencies: + lodash.memoize "^4.1.1" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.19.0: + version "13.23.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" + integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== + dependencies: + type-fest "^0.20.2" + +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +globby@^11.0.4, globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +gzip-size@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" + integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== + dependencies: + duplexer "^0.1.2" + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +harmony-reflect@^1.4.6: + version "1.6.2" + resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.2.tgz#31ecbd32e648a34d030d86adb67d4d47547fe710" + integrity sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g== + +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== + dependencies: + get-intrinsic "^1.2.2" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hoist-non-react-statics@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +hoopy@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" + +html-entities@^2.1.0, html-entities@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.4.0.tgz#edd0cee70402584c8c76cc2c0556db09d1f45061" + integrity sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ== + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +html-minifier-terser@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" + integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== + dependencies: + camel-case "^4.1.2" + clean-css "^5.2.2" + commander "^8.3.0" + he "^1.2.0" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.10.0" + +html-webpack-plugin@^5.5.0: + version "5.5.4" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.4.tgz#517a48e6f046ff1ae1a172c983cd993eb79d2f6a" + integrity sha512-3wNSaVVxdxcu0jd4FpQFoICdqgxs4zIQQvj+2yQKFfBOnLETQ6X5CDWdeasuGlSsooFlMkEioWDTqBv1wvw5Iw== + dependencies: + "@types/html-minifier-terser" "^6.0.0" + html-minifier-terser "^6.0.2" + lodash "^4.17.21" + pretty-error "^4.0.0" + tapable "^2.0.0" + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +idb@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/idb/-/idb-7.0.1.tgz#d2875b3a2f205d854ee307f6d196f246fea590a7" + integrity sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg== + +idb@7.1.1, idb@^7.0.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" + integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== + +identity-obj-proxy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14" + integrity sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA== + dependencies: + harmony-reflect "^1.4.6" + +ignore@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== + +immer@^10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/immer/-/immer-10.0.3.tgz#a8de42065e964aa3edf6afc282dfc7f7f34ae3c9" + integrity sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A== + +immer@^9.0.7: + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== + +import-fresh@^3.1.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +ini@^1.3.5: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +internal-slot@^1.0.4, internal-slot@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== + dependencies: + get-intrinsic "^1.2.2" + hasown "^2.0.0" + side-channel "^1.0.4" + +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" + integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== + +is-arguments@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-async-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" + integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== + dependencies: + has-tostringtag "^1.0.0" + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.13.0, is-core-module@^2.13.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-date-object@^1.0.1, is-date-object@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-finalizationregistry@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz#c8749b65f17c133313e661b1289b95ad3dbd62e6" + integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== + dependencies: + call-bind "^1.0.2" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-generator-function@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== + +is-root@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" + integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== + +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +iterator.prototype@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" + integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== + dependencies: + define-properties "^1.2.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + reflect.getprototypeof "^1.0.4" + set-function-name "^2.0.1" + +jake@^10.8.5: + version "10.8.7" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" + +jest-changed-files@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" + integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== + dependencies: + "@jest/types" "^27.5.1" + execa "^5.0.0" + throat "^6.0.1" + +jest-circus@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" + integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + +jest-cli@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" + integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== + dependencies: + "@jest/core" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + prompts "^2.0.1" + yargs "^16.2.0" + +jest-config@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" + integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== + dependencies: + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.5.1" + "@jest/types" "^27.5.1" + babel-jest "^27.5.1" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.9" + jest-circus "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-get-type "^27.5.1" + jest-jasmine2 "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runner "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^27.5.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-docblock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" + integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== + dependencies: + detect-newline "^3.0.0" + +jest-each@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" + integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + jest-get-type "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + +jest-environment-jsdom@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" + integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jsdom "^16.6.0" + +jest-environment-node@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" + integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +jest-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== + +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== + +jest-haste-map@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== + dependencies: + "@jest/types" "^27.5.1" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^27.5.1" + jest-serializer "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + +jest-jasmine2@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" + integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + throat "^6.0.1" + +jest-leak-detector@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" + integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== + dependencies: + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== + dependencies: + chalk "^4.0.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== + dependencies: + chalk "^4.0.0" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.5.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-message-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" + integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^28.1.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^28.1.3" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + +jest-regex-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== + +jest-regex-util@^28.0.0: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" + integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== + +jest-resolve-dependencies@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" + integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== + dependencies: + "@jest/types" "^27.5.1" + jest-regex-util "^27.5.1" + jest-snapshot "^27.5.1" + +jest-resolve@^27.4.2, jest-resolve@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" + integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-runner@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" + integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + graceful-fs "^4.2.9" + jest-docblock "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-haste-map "^27.5.1" + jest-leak-detector "^27.5.1" + jest-message-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runtime "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + source-map-support "^0.5.6" + throat "^6.0.1" + +jest-runtime@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" + integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/globals" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-serializer@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.9" + +jest-snapshot@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" + integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.5.1" + graceful-fs "^4.2.9" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + jest-haste-map "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + natural-compare "^1.4.0" + pretty-format "^27.5.1" + semver "^7.3.2" + +jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" + integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" + integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== + dependencies: + "@jest/types" "^27.5.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.5.1" + leven "^3.1.0" + pretty-format "^27.5.1" + +jest-watch-typeahead@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz#b4a6826dfb9c9420da2f7bc900de59dad11266a9" + integrity sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw== + dependencies: + ansi-escapes "^4.3.1" + chalk "^4.0.0" + jest-regex-util "^28.0.0" + jest-watcher "^28.0.0" + slash "^4.0.0" + string-length "^5.0.1" + strip-ansi "^7.0.1" + +jest-watcher@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" + integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== + dependencies: + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.5.1" + string-length "^4.0.1" + +jest-watcher@^28.0.0: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" + integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== + dependencies: + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.10.2" + jest-util "^28.1.3" + string-length "^4.0.1" + +jest-worker@^26.2.1: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest-worker@^27.0.2, jest-worker@^27.4.5, jest-worker@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest-worker@^28.0.2: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" + integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^27.4.3: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" + integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== + dependencies: + "@jest/core" "^27.5.1" + import-local "^3.0.2" + jest-cli "^27.5.1" + +jiti@^1.19.1: + version "1.21.0" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" + integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsdom@^16.6.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== + dependencies: + abab "^2.0.5" + acorn "^8.2.4" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + form-data "^3.0.0" + html-encoding-sniffer "^2.0.1" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.6" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2, json5@^2.2.0, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonpath@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/jsonpath/-/jsonpath-1.1.1.tgz#0ca1ed8fb65bb3309248cc9d5466d12d5b0b9901" + integrity sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w== + dependencies: + esprima "1.2.2" + static-eval "2.0.2" + underscore "1.12.1" + +jsonpointer@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" + integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== + +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: + version "3.3.5" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" + integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== + dependencies: + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + object.assign "^4.1.4" + object.values "^1.1.6" + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +klona@^2.0.4, klona@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== + +language-subtag-registry@^0.3.20: + version "0.3.22" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" + integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== + +language-tags@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777" + integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== + dependencies: + language-subtag-registry "^0.3.20" + +launch-editor@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.1.tgz#f259c9ef95cbc9425620bbbd14b468fcdb4ffe3c" + integrity sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw== + dependencies: + picocolors "^1.0.0" + shell-quote "^1.8.1" + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lilconfig@^2.0.3, lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lilconfig@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.0.0.tgz#f8067feb033b5b74dab4602a5f5029420be749bc" + integrity sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +loader-utils@^2.0.0, loader-utils@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +loader-utils@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.1.tgz#4fb104b599daafd82ef3e1a41fb9265f87e1f576" + integrity sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw== + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== + +lodash.memoize@^4.1.1, lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.mergewith@4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== + +lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +long@^5.0.0: + version "5.2.3" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" + integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lz-string@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== + +magic-string@^0.25.0, magic-string@^0.25.7: + version "0.25.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== + dependencies: + sourcemap-codec "^1.4.8" + +make-dir@^3.0.2, make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + +make-event-props@^1.1.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/make-event-props/-/make-event-props-1.6.2.tgz#c8e0e48eb28b9b808730de38359f6341de7ec5a2" + integrity sha512-iDwf7mA03WPiR8QxvcVHmVWEPfMY1RZXerDVNCRYW7dUr2ppH3J58Rwb39/WG39yTZdRSxr3x+2v22tvI0VEvA== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memfs@^3.1.2, memfs@^3.4.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" + integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== + dependencies: + fs-monkey "^1.0.4" + +merge-class-names@^1.1.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/merge-class-names/-/merge-class-names-1.4.2.tgz#78d6d95ab259e7e647252a7988fd25a27d5a8835" + integrity sha512-bOl98VzwCGi25Gcn3xKxnR5p/WrhWFQB59MS/aGENcmUc6iSm96yrFDF0XSNurX9qN4LbJm0R9kfvsQ17i8zCw== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-options@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/merge-options/-/merge-options-3.0.4.tgz#84709c2aa2a4b24c1981f66c179fe5565cc6dbb7" + integrity sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ== + dependencies: + is-plain-obj "^2.1.0" + +merge-refs@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/merge-refs/-/merge-refs-1.2.2.tgz#6142633398dd0d10a37626cae77ddeb1db26db0c" + integrity sha512-RwcT7GsQR3KbuLw1rRuodq4Nt547BKEBkliZ0qqsrpyNne9bGTFtsFIsIpx82huWhcl3kOlOlH4H0xkPk/DqVw== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +min-indent@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" + integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== + +mini-css-extract-plugin@^2.4.5: + version "2.7.6" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz#282a3d38863fddcd2e0c220aaed5b90bc156564d" + integrity sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw== + dependencies: + schema-utils "^4.0.0" + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nth-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +nwsapi@^2.2.0: + version "2.2.7" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" + integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== + +object-assign@^4.0.1, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + +object-inspect@^1.13.1, object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +object-is@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.4: + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== + dependencies: + call-bind "^1.0.5" + define-properties "^1.2.1" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.entries@^1.1.6, object.entries@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" + integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +object.fromentries@^2.0.6, object.fromentries@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" + integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +object.getownpropertydescriptors@^2.1.0: + version "2.1.7" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.7.tgz#7a466a356cd7da4ba8b9e94ff6d35c3eeab5d56a" + integrity sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g== + dependencies: + array.prototype.reduce "^1.0.6" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + safe-array-concat "^1.0.0" + +object.groupby@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" + integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + +object.hasown@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.3.tgz#6a5f2897bb4d3668b8e79364f98ccf971bda55ae" + integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== + dependencies: + define-properties "^1.2.0" + es-abstract "^1.22.1" + +object.values@^1.1.0, object.values@^1.1.6, object.values@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" + integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9, open@^8.4.0: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0, parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + +picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" + integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pirates@^4.0.1, pirates@^4.0.4: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +pkg-dir@^4.1.0, pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + +postcss-attribute-case-insensitive@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz#03d761b24afc04c09e757e92ff53716ae8ea2741" + integrity sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-browser-comments@^4: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz#bcfc86134df5807f5d3c0eefa191d42136b5e72a" + integrity sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg== + +postcss-calc@^8.2.3: + version "8.2.4" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" + integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== + dependencies: + postcss-selector-parser "^6.0.9" + postcss-value-parser "^4.2.0" + +postcss-clamp@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-clamp/-/postcss-clamp-4.1.0.tgz#7263e95abadd8c2ba1bd911b0b5a5c9c93e02363" + integrity sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-functional-notation@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz#21a909e8d7454d3612d1659e471ce4696f28caec" + integrity sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-hex-alpha@^8.0.4: + version "8.0.4" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz#c66e2980f2fbc1a63f5b079663340ce8b55f25a5" + integrity sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-rebeccapurple@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz#63fdab91d878ebc4dd4b7c02619a0c3d6a56ced0" + integrity sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-colormin@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f" + integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + colord "^2.9.1" + postcss-value-parser "^4.2.0" + +postcss-convert-values@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz#04998bb9ba6b65aa31035d669a6af342c5f9d393" + integrity sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA== + dependencies: + browserslist "^4.21.4" + postcss-value-parser "^4.2.0" + +postcss-custom-media@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz#c8f9637edf45fef761b014c024cee013f80529ea" + integrity sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-properties@^12.1.10: + version "12.1.11" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz#d14bb9b3989ac4d40aaa0e110b43be67ac7845cf" + integrity sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-selectors@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz#1ab4684d65f30fed175520f82d223db0337239d9" + integrity sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-dir-pseudo-class@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz#2bf31de5de76added44e0a25ecf60ae9f7c7c26c" + integrity sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-discard-comments@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696" + integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ== + +postcss-discard-duplicates@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" + integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== + +postcss-discard-empty@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" + integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== + +postcss-discard-overridden@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" + integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== + +postcss-double-position-gradients@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz#b96318fdb477be95997e86edd29c6e3557a49b91" + integrity sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +postcss-env-function@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-4.0.6.tgz#7b2d24c812f540ed6eda4c81f6090416722a8e7a" + integrity sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-flexbugs-fixes@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz#2028e145313074fc9abe276cb7ca14e5401eb49d" + integrity sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ== + +postcss-focus-visible@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz#50c9ea9afa0ee657fb75635fabad25e18d76bf9e" + integrity sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-focus-within@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz#5b1d2ec603195f3344b716c0b75f61e44e8d2e20" + integrity sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-font-variant@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" + integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== + +postcss-gap-properties@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz#f7e3cddcf73ee19e94ccf7cb77773f9560aa2fff" + integrity sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg== + +postcss-image-set-function@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz#08353bd756f1cbfb3b6e93182c7829879114481f" + integrity sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-initial@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" + integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== + +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== + dependencies: + camelcase-css "^2.0.1" + +postcss-lab-function@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz#6fe4c015102ff7cd27d1bd5385582f67ebdbdc98" + integrity sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +postcss-load-config@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3" + integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ== + dependencies: + lilconfig "^3.0.0" + yaml "^2.3.4" + +postcss-loader@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.1.tgz#0895f7346b1702103d30fdc66e4d494a93c008ef" + integrity sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.5" + semver "^7.3.5" + +postcss-logical@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-5.0.4.tgz#ec75b1ee54421acc04d5921576b7d8db6b0e6f73" + integrity sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g== + +postcss-media-minmax@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz#7140bddec173e2d6d657edbd8554a55794e2a5b5" + integrity sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ== + +postcss-merge-longhand@^5.1.7: + version "5.1.7" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz#24a1bdf402d9ef0e70f568f39bdc0344d568fb16" + integrity sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^5.1.1" + +postcss-merge-rules@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c" + integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + cssnano-utils "^3.1.0" + postcss-selector-parser "^6.0.5" + +postcss-minify-font-values@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" + integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-minify-gradients@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c" + integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw== + dependencies: + colord "^2.9.1" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-minify-params@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz#c06a6c787128b3208b38c9364cfc40c8aa5d7352" + integrity sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw== + dependencies: + browserslist "^4.21.4" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-minify-selectors@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6" + integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz#b08eb4f083050708998ba2c6061b50c2870ca524" + integrity sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-nested@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c" + integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== + dependencies: + postcss-selector-parser "^6.0.11" + +postcss-nesting@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.2.0.tgz#0b12ce0db8edfd2d8ae0aaf86427370b898890be" + integrity sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA== + dependencies: + "@csstools/selector-specificity" "^2.0.0" + postcss-selector-parser "^6.0.10" + +postcss-normalize-charset@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" + integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== + +postcss-normalize-display-values@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" + integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-positions@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" + integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-repeat-style@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" + integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-string@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" + integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-timing-functions@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" + integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-unicode@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz#f67297fca3fea7f17e0d2caa40769afc487aa030" + integrity sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA== + dependencies: + browserslist "^4.21.4" + postcss-value-parser "^4.2.0" + +postcss-normalize-url@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" + integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== + dependencies: + normalize-url "^6.0.1" + postcss-value-parser "^4.2.0" + +postcss-normalize-whitespace@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" + integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize/-/postcss-normalize-10.0.1.tgz#464692676b52792a06b06880a176279216540dd7" + integrity sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA== + dependencies: + "@csstools/normalize.css" "*" + postcss-browser-comments "^4" + sanitize.css "*" + +postcss-opacity-percentage@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz#5b89b35551a556e20c5d23eb5260fbfcf5245da6" + integrity sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A== + +postcss-ordered-values@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" + integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== + dependencies: + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-overflow-shorthand@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz#7ed6486fec44b76f0eab15aa4866cda5d55d893e" + integrity sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-page-break@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" + integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== + +postcss-place@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-7.0.5.tgz#95dbf85fd9656a3a6e60e832b5809914236986c4" + integrity sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-preset-env@^7.0.1: + version "7.8.3" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz#2a50f5e612c3149cc7af75634e202a5b2ad4f1e2" + integrity sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag== + dependencies: + "@csstools/postcss-cascade-layers" "^1.1.1" + "@csstools/postcss-color-function" "^1.1.1" + "@csstools/postcss-font-format-keywords" "^1.0.1" + "@csstools/postcss-hwb-function" "^1.0.2" + "@csstools/postcss-ic-unit" "^1.0.1" + "@csstools/postcss-is-pseudo-class" "^2.0.7" + "@csstools/postcss-nested-calc" "^1.0.0" + "@csstools/postcss-normalize-display-values" "^1.0.1" + "@csstools/postcss-oklab-function" "^1.1.1" + "@csstools/postcss-progressive-custom-properties" "^1.3.0" + "@csstools/postcss-stepped-value-functions" "^1.0.1" + "@csstools/postcss-text-decoration-shorthand" "^1.0.0" + "@csstools/postcss-trigonometric-functions" "^1.0.2" + "@csstools/postcss-unset-value" "^1.0.2" + autoprefixer "^10.4.13" + browserslist "^4.21.4" + css-blank-pseudo "^3.0.3" + css-has-pseudo "^3.0.4" + css-prefers-color-scheme "^6.0.3" + cssdb "^7.1.0" + postcss-attribute-case-insensitive "^5.0.2" + postcss-clamp "^4.1.0" + postcss-color-functional-notation "^4.2.4" + postcss-color-hex-alpha "^8.0.4" + postcss-color-rebeccapurple "^7.1.1" + postcss-custom-media "^8.0.2" + postcss-custom-properties "^12.1.10" + postcss-custom-selectors "^6.0.3" + postcss-dir-pseudo-class "^6.0.5" + postcss-double-position-gradients "^3.1.2" + postcss-env-function "^4.0.6" + postcss-focus-visible "^6.0.4" + postcss-focus-within "^5.0.4" + postcss-font-variant "^5.0.0" + postcss-gap-properties "^3.0.5" + postcss-image-set-function "^4.0.7" + postcss-initial "^4.0.1" + postcss-lab-function "^4.2.1" + postcss-logical "^5.0.4" + postcss-media-minmax "^5.0.0" + postcss-nesting "^10.2.0" + postcss-opacity-percentage "^1.1.2" + postcss-overflow-shorthand "^3.0.4" + postcss-page-break "^3.0.4" + postcss-place "^7.0.5" + postcss-pseudo-class-any-link "^7.1.6" + postcss-replace-overflow-wrap "^4.0.0" + postcss-selector-not "^6.0.1" + postcss-value-parser "^4.2.0" + +postcss-pseudo-class-any-link@^7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz#2693b221902da772c278def85a4d9a64b6e617ab" + integrity sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-reduce-initial@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6" + integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + +postcss-reduce-transforms@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" + integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-replace-overflow-wrap@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" + integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== + +postcss-selector-not@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz#8f0a709bf7d4b45222793fc34409be407537556d" + integrity sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: + version "6.0.13" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-svgo@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" + integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== + dependencies: + postcss-value-parser "^4.2.0" + svgo "^2.7.0" + +postcss-unique-selectors@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" + integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^7.0.35: + version "7.0.39" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + +postcss@^8.3.5, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.4: + version "8.4.32" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.32.tgz#1dac6ac51ab19adb21b8b34fd2d93a86440ef6c9" + integrity sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== + +prettier@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.1.0.tgz#c6d16474a5f764ea1a4a373c593b779697744d5e" + integrity sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw== + +pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== + +pretty-error@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" + integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== + dependencies: + lodash "^4.17.20" + renderkid "^3.0.0" + +pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + +pretty-format@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" + integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== + dependencies: + "@jest/schemas" "^28.1.3" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +promise@^8.1.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" + integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== + dependencies: + asap "~2.0.6" + +prompts@^2.0.1, prompts@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +property-expr@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8" + integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== + +protobufjs@^7.2.4: + version "7.2.5" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.5.tgz#45d5c57387a6d29a17aab6846dcc283f9b8e7f2d" + integrity sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +psl@^1.1.33: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +raf@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== + dependencies: + performance-now "^2.1.0" + +ramda@^0.29.1: + version "0.29.1" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.29.1.tgz#408a6165b9555b7ba2fc62555804b6c5a2eca196" + integrity sha512-OfxIeWzd4xdUNxlWhgFazxsA/nl3mS4/jGZI5n00uWOoSSFRhC1b6gl6xvmzUamgmqELraWp0J/qqVlXYPDPyA== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-app-polyfill@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz#95221e0a9bd259e5ca6b177c7bb1cb6768f68fd7" + integrity sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w== + dependencies: + core-js "^3.19.2" + object-assign "^4.1.1" + promise "^8.1.0" + raf "^3.4.1" + regenerator-runtime "^0.13.9" + whatwg-fetch "^3.6.2" + +react-calendar@^3.3.1: + version "3.9.0" + resolved "https://registry.yarnpkg.com/react-calendar/-/react-calendar-3.9.0.tgz#4dfe342ef61574c0e819e49847981076c7af58ea" + integrity sha512-g6RJCEaPovHTiV2bMhBUfm0a1YoMj4bOUpL8hQSLmR1Glhc7lgRLtZBd4mcC4jkoGsb+hv9uA/QH4pZcm5l9lQ== + dependencies: + "@wojtekmaj/date-utils" "^1.0.2" + get-user-locale "^1.2.0" + merge-class-names "^1.1.1" + prop-types "^15.6.0" + +react-clientside-effect@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz#29f9b14e944a376b03fb650eed2a754dd128ea3a" + integrity sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg== + dependencies: + "@babel/runtime" "^7.12.13" + +react-date-picker@^8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/react-date-picker/-/react-date-picker-8.4.0.tgz#2d166bbaa59b08ec8686f671fde553458d19f8c8" + integrity sha512-zocntugDUyiHmV2Nq1qnsk4kDQuhBLUsDTz7akfIEJ0jVX925w0K5Ai5oZzWFNQOzXL/ITxafmDMuSbzlpBt/A== + dependencies: + "@types/react-calendar" "^3.0.0" + "@wojtekmaj/date-utils" "^1.0.3" + get-user-locale "^1.2.0" + make-event-props "^1.1.0" + merge-class-names "^1.1.1" + merge-refs "^1.0.0" + prop-types "^15.6.0" + react-calendar "^3.3.1" + react-fit "^1.4.0" + update-input-width "^1.2.2" + +react-dev-utils@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz#ba92edb4a1f379bd46ccd6bcd4e7bc398df33e73" + integrity sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ== + dependencies: + "@babel/code-frame" "^7.16.0" + address "^1.1.2" + browserslist "^4.18.1" + chalk "^4.1.2" + cross-spawn "^7.0.3" + detect-port-alt "^1.1.6" + escape-string-regexp "^4.0.0" + filesize "^8.0.6" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^6.5.0" + global-modules "^2.0.0" + globby "^11.0.4" + gzip-size "^6.0.0" + immer "^9.0.7" + is-root "^2.1.0" + loader-utils "^3.2.0" + open "^8.4.0" + pkg-up "^3.1.0" + prompts "^2.4.2" + react-error-overlay "^6.0.11" + recursive-readdir "^2.2.2" + shell-quote "^1.7.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-error-overlay@^6.0.11: + version "6.0.11" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" + integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== + +react-fast-compare@3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== + +react-fit@^1.4.0: + version "1.7.1" + resolved "https://registry.yarnpkg.com/react-fit/-/react-fit-1.7.1.tgz#95259e90cfa9c4d243a8013d03ea59c9c5c51a6f" + integrity sha512-y/TYovCCBzfIwRJsbLj0rH4Es40wPQhU5GPPq9GlbdF09b0OdzTdMSkBza0QixSlgFzTm6dkM7oTFzaVvaBx+w== + dependencies: + detect-element-overflow "^1.4.0" + prop-types "^15.6.0" + tiny-warning "^1.0.0" + +react-focus-lock@^2.9.4: + version "2.9.6" + resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.6.tgz#cad168a150fdd72d5ab2419ba8e62780788011b1" + integrity sha512-B7gYnCjHNrNYwY2juS71dHbf0+UpXXojt02svxybj8N5bxceAkzPChKEncHuratjUHkIFNCn06k2qj1DRlzTug== + dependencies: + "@babel/runtime" "^7.0.0" + focus-lock "^1.0.0" + prop-types "^15.6.2" + react-clientside-effect "^1.2.6" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + +react-hook-form@^7.48.2: + version "7.48.2" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.48.2.tgz#01150354d2be61412ff56a030b62a119283b9935" + integrity sha512-H0T2InFQb1hX7qKtDIZmvpU1Xfn/bdahWBN1fH19gSe4bBEqTfmlr7H3XWTaVtiK4/tpPaI1F3355GPMZYge+A== + +react-icons@^4.12.0: + version "4.12.0" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.12.0.tgz#54806159a966961bfd5cdb26e492f4dafd6a8d78" + integrity sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw== + +react-is@^16.13.1, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +react-redux@^9.0.4: + version "9.0.4" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-9.0.4.tgz#6892d465f086507a517d4b53eb589876e6bc8344" + integrity sha512-9J1xh8sWO0vYq2sCxK2My/QO7MzUMRi3rpiILP/+tDr8krBHixC6JMM17fMK88+Oh3e4Ae6/sHIhNBgkUivwFA== + dependencies: + "@types/use-sync-external-store" "^0.0.3" + use-sync-external-store "^1.0.0" + +react-refresh@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" + integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== + +react-remove-scroll-bar@^2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9" + integrity sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A== + dependencies: + react-style-singleton "^2.2.1" + tslib "^2.0.0" + +react-remove-scroll@^2.5.6: + version "2.5.7" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz#15a1fd038e8497f65a695bf26a4a57970cac1ccb" + integrity sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA== + dependencies: + react-remove-scroll-bar "^2.3.4" + react-style-singleton "^2.2.1" + tslib "^2.1.0" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + +react-router-dom@^6.20.0: + version "6.20.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.20.1.tgz#e34f8075b9304221420de3609e072bb349824984" + integrity sha512-npzfPWcxfQN35psS7rJgi/EW0Gx6EsNjfdJSAk73U/HqMEJZ2k/8puxfwHFgDQhBGmS3+sjnGbMdMSV45axPQw== + dependencies: + "@remix-run/router" "1.13.1" + react-router "6.20.1" + +react-router@6.20.1: + version "6.20.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.20.1.tgz#e8cc326031d235aaeec405bb234af77cf0fe75ef" + integrity sha512-ccvLrB4QeT5DlaxSFFYi/KR8UMQ4fcD8zBcR71Zp1kaYTC5oJKYAp1cbavzGrogwxca+ubjkd7XjFZKBW8CxPA== + dependencies: + "@remix-run/router" "1.13.1" + +react-scripts@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-5.0.1.tgz#6285dbd65a8ba6e49ca8d651ce30645a6d980003" + integrity sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ== + dependencies: + "@babel/core" "^7.16.0" + "@pmmmwh/react-refresh-webpack-plugin" "^0.5.3" + "@svgr/webpack" "^5.5.0" + babel-jest "^27.4.2" + babel-loader "^8.2.3" + babel-plugin-named-asset-import "^0.3.8" + babel-preset-react-app "^10.0.1" + bfj "^7.0.2" + browserslist "^4.18.1" + camelcase "^6.2.1" + case-sensitive-paths-webpack-plugin "^2.4.0" + css-loader "^6.5.1" + css-minimizer-webpack-plugin "^3.2.0" + dotenv "^10.0.0" + dotenv-expand "^5.1.0" + eslint "^8.3.0" + eslint-config-react-app "^7.0.1" + eslint-webpack-plugin "^3.1.1" + file-loader "^6.2.0" + fs-extra "^10.0.0" + html-webpack-plugin "^5.5.0" + identity-obj-proxy "^3.0.0" + jest "^27.4.3" + jest-resolve "^27.4.2" + jest-watch-typeahead "^1.0.0" + mini-css-extract-plugin "^2.4.5" + postcss "^8.4.4" + postcss-flexbugs-fixes "^5.0.2" + postcss-loader "^6.2.1" + postcss-normalize "^10.0.1" + postcss-preset-env "^7.0.1" + prompts "^2.4.2" + react-app-polyfill "^3.0.0" + react-dev-utils "^12.0.1" + react-refresh "^0.11.0" + resolve "^1.20.0" + resolve-url-loader "^4.0.0" + sass-loader "^12.3.0" + semver "^7.3.5" + source-map-loader "^3.0.0" + style-loader "^3.3.1" + tailwindcss "^3.0.2" + terser-webpack-plugin "^5.2.5" + webpack "^5.64.4" + webpack-dev-server "^4.6.0" + webpack-manifest-plugin "^4.0.2" + workbox-webpack-plugin "^6.4.1" + optionalDependencies: + fsevents "^2.3.2" + +react-style-singleton@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" + integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== + dependencies: + get-nonce "^1.0.0" + invariant "^2.2.4" + tslib "^2.0.0" + +react-table@^7.8.0: + version "7.8.0" + resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.8.0.tgz#07858c01c1718c09f7f1aed7034fcfd7bda907d2" + integrity sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA== + +react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + +readable-stream@^2.0.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +recursive-readdir@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" + integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== + dependencies: + minimatch "^3.0.5" + +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + +redux-persist@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8" + integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ== + +redux-thunk@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-3.1.0.tgz#94aa6e04977c30e14e892eae84978c1af6058ff3" + integrity sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw== + +redux@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-5.0.0.tgz#29572e29a439e094ff8fec46883fc45053f6736d" + integrity sha512-blLIYmYetpZMET6Q6uCY7Jtl/Im5OBldy+vNPauA8vvsdqyt66oep4EUpAMWNHauTC6xa9JuRPhRB72rY82QGA== + +reflect.getprototypeof@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" + integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + which-builtin-type "^1.1.3" + +regenerate-unicode-properties@^10.1.0: + version "10.1.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" + integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.13.9: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + +regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" + integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + set-function-name "^2.0.0" + +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== + dependencies: + "@babel/regjsgen" "^0.8.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== + +render-and-add-props@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/render-and-add-props/-/render-and-add-props-0.5.0.tgz#79e35b2251936ec187188322826e56401c2ef70b" + integrity sha512-jIVQsWxGDHwpMcI0d9w6OxF/GCtwL02Lyqk8aGjyF6LyR9GPLY+1ONwPjs6kbQ2d6gTApWk8aprZkBli0tpG/w== + +renderkid@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" + integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^6.0.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +reselect@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-5.0.1.tgz#587cdaaeb4e0e8927cff80ebe2bbef05f74b1648" + integrity sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz#d50d4ddc746bb10468443167acf800dcd6c3ad57" + integrity sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA== + dependencies: + adjust-sourcemap-loader "^4.0.0" + convert-source-map "^1.7.0" + loader-utils "^2.0.0" + postcss "^7.0.35" + source-map "0.6.1" + +resolve.exports@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" + integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== + +resolve@^1.1.7, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.2, resolve@^1.22.4: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^2.0.0-next.4: + version "2.0.0-next.5" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rollup-plugin-terser@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" + integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== + dependencies: + "@babel/code-frame" "^7.10.4" + jest-worker "^26.2.1" + serialize-javascript "^4.0.0" + terser "^5.0.0" + +rollup@^2.43.1: + version "2.79.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== + optionalDependencies: + fsevents "~2.3.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-array-concat@^1.0.0, safe-array-concat@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" + integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + isarray "^2.0.5" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sanitize.css@*: + version "13.0.0" + resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-13.0.0.tgz#2675553974b27964c75562ade3bd85d79879f173" + integrity sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA== + +sass-loader@^12.3.0: + version "12.6.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.6.0.tgz#5148362c8e2cdd4b950f3c63ac5d16dbfed37bcb" + integrity sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA== + dependencies: + klona "^2.0.4" + neo-async "^2.6.2" + +sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + +schema-utils@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + +schema-utils@^2.6.5: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" + integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.1.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== + dependencies: + "@types/node-forge" "^1.3.0" + node-forge "^1" + +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +set-function-name@^2.0.0, set-function-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" + integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== + dependencies: + define-data-property "^1.0.1" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.0" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@^1.7.3, shell-quote@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-list-map@^2.0.0, source-list-map@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-js@^1.0.1, source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-loader@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.2.tgz#af23192f9b344daa729f6772933194cc5fa54fee" + integrity sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg== + dependencies: + abab "^2.0.5" + iconv-lite "^0.6.3" + source-map-js "^1.0.1" + +source-map-support@^0.5.6, source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +source-map@^0.7.3: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + +source-map@^0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + +stackframe@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" + integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== + +static-eval@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-2.0.2.tgz#2d1759306b1befa688938454c546b7871f806a42" + integrity sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg== + dependencies: + escodegen "^1.8.1" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-length@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-5.0.1.tgz#3d647f497b6e8e8d41e422f7e0b23bc536c8381e" + integrity sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow== + dependencies: + char-regex "^2.0.0" + strip-ansi "^7.0.1" + +string-natural-compare@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" + integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz#a1553eb532221d4180c51581d6072cd65d1ee100" + integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + regexp.prototype.flags "^1.5.0" + set-function-name "^2.0.0" + side-channel "^1.0.4" + +string.prototype.trim@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" + integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string.prototype.trimend@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" + integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string.prototype.trimstart@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" + integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" + integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@^3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.3.tgz#bba8daac19930169c0c9c96706749a597ae3acff" + integrity sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw== + +stylehacks@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9" + integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw== + dependencies: + browserslist "^4.21.4" + postcss-selector-parser "^6.0.4" + +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== + +sucrase@^3.32.0: + version "3.34.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.34.0.tgz#1e0e2d8fcf07f8b9c3569067d92fbd8690fb576f" + integrity sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "7.1.6" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" + integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svg-parser@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + +svgo@^1.2.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + +svgo@^2.7.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + picocolors "^1.0.0" + stable "^0.1.8" + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +tailwindcss@^3.0.2: + version "3.3.6" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.6.tgz#4dd7986bf4902ad385d90d45fd4b2fa5fab26d5f" + integrity sha512-AKjF7qbbLvLaPieoKeTjG1+FyNZT6KaJMJPFeQyLfIp7l82ggH1fbHJSsYIvnbTFQOlkh+gBYpyby5GT1LIdLw== + dependencies: + "@alloc/quick-lru" "^5.2.0" + arg "^5.0.2" + chokidar "^3.5.3" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.3.0" + glob-parent "^6.0.2" + is-glob "^4.0.3" + jiti "^1.19.1" + lilconfig "^2.1.0" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-hash "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" + resolve "^1.22.2" + sucrase "^3.32.0" + +tapable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +temp-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" + integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== + +tempy@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.6.0.tgz#65e2c35abc06f1124a97f387b08303442bde59f3" + integrity sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw== + dependencies: + is-stream "^2.0.0" + temp-dir "^2.0.0" + type-fest "^0.16.0" + unique-string "^2.0.0" + +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +terser-webpack-plugin@^5.2.5, terser-webpack-plugin@^5.3.7: + version "5.3.9" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" + integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.17" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.16.8" + +terser@^5.0.0, terser@^5.10.0, terser@^5.16.8: + version "5.26.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.26.0.tgz#ee9f05d929f4189a9c28a0feb889d96d50126fe1" + integrity sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + +throat@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" + integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +tiny-case@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03" + integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q== + +tiny-invariant@^1.0.6: + version "1.3.1" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" + integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== + +tiny-warning@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== + +tough-cookie@^4.0.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== + dependencies: + punycode "^2.1.0" + +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== + dependencies: + punycode "^2.1.1" + +tryer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== + +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + +ts-toolbelt@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz#50a25426cfed500d4a09bd1b3afb6f28879edfd5" + integrity sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w== + +tsconfig-paths@^3.14.2: + version "3.14.2" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" + integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" + integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +types-ramda@^0.29.6: + version "0.29.6" + resolved "https://registry.yarnpkg.com/types-ramda/-/types-ramda-0.29.6.tgz#a1d2a3c15a48e27d35832d7194d93369975f1427" + integrity sha512-VJoOk1uYNh9ZguGd3eZvqkdhD4hTGtnjRBUx5Zc0U9ftmnCgiWcSj/lsahzKunbiwRje1MxxNkEy1UdcXRCpYw== + dependencies: + ts-toolbelt "^9.6.0" + +typescript@^4.9.5: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + +underscore@1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.1.tgz#7bb8cc9b3d397e201cf8553336d262544ead829e" + integrity sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +undici@5.26.5: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.26.5.tgz#f6dc8c565e3cad8c4475b187f51a13e505092838" + integrity sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw== + dependencies: + "@fastify/busboy" "^2.0.0" + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== + +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg== + +upath@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +update-input-width@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/update-input-width/-/update-input-width-1.4.2.tgz#49d327a39395185b0fd440b9c3b1d6f81173655c" + integrity sha512-/p0XLhrQQQ4bMWD7bL9duYObwYCO1qGr8R19xcMmoMSmXuQ7/1//veUnCObQ7/iW6E2pGS6rFkS4TfH4ur7e/g== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +use-callback-ref@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.0.tgz#772199899b9c9a50526fedc4993fc7fa1f7e32d5" + integrity sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w== + dependencies: + tslib "^2.0.0" + +use-sidecar@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" + integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== + dependencies: + detect-node-es "^1.1.0" + tslib "^2.0.0" + +use-sync-external-store@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +v8-to-istanbul@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" + integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" + +walker@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +web-vitals@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-2.1.4.tgz#76563175a475a5e835264d373704f9dde718290c" + integrity sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg== + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@^4.6.0: + version "4.15.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz#8944b29c12760b3a45bdaa70799b17cb91b03df7" + integrity sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.5" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + launch-editor "^2.6.0" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.1.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.13.0" + +webpack-manifest-plugin@^4.0.2: + version "4.1.1" + resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz#10f8dbf4714ff93a215d5a45bcc416d80506f94f" + integrity sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow== + dependencies: + tapable "^2.0.0" + webpack-sources "^2.2.0" + +webpack-sources@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-sources@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd" + integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA== + dependencies: + source-list-map "^2.0.1" + source-map "^0.6.1" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@^5.64.4: + version "5.89.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.89.0.tgz#56b8bf9a34356e93a6625770006490bf3a7f32dc" + integrity sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" + acorn "^8.7.1" + acorn-import-assertions "^1.9.0" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.15.0" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.2.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.7" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-fetch@^3.6.2: + version "3.6.19" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz#caefd92ae630b91c07345537e67f8354db470973" + integrity sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw== + +whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== + dependencies: + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-builtin-type@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz#b1b8443707cc58b6e9bf98d32110ff0c2cbd029b" + integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== + dependencies: + function.prototype.name "^1.1.5" + has-tostringtag "^1.0.0" + is-async-function "^2.0.0" + is-date-object "^1.0.5" + is-finalizationregistry "^1.0.2" + is-generator-function "^1.0.10" + is-regex "^1.1.4" + is-weakref "^1.0.2" + isarray "^2.0.5" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + +which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.4" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@~1.2.3: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + +workbox-background-sync@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.6.1.tgz#08d603a33717ce663e718c30cc336f74909aff2f" + integrity sha512-trJd3ovpWCvzu4sW0E8rV3FUyIcC0W8G+AZ+VcqzzA890AsWZlUGOTSxIMmIHVusUw/FDq1HFWfy/kC/WTRqSg== + dependencies: + idb "^7.0.1" + workbox-core "6.6.1" + +workbox-broadcast-update@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-6.6.1.tgz#0fad9454cf8e4ace0c293e5617c64c75d8a8c61e" + integrity sha512-fBhffRdaANdeQ1V8s692R9l/gzvjjRtydBOvR6WCSB0BNE2BacA29Z4r9/RHd9KaXCPl6JTdI9q0bR25YKP8TQ== + dependencies: + workbox-core "6.6.1" + +workbox-build@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-6.6.1.tgz#6010e9ce550910156761448f2dbea8cfcf759cb0" + integrity sha512-INPgDx6aRycAugUixbKgiEQBWD0MPZqU5r0jyr24CehvNuLPSXp/wGOpdRJmts656lNiXwqV7dC2nzyrzWEDnw== + dependencies: + "@apideck/better-ajv-errors" "^0.3.1" + "@babel/core" "^7.11.1" + "@babel/preset-env" "^7.11.0" + "@babel/runtime" "^7.11.2" + "@rollup/plugin-babel" "^5.2.0" + "@rollup/plugin-node-resolve" "^11.2.1" + "@rollup/plugin-replace" "^2.4.1" + "@surma/rollup-plugin-off-main-thread" "^2.2.3" + ajv "^8.6.0" + common-tags "^1.8.0" + fast-json-stable-stringify "^2.1.0" + fs-extra "^9.0.1" + glob "^7.1.6" + lodash "^4.17.20" + pretty-bytes "^5.3.0" + rollup "^2.43.1" + rollup-plugin-terser "^7.0.0" + source-map "^0.8.0-beta.0" + stringify-object "^3.3.0" + strip-comments "^2.0.1" + tempy "^0.6.0" + upath "^1.2.0" + workbox-background-sync "6.6.1" + workbox-broadcast-update "6.6.1" + workbox-cacheable-response "6.6.1" + workbox-core "6.6.1" + workbox-expiration "6.6.1" + workbox-google-analytics "6.6.1" + workbox-navigation-preload "6.6.1" + workbox-precaching "6.6.1" + workbox-range-requests "6.6.1" + workbox-recipes "6.6.1" + workbox-routing "6.6.1" + workbox-strategies "6.6.1" + workbox-streams "6.6.1" + workbox-sw "6.6.1" + workbox-window "6.6.1" + +workbox-cacheable-response@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-6.6.1.tgz#284c2b86be3f4fd191970ace8c8e99797bcf58e9" + integrity sha512-85LY4veT2CnTCDxaVG7ft3NKaFbH6i4urZXgLiU4AiwvKqS2ChL6/eILiGRYXfZ6gAwDnh5RkuDbr/GMS4KSag== + dependencies: + workbox-core "6.6.1" + +workbox-core@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-6.6.1.tgz#7184776d4134c5ed2f086878c882728fc9084265" + integrity sha512-ZrGBXjjaJLqzVothoE12qTbVnOAjFrHDXpZe7coCb6q65qI/59rDLwuFMO4PcZ7jcbxY+0+NhUVztzR/CbjEFw== + +workbox-expiration@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-6.6.1.tgz#a841fa36676104426dbfb9da1ef6a630b4f93739" + integrity sha512-qFiNeeINndiOxaCrd2DeL1Xh1RFug3JonzjxUHc5WkvkD2u5abY3gZL1xSUNt3vZKsFFGGORItSjVTVnWAZO4A== + dependencies: + idb "^7.0.1" + workbox-core "6.6.1" + +workbox-google-analytics@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-6.6.1.tgz#a07a6655ab33d89d1b0b0a935ffa5dea88618c5d" + integrity sha512-1TjSvbFSLmkpqLcBsF7FuGqqeDsf+uAXO/pjiINQKg3b1GN0nBngnxLcXDYo1n/XxK4N7RaRrpRlkwjY/3ocuA== + dependencies: + workbox-background-sync "6.6.1" + workbox-core "6.6.1" + workbox-routing "6.6.1" + workbox-strategies "6.6.1" + +workbox-navigation-preload@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-6.6.1.tgz#61a34fe125558dd88cf09237f11bd966504ea059" + integrity sha512-DQCZowCecO+wRoIxJI2V6bXWK6/53ff+hEXLGlQL4Rp9ZaPDLrgV/32nxwWIP7QpWDkVEtllTAK5h6cnhxNxDA== + dependencies: + workbox-core "6.6.1" + +workbox-precaching@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-6.6.1.tgz#dedeeba10a2d163d990bf99f1c2066ac0d1a19e2" + integrity sha512-K4znSJ7IKxCnCYEdhNkMr7X1kNh8cz+mFgx9v5jFdz1MfI84pq8C2zG+oAoeE5kFrUf7YkT5x4uLWBNg0DVZ5A== + dependencies: + workbox-core "6.6.1" + workbox-routing "6.6.1" + workbox-strategies "6.6.1" + +workbox-range-requests@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-6.6.1.tgz#ddaf7e73af11d362fbb2f136a9063a4c7f507a39" + integrity sha512-4BDzk28govqzg2ZpX0IFkthdRmCKgAKreontYRC5YsAPB2jDtPNxqx3WtTXgHw1NZalXpcH/E4LqUa9+2xbv1g== + dependencies: + workbox-core "6.6.1" + +workbox-recipes@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-6.6.1.tgz#ea70d2b2b0b0bce8de0a9d94f274d4a688e69fae" + integrity sha512-/oy8vCSzromXokDA+X+VgpeZJvtuf8SkQ8KL0xmRivMgJZrjwM3c2tpKTJn6PZA6TsbxGs3Sc7KwMoZVamcV2g== + dependencies: + workbox-cacheable-response "6.6.1" + workbox-core "6.6.1" + workbox-expiration "6.6.1" + workbox-precaching "6.6.1" + workbox-routing "6.6.1" + workbox-strategies "6.6.1" + +workbox-routing@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-6.6.1.tgz#cba9a1c7e0d1ea11e24b6f8c518840efdc94f581" + integrity sha512-j4ohlQvfpVdoR8vDYxTY9rA9VvxTHogkIDwGdJ+rb2VRZQ5vt1CWwUUZBeD/WGFAni12jD1HlMXvJ8JS7aBWTg== + dependencies: + workbox-core "6.6.1" + +workbox-strategies@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-6.6.1.tgz#38d0f0fbdddba97bd92e0c6418d0b1a2ccd5b8bf" + integrity sha512-WQLXkRnsk4L81fVPkkgon1rZNxnpdO5LsO+ws7tYBC6QQQFJVI6v98klrJEjFtZwzw/mB/HT5yVp7CcX0O+mrw== + dependencies: + workbox-core "6.6.1" + +workbox-streams@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-6.6.1.tgz#b2f7ba7b315c27a6e3a96a476593f99c5d227d26" + integrity sha512-maKG65FUq9e4BLotSKWSTzeF0sgctQdYyTMq529piEN24Dlu9b6WhrAfRpHdCncRS89Zi2QVpW5V33NX8PgH3Q== + dependencies: + workbox-core "6.6.1" + workbox-routing "6.6.1" + +workbox-sw@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-6.6.1.tgz#d4c4ca3125088e8b9fd7a748ed537fa0247bd72c" + integrity sha512-R7whwjvU2abHH/lR6kQTTXLHDFU2izht9kJOvBRYK65FbwutT4VvnUAJIgHvfWZ/fokrOPhfoWYoPCMpSgUKHQ== + +workbox-webpack-plugin@^6.4.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.1.tgz#4f81cc1ad4e5d2cd7477a86ba83c84ee2d187531" + integrity sha512-zpZ+ExFj9NmiI66cFEApyjk7hGsfJ1YMOaLXGXBoZf0v7Iu6hL0ZBe+83mnDq3YYWAfA3fnyFejritjOHkFcrA== + dependencies: + fast-json-stable-stringify "^2.1.0" + pretty-bytes "^5.4.1" + upath "^1.2.0" + webpack-sources "^1.4.3" + workbox-build "6.6.1" + +workbox-window@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-6.6.1.tgz#f22a394cbac36240d0dadcbdebc35f711bb7b89e" + integrity sha512-wil4nwOY58nTdCvif/KEZjQ2NP8uk3gGeRNy2jPBbzypU4BT4D9L8xiwbmDBpZlSgJd2xsT9FvSNU0gsxV51JQ== + dependencies: + "@types/trusted-types" "^2.0.2" + workbox-core "6.6.1" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^7.4.6: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + +ws@^8.13.0: + version "8.14.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" + integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yaml@^2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" + integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yup@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/yup/-/yup-1.3.3.tgz#d2f6020ad1679754c5f8178a29243d5447dead04" + integrity sha512-v8QwZSsHH2K3/G9WSkp6mZKO+hugKT1EmnMqLNUcfu51HU9MDyhlETT/JgtzprnrnQHPWsjc6MUDMBp/l9fNnw== + dependencies: + property-expr "^2.0.5" + tiny-case "^1.0.3" + toposort "^2.0.2" + type-fest "^2.19.0" From d9e7052800ae7e28fae427d7456aae94f97e8470 Mon Sep 17 00:00:00 2001 From: Anh Date: Thu, 25 Jan 2024 09:28:39 +0700 Subject: [PATCH 14/17] feat: add screen to manage uploaded files (#837) * Add screen to manage uploaded files * Add class ResultFileName * Fix UI not updated * Add unit test * Refactor formatDateTime() to extension method toUIString() * Refactor formatDuration() to extension method toDurationUIString() * Rename time_utils.dart to formatter.dart * Update expected_throughput --- .../integration_test/expected_throughput.dart | 17 +- flutter/lib/data/result_file_name.dart | 26 +++ flutter/lib/firebase/firebase_manager.dart | 40 +++-- .../firebase/firebase_storage_service.dart | 1 + flutter/lib/l10n/app_en.arb | 2 + flutter/lib/resources/result_manager.dart | 10 +- flutter/lib/ui/formatter.dart | 27 +++ .../benchmark_export_result_screen.dart | 10 +- .../ui/history/extended_result_screen.dart | 160 ++++++++++++++---- flutter/lib/ui/history/history_list_item.dart | 6 +- .../lib/ui/home/benchmark_result_screen.dart | 4 +- .../lib/ui/home/benchmark_running_screen.dart | 6 +- .../lib/ui/home/uploaded_files_screen.dart | 86 ++++++++++ flutter/lib/ui/home/user_profile.dart | 30 +++- flutter/lib/ui/time_utils.dart | 23 --- .../unit_test/data/result_file_name_test.dart | 29 ++++ 16 files changed, 377 insertions(+), 100 deletions(-) create mode 100644 flutter/lib/data/result_file_name.dart create mode 100644 flutter/lib/ui/formatter.dart create mode 100644 flutter/lib/ui/home/uploaded_files_screen.dart delete mode 100644 flutter/lib/ui/time_utils.dart create mode 100644 flutter/unit_test/data/result_file_name_test.dart diff --git a/flutter/integration_test/expected_throughput.dart b/flutter/integration_test/expected_throughput.dart index af87142f1..a30e1bd58 100644 --- a/flutter/integration_test/expected_throughput.dart +++ b/flutter/integration_test/expected_throughput.dart @@ -48,28 +48,28 @@ const Map> _objectDetection = { _kCloudBuildX28: Interval(min: 3.5, max: 8), _kRyzen5600: Interval(min: 14, max: 22), _kPixel5: Interval(min: 40, max: 60), - _kIphoneOnGitHubAction: Interval(min: 1.5, max: 4), + _kIphoneOnGitHubAction: Interval(min: 0.8, max: 4), _kIphoneOnMacbookM1: Interval(min: 9, max: 16), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 1.0, max: 4), + _kIphoneOnGitHubAction: Interval(min: 0.8, max: 4), }, _kPixelBackend: { _kPixel6: Interval(min: 300, max: 490), }, }; -const Map> _imageSegmentation = { +const Map> _imageSegmentationV2 = { _kTFLiteBackend: { _kCloudBuildX23: Interval(min: 0.5, max: 3), _kCloudBuildX28: Interval(min: 0.5, max: 4), _kRyzen5600: Interval(min: 5, max: 7), _kPixel5: Interval(min: 25, max: 40), - _kIphoneOnGitHubAction: Interval(min: 0.4, max: 2.5), + _kIphoneOnGitHubAction: Interval(min: 0.3, max: 2.5), _kIphoneOnMacbookM1: Interval(min: 3, max: 6), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 0.4, max: 2.5), + _kIphoneOnGitHubAction: Interval(min: 0.3, max: 2.5), }, _kPixelBackend: { _kPixel6: Interval(min: 100, max: 180), @@ -111,18 +111,17 @@ const Map> _imageClassificationOffline = { }, }; -// TODO (anhappdev): update min throughput for _superResolution after we gather some statistic const Map> _superResolution = { _kTFLiteBackend: { _kCloudBuildX23: Interval(min: 0.1, max: 3), _kCloudBuildX28: Interval(min: 0.1, max: 4), _kRyzen5600: Interval(min: 0.1, max: 3), _kPixel5: Interval(min: 4, max: 8), - _kIphoneOnGitHubAction: Interval(min: 0.1, max: 3), + _kIphoneOnGitHubAction: Interval(min: 0.08, max: 1.0), _kIphoneOnMacbookM1: Interval(min: 0.1, max: 10), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 0.1, max: 3), + _kIphoneOnGitHubAction: Interval(min: 0.08, max: 1.0), }, _kPixelBackend: { _kPixel6: Interval(min: 10, max: 14), @@ -132,7 +131,7 @@ const Map> _superResolution = { const benchmarkExpectedThroughput = { BenchmarkId.imageClassification: _imageClassification, BenchmarkId.objectDetection: _objectDetection, - BenchmarkId.imageSegmentationV2: _imageSegmentation, + BenchmarkId.imageSegmentationV2: _imageSegmentationV2, BenchmarkId.naturalLanguageProcessing: _naturalLanguageProcessing, BenchmarkId.superResolution: _superResolution, BenchmarkId.imageClassificationOffline: _imageClassificationOffline, diff --git a/flutter/lib/data/result_file_name.dart b/flutter/lib/data/result_file_name.dart new file mode 100644 index 000000000..e5904eabc --- /dev/null +++ b/flutter/lib/data/result_file_name.dart @@ -0,0 +1,26 @@ +import 'package:intl/intl.dart'; + +class ResultFileName { + // Filename Format: _.json + // Example fileName: 2023-06-06T13-38-01_125ef847-ca9a-45e0-bf36-8fd22f493b8d.json + late String fileName; + late String uuid; + late DateTime dateTime; + + ResultFileName(this.uuid, this.dateTime) { + // Custom date format for valid file name (avoid colon and space) + final DateFormat formatter = DateFormat('yyyy-MM-ddTHH-mm-ss'); + final String datetimeString = formatter.format(dateTime); + fileName = '${datetimeString}_$uuid.json'; + } + + ResultFileName.fromFileName(this.fileName) { + var fileNameComponents = fileName.split('_'); + uuid = fileNameComponents.last.replaceAll('.json', ''); + final dateTimeString = fileNameComponents.first; + final dateTimeStringComponents = dateTimeString.split('T'); + final dateString = dateTimeStringComponents.first; + final timeString = dateTimeStringComponents.last.replaceAll('-', ':'); + dateTime = DateTime.parse('$dateString $timeString'); + } +} diff --git a/flutter/lib/firebase/firebase_manager.dart b/flutter/lib/firebase/firebase_manager.dart index e3edf8922..39398997d 100644 --- a/flutter/lib/firebase/firebase_manager.dart +++ b/flutter/lib/firebase/firebase_manager.dart @@ -4,9 +4,9 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:firebase_ui_auth/firebase_ui_auth.dart'; -import 'package:intl/intl.dart'; import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/result_file_name.dart'; import 'package:mlperfbench/firebase/firebase_auth_service.dart'; import 'package:mlperfbench/firebase/firebase_crashlytics_service.dart'; import 'package:mlperfbench/firebase/firebase_options.gen.dart'; @@ -81,13 +81,25 @@ extension Authentication on FirebaseManager { extension Storage on FirebaseManager { Future uploadResult(ExtendedResult result) async { - final DateFormat formatter = DateFormat('yyyy-MM-ddTHH-mm-ss'); - final String datetime = formatter.format(result.meta.creationDate); - // Example fileName: 2023-06-06T13-38-01_125ef847-ca9a-45e0-bf36-8fd22f493b8d.json - final fileName = '${datetime}_${result.meta.uuid}.json'; + final resultFile = + ResultFileName(result.meta.uuid, result.meta.creationDate); final jsonString = jsonToStringIndented(result); await _storageService.upload( - jsonString, _authService.currentUser.uid, fileName); + jsonString, _authService.currentUser.uid, resultFile.fileName); + } + + Future deleteResult(String fileName) async { + final uid = _authService.currentUser.uid; + await _storageService.delete(uid, fileName); + } + + Future downloadResult(String fileName) async { + print('Download online result [$fileName]'); + final uid = _authService.currentUser.uid; + final content = await _storageService.download(uid, fileName); + final json = jsonDecode(content) as Map; + final result = ExtendedResult.fromJson(json); + return result; } Future> downloadResults(List excluded) async { @@ -95,20 +107,22 @@ extension Storage on FirebaseManager { final fileNames = await _storageService.list(uid); List results = []; for (final fileName in fileNames) { - // Example fileName: 2023-06-06T13-38-01_125ef847-ca9a-45e0-bf36-8fd22f493b8d.json - final resultUuid = fileName.replaceAll('.json', '').split('_').last; - if (excluded.contains(resultUuid)) { + final resultFile = ResultFileName.fromFileName(fileName); + if (excluded.contains(resultFile.uuid)) { print('Exclude local existed result [$fileName] from download'); continue; } - print('Download online result [$fileName]'); - final content = await _storageService.download(uid, fileName); - final json = jsonDecode(content) as Map; - final result = ExtendedResult.fromJson(json); + final result = await downloadResult(fileName); results.add(result); } return results; } + + Future> listResults() async { + final uid = _authService.currentUser.uid; + final fileNames = await _storageService.list(uid); + return fileNames; + } } extension Crashlytics on FirebaseManager { diff --git a/flutter/lib/firebase/firebase_storage_service.dart b/flutter/lib/firebase/firebase_storage_service.dart index 5ff3716b1..eacb87a21 100644 --- a/flutter/lib/firebase/firebase_storage_service.dart +++ b/flutter/lib/firebase/firebase_storage_service.dart @@ -36,6 +36,7 @@ class FirebaseStorageService { Future delete(String uid, String fileName) async { final path = _getCloudStoragePath(uid, fileName); await firebaseStorage.ref(path).delete(); + print('Deleted: $path'); } Future> list(String uid) async { diff --git a/flutter/lib/l10n/app_en.arb b/flutter/lib/l10n/app_en.arb index 3624f60f0..2943471a9 100644 --- a/flutter/lib/l10n/app_en.arb +++ b/flutter/lib/l10n/app_en.arb @@ -17,6 +17,8 @@ "userProfile": "User Profile", "userId": "User ID", "userCreated": "Created", + "userManageUploadedResults": "Manage uploaded results", + "userUploadedFiles": "Uploaded Files", "unsupportedMainMessage": "This device is not yet supported.", "unsupportedBackendError": "Error message", diff --git a/flutter/lib/resources/result_manager.dart b/flutter/lib/resources/result_manager.dart index 0c7caa478..5b7919faa 100644 --- a/flutter/lib/resources/result_manager.dart +++ b/flutter/lib/resources/result_manager.dart @@ -1,10 +1,9 @@ import 'dart:convert'; import 'dart:io'; -import 'package:intl/intl.dart'; - import 'package:mlperfbench/benchmark/benchmark.dart'; import 'package:mlperfbench/data/extended_result.dart'; +import 'package:mlperfbench/data/result_file_name.dart'; import 'package:mlperfbench/data/result_filter.dart'; import 'package:mlperfbench/data/result_sort.dart'; import 'package:mlperfbench/data/results/benchmark_result.dart'; @@ -68,10 +67,9 @@ class ResultManager { Future saveResult(ExtendedResult result) async { localResults.add(result); - final DateFormat formatter = DateFormat('yyyy-MM-ddTHH-mm-ss'); - final String datetime = formatter.format(result.meta.creationDate); - final resultFile = - File('${_resultsDir.path}/${datetime}_${result.meta.uuid}.json'); + final resultFileName = + ResultFileName(result.meta.uuid, result.meta.creationDate); + final resultFile = File('${_resultsDir.path}/${resultFileName.fileName}'); await resultFile.writeAsString(jsonToStringIndented(result)); final submissionFile = File('${_resultsDir.path}/$_submissionFileName'); await submissionFile.writeAsString(jsonToStringIndented(result)); diff --git a/flutter/lib/ui/formatter.dart b/flutter/lib/ui/formatter.dart new file mode 100644 index 000000000..b18e7e6bb --- /dev/null +++ b/flutter/lib/ui/formatter.dart @@ -0,0 +1,27 @@ +import 'package:intl/intl.dart'; + +extension DurationFormat on double { + String toDurationUIString() { + var intSeconds = ceil(); + var minutes = intSeconds ~/ Duration.secondsPerMinute; + intSeconds -= minutes * Duration.secondsPerMinute; + final hours = minutes ~/ Duration.minutesPerHour; + minutes -= hours * Duration.minutesPerHour; + + final tokens = []; + if (hours != 0) { + tokens.add(hours.toString().padLeft(2, '0')); + } + tokens.add(minutes.toString().padLeft(2, '0')); + tokens.add(intSeconds.toString().padLeft(2, '0')); + + return tokens.join(':'); + } +} + +extension DateTimeFormat on DateTime { + String toUIString() { + var dateFormat = DateFormat('yyyy-MM-dd HH:mm:ss'); + return dateFormat.format(this); + } +} diff --git a/flutter/lib/ui/history/benchmark_export_result_screen.dart b/flutter/lib/ui/history/benchmark_export_result_screen.dart index e262434a9..92dc19b26 100644 --- a/flutter/lib/ui/history/benchmark_export_result_screen.dart +++ b/flutter/lib/ui/history/benchmark_export_result_screen.dart @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; import 'package:mlperfbench/data/results/benchmark_result.dart'; import 'package:mlperfbench/data/results/dataset_info.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/formatter.dart'; import 'package:mlperfbench/ui/history/utils.dart'; -import 'package:mlperfbench/ui/time_utils.dart'; class BenchmarkExportResultScreen extends StatefulWidget { final BenchmarkExportResult result; @@ -79,7 +79,7 @@ class _BenchmarkExportResultScreenState helper.makeInfo(l10n.historyRunDetailsValid, (perf.loadgenInfo?.validity ?? false).toString()), helper.makeInfo(l10n.historyRunDetailsDuration, - formatDuration(perf.measuredDuration)), + perf.measuredDuration.toDurationUIString()), helper.makeInfo( l10n.historyRunDetailsSamples, perf.measuredSamples.toString()), helper.makeInfo( @@ -92,10 +92,8 @@ class _BenchmarkExportResultScreenState return [ helper.makeInfo(l10n.historyRunDetailsAccuracy, accuracy.accuracy?.formatted ?? l10n.resultsNotAvailable), - helper.makeInfo( - l10n.historyRunDetailsDuration, - formatDuration(accuracy.measuredDuration), - ), + helper.makeInfo(l10n.historyRunDetailsDuration, + accuracy.measuredDuration.toDurationUIString()), helper.makeInfo( l10n.historyRunDetailsSamples, accuracy.measuredSamples.toString()), helper.makeInfo( diff --git a/flutter/lib/ui/history/extended_result_screen.dart b/flutter/lib/ui/history/extended_result_screen.dart index 255c1895b..bfae2e401 100644 --- a/flutter/lib/ui/history/extended_result_screen.dart +++ b/flutter/lib/ui/history/extended_result_screen.dart @@ -5,23 +5,94 @@ import 'package:provider/provider.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/data/extended_result.dart'; import 'package:mlperfbench/data/results/benchmark_result.dart'; +import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/ui/confirm_dialog.dart'; +import 'package:mlperfbench/ui/formatter.dart'; import 'package:mlperfbench/ui/history/benchmark_export_result_screen.dart'; import 'package:mlperfbench/ui/history/utils.dart'; -import 'package:mlperfbench/ui/time_utils.dart'; -class ExtendedResultScreen extends StatefulWidget { +class RemoteExtendedResultScreen extends StatefulWidget { + final String fileName; + + const RemoteExtendedResultScreen({Key? key, required this.fileName}) + : super(key: key); + + @override + State createState() => _RemoteExtendedResultScreenState(); +} + +class _RemoteExtendedResultScreenState + extends State { + late AppLocalizations l10n; + + Future downloadResult() => + FirebaseManager.instance.downloadResult(widget.fileName); + + @override + Widget build(BuildContext context) { + l10n = AppLocalizations.of(context); + return Scaffold( + appBar: AppBar( + title: Text(l10n.historyDetailsTitle), + actions: [_deleteButton()], + ), + body: FutureBuilder( + future: downloadResult(), + builder: (context, AsyncSnapshot snapshot) { + Widget child; + final result = snapshot.data; + if (snapshot.hasData && result != null) { + child = ExtendedResultView(result: result); + } else if (snapshot.hasError) { + child = Text('${snapshot.error}'); + } else { + child = const CircularProgressIndicator(); + } + return Container(color: Colors.white, child: Center(child: child)); + }, + ), + ); + } + + Widget _deleteButton() { + return IconButton( + icon: const Icon(Icons.delete), + tooltip: l10n.historyListSelectionDelete, + onPressed: () async { + final dialogResult = await showConfirmDialog( + context, + l10n.historyDetailsDeleteConfirm, + title: l10n.historyDetailsDelete, + ); + switch (dialogResult) { + case ConfirmDialogAction.ok: + await FirebaseManager.instance.deleteResult(widget.fileName); + if (context.mounted) { + Navigator.pop(context); + } + break; + case null: + case ConfirmDialogAction.cancel: + break; + } + }, + ); + } +} + +class LocalExtendedResultScreen extends StatefulWidget { final ExtendedResult result; - const ExtendedResultScreen({Key? key, required this.result}) + const LocalExtendedResultScreen({Key? key, required this.result}) : super(key: key); @override - State createState() => _ExtendedResultScreenState(); + State createState() => + _LocalExtendedResultScreenState(); } -class _ExtendedResultScreenState extends State { +class _LocalExtendedResultScreenState extends State { late AppLocalizations l10n; late HistoryHelperUtils helper; late BenchmarkState state; @@ -35,11 +106,59 @@ class _ExtendedResultScreenState extends State { return Scaffold( appBar: AppBar( title: Text(l10n.historyDetailsTitle), - actions: [_makeDeleteButton()], + actions: [_deleteButton()], ), - body: ListView(children: _makeBody()), + body: ExtendedResultView(result: widget.result), + ); + } + + Widget _deleteButton() { + return IconButton( + icon: const Icon(Icons.delete), + tooltip: l10n.historyListSelectionDelete, + onPressed: () async { + final dialogResult = await showConfirmDialog( + context, + l10n.historyDetailsDeleteConfirm, + title: l10n.historyDetailsDelete, + ); + switch (dialogResult) { + case ConfirmDialogAction.ok: + setState(() { + state.resourceManager.resultManager.deleteResult(widget.result); + Navigator.pop(context); + }); + break; + case null: + case ConfirmDialogAction.cancel: + break; + } + }, ); } +} + +class ExtendedResultView extends StatefulWidget { + final ExtendedResult result; + + const ExtendedResultView({Key? key, required this.result}) : super(key: key); + + @override + State createState() => _ExtendedResultViewState(); +} + +class _ExtendedResultViewState extends State { + late AppLocalizations l10n; + late HistoryHelperUtils helper; + late BenchmarkState state; + + @override + Widget build(BuildContext context) { + l10n = AppLocalizations.of(context); + helper = HistoryHelperUtils(l10n); + state = context.watch(); + return ListView(children: _makeBody()); + } double calculateAverageThroughput(List results) { var throughput = 0.0; @@ -58,7 +177,7 @@ class _ExtendedResultScreenState extends State { final res = widget.result; final firstResult = res.results.first; - final date = formatDateTime(res.meta.creationDate); + final date = res.meta.creationDate.toUIString(); final backendName = firstResult.backendInfo.backendName; final averageThroughput = @@ -133,29 +252,4 @@ class _ExtendedResultScreenState extends State { }, ); } - - Widget _makeDeleteButton() { - return IconButton( - icon: const Icon(Icons.delete), - tooltip: l10n.historyListSelectionDelete, - onPressed: () async { - final dialogResult = await showConfirmDialog( - context, - l10n.historyDetailsDeleteConfirm, - title: l10n.historyDetailsDelete, - ); - switch (dialogResult) { - case ConfirmDialogAction.ok: - setState(() { - state.resourceManager.resultManager.deleteResult(widget.result); - Navigator.pop(context); - }); - break; - case null: - case ConfirmDialogAction.cancel: - break; - } - }, - ); - } } diff --git a/flutter/lib/ui/history/history_list_item.dart b/flutter/lib/ui/history/history_list_item.dart index b34e81032..433d1f6ce 100644 --- a/flutter/lib/ui/history/history_list_item.dart +++ b/flutter/lib/ui/history/history_list_item.dart @@ -2,9 +2,9 @@ import 'package:flutter/material.dart'; import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/data/results/benchmark_result.dart'; +import 'package:mlperfbench/ui/formatter.dart'; import 'package:mlperfbench/ui/history/list_item.dart'; import 'package:mlperfbench/ui/icons.dart'; -import 'package:mlperfbench/ui/time_utils.dart'; class HistoryListItem implements ListItem { final BenchmarkExportResult item; @@ -86,9 +86,9 @@ class HistoryListItem implements ListItem { final prDateTime = item.performanceRun?.startDatetime; final arDateTime = item.accuracyRun?.startDatetime; if (prDateTime != null) { - return formatDateTime(prDateTime); + return prDateTime.toUIString(); } else if (arDateTime != null) { - return formatDateTime(arDateTime); + return arDateTime.toUIString(); } else { return 'unknown'; } diff --git a/flutter/lib/ui/home/benchmark_result_screen.dart b/flutter/lib/ui/home/benchmark_result_screen.dart index 216682f1c..e58037fc2 100644 --- a/flutter/lib/ui/home/benchmark_result_screen.dart +++ b/flutter/lib/ui/home/benchmark_result_screen.dart @@ -8,12 +8,12 @@ import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/device_info.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/ui/confirm_dialog.dart'; +import 'package:mlperfbench/ui/formatter.dart'; import 'package:mlperfbench/ui/home/app_drawer.dart'; import 'package:mlperfbench/ui/home/benchmark_info_button.dart'; import 'package:mlperfbench/ui/home/result_circle.dart'; import 'package:mlperfbench/ui/home/share_button.dart'; import 'package:mlperfbench/ui/home/shared_styles.dart'; -import 'package:mlperfbench/ui/time_utils.dart'; enum _ScreenMode { performance, accuracy } @@ -103,7 +103,7 @@ class _BenchmarkResultScreenState extends State Text benchmarkDateText; if (lastResult != null) { deviceInfoText = Text(lastResult.environmentInfo.modelDescription); - benchmarkDateText = Text(formatDateTime(lastResult.meta.creationDate)); + benchmarkDateText = Text(lastResult.meta.creationDate.toUIString()); } else { deviceInfoText = Text(DeviceInfo.instance.envInfo.modelDescription); benchmarkDateText = Text(l10n.na); diff --git a/flutter/lib/ui/home/benchmark_running_screen.dart b/flutter/lib/ui/home/benchmark_running_screen.dart index d63b0150b..8b2e9163c 100644 --- a/flutter/lib/ui/home/benchmark_running_screen.dart +++ b/flutter/lib/ui/home/benchmark_running_screen.dart @@ -12,9 +12,9 @@ import 'package:mlperfbench/benchmark/run_mode.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/state/task_runner.dart'; +import 'package:mlperfbench/ui/formatter.dart'; import 'package:mlperfbench/ui/home/progress_circles.dart'; import 'package:mlperfbench/ui/icons.dart'; -import 'package:mlperfbench/ui/time_utils.dart'; class BenchmarkRunningScreen extends StatefulWidget { static final GlobalKey scaffoldKey = @@ -371,8 +371,8 @@ class _StageProgressTextState extends State<_StageProgressText> { final progress = state.taskRunner.progressInfo; String progressStr; if (progress.cooldown) { - progressStr = formatDuration( - progress.cooldownDuration * (1.0 - progress.stageProgress)); + progressStr = (progress.cooldownDuration * (1.0 - progress.stageProgress)) + .toDurationUIString(); } else { progressStr = '${(progress.stageProgress * 100).round().clamp(0, 100)}%'; } diff --git a/flutter/lib/ui/home/uploaded_files_screen.dart b/flutter/lib/ui/home/uploaded_files_screen.dart new file mode 100644 index 000000000..12ba5074c --- /dev/null +++ b/flutter/lib/ui/home/uploaded_files_screen.dart @@ -0,0 +1,86 @@ +import 'package:flutter/material.dart'; + +import 'package:mlperfbench/data/result_file_name.dart'; +import 'package:mlperfbench/firebase/firebase_manager.dart'; +import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/formatter.dart'; +import 'package:mlperfbench/ui/history/extended_result_screen.dart'; + +class UploadedFilesScreen extends StatefulWidget { + const UploadedFilesScreen({Key? key}) : super(key: key); + + @override + State createState() => _UploadedFilesScreenState(); +} + +class _UploadedFilesScreenState extends State { + Future> fetchFileList() => + FirebaseManager.instance.listResults(); + + @override + Widget build(BuildContext context) { + final l10n = AppLocalizations.of(context); + return Scaffold( + appBar: AppBar( + title: Text(l10n.userUploadedFiles), + ), + body: FutureBuilder( + future: fetchFileList(), + builder: (context, AsyncSnapshot> snapshot) { + Widget child; + final fileList = snapshot.data; + if (snapshot.hasData && fileList != null) { + fileList.sort((b, a) => a.compareTo(b)); + child = ListView.separated( + itemCount: fileList.length, + shrinkWrap: false, + separatorBuilder: (_, __) => const Divider(), + itemBuilder: (context, index) { + final fileName = fileList[index]; + final resultFileName = ResultFileName.fromFileName(fileName); + return ListTile( + title: Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 4), + child: Text(resultFileName.dateTime.toUIString()), + ), + subtitle: Text(fileName), + onTap: () { + _viewFile(fileName); + }, + trailing: IconButton( + icon: const Icon(Icons.delete), + onPressed: () async { + await _deleteFile(fileName); + }, + ), + ); + }, + ); + } else if (snapshot.hasError) { + child = Text('${snapshot.error}'); + } else { + child = const CircularProgressIndicator(); + } + return Center(child: child); + }, + ), + ); + } + + Future _deleteFile(String fileName) async { + await FirebaseManager.instance.deleteResult(fileName); + setState(() { + fetchFileList(); + }); + } + + void _viewFile(String fileName) { + Navigator.push(context, MaterialPageRoute( + builder: (context) { + return RemoteExtendedResultScreen(fileName: fileName); + }, + )).then((value) => setState(() { + fetchFileList(); + })); + } +} diff --git a/flutter/lib/ui/home/user_profile.dart b/flutter/lib/ui/home/user_profile.dart index 102281213..a634946cb 100644 --- a/flutter/lib/ui/home/user_profile.dart +++ b/flutter/lib/ui/home/user_profile.dart @@ -7,7 +7,8 @@ import 'package:provider/provider.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; -import 'package:mlperfbench/ui/time_utils.dart'; +import 'package:mlperfbench/ui/formatter.dart'; +import 'package:mlperfbench/ui/home/uploaded_files_screen.dart'; class UserProfileSection extends StatefulWidget { const UserProfileSection({Key? key}) : super(key: key); @@ -157,6 +158,7 @@ class _UserProfileScreenState extends State { _buildUserInfoSection(), const SizedBox(height: 8), const Divider(), + _buildManageUploadedFileButton(), ], ), ); @@ -199,7 +201,7 @@ class _UserProfileScreenState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text(l10n.userCreated, style: titleTextStyle), - Text(formatDateTime(creationTime), style: subtitleTextStyle), + Text(creationTime.toUIString(), style: subtitleTextStyle), ], ); children.add(creationTimeRow); @@ -211,4 +213,28 @@ class _UserProfileScreenState extends State { children: children, ); } + + Widget _buildManageUploadedFileButton() { + return ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) { + return const UploadedFilesScreen(); + }, + ), + ); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Icon(Icons.cloud), + const SizedBox(width: 8), + Text(l10n.userManageUploadedResults), + ], + ), + ); + } } diff --git a/flutter/lib/ui/time_utils.dart b/flutter/lib/ui/time_utils.dart deleted file mode 100644 index ab178278d..000000000 --- a/flutter/lib/ui/time_utils.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:intl/intl.dart'; - -String formatDuration(double seconds) { - var intSeconds = seconds.ceil(); - var minutes = intSeconds ~/ Duration.secondsPerMinute; - intSeconds -= minutes * Duration.secondsPerMinute; - final hours = minutes ~/ Duration.minutesPerHour; - minutes -= hours * Duration.minutesPerHour; - - final tokens = []; - if (hours != 0) { - tokens.add(hours.toString().padLeft(2, '0')); - } - tokens.add(minutes.toString().padLeft(2, '0')); - tokens.add(intSeconds.toString().padLeft(2, '0')); - - return tokens.join(':'); -} - -String formatDateTime(DateTime value) { - var dateFormat = DateFormat('yyyy-MM-dd HH:mm:ss'); - return dateFormat.format(value); -} diff --git a/flutter/unit_test/data/result_file_name_test.dart b/flutter/unit_test/data/result_file_name_test.dart new file mode 100644 index 000000000..6a131e731 --- /dev/null +++ b/flutter/unit_test/data/result_file_name_test.dart @@ -0,0 +1,29 @@ +import 'package:flutter_test/flutter_test.dart'; + +import 'package:mlperfbench/data/result_file_name.dart'; + +void main() { + group('ResultFileName', () { + test('Init from file name', () { + const fileName = + '2023-06-06T13-38-01_125ef847-ca9a-45e0-bf36-8fd22f493b8d.json'; + const uuid = '125ef847-ca9a-45e0-bf36-8fd22f493b8d'; + final dateTime = DateTime.parse('2023-06-06T13:38:01'); + final resultFileName = ResultFileName.fromFileName(fileName); + expect(resultFileName.fileName, equals(fileName)); + expect(resultFileName.uuid, equals(uuid)); + expect(resultFileName.dateTime, equals(dateTime)); + }); + + test('Init from UUID and date time', () { + const fileName = + '2023-06-06T13-38-01_125ef847-ca9a-45e0-bf36-8fd22f493b8d.json'; + const uuid = '125ef847-ca9a-45e0-bf36-8fd22f493b8d'; + final dateTime = DateTime.parse('2023-06-06T13:38:01'); + final resultFileName = ResultFileName(uuid, dateTime); + expect(resultFileName.fileName, equals(fileName)); + expect(resultFileName.uuid, equals(uuid)); + expect(resultFileName.dateTime, equals(dateTime)); + }); + }); +} From 12867cda00b5f6e5d530c02dd97e814544be1102 Mon Sep 17 00:00:00 2001 From: Anh Date: Tue, 30 Jan 2024 13:35:33 +0700 Subject: [PATCH 15/17] ci: add new test devices for QTI and MTK backend (#842) * Update workflow to build and test APKs via Firebase Test Lab * Add expected accuracy and throughput for QTI * Add expected accuracy and throughput for Mediatek * Add expected throughput for Pixel * Remove cloud build workflow for Android * Update expected_throughput * Updated expected_throughput for _kIphoneOnGitHubAction * Retry failed steps in iOS test * Rename iOS workflow --- .github/cloudbuild/android-build.yaml | 206 ------------- .github/cloudbuild/android-test.yaml | 34 --- .github/workflows/android-build-test.yml | 284 ++++++++++++++++++ .github/workflows/app-build.yml | 148 --------- .../{ios-tests.yml => ios-build-test.yml} | 14 +- .../integration_test/expected_accuracy.dart | 31 +- .../integration_test/expected_throughput.dart | 96 ++++-- 7 files changed, 386 insertions(+), 427 deletions(-) delete mode 100644 .github/cloudbuild/android-build.yaml delete mode 100644 .github/cloudbuild/android-test.yaml create mode 100644 .github/workflows/android-build-test.yml delete mode 100644 .github/workflows/app-build.yml rename .github/workflows/{ios-tests.yml => ios-build-test.yml} (89%) diff --git a/.github/cloudbuild/android-build.yaml b/.github/cloudbuild/android-build.yaml deleted file mode 100644 index d42e89be8..000000000 --- a/.github/cloudbuild/android-build.yaml +++ /dev/null @@ -1,206 +0,0 @@ -substitutions: - _BUILDER_IMAGE_NAME: mlperf-mobile-flutter-android - _APK_DIR: /workspace/output/artifacts - # allow to override trigger names - _TFLITE_TEST_TRIGGER: android-test-tflite - _PIXEL_TEST_TRIGGER: android-test-pixel - -# Building apks with flutter requires a lot of memory. -# Builds on standard machines with 4GB of RAM can unexpectedly hang. -# Also the build is mostly CPU-intensive, so using 8-core machines -# reduces build time up to 3 times. -options: - machineType: "E2_HIGHCPU_8" - -steps: - - id: set-up-repo - name: gcr.io/cloud-builders/git - timeout: 10s - entrypoint: bash - args: - - -xc - - | - # non-master branches may contain large file that would slow down fetching - git config remote.origin.fetch "+refs/heads/master:refs/remotes/origin/master" || exit 1 - - # we need full commit history for docker builder image tag - git fetch --unshallow || exit 1 - - # next line is a fix for this issue https://github.com/actions/checkout/issues/766 - git config --global --add safe.directory '/image-workdir/flutter' - - id: cache-old-image - name: gcr.io/cloud-builders/docker - timeout: 300s # 5 minutes - entrypoint: bash - args: - - -xc - - | - # if :DOCKERFILE_COMMIT tag already exists we can skip the image build stage - # else we can try to reuse the :latest image to skip the build partially - DOCKERFILE_COMMIT=$$(git log -n 1 --pretty=format:%H -- flutter/android/docker/Dockerfile) - docker pull gcr.io/$PROJECT_ID/$_BUILDER_IMAGE_NAME:$$DOCKERFILE_COMMIT \ - || docker pull gcr.io/$PROJECT_ID/$_BUILDER_IMAGE_NAME:latest \ - || true - - id: build-new-image - name: gcr.io/cloud-builders/docker - timeout: 1800s # 30 minutes - entrypoint: bash - args: - - -xc - - | - DOCKERFILE_COMMIT=$$(git log -n 1 --pretty=format:%H -- flutter/android/docker/Dockerfile) - docker build \ - -t gcr.io/$PROJECT_ID/$_BUILDER_IMAGE_NAME:$$DOCKERFILE_COMMIT \ - -t gcr.io/$PROJECT_ID/$_BUILDER_IMAGE_NAME:latest \ - --cache-from gcr.io/$PROJECT_ID/$_BUILDER_IMAGE_NAME:$$DOCKERFILE_COMMIT \ - --cache-from gcr.io/$PROJECT_ID/$_BUILDER_IMAGE_NAME:latest \ - flutter/android/docker - # If the build step fails artifacts won't be uploaded, so we push image manually before build - - id: push-new-image - name: gcr.io/cloud-builders/docker - timeout: 600s # 10 minutes - entrypoint: bash - args: - - -xc - - | - DOCKERFILE_COMMIT=$$(git log -n 1 --pretty=format:%H -- flutter/android/docker/Dockerfile) - docker push gcr.io/$PROJECT_ID/$_BUILDER_IMAGE_NAME:$$DOCKERFILE_COMMIT - docker push gcr.io/$PROJECT_ID/$_BUILDER_IMAGE_NAME:latest - - id: build-native-libs - name: gcr.io/$PROJECT_ID/$_BUILDER_IMAGE_NAME:latest - # if build fails while image is still uploading, uploading will be cancelled - waitFor: [] - timeout: 5400s # 1.5 hours - entrypoint: bash - env: - - BAZEL_CACHE_ARG=--remote_cache=https://storage.googleapis.com/$_BAZEL_CACHE_BUCKET --google_default_credentials - - WITH_TFLITE=1 - - WITH_PIXEL=1 - args: - - -xc - - | - make flutter/android/libs/build - - id: build-tflite-apks - name: gcr.io/$PROJECT_ID/$_BUILDER_IMAGE_NAME:latest - timeout: 600s # 10 minutes - entrypoint: bash - env: - - OFFICIAL_BUILD=true - - FLUTTER_BUILD_NUMBER=0 - - FLUTTER_FORCE_PUB_GET=1 - - FLUTTER_ANDROID_APK_FOLDER=$_APK_DIR/tflite - - FLUTTER_ANDROID_APK_RELEASE=mlperfbench-t-$SHORT_SHA.apk - - FLUTTER_ANDROID_APK_TEST_MAIN=test-main-t-$SHORT_SHA.apk - - FLUTTER_ANDROID_APK_TEST_HELPER=test-helper-t-$SHORT_SHA.apk - - PERF_TEST=true - - FIREBASE_ANDROID_API_KEY=$_FIREBASE_ANDROID_API_KEY - - FIREBASE_ANDROID_APP_ID=$_FIREBASE_ANDROID_APP_ID - - FIREBASE_PROJECT_ID=$_FIREBASE_PROJECT_ID - - FIREBASE_MESSAGING_SENDER_ID=$_FIREBASE_MESSAGING_SENDER_ID - - FIREBASE_DATABASE_URL=$_FIREBASE_DATABASE_URL - - FIREBASE_STORAGE_BUCKET=$_FIREBASE_STORAGE_BUCKET - - FIREBASE_CI_USER_EMAIL=$_FIREBASE_CI_USER_EMAIL - - FIREBASE_CI_USER_PASSWORD=$_FIREBASE_CI_USER_PASSWORD - - FIREBASE_CRASHLYTICS_ENABLED=true - args: - - -xc - - | - make flutter/android/libs/copy flutter/prepare || exit $? - make flutter/android/apk flutter/android/test-apk || exit $? - cat >request-tflite.json <request-pixel.json <= 363.0.0' + project_id: mobile-app-build-290400 + - name: Install AWS CLI + run: | + python3 -m pip install awscli + - name: Download Samsung libraries + env: + AWS_ACCESS_KEY_ID: ${{ secrets.READONLY_AWS_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.READONLY_AWS_KEY }} + run: | + aws s3 --endpoint-url=https://s3.us-east-1.lyvecloud.seagate.com \ + cp --quiet s3://mlcommons-mobile-wg-private/libs/v3.1/samsung_libs_v3.1_20231116.zip /tmp/ && \ + unzip /tmp/samsung_libs_v3.1_20231116.zip -d /tmp/samsung_libs_v3.1_20231116 && \ + rm /tmp/samsung_libs_v3.1_20231116.zip && \ + mkdir -p mobile_back_samsung/samsung/lib/internal && \ + mv /tmp/samsung_libs_v3.1_20231116/* mobile_back_samsung/samsung/lib/internal/ + - name: Download QTI libraries + env: + AWS_ACCESS_KEY_ID: ${{ secrets.READONLY_AWS_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.READONLY_AWS_KEY }} + run: | + aws s3 --endpoint-url=https://s3.us-east-1.lyvecloud.seagate.com \ + cp --quiet s3://mlcommons-mobile-wg-private/libs/v3.1/qaisw-2.13.4.230831213719_60417-linux.zip /tmp/ && \ + unzip -P ${AWS_SECRET_ACCESS_KEY} /tmp/qaisw-2.13.4.230831213719_60417-linux.zip -d /tmp/qaisw-2.13.4.230831213719_60417-linux && \ + rm /tmp/qaisw-2.13.4.230831213719_60417-linux.zip && \ + mv /tmp/qaisw-2.13.4.230831213719_60417-linux/qaisw-2.13.4.230831213719_60417 mobile_back_qti/ + - name: Cache bazel + uses: actions/cache@v3 + with: + path: /tmp/bazel_cache + key: ${{ runner.os }}-bazel_cache-${{ hashFiles('**/BUILD', '**/WORKSPACE') }} + restore-keys: ${{ runner.os }}-bazel_cache- + - name: Run Flutter unit tests + run: | + make flutter/prepare && make flutter/test/unit + - name: Build and upload test APK for TFLite + env: + OFFICIAL_BUILD: false + PERF_TEST: true + WITH_TFLITE: 1 + run: | + make flutter/android/release flutter/android/apk flutter/android/test-apk + gsutil mv output/android-apks/test-main.apk $GCLOUD_BUCKET_PATH/test-main-tflite.apk + gsutil mv output/android-apks/test-helper.apk $GCLOUD_BUCKET_PATH/test-helper-tflite.apk + - name: Build and upload test APK for Pixel + env: + OFFICIAL_BUILD: false + PERF_TEST: true + WITH_TFLITE: 0 + WITH_PIXEL: 1 + run: | + make flutter/android/release flutter/android/apk flutter/android/test-apk + gsutil mv output/android-apks/test-main.apk $GCLOUD_BUCKET_PATH/test-main-pixel.apk + gsutil mv output/android-apks/test-helper.apk $GCLOUD_BUCKET_PATH/test-helper-pixel.apk + - name: Build and upload test APK for QTI + env: + OFFICIAL_BUILD: false + PERF_TEST: true + WITH_TFLITE: 0 + WITH_QTI: 1 + run: | + make flutter/android/release flutter/android/apk flutter/android/test-apk + gsutil mv output/android-apks/test-main.apk $GCLOUD_BUCKET_PATH/test-main-qti.apk + gsutil mv output/android-apks/test-helper.apk $GCLOUD_BUCKET_PATH/test-helper-qti.apk + - name: Build and upload test APK for MediaTek + env: + OFFICIAL_BUILD: false + PERF_TEST: true + WITH_TFLITE: 0 + WITH_MEDIATEK: 1 + run: | + make flutter/android/release flutter/android/apk flutter/android/test-apk + gsutil mv output/android-apks/test-main.apk $GCLOUD_BUCKET_PATH/test-main-mtk.apk + gsutil mv output/android-apks/test-helper.apk $GCLOUD_BUCKET_PATH/test-helper-mtk.apk + - name: Build and upload test APK for Samsung + env: + OFFICIAL_BUILD: false + PERF_TEST: true + WITH_TFLITE: 0 + WITH_SAMSUNG: 1 + run: | + make flutter/android/release flutter/android/apk flutter/android/test-apk + gsutil mv output/android-apks/test-main.apk $GCLOUD_BUCKET_PATH/test-main-samsung.apk + gsutil mv output/android-apks/test-helper.apk $GCLOUD_BUCKET_PATH/test-helper-samsung.apk + - name: Build Android release APK with all backends + env: + OFFICIAL_BUILD: true + FIREBASE_CRASHLYTICS_ENABLED: true + WITH_TFLITE: 1 + WITH_PIXEL: 1 + WITH_MEDIATEK: 1 + WITH_QTI: 1 + WITH_SAMSUNG: 1 + WITH_APPLE: 0 + run: | + make flutter/android/release + - name: Archive Android APKs + uses: actions/upload-artifact@v3 + with: + name: android-apks-${{ github.run_number }} + path: output/android-apks/*.apk + retention-days: 30 + if-no-files-found: error + + test-android-apk-tflite: + needs: build-android-apk + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - name: Set up authentication for Google Cloud SDK + uses: google-github-actions/auth@v2 + with: + credentials_json: ${{ secrets.GCLOUD_SERVICE_ACCOUNT_MOBILE_APP_BUILD }} + - name: Set up Google Cloud SDK + uses: google-github-actions/setup-gcloud@v2 + with: + version: '>= 363.0.0' + project_id: mobile-app-build-290400 + - name: Trigger Firebase Test Lab for [Google Pixel 5](redfin) + run: | + gcloud firebase test android run \ + --type instrumentation \ + --app $GCLOUD_BUCKET_PATH/test-main-tflite.apk \ + --test $GCLOUD_BUCKET_PATH/test-helper-tflite.apk \ + --timeout 30m \ + --num-flaky-test-attempts 2 \ + --device model=redfin,version=30,locale=en,orientation=portrait \ + --client-details=buildNumber=${{ github.run_number }} + + test-android-apk-pixel: + needs: build-android-apk + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - name: Set up authentication for Google Cloud SDK + uses: google-github-actions/auth@v2 + with: + credentials_json: ${{ secrets.GCLOUD_SERVICE_ACCOUNT_MOBILE_APP_BUILD }} + - name: Set up Google Cloud SDK + uses: google-github-actions/setup-gcloud@v2 + with: + version: '>= 363.0.0' + project_id: mobile-app-build-290400 + - name: Trigger Firebase Test Lab for [Google Pixel 6](oriole) + run: | + gcloud firebase test android run \ + --type instrumentation \ + --app $GCLOUD_BUCKET_PATH/test-main-pixel.apk \ + --test $GCLOUD_BUCKET_PATH/test-helper-pixel.apk \ + --timeout 30m \ + --num-flaky-test-attempts 2 \ + --device model=oriole,version=32,locale=en,orientation=portrait \ + --client-details=buildNumber=${{ github.run_number }} + + test-android-apk-qti: + needs: build-android-apk + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - name: Set up authentication for Google Cloud SDK + uses: google-github-actions/auth@v2 + with: + credentials_json: ${{ secrets.GCLOUD_SERVICE_ACCOUNT_MOBILE_APP_BUILD }} + - name: Set up Google Cloud SDK + uses: google-github-actions/setup-gcloud@v2 + with: + version: '>= 363.0.0' + project_id: mobile-app-build-290400 + - name: Trigger Firebase Test Lab for [Samsung Galaxy S22 Ultra](b0q) + run: | + gcloud firebase test android run \ + --type instrumentation \ + --app $GCLOUD_BUCKET_PATH/test-main-qti.apk \ + --test $GCLOUD_BUCKET_PATH/test-helper-qti.apk \ + --timeout 30m \ + --num-flaky-test-attempts 2 \ + --device model=b0q,version=33,locale=en,orientation=portrait \ + --client-details=buildNumber=${{ github.run_number }} + + test-android-apk-mtk: + needs: build-android-apk + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - name: Set up authentication for Google Cloud SDK + uses: google-github-actions/auth@v2 + with: + credentials_json: ${{ secrets.GCLOUD_SERVICE_ACCOUNT_MOBILE_APP_BUILD }} + - name: Set up Google Cloud SDK + uses: google-github-actions/setup-gcloud@v2 + with: + version: '>= 363.0.0' + project_id: mobile-app-build-290400 + - name: Trigger Firebase Test Lab for [OnePlus DN2103](OP515BL1) + run: | + gcloud firebase test android run \ + --type instrumentation \ + --app $GCLOUD_BUCKET_PATH/test-main-mtk.apk \ + --test $GCLOUD_BUCKET_PATH/test-helper-mtk.apk \ + --timeout 30m \ + --num-flaky-test-attempts 2 \ + --device model=OP515BL1,version=33,locale=en,orientation=portrait \ + --client-details=buildNumber=${{ github.run_number }} diff --git a/.github/workflows/app-build.yml b/.github/workflows/app-build.yml deleted file mode 100644 index 4a374632f..000000000 --- a/.github/workflows/app-build.yml +++ /dev/null @@ -1,148 +0,0 @@ -name: App Build - -on: - push: - branches: [ master, submission-v* ] - pull_request: - types: [ opened, synchronize, reopened ] - -jobs: - build-android-image: - runs-on: ubuntu-22.04 - permissions: - contents: read - packages: write - steps: - - uses: actions/checkout@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - name: Log in to the Container registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract metadata for Docker image - id: meta - uses: docker/metadata-action@v4 - with: - images: ghcr.io/mlcommons/mobile_app_open-android - flavor: latest=true - tags: type=raw,value=${{ github.run_number }} - - name: Build and push Docker image - uses: docker/build-push-action@v4 - with: - context: flutter/android/docker - file: flutter/android/docker/Dockerfile - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max - - build-android-apk: - needs: build-android-image - runs-on: ubuntu-22.04 - container: - image: ghcr.io/mlcommons/mobile_app_open-android:${{ github.run_number }} - timeout-minutes: 120 - steps: - - uses: actions/checkout@v3 - # Preinstalled tools from host at `/opt/hostedtoolcache` is not needed since we run commands inside our own Docker container. - # `/opt/hostedtoolcache` is mounted to `/__t`. We delete it to free up disk space. - - name: Free up disk space - run: | - echo BEFORE: - df -h - rm -rf /__t/* - echo AFTER: - df -h - - name: Configure Git - run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - - name: Install AWS CLI - run: | - python3 -m pip install awscli - - name: Download Samsung libraries - env: - AWS_ACCESS_KEY_ID: ${{ secrets.READONLY_AWS_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.READONLY_AWS_KEY }} - run: | - aws s3 --endpoint-url=https://s3.us-east-1.lyvecloud.seagate.com \ - cp --quiet s3://mlcommons-mobile-wg-private/libs/v3.1/samsung_libs_v3.1_20231116.zip /tmp/ && \ - unzip /tmp/samsung_libs_v3.1_20231116.zip -d /tmp/samsung_libs_v3.1_20231116 && \ - rm /tmp/samsung_libs_v3.1_20231116.zip && \ - mkdir -p mobile_back_samsung/samsung/lib/internal && \ - mv /tmp/samsung_libs_v3.1_20231116/* mobile_back_samsung/samsung/lib/internal/ - - name: Download QTI libraries - env: - AWS_ACCESS_KEY_ID: ${{ secrets.READONLY_AWS_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.READONLY_AWS_KEY }} - run: | - aws s3 --endpoint-url=https://s3.us-east-1.lyvecloud.seagate.com \ - cp --quiet s3://mlcommons-mobile-wg-private/libs/v3.1/qaisw-2.13.4.230831213719_60417-linux.zip /tmp/ && \ - unzip -P ${AWS_SECRET_ACCESS_KEY} /tmp/qaisw-2.13.4.230831213719_60417-linux.zip -d /tmp/qaisw-2.13.4.230831213719_60417-linux && \ - rm /tmp/qaisw-2.13.4.230831213719_60417-linux.zip && \ - mv /tmp/qaisw-2.13.4.230831213719_60417-linux/qaisw-2.13.4.230831213719_60417 mobile_back_qti/ - - name: Cache bazel - uses: actions/cache@v3 - with: - path: /tmp/bazel_cache - key: ${{ runner.os }}-bazel_cache-${{ hashFiles('**/BUILD', '**/WORKSPACE') }} - restore-keys: ${{ runner.os }}-bazel_cache- - - name: Run Flutter unit tests - run: | - make flutter/prepare && \ - make flutter/test/unit - - name: Build Android release APK - env: - BAZEL_OUTPUT_ROOT_ARG: "--output_user_root=/tmp/bazel_output" - BAZEL_CACHE_ARG: "--disk_cache=/tmp/bazel_cache" - FIREBASE_ANDROID_API_KEY: ${{ secrets.FIREBASE_ANDROID_API_KEY }} - FIREBASE_ANDROID_APP_ID: ${{ secrets.FIREBASE_ANDROID_APP_ID }} - FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }} - FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.FIREBASE_MESSAGING_SENDER_ID }} - FIREBASE_DATABASE_URL: ${{ secrets.FIREBASE_DATABASE_URL }} - FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} - FIREBASE_CRASHLYTICS_ENABLED: true - OFFICIAL_BUILD: true - FLUTTER_BUILD_NUMBER: ${{ github.run_number }} - WITH_TFLITE: 1 - WITH_PIXEL: 1 - WITH_MEDIATEK: 1 - WITH_QTI: 1 - WITH_SAMSUNG: 1 - WITH_APPLE: 0 - run: | - make flutter/android/release - - name: Archive Android release APK - uses: actions/upload-artifact@v3 - with: - name: android-apks-${{ github.run_number }} - path: output/android-apks/*.apk - retention-days: 30 - if-no-files-found: error - - name: Build Android test APK - env: - BAZEL_OUTPUT_ROOT_ARG: "--output_user_root=/tmp/bazel_output" - BAZEL_CACHE_ARG: "--disk_cache=/tmp/bazel_cache" - OFFICIAL_BUILD: false - FLUTTER_BUILD_NUMBER: ${{ github.run_number }} - WITH_TFLITE: 1 - WITH_PIXEL: 1 - WITH_MEDIATEK: 1 - WITH_QTI: 1 - WITH_SAMSUNG: 1 - WITH_APPLE: 0 - run: | - make flutter/android/apk flutter/android/test-apk - - name: Upload Android test APK - env: - AWS_ACCESS_KEY_ID: ${{ secrets.MLPERF_ARM_AWS_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.MLPERF_ARM_AWS_KEY }} - run: | - aws s3 --endpoint-url=https://s3.us-east-1.lyvecloud.seagate.com \ - cp --quiet output/android-apks/test-main.apk s3://mlcommons-mobile-mlperf-arm/builds/${{ github.run_number }}/ && \ - aws s3 --endpoint-url=https://s3.us-east-1.lyvecloud.seagate.com \ - cp --quiet output/android-apks/test-helper.apk s3://mlcommons-mobile-mlperf-arm/builds/${{ github.run_number }}/ && \ - aws s3 --endpoint-url=https://s3.us-east-1.lyvecloud.seagate.com \ - cp --quiet flutter/build/app/outputs/flutter-apk/app-release.apk s3://mlcommons-mobile-mlperf-arm/builds/${{ github.run_number }}/ diff --git a/.github/workflows/ios-tests.yml b/.github/workflows/ios-build-test.yml similarity index 89% rename from .github/workflows/ios-tests.yml rename to .github/workflows/ios-build-test.yml index 27d135845..c43abe226 100644 --- a/.github/workflows/ios-tests.yml +++ b/.github/workflows/ios-build-test.yml @@ -1,4 +1,4 @@ -name: iOS Tests +name: iOS Build & Test on: push: @@ -59,7 +59,11 @@ jobs: - name: Build iOS integration tests run: | cd flutter && flutter --no-version-check build ios --simulator integration_test/first_test.dart - - name: Run iOS integration tests - run: | - open -a Simulator - make flutter/test/integration + - uses: nick-fields/retry@v2 + name: Run iOS integration tests + with: + timeout_minutes: 45 + max_attempts: 2 + command: | + open -a Simulator + make flutter/test/integration diff --git a/flutter/integration_test/expected_accuracy.dart b/flutter/integration_test/expected_accuracy.dart index 7b2589d8c..58336de46 100644 --- a/flutter/integration_test/expected_accuracy.dart +++ b/flutter/integration_test/expected_accuracy.dart @@ -9,7 +9,11 @@ key: OR | - npu -> Android TFLite - tpu -> Android Pixel - ane -> iOS TFLite or Core ML -- cpu&gpu&ane -> IOS Core ML +- cpu&gpu&ane -> iOS Core ML +- snpe_dsp -> Android QTI +- psnpe_dsp -> Android QTI +- neuron-mdla > Android MediaTek +- neuron > Android MediaTek */ const Map _imageClassification = { @@ -17,7 +21,10 @@ const Map _imageClassification = { 'npu': Interval(min: 0.89, max: 0.91), 'tpu': Interval(min: 0.89, max: 0.91), 'ane': Interval(min: 1.00, max: 1.00), - 'cpu&gpu&ane': Interval(min: 1.00, max: 1.00) + 'cpu&gpu&ane': Interval(min: 1.00, max: 1.00), + 'snpe_dsp': Interval(min: 0.78, max: 0.82), + 'psnpe_dsp': Interval(min: 0.78, max: 0.82), + 'neuron-mdla': Interval(min: 0.88, max: 0.91), }; const Map _objectDetection = { @@ -26,7 +33,10 @@ const Map _objectDetection = { 'tpu': Interval(min: 0.36, max: 0.38), 'ane|TFLite': Interval(min: 0.31, max: 0.34), 'ane|Core ML': Interval(min: 0.45, max: 0.46), - 'cpu&gpu&ane': Interval(min: 0.45, max: 0.46) + 'cpu&gpu&ane': Interval(min: 0.45, max: 0.46), + 'snpe_dsp': Interval(min: 0.32, max: 0.35), + 'psnpe_dsp': Interval(min: 0.32, max: 0.35), + 'neuron': Interval(min: 0.28, max: 0.31), }; const Map _imageSegmentation = { @@ -35,7 +45,10 @@ const Map _imageSegmentation = { 'tpu': Interval(min: 0.33, max: 0.34), 'ane|TFLite': Interval(min: 0.38, max: 0.40), 'ane|Core ML': Interval(min: 0.38, max: 0.40), - 'cpu&gpu&ane': Interval(min: 0.38, max: 0.40) + 'cpu&gpu&ane': Interval(min: 0.38, max: 0.40), + 'snpe_dsp': Interval(min: 0.35, max: 0.38), + 'psnpe_dsp': Interval(min: 0.35, max: 0.38), + 'neuron': Interval(min: 0.32, max: 0.34), }; const Map _naturalLanguageProcessing = { @@ -44,7 +57,10 @@ const Map _naturalLanguageProcessing = { 'gpu|TFLite': Interval(min: 1.00, max: 1.00), // 1.00 in simulator, 0.80 on iphone 12 mini 'gpu|Core ML': Interval(min: 0.80, max: 1.00), - 'cpu&gpu&ane': Interval(min: 0.80, max: 1.00) + 'cpu&gpu&ane': Interval(min: 0.80, max: 1.00), + 'snpe_dsp': Interval(min: 1.00, max: 1.00), + 'psnpe_dsp': Interval(min: 1.00, max: 1.00), + 'neuron-no-ahwb': Interval(min: 1.00, max: 1.00), }; const Map _superResolution = { @@ -53,7 +69,10 @@ const Map _superResolution = { 'tpu': Interval(min: 0.32, max: 0.35), 'ane|TFLite': Interval(min: 0.32, max: 0.35), 'ane|Core ML': Interval(min: 0.32, max: 0.35), - 'cpu&gpu&ane': Interval(min: 0.32, max: 0.35) + 'cpu&gpu&ane': Interval(min: 0.32, max: 0.35), + 'snpe_dsp': Interval(min: 0.32, max: 0.35), + 'psnpe_dsp': Interval(min: 0.32, max: 0.35), + 'neuron': Interval(min: 0.32, max: 0.35), }; const benchmarkExpectedAccuracy = { diff --git a/flutter/integration_test/expected_throughput.dart b/flutter/integration_test/expected_throughput.dart index a30e1bd58..f823c2729 100644 --- a/flutter/integration_test/expected_throughput.dart +++ b/flutter/integration_test/expected_throughput.dart @@ -10,6 +10,8 @@ key: model_code (on Android or iOS) or cpuFullName (on Windows) const _kTFLiteBackend = 'libtflitebackend'; const _kPixelBackend = 'libtflitepixelbackend'; const _kCoreMLBackend = 'libcoremlbackend'; +const _kQtiBackend = 'libqtibackend'; +const _kMediatekBackend = 'libtfliteneuronbackend'; // Windows // Google Cloud Build n2-standard-4 machine @@ -18,8 +20,10 @@ const _kCloudBuildX28 = 'Intel Xeon 2.80GHz'; const _kRyzen5600 = 'AMD Ryzen 5 5600X 6-Core'; // Android -const _kPixel5 = 'Pixel 5'; -const _kPixel6 = 'Pixel 6'; +const _kPixel5 = 'Pixel 5'; // Google Pixel 5 +const _kPixel6 = 'Pixel 6'; // Google Pixel 6 +const _kS22Ultra = 'SM-S908U1'; // Galaxy S22 Ultra +const _kDN2103 = 'DN2103'; // OnePlus DN2103 // iOS const _kIphoneOnGitHubAction = 'iPhone15,3'; @@ -31,15 +35,21 @@ const Map> _imageClassification = { _kCloudBuildX28: Interval(min: 4, max: 13), _kRyzen5600: Interval(min: 31, max: 37), _kPixel5: Interval(min: 80, max: 130), - _kIphoneOnGitHubAction: Interval(min: 2, max: 8), + _kIphoneOnGitHubAction: Interval(min: 1, max: 8), _kIphoneOnMacbookM1: Interval(min: 19, max: 27), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 2, max: 8), + _kIphoneOnGitHubAction: Interval(min: 1, max: 8), }, _kPixelBackend: { _kPixel6: Interval(min: 800, max: 1100), }, + _kQtiBackend: { + _kS22Ultra: Interval(min: 1900, max: 2200), + }, + _kMediatekBackend: { + _kDN2103: Interval(min: 30, max: 50), + }, }; const Map> _objectDetection = { @@ -48,14 +58,20 @@ const Map> _objectDetection = { _kCloudBuildX28: Interval(min: 3.5, max: 8), _kRyzen5600: Interval(min: 14, max: 22), _kPixel5: Interval(min: 40, max: 60), - _kIphoneOnGitHubAction: Interval(min: 0.8, max: 4), + _kIphoneOnGitHubAction: Interval(min: 0.5, max: 4), _kIphoneOnMacbookM1: Interval(min: 9, max: 16), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 0.8, max: 4), + _kIphoneOnGitHubAction: Interval(min: 0.5, max: 4), }, _kPixelBackend: { - _kPixel6: Interval(min: 300, max: 490), + _kPixel6: Interval(min: 250, max: 450), + }, + _kQtiBackend: { + _kS22Ultra: Interval(min: 800, max: 1100), + }, + _kMediatekBackend: { + _kDN2103: Interval(min: 120, max: 180), }, }; @@ -65,15 +81,21 @@ const Map> _imageSegmentationV2 = { _kCloudBuildX28: Interval(min: 0.5, max: 4), _kRyzen5600: Interval(min: 5, max: 7), _kPixel5: Interval(min: 25, max: 40), - _kIphoneOnGitHubAction: Interval(min: 0.3, max: 2.5), + _kIphoneOnGitHubAction: Interval(min: 0.1, max: 2.5), _kIphoneOnMacbookM1: Interval(min: 3, max: 6), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 0.3, max: 2.5), + _kIphoneOnGitHubAction: Interval(min: 0.1, max: 2.5), }, _kPixelBackend: { _kPixel6: Interval(min: 100, max: 180), }, + _kQtiBackend: { + _kS22Ultra: Interval(min: 450, max: 650), + }, + _kMediatekBackend: { + _kDN2103: Interval(min: 45, max: 65), + }, }; const Map> _naturalLanguageProcessing = { @@ -82,32 +104,21 @@ const Map> _naturalLanguageProcessing = { _kCloudBuildX28: Interval(min: 0.5, max: 1.3), _kRyzen5600: Interval(min: 2.8, max: 3.2), _kPixel5: Interval(min: 2.3, max: 3.0), - _kIphoneOnGitHubAction: Interval(min: 0.2, max: 1), + _kIphoneOnGitHubAction: Interval(min: 0.1, max: 1), _kIphoneOnMacbookM1: Interval(min: 1.8, max: 3), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 0.2, max: 1), + _kIphoneOnGitHubAction: Interval(min: 0.1, max: 1), }, _kPixelBackend: { // pixel some time finish this task in 4 seconds, not sure why. _kPixel6: Interval(min: 2, max: 75), }, -}; - -const Map> _imageClassificationOffline = { - _kTFLiteBackend: { - _kCloudBuildX23: Interval(min: 8, max: 14), - _kCloudBuildX28: Interval(min: 7, max: 16), - _kRyzen5600: Interval(min: 45, max: 60), - _kPixel5: Interval(min: 120, max: 190), - _kIphoneOnGitHubAction: Interval(min: 3, max: 15), - _kIphoneOnMacbookM1: Interval(min: 30, max: 45), + _kQtiBackend: { + _kS22Ultra: Interval(min: 120, max: 160), }, - _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 3, max: 20), - }, - _kPixelBackend: { - _kPixel6: Interval(min: 1000, max: 1700), + _kMediatekBackend: { + _kDN2103: Interval(min: 1, max: 5), }, }; @@ -117,15 +128,44 @@ const Map> _superResolution = { _kCloudBuildX28: Interval(min: 0.1, max: 4), _kRyzen5600: Interval(min: 0.1, max: 3), _kPixel5: Interval(min: 4, max: 8), - _kIphoneOnGitHubAction: Interval(min: 0.08, max: 1.0), + _kIphoneOnGitHubAction: Interval(min: 0.02, max: 1.0), _kIphoneOnMacbookM1: Interval(min: 0.1, max: 10), }, _kCoreMLBackend: { - _kIphoneOnGitHubAction: Interval(min: 0.08, max: 1.0), + _kIphoneOnGitHubAction: Interval(min: 0.02, max: 1.0), }, _kPixelBackend: { _kPixel6: Interval(min: 10, max: 14), }, + _kQtiBackend: { + _kS22Ultra: Interval(min: 35, max: 45), + }, + _kMediatekBackend: { + _kDN2103: Interval(min: 5, max: 12), + }, +}; + +const Map> _imageClassificationOffline = { + _kTFLiteBackend: { + _kCloudBuildX23: Interval(min: 8, max: 14), + _kCloudBuildX28: Interval(min: 7, max: 16), + _kRyzen5600: Interval(min: 45, max: 60), + _kPixel5: Interval(min: 120, max: 190), + _kIphoneOnGitHubAction: Interval(min: 2, max: 15), + _kIphoneOnMacbookM1: Interval(min: 30, max: 45), + }, + _kCoreMLBackend: { + _kIphoneOnGitHubAction: Interval(min: 2, max: 20), + }, + _kPixelBackend: { + _kPixel6: Interval(min: 1000, max: 1700), + }, + _kQtiBackend: { + _kS22Ultra: Interval(min: 2600, max: 3000), + }, + _kMediatekBackend: { + _kDN2103: Interval(min: 75, max: 110), + }, }; const benchmarkExpectedThroughput = { From 84ca6c830e6054484552d6a10bfb7e3ab7cfb90a Mon Sep 17 00:00:00 2001 From: Anh Date: Tue, 30 Jan 2024 13:40:23 +0700 Subject: [PATCH 16/17] ui: update color scheme and task icon (#845) * Use new task icon set * Refactor color management * Update app colors * Change app bar color for unofficial build. --- .../assets/icons/ic_image_classification.svg | 1 - .../icons/ic_image_classification_offline.svg | 22 ------ .../ic_image_classification_offline_white.svg | 22 ------ .../assets/icons/ic_image_segmentation.svg | 23 ------ .../assets/icons/ic_language_processing.svg | 1 - flutter/assets/icons/ic_object_detection.svg | 1 - .../icons/ic_offline_image_classification.svg | 1 - flutter/assets/icons/ic_super_resolution.svg | 13 ---- .../icons/ic_task_image_classification.svg | 3 + .../ic_task_image_classification_offline.svg | 5 ++ ...ask_image_classification_offline_white.svg | 5 ++ .../ic_task_image_classification_white.svg | 3 + .../icons/ic_task_image_segmentation.svg | 4 + .../ic_task_image_segmentation_white.svg | 4 + .../icons/ic_task_language_processing.svg | 4 + .../ic_task_language_processing_white.svg | 4 + .../assets/icons/ic_task_object_detection.svg | 4 + .../icons/ic_task_object_detection_white.svg | 4 + .../assets/icons/ic_task_super_resolution.svg | 6 ++ .../icons/ic_task_super_resolution_white.svg | 6 ++ flutter/lib/app_constants.dart | 74 +------------------ .../data/environment/environment_info.dart | 3 +- flutter/lib/ui/app_styles.dart | 68 +++++++++++++++++ flutter/lib/ui/confirm_dialog.dart | 2 +- flutter/lib/ui/error_dialog.dart | 2 +- flutter/lib/ui/formatter.dart | 6 ++ flutter/lib/ui/history/history_list_item.dart | 4 +- flutter/lib/ui/history/utils.dart | 4 +- flutter/lib/ui/home/app_drawer.dart | 23 +++++- .../lib/ui/home/benchmark_config_section.dart | 7 +- .../lib/ui/home/benchmark_result_screen.dart | 40 ++++++---- .../lib/ui/home/benchmark_running_screen.dart | 18 ++--- .../lib/ui/home/benchmark_start_screen.dart | 23 +++--- .../lib/ui/home/resource_loading_screen.dart | 74 ++++++------------- flutter/lib/ui/home/result_circle.dart | 12 +-- flutter/lib/ui/home/share_button.dart | 10 +-- flutter/lib/ui/home/shared_styles.dart | 14 ---- flutter/lib/ui/icons.dart | 31 ++++---- flutter/lib/ui/root/app.dart | 8 +- flutter/lib/ui/root/exception_screen.dart | 2 +- .../lib/ui/root/resource_error_screen.dart | 4 +- flutter/lib/ui/settings/settings_screen.dart | 1 + flutter/lib/ui/settings/snack_bar.dart | 13 ---- .../lib/ui/settings/task_config_section.dart | 3 +- 44 files changed, 266 insertions(+), 316 deletions(-) delete mode 100644 flutter/assets/icons/ic_image_classification.svg delete mode 100644 flutter/assets/icons/ic_image_classification_offline.svg delete mode 100644 flutter/assets/icons/ic_image_classification_offline_white.svg delete mode 100644 flutter/assets/icons/ic_image_segmentation.svg delete mode 100644 flutter/assets/icons/ic_language_processing.svg delete mode 100644 flutter/assets/icons/ic_object_detection.svg delete mode 100644 flutter/assets/icons/ic_offline_image_classification.svg delete mode 100644 flutter/assets/icons/ic_super_resolution.svg create mode 100644 flutter/assets/icons/ic_task_image_classification.svg create mode 100644 flutter/assets/icons/ic_task_image_classification_offline.svg create mode 100644 flutter/assets/icons/ic_task_image_classification_offline_white.svg create mode 100644 flutter/assets/icons/ic_task_image_classification_white.svg create mode 100644 flutter/assets/icons/ic_task_image_segmentation.svg create mode 100644 flutter/assets/icons/ic_task_image_segmentation_white.svg create mode 100644 flutter/assets/icons/ic_task_language_processing.svg create mode 100644 flutter/assets/icons/ic_task_language_processing_white.svg create mode 100644 flutter/assets/icons/ic_task_object_detection.svg create mode 100644 flutter/assets/icons/ic_task_object_detection_white.svg create mode 100644 flutter/assets/icons/ic_task_super_resolution.svg create mode 100644 flutter/assets/icons/ic_task_super_resolution_white.svg create mode 100644 flutter/lib/ui/app_styles.dart delete mode 100644 flutter/lib/ui/home/shared_styles.dart delete mode 100644 flutter/lib/ui/settings/snack_bar.dart diff --git a/flutter/assets/icons/ic_image_classification.svg b/flutter/assets/icons/ic_image_classification.svg deleted file mode 100644 index b02ac5bdd..000000000 --- a/flutter/assets/icons/ic_image_classification.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/flutter/assets/icons/ic_image_classification_offline.svg b/flutter/assets/icons/ic_image_classification_offline.svg deleted file mode 100644 index e3bba115c..000000000 --- a/flutter/assets/icons/ic_image_classification_offline.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - diff --git a/flutter/assets/icons/ic_image_classification_offline_white.svg b/flutter/assets/icons/ic_image_classification_offline_white.svg deleted file mode 100644 index 2455d1f8e..000000000 --- a/flutter/assets/icons/ic_image_classification_offline_white.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - diff --git a/flutter/assets/icons/ic_image_segmentation.svg b/flutter/assets/icons/ic_image_segmentation.svg deleted file mode 100644 index 4c5f897c9..000000000 --- a/flutter/assets/icons/ic_image_segmentation.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/flutter/assets/icons/ic_language_processing.svg b/flutter/assets/icons/ic_language_processing.svg deleted file mode 100644 index ddacf9ceb..000000000 --- a/flutter/assets/icons/ic_language_processing.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/flutter/assets/icons/ic_object_detection.svg b/flutter/assets/icons/ic_object_detection.svg deleted file mode 100644 index c22c94092..000000000 --- a/flutter/assets/icons/ic_object_detection.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/flutter/assets/icons/ic_offline_image_classification.svg b/flutter/assets/icons/ic_offline_image_classification.svg deleted file mode 100644 index 20441ae49..000000000 --- a/flutter/assets/icons/ic_offline_image_classification.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/flutter/assets/icons/ic_super_resolution.svg b/flutter/assets/icons/ic_super_resolution.svg deleted file mode 100644 index 56caf7a9c..000000000 --- a/flutter/assets/icons/ic_super_resolution.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/flutter/assets/icons/ic_task_image_classification.svg b/flutter/assets/icons/ic_task_image_classification.svg new file mode 100644 index 000000000..58ea39bc9 --- /dev/null +++ b/flutter/assets/icons/ic_task_image_classification.svg @@ -0,0 +1,3 @@ + + + diff --git a/flutter/assets/icons/ic_task_image_classification_offline.svg b/flutter/assets/icons/ic_task_image_classification_offline.svg new file mode 100644 index 000000000..1f0ad1237 --- /dev/null +++ b/flutter/assets/icons/ic_task_image_classification_offline.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/flutter/assets/icons/ic_task_image_classification_offline_white.svg b/flutter/assets/icons/ic_task_image_classification_offline_white.svg new file mode 100644 index 000000000..ca6ec2e9c --- /dev/null +++ b/flutter/assets/icons/ic_task_image_classification_offline_white.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/flutter/assets/icons/ic_task_image_classification_white.svg b/flutter/assets/icons/ic_task_image_classification_white.svg new file mode 100644 index 000000000..2a802d887 --- /dev/null +++ b/flutter/assets/icons/ic_task_image_classification_white.svg @@ -0,0 +1,3 @@ + + + diff --git a/flutter/assets/icons/ic_task_image_segmentation.svg b/flutter/assets/icons/ic_task_image_segmentation.svg new file mode 100644 index 000000000..cbfa18d83 --- /dev/null +++ b/flutter/assets/icons/ic_task_image_segmentation.svg @@ -0,0 +1,4 @@ + + + + diff --git a/flutter/assets/icons/ic_task_image_segmentation_white.svg b/flutter/assets/icons/ic_task_image_segmentation_white.svg new file mode 100644 index 000000000..11439b411 --- /dev/null +++ b/flutter/assets/icons/ic_task_image_segmentation_white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/flutter/assets/icons/ic_task_language_processing.svg b/flutter/assets/icons/ic_task_language_processing.svg new file mode 100644 index 000000000..c8d194ba5 --- /dev/null +++ b/flutter/assets/icons/ic_task_language_processing.svg @@ -0,0 +1,4 @@ + + + + diff --git a/flutter/assets/icons/ic_task_language_processing_white.svg b/flutter/assets/icons/ic_task_language_processing_white.svg new file mode 100644 index 000000000..a80b6c864 --- /dev/null +++ b/flutter/assets/icons/ic_task_language_processing_white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/flutter/assets/icons/ic_task_object_detection.svg b/flutter/assets/icons/ic_task_object_detection.svg new file mode 100644 index 000000000..07ebdf97b --- /dev/null +++ b/flutter/assets/icons/ic_task_object_detection.svg @@ -0,0 +1,4 @@ + + + + diff --git a/flutter/assets/icons/ic_task_object_detection_white.svg b/flutter/assets/icons/ic_task_object_detection_white.svg new file mode 100644 index 000000000..b79287cf0 --- /dev/null +++ b/flutter/assets/icons/ic_task_object_detection_white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/flutter/assets/icons/ic_task_super_resolution.svg b/flutter/assets/icons/ic_task_super_resolution.svg new file mode 100644 index 000000000..62a11dc6e --- /dev/null +++ b/flutter/assets/icons/ic_task_super_resolution.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/flutter/assets/icons/ic_task_super_resolution_white.svg b/flutter/assets/icons/ic_task_super_resolution_white.svg new file mode 100644 index 000000000..83732a455 --- /dev/null +++ b/flutter/assets/icons/ic_task_super_resolution_white.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/flutter/lib/app_constants.dart b/flutter/lib/app_constants.dart index 552460d0e..176dc7f79 100644 --- a/flutter/lib/app_constants.dart +++ b/flutter/lib/app_constants.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; - class DartDefine { + DartDefine._(); + static const isOfficialBuild = bool.fromEnvironment('OFFICIAL_BUILD', defaultValue: false); static const firebaseCrashlyticsEnabled = @@ -19,76 +19,6 @@ class WidgetKeys { static const String totalScoreCircle = 'totalScoreCircle'; } -class AppColors { - static const lightText = Colors.white; - static const lightRedText = Color.fromARGB(255, 255, 120, 100); - static const darkText = Colors.black; - static const resultValid = Colors.indigo; - static const resultInvalid = Colors.red; - static const darkRedText = Colors.red; - static const lightBlue = Color(0XFF2C92CB); - static const mediumBlue = Color(0xFF135384); - static const darkBlue = Color(0xFF0B3A61); - - static const dialogBackground = Colors.white; - static const snackBarBackground = Color(0xFFEDEDED); - static const appBarBackground = - DartDefine.isOfficialBuild ? Color(0xFF166299) : Colors.brown; - - static const appBarIcon = Colors.white; - - static List get mainScreenGradient => DartDefine.isOfficialBuild - ? [ - const Color(0xFF31A3E2), - const Color(0xFF31A3E2), - const Color(0xFF31A3E2), - const Color(0xFF3189E2), - const Color(0xFF0B4A7F), - ] - : [ - Colors.brown, - Colors.brown.shade500, - Colors.brown.shade500, - Colors.brown.shade700, - Colors.brown.shade800, - ]; - - static const runBenchmarkRectangle = Color(0xFF0DB526); - - static List get progressScreenGradient => DartDefine.isOfficialBuild - ? [const Color(0xff3189E2), const Color(0xff0B4A7F)] - : [Colors.brown.shade400, Colors.brown]; - - static const progressCircle = Color(0xff135384); - - static const progressCancelButton = Color(0x000B4A7F); - - static List get progressCircleGradient => - [const Color(0xff135384), const Color(0xff135384)]; - - static List get resultCircleGradient => [ - Color.lerp(const Color(0xFF328BE2), Colors.white, 1 - 0.65)!, - const Color(0xFF328BE2), // 328BE2 - ]; - - static List get resultBarGradient => [ - const Color(0xFF135384), - const Color(0xFF3183E2), - const Color(0xFF31B8E2), - const Color(0xFF7DD5F0), - const Color(0xFF6AD7F9) - ]; - - static const shareRectangle = Colors.green; - - static Color get shareTextButton => Colors.blue.shade900; -} - -class WidgetSizes { - static const circleWidthFactor = 0.32; - static const borderRadius = 8.0; -} - class BenchmarkId { static const imageClassification = 'image_classification'; static const objectDetection = 'object_detection'; diff --git a/flutter/lib/data/environment/environment_info.dart b/flutter/lib/data/environment/environment_info.dart index 87e26d81d..57a36da8e 100644 --- a/flutter/lib/data/environment/environment_info.dart +++ b/flutter/lib/data/environment/environment_info.dart @@ -3,6 +3,7 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:mlperfbench/data/environment/env_android.dart'; import 'package:mlperfbench/data/environment/env_ios.dart'; import 'package:mlperfbench/data/environment/env_windows.dart'; +import 'package:mlperfbench/ui/formatter.dart'; part 'environment_info.g.dart'; @@ -54,7 +55,7 @@ class EnvironmentInfo { if (android == null) { return 'Unknown Android device'; } - return '${android.manufacturer} ${android.modelName}'; + return '${android.manufacturer} ${android.modelName}'.toUIString(); case EnvPlatform.ios: final ios = value.ios; if (ios == null) { diff --git a/flutter/lib/ui/app_styles.dart b/flutter/lib/ui/app_styles.dart new file mode 100644 index 000000000..6c14b8f13 --- /dev/null +++ b/flutter/lib/ui/app_styles.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; + +import 'package:mlperfbench/app_constants.dart'; + +class AppColors { + AppColors._(); + + static const _blue1 = Color(0XFF2C92CB); + static const _blue2 = Color(0XFF2980B7); + static const _blue3 = Color(0XFF166299); + static const _blue4 = Color(0XFF135384); + static const _blue5 = Color(0xFF0B3A61); + static const _green = Color(0xFF41C555); + static const _brown = Colors.brown; + + static const lightText = Colors.white; + static const darkText = Colors.black; + static const resultValidText = Colors.indigo; + static const resultInvalidText = Colors.red; + static const errorText = Colors.red; + + static const primary = _blue2; + static const secondary = _blue1; + + static const primaryAppBarBackground = + DartDefine.isOfficialBuild ? _blue3 : _brown; + static const secondaryAppBarBackground = + DartDefine.isOfficialBuild ? _blue1 : _brown; + static const appBarIcon = Colors.white; + static const drawerBackground = _blue4; + static const drawerForeground = Colors.white; + static const dialogBackground = Colors.white; + static const shareTextButton = _blue2; + static const shareSectionBackground = _blue4; + static const infoSectionBackground = _blue5; + static const progressCircle = _blue4; + static const goCircle = _green; +} + +class AppGradients { + AppGradients._(); + + static List fullScreen = [ + AppColors._blue1, + AppColors._blue2, + AppColors._blue3, + AppColors._blue4, + ]; + + static List halfScreen = [ + AppColors._blue1, + AppColors._blue2, + AppColors._blue3, + ]; + + static List get scoreBar => [ + AppColors._blue3, + AppColors._blue2, + AppColors._blue1, + ]; +} + +class WidgetSizes { + WidgetSizes._(); + + static const circleWidthFactor = 0.32; + static const borderRadius = 8.0; +} diff --git a/flutter/lib/ui/confirm_dialog.dart b/flutter/lib/ui/confirm_dialog.dart index 52dc5a879..7946b9c84 100644 --- a/flutter/lib/ui/confirm_dialog.dart +++ b/flutter/lib/ui/confirm_dialog.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; enum ConfirmDialogAction { ok, cancel } diff --git a/flutter/lib/ui/error_dialog.dart b/flutter/lib/ui/error_dialog.dart index 1691e5745..c5deb5d3e 100644 --- a/flutter/lib/ui/error_dialog.dart +++ b/flutter/lib/ui/error_dialog.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; enum DialogTypeEnum { error, warning, success } diff --git a/flutter/lib/ui/formatter.dart b/flutter/lib/ui/formatter.dart index b18e7e6bb..cc393c698 100644 --- a/flutter/lib/ui/formatter.dart +++ b/flutter/lib/ui/formatter.dart @@ -25,3 +25,9 @@ extension DateTimeFormat on DateTime { return dateFormat.format(this); } } + +extension StringFormat on String { + String toUIString() { + return toBeginningOfSentenceCase(this) ?? this; + } +} diff --git a/flutter/lib/ui/history/history_list_item.dart b/flutter/lib/ui/history/history_list_item.dart index 433d1f6ce..2a3ac8fe4 100644 --- a/flutter/lib/ui/history/history_list_item.dart +++ b/flutter/lib/ui/history/history_list_item.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/data/results/benchmark_result.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/formatter.dart'; import 'package:mlperfbench/ui/history/list_item.dart'; import 'package:mlperfbench/ui/icons.dart'; @@ -53,7 +53,7 @@ class HistoryListItem implements ListItem { style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 16.0, - color: AppColors.resultValid, + color: AppColors.resultValidText, ), ), ), diff --git a/flutter/lib/ui/history/utils.dart b/flutter/lib/ui/history/utils.dart index 132d89dc7..680b37e20 100644 --- a/flutter/lib/ui/history/utils.dart +++ b/flutter/lib/ui/history/utils.dart @@ -3,11 +3,11 @@ import 'package:flutter/services.dart'; import 'package:bot_toast/bot_toast.dart'; -import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/data/environment/env_android.dart'; import 'package:mlperfbench/data/environment/environment_info.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; class HistoryHelperUtils { final AppLocalizations l10n; @@ -92,7 +92,7 @@ class HistoryHelperUtils { final style = rowData.isHeader ? headerStyle : rowStyle; final perfStyle = rowData.throughputValid ? style - : const TextStyle(color: AppColors.darkRedText); + : const TextStyle(color: AppColors.resultInvalidText); final firstColumnText = Text(rowData.name, style: style); final firstColumn = rowData.isHeader ? firstColumnText diff --git a/flutter/lib/ui/home/app_drawer.dart b/flutter/lib/ui/home/app_drawer.dart index 55c71209c..9fceb08a1 100644 --- a/flutter/lib/ui/home/app_drawer.dart +++ b/flutter/lib/ui/home/app_drawer.dart @@ -5,6 +5,7 @@ import 'package:url_launcher/url_launcher.dart'; import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/history/history_list_screen.dart'; import 'package:mlperfbench/ui/home/user_profile.dart'; import 'package:mlperfbench/ui/settings/about_screen.dart'; @@ -18,8 +19,26 @@ class AppDrawer extends StatelessWidget { final header = buildHeader(context); final menuList = buildMenuList(context); return Drawer( - child: Column( - children: [header] + menuList, + child: Theme( + data: Theme.of(context).copyWith( + textTheme: Theme.of(context).textTheme.apply( + bodyColor: AppColors.drawerForeground, + displayColor: AppColors.drawerForeground, + decorationColor: AppColors.drawerForeground, + ), + listTileTheme: const ListTileThemeData( + iconColor: AppColors.drawerForeground, + ), + iconTheme: const IconThemeData( + color: AppColors.drawerForeground, + ), + ), + child: Container( + color: AppColors.drawerBackground, + child: Column( + children: [header] + menuList, + ), + ), ), ); } diff --git a/flutter/lib/ui/home/benchmark_config_section.dart b/flutter/lib/ui/home/benchmark_config_section.dart index 1d82fa7e7..2f18c4cfb 100644 --- a/flutter/lib/ui/home/benchmark_config_section.dart +++ b/flutter/lib/ui/home/benchmark_config_section.dart @@ -3,10 +3,10 @@ import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; import 'package:provider/provider.dart'; -import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/benchmark.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/home/benchmark_info_button.dart'; class BenchmarkConfigSection extends StatefulWidget { @@ -54,7 +54,10 @@ class _BenchmarkConfigSectionState extends State { leading: SizedBox( width: leadingWidth, height: leadingWidth, - child: benchmark.info.icon), + child: Padding( + padding: const EdgeInsets.all(4), + child: benchmark.info.icon, + )), title: _name(benchmark), subtitle: SizedBox( width: subtitleWidth, diff --git a/flutter/lib/ui/home/benchmark_result_screen.dart b/flutter/lib/ui/home/benchmark_result_screen.dart index e58037fc2..54beb72b9 100644 --- a/flutter/lib/ui/home/benchmark_result_screen.dart +++ b/flutter/lib/ui/home/benchmark_result_screen.dart @@ -7,13 +7,13 @@ import 'package:mlperfbench/benchmark/benchmark.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/device_info.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/confirm_dialog.dart'; import 'package:mlperfbench/ui/formatter.dart'; import 'package:mlperfbench/ui/home/app_drawer.dart'; import 'package:mlperfbench/ui/home/benchmark_info_button.dart'; import 'package:mlperfbench/ui/home/result_circle.dart'; import 'package:mlperfbench/ui/home/share_button.dart'; -import 'package:mlperfbench/ui/home/shared_styles.dart'; enum _ScreenMode { performance, accuracy } @@ -74,9 +74,9 @@ class _BenchmarkResultScreenState extends State title: Text(title), bottom: PreferredSize( preferredSize: const Size.fromHeight(56.0), - child: _sharingSection(), + child: _shareSection(), ), - backgroundColor: AppColors.lightBlue, + backgroundColor: AppColors.secondaryAppBarBackground, ), drawer: const AppDrawer(), body: LayoutBuilder( @@ -97,7 +97,7 @@ class _BenchmarkResultScreenState extends State ); } - Widget _sharingSection() { + Widget _shareSection() { final lastResult = state.lastResult; Text deviceInfoText; Text benchmarkDateText; @@ -142,8 +142,8 @@ class _BenchmarkResultScreenState extends State }, ); return Container( - padding: const EdgeInsets.fromLTRB(20, 8, 10, 8), - color: AppColors.mediumBlue, + padding: const EdgeInsets.fromLTRB(20, 4, 10, 4), + color: AppColors.shareSectionBackground, child: DefaultTextStyle.merge( style: const TextStyle(color: Colors.white), child: Row( @@ -162,7 +162,13 @@ class _BenchmarkResultScreenState extends State Widget _totalScoreSection() { return Container( - decoration: mainLinearGradientDecoration, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: AppGradients.halfScreen, + ), + ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, @@ -243,7 +249,9 @@ class _BenchmarkResultScreenState extends State var subtitleColumnChildren = []; subtitleColumnChildren.add(const SizedBox(height: 4)); final resultTextStyle = TextStyle( - color: resultIsValid ? AppColors.resultValid : AppColors.resultInvalid, + color: resultIsValid + ? AppColors.resultValidText + : AppColors.resultInvalidText, fontSize: 18.0, fontWeight: FontWeight.bold, ); @@ -302,7 +310,10 @@ class _BenchmarkResultScreenState extends State leading: SizedBox( width: leadingWidth, height: leadingWidth, - child: benchmark.info.icon), + child: Padding( + padding: const EdgeInsets.all(8), + child: benchmark.info.icon, + )), title: SizedBox( width: subtitleWidth, child: Text(benchmark.taskConfig.name), @@ -357,15 +368,14 @@ class BlueProgressLine extends Container { widthFactor: _progressValue, child: Container( alignment: Alignment.topLeft, - margin: const EdgeInsets.only(bottom: 10.0), - height: 10, + margin: const EdgeInsets.only(bottom: 8.0), + height: 8.0, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), + borderRadius: BorderRadius.circular(4.0), gradient: LinearGradient( - colors: AppColors.resultBarGradient, + colors: AppGradients.scoreBar, begin: Alignment.topLeft, - end: Alignment(1 / _progressValue, 0), - stops: const [0, 0.36, 0.61, 0.83, 1.0], + end: Alignment.bottomRight, ), ), ), diff --git a/flutter/lib/ui/home/benchmark_running_screen.dart b/flutter/lib/ui/home/benchmark_running_screen.dart index 8b2e9163c..0829f9694 100644 --- a/flutter/lib/ui/home/benchmark_running_screen.dart +++ b/flutter/lib/ui/home/benchmark_running_screen.dart @@ -6,12 +6,12 @@ import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; import 'package:provider/provider.dart'; -import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/info.dart'; import 'package:mlperfbench/benchmark/run_mode.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/state/task_runner.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/formatter.dart'; import 'package:mlperfbench/ui/home/progress_circles.dart'; import 'package:mlperfbench/ui/icons.dart'; @@ -39,7 +39,7 @@ class _BenchmarkRunningScreenState extends State { final backgroundGradient = BoxDecoration( gradient: LinearGradient( - colors: AppColors.progressScreenGradient, + colors: AppGradients.fullScreen, begin: Alignment.topCenter, end: Alignment.bottomCenter, ), @@ -96,14 +96,10 @@ class _BenchmarkRunningScreenState extends State { Container( width: containerWidth, height: containerWidth, - decoration: BoxDecoration( + decoration: const BoxDecoration( shape: BoxShape.circle, - gradient: LinearGradient( - colors: AppColors.progressCircleGradient, - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - boxShadow: const [ + color: AppColors.progressCircle, + boxShadow: [ BoxShadow( color: Colors.black12, offset: Offset(15, 15), @@ -218,7 +214,7 @@ class _BenchmarkRunningScreenState extends State { } return ListTile( contentPadding: const EdgeInsets.symmetric(vertical: 0, horizontal: 32), - tileColor: isEven ? AppColors.mediumBlue : Colors.transparent, + tileColor: isEven ? AppColors.progressCircle : Colors.transparent, textColor: AppColors.lightText, dense: true, minVerticalPadding: 0, @@ -284,8 +280,6 @@ class _BenchmarkRunningScreenState extends State { padding: const EdgeInsets.fromLTRB(20, 10, 20, 20), child: TextButton( style: ButtonStyle( - backgroundColor: - MaterialStateProperty.all(AppColors.progressCancelButton), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(18.0), diff --git a/flutter/lib/ui/home/benchmark_start_screen.dart b/flutter/lib/ui/home/benchmark_start_screen.dart index ba58eedd6..af0955fae 100644 --- a/flutter/lib/ui/home/benchmark_start_screen.dart +++ b/flutter/lib/ui/home/benchmark_start_screen.dart @@ -7,11 +7,11 @@ import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/device_info.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/store.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/confirm_dialog.dart'; import 'package:mlperfbench/ui/error_dialog.dart'; import 'package:mlperfbench/ui/home/app_drawer.dart'; import 'package:mlperfbench/ui/home/benchmark_config_section.dart'; -import 'package:mlperfbench/ui/home/shared_styles.dart'; class BenchmarkStartScreen extends StatefulWidget { const BenchmarkStartScreen({Key? key}) : super(key: key); @@ -34,7 +34,7 @@ class _BenchmarkStartScreenState extends State { return Scaffold( appBar: AppBar( title: Text(l10n.menuHome), - backgroundColor: AppColors.lightBlue, + backgroundColor: AppColors.secondaryAppBarBackground, ), drawer: const AppDrawer(), body: SafeArea( @@ -43,11 +43,11 @@ class _BenchmarkStartScreenState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( - flex: 32, + flex: 34, child: _goButtonSection(context), ), Expanded( - flex: 8, + flex: 6, child: _infoSection(), ), Expanded( @@ -75,9 +75,9 @@ class _BenchmarkStartScreenState extends State { .replaceAll('', totalCount); var deviceDescription = DeviceInfo.instance.envInfo.modelDescription; return Container( - padding: const EdgeInsets.fromLTRB(20, 8, 10, 8), + padding: const EdgeInsets.fromLTRB(20, 4, 10, 4), width: double.infinity, - color: AppColors.mediumBlue, + color: AppColors.infoSectionBackground, child: DefaultTextStyle.merge( style: const TextStyle(color: Colors.white, fontSize: 14), child: Column( @@ -85,7 +85,6 @@ class _BenchmarkStartScreenState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded(flex: 1, child: Text(deviceDescription)), - const SizedBox(height: 4), Expanded(flex: 1, child: Text(selectedBenchmarkText)) ], ), @@ -103,14 +102,20 @@ class _BenchmarkStartScreenState extends State { Container( width: MediaQuery.of(context).size.width, alignment: Alignment.center, - decoration: mainLinearGradientDecoration, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: AppGradients.halfScreen, + ), + ), ), Container( alignment: Alignment.center, child: ElevatedButton( key: const Key(WidgetKeys.goButton), style: ElevatedButton.styleFrom( - backgroundColor: Colors.green, + backgroundColor: AppColors.goCircle, shape: const CircleBorder(), minimumSize: Size.fromWidth(circleWidth)), child: Text( diff --git a/flutter/lib/ui/home/resource_loading_screen.dart b/flutter/lib/ui/home/resource_loading_screen.dart index 1f54c2c29..b114cdede 100644 --- a/flutter/lib/ui/home/resource_loading_screen.dart +++ b/flutter/lib/ui/home/resource_loading_screen.dart @@ -2,9 +2,9 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; class ResourceLoadingScreen extends StatefulWidget { const ResourceLoadingScreen({super.key}); @@ -22,58 +22,32 @@ class _ResourceLoadingScreenState extends State { final l10n = AppLocalizations.of(context); final loadingProgressText = '${(state.loadingProgress * 100).round()}%'; - final progressCircle = Stack( - alignment: AlignmentDirectional.center, - children: [ - Center( - child: Container( - width: progressCircleEdgeSize, - height: progressCircleEdgeSize, - decoration: BoxDecoration( - shape: BoxShape.circle, - gradient: LinearGradient( - colors: AppColors.progressCircleGradient, - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - boxShadow: const [ - BoxShadow( - color: Colors.black12, - offset: Offset(15, 15), - blurRadius: 10, - ) - ], - ), - child: Center( - child: Text( - loadingProgressText, - style: const TextStyle( - fontWeight: FontWeight.bold, - color: AppColors.lightText, - ), - textScaleFactor: 2, - ), - ), - ), + final progressCircle = Center( + child: Container( + width: progressCircleEdgeSize, + height: progressCircleEdgeSize, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: AppColors.progressCircle, + boxShadow: [ + BoxShadow( + color: Colors.black12, + offset: Offset(15, 15), + blurRadius: 10, + ) + ], ), - Center( - child: Container( - width: MediaQuery.of(context).size.width * 0.35, - alignment: Alignment.center, - decoration: const BoxDecoration( - shape: BoxShape.circle, - color: AppColors.progressCircle, - boxShadow: [ - BoxShadow( - color: Colors.black12, - offset: Offset(15, 15), - blurRadius: 10, - ) - ], + child: Center( + child: Text( + loadingProgressText, + style: const TextStyle( + fontWeight: FontWeight.bold, + color: AppColors.lightText, ), + textScaleFactor: 2, ), ), - ], + ), ); final statusText = Padding( @@ -104,7 +78,7 @@ class _ResourceLoadingScreenState extends State { final backgroundGradient = BoxDecoration( gradient: LinearGradient( - colors: AppColors.progressScreenGradient, + colors: AppGradients.fullScreen, begin: Alignment.topCenter, end: Alignment.bottomCenter, ), diff --git a/flutter/lib/ui/home/result_circle.dart b/flutter/lib/ui/home/result_circle.dart index e0d2fa918..67dc21ee1 100644 --- a/flutter/lib/ui/home/result_circle.dart +++ b/flutter/lib/ui/home/result_circle.dart @@ -2,7 +2,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; -import 'package:mlperfbench/app_constants.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/icons.dart' as app_icons; class ResultCircle extends StatefulWidget { @@ -63,14 +63,10 @@ class _ResultCircleState extends State margin: const EdgeInsets.only(bottom: 20.0), width: edgeSize, height: edgeSize, - decoration: BoxDecoration( + decoration: const BoxDecoration( shape: BoxShape.circle, - gradient: LinearGradient( - colors: AppColors.resultCircleGradient, - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - boxShadow: const [ + color: AppColors.progressCircle, + boxShadow: [ BoxShadow( color: Colors.black12, offset: Offset(15, 15), diff --git a/flutter/lib/ui/home/share_button.dart b/flutter/lib/ui/home/share_button.dart index f85259dd5..4b5495bc6 100644 --- a/flutter/lib/ui/home/share_button.dart +++ b/flutter/lib/ui/home/share_button.dart @@ -3,10 +3,10 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:share_plus/share_plus.dart'; -import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/home/user_profile.dart'; enum _ShareDestination { local, cloud } @@ -95,7 +95,7 @@ class _ShareButton extends State { const SizedBox(width: 20), Text( l10n.shareButtonOther, - style: TextStyle( + style: const TextStyle( color: AppColors.shareTextButton, fontSize: 18, ), @@ -120,7 +120,7 @@ class _ShareButton extends State { const SizedBox(width: 20), Text( l10n.shareButtonMLCommons, - style: TextStyle( + style: const TextStyle( color: AppColors.shareTextButton, fontSize: 18, ), @@ -155,8 +155,8 @@ class _ShareButton extends State { children: [ Text( l10n.shareButtonMLCommons, - style: - TextStyle(color: AppColors.shareTextButton, fontSize: 18), + style: const TextStyle( + color: AppColors.shareTextButton, fontSize: 18), ), const SizedBox(height: 20), Text(l10n.uploadRequiredSignedIn), diff --git a/flutter/lib/ui/home/shared_styles.dart b/flutter/lib/ui/home/shared_styles.dart deleted file mode 100644 index dc1568dab..000000000 --- a/flutter/lib/ui/home/shared_styles.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:mlperfbench/app_constants.dart'; - -const mainLinearGradientDecoration = BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - AppColors.lightBlue, - AppColors.darkBlue, - ], - ), -); diff --git a/flutter/lib/ui/icons.dart b/flutter/lib/ui/icons.dart index 078c16d26..edc1dcc80 100644 --- a/flutter/lib/ui/icons.dart +++ b/flutter/lib/ui/icons.dart @@ -5,11 +5,6 @@ import 'package:flutter_svg/svg.dart'; import 'package:mlperfbench/app_constants.dart'; class AppIcons { - static SvgPicture _pSvgWhite(String name) { - const colorFilter = ColorFilter.mode(Colors.white, BlendMode.srcIn); - return SvgPicture.asset('assets/icons/$name', colorFilter: colorFilter); - } - static SvgPicture _pSvgBlack(String name) { const colorFilter = ColorFilter.mode(Colors.black, BlendMode.srcIn); return SvgPicture.asset('assets/icons/$name', colorFilter: colorFilter); @@ -20,28 +15,30 @@ class AppIcons { } static final SvgPicture imageClassification = - _pSvg('ic_image_classification.svg'); + _pSvg('ic_task_image_classification.svg'); static final SvgPicture imageSegmentation = - _pSvg('ic_image_segmentation.svg'); - static final SvgPicture objectDetection = _pSvg('ic_object_detection.svg'); + _pSvg('ic_task_image_segmentation.svg'); + static final SvgPicture objectDetection = + _pSvg('ic_task_object_detection.svg'); static final SvgPicture languageProcessing = - _pSvg('ic_language_processing.svg'); + _pSvg('ic_task_language_processing.svg'); static final SvgPicture imageClassificationOffline = - _pSvg('ic_image_classification_offline.svg'); - static final SvgPicture superResolution = _pSvg('ic_super_resolution.svg'); + _pSvg('ic_task_image_classification_offline.svg'); + static final SvgPicture superResolution = + _pSvg('ic_task_super_resolution.svg'); static final SvgPicture imageClassificationWhite = - _pSvgWhite('ic_image_classification.svg'); + _pSvg('ic_task_image_classification_white.svg'); static final SvgPicture imageSegmentationWhite = - _pSvgWhite('ic_image_segmentation.svg'); + _pSvg('ic_task_image_segmentation_white.svg'); static final SvgPicture objectDetectionWhite = - _pSvgWhite('ic_object_detection.svg'); + _pSvg('ic_task_object_detection_white.svg'); static final SvgPicture languageProcessingWhite = - _pSvgWhite('ic_language_processing.svg'); + _pSvg('ic_task_language_processing_white.svg'); static final SvgPicture imageClassificationOfflineWhite = - _pSvg('ic_image_classification_offline_white.svg'); + _pSvg('ic_task_image_classification_offline_white.svg'); static final SvgPicture superResolutionWhite = - _pSvgWhite('ic_super_resolution.svg'); + _pSvg('ic_task_super_resolution_white.svg'); static final SvgPicture arrow = _pSvg('ic_arrow.svg'); diff --git a/flutter/lib/ui/root/app.dart b/flutter/lib/ui/root/app.dart index 091e77368..210a0e4f2 100644 --- a/flutter/lib/ui/root/app.dart +++ b/flutter/lib/ui/root/app.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:bot_toast/bot_toast.dart'; -import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; class MyApp extends StatelessWidget { final Widget home; @@ -18,11 +18,15 @@ class MyApp extends StatelessWidget { localizationsDelegates: const [AppLocalizations.delegate], supportedLocales: const [Locale('en', '')], theme: Theme.of(context).copyWith( + colorScheme: ColorScheme.fromSwatch().copyWith( + primary: AppColors.primary, + secondary: AppColors.secondary, + ), appBarTheme: const AppBarTheme( centerTitle: true, titleTextStyle: TextStyle(color: AppColors.lightText, fontSize: 20), elevation: 0, - backgroundColor: AppColors.appBarBackground, + backgroundColor: AppColors.primaryAppBarBackground, iconTheme: IconThemeData(color: AppColors.appBarIcon), ), popupMenuTheme: PopupMenuThemeData( diff --git a/flutter/lib/ui/root/exception_screen.dart b/flutter/lib/ui/root/exception_screen.dart index 8cf70e0b3..00df4c101 100644 --- a/flutter/lib/ui/root/exception_screen.dart +++ b/flutter/lib/ui/root/exception_screen.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:mlperfbench/app_constants.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; class ExceptionWidget extends StatelessWidget { final Object error; diff --git a/flutter/lib/ui/root/resource_error_screen.dart b/flutter/lib/ui/root/resource_error_screen.dart index 809902e09..db10b33d3 100644 --- a/flutter/lib/ui/root/resource_error_screen.dart +++ b/flutter/lib/ui/root/resource_error_screen.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:mlperfbench/app_constants.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/store.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/error_dialog.dart'; import 'package:mlperfbench/ui/icons.dart' show AppIcons; import 'package:mlperfbench/ui/page_constraints.dart'; @@ -50,7 +50,7 @@ class ResourceErrorScreen extends StatelessWidget { textAlign: TextAlign.center, style: const TextStyle( fontSize: 15, - color: AppColors.darkRedText, + color: AppColors.errorText, ), ), Text( diff --git a/flutter/lib/ui/settings/settings_screen.dart b/flutter/lib/ui/settings/settings_screen.dart index 426f0fa67..48559e60f 100644 --- a/flutter/lib/ui/settings/settings_screen.dart +++ b/flutter/lib/ui/settings/settings_screen.dart @@ -12,6 +12,7 @@ import 'package:mlperfbench/firebase/firebase_manager.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/resources/config_manager.dart'; import 'package:mlperfbench/store.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/confirm_dialog.dart'; import 'package:mlperfbench/ui/settings/task_config_section.dart'; diff --git a/flutter/lib/ui/settings/snack_bar.dart b/flutter/lib/ui/settings/snack_bar.dart deleted file mode 100644 index 4846efecb..000000000 --- a/flutter/lib/ui/settings/snack_bar.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:mlperfbench/app_constants.dart'; - -SnackBar getSnackBar(String message) => SnackBar( - duration: const Duration(seconds: 2), - backgroundColor: AppColors.snackBarBackground, - content: Text( - message, - textAlign: TextAlign.center, - style: const TextStyle(color: AppColors.darkText), - ), - ); diff --git a/flutter/lib/ui/settings/task_config_section.dart b/flutter/lib/ui/settings/task_config_section.dart index 93c23ffd7..ebea3f0b6 100644 --- a/flutter/lib/ui/settings/task_config_section.dart +++ b/flutter/lib/ui/settings/task_config_section.dart @@ -11,6 +11,7 @@ import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; import 'package:mlperfbench/resources/config_manager.dart'; import 'package:mlperfbench/store.dart'; +import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/error_dialog.dart'; import 'package:mlperfbench/ui/settings/data_folder_type.dart'; @@ -121,7 +122,7 @@ class _DataFolderSelectorHelper { return Text( l10n.settingsTaskDataFolderWarning .replaceFirst('', store.customDataFolder), - style: const TextStyle(color: AppColors.darkRedText), + style: const TextStyle(color: AppColors.errorText), ); } return const SizedBox.shrink(); From fa6889b7ab6e2bf45be141dd126b0d54a7801f3a Mon Sep 17 00:00:00 2001 From: RSMNYS Date: Tue, 30 Jan 2024 09:33:21 +0200 Subject: [PATCH 17/17] fix: fixed dependabot security alerts for react app (#847) --- react/package.json | 5 +++++ react/yarn.lock | 29 +++++++++-------------------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/react/package.json b/react/package.json index 476d72ad2..28a902016 100644 --- a/react/package.json +++ b/react/package.json @@ -78,5 +78,10 @@ "devDependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "prettier": "^3.1.0" + }, + "resolutions": { + "react-scripts/@svgr/webpack/@svgr/plugin-svgo/svgo/css-select/nth-check": "^2.1.1", + "react-scripts/resolve-url-loader/postcss": "^8.4.31" } + } diff --git a/react/yarn.lock b/react/yarn.lock index bf4574a99..8af99bbaa 100644 --- a/react/yarn.lock +++ b/react/yarn.lock @@ -4590,7 +4590,7 @@ bonjour-service@^1.0.11: fast-deep-equal "^3.1.3" multicast-dns "^7.2.5" -boolbase@^1.0.0, boolbase@~1.0.0: +boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== @@ -8454,14 +8454,7 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -nth-check@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== - dependencies: - boolbase "~1.0.0" - -nth-check@^2.0.1: +nth-check@^1.0.2, nth-check@^2.0.1, nth-check@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== @@ -8762,11 +8755,6 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -9336,13 +9324,14 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^7.0.35: - version "7.0.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== +postcss@^7.0.35, postcss@^8.4.31: + version "8.4.33" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.33.tgz#1378e859c9f69bf6f638b990a0212f43e2aaa742" + integrity sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg== dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.0.2" postcss@^8.3.5, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.4: version "8.4.32"