From 06137a4acd5f97f129ca7c91b12b192e867faa59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 06:40:56 +0000 Subject: [PATCH 01/30] Bump intl from 0.19.0 to 0.20.0 in /background_isolate_channels (#2484) Bumps [intl](https://github.com/dart-lang/i18n/tree/main/pkgs) from 0.19.0 to 0.20.0.
Release notes

Sourced from intl's releases.

package:intl v0.20.0

package:intl_translation v0.20.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=intl&package-manager=pub&previous-version=0.19.0&new-version=0.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- background_isolate_channels/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/background_isolate_channels/pubspec.yaml b/background_isolate_channels/pubspec.yaml index 24e78dd9f..9b0d4c2e5 100644 --- a/background_isolate_channels/pubspec.yaml +++ b/background_isolate_channels/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: cupertino_icons: ^1.0.2 flutter: sdk: flutter - intl: ^0.19.0 + intl: ^0.20.0 path: ^1.8.2 path_provider: ^2.0.11 shared_preferences: ^2.0.15 From 55e4254e70306daed6038a0b360e3ea64b459d2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 06:43:17 +0000 Subject: [PATCH 02/30] Bump intl from 0.19.0 to 0.20.0 in /form_app (#2485) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- Bumps [intl](https://github.com/dart-lang/i18n/tree/main/pkgs) from 0.19.0 to 0.20.0.
Release notes

Sourced from intl's releases.

package:intl v0.20.0

package:intl_translation v0.20.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=intl&package-manager=pub&previous-version=0.19.0&new-version=0.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- form_app/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/form_app/pubspec.yaml b/form_app/pubspec.yaml index ce5df21e9..29fd73b0e 100644 --- a/form_app/pubspec.yaml +++ b/form_app/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.0 - intl: ^0.19.0 + intl: ^0.20.0 http: ^1.0.0 json_annotation: any english_words: ^4.0.0 From d63686c3d9b505008d1adffed5ce98dac141da21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 07:14:21 +0000 Subject: [PATCH 03/30] Bump intl from 0.19.0 to 0.20.0 in /veggieseasons (#2486) Bumps [intl](https://github.com/dart-lang/i18n/tree/main/pkgs) from 0.19.0 to 0.20.0.
Release notes

Sourced from intl's releases.

package:intl v0.20.0

package:intl_translation v0.20.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=intl&package-manager=pub&previous-version=0.19.0&new-version=0.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- veggieseasons/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/veggieseasons/pubspec.yaml b/veggieseasons/pubspec.yaml index 06589a2d3..05e546d29 100644 --- a/veggieseasons/pubspec.yaml +++ b/veggieseasons/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: cupertino_icons: ^1.0.2 font_awesome_flutter: ^10.1.0 - intl: ^0.19.0 + intl: ^0.20.0 provider: ^6.0.1 shared_preferences: ^2.0.14 window_size: From 6921283923face1085dacc8a9b5c138a63fa42ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 07:44:39 +0000 Subject: [PATCH 04/30] Bump intl from 0.19.0 to 0.20.0 in /experimental/pedometer/example (#2487) Bumps [intl](https://github.com/dart-lang/i18n/tree/main/pkgs) from 0.19.0 to 0.20.0.
Release notes

Sourced from intl's releases.

package:intl v0.20.0

package:intl_translation v0.20.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=intl&package-manager=pub&previous-version=0.19.0&new-version=0.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- experimental/pedometer/example/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/pedometer/example/pubspec.yaml b/experimental/pedometer/example/pubspec.yaml index fc2874ab9..a13852bd9 100644 --- a/experimental/pedometer/example/pubspec.yaml +++ b/experimental/pedometer/example/pubspec.yaml @@ -40,7 +40,7 @@ dependencies: path: ../ ffi: ^2.1.2 - intl: ^0.19.0 + intl: ^0.20.0 jni: ^0.12.0 fl_chart: ^0.69.0 From 36b4e6e6027d14c89e009212286c393877e90f3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 07:16:22 +0000 Subject: [PATCH 05/30] Bump ffigen from 15.0.0 to 16.0.0 in /experimental/pedometer (#2489) Bumps [ffigen](https://github.com/dart-lang/native/tree/main/pkgs) from 15.0.0 to 16.0.0.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ffigen&package-manager=pub&previous-version=15.0.0&new-version=16.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- experimental/pedometer/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/pedometer/pubspec.yaml b/experimental/pedometer/pubspec.yaml index bc1455ecd..ef17df0a9 100644 --- a/experimental/pedometer/pubspec.yaml +++ b/experimental/pedometer/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: ffi: ^2.1.2 dev_dependencies: - ffigen: ^15.0.0 + ffigen: ^16.0.0 jnigen: ^0.12.1 flutter_test: sdk: flutter From 66ab725924cbcbcb6af3d8902dbc8da75a08df86 Mon Sep 17 00:00:00 2001 From: Eric Windmill Date: Fri, 22 Nov 2024 11:10:01 -0500 Subject: [PATCH 06/30] Remove io sample (#2490) This sample has been moved to my personal Github, because we shouldn't maintain samples that are tied to events. - Moved sample to personal repo - Removed sample from this repo - Updated README here and the link to this repo in the YouTube video --- ai_recipe_generation/.gitignore | 45 - ai_recipe_generation/.metadata | 45 - ai_recipe_generation/README.md | 21 +- ai_recipe_generation/analysis_options.yaml | 1 - ai_recipe_generation/android/.gitignore | 13 - ai_recipe_generation/android/app/build.gradle | 67 -- .../android/app/google-services.json | 29 - .../android/app/src/debug/AndroidManifest.xml | 7 - .../android/app/src/main/AndroidManifest.xml | 33 - .../example/gemini_io_talk/MainActivity.kt | 6 - .../res/drawable-v21/launch_background.xml | 12 - .../main/res/drawable/launch_background.xml | 12 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 544 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 442 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 721 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1031 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 1443 -> 0 bytes .../app/src/main/res/values-night/styles.xml | 18 - .../app/src/main/res/values/styles.xml | 18 - .../app/src/profile/AndroidManifest.xml | 7 - ai_recipe_generation/android/build.gradle | 30 - .../android/gradle.properties | 3 - .../gradle/wrapper/gradle-wrapper.properties | 5 - ai_recipe_generation/android/settings.gradle | 29 - ai_recipe_generation/assets/chef_cat.svg | 43 - .../assets/fridge_test_image.jpeg | Bin 34128 -> 0 bytes ai_recipe_generation/assets/user_icon.svg | 11 - ai_recipe_generation/ios/.gitignore | 34 - .../ios/Flutter/AppFrameworkInfo.plist | 26 - .../ios/Flutter/Debug.xcconfig | 2 - .../ios/Flutter/Release.xcconfig | 2 - ai_recipe_generation/ios/Podfile | 44 - .../ios/Runner.xcodeproj/project.pbxproj | 728 ---------------- .../contents.xcworkspacedata | 7 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/WorkspaceSettings.xcsettings | 8 - .../xcshareddata/xcschemes/Runner.xcscheme | 98 --- .../contents.xcworkspacedata | 10 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/WorkspaceSettings.xcsettings | 8 - .../ios/Runner/AppDelegate.swift | 13 - .../AppIcon.appiconset/Contents.json | 122 --- .../Icon-App-1024x1024@1x.png | Bin 10932 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 295 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 406 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 450 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 282 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 462 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 704 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 406 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 586 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 862 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 862 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 1674 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 762 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 1226 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 1418 -> 0 bytes .../LaunchImage.imageset/Contents.json | 23 - .../LaunchImage.imageset/LaunchImage.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/README.md | 5 - .../Runner/Base.lproj/LaunchScreen.storyboard | 37 - .../ios/Runner/Base.lproj/Main.storyboard | 26 - .../ios/Runner/GoogleService-Info.plist | 30 - ai_recipe_generation/ios/Runner/Info.plist | 59 -- .../ios/Runner/Runner-Bridging-Header.h | 1 - .../ios/RunnerTests/RunnerTests.swift | 12 - .../ios/firebase_app_id_file.json | 7 - ai_recipe_generation/lib/app_bar.dart | 160 ---- .../lib/features/prompt/prompt_model.dart | 66 -- .../lib/features/prompt/prompt_screen.dart | 391 --------- .../features/prompt/prompt_view_model.dart | 168 ---- .../widgets/app_info_dialog_widget.dart | 118 --- .../widgets/full_prompt_dialog_widget.dart | 112 --- .../prompt/widgets/image_input_widget.dart | 278 ------ .../lib/features/recipes/recipe_model.dart | 110 --- .../features/recipes/recipes_view_model.dart | 31 - .../recipes/saved_recipes_screen.dart | 263 ------ .../widgets/recipe_display_widget.dart | 277 ------ .../widgets/recipe_fullscreen_dialog.dart | 56 -- .../lib/firebase_options.dart | 81 -- ai_recipe_generation/lib/main.dart | 122 --- ai_recipe_generation/lib/router.dart | 244 ------ .../lib/services/firestore.dart | 25 - ai_recipe_generation/lib/services/gemini.dart | 58 -- ai_recipe_generation/lib/theme.dart | 134 --- .../lib/util/device_info.dart | 39 - ai_recipe_generation/lib/util/extensions.dart | 13 - .../lib/util/filter_chip_enums.dart | 66 -- .../lib/util/json_parsing.dart | 8 - .../lib/util/tap_recorder.dart | 121 --- .../lib/widgets/add_image_widget.dart | 85 -- .../lib/widgets/appbar_shape_border.dart | 52 -- .../lib/widgets/bottom_bar_shape_border.dart | 54 -- .../lib/widgets/cross_image_widget.dart | 41 - .../widgets/filter_chip_selection_input.dart | 89 -- .../highlight_border_on_hover_widget.dart | 51 -- .../lib/widgets/icon_loading_indicator.dart | 93 -- .../widgets/marketplace_button_widget.dart | 86 -- .../lib/widgets/prompt_image_widget.dart | 65 -- .../lib/widgets/star_rating.dart | 58 -- ai_recipe_generation/linux/.gitignore | 1 - ai_recipe_generation/linux/CMakeLists.txt | 145 ---- .../linux/flutter/CMakeLists.txt | 88 -- .../flutter/generated_plugin_registrant.cc | 15 - .../flutter/generated_plugin_registrant.h | 15 - .../linux/flutter/generated_plugins.cmake | 24 - ai_recipe_generation/linux/main.cc | 6 - ai_recipe_generation/linux/my_application.cc | 104 --- ai_recipe_generation/linux/my_application.h | 18 - ai_recipe_generation/macos/.gitignore | 7 - .../macos/Flutter/Flutter-Debug.xcconfig | 2 - .../macos/Flutter/Flutter-Release.xcconfig | 2 - .../Flutter/GeneratedPluginRegistrant.swift | 22 - ai_recipe_generation/macos/Podfile | 43 - .../macos/Runner.xcodeproj/project.pbxproj | 795 ------------------ .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/xcschemes/Runner.xcscheme | 98 --- .../contents.xcworkspacedata | 10 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../macos/Runner/AppDelegate.swift | 9 - .../AppIcon.appiconset/Contents.json | 68 -- .../AppIcon.appiconset/app_icon_1024.png | Bin 102994 -> 0 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 5680 -> 0 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 520 -> 0 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 14142 -> 0 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 1066 -> 0 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 36406 -> 0 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 2218 -> 0 bytes .../macos/Runner/Base.lproj/MainMenu.xib | 343 -------- .../macos/Runner/Configs/AppInfo.xcconfig | 14 - .../macos/Runner/Configs/Debug.xcconfig | 2 - .../macos/Runner/Configs/Release.xcconfig | 2 - .../macos/Runner/Configs/Warnings.xcconfig | 13 - .../macos/Runner/DebugProfile.entitlements | 16 - .../macos/Runner/GoogleService-Info.plist | 30 - ai_recipe_generation/macos/Runner/Info.plist | 36 - .../macos/Runner/MainFlutterWindow.swift | 15 - .../macos/Runner/Release.entitlements | 10 - .../macos/RunnerTests/RunnerTests.swift | 12 - .../macos/firebase_app_id_file.json | 7 - ai_recipe_generation/pubspec.yaml | 40 - ai_recipe_generation/web/favicon.png | Bin 917 -> 0 bytes ai_recipe_generation/web/icons/Icon-192.png | Bin 5292 -> 0 bytes ai_recipe_generation/web/icons/Icon-512.png | Bin 8252 -> 0 bytes .../web/icons/Icon-maskable-192.png | Bin 5594 -> 0 bytes .../web/icons/Icon-maskable-512.png | Bin 20998 -> 0 bytes ai_recipe_generation/web/index.html | 38 - ai_recipe_generation/web/manifest.json | 35 - ai_recipe_generation/windows/.gitignore | 17 - ai_recipe_generation/windows/CMakeLists.txt | 108 --- .../windows/flutter/CMakeLists.txt | 109 --- .../flutter/generated_plugin_registrant.cc | 20 - .../flutter/generated_plugin_registrant.h | 15 - .../windows/flutter/generated_plugins.cmake | 26 - .../windows/runner/CMakeLists.txt | 40 - ai_recipe_generation/windows/runner/Runner.rc | 121 --- .../windows/runner/flutter_window.cpp | 71 -- .../windows/runner/flutter_window.h | 33 - ai_recipe_generation/windows/runner/main.cpp | 43 - .../windows/runner/resource.h | 16 - .../windows/runner/resources/app_icon.ico | Bin 33772 -> 0 bytes .../windows/runner/runner.exe.manifest | 20 - ai_recipe_generation/windows/runner/utils.cpp | 65 -- ai_recipe_generation/windows/runner/utils.h | 19 - .../windows/runner/win32_window.cpp | 288 ------- .../windows/runner/win32_window.h | 102 --- tool/flutter_ci_script_beta.sh | 1 - tool/flutter_ci_script_master.sh | 1 - tool/flutter_ci_script_stable.sh | 1 - 171 files changed, 10 insertions(+), 8595 deletions(-) delete mode 100644 ai_recipe_generation/.gitignore delete mode 100644 ai_recipe_generation/.metadata delete mode 100644 ai_recipe_generation/analysis_options.yaml delete mode 100644 ai_recipe_generation/android/.gitignore delete mode 100644 ai_recipe_generation/android/app/build.gradle delete mode 100644 ai_recipe_generation/android/app/google-services.json delete mode 100644 ai_recipe_generation/android/app/src/debug/AndroidManifest.xml delete mode 100644 ai_recipe_generation/android/app/src/main/AndroidManifest.xml delete mode 100644 ai_recipe_generation/android/app/src/main/kotlin/com/example/gemini_io_talk/MainActivity.kt delete mode 100644 ai_recipe_generation/android/app/src/main/res/drawable-v21/launch_background.xml delete mode 100644 ai_recipe_generation/android/app/src/main/res/drawable/launch_background.xml delete mode 100644 ai_recipe_generation/android/app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 ai_recipe_generation/android/app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 ai_recipe_generation/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 ai_recipe_generation/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 ai_recipe_generation/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 ai_recipe_generation/android/app/src/main/res/values-night/styles.xml delete mode 100644 ai_recipe_generation/android/app/src/main/res/values/styles.xml delete mode 100644 ai_recipe_generation/android/app/src/profile/AndroidManifest.xml delete mode 100644 ai_recipe_generation/android/build.gradle delete mode 100644 ai_recipe_generation/android/gradle.properties delete mode 100644 ai_recipe_generation/android/gradle/wrapper/gradle-wrapper.properties delete mode 100644 ai_recipe_generation/android/settings.gradle delete mode 100644 ai_recipe_generation/assets/chef_cat.svg delete mode 100644 ai_recipe_generation/assets/fridge_test_image.jpeg delete mode 100644 ai_recipe_generation/assets/user_icon.svg delete mode 100644 ai_recipe_generation/ios/.gitignore delete mode 100644 ai_recipe_generation/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 ai_recipe_generation/ios/Flutter/Debug.xcconfig delete mode 100644 ai_recipe_generation/ios/Flutter/Release.xcconfig delete mode 100644 ai_recipe_generation/ios/Podfile delete mode 100644 ai_recipe_generation/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings delete mode 100644 ai_recipe_generation/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 ai_recipe_generation/ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings delete mode 100644 ai_recipe_generation/ios/Runner/AppDelegate.swift delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png delete mode 100644 ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md delete mode 100644 ai_recipe_generation/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 ai_recipe_generation/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 ai_recipe_generation/ios/Runner/GoogleService-Info.plist delete mode 100644 ai_recipe_generation/ios/Runner/Info.plist delete mode 100644 ai_recipe_generation/ios/Runner/Runner-Bridging-Header.h delete mode 100644 ai_recipe_generation/ios/RunnerTests/RunnerTests.swift delete mode 100644 ai_recipe_generation/ios/firebase_app_id_file.json delete mode 100644 ai_recipe_generation/lib/app_bar.dart delete mode 100644 ai_recipe_generation/lib/features/prompt/prompt_model.dart delete mode 100644 ai_recipe_generation/lib/features/prompt/prompt_screen.dart delete mode 100644 ai_recipe_generation/lib/features/prompt/prompt_view_model.dart delete mode 100644 ai_recipe_generation/lib/features/prompt/widgets/app_info_dialog_widget.dart delete mode 100644 ai_recipe_generation/lib/features/prompt/widgets/full_prompt_dialog_widget.dart delete mode 100644 ai_recipe_generation/lib/features/prompt/widgets/image_input_widget.dart delete mode 100644 ai_recipe_generation/lib/features/recipes/recipe_model.dart delete mode 100644 ai_recipe_generation/lib/features/recipes/recipes_view_model.dart delete mode 100644 ai_recipe_generation/lib/features/recipes/saved_recipes_screen.dart delete mode 100644 ai_recipe_generation/lib/features/recipes/widgets/recipe_display_widget.dart delete mode 100644 ai_recipe_generation/lib/features/recipes/widgets/recipe_fullscreen_dialog.dart delete mode 100644 ai_recipe_generation/lib/firebase_options.dart delete mode 100644 ai_recipe_generation/lib/main.dart delete mode 100644 ai_recipe_generation/lib/router.dart delete mode 100644 ai_recipe_generation/lib/services/firestore.dart delete mode 100644 ai_recipe_generation/lib/services/gemini.dart delete mode 100644 ai_recipe_generation/lib/theme.dart delete mode 100644 ai_recipe_generation/lib/util/device_info.dart delete mode 100644 ai_recipe_generation/lib/util/extensions.dart delete mode 100644 ai_recipe_generation/lib/util/filter_chip_enums.dart delete mode 100644 ai_recipe_generation/lib/util/json_parsing.dart delete mode 100644 ai_recipe_generation/lib/util/tap_recorder.dart delete mode 100644 ai_recipe_generation/lib/widgets/add_image_widget.dart delete mode 100644 ai_recipe_generation/lib/widgets/appbar_shape_border.dart delete mode 100644 ai_recipe_generation/lib/widgets/bottom_bar_shape_border.dart delete mode 100644 ai_recipe_generation/lib/widgets/cross_image_widget.dart delete mode 100644 ai_recipe_generation/lib/widgets/filter_chip_selection_input.dart delete mode 100644 ai_recipe_generation/lib/widgets/highlight_border_on_hover_widget.dart delete mode 100644 ai_recipe_generation/lib/widgets/icon_loading_indicator.dart delete mode 100644 ai_recipe_generation/lib/widgets/marketplace_button_widget.dart delete mode 100644 ai_recipe_generation/lib/widgets/prompt_image_widget.dart delete mode 100644 ai_recipe_generation/lib/widgets/star_rating.dart delete mode 100644 ai_recipe_generation/linux/.gitignore delete mode 100644 ai_recipe_generation/linux/CMakeLists.txt delete mode 100644 ai_recipe_generation/linux/flutter/CMakeLists.txt delete mode 100644 ai_recipe_generation/linux/flutter/generated_plugin_registrant.cc delete mode 100644 ai_recipe_generation/linux/flutter/generated_plugin_registrant.h delete mode 100644 ai_recipe_generation/linux/flutter/generated_plugins.cmake delete mode 100644 ai_recipe_generation/linux/main.cc delete mode 100644 ai_recipe_generation/linux/my_application.cc delete mode 100644 ai_recipe_generation/linux/my_application.h delete mode 100644 ai_recipe_generation/macos/.gitignore delete mode 100644 ai_recipe_generation/macos/Flutter/Flutter-Debug.xcconfig delete mode 100644 ai_recipe_generation/macos/Flutter/Flutter-Release.xcconfig delete mode 100644 ai_recipe_generation/macos/Flutter/GeneratedPluginRegistrant.swift delete mode 100644 ai_recipe_generation/macos/Podfile delete mode 100644 ai_recipe_generation/macos/Runner.xcodeproj/project.pbxproj delete mode 100644 ai_recipe_generation/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 ai_recipe_generation/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 ai_recipe_generation/macos/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 ai_recipe_generation/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 ai_recipe_generation/macos/Runner/AppDelegate.swift delete mode 100644 ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png delete mode 100644 ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png delete mode 100644 ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png delete mode 100644 ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png delete mode 100644 ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png delete mode 100644 ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png delete mode 100644 ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png delete mode 100644 ai_recipe_generation/macos/Runner/Base.lproj/MainMenu.xib delete mode 100644 ai_recipe_generation/macos/Runner/Configs/AppInfo.xcconfig delete mode 100644 ai_recipe_generation/macos/Runner/Configs/Debug.xcconfig delete mode 100644 ai_recipe_generation/macos/Runner/Configs/Release.xcconfig delete mode 100644 ai_recipe_generation/macos/Runner/Configs/Warnings.xcconfig delete mode 100644 ai_recipe_generation/macos/Runner/DebugProfile.entitlements delete mode 100644 ai_recipe_generation/macos/Runner/GoogleService-Info.plist delete mode 100644 ai_recipe_generation/macos/Runner/Info.plist delete mode 100644 ai_recipe_generation/macos/Runner/MainFlutterWindow.swift delete mode 100644 ai_recipe_generation/macos/Runner/Release.entitlements delete mode 100644 ai_recipe_generation/macos/RunnerTests/RunnerTests.swift delete mode 100644 ai_recipe_generation/macos/firebase_app_id_file.json delete mode 100644 ai_recipe_generation/pubspec.yaml delete mode 100644 ai_recipe_generation/web/favicon.png delete mode 100644 ai_recipe_generation/web/icons/Icon-192.png delete mode 100644 ai_recipe_generation/web/icons/Icon-512.png delete mode 100644 ai_recipe_generation/web/icons/Icon-maskable-192.png delete mode 100644 ai_recipe_generation/web/icons/Icon-maskable-512.png delete mode 100644 ai_recipe_generation/web/index.html delete mode 100644 ai_recipe_generation/web/manifest.json delete mode 100644 ai_recipe_generation/windows/.gitignore delete mode 100644 ai_recipe_generation/windows/CMakeLists.txt delete mode 100644 ai_recipe_generation/windows/flutter/CMakeLists.txt delete mode 100644 ai_recipe_generation/windows/flutter/generated_plugin_registrant.cc delete mode 100644 ai_recipe_generation/windows/flutter/generated_plugin_registrant.h delete mode 100644 ai_recipe_generation/windows/flutter/generated_plugins.cmake delete mode 100644 ai_recipe_generation/windows/runner/CMakeLists.txt delete mode 100644 ai_recipe_generation/windows/runner/Runner.rc delete mode 100644 ai_recipe_generation/windows/runner/flutter_window.cpp delete mode 100644 ai_recipe_generation/windows/runner/flutter_window.h delete mode 100644 ai_recipe_generation/windows/runner/main.cpp delete mode 100644 ai_recipe_generation/windows/runner/resource.h delete mode 100644 ai_recipe_generation/windows/runner/resources/app_icon.ico delete mode 100644 ai_recipe_generation/windows/runner/runner.exe.manifest delete mode 100644 ai_recipe_generation/windows/runner/utils.cpp delete mode 100644 ai_recipe_generation/windows/runner/utils.h delete mode 100644 ai_recipe_generation/windows/runner/win32_window.cpp delete mode 100644 ai_recipe_generation/windows/runner/win32_window.h diff --git a/ai_recipe_generation/.gitignore b/ai_recipe_generation/.gitignore deleted file mode 100644 index 86e0c2c5c..000000000 --- a/ai_recipe_generation/.gitignore +++ /dev/null @@ -1,45 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ -migrate_working_dir/ -.env - -# 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/ -**/ios/Flutter/.last_build_id -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.pub-cache/ -.pub/ -/build/ - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json - -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release diff --git a/ai_recipe_generation/.metadata b/ai_recipe_generation/.metadata deleted file mode 100644 index ff2d6f151..000000000 --- a/ai_recipe_generation/.metadata +++ /dev/null @@ -1,45 +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: "2e9cb0aa71a386a91f73f7088d115c0d96654829" - channel: "stable" - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: android - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: ios - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: linux - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: macos - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: web - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: windows - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ai_recipe_generation/README.md b/ai_recipe_generation/README.md index ca96ee952..1336a6878 100644 --- a/ai_recipe_generation/README.md +++ b/ai_recipe_generation/README.md @@ -1,17 +1,16 @@ -This is a demo app created for the Google I/O talk "Gemini API and Flutter: Practical, AI-driven apps with Google AI tools" +# Sample retired -Check out the [the prompt we used on Google AI Studio](https://aistudio.google.com/app/prompts/1RsTAt6_N8BPhXbrrd8gSJcdeuYV834kf). +The `ai_recipe_generation` sample has been retired. -## Running the app +The sample was written for an event (Google IO 2024). Per our policies, +we don't maintain samples that are tied to events. -Before running the app: -* Get an API key from [ai.google.dev](ai.google.dev). -* Create a Firebase project, and install the Flutter Firebase CLI, and configure the platforms that you want to run this app on. You can find instructions by following [steps 2-4 of the Get to know Firebase for Flutter](https://firebase.google.com/codelabs/firebase-get-to-know-flutter?hl=en#2) codelab. +This sample has been copied to [another repository](https://github.com/ericwindmill/gemini_recipe_generation). It will not be updated to reflect changes to Gemini. -Then, pass the API key in with dart define when running the app: - -```bash -flutter run --dart-define=API_KEY=your_api_key -``` +## Other Gemini resources +The following resources can assist you in integrating Gemini with Flutter: +* [gemini_tasks sample](https://github.com/flutter/samples/tree/main/gemini_tasks) is a Gemini sample in this repository. +* [google_generative_ai package](https://pub.dev/packages/google_generative_ai) is the package that Flutter apps use to integrate with gemini, and it has additional samples. +* The [google-gemini github](https://github.com/google-gemini) has additional Flutter samples. \ No newline at end of file diff --git a/ai_recipe_generation/analysis_options.yaml b/ai_recipe_generation/analysis_options.yaml deleted file mode 100644 index 1b30f7553..000000000 --- a/ai_recipe_generation/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: package:analysis_defaults/flutter.yaml \ No newline at end of file diff --git a/ai_recipe_generation/android/.gitignore b/ai_recipe_generation/android/.gitignore deleted file mode 100644 index 6f568019d..000000000 --- a/ai_recipe_generation/android/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java - -# Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app -key.properties -**/*.keystore -**/*.jks diff --git a/ai_recipe_generation/android/app/build.gradle b/ai_recipe_generation/android/app/build.gradle deleted file mode 100644 index 1d7d65b8b..000000000 --- a/ai_recipe_generation/android/app/build.gradle +++ /dev/null @@ -1,67 +0,0 @@ -plugins { - id "com.android.application" - id "kotlin-android" - id "dev.flutter.flutter-gradle-plugin" -} - -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -android { - namespace "com.example.gemini_io_talk" - compileSdkVersion flutter.compileSdkVersion - ndkVersion flutter.ndkVersion - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = '1.8' - } - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.gemini_io_talk" - // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion flutter.minSdkVersion - targetSdkVersion flutter.targetSdkVersion - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - } - - buildTypes { - release { - // 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 - } - } -} - -flutter { - source '../..' -} - -dependencies {} diff --git a/ai_recipe_generation/android/app/google-services.json b/ai_recipe_generation/android/app/google-services.json deleted file mode 100644 index 3cf8eab78..000000000 --- a/ai_recipe_generation/android/app/google-services.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "project_info": { - "project_number": "44885228795", - "project_id": "gemini-cat-chef", - "storage_bucket": "gemini-cat-chef.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:44885228795:android:d1ed69a5c617a8b98f845e", - "android_client_info": { - "package_name": "com.example.gemini_io_talk" - } - }, - "oauth_client": [], - "api_key": [ - { - "current_key": "AIzaSyANxBBzc4s-Yuol0xqs-mEtXe-pNcut3OU" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [] - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file diff --git a/ai_recipe_generation/android/app/src/debug/AndroidManifest.xml b/ai_recipe_generation/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index 399f6981d..000000000 --- a/ai_recipe_generation/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/ai_recipe_generation/android/app/src/main/AndroidManifest.xml b/ai_recipe_generation/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index b8d463506..000000000 --- a/ai_recipe_generation/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/android/app/src/main/kotlin/com/example/gemini_io_talk/MainActivity.kt b/ai_recipe_generation/android/app/src/main/kotlin/com/example/gemini_io_talk/MainActivity.kt deleted file mode 100644 index 3df14b9aa..000000000 --- a/ai_recipe_generation/android/app/src/main/kotlin/com/example/gemini_io_talk/MainActivity.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.example.gemini_io_talk - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { -} diff --git a/ai_recipe_generation/android/app/src/main/res/drawable-v21/launch_background.xml b/ai_recipe_generation/android/app/src/main/res/drawable-v21/launch_background.xml deleted file mode 100644 index f74085f3f..000000000 --- a/ai_recipe_generation/android/app/src/main/res/drawable-v21/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/ai_recipe_generation/android/app/src/main/res/drawable/launch_background.xml b/ai_recipe_generation/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f88..000000000 --- a/ai_recipe_generation/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/ai_recipe_generation/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/ai_recipe_generation/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4b7b0906d62b1847e87f15cdcacf6a4f29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ diff --git a/ai_recipe_generation/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/ai_recipe_generation/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b79bb8a35cc66c3c1fd44f5a5526c1b78be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ diff --git a/ai_recipe_generation/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/ai_recipe_generation/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d34e7a88e3f88bea192c3a370d44689c3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof diff --git a/ai_recipe_generation/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/ai_recipe_generation/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372eebdb28e45604e46eeda8dd24651419bc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` diff --git a/ai_recipe_generation/android/app/src/main/res/values-night/styles.xml b/ai_recipe_generation/android/app/src/main/res/values-night/styles.xml deleted file mode 100644 index 06952be74..000000000 --- a/ai_recipe_generation/android/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/ai_recipe_generation/android/app/src/main/res/values/styles.xml b/ai_recipe_generation/android/app/src/main/res/values/styles.xml deleted file mode 100644 index cb1ef8805..000000000 --- a/ai_recipe_generation/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/ai_recipe_generation/android/app/src/profile/AndroidManifest.xml b/ai_recipe_generation/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index 399f6981d..000000000 --- a/ai_recipe_generation/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/ai_recipe_generation/android/build.gradle b/ai_recipe_generation/android/build.gradle deleted file mode 100644 index e83fb5dac..000000000 --- a/ai_recipe_generation/android/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -tasks.register("clean", Delete) { - delete rootProject.buildDir -} diff --git a/ai_recipe_generation/android/gradle.properties b/ai_recipe_generation/android/gradle.properties deleted file mode 100644 index 598d13fee..000000000 --- a/ai_recipe_generation/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.jvmargs=-Xmx4G -android.useAndroidX=true -android.enableJetifier=true diff --git a/ai_recipe_generation/android/gradle/wrapper/gradle-wrapper.properties b/ai_recipe_generation/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 3c472b99c..000000000 --- a/ai_recipe_generation/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/ai_recipe_generation/android/settings.gradle b/ai_recipe_generation/android/settings.gradle deleted file mode 100644 index 7cd712855..000000000 --- a/ai_recipe_generation/android/settings.gradle +++ /dev/null @@ -1,29 +0,0 @@ -pluginManagement { - def flutterSdkPath = { - def properties = new Properties() - file("local.properties").withInputStream { properties.load(it) } - def flutterSdkPath = properties.getProperty("flutter.sdk") - assert flutterSdkPath != null, "flutter.sdk not set in local.properties" - return flutterSdkPath - } - settings.ext.flutterSdkPath = flutterSdkPath() - - includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") - - repositories { - google() - mavenCentral() - gradlePluginPortal() - } - - plugins { - id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false - } -} - -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "7.3.0" apply false -} - -include ":app" diff --git a/ai_recipe_generation/assets/chef_cat.svg b/ai_recipe_generation/assets/chef_cat.svg deleted file mode 100644 index 2e579bcbe..000000000 --- a/ai_recipe_generation/assets/chef_cat.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/assets/fridge_test_image.jpeg b/ai_recipe_generation/assets/fridge_test_image.jpeg deleted file mode 100644 index 6fd02efe09cdd837207e82d3e296882caf9d95ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34128 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 s2K&k3>)WiwB>)pzO0id=D}j3!kB)&Rbvr8z - - - - - - - - - - diff --git a/ai_recipe_generation/ios/.gitignore b/ai_recipe_generation/ios/.gitignore deleted file mode 100644 index 7a7f9873a..000000000 --- a/ai_recipe_generation/ios/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -**/dgph -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Flutter.podspec -Flutter/Generated.xcconfig -Flutter/ephemeral/ -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/ai_recipe_generation/ios/Flutter/AppFrameworkInfo.plist b/ai_recipe_generation/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 7c5696400..000000000 --- a/ai_recipe_generation/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 12.0 - - diff --git a/ai_recipe_generation/ios/Flutter/Debug.xcconfig b/ai_recipe_generation/ios/Flutter/Debug.xcconfig deleted file mode 100644 index ec97fc6f3..000000000 --- a/ai_recipe_generation/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/ai_recipe_generation/ios/Flutter/Release.xcconfig b/ai_recipe_generation/ios/Flutter/Release.xcconfig deleted file mode 100644 index c4855bfe2..000000000 --- a/ai_recipe_generation/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/ai_recipe_generation/ios/Podfile b/ai_recipe_generation/ios/Podfile deleted file mode 100644 index d97f17e22..000000000 --- a/ai_recipe_generation/ios/Podfile +++ /dev/null @@ -1,44 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '12.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_ios_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths - end -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_ios_build_settings(target) - end -end diff --git a/ai_recipe_generation/ios/Runner.xcodeproj/project.pbxproj b/ai_recipe_generation/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 9f8fe71ca..000000000 --- a/ai_recipe_generation/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,728 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 6CEAC1BB3402D2FB3D949175 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3AEDF9CC1F2478538C36F4EC /* GoogleService-Info.plist */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - D176046199A01D7761A9B663 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55AAE8E90222A83A2A3C5725 /* Pods_RunnerTests.framework */; }; - EC8FDDE32B650F9294E84E49 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 560968E9DE345774409B17C1 /* Pods_Runner.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 97C146E61CF9000F007C117D /* Project object */; - proxyType = 1; - remoteGlobalIDString = 97C146ED1CF9000F007C117D; - remoteInfo = Runner; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 26885269168D3B8FD1AC5E99 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; - 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; - 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3AEDF9CC1F2478538C36F4EC /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 55AAE8E90222A83A2A3C5725 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 560968E9DE345774409B17C1 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E452F04B76B6311A2D269D2 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 8AC0061116C886C86A9B5490 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 8C41D0F2AC811E3A0FF6FC41 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - CE028EB35B4B427E70F8476C /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; - D397ABCFD4CECC2D1C87B0F5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 3C97DB56F9108CED1F143C54 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D176046199A01D7761A9B663 /* Pods_RunnerTests.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - EC8FDDE32B650F9294E84E49 /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 331C8082294A63A400263BE5 /* RunnerTests */ = { - isa = PBXGroup; - children = ( - 331C807B294A618700263BE5 /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; - 4DC0F3FBD4704312B8DDA602 /* Pods */ = { - isa = PBXGroup; - children = ( - D397ABCFD4CECC2D1C87B0F5 /* Pods-Runner.debug.xcconfig */, - 8AC0061116C886C86A9B5490 /* Pods-Runner.release.xcconfig */, - 8C41D0F2AC811E3A0FF6FC41 /* Pods-Runner.profile.xcconfig */, - 26885269168D3B8FD1AC5E99 /* Pods-RunnerTests.debug.xcconfig */, - 6E452F04B76B6311A2D269D2 /* Pods-RunnerTests.release.xcconfig */, - CE028EB35B4B427E70F8476C /* Pods-RunnerTests.profile.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; - 774D05E8B814CE61D1EBF4C8 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 560968E9DE345774409B17C1 /* Pods_Runner.framework */, - 55AAE8E90222A83A2A3C5725 /* Pods_RunnerTests.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 331C8082294A63A400263BE5 /* RunnerTests */, - 4DC0F3FBD4704312B8DDA602 /* Pods */, - 774D05E8B814CE61D1EBF4C8 /* Frameworks */, - 3AEDF9CC1F2478538C36F4EC /* GoogleService-Info.plist */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - 331C8081294A63A400263BE5 /* RunnerTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 331C8080294A63A400263BE5 /* RunnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; - buildPhases = ( - 825D4F9DB9CE5CD128B67AF7 /* [CP] Check Pods Manifest.lock */, - 331C807D294A63A400263BE5 /* Sources */, - 331C807F294A63A400263BE5 /* Resources */, - 3C97DB56F9108CED1F143C54 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 331C8086294A63A400263BE5 /* PBXTargetDependency */, - ); - name = RunnerTests; - productName = RunnerTests; - productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 9B274ACE53869D8B50572937 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 04F3356025EB4C21B4C3E754 /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 1510; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 331C8080294A63A400263BE5 = { - CreatedOnToolsVersion = 14.0; - TestTargetID = 97C146ED1CF9000F007C117D; - }; - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - 331C8080294A63A400263BE5 /* RunnerTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 331C807F294A63A400263BE5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - 6CEAC1BB3402D2FB3D949175 /* GoogleService-Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 04F3356025EB4C21B4C3E754 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 825D4F9DB9CE5CD128B67AF7 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - 9B274ACE53869D8B50572937 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 331C807D294A63A400263BE5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 97C146ED1CF9000F007C117D /* Runner */; - targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 2UUT9AMTS2; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 331C8088294A63A400263BE5 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 26885269168D3B8FD1AC5E99 /* Pods-RunnerTests.debug.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Debug; - }; - 331C8089294A63A400263BE5 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 6E452F04B76B6311A2D269D2 /* Pods-RunnerTests.release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Release; - }; - 331C808A294A63A400263BE5 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = CE028EB35B4B427E70F8476C /* Pods-RunnerTests.profile.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 2UUT9AMTS2; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 2UUT9AMTS2; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 331C8088294A63A400263BE5 /* Debug */, - 331C8089294A63A400263BE5 /* Release */, - 331C808A294A63A400263BE5 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a62..000000000 --- a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5e..000000000 --- a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/ai_recipe_generation/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ai_recipe_generation/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 8e3ca5dfe..000000000 --- a/ai_recipe_generation/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/ios/Runner.xcworkspace/contents.xcworkspacedata b/ai_recipe_generation/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14c..000000000 --- a/ai_recipe_generation/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5e..000000000 --- a/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/ai_recipe_generation/ios/Runner/AppDelegate.swift b/ai_recipe_generation/ios/Runner/AppDelegate.swift deleted file mode 100644 index 70693e4a8..000000000 --- a/ai_recipe_generation/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab2..000000000 --- a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada4725e9b0ddb1deab583e5b5102493aa332..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10932 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 diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 797d452e458972bab9d994556c8305db4c827017..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 406 zcmV;H0crk;P))>cdjpWt&rLJgVp-t?DREyuq1A%0Z4)6_WsQ7{nzjN zo!X zGXV)2i3kcZIL~_j>uIKPK_zib+3T+Nt3Mb&Br)s)UIaA}@p{wDda>7=Q|mGRp7pqY zkJ!7E{MNz$9nOwoVqpFb)}$IP24Wn2JJ=Cw(!`OXJBr45rP>>AQr$6c7slJWvbpNW z@KTwna6d?PP>hvXCcp=4F;=GR@R4E7{4VU^0p4F>v^#A|>07*qoM6N<$f*5nx ACIA2c diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index 6ed2d933e1120817fe9182483a228007b18ab6ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 450 zcmV;z0X_bSP)iGWQ_5NJQ_~rNh*z)}eT%KUb z`7gNk0#AwF^#0T0?hIa^`~Ck;!}#m+_uT050aTR(J!bU#|IzRL%^UsMS#KsYnTF*!YeDOytlP4VhV?b} z%rz_<=#CPc)tU1MZTq~*2=8~iZ!lSa<{9b@2Jl;?IEV8)=fG217*|@)CCYgFze-x? zIFODUIA>nWKpE+bn~n7;-89sa>#DR>TSlqWk*!2hSN6D~Qb#VqbP~4Fk&m`@1$JGr zXPIdeRE&b2Thd#{MtDK$px*d3-Wx``>!oimf%|A-&-q*6KAH)e$3|6JV%HX{Hig)k suLT-RhftRq8b9;(V=235Wa|I=027H2wCDra;{X5v07*qoM6N<$f;9x^2LJ#7 diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cd7b0099ca80c806f8fe495613e8d6c69460d76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 282 zcmV+#0p(^bcu7P-R4C8Q z&e;xxFbF_Vrezo%_kH*OKhshZ6BFpG-Y1e10`QXJKbND7AMQ&cMj60B5TNObaZxYybcN07*qoM6N<$g3m;S%K!iX diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index fe730945a01f64a61e2235dbe3f45b08f7729182..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 462 zcmV;<0WtoGP)-}iV`2<;=$?g5M=KQbZ{F&YRNy7Nn@%_*5{gvDM0aKI4?ESmw z{NnZg)A0R`+4?NF_RZexyVB&^^ZvN!{I28tr{Vje;QNTz`dG&Jz0~Ek&f2;*Z7>B|cg}xYpxEFY+0YrKLF;^Q+-HreN0P{&i zK~zY`?b7ECf-n?@;d<&orQ*Q7KoR%4|C>{W^h6@&01>0SKS`dn{Q}GT%Qj_{PLZ_& zs`MFI#j-(>?bvdZ!8^xTwlY{qA)T4QLbY@j(!YJ7aXJervHy6HaG_2SB`6CC{He}f zHVw(fJWApwPq!6VY7r1w-Fs)@ox~N+q|w~e;JI~C4Vf^@d>Wvj=fl`^u9x9wd9 zR%3*Q+)t%S!MU_`id^@&Y{y7-r98lZX0?YrHlfmwb?#}^1b{8g&KzmkE(L>Z&)179 zp<)v6Y}pRl100G2FL_t(o!|l{-Q-VMg#&MKg7c{O0 z2wJImOS3Gy*Z2Qifdv~JYOp;v+U)a|nLoc7hNH;I$;lzDt$}rkaFw1mYK5_0Q(Sut zvbEloxON7$+HSOgC9Z8ltuC&0OSF!-mXv5caV>#bc3@hBPX@I$58-z}(ZZE!t-aOG zpjNkbau@>yEzH(5Yj4kZiMH32XI!4~gVXNnjAvRx;Sdg^`>2DpUEwoMhTs_st8pKG z(%SHyHdU&v%f36~uERh!bd`!T2dw;z6PrOTQ7Vt*#9F2uHlUVnb#ev_o^fh}Dzmq} zWtlk35}k=?xj28uO|5>>$yXadTUE@@IPpgH`gJ~Ro4>jd1IF|(+IX>8M4Ps{PNvmI zNj4D+XgN83gPt_Gm}`Ybv{;+&yu-C(Grdiahmo~BjG-l&mWM+{e5M1sm&=xduwgM9 z`8OEh`=F3r`^E{n_;%9weN{cf2%7=VzC@cYj+lg>+3|D|_1C@{hcU(DyQG_BvBWe? zvTv``=%b1zrol#=R`JB)>cdjpWt&rLJgVp-t?DREyuq1A%0Z4)6_WsQ7{nzjN zo!X zGXV)2i3kcZIL~_j>uIKPK_zib+3T+Nt3Mb&Br)s)UIaA}@p{wDda>7=Q|mGRp7pqY zkJ!7E{MNz$9nOwoVqpFb)}$IP24Wn2JJ=Cw(!`OXJBr45rP>>AQr$6c7slJWvbpNW z@KTwna6d?PP>hvXCcp=4F;=GR@R4E7{4VU^0p4F>v^#A|>07*qoM6N<$f*5nx ACIA2c diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index 502f463a9bc882b461c96aadf492d1729e49e725..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 586 zcmV-Q0=4~#P)+}#`wDE{8-2Mebf5<{{PqV{TgVcv*r8?UZ3{-|G?_}T*&y;@cqf{ z{Q*~+qr%%p!1pS*_Uicl#q9lc(D`!D`LN62sNwq{oYw(Wmhk)k<@f$!$@ng~_5)Ru z0Z)trIA5^j{DIW^c+vT2%lW+2<(RtE2wR;4O@)Tm`Xr*?A(qYoM}7i5Yxw>D(&6ou zxz!_Xr~yNF+waPe00049Nkl*;a!v6h%{rlvIH#gW3s8p;bFr=l}mRqpW2h zw=OA%hdyL~z+UHOzl0eKhEr$YYOL-c-%Y<)=j?(bzDweB7{b+%_ypvm_cG{SvM=DK zhv{K@m>#Bw>2W$eUI#iU)Wdgs8Y3U+A$Gd&{+j)d)BmGKx+43U_!tik_YlN)>$7G! zhkE!s;%oku3;IwG3U^2kw?z+HM)jB{@zFhK8P#KMSytSthr+4!c(5c%+^UBn`0X*2 zy3(k600_CSZj?O$Qu%&$;|TGUJrptR(HzyIx>5E(2r{eA(<6t3e3I0B)7d6s7?Z5J zZ!rtKvA{MiEBm&KFtoifx>5P^Z=vl)95XJn()aS5%ad(s?4-=Tkis9IGu{`Fy8r+H07*qoM6N<$f20Z)wqMt%V?S?~D#06};F zA3KcL`Wb+>5ObvgQIG&ig8(;V04hz?@cqy3{mSh8o!|U|)cI!1_+!fWH@o*8vh^CU z^ws0;(c$gI+2~q^tO#GDHf@=;DncUw00J^eL_t(&-tE|HQ`%4vfZ;WsBqu-$0nu1R zq^Vj;p$clf^?twn|KHO+IGt^q#a3X?w9dXC@*yxhv&l}F322(8Y1&=P&I}~G@#h6; z1CV9ecD9ZEe87{{NtI*)_aJ<`kJa z?5=RBtFF50s;jQLFil-`)m2wrb=6h(&brpj%nG_U&ut~$?8Rokzxi8zJoWr#2dto5 zOX_URcc<1`Iky+jc;A%Vzx}1QU{2$|cKPom2Vf1{8m`vja4{F>HS?^Nc^rp}xo+Nh zxd}eOm`fm3@MQC1< zIk&aCjb~Yh%5+Yq0`)D;q{#-Uqlv*o+Oor zE!I71Z@ASH3grl8&P^L0WpavHoP|UX4e?!igT`4?AZk$hu*@%6WJ;zDOGlw7kj@ zY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f~t1N9smFU diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index 0ec303439225b78712f49115768196d8d76f6790..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 862 zcmV-k1EKthP)20Z)wqMt%V?S?~D#06};F zA3KcL`Wb+>5ObvgQIG&ig8(;V04hz?@cqy3{mSh8o!|U|)cI!1_+!fWH@o*8vh^CU z^ws0;(c$gI+2~q^tO#GDHf@=;DncUw00J^eL_t(&-tE|HQ`%4vfZ;WsBqu-$0nu1R zq^Vj;p$clf^?twn|KHO+IGt^q#a3X?w9dXC@*yxhv&l}F322(8Y1&=P&I}~G@#h6; z1CV9ecD9ZEe87{{NtI*)_aJ<`kJa z?5=RBtFF50s;jQLFil-`)m2wrb=6h(&brpj%nG_U&ut~$?8Rokzxi8zJoWr#2dto5 zOX_URcc<1`Iky+jc;A%Vzx}1QU{2$|cKPom2Vf1{8m`vja4{F>HS?^Nc^rp}xo+Nh zxd}eOm`fm3@MQC1< zIk&aCjb~Yh%5+Yq0`)D;q{#-Uqlv*o+Oor zE!I71Z@ASH3grl8&P^L0WpavHoP|UX4e?!igT`4?AZk$hu*@%6WJ;zDOGlw7kj@ zY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f~t1N9smFU diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index e9f5fea27c705180eb716271f41b582e76dcbd90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1674 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 diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index 0467bf12aa4d28f374bb26596605a46dcbb3e7c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1418 zcmV;51$Fv~P)q zKfU)WzW*n(@|xWGCA9ScMt*e9`2kdxPQ&&>|-UCa7_51w+ zLUsW@ZzZSW0y$)Hp~e9%PvP|a03ks1`~K?q{u;6NC8*{AOqIUq{CL&;p56Lf$oQGq z^={4hPQv)y=I|4n+?>7Fim=dxt1 z2H+Dm+1+fh+IF>G0SjJMkQQre1x4|G*Z==(Ot&kCnUrL4I(rf(ucITwmuHf^hXiJT zkdTm&kdTm&kdTm&kdP`esgWG0BcWCVkVZ&2dUwN`cgM8QJb`Z7Z~e<&Yj2(}>Tmf` zm1{eLgw!b{bXkjWbF%dTkTZEJWyWOb##Lfw4EK2}<0d6%>AGS{po>WCOy&f$Tay_> z?NBlkpo@s-O;0V%Y_Xa-G#_O08q5LR*~F%&)}{}r&L%Sbs8AS4t7Y0NEx*{soY=0MZExqA5XHQkqi#4gW3 zqODM^iyZl;dvf)-bOXtOru(s)Uc7~BFx{w-FK;2{`VA?(g&@3z&bfLFyctOH!cVsF z7IL=fo-qBndRUm;kAdXR4e6>k-z|21AaN%ubeVrHl*<|s&Ax@W-t?LR(P-24A5=>a z*R9#QvjzF8n%@1Nw@?CG@6(%>+-0ASK~jEmCV|&a*7-GKT72W<(TbSjf)&Eme6nGE z>Gkj4Sq&2e+-G%|+NM8OOm5zVl9{Z8Dd8A5z3y8mZ=4Bv4%>as_{9cN#bm~;h>62( zdqY93Zy}v&c4n($Vv!UybR8ocs7#zbfX1IY-*w~)p}XyZ-SFC~4w>BvMVr`dFbelV{lLL0bx7@*ZZdebr3`sP;? zVImji)kG)(6Juv0lz@q`F!k1FE;CQ(D0iG$wchPbKZQELlsZ#~rt8#90Y_Xh&3U-< z{s<&cCV_1`^TD^ia9!*mQDq& zn2{r`j};V|uV%_wsP!zB?m%;FeaRe+X47K0e+KE!8C{gAWF8)lCd1u1%~|M!XNRvw zvtqy3iz0WSpWdhn6$hP8PaRBmp)q`#PCA`Vd#Tc$@f1tAcM>f_I@bC)hkI9|o(Iqv zo}Piadq!j76}004RBio<`)70k^`K1NK)q>w?p^C6J2ZC!+UppiK6&y3Kmbv&O!oYF z34$0Z;QO!JOY#!`qyGH<3Pd}Pt@q*A0V=3SVtWKRR8d8Z&@)3qLPA19LPA19LPEUC YUoZo%k(ykuW&i*H07*qoM6N<$f+CH{y8r+H diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json deleted file mode 100644 index 0bedcf2fd..000000000 --- a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "LaunchImage.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b7..000000000 --- a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/ai_recipe_generation/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ai_recipe_generation/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7c..000000000 --- a/ai_recipe_generation/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/ios/Runner/Base.lproj/Main.storyboard b/ai_recipe_generation/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516f..000000000 --- a/ai_recipe_generation/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/ios/Runner/GoogleService-Info.plist b/ai_recipe_generation/ios/Runner/GoogleService-Info.plist deleted file mode 100644 index a22623df5..000000000 --- a/ai_recipe_generation/ios/Runner/GoogleService-Info.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - API_KEY - AIzaSyBNEtAHdjm3oFV6JZ6nbx5t6Pfyj4w4hbo - GCM_SENDER_ID - 44885228795 - PLIST_VERSION - 1 - BUNDLE_ID - com.example.geminiIoTalk - PROJECT_ID - gemini-cat-chef - STORAGE_BUCKET - gemini-cat-chef.appspot.com - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:44885228795:ios:8ef52eb95f012a148f845e - - \ No newline at end of file diff --git a/ai_recipe_generation/ios/Runner/Info.plist b/ai_recipe_generation/ios/Runner/Info.plist deleted file mode 100644 index 04e544b40..000000000 --- a/ai_recipe_generation/ios/Runner/Info.plist +++ /dev/null @@ -1,59 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Gemini Io Talk - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - gemini_io_talk - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - NSCameraUsageDescription - Used to demonstrate image picker plugin - NSMicrophoneUsageDescription - Used to capture audio for image picker plugin - NSPhotoLibraryUsageDescription - Used to demonstrate image picker plugin - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - - NSCameraUsageDescription - your usage description here - NSMicrophoneUsageDescription - your usage description here - - diff --git a/ai_recipe_generation/ios/Runner/Runner-Bridging-Header.h b/ai_recipe_generation/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 308a2a560..000000000 --- a/ai_recipe_generation/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" diff --git a/ai_recipe_generation/ios/RunnerTests/RunnerTests.swift b/ai_recipe_generation/ios/RunnerTests/RunnerTests.swift deleted file mode 100644 index 86a7c3b1b..000000000 --- a/ai_recipe_generation/ios/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Flutter -import UIKit -import XCTest - -class RunnerTests: XCTestCase { - - func testExample() { - // If you add code to the Runner application, consider adding tests here. - // See https://developer.apple.com/documentation/xctest for more information about using XCTest. - } - -} diff --git a/ai_recipe_generation/ios/firebase_app_id_file.json b/ai_recipe_generation/ios/firebase_app_id_file.json deleted file mode 100644 index 2e5b1c36b..000000000 --- a/ai_recipe_generation/ios/firebase_app_id_file.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "file_generated_by": "FlutterFire CLI", - "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", - "GOOGLE_APP_ID": "1:44885228795:ios:8ef52eb95f012a148f845e", - "FIREBASE_PROJECT_ID": "gemini-cat-chef", - "GCM_SENDER_ID": "44885228795" -} \ No newline at end of file diff --git a/ai_recipe_generation/lib/app_bar.dart b/ai_recipe_generation/lib/app_bar.dart deleted file mode 100644 index 487deb3d5..000000000 --- a/ai_recipe_generation/lib/app_bar.dart +++ /dev/null @@ -1,160 +0,0 @@ -import 'package:ai_recipe_generation/util/extensions.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import 'features/prompt/widgets/app_info_dialog_widget.dart'; -import 'theme.dart'; -import 'widgets/appbar_shape_border.dart'; - -class AnimatedAppBar extends StatelessWidget { - const AnimatedAppBar({ - super.key, - required this.scrollController, - required this.textStyle, - required this.tabController, - }); - - final ScrollController scrollController; - final double collapsedHeight = 100; - final double expandedHeight = 300; - final double avatarSize = 50; - final TextStyle textStyle; - final TabController tabController; - - String get headerText { - return switch (tabController.index) { - 0 => 'Create a recipe', - 1 => 'Saved recipes', - 2 => 'Settings', - _ => 'Uh oh!', - }; - } - - String get helperText { - return switch (tabController.index) { - 0 => - "Tell me what ingredients you have and what you're feelin', and I'll create a recipe for you!", - 1 => "These are all my saved recipes created by Chef Noodle.", - 2 => 'Settings', - _ => 'Uh oh!', - }; - } - - @override - Widget build(BuildContext context) { - return SliverLayoutBuilder( - builder: (context, constraints) { - return SliverAppBar( - automaticallyImplyLeading: false, - pinned: true, - forceElevated: true, - elevation: 2, - shadowColor: Colors.black, - expandedHeight: expandedHeight, - collapsedHeight: collapsedHeight, - backgroundColor: Theme.of(context).primaryColor, - shape: const AppBarShapeBorder(50), - title: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - width: avatarSize, - height: avatarSize, - child: SvgPicture.asset( - 'assets/chef_cat.svg', - semanticsLabel: 'Chef cat icon', - ), - ), - const SizedBox( - width: MarketplaceTheme.spacing1, - ), - if (scrollController.positions.isNotEmpty && - scrollController.offset < 200) - Text( - "Meowdy! Let's get cooking!", - style: MarketplaceTheme.heading3, - ), - if (scrollController.positions.isNotEmpty && - scrollController.offset > 200) - Text( - headerText, - style: MarketplaceTheme.heading3, - ), - const Spacer(), - if (scrollController.positions.isNotEmpty && - scrollController.offset > 200) - IconButton( - onPressed: () => showDialog( - context: context, - builder: (context) => const AppInfoDialog(), - ), - icon: const Icon( - Symbols.info, - color: Colors.black12, - ), - ), - ], - ), - ], - ), - flexibleSpace: FlexibleSpaceBar( - background: Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing4), - child: SizedBox( - width: MediaQuery.of(context).size.width, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Expanded( - child: Text( - helperText, - style: constraints.isMobile - ? MarketplaceTheme.subheading2 - : MarketplaceTheme.subheading1, - ), - ), - IconButton( - onPressed: () { - showDialog( - context: context, - builder: (context) => const AppInfoDialog(), - ); - }, - icon: const Icon( - Symbols.info, - color: Colors.black12, - ), - ), - ], - ), - ), - ), - ), - bottom: PreferredSize( - preferredSize: const Size(double.infinity, 0), - child: Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: EdgeInsets.only( - left: constraints.isMobile - ? MarketplaceTheme.spacing2 - : MarketplaceTheme.spacing1, - ), - child: AnimatedDefaultTextStyle( - duration: const Duration(milliseconds: 0), - style: textStyle, - child: Text( - headerText, - ), - ), - ), - ), - ), - ); - }, - ); - } -} diff --git a/ai_recipe_generation/lib/features/prompt/prompt_model.dart b/ai_recipe_generation/lib/features/prompt/prompt_model.dart deleted file mode 100644 index 8ff1222d4..000000000 --- a/ai_recipe_generation/lib/features/prompt/prompt_model.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:image_picker/image_picker.dart'; - -import '../../util/filter_chip_enums.dart'; - -class PromptData { - PromptData({ - required this.images, - required this.textInput, - Set? basicIngredients, - Set? cuisines, - Set? dietaryRestrictions, - List? additionalTextInputs, - }) : additionalTextInputs = additionalTextInputs ?? [], - selectedBasicIngredients = basicIngredients ?? {}, - selectedCuisines = cuisines ?? {}, - selectedDietaryRestrictions = dietaryRestrictions ?? {}; - - PromptData.empty() - : images = [], - additionalTextInputs = [], - selectedBasicIngredients = {}, - selectedCuisines = {}, - selectedDietaryRestrictions = {}, - textInput = ''; - - String get cuisines { - return selectedCuisines.map((catFilter) => catFilter.name).join(","); - } - - String get ingredients { - return selectedBasicIngredients - .map((ingredient) => ingredient.name) - .join(", "); - } - - String get dietaryRestrictions { - return selectedDietaryRestrictions - .map((restriction) => restriction.name) - .join(", "); - } - - List images; - String textInput; - List additionalTextInputs; - Set selectedBasicIngredients; - Set selectedCuisines; - Set selectedDietaryRestrictions; - - PromptData copyWith({ - List? images, - String? textInput, - List? additionalTextInputs, - Set? basicIngredients, - Set? cuisineSelections, - Set? dietaryRestrictions, - }) { - return PromptData( - images: images ?? this.images, - textInput: textInput ?? this.textInput, - additionalTextInputs: additionalTextInputs ?? this.additionalTextInputs, - basicIngredients: basicIngredients ?? selectedBasicIngredients, - cuisines: cuisineSelections ?? selectedCuisines, - dietaryRestrictions: dietaryRestrictions ?? selectedDietaryRestrictions, - ); - } -} diff --git a/ai_recipe_generation/lib/features/prompt/prompt_screen.dart b/ai_recipe_generation/lib/features/prompt/prompt_screen.dart deleted file mode 100644 index a22aa57c0..000000000 --- a/ai_recipe_generation/lib/features/prompt/prompt_screen.dart +++ /dev/null @@ -1,391 +0,0 @@ -import 'package:ai_recipe_generation/features/prompt/prompt_view_model.dart'; -import 'package:ai_recipe_generation/util/extensions.dart'; -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/material_symbols_icons.dart'; -import 'package:provider/provider.dart'; - -import '../../theme.dart'; -import '../../util/filter_chip_enums.dart'; -import '../../widgets/filter_chip_selection_input.dart'; -import '../../widgets/highlight_border_on_hover_widget.dart'; -import '../../widgets/marketplace_button_widget.dart'; -import '../recipes/widgets/recipe_fullscreen_dialog.dart'; -import 'widgets/full_prompt_dialog_widget.dart'; -import 'widgets/image_input_widget.dart'; - -const double kAvatarSize = 50; -const double collapsedHeight = 100; -const double expandedHeight = 300; -const double elementPadding = MarketplaceTheme.spacing7; - -class PromptScreen extends StatelessWidget { - const PromptScreen({super.key, required this.canScroll}); - - final bool canScroll; - - @override - Widget build(BuildContext context) { - final viewModel = context.watch(); - - return LayoutBuilder( - builder: (context, constraints) { - return SingleChildScrollView( - physics: canScroll - ? const BouncingScrollPhysics() - : const NeverScrollableScrollPhysics(), - child: Container( - padding: constraints.isMobile - ? const EdgeInsets.only( - left: MarketplaceTheme.spacing7, - right: MarketplaceTheme.spacing7, - bottom: MarketplaceTheme.spacing7, - top: MarketplaceTheme.spacing7, - ) - : const EdgeInsets.only( - left: MarketplaceTheme.spacing7, - right: MarketplaceTheme.spacing7, - bottom: MarketplaceTheme.spacing1, - top: MarketplaceTheme.spacing7, - ), - child: Container( - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: MarketplaceTheme.borderColor), - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(4), - topRight: Radius.circular(50), - bottomRight: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(elementPadding + 10), - child: Text( - 'Create a recipe:', - style: MarketplaceTheme.dossierParagraph.copyWith( - fontWeight: FontWeight.bold, - fontSize: 18, - ), - ), - ), - Padding( - padding: const EdgeInsets.all( - elementPadding, - ), - child: SizedBox( - height: constraints.isMobile ? 130 : 230, - child: AddImageToPromptWidget( - height: constraints.isMobile ? 100 : 200, - width: constraints.isMobile ? 100 : 200, - ), - ), - ), - if (constraints.isMobile) - Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: "I also have these staple ingredients: ", - child: FilterChipSelectionInput( - onChipSelected: (selected) { - viewModel.addBasicIngredients( - selected as Set); - }, - allValues: BasicIngredientsFilter.values, - selectedValues: - viewModel.userPrompt.selectedBasicIngredients, - ), - ), - ), - if (constraints.isMobile) - Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: "I'm in the mood for: ", - child: FilterChipSelectionInput( - onChipSelected: (selected) { - viewModel.addCategoryFilters( - selected as Set); - }, - allValues: CuisineFilter.values, - selectedValues: viewModel.userPrompt.selectedCuisines, - ), - ), - ), - if (constraints.isMobile) - Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: "I have the following dietary restrictions:", - child: - FilterChipSelectionInput( - onChipSelected: (selected) { - viewModel.addDietaryRestrictionFilter( - selected as Set); - }, - allValues: DietaryRestrictionsFilter.values, - selectedValues: - viewModel.userPrompt.selectedDietaryRestrictions, - ), - ), - ), - if (!constraints.isMobile) - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: "I'm in the mood for: ", - child: FilterChipSelectionInput( - onChipSelected: (selected) { - viewModel.addCategoryFilters( - selected as Set); - }, - allValues: CuisineFilter.values, - selectedValues: - viewModel.userPrompt.selectedCuisines, - ), - ), - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: "I also have these staple ingredients: ", - child: FilterChipSelectionInput< - BasicIngredientsFilter>( - onChipSelected: (selected) { - viewModel.addBasicIngredients( - selected as Set); - }, - allValues: BasicIngredientsFilter.values, - selectedValues: viewModel - .userPrompt.selectedBasicIngredients, - ), - ), - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: - "I have the following dietary restrictions:", - child: FilterChipSelectionInput< - DietaryRestrictionsFilter>( - onChipSelected: (selected) { - viewModel.addDietaryRestrictionFilter(selected - as Set); - }, - allValues: DietaryRestrictionsFilter.values, - selectedValues: viewModel - .userPrompt.selectedDietaryRestrictions, - ), - ), - ), - ), - ], - ), - Padding( - padding: const EdgeInsets.all(elementPadding), - child: _TextField( - controller: viewModel.promptTextController, - onChanged: (value) { - viewModel.notify(); - }, - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing4, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - if (!constraints.isMobile) const Spacer(flex: 1), - if (!constraints.isMobile) - Expanded( - flex: 3, - child: MarketplaceButton( - onPressed: viewModel.resetPrompt, - buttonText: 'Reset prompt', - icon: Symbols.restart_alt, - iconColor: Colors.black45, - buttonBackgroundColor: Colors.transparent, - hoverColor: - MarketplaceTheme.secondary.withAlpha(25), - ), - ), - const Spacer(flex: 1), - Expanded( - flex: constraints.isMobile ? 10 : 3, - child: MarketplaceButton( - onPressed: () { - final promptData = viewModel.buildPrompt(); - showDialog( - context: context, - builder: (context) { - return FullPromptDialog( - promptData: promptData, - ); - }, - ); - }, - buttonText: 'Full prompt', - icon: Symbols.info_rounded, - ), - ), - const Spacer(flex: 1), - Expanded( - flex: constraints.isMobile ? 10 : 3, - child: MarketplaceButton( - onPressed: () async { - await viewModel.submitPrompt().then((_) async { - if (!context.mounted) return; - if (viewModel.recipe != null) { - bool? shouldSave = await showDialog( - context: context, - barrierDismissible: false, - builder: (context) => RecipeDialogScreen( - recipe: viewModel.recipe!, - actions: [ - MarketplaceButton( - onPressed: () { - Navigator.of(context).pop(true); - }, - buttonText: "Save Recipe", - icon: Symbols.save, - ), - ], - ), - ); - if (shouldSave != null && shouldSave) { - viewModel.saveRecipe(); - } - } - }); - }, - buttonText: 'Submit prompt', - icon: Symbols.send, - ), - ), - const Spacer(flex: 1), - ], - ), - ), - if (constraints.isMobile) - Align( - alignment: Alignment.center, - child: MarketplaceButton( - onPressed: viewModel.resetPrompt, - buttonText: 'Reset prompt', - icon: Symbols.restart_alt, - iconColor: Colors.black45, - buttonBackgroundColor: Colors.transparent, - hoverColor: MarketplaceTheme.secondary.withAlpha(25), - ), - ), - const SizedBox(height: 200.0), - ], - ), - ), - ), - ); - }, - ); - } -} - -class _FilterChipSection extends StatelessWidget { - const _FilterChipSection({ - required this.child, - required this.label, - }); - - final Widget child; - final String label; - - @override - Widget build(BuildContext context) { - return HighlightBorderOnHoverWidget( - borderRadius: BorderRadius.zero, - child: Container( - height: 230, - decoration: BoxDecoration( - color: Theme.of(context).splashColor.withAlpha(25), - border: Border.all( - color: MarketplaceTheme.borderColor, - ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisSize: MainAxisSize.max, - children: [ - Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing7), - child: Text( - label, - style: MarketplaceTheme.dossierParagraph, - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: child, - ), - ), - ], - ), - ), - ); - } -} - -class _TextField extends StatelessWidget { - const _TextField({ - required this.controller, - this.onChanged, - }); - - final TextEditingController controller; - final Null Function(String)? onChanged; - - @override - Widget build(BuildContext context) { - return TextField( - scrollPadding: const EdgeInsets.only(bottom: 150), - maxLines: null, - onChanged: onChanged, - minLines: 3, - controller: controller, - style: WidgetStateTextStyle.resolveWith( - (states) => MarketplaceTheme.dossierParagraph), - decoration: InputDecoration( - fillColor: Theme.of(context).splashColor, - hintText: "Add additional context...", - hintStyle: WidgetStateTextStyle.resolveWith( - (states) => MarketplaceTheme.dossierParagraph, - ), - enabledBorder: const OutlineInputBorder( - borderRadius: BorderRadius.zero, - borderSide: BorderSide(width: 1, color: Colors.black12), - ), - focusedBorder: const OutlineInputBorder( - borderRadius: BorderRadius.zero, - borderSide: BorderSide(width: 1, color: Colors.black45), - ), - filled: true, - ), - ); - } -} diff --git a/ai_recipe_generation/lib/features/prompt/prompt_view_model.dart b/ai_recipe_generation/lib/features/prompt/prompt_view_model.dart deleted file mode 100644 index adb1d99e6..000000000 --- a/ai_recipe_generation/lib/features/prompt/prompt_view_model.dart +++ /dev/null @@ -1,168 +0,0 @@ -import 'package:ai_recipe_generation/services/gemini.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:google_generative_ai/google_generative_ai.dart'; -import 'package:image_picker/image_picker.dart'; - -import '../../services/firestore.dart'; -import '../../util/filter_chip_enums.dart'; -import '../recipes/recipe_model.dart'; -import 'prompt_model.dart'; - -class PromptViewModel extends ChangeNotifier { - PromptViewModel({ - required this.multiModalModel, - required this.textModel, - }); - - final GenerativeModel multiModalModel; - final GenerativeModel textModel; - bool loadingNewRecipe = false; - - PromptData userPrompt = PromptData.empty(); - TextEditingController promptTextController = TextEditingController(); - - String badImageFailure = - "The recipe request either does not contain images, or does not contain images of food items. I cannot recommend a recipe."; - - Recipe? recipe; - String? _geminiFailureResponse; - String? get geminiFailureResponse => _geminiFailureResponse; - set geminiFailureResponse(String? value) { - _geminiFailureResponse = value; - notifyListeners(); - } - - void notify() => notifyListeners(); - - void addImage(XFile image) { - userPrompt.images.insert(0, image); - notifyListeners(); - } - - void addAdditionalPromptContext(String text) { - final existingInputs = userPrompt.additionalTextInputs; - userPrompt.copyWith(additionalTextInputs: [...existingInputs, text]); - } - - void removeImage(XFile image) { - userPrompt.images.removeWhere((el) => el.path == image.path); - notifyListeners(); - } - - void resetPrompt() { - userPrompt = PromptData.empty(); - notifyListeners(); - } - - // Creates an ephemeral prompt with additional text that the user shouldn't be - // concerned with to send to Gemini, such as formatting. - PromptData buildPrompt() { - return PromptData( - images: userPrompt.images, - textInput: mainPrompt, - basicIngredients: userPrompt.selectedBasicIngredients, - cuisines: userPrompt.selectedCuisines, - dietaryRestrictions: userPrompt.selectedDietaryRestrictions, - additionalTextInputs: [format], - ); - } - - Future submitPrompt() async { - loadingNewRecipe = true; - notifyListeners(); - // Create an ephemeral PromptData, preserving the user prompt data without - // adding the additional context to it. - var model = userPrompt.images.isEmpty ? textModel : multiModalModel; - final prompt = buildPrompt(); - - try { - final content = await GeminiService.generateContent(model, prompt); - - // handle no image or image of not-food - if (content.text != null && content.text!.contains(badImageFailure)) { - geminiFailureResponse = badImageFailure; - } else { - recipe = Recipe.fromGeneratedContent(content); - } - } catch (error) { - geminiFailureResponse = 'Failed to reach Gemini. \n\n$error'; - if (kDebugMode) { - print(error); - } - loadingNewRecipe = false; - } - - loadingNewRecipe = false; - resetPrompt(); - notifyListeners(); - } - - void saveRecipe() { - FirestoreService.saveRecipe(recipe!); - } - - void addBasicIngredients(Set ingredients) { - userPrompt.selectedBasicIngredients.addAll(ingredients); - notifyListeners(); - } - - void addCategoryFilters(Set categories) { - userPrompt.selectedCuisines.addAll(categories); - notifyListeners(); - } - - void addDietaryRestrictionFilter( - Set restrictions) { - userPrompt.selectedDietaryRestrictions.addAll(restrictions); - notifyListeners(); - } - - String get mainPrompt { - return ''' -You are a Cat who's a chef that travels around the world a lot, and your travels inspire recipes. - -Recommend a recipe for me based on the provided image. -The recipe should only contain real, edible ingredients. -If there are no images attached, or if the image does not contain food items, respond exactly with: $badImageFailure - -Adhere to food safety and handling best practices like ensuring that poultry is fully cooked. -I'm in the mood for the following types of cuisine: ${userPrompt.cuisines}, -I have the following dietary restrictions: ${userPrompt.dietaryRestrictions} -Optionally also include the following ingredients: ${userPrompt.ingredients} -Do not repeat any ingredients. - -After providing the recipe, add an descriptions that creatively explains why the recipe is good based on only the ingredients used in the recipe. Tell a short story of a travel experience that inspired the recipe. -List out any ingredients that are potential allergens. -Provide a summary of how many people the recipe will serve and the the nutritional information per serving. - -${promptTextController.text.isNotEmpty ? promptTextController.text : ''} -'''; - } - - final String format = ''' -Return the recipe as valid JSON using the following structure: -{ - "id": \$uniqueId, - "title": \$recipeTitle, - "ingredients": \$ingredients, - "description": \$description, - "instructions": \$instructions, - "cuisine": \$cuisineType, - "allergens": \$allergens, - "servings": \$servings, - "nutritionInformation": { - "calories": "\$calories", - "fat": "\$fat", - "carbohydrates": "\$carbohydrates", - "protein": "\$protein", - }, -} - -uniqueId should be unique and of type String. -title, description, cuisine, allergens, and servings should be of String type. -ingredients and instructions should be of type List. -nutritionInformation should be of type Map. -'''; -} diff --git a/ai_recipe_generation/lib/features/prompt/widgets/app_info_dialog_widget.dart b/ai_recipe_generation/lib/features/prompt/widgets/app_info_dialog_widget.dart deleted file mode 100644 index 5aa2a2ae0..000000000 --- a/ai_recipe_generation/lib/features/prompt/widgets/app_info_dialog_widget.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import '../../../theme.dart'; - -class AppInfoDialog extends StatelessWidget { - const AppInfoDialog({super.key}); - - Widget bulletRow(String text, {IconData? icon}) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Icon(icon ?? Symbols.label_important_outline), - const SizedBox( - width: 10, - ), - Expanded( - child: Text( - text, - ), - ), - ], - ); - } - - @override - Widget build(BuildContext context) { - return Dialog( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - MarketplaceTheme.defaultBorderRadius, - ), - ), - child: Container( - decoration: BoxDecoration( - border: Border.all(color: MarketplaceTheme.borderColor), - ), - padding: const EdgeInsets.all(MarketplaceTheme.spacing4), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Use the form on this screen to ask Cat Chef to make a recipe for you.", - style: MarketplaceTheme.heading3, - ), - const SizedBox( - height: MarketplaceTheme.spacing4, - ), - bulletRow( - "Add images of ingredients you have, like a picture of the inside of your fridge or pantry.", - icon: Symbols.looks_one, - ), - const SizedBox( - height: MarketplaceTheme.spacing7, - ), - bulletRow( - "Choose what kind of food you're in the mood for, and what staple ingredients you have that might not be pictured.", - icon: Symbols.looks_two, - ), - const SizedBox( - height: MarketplaceTheme.spacing7, - ), - bulletRow( - "In the text box at the bottom, add any additional context that you'd like. \nFor example, you could say \"I'm in a hurry! Make sure the recipe doesn't take longer than 30 minutes to make.\"", - icon: Symbols.looks_3, - ), - const SizedBox( - height: MarketplaceTheme.spacing7, - ), - bulletRow( - "Submit the prompt, and Chef Noodle will give you a recipe!", - icon: Symbols.looks_4, - ), - const SizedBox( - height: MarketplaceTheme.spacing4, - ), - Text( - "Steps 1, 2 and 3 are optional. More information will provide better results.", - style: MarketplaceTheme.label, - ), - const SizedBox(height: MarketplaceTheme.spacing4), - TextButton.icon( - icon: const Icon( - Symbols.close, - color: Colors.black87, - ), - label: Text( - 'Close', - style: MarketplaceTheme.dossierParagraph, - ), - onPressed: () { - Navigator.pop(context); - }, - style: ButtonStyle( - shape: WidgetStateProperty.resolveWith( - (states) { - return const RoundedRectangleBorder( - side: BorderSide(color: Colors.black26), - borderRadius: BorderRadius.all( - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - ); - }, - ), - textStyle: WidgetStateTextStyle.resolveWith( - (states) { - return MarketplaceTheme.dossierParagraph - .copyWith(color: Colors.black45); - }, - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/features/prompt/widgets/full_prompt_dialog_widget.dart b/ai_recipe_generation/lib/features/prompt/widgets/full_prompt_dialog_widget.dart deleted file mode 100644 index 420667c06..000000000 --- a/ai_recipe_generation/lib/features/prompt/widgets/full_prompt_dialog_widget.dart +++ /dev/null @@ -1,112 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import '../../../theme.dart'; -import '../../../widgets/prompt_image_widget.dart'; -import '../prompt_model.dart'; - -class FullPromptDialog extends StatelessWidget { - const FullPromptDialog({super.key, required this.promptData}); - - final PromptData promptData; - - Widget bulletRow(String text, {IconData? icon}) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Icon(icon ?? Symbols.label_important_outline), - const SizedBox( - width: 10, - ), - Expanded( - child: Text( - text, - ), - ), - ], - ); - } - - @override - Widget build(BuildContext context) { - return Dialog.fullscreen( - child: SingleChildScrollView( - child: Container( - decoration: BoxDecoration( - border: Border.all(color: MarketplaceTheme.borderColor), - ), - padding: const EdgeInsets.all(MarketplaceTheme.spacing4), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "This is the full prompt that will be sent to Google's Gemini model.", - style: MarketplaceTheme.heading3, - ), - const SizedBox(height: MarketplaceTheme.spacing4), - if (promptData.images.isNotEmpty) - Container( - height: 100, - decoration: const BoxDecoration( - border: Border.symmetric( - horizontal: BorderSide( - color: MarketplaceTheme.borderColor, - ), - ), - ), - child: ListView( - scrollDirection: Axis.horizontal, - children: [ - for (var image in promptData.images) - Padding( - padding: const EdgeInsets.all(8.0), - child: PromptImage( - file: image, - ), - ), - ], - ), - ), - const SizedBox(height: MarketplaceTheme.spacing4), - bulletRow(promptData.textInput), - if (promptData.additionalTextInputs.isNotEmpty) - ...promptData.additionalTextInputs.map((i) => bulletRow(i)), - const SizedBox(height: MarketplaceTheme.spacing4), - TextButton.icon( - icon: const Icon( - Symbols.close, - color: Colors.black87, - ), - label: Text( - 'Close', - style: MarketplaceTheme.dossierParagraph, - ), - onPressed: () { - Navigator.pop(context); - }, - style: ButtonStyle( - shape: WidgetStateProperty.resolveWith( - (states) { - return const RoundedRectangleBorder( - side: BorderSide(color: Colors.black26), - borderRadius: BorderRadius.all( - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - ); - }, - ), - textStyle: WidgetStateTextStyle.resolveWith( - (states) { - return MarketplaceTheme.dossierParagraph - .copyWith(color: Colors.black45); - }, - ), - ), - ), - ], - ), - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/features/prompt/widgets/image_input_widget.dart b/ai_recipe_generation/lib/features/prompt/widgets/image_input_widget.dart deleted file mode 100644 index 70484a16a..000000000 --- a/ai_recipe_generation/lib/features/prompt/widgets/image_input_widget.dart +++ /dev/null @@ -1,278 +0,0 @@ -import 'package:ai_recipe_generation/widgets/highlight_border_on_hover_widget.dart'; -import 'package:camera/camera.dart'; -import 'package:flutter/material.dart'; -import 'package:image_picker/image_picker.dart'; -import 'package:material_symbols_icons/symbols.dart'; -import 'package:provider/provider.dart'; - -import '../../../main.dart'; -import '../../../theme.dart'; -import '../../../util/device_info.dart'; -import '../../../widgets/add_image_widget.dart'; -import '../../../widgets/prompt_image_widget.dart'; -import '../prompt_view_model.dart'; - -class AddImageToPromptWidget extends StatefulWidget { - const AddImageToPromptWidget({ - super.key, - this.width = 100, - this.height = 100, - }); - - final double width; - final double height; - - @override - State createState() => _AddImageToPromptWidgetState(); -} - -class _AddImageToPromptWidgetState extends State { - final ImagePicker picker = ImagePicker(); - late CameraController _controller; - late Future _initializeControllerFuture; - bool flashOn = false; - - @override - void initState() { - super.initState(); - if (DeviceInfo.isPhysicalDeviceWithCamera(deviceInfo)) { - _controller = CameraController( - camera, - ResolutionPreset.medium, - ); - _initializeControllerFuture = _controller.initialize(); - } - } - - Future _showCamera() async { - final image = await showGeneralDialog( - context: context, - transitionBuilder: (context, animation, secondaryAnimation, child) { - return AnimatedOpacity( - opacity: animation.value, - duration: const Duration(milliseconds: 100), - child: child, - ); - }, - pageBuilder: (context, animation, secondaryAnimation) { - return Dialog.fullscreen( - insetAnimationDuration: const Duration(seconds: 1), - child: FutureBuilder( - future: _initializeControllerFuture, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - // If the Future is complete, display the preview. - return CameraView( - controller: _controller, - initializeControllerFuture: _initializeControllerFuture, - ); - } else { - // Otherwise, display a loading indicator. - return const Center(child: CircularProgressIndicator()); - } - }, - ), - ); - }, - ); - - if (image != null) { - return image; - } else { - throw "failed to take image"; - } - } - - Future _pickImage() async { - final image = await picker.pickImage(source: ImageSource.gallery); - if (image != null) { - return image; - } else { - throw "failed to take image"; - } - } - - Future _addImage() async { - if (DeviceInfo.isPhysicalDeviceWithCamera(deviceInfo)) { - return await _showCamera(); - } else { - return await _pickImage(); - } - } - - @override - Widget build(BuildContext context) { - final viewModel = context.watch(); - - return HighlightBorderOnHoverWidget( - borderRadius: BorderRadius.zero, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only( - left: MarketplaceTheme.spacing7, - top: MarketplaceTheme.spacing7, - ), - child: Text( - 'I have these ingredients:', - style: MarketplaceTheme.dossierParagraph, - ), - ), - SizedBox( - height: widget.height, - child: ListView( - scrollDirection: Axis.horizontal, - children: [ - Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing7), - child: AddImage( - width: widget.width, - height: widget.height, - onTap: () async { - final image = await _addImage(); - viewModel.addImage(image); - }), - ), - for (var image in viewModel.userPrompt.images) - Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing7), - child: PromptImage( - width: widget.width, - file: image, - onTapIcon: () => viewModel.removeImage(image), - ), - ), - ], - ), - ), - ], - ), - ); - } -} - -class CameraView extends StatefulWidget { - final CameraController controller; - final Future initializeControllerFuture; - const CameraView( - {super.key, - required this.controller, - required this.initializeControllerFuture}); - - @override - State createState() => _CameraViewState(); -} - -class _CameraViewState extends State { - bool flashOn = false; - - @override - Widget build(BuildContext context) { - CameraController controller = widget.controller; - return Stack( - children: [ - Center( - child: AspectRatio( - aspectRatio: 9 / 14, - child: ClipRect( - child: FittedBox( - fit: BoxFit.cover, - child: SizedBox( - height: controller.value.previewSize!.width, - width: controller.value.previewSize!.height, - child: Center( - child: CameraPreview( - controller, - // child: ElevatedButton( - // child: Text('Button'), - // onPressed: () {}, - // ), - ), - ), - ), - ), - ), - ), - ), - Positioned( - top: 0, - left: 0, - right: 0, - height: 89.5, - child: Container( - color: Colors.black.withAlpha(179), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: - const EdgeInsets.only(left: MarketplaceTheme.spacing4), - child: IconButton( - icon: Icon( - flashOn ? Symbols.flash_on : Symbols.flash_off, - size: 40, - color: flashOn ? Colors.yellowAccent : Colors.white, - ), - onPressed: () { - controller.setFlashMode( - flashOn ? FlashMode.off : FlashMode.always); - setState(() { - flashOn = !flashOn; - }); - }, - ), - ), - Padding( - padding: - const EdgeInsets.only(right: MarketplaceTheme.spacing4), - child: IconButton( - icon: const Icon( - Symbols.cancel, - color: Colors.white, - size: 40, - ), - onPressed: () async { - Navigator.of(context).pop(); - }, - ), - ), - ], - ), - ), - ), - Positioned( - bottom: 0, - left: 0, - right: 0, - height: 150, - child: Container( - color: Colors.black.withAlpha(179), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - IconButton( - icon: const Icon( - Symbols.camera, - color: Colors.white, - size: 70, - ), - onPressed: () async { - try { - await widget.initializeControllerFuture; - final image = await controller.takePicture(); - if (!context.mounted) return; - Navigator.of(context).pop(image); - } catch (e) { - rethrow; - } - }, - ), - ], - ), - ), - ) - ], - ); - } -} diff --git a/ai_recipe_generation/lib/features/recipes/recipe_model.dart b/ai_recipe_generation/lib/features/recipes/recipe_model.dart deleted file mode 100644 index 00d4a7e79..000000000 --- a/ai_recipe_generation/lib/features/recipes/recipe_model.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'dart:convert'; - -import 'package:ai_recipe_generation/util/json_parsing.dart'; -import 'package:google_generative_ai/google_generative_ai.dart'; - -class Recipe { - Recipe({ - required this.title, - required this.id, - required this.description, - required this.ingredients, - required this.instructions, - required this.cuisine, - required this.allergens, - required this.servings, - required this.nutritionInformation, - this.rating = -1, - }); - - final String id; - final String title; - final String description; - final List ingredients; - final List instructions; - final String cuisine; - final List allergens; - final String servings; - final Map nutritionInformation; - int rating; - - factory Recipe.fromGeneratedContent(GenerateContentResponse content) { - /// failures should be handled when the response is received - assert(content.text != null); - - final validJson = cleanJson(content.text!); - final json = jsonDecode(validJson); - - if (json - case { - "ingredients": List ingredients, - "instructions": List instructions, - "title": String title, - "id": String id, - "cuisine": String cuisine, - "description": String description, - "servings": String servings, - "nutritionInformation": Map nutritionInformation, - "allergens": List allergens, - }) { - return Recipe( - id: id, - title: title, - ingredients: ingredients.map((i) => i.toString()).toList(), - instructions: instructions.map((i) => i.toString()).toList(), - nutritionInformation: nutritionInformation, - allergens: allergens.map((i) => i.toString()).toList(), - cuisine: cuisine, - servings: servings, - description: description); - } - - throw JsonUnsupportedObjectError(json); - } - - Map toFirestore() { - return { - 'id': id, - 'title': title, - 'instructions': instructions, - 'ingredients': ingredients, - 'cuisine': cuisine, - 'rating': rating, - 'allergens': allergens, - 'nutritionInformation': nutritionInformation, - 'servings': servings, - 'description': description, - }; - } - - factory Recipe.fromFirestore(Map data) { - if (data - case { - "ingredients": List ingredients, - "instructions": List instructions, - "title": String title, - "id": String id, - "cuisine": String cuisine, - "description": String description, - "servings": String servings, - "nutritionInformation": Map nutritionInformation, - "allergens": List allergens, - "rating": int rating - }) { - return Recipe( - id: id, - title: title, - ingredients: ingredients.map((i) => i.toString()).toList(), - instructions: instructions.map((i) => i.toString()).toList(), - nutritionInformation: nutritionInformation, - allergens: allergens.map((i) => i.toString()).toList(), - cuisine: cuisine, - servings: servings, - description: description, - rating: rating, - ); - } - - throw "Malformed Firestore data"; - } -} diff --git a/ai_recipe_generation/lib/features/recipes/recipes_view_model.dart b/ai_recipe_generation/lib/features/recipes/recipes_view_model.dart deleted file mode 100644 index 494115dc3..000000000 --- a/ai_recipe_generation/lib/features/recipes/recipes_view_model.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:flutter/cupertino.dart'; - -import '../../services/firestore.dart'; -import 'recipe_model.dart'; - -class SavedRecipesViewModel extends ChangeNotifier { - List recipes = []; - - final recipePath = '/recipes'; - final firestore = FirebaseFirestore.instance; - - SavedRecipesViewModel() { - firestore.collection(recipePath).snapshots().listen((querySnapshot) { - recipes = querySnapshot.docs.map((doc) { - final data = doc.data(); - return Recipe.fromFirestore(data); - }).toList(); - notifyListeners(); - }); - } - - void deleteRecipe(Recipe recipe) { - FirestoreService.deleteRecipe(recipe); - } - - void updateRecipe(Recipe recipe) { - FirestoreService.updateRecipe(recipe); - notifyListeners(); - } -} diff --git a/ai_recipe_generation/lib/features/recipes/saved_recipes_screen.dart b/ai_recipe_generation/lib/features/recipes/saved_recipes_screen.dart deleted file mode 100644 index 604ac64ad..000000000 --- a/ai_recipe_generation/lib/features/recipes/saved_recipes_screen.dart +++ /dev/null @@ -1,263 +0,0 @@ -import 'package:ai_recipe_generation/features/recipes/recipes_view_model.dart'; -import 'package:ai_recipe_generation/features/recipes/widgets/recipe_fullscreen_dialog.dart'; -import 'package:ai_recipe_generation/theme.dart'; -import 'package:ai_recipe_generation/util/extensions.dart'; -import 'package:ai_recipe_generation/widgets/highlight_border_on_hover_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; -import 'package:provider/provider.dart'; - -import '../../widgets/marketplace_button_widget.dart'; -import '../../widgets/star_rating.dart'; -import 'recipe_model.dart'; - -class SavedRecipesScreen extends StatefulWidget { - const SavedRecipesScreen({super.key, required this.canScroll}); - - final bool canScroll; - - @override - State createState() => _SavedRecipesScreenState(); -} - -class _SavedRecipesScreenState extends State - with TickerProviderStateMixin { - @override - Widget build(BuildContext context) { - final viewModel = context.watch(); - return LayoutBuilder( - builder: (context, constraints) { - return Padding( - padding: constraints.isMobile - ? const EdgeInsets.only( - left: MarketplaceTheme.spacing7, - right: MarketplaceTheme.spacing7, - bottom: MarketplaceTheme.spacing7, - top: MarketplaceTheme.spacing7, - ) - : const EdgeInsets.only( - left: MarketplaceTheme.spacing7, - right: MarketplaceTheme.spacing7, - bottom: MarketplaceTheme.spacing1, - top: MarketplaceTheme.spacing7, - ), - child: ClipRRect( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - topRight: Radius.circular(50), - bottomRight: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - child: Container( - decoration: BoxDecoration( - border: Border.all(color: MarketplaceTheme.borderColor), - borderRadius: const BorderRadius.only( - topLeft: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - topRight: Radius.circular(50), - bottomRight: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - color: Colors.white, - ), - child: constraints.isMobile - ? ListView.builder( - physics: widget.canScroll - ? const PageScrollPhysics() - : const NeverScrollableScrollPhysics(), - itemCount: viewModel.recipes.length, - itemBuilder: (context, idx) { - final recipe = viewModel.recipes[idx]; - return Container( - margin: EdgeInsets.only(top: idx == 0 ? 70 : 0), - child: Align( - heightFactor: .5, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: MarketplaceTheme.spacing7, - vertical: MarketplaceTheme.spacing7, - ), - child: SizedBox( - width: MediaQuery.of(context).size.width * .99, - height: 200, - child: _ListTile( - constraints: constraints, - key: Key('$idx-${recipe.hashCode}'), - recipe: recipe, - idx: idx, - ), - ), - ), - ), - ); - }, - ) - : GridView.count( - physics: widget.canScroll - ? const PageScrollPhysics() - : const NeverScrollableScrollPhysics(), - crossAxisCount: 3, - childAspectRatio: 1.5, - children: [ - ...List.generate(viewModel.recipes.length, (idx) { - final recipe = viewModel.recipes[idx]; - return Padding( - padding: const EdgeInsets.symmetric( - horizontal: MarketplaceTheme.spacing7, - vertical: MarketplaceTheme.spacing7, - ), - child: _ListTile( - key: Key('$idx-${recipe.hashCode}'), - recipe: recipe, - idx: idx, - constraints: constraints, - ), - ); - }), - ], - ), - ), - ), - ); - }, - ); - } -} - -class _ListTile extends StatefulWidget { - const _ListTile({ - super.key, - required this.recipe, - this.idx = 0, - required this.constraints, - }); - - final Recipe recipe; - final int idx; - final BoxConstraints constraints; - - @override - State<_ListTile> createState() => _ListTileState(); -} - -class _ListTileState extends State<_ListTile> { - final List colors = [ - MarketplaceTheme.primary, - MarketplaceTheme.secondary, - MarketplaceTheme.tertiary, - MarketplaceTheme.scrim, - ]; - - @override - Widget build(BuildContext context) { - final viewModel = context.watch(); - final color = colors[widget.idx % colors.length]; - - return GestureDetector( - child: HighlightBorderOnHoverWidget( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - topRight: Radius.circular(50), - bottomRight: Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - color: color, - child: Container( - decoration: const BoxDecoration( - boxShadow: [ - BoxShadow( - offset: Offset(0, -2), - color: Colors.black38, - blurRadius: 5, - ), - ], - borderRadius: BorderRadius.only( - topLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - topRight: Radius.circular(50), - bottomRight: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - color: Colors.white, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - topRight: Radius.circular(50), - bottomRight: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - color: color.withAlpha(77), - ), - padding: const EdgeInsets.all(MarketplaceTheme.spacing7), - child: Stack( - children: [ - Text( - widget.recipe.title, - style: MarketplaceTheme.heading3, - ), - Positioned( - top: widget.constraints.isMobile ? 40 : 60, - left: 0, - child: Text( - widget.recipe.cuisine, - style: MarketplaceTheme.subheading1, - ), - ), - Positioned( - right: 15, - top: widget.constraints.isMobile ? 40 : 60, - child: StartRating( - initialRating: widget.recipe.rating, - starColor: color, - onTap: null, - ), - ) - ], - ), - ), - ), - ), - onTap: () async { - await showDialog( - context: context, - builder: (context) { - return RecipeDialogScreen( - recipe: widget.recipe, - subheading: Row( - children: [ - const Text('My rating:'), - const SizedBox(width: 10), - StartRating( - initialRating: widget.recipe.rating, - starColor: MarketplaceTheme.tertiary, - onTap: (index) { - widget.recipe.rating = index + 1; - viewModel.updateRecipe(widget.recipe); - }, - ), - ], - ), - actions: [ - MarketplaceButton( - onPressed: () { - viewModel.deleteRecipe(widget.recipe); - Navigator.of(context).pop(); - }, - buttonText: "Delete Recipe", - icon: Symbols.delete, - ), - ], - ); - }, - ); - }, - ); - } -} diff --git a/ai_recipe_generation/lib/features/recipes/widgets/recipe_display_widget.dart b/ai_recipe_generation/lib/features/recipes/widgets/recipe_display_widget.dart deleted file mode 100644 index 113f2015b..000000000 --- a/ai_recipe_generation/lib/features/recipes/widgets/recipe_display_widget.dart +++ /dev/null @@ -1,277 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import '../../../theme.dart'; -import '../recipe_model.dart'; - -class RecipeDisplayWidget extends StatelessWidget { - const RecipeDisplayWidget({ - super.key, - required this.recipe, - this.subheading, - }); - - final Recipe recipe; - final Widget? subheading; - - List _buildIngredients(List ingredients) { - final widgets = []; - for (var ingredient in ingredients) { - widgets.add( - Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon( - Symbols.stat_0_rounded, - size: 12, - ), - const SizedBox( - width: 5, - ), - Expanded( - child: Text( - ingredient, - softWrap: true, - ), - ), - ], - ), - ); - } - - return widgets; - } - - List _buildInstructions(List instructions) { - final widgets = []; - - // check for existing numbers in instructions. - if (instructions.first.startsWith(RegExp('[0-9]'))) { - for (var instruction in instructions) { - widgets.add(Text(instruction)); - widgets.add(const SizedBox(height: MarketplaceTheme.spacing6)); - } - } else { - for (var i = 0; i < instructions.length; i++) { - widgets.add(Text( - '${i + 1}. ${instructions[i]}', - softWrap: true, - )); - widgets.add(const SizedBox(height: MarketplaceTheme.spacing6)); - } - } - - return widgets; - } - - @override - Widget build(BuildContext context) { - return SingleChildScrollView( - physics: const ClampingScrollPhysics(), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - padding: const EdgeInsets.all(MarketplaceTheme.defaultBorderRadius), - color: MarketplaceTheme.primary.withAlpha(128), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - recipe.title, - softWrap: true, - style: MarketplaceTheme.heading2, - ), - if (subheading != null) - Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing7, - ), - child: subheading, - ), - ], - ), - ), - TextButton( - style: ButtonStyle( - backgroundColor: WidgetStateColor.resolveWith((states) { - if (states.contains(WidgetState.hovered)) { - return MarketplaceTheme.scrim.withAlpha(153); - } - return Colors.white; - }), - shape: WidgetStateProperty.resolveWith( - (states) { - return RoundedRectangleBorder( - side: const BorderSide( - color: MarketplaceTheme.primary), - borderRadius: BorderRadius.circular( - MarketplaceTheme.defaultBorderRadius, - ), - ); - }, - ), - textStyle: WidgetStateTextStyle.resolveWith( - (states) { - return MarketplaceTheme.dossierParagraph.copyWith( - color: Colors.black45, - ); - }, - ), - ), - onPressed: () async { - await showDialog( - context: context, - builder: (context) { - return AlertDialog( - content: Padding( - padding: const EdgeInsets.all( - MarketplaceTheme.spacing7), - child: Text(recipe.description), - ), - ); - }, - ); - }, - child: Transform.translate( - offset: const Offset(0, 5), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing6), - child: Row( - children: [ - SizedBox( - width: 35, - height: 35, - child: SvgPicture.asset( - 'assets/chef_cat.svg', - semanticsLabel: 'Chef cat icon', - ), - ), - Transform.translate( - offset: const Offset(1, -6), - child: Transform.rotate( - angle: -pi / 20.0, - child: Text( - 'Chef Noodle \n says...', - style: MarketplaceTheme.label, - ), - ), - ) - ], - ), - ), - ), - ) - ], - ), - const Divider( - height: 40, - color: Colors.black26, - ), - Table( - columnWidths: const { - 0: FlexColumnWidth(2), - 1: FlexColumnWidth(3), - }, - children: [ - TableRow( - children: [ - Text( - 'Allergens:', - style: MarketplaceTheme.paragraph.copyWith( - fontWeight: FontWeight.bold, - ), - ), - Text(recipe.allergens.join(', ')) - ], - ), - TableRow(children: [ - Text( - 'Servings:', - style: MarketplaceTheme.paragraph.copyWith( - fontWeight: FontWeight.bold, - ), - ), - Text(recipe.servings) - ]), - TableRow(children: [ - Text( - 'Nutrition per serving:', - style: MarketplaceTheme.paragraph.copyWith( - fontWeight: FontWeight.bold, - ), - ), - const Text(''), - ]), - ...recipe.nutritionInformation.entries.map((entry) { - return TableRow(children: [ - Row( - children: [ - const Icon( - Symbols.stat_0_rounded, - size: 12, - ), - const SizedBox( - width: 5, - ), - Expanded( - child: Text( - entry.key, - style: MarketplaceTheme.label, - softWrap: true, - ), - ), - ], - ), - Text(entry.value as String, - style: MarketplaceTheme.label) - ]); - }), - ], - ), - ], - ), - ), - - /// Body section - Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing4), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing7, - ), - child: - Text('Ingredients:', style: MarketplaceTheme.subheading1), - ), - ..._buildIngredients(recipe.ingredients), - const SizedBox(height: MarketplaceTheme.spacing4), - Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing7), - child: Text('Instructions:', - style: MarketplaceTheme.subheading1), - ), - ..._buildInstructions(recipe.instructions), - ], - ), - ) - ], - ), - ); - } -} diff --git a/ai_recipe_generation/lib/features/recipes/widgets/recipe_fullscreen_dialog.dart b/ai_recipe_generation/lib/features/recipes/widgets/recipe_fullscreen_dialog.dart deleted file mode 100644 index 61c21b3e2..000000000 --- a/ai_recipe_generation/lib/features/recipes/widgets/recipe_fullscreen_dialog.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:ai_recipe_generation/features/recipes/widgets/recipe_display_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import '../../../theme.dart'; -import '../../../widgets/marketplace_button_widget.dart'; -import '../recipe_model.dart'; - -class RecipeDialogScreen extends StatelessWidget { - const RecipeDialogScreen({ - super.key, - required this.recipe, - required this.actions, - this.subheading, - }); - - final Recipe recipe; - final List actions; - final Widget? subheading; - - @override - Widget build(BuildContext context) { - return Dialog.fullscreen( - backgroundColor: Colors.white, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: RecipeDisplayWidget( - recipe: recipe, - subheading: subheading, - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing5, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - MarketplaceButton( - onPressed: () { - Navigator.of(context).pop(true); - }, - buttonText: 'Close', - icon: Symbols.close, - ), - ...actions, - ], - ), - ), - ], - ), - ); - } -} diff --git a/ai_recipe_generation/lib/firebase_options.dart b/ai_recipe_generation/lib/firebase_options.dart deleted file mode 100644 index 428d75fe1..000000000 --- a/ai_recipe_generation/lib/firebase_options.dart +++ /dev/null @@ -1,81 +0,0 @@ -// File generated by FlutterFire CLI. -// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members -import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; -import 'package:flutter/foundation.dart' - show defaultTargetPlatform, kIsWeb, TargetPlatform; - -/// Default [FirebaseOptions] for use with your Firebase apps. -/// -/// Example: -/// ```dart -/// import 'firebase_options.dart'; -/// // ... -/// await Firebase.initializeApp( -/// options: DefaultFirebaseOptions.currentPlatform, -/// ); -/// ``` -class DefaultFirebaseOptions { - static FirebaseOptions get currentPlatform { - if (kIsWeb) { - return web; - } - switch (defaultTargetPlatform) { - case TargetPlatform.android: - return android; - case TargetPlatform.iOS: - return ios; - case TargetPlatform.macOS: - return macos; - case TargetPlatform.windows: - throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for windows - ' - 'you can reconfigure this by running the FlutterFire CLI again.', - ); - case TargetPlatform.linux: - throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for linux - ' - 'you can reconfigure this by running the FlutterFire CLI again.', - ); - default: - throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ); - } - } - - static const FirebaseOptions web = FirebaseOptions( - apiKey: 'FIREBASE API KEY', - appId: 'FIREBASE APP ID', - messagingSenderId: 'FIREBASE MESSAGING ID', - projectId: 'PROJECT ID', - authDomain: 'AUTH DOMAIN', - storageBucket: 'STORAGE BUCKET ID', - ); - - static const FirebaseOptions android = FirebaseOptions( - apiKey: 'FIREBASE API KEY', - appId: 'FIREBASE APP ID', - messagingSenderId: 'FIREBASE MESSAGING ID', - projectId: 'PROJECT ID', - authDomain: 'AUTH DOMAIN', - storageBucket: 'STORAGE BUCKET ID', - ); - - static const FirebaseOptions ios = FirebaseOptions( - apiKey: 'FIREBASE API KEY', - appId: 'FIREBASE APP ID', - messagingSenderId: 'FIREBASE MESSAGING ID', - projectId: 'PROJECT ID', - authDomain: 'AUTH DOMAIN', - storageBucket: 'STORAGE BUCKET ID', - ); - - static const FirebaseOptions macos = FirebaseOptions( - apiKey: 'FIREBASE API KEY', - appId: 'FIREBASE APP ID', - messagingSenderId: 'FIREBASE MESSAGING ID', - projectId: 'PROJECT ID', - authDomain: 'AUTH DOMAIN', - storageBucket: 'STORAGE BUCKET ID', - ); -} diff --git a/ai_recipe_generation/lib/main.dart b/ai_recipe_generation/lib/main.dart deleted file mode 100644 index 432c1bb36..000000000 --- a/ai_recipe_generation/lib/main.dart +++ /dev/null @@ -1,122 +0,0 @@ -import 'package:ai_recipe_generation/util/device_info.dart'; -import 'package:ai_recipe_generation/util/tap_recorder.dart'; -import 'package:camera/camera.dart'; -import 'package:device_info_plus/device_info_plus.dart'; -import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:google_generative_ai/google_generative_ai.dart'; -import 'package:provider/provider.dart'; - -import 'features/prompt/prompt_view_model.dart'; -import 'features/recipes/recipes_view_model.dart'; -import 'firebase_options.dart'; -import 'router.dart'; -import 'theme.dart'; - -late CameraDescription camera; -late BaseDeviceInfo deviceInfo; - -void main() async { - WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); - deviceInfo = await DeviceInfo.initialize(DeviceInfoPlugin()); - if (DeviceInfo.isPhysicalDeviceWithCamera(deviceInfo)) { - final cameras = await availableCameras(); - camera = cameras.first; - } - - runApp(const MainApp()); -} - -class MainApp extends StatefulWidget { - const MainApp({super.key}); - - @override - State createState() => _MainAppState(); -} - -class _MainAppState extends State { - late GenerativeModel geminiVisionProModel; - late GenerativeModel geminiProModel; - @override - void initState() { - const apiKey = - String.fromEnvironment('API_KEY', defaultValue: 'key not found'); - if (apiKey == 'key not found') { - throw InvalidApiKey( - 'Key not found in environment. Please add an API key.', - ); - } - - geminiVisionProModel = GenerativeModel( - model: 'gemini-pro-vision', - apiKey: apiKey, - generationConfig: GenerationConfig( - temperature: 0.4, - topK: 32, - topP: 1, - maxOutputTokens: 4096, - ), - safetySettings: [ - SafetySetting(HarmCategory.harassment, HarmBlockThreshold.high), - SafetySetting(HarmCategory.hateSpeech, HarmBlockThreshold.high), - ], - ); - - geminiProModel = GenerativeModel( - model: 'gemini-pro', - apiKey: const String.fromEnvironment('API_KEY'), - generationConfig: GenerationConfig( - temperature: 0.4, - topK: 32, - topP: 1, - maxOutputTokens: 4096, - ), - safetySettings: [ - SafetySetting(HarmCategory.harassment, HarmBlockThreshold.high), - SafetySetting(HarmCategory.hateSpeech, HarmBlockThreshold.high), - ], - ); - - super.initState(); - } - - @override - Widget build(BuildContext context) { - final recipesViewModel = SavedRecipesViewModel(); - - return TapRecorder( - child: MultiProvider( - providers: [ - ChangeNotifierProvider( - create: (_) => PromptViewModel( - multiModalModel: geminiVisionProModel, - textModel: geminiProModel, - ), - ), - ChangeNotifierProvider( - create: (_) => recipesViewModel, - ), - ], - child: SafeArea( - child: MaterialApp( - debugShowCheckedModeBanner: false, - theme: MarketplaceTheme.theme, - scrollBehavior: const ScrollBehavior().copyWith( - dragDevices: { - PointerDeviceKind.mouse, - PointerDeviceKind.touch, - PointerDeviceKind.stylus, - PointerDeviceKind.unknown, - }, - ), - home: const AdaptiveRouter(), - ), - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/router.dart b/ai_recipe_generation/lib/router.dart deleted file mode 100644 index 0ca954f95..000000000 --- a/ai_recipe_generation/lib/router.dart +++ /dev/null @@ -1,244 +0,0 @@ -import 'package:ai_recipe_generation/app_bar.dart'; -import 'package:ai_recipe_generation/features/prompt/prompt_screen.dart'; -import 'package:ai_recipe_generation/features/prompt/prompt_view_model.dart'; -import 'package:ai_recipe_generation/features/recipes/saved_recipes_screen.dart'; -import 'package:ai_recipe_generation/widgets/bottom_bar_shape_border.dart'; -import 'package:ai_recipe_generation/widgets/marketplace_button_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; -import 'package:provider/provider.dart'; - -import 'theme.dart'; -import 'widgets/icon_loading_indicator.dart'; - -const double avatarSize = 50; -const double collapsedHeight = 100; -const double expandedHeight = 300; -const double bottomTabBarHeight = 50; - -class AdaptiveRouter extends StatefulWidget { - const AdaptiveRouter({super.key}); - - @override - State createState() => _AdaptiveRouterState(); -} - -class _AdaptiveRouterState extends State - with TickerProviderStateMixin { - late TextStyle _textStyle; - late ScrollController scrollController; - late TabController tabController; - bool innerScrollAllowed = false; - - @override - void initState() { - super.initState(); - tabController = TabController(length: 2, vsync: this); - _textStyle = MarketplaceTheme.heading1.copyWith( - color: Colors.black87.withAlpha(255), - ); - - scrollController = ScrollController(); - scrollController.addListener(_scrollListener); - } - - double prevOffset = 0; - void _scrollListener() { - setState(() { - innerScrollAllowed = scrollController.offset >= 230; - if (scrollController.offset >= 230) { - scrollController.animateTo(230, - duration: const Duration(milliseconds: 100), - curve: Curves.decelerate); - } - - // Don't change the text opacity if scrolling down from original position (overscroll) - if (scrollController.offset < 0) return; - - // By offset 200, ensure the text is transparent - if (scrollController.offset > 200) { - _textStyle = _textStyle.copyWith( - color: Colors.black87.withAlpha(0), - ); - return; - } - - var value = double.parse( - (1 - (scrollController.offset - 50) / 100).toStringAsFixed(2), - ); - - if (scrollController.offset > 200 && value > 0) value = 0; - if (value > 1) value = 1; - if (value < 0) value = 0; - _textStyle = _textStyle.copyWith( - color: Colors.black87.withAlpha((255 * value).ceil()), - ); - }); - } - - @override - void dispose() { - scrollController.dispose(); - tabController.dispose(); - super.dispose(); - } - - List destinations = [ - const NavigationRailDestination( - icon: Icon(Symbols.home), - label: Text('Create a recipe'), - ), - const NavigationRailDestination( - icon: Icon(Symbols.bookmarks), - label: Text('Saved Recipes'), - ) - ]; - - @override - Widget build(BuildContext context) { - final viewModel = context.watch(); - - return LayoutBuilder( - builder: (context, constraints) { - return Scaffold( - body: Stack( - children: [ - CustomScrollView( - controller: scrollController, - keyboardDismissBehavior: - ScrollViewKeyboardDismissBehavior.onDrag, - slivers: [ - AnimatedAppBar( - scrollController: scrollController, - textStyle: _textStyle, - tabController: tabController, - ), - SliverToBoxAdapter( - child: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: constraints.minHeight, - ), - child: TabBarView( - controller: tabController, - children: [ - PromptScreen( - canScroll: innerScrollAllowed, - ), - SavedRecipesScreen( - canScroll: innerScrollAllowed, - ), - ], - ), - ), - ) - ], - ), - Positioned( - bottom: 0, - left: 0, - right: 0, - child: Container( - height: bottomTabBarHeight, - decoration: ShapeDecoration( - shadows: const [ - BoxShadow( - offset: Offset(1, -1), - color: Colors.black45, - blurRadius: 5, - ) - ], - shape: const BottomBarShapeBorder(50), - color: Theme.of(context).primaryColor, - ), - child: TabBar( - labelColor: Colors.black, - unselectedLabelColor: Colors.black26, - controller: tabController, - onTap: (idx) { - setState(() {}); - }, - dividerColor: Colors.transparent, - tabs: [ - for (var destination in destinations) destination.icon, - ], - ), - ), - ), - if (viewModel.loadingNewRecipe) - Positioned( - top: (MediaQuery.of(context).size.height / 2) - 80, - left: (MediaQuery.of(context).size.width / 2) - 80, - height: 160, - width: 160, - child: IconLoadingAnimator( - icons: const [ - Symbols.icecream, - Symbols.local_pizza, - Symbols.restaurant_menu, - Symbols.egg, - Symbols.bakery_dining, - Symbols.skillet, - Symbols.nutrition, - Symbols.grocery, - Symbols.set_meal, - Icons.egg_alt, - Symbols.oven, - Icons.dinner_dining, - Icons.outdoor_grill, - Icons.cookie, - Icons.blender, - Symbols.stockpot, - ], - ), - ), - if (viewModel.geminiFailureResponse != null) - Positioned( - top: (MediaQuery.of(context).size.height / 4), - left: (MediaQuery.of(context).size.width / 2) - 160, - height: MediaQuery.of(context).size.height / 4, - width: 320, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular( - MarketplaceTheme.defaultBorderRadius), - boxShadow: const [ - BoxShadow( - offset: Offset(-1, 1), - color: Colors.black45, - blurRadius: 5, - ) - ], - color: Colors.white, - border: Border.all( - color: MarketplaceTheme.focusedBorderColor, - width: 1, - ), - ), - child: Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing6), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(viewModel.geminiFailureResponse!), - Align( - alignment: Alignment.bottomRight, - child: MarketplaceButton( - onPressed: () { - viewModel.geminiFailureResponse = null; - }, - buttonText: "Dismiss", - icon: Symbols.close, - ), - ) - ], - ), - ), - ), - ), - ], - ), - ); - }, - ); - } -} diff --git a/ai_recipe_generation/lib/services/firestore.dart b/ai_recipe_generation/lib/services/firestore.dart deleted file mode 100644 index 2a1e599c8..000000000 --- a/ai_recipe_generation/lib/services/firestore.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; - -import '../features/recipes/recipe_model.dart'; - -const recipePath = '/recipes'; -final firestore = FirebaseFirestore.instance; - -class FirestoreService { - static Future saveRecipe(Recipe recipe) async { - await firestore - .collection(recipePath) - .doc(recipe.id) - .set(recipe.toFirestore()); - } - - static Future deleteRecipe(Recipe recipe) async { - await firestore.doc("$recipePath/${recipe.id}").delete(); - } - - static Future updateRecipe(Recipe recipe) async { - await firestore - .doc("$recipePath/${recipe.id}") - .update(recipe.toFirestore()); - } -} diff --git a/ai_recipe_generation/lib/services/gemini.dart b/ai_recipe_generation/lib/services/gemini.dart deleted file mode 100644 index 56c2a6fb2..000000000 --- a/ai_recipe_generation/lib/services/gemini.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:google_generative_ai/google_generative_ai.dart'; - -import '../features/prompt/prompt_model.dart'; - -class GeminiService { - static Future generateContent( - GenerativeModel model, PromptData prompt) async { - if (prompt.images.isEmpty) { - return await GeminiService.generateContentFromText(model, prompt); - } else { - return await GeminiService.generateContentFromMultiModal(model, prompt); - } - } - - static Future generateContentFromMultiModal( - GenerativeModel model, PromptData prompt) async { - final mainText = TextPart(prompt.textInput); - final additionalTextParts = - prompt.additionalTextInputs.map((t) => TextPart(t)); - final imagesParts = []; - - for (var f in prompt.images) { - final bytes = await (f.readAsBytes()); - imagesParts.add(DataPart('image/jpeg', bytes)); - } - - final input = [ - Content.multi([...imagesParts, mainText, ...additionalTextParts]) - ]; - - return await model.generateContent( - input, - generationConfig: GenerationConfig( - temperature: 0.4, - topK: 32, - topP: 1, - maxOutputTokens: 4096, - ), - safetySettings: [ - SafetySetting(HarmCategory.harassment, HarmBlockThreshold.high), - SafetySetting(HarmCategory.hateSpeech, HarmBlockThreshold.high), - ], - ); - } - - static Future generateContentFromText( - GenerativeModel model, PromptData prompt) async { - final mainText = TextPart(prompt.textInput); - final additionalTextParts = - prompt.additionalTextInputs.map((t) => TextPart(t)).join("\n"); - - return await model.generateContent([ - Content.text( - '${mainText.text} \n $additionalTextParts', - ) - ]); - } -} diff --git a/ai_recipe_generation/lib/theme.dart b/ai_recipe_generation/lib/theme.dart deleted file mode 100644 index 1d546de95..000000000 --- a/ai_recipe_generation/lib/theme.dart +++ /dev/null @@ -1,134 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; - -abstract class MarketplaceTheme { - static ThemeData theme = ThemeData( - fontFamily: GoogleFonts.lexend().fontFamily, - textTheme: GoogleFonts.lexendTextTheme().copyWith().apply( - bodyColor: const Color(0xff000000), - displayColor: const Color(0xff000000)), - colorScheme: const ColorScheme.light( - primary: Color(0xffA2E3F6), - secondary: Color(0xff4FAD85), - tertiary: Color(0xffDE7A60), - scrim: Color(0xffFFABC7), - surface: Color(0xffFDF7F0), - onSecondary: Color(0xff000000), - shadow: Color(0xffAEAEAE), - onPrimary: Color(0xffFFFFFF), - ), - useMaterial3: true, - canvasColor: Colors.transparent, - navigationBarTheme: NavigationBarThemeData( - indicatorColor: const Color(0xffA2E3F6), - indicatorShape: CircleBorder( - side: BorderSide.lerp( - const BorderSide( - color: Color(0xff000000), - width: 2, - ), - const BorderSide( - color: Color(0xff000000), - width: 2, - ), - 1), - ), - ), - ); - - static const Color primary = Color(0xffA2E3F6); - static const Color scrim = Color(0xffFFABC7); - static const Color tertiary = Color(0xffDE7A60); - static const Color secondary = Color(0xff4FAD85); - static const Color borderColor = Colors.black12; - static const Color focusedBorderColor = Colors.black45; - - static const double defaultBorderRadius = 16; - - static const double defaultTextSize = 16; - - static const Color defaultTextColor = Colors.black87; - - static TextStyle get heading1 => theme.textTheme.headlineLarge!.copyWith( - fontWeight: FontWeight.bold, - fontSize: 28, - //height: 36, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get heading2 => theme.textTheme.headlineMedium!.copyWith( - fontWeight: FontWeight.bold, - fontSize: 24, - //height: 32, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get heading3 => theme.textTheme.headlineSmall!.copyWith( - fontWeight: FontWeight.bold, - fontSize: 18, - //height: 24, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get subheading1 => theme.textTheme.bodyLarge!.copyWith( - fontWeight: FontWeight.normal, - fontSize: 18, - //height: 20, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get subheading2 => theme.textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.normal, - fontSize: 14, - //height: 18, - color: theme.colorScheme.onSecondary, - ); - static TextStyle get paragraph => theme.textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.normal, - fontSize: 14, - //height: 18, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get label => theme.textTheme.labelSmall!.copyWith( - fontWeight: FontWeight.w600, - fontSize: 11, - //height: 16, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get dossierParagraph => GoogleFonts.anonymousPro().copyWith( - fontWeight: FontWeight.normal, - fontSize: 14, - //height: 18, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get dossierSubheading => GoogleFonts.anonymousPro().copyWith( - fontWeight: FontWeight.normal, - fontSize: 18, - //height: 18, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get dossierHeading => GoogleFonts.anonymousPro().copyWith( - fontWeight: FontWeight.bold, - fontSize: 28, - //height: 18, - color: theme.colorScheme.onSecondary, - ); - - static const double _spacingUnit = 8; - static const double spacing8 = _spacingUnit / 2; - static const double spacing7 = _spacingUnit; - static const double spacing6 = _spacingUnit * 1.5; - static const double spacing5 = _spacingUnit * 2; - static const double spacing4 = _spacingUnit * 2.5; - static const double spacing3 = _spacingUnit * 3; - static const double spacing2 = _spacingUnit * 3.5; - static const double spacing1 = _spacingUnit * 4; - - static double lineWidth = 1; - - static const Widget verticalSpacer = SizedBox(height: spacing5); -} diff --git a/ai_recipe_generation/lib/util/device_info.dart b/ai_recipe_generation/lib/util/device_info.dart deleted file mode 100644 index 9006fbddd..000000000 --- a/ai_recipe_generation/lib/util/device_info.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:device_info_plus/device_info_plus.dart'; -import 'package:flutter/foundation.dart'; - -class DeviceInfo { - static Future initialize(DeviceInfoPlugin plugin) async { - if (kIsWeb) { - return await plugin.webBrowserInfo; - } - switch (defaultTargetPlatform) { - case TargetPlatform.android: - return await plugin.androidInfo; - case TargetPlatform.iOS: - return await plugin.iosInfo; - case TargetPlatform.macOS: - return plugin.macOsInfo; - case TargetPlatform.windows: - return await plugin.windowsInfo; - case TargetPlatform.linux: - return await plugin.linuxInfo; - default: - throw UnsupportedError( - 'Device info not supported for this platform', - ); - } - } - - static bool isPhysicalDeviceWithCamera(BaseDeviceInfo deviceInfo) { - if (deviceInfo is! IosDeviceInfo && deviceInfo is! AndroidDeviceInfo) { - return false; - } - if (deviceInfo is IosDeviceInfo && deviceInfo.isPhysicalDevice) { - return true; - } - if (deviceInfo is AndroidDeviceInfo && deviceInfo.isPhysicalDevice) { - return true; - } - return false; - } -} diff --git a/ai_recipe_generation/lib/util/extensions.dart b/ai_recipe_generation/lib/util/extensions.dart deleted file mode 100644 index 8239f8f8b..000000000 --- a/ai_recipe_generation/lib/util/extensions.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/rendering.dart'; - -extension SliverBreakpointUtils on SliverConstraints { - bool get isTablet => crossAxisExtent > 730 && crossAxisExtent < 1000; - bool get isDesktop => crossAxisExtent > 1000; - bool get isMobile => crossAxisExtent < 730; -} - -extension BoxBreakpointUtils on BoxConstraints { - bool get isTablet => maxWidth > 730 && maxWidth < 1000; - bool get isDesktop => maxWidth > 1000; - bool get isMobile => maxWidth < 730; -} diff --git a/ai_recipe_generation/lib/util/filter_chip_enums.dart b/ai_recipe_generation/lib/util/filter_chip_enums.dart deleted file mode 100644 index da118888f..000000000 --- a/ai_recipe_generation/lib/util/filter_chip_enums.dart +++ /dev/null @@ -1,66 +0,0 @@ -enum CuisineFilter { - italian, - mexican, - american, - french, - japanese, - chinese, - indian, - greek, - moroccan, - ethiopian, - southAfrican, -} - -enum BasicIngredientsFilter { - oil, - butter, - flour, - salt, - pepper, - sugar, - milk, - vinegar, -} - -enum DietaryRestrictionsFilter { - vegan, - vegetarian, - lactoseIntolerant, - kosher, - // keto, - wheatAllergies, - nutAllergies, - fishAllergies, - soyAllergies, -} - -String dietaryRestrictionReadable(DietaryRestrictionsFilter filter) { - return switch (filter) { - DietaryRestrictionsFilter.vegan => 'vegan', - DietaryRestrictionsFilter.vegetarian => 'vegetarian', - DietaryRestrictionsFilter.lactoseIntolerant => 'dairy free', - DietaryRestrictionsFilter.kosher => 'kosher', - // DietaryRestrictionsFilter.keto => 'low carb', - DietaryRestrictionsFilter.wheatAllergies => 'wheat allergy', - DietaryRestrictionsFilter.nutAllergies => 'nut allergy', - DietaryRestrictionsFilter.fishAllergies => 'fish allergy', - DietaryRestrictionsFilter.soyAllergies => 'soy allergy', - }; -} - -String cuisineReadable(CuisineFilter filter) { - return switch (filter) { - CuisineFilter.italian => 'Italian', - CuisineFilter.mexican => 'Mexican', - CuisineFilter.american => 'American', - CuisineFilter.french => 'French', - CuisineFilter.japanese => 'Japanese', - CuisineFilter.chinese => 'Chinese', - CuisineFilter.indian => 'Indian', - CuisineFilter.ethiopian => 'Ethiopian', - CuisineFilter.moroccan => 'Moroccan', - CuisineFilter.greek => 'Greek', - CuisineFilter.southAfrican => 'South African', - }; -} diff --git a/ai_recipe_generation/lib/util/json_parsing.dart b/ai_recipe_generation/lib/util/json_parsing.dart deleted file mode 100644 index 515a3404e..000000000 --- a/ai_recipe_generation/lib/util/json_parsing.dart +++ /dev/null @@ -1,8 +0,0 @@ -String cleanJson(String maybeInvalidJson) { - if (maybeInvalidJson.contains('```')) { - final withoutLeading = maybeInvalidJson.split('```json').last; - final withoutTrailing = withoutLeading.split('```').first; - return withoutTrailing; - } - return maybeInvalidJson; -} diff --git a/ai_recipe_generation/lib/util/tap_recorder.dart b/ai_recipe_generation/lib/util/tap_recorder.dart deleted file mode 100644 index d411473c5..000000000 --- a/ai_recipe_generation/lib/util/tap_recorder.dart +++ /dev/null @@ -1,121 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter/scheduler.dart'; - -/// From: https://gist.github.com/creativecreatorormaybenot/cd42b60cb33c9962b19f629ec638d4de -/// This is code that I (https://twitter.com/creativemaybeno) wrote for a -/// StackOverflow answer. -/// You can find it here: https://stackoverflow.com/a/65067655/6509751. -/// List of the taps recorded by [TapRecorder]. -/// -/// This is only a make-shift solution of course. This will only be viable -/// when using a single [TapRecorder] because it is saved as a top-level -/// variable. -@visibleForTesting -final recordedTaps = []; - -/// These are the parameters for the visualization of the recorded taps. -const _tapRadius = 15.0, - _tapDuration = Duration(milliseconds: 420), - _tapColor = Colors.white, - _shadowColor = Colors.black, - _shadowElevation = 2.0; - -/// Widget that records any taps that hit its child. -/// -/// It does not matter to this widget whether the child accepts the hit events. -/// Everything hitting the rect of the child will be recorded. -/// -/// It will both visualize them and add them to [recordedTaps]. -class TapRecorder extends SingleChildRenderObjectWidget { - const TapRecorder({super.key, required Widget child}) : super(child: child); - - @override - RenderObject createRenderObject(BuildContext context) { - return _RenderTapRecorder(); - } -} - -class _RenderTapRecorder extends RenderProxyBox with _SilentTickerProvider { - final _recordedTaps = <_RecordedTap>[]; - - @override - void detach() { - for (final recordedTap in _recordedTaps) { - (recordedTap.animation as AnimationController).dispose(); - } - _recordedTaps.clear(); - super.detach(); - } - - @override - bool hitTest(BoxHitTestResult result, {required Offset position}) { - if (!size.contains(position)) return false; - // We always want to add a hit test entry for ourselves as we want to react - // to each and every hit event. - result.add(BoxHitTestEntry(this, position)); - return hitTestChildren(result, position: position); - } - - @override - void handleEvent(PointerEvent event, covariant HitTestEntry entry) { - // We do not want to interfere in the gesture arena, which is why we are not - // using regular tap recognizers. Instead, we handle it ourselves and always - // react to the hit events (ignoring the gesture arena). - if (event is PointerDownEvent) { - // Records the global position. - recordedTaps.add(event.position); - - final controller = AnimationController( - vsync: this, - duration: _tapDuration, - ), - recordedTap = _RecordedTap(event.localPosition, controller); - _recordedTaps.add(recordedTap); - - controller - ..addListener(markNeedsPaint) - ..addStatusListener((status) { - if (status == AnimationStatus.completed) { - controller.dispose(); - _recordedTaps.remove(recordedTap); - } - }) - ..forward(); - } - } - - @override - void paint(PaintingContext context, Offset offset) { - context.paintChild(child!, offset); - - final canvas = context.canvas; - for (final tap in _recordedTaps) { - final path = Path() - ..addOval( - Rect.fromCircle(center: tap.localPosition, radius: _tapRadius)); - final opacity = 1 - tap.animation.value; - - canvas.drawShadow(path, _shadowColor.withAlpha((2565 * opacity).ceil()), - _shadowElevation, true); - canvas.drawPath( - path, Paint()..color = _tapColor.withAlpha((2565 * opacity).ceil())); - } - } -} - -class _RecordedTap { - _RecordedTap(this.localPosition, this.animation); - - final Offset localPosition; - final Animation animation; -} - -/// Ticker provider that does not perform any diagnostics. -/// -/// We trust that the [_RenderTapRecorder] instance will dispose all tickers -/// by disposing the animation controllers. -mixin _SilentTickerProvider implements TickerProvider { - @override - Ticker createTicker(TickerCallback onTick) => Ticker(onTick); -} diff --git a/ai_recipe_generation/lib/widgets/add_image_widget.dart b/ai_recipe_generation/lib/widgets/add_image_widget.dart deleted file mode 100644 index 8f1fe6dee..000000000 --- a/ai_recipe_generation/lib/widgets/add_image_widget.dart +++ /dev/null @@ -1,85 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import '../theme.dart'; - -class AddImage extends StatefulWidget { - const AddImage({ - super.key, - required this.onTap, - this.height = 100, - this.width = 100, - }); - - final VoidCallback onTap; - final double height; - final double width; - - @override - State createState() => _AddImageState(); -} - -class _AddImageState extends State { - bool hovered = false; - bool tappedDown = false; - - Color get buttonColor { - var state = (hovered, tappedDown); - return switch (state) { - // tapped down state - (_, true) => MarketplaceTheme.secondary.withAlpha(179), - // hovered - (true, _) => MarketplaceTheme.secondary.withAlpha(77), - // base color - (_, _) => MarketplaceTheme.secondary.withAlpha(77), - }; - } - - @override - Widget build(BuildContext context) { - return MouseRegion( - onEnter: (event) { - setState(() { - hovered = true; - }); - }, - onExit: (event) { - setState(() { - hovered = false; - }); - }, - child: GestureDetector( - onTapDown: (details) { - setState(() { - tappedDown = true; - }); - }, - onTapUp: (details) { - setState(() { - tappedDown = false; - }); - widget.onTap(); - }, - child: SizedBox( - width: widget.width, - height: widget.height, - child: ClipRRect( - borderRadius: - BorderRadius.circular(MarketplaceTheme.defaultBorderRadius), - child: Container( - decoration: BoxDecoration( - color: buttonColor, - ), - child: const Center( - child: Icon( - Symbols.add_photo_alternate_rounded, - size: 32, - ), - ), - ), - ), - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/widgets/appbar_shape_border.dart b/ai_recipe_generation/lib/widgets/appbar_shape_border.dart deleted file mode 100644 index e9198c10e..000000000 --- a/ai_recipe_generation/lib/widgets/appbar_shape_border.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; - -class AppBarShapeBorder extends ShapeBorder { - final double radius; - - const AppBarShapeBorder(this.radius); - - @override - EdgeInsetsGeometry get dimensions => EdgeInsets.zero; - - @override - Path getInnerPath(Rect rect, {TextDirection? textDirection}) { - return Path(); // Define inner path if needed - } - - @override - Path getOuterPath(Rect rect, {TextDirection? textDirection}) { - // Define your custom shape path here - Path path = Path(); - path.moveTo(rect.left, rect.top); - path.lineTo(rect.left, rect.bottom - (radius * 2)); - - path.quadraticBezierTo( - rect.left, - rect.bottom - radius, - rect.left + radius, - rect.bottom - radius, - ); - - path.lineTo(rect.right - radius, rect.bottom - radius); - - path.quadraticBezierTo( - rect.right, rect.bottom - radius, rect.right, rect.bottom); - - path.lineTo(rect.right, rect.top); - path.close(); - return path; - } - - @override - void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { - // Define your painting logic here - Paint paint = Paint()..color = Colors.transparent; - canvas.drawPath(getOuterPath(rect), paint); - } - - @override - ShapeBorder scale(double t) { - // Implement scaling if needed - return this; - } -} diff --git a/ai_recipe_generation/lib/widgets/bottom_bar_shape_border.dart b/ai_recipe_generation/lib/widgets/bottom_bar_shape_border.dart deleted file mode 100644 index f55fa02e6..000000000 --- a/ai_recipe_generation/lib/widgets/bottom_bar_shape_border.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; - -class BottomBarShapeBorder extends ShapeBorder { - final double radius; - - const BottomBarShapeBorder(this.radius); - - @override - EdgeInsetsGeometry get dimensions => EdgeInsets.zero; - - @override - Path getInnerPath(Rect rect, {TextDirection? textDirection}) { - return Path(); // Define inner path if needed - } - - @override - Path getOuterPath(Rect rect, {TextDirection? textDirection}) { - // Define your custom shape path here - Path path = Path(); - path.moveTo(rect.left, rect.top - radius); - path.quadraticBezierTo( - rect.left, - rect.top, - rect.left + radius, - rect.top, - ); - - path.lineTo(rect.right - radius, rect.top); - path.quadraticBezierTo( - rect.right, - rect.top, - rect.right, - rect.bottom, - ); - - path.lineTo(rect.left, rect.bottom); - path.lineTo(rect.left, rect.top + radius); - path.close(); - return path; - } - - @override - void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { - // Define your painting logic here - Paint paint = Paint()..color = Colors.transparent; - canvas.drawPath(getOuterPath(rect), paint); - } - - @override - ShapeBorder scale(double t) { - // Implement scaling if needed - return this; - } -} diff --git a/ai_recipe_generation/lib/widgets/cross_image_widget.dart b/ai_recipe_generation/lib/widgets/cross_image_widget.dart deleted file mode 100644 index 308204731..000000000 --- a/ai_recipe_generation/lib/widgets/cross_image_widget.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:image_picker/image_picker.dart'; - -class CrossImage extends StatelessWidget { - const CrossImage({ - super.key, - required this.file, - this.fit = BoxFit.cover, - this.height = 100, - this.width = 100, - }); - - final XFile file; - final BoxFit fit; - final double width; - final double height; - - @override - Widget build(BuildContext context) { - if (kIsWeb) { - return Image.network( - file.path, - fit: fit, - ); - } else { - return Image.file( - File(file.path), - height: height, - width: width, - ); - } - } - - static DecorationImage decoration(XFile file, {BoxFit fit = BoxFit.cover}) { - final image = kIsWeb ? NetworkImage(file.path) : FileImage(File(file.path)); - return DecorationImage(image: image as ImageProvider, fit: fit); - } -} diff --git a/ai_recipe_generation/lib/widgets/filter_chip_selection_input.dart b/ai_recipe_generation/lib/widgets/filter_chip_selection_input.dart deleted file mode 100644 index 5d403699c..000000000 --- a/ai_recipe_generation/lib/widgets/filter_chip_selection_input.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'package:ai_recipe_generation/theme.dart'; -import 'package:ai_recipe_generation/util/extensions.dart'; -import 'package:ai_recipe_generation/util/filter_chip_enums.dart'; -import 'package:flutter/material.dart'; - -class FilterChipSelectionInput extends StatefulWidget { - const FilterChipSelectionInput({ - super.key, - required this.onChipSelected, - required this.selectedValues, - required this.allValues, - }); - - final Null Function(Set) onChipSelected; - final Set selectedValues; - final List allValues; - - @override - State createState() => - _CategorySelectionInputState(); -} - -class _CategorySelectionInputState - extends State { - bool isExpanded = false; - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, constraints) { - return Theme( - data: Theme.of(context).copyWith(canvasColor: Colors.transparent), - child: Wrap( - spacing: 5.0, - runSpacing: constraints.isMobile ? 5.0 : -5.0, - children: List.generate( - widget.allValues.length, - (idx) { - final chipData = widget.allValues[idx]; - String label(dynamic chipData) { - if (chipData is CuisineFilter) { - return cuisineReadable(chipData); - } else if (chipData is DietaryRestrictionsFilter) { - return dietaryRestrictionReadable(chipData); - } else if (chipData is BasicIngredientsFilter) { - return chipData.name; - } else { - throw "unknown enum"; - } - } - - return FilterChip( - color: WidgetStateColor.resolveWith((states) { - if (states.contains(WidgetState.hovered)) { - return MarketplaceTheme.secondary.withAlpha(128); - } - if (states.contains(WidgetState.selected)) { - return MarketplaceTheme.secondary.withAlpha(77); - } - return Theme.of(context).splashColor; - }), - surfaceTintColor: Colors.transparent, - shadowColor: Colors.transparent, - backgroundColor: Colors.transparent, - padding: const EdgeInsets.all(4), - label: Text( - label(chipData), - style: MarketplaceTheme.dossierParagraph, - ), - selected: widget.selectedValues.contains(chipData), - onSelected: (selected) { - setState( - () { - if (selected) { - widget.selectedValues.add(chipData as T); - } else { - widget.selectedValues.remove(chipData); - } - widget.onChipSelected(widget.selectedValues); - }, - ); - }, - ); - }, - ).toList(), - ), - ); - }); - } -} diff --git a/ai_recipe_generation/lib/widgets/highlight_border_on_hover_widget.dart b/ai_recipe_generation/lib/widgets/highlight_border_on_hover_widget.dart deleted file mode 100644 index d6fe3591c..000000000 --- a/ai_recipe_generation/lib/widgets/highlight_border_on_hover_widget.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../theme.dart'; - -class HighlightBorderOnHoverWidget extends StatefulWidget { - const HighlightBorderOnHoverWidget({ - super.key, - required this.child, - this.color = MarketplaceTheme.secondary, - required this.borderRadius, - }); - - final Widget child; - final Color color; - final BorderRadius borderRadius; - - @override - State createState() => - _HighlightBorderOnHoverWidgetState(); -} - -class _HighlightBorderOnHoverWidgetState - extends State { - bool hovered = false; - - @override - Widget build(BuildContext context) { - return MouseRegion( - onEnter: (event) { - setState(() { - hovered = true; - }); - }, - onExit: (event) { - setState(() { - hovered = false; - }); - }, - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).splashColor.withAlpha(25), - border: Border.all( - color: hovered ? widget.color : MarketplaceTheme.borderColor, - ), - borderRadius: widget.borderRadius, - ), - child: widget.child, - ), - ); - } -} diff --git a/ai_recipe_generation/lib/widgets/icon_loading_indicator.dart b/ai_recipe_generation/lib/widgets/icon_loading_indicator.dart deleted file mode 100644 index 3b746222c..000000000 --- a/ai_recipe_generation/lib/widgets/icon_loading_indicator.dart +++ /dev/null @@ -1,93 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:ai_recipe_generation/theme.dart'; -import 'package:flutter/material.dart'; - -class IconLoadingAnimator extends StatefulWidget { - IconLoadingAnimator({ - super.key, - required this.icons, - this.animationDuration, - this.millisecondsBetweenAnimations, - }); - - final List icons; - final Duration? animationDuration; - final int? millisecondsBetweenAnimations; - final List colors = [ - MarketplaceTheme.primary, - MarketplaceTheme.secondary, - MarketplaceTheme.tertiary, - MarketplaceTheme.scrim, - Colors.black87, - ]; - - @override - State createState() => _IconLoadingAnimatorState(); -} - -var rand = Random(); - -class _IconLoadingAnimatorState extends State { - late IconData currentIcon; - late Color currentColor; - late Timer timer; - - @override - void initState() { - super.initState(); - - currentIcon = widget.icons[rand.nextInt(widget.icons.length)]; - currentColor = widget.colors[rand.nextInt(widget.colors.length)]; - - timer = Timer.periodic( - Duration(milliseconds: widget.millisecondsBetweenAnimations ?? 1000), - (timer) { - nextIcon(); - }, - ); - } - - void nextIcon() { - setState(() { - currentIcon = widget.icons[rand.nextInt(widget.icons.length)]; - currentColor = widget.colors[rand.nextInt(widget.colors.length)]; - }); - } - - @override - void dispose() { - timer.cancel(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Colors.white, - border: Border.all( - color: MarketplaceTheme.focusedBorderColor, - width: 2, - ), - ), - child: AnimatedSwitcher( - duration: widget.animationDuration ?? const Duration(milliseconds: 200), - transitionBuilder: (child, animation) { - return ScaleTransition( - scale: animation, - child: child, - ); - }, - child: Icon( - size: 75, - color: currentColor, - key: Key(currentIcon.hashCode.toString()), - currentIcon, - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/widgets/marketplace_button_widget.dart b/ai_recipe_generation/lib/widgets/marketplace_button_widget.dart deleted file mode 100644 index 53cce4aaa..000000000 --- a/ai_recipe_generation/lib/widgets/marketplace_button_widget.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../theme.dart'; - -class MarketplaceButton extends StatefulWidget { - const MarketplaceButton({ - super.key, - required this.onPressed, - required this.buttonText, - required this.icon, - this.iconRotateAngle, - this.iconBackgroundColor, - this.iconColor, - this.buttonBackgroundColor, - this.hoverColor, - }); - - final VoidCallback? onPressed; - final String buttonText; - final IconData icon; - final double? iconRotateAngle; - final Color? iconBackgroundColor; - final Color? iconColor; - final Color? buttonBackgroundColor; - final Color? hoverColor; - - @override - State createState() => _MarketplaceButtonState(); -} - -class _MarketplaceButtonState extends State { - @override - Widget build(BuildContext context) { - return TextButton.icon( - icon: Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - color: widget.iconBackgroundColor ?? Colors.transparent, - ), - child: Transform.rotate( - angle: widget.iconRotateAngle ?? 0, - child: Icon( - widget.icon, - color: widget.iconColor ?? Colors.black87, - size: 20.0, - ), - ), - ), - label: Text( - widget.buttonText, - style: MarketplaceTheme.dossierParagraph, - ), - onPressed: widget.onPressed, - style: ButtonStyle( - backgroundColor: WidgetStateColor.resolveWith((states) { - if (states.contains(WidgetState.hovered)) { - return widget.hoverColor ?? - MarketplaceTheme.secondary.withAlpha(77); - } - return widget.buttonBackgroundColor ?? - Theme.of(context).splashColor.withAlpha(77); - }), - shape: WidgetStateProperty.resolveWith( - (states) { - if (states.contains(WidgetState.hovered)) { - // TODO: how can I animate between states? - } - return const RoundedRectangleBorder( - side: BorderSide(color: Colors.black26), - borderRadius: BorderRadius.all( - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - ); - }, - ), - textStyle: WidgetStateTextStyle.resolveWith( - (states) { - return MarketplaceTheme.dossierParagraph.copyWith( - color: Colors.black45, - ); - }, - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/widgets/prompt_image_widget.dart b/ai_recipe_generation/lib/widgets/prompt_image_widget.dart deleted file mode 100644 index 860726f8c..000000000 --- a/ai_recipe_generation/lib/widgets/prompt_image_widget.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:ai_recipe_generation/theme.dart'; -import 'package:flutter/material.dart'; -import 'package:image_picker/image_picker.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import 'cross_image_widget.dart'; - -typedef OnTapRemoveImageCallback = void Function(XFile); - -class PromptImage extends StatelessWidget { - const PromptImage({ - super.key, - required this.file, - this.onTapIcon, - this.width = 100, - }); - - final XFile file; - final VoidCallback? onTapIcon; - final double width; - - @override - Widget build(BuildContext context) { - return SizedBox( - width: width, - child: Stack( - children: [ - Positioned( - child: ClipRRect( - borderRadius: const BorderRadius.all( - Radius.circular( - MarketplaceTheme.defaultBorderRadius, - ), - ), - child: Container( - foregroundDecoration: BoxDecoration( - image: CrossImage.decoration(file), - ), - ), - ), - ), - if (onTapIcon != null) - Positioned( - right: 5, - top: 5, - child: GestureDetector( - onTap: onTapIcon, - child: Container( - decoration: const BoxDecoration( - color: Colors.white, - shape: BoxShape.circle, - ), - child: Icon( - Symbols.remove, - size: 16, - color: Colors.red.shade400, - ), - ), - ), - ), - ], - ), - ); - } -} diff --git a/ai_recipe_generation/lib/widgets/star_rating.dart b/ai_recipe_generation/lib/widgets/star_rating.dart deleted file mode 100644 index 8650ca8d9..000000000 --- a/ai_recipe_generation/lib/widgets/star_rating.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -typedef StarRatingCallback = void Function(int); - -class StartRating extends StatefulWidget { - const StartRating({ - super.key, - required this.starColor, - required this.onTap, - this.initialRating = -1, - }); - - final Color starColor; - final int initialRating; - - /// If [onTap] is not null, the stars are interactive - final StarRatingCallback? onTap; - - @override - State createState() => _StartRatingState(); -} - -class _StartRatingState extends State { - late int selectedIdx; - - @override - void initState() { - selectedIdx = widget.initialRating - 1; - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Row( - children: [ - ...List.generate( - 5, - (index) => GestureDetector( - onTap: widget.onTap != null - ? () { - setState(() { - selectedIdx = index; - }); - widget.onTap!(index); - } - : null, - child: Icon( - Symbols.kid_star, - color: widget.starColor, - fill: selectedIdx >= index ? 1 : 0, - ), - ), - ) - ], - ); - } -} diff --git a/ai_recipe_generation/linux/.gitignore b/ai_recipe_generation/linux/.gitignore deleted file mode 100644 index d3896c984..000000000 --- a/ai_recipe_generation/linux/.gitignore +++ /dev/null @@ -1 +0,0 @@ -flutter/ephemeral diff --git a/ai_recipe_generation/linux/CMakeLists.txt b/ai_recipe_generation/linux/CMakeLists.txt deleted file mode 100644 index 7eaab24db..000000000 --- a/ai_recipe_generation/linux/CMakeLists.txt +++ /dev/null @@ -1,145 +0,0 @@ -# Project-level configuration. -cmake_minimum_required(VERSION 3.10) -project(runner LANGUAGES CXX) - -# The name of the executable created for the application. Change this to change -# the on-disk name of your application. -set(BINARY_NAME "gemini_io_talk") -# The unique GTK application identifier for this application. See: -# https://wiki.gnome.org/HowDoI/ChooseApplicationID -set(APPLICATION_ID "com.example.gemini_io_talk") - -# Explicitly opt in to modern CMake behaviors to avoid warnings with recent -# versions of CMake. -cmake_policy(SET CMP0063 NEW) - -# Load bundled libraries from the lib/ directory relative to the binary. -set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") - -# Root filesystem for cross-building. -if(FLUTTER_TARGET_PLATFORM_SYSROOT) - set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -endif() - -# Define build configuration options. -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") -endif() - -# Compilation settings that should be applied to most targets. -# -# Be cautious about adding new options here, as plugins use this function by -# default. In most cases, you should add new options to specific targets instead -# of modifying this function. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_14) - target_compile_options(${TARGET} PRIVATE -Wall -Werror) - target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") - target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") -endfunction() - -# Flutter library and tool build rules. -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) - -add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") - -# Define the application target. To change its name, change BINARY_NAME above, -# not the value here, or `flutter run` will no longer work. -# -# Any new source files that you add to the application should be added here. -add_executable(${BINARY_NAME} - "main.cc" - "my_application.cc" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" -) - -# Apply the standard set of build settings. This can be removed for applications -# that need different build settings. -apply_standard_settings(${BINARY_NAME}) - -# Add dependency libraries. Add any application-specific dependencies here. -target_link_libraries(${BINARY_NAME} PRIVATE flutter) -target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) - -# Run the Flutter tool portions of the build. This must not be removed. -add_dependencies(${BINARY_NAME} flutter_assemble) - -# Only the install-generated bundle's copy of the executable will launch -# correctly, since the resources must in the right relative locations. To avoid -# people trying to run the unbundled copy, put it in a subdirectory instead of -# the default top-level location. -set_target_properties(${BINARY_NAME} - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" -) - - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - - -# === Installation === -# By default, "installing" just makes a relocatable bundle in the build -# directory. -set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -# Start with a clean build bundle directory every time. -install(CODE " - file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") - " COMPONENT Runtime) - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) - install(FILES "${bundled_library}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endforeach(bundled_library) - -# Copy the native assets provided by the build.dart from all packages. -set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") -install(DIRECTORY "${NATIVE_ASSETS_DIR}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") - install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() diff --git a/ai_recipe_generation/linux/flutter/CMakeLists.txt b/ai_recipe_generation/linux/flutter/CMakeLists.txt deleted file mode 100644 index d5bd01648..000000000 --- a/ai_recipe_generation/linux/flutter/CMakeLists.txt +++ /dev/null @@ -1,88 +0,0 @@ -# This file controls Flutter-level build steps. It should not be edited. -cmake_minimum_required(VERSION 3.10) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. - -# Serves the same purpose as list(TRANSFORM ... PREPEND ...), -# which isn't available in 3.10. -function(list_prepend LIST_NAME PREFIX) - set(NEW_LIST "") - foreach(element ${${LIST_NAME}}) - list(APPEND NEW_LIST "${PREFIX}${element}") - endforeach(element) - set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) -endfunction() - -# === Flutter Library === -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) -pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) -pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) - -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "fl_basic_message_channel.h" - "fl_binary_codec.h" - "fl_binary_messenger.h" - "fl_dart_project.h" - "fl_engine.h" - "fl_json_message_codec.h" - "fl_json_method_codec.h" - "fl_message_codec.h" - "fl_method_call.h" - "fl_method_channel.h" - "fl_method_codec.h" - "fl_method_response.h" - "fl_plugin_registrar.h" - "fl_plugin_registry.h" - "fl_standard_message_codec.h" - "fl_standard_method_codec.h" - "fl_string_codec.h" - "fl_value.h" - "fl_view.h" - "flutter_linux.h" -) -list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") -target_link_libraries(flutter INTERFACE - PkgConfig::GTK - PkgConfig::GLIB - PkgConfig::GIO -) -add_dependencies(flutter flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CMAKE_CURRENT_BINARY_DIR}/_phony_ - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" - ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} -) diff --git a/ai_recipe_generation/linux/flutter/generated_plugin_registrant.cc b/ai_recipe_generation/linux/flutter/generated_plugin_registrant.cc deleted file mode 100644 index 64a0ecea4..000000000 --- a/ai_recipe_generation/linux/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include - -void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); - file_selector_plugin_register_with_registrar(file_selector_linux_registrar); -} diff --git a/ai_recipe_generation/linux/flutter/generated_plugin_registrant.h b/ai_recipe_generation/linux/flutter/generated_plugin_registrant.h deleted file mode 100644 index e0f0a47bc..000000000 --- a/ai_recipe_generation/linux/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void fl_register_plugins(FlPluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/ai_recipe_generation/linux/flutter/generated_plugins.cmake b/ai_recipe_generation/linux/flutter/generated_plugins.cmake deleted file mode 100644 index 2db3c22ae..000000000 --- a/ai_recipe_generation/linux/flutter/generated_plugins.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - file_selector_linux -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/ai_recipe_generation/linux/main.cc b/ai_recipe_generation/linux/main.cc deleted file mode 100644 index e7c5c5437..000000000 --- a/ai_recipe_generation/linux/main.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include "my_application.h" - -int main(int argc, char** argv) { - g_autoptr(MyApplication) app = my_application_new(); - return g_application_run(G_APPLICATION(app), argc, argv); -} diff --git a/ai_recipe_generation/linux/my_application.cc b/ai_recipe_generation/linux/my_application.cc deleted file mode 100644 index 1e94f6892..000000000 --- a/ai_recipe_generation/linux/my_application.cc +++ /dev/null @@ -1,104 +0,0 @@ -#include "my_application.h" - -#include -#ifdef GDK_WINDOWING_X11 -#include -#endif - -#include "flutter/generated_plugin_registrant.h" - -struct _MyApplication { - GtkApplication parent_instance; - char** dart_entrypoint_arguments; -}; - -G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) - -// Implements GApplication::activate. -static void my_application_activate(GApplication* application) { - MyApplication* self = MY_APPLICATION(application); - GtkWindow* window = - GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); - - // Use a header bar when running in GNOME as this is the common style used - // by applications and is the setup most users will be using (e.g. Ubuntu - // desktop). - // If running on X and not using GNOME then just use a traditional title bar - // in case the window manager does more exotic layout, e.g. tiling. - // If running on Wayland assume the header bar will work (may need changing - // if future cases occur). - gboolean use_header_bar = TRUE; -#ifdef GDK_WINDOWING_X11 - GdkScreen* screen = gtk_window_get_screen(window); - if (GDK_IS_X11_SCREEN(screen)) { - const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); - if (g_strcmp0(wm_name, "GNOME Shell") != 0) { - use_header_bar = FALSE; - } - } -#endif - if (use_header_bar) { - GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); - gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "gemini_io_talk"); - gtk_header_bar_set_show_close_button(header_bar, TRUE); - gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); - } else { - gtk_window_set_title(window, "gemini_io_talk"); - } - - gtk_window_set_default_size(window, 1280, 720); - gtk_widget_show(GTK_WIDGET(window)); - - g_autoptr(FlDartProject) project = fl_dart_project_new(); - fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); - - FlView* view = fl_view_new(project); - gtk_widget_show(GTK_WIDGET(view)); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); - - fl_register_plugins(FL_PLUGIN_REGISTRY(view)); - - gtk_widget_grab_focus(GTK_WIDGET(view)); -} - -// Implements GApplication::local_command_line. -static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { - MyApplication* self = MY_APPLICATION(application); - // Strip out the first argument as it is the binary name. - self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); - - g_autoptr(GError) error = nullptr; - if (!g_application_register(application, nullptr, &error)) { - g_warning("Failed to register: %s", error->message); - *exit_status = 1; - return TRUE; - } - - g_application_activate(application); - *exit_status = 0; - - return TRUE; -} - -// Implements GObject::dispose. -static void my_application_dispose(GObject* object) { - MyApplication* self = MY_APPLICATION(object); - g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); - G_OBJECT_CLASS(my_application_parent_class)->dispose(object); -} - -static void my_application_class_init(MyApplicationClass* klass) { - G_APPLICATION_CLASS(klass)->activate = my_application_activate; - G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; - G_OBJECT_CLASS(klass)->dispose = my_application_dispose; -} - -static void my_application_init(MyApplication* self) {} - -MyApplication* my_application_new() { - return MY_APPLICATION(g_object_new(my_application_get_type(), - "application-id", APPLICATION_ID, - "flags", G_APPLICATION_NON_UNIQUE, - nullptr)); -} diff --git a/ai_recipe_generation/linux/my_application.h b/ai_recipe_generation/linux/my_application.h deleted file mode 100644 index 72271d5e4..000000000 --- a/ai_recipe_generation/linux/my_application.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FLUTTER_MY_APPLICATION_H_ -#define FLUTTER_MY_APPLICATION_H_ - -#include - -G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, - GtkApplication) - -/** - * my_application_new: - * - * Creates a new Flutter-based application. - * - * Returns: a new #MyApplication. - */ -MyApplication* my_application_new(); - -#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/ai_recipe_generation/macos/.gitignore b/ai_recipe_generation/macos/.gitignore deleted file mode 100644 index 746adbb6b..000000000 --- a/ai_recipe_generation/macos/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# Flutter-related -**/Flutter/ephemeral/ -**/Pods/ - -# Xcode-related -**/dgph -**/xcuserdata/ diff --git a/ai_recipe_generation/macos/Flutter/Flutter-Debug.xcconfig b/ai_recipe_generation/macos/Flutter/Flutter-Debug.xcconfig deleted file mode 100644 index 4b81f9b2d..000000000 --- a/ai_recipe_generation/macos/Flutter/Flutter-Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/ai_recipe_generation/macos/Flutter/Flutter-Release.xcconfig b/ai_recipe_generation/macos/Flutter/Flutter-Release.xcconfig deleted file mode 100644 index 5caa9d157..000000000 --- a/ai_recipe_generation/macos/Flutter/Flutter-Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/ai_recipe_generation/macos/Flutter/GeneratedPluginRegistrant.swift b/ai_recipe_generation/macos/Flutter/GeneratedPluginRegistrant.swift deleted file mode 100644 index 400a1a849..000000000 --- a/ai_recipe_generation/macos/Flutter/GeneratedPluginRegistrant.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// Generated file. Do not edit. -// - -import FlutterMacOS -import Foundation - -import cloud_firestore -import device_info_plus -import file_selector_macos -import firebase_core -import path_provider_foundation -import shared_preferences_foundation - -func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) - DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) - FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) - FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) - PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) - SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) -} diff --git a/ai_recipe_generation/macos/Podfile b/ai_recipe_generation/macos/Podfile deleted file mode 100644 index c795730db..000000000 --- a/ai_recipe_generation/macos/Podfile +++ /dev/null @@ -1,43 +0,0 @@ -platform :osx, '10.14' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_macos_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths - end -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_macos_build_settings(target) - end -end diff --git a/ai_recipe_generation/macos/Runner.xcodeproj/project.pbxproj b/ai_recipe_generation/macos/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 153f28d0d..000000000 --- a/ai_recipe_generation/macos/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,795 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXAggregateTarget section */ - 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; - buildPhases = ( - 33CC111E2044C6BF0003C045 /* ShellScript */, - ); - dependencies = ( - ); - name = "Flutter Assemble"; - productName = FLX; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 045ED23A4B33E4F2FA434896 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 38F9AD322406A70F654D9022 /* GoogleService-Info.plist */; }; - 244B07C54A330077F9A2F055 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08283E03A7D1FDC603938AE0 /* Pods_Runner.framework */; }; - 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 4A9C215D043B623939727167 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2B3A731FA44098272D037D5 /* Pods_RunnerTests.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 33CC10E52044A3C60003C045 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 33CC10EC2044A3C60003C045; - remoteInfo = Runner; - }; - 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 33CC10E52044A3C60003C045 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 33CC111A2044C6BA0003C045; - remoteInfo = FLX; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 33CC110E2044A8840003C045 /* Bundle Framework */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Bundle Framework"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 08283E03A7D1FDC603938AE0 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 20E24AD12C2A08D4C5838D8F /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; - 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* gemini_io_talk.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = gemini_io_talk.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; - 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; - 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; - 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; - 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; - 38F9AD322406A70F654D9022 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; - 7358AE11276B20A48E44DAF5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; - 7DC58890B42AAC39F0F3C3BA /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - B82D42F50A1CA25092D94C23 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - B8C09668FAC2FC05DF59B887 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; - C2B3A731FA44098272D037D5 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C359B5621FA51EC13E1CF60F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 331C80D2294CF70F00263BE5 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4A9C215D043B623939727167 /* Pods_RunnerTests.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10EA2044A3C60003C045 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 244B07C54A330077F9A2F055 /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 331C80D6294CF71000263BE5 /* RunnerTests */ = { - isa = PBXGroup; - children = ( - 331C80D7294CF71000263BE5 /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; - 33BA886A226E78AF003329D5 /* Configs */ = { - isa = PBXGroup; - children = ( - 33E5194F232828860026EE4D /* AppInfo.xcconfig */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, - ); - path = Configs; - sourceTree = ""; - }; - 33CC10E42044A3C60003C045 = { - isa = PBXGroup; - children = ( - 33FAB671232836740065AC1E /* Runner */, - 33CEB47122A05771004F2AC0 /* Flutter */, - 331C80D6294CF71000263BE5 /* RunnerTests */, - 33CC10EE2044A3C60003C045 /* Products */, - D73912EC22F37F3D000D13A0 /* Frameworks */, - 4641E830ED1DA52584603D32 /* Pods */, - 38F9AD322406A70F654D9022 /* GoogleService-Info.plist */, - ); - sourceTree = ""; - }; - 33CC10EE2044A3C60003C045 /* Products */ = { - isa = PBXGroup; - children = ( - 33CC10ED2044A3C60003C045 /* gemini_io_talk.app */, - 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 33CC11242044D66E0003C045 /* Resources */ = { - isa = PBXGroup; - children = ( - 33CC10F22044A3C60003C045 /* Assets.xcassets */, - 33CC10F42044A3C60003C045 /* MainMenu.xib */, - 33CC10F72044A3C60003C045 /* Info.plist */, - ); - name = Resources; - path = ..; - sourceTree = ""; - }; - 33CEB47122A05771004F2AC0 /* Flutter */ = { - isa = PBXGroup; - children = ( - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - ); - path = Flutter; - sourceTree = ""; - }; - 33FAB671232836740065AC1E /* Runner */ = { - isa = PBXGroup; - children = ( - 33CC10F02044A3C60003C045 /* AppDelegate.swift */, - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, - 33E51913231747F40026EE4D /* DebugProfile.entitlements */, - 33E51914231749380026EE4D /* Release.entitlements */, - 33CC11242044D66E0003C045 /* Resources */, - 33BA886A226E78AF003329D5 /* Configs */, - ); - path = Runner; - sourceTree = ""; - }; - 4641E830ED1DA52584603D32 /* Pods */ = { - isa = PBXGroup; - children = ( - 7358AE11276B20A48E44DAF5 /* Pods-Runner.debug.xcconfig */, - B82D42F50A1CA25092D94C23 /* Pods-Runner.release.xcconfig */, - C359B5621FA51EC13E1CF60F /* Pods-Runner.profile.xcconfig */, - B8C09668FAC2FC05DF59B887 /* Pods-RunnerTests.debug.xcconfig */, - 20E24AD12C2A08D4C5838D8F /* Pods-RunnerTests.release.xcconfig */, - 7DC58890B42AAC39F0F3C3BA /* Pods-RunnerTests.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; - D73912EC22F37F3D000D13A0 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 08283E03A7D1FDC603938AE0 /* Pods_Runner.framework */, - C2B3A731FA44098272D037D5 /* Pods_RunnerTests.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 331C80D4294CF70F00263BE5 /* RunnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; - buildPhases = ( - D55612DEAFE1622F2EAF6516 /* [CP] Check Pods Manifest.lock */, - 331C80D1294CF70F00263BE5 /* Sources */, - 331C80D2294CF70F00263BE5 /* Frameworks */, - 331C80D3294CF70F00263BE5 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 331C80DA294CF71000263BE5 /* PBXTargetDependency */, - ); - name = RunnerTests; - productName = RunnerTests; - productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 33CC10EC2044A3C60003C045 /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 1DCEDE898738D93BCB6F7DE0 /* [CP] Check Pods Manifest.lock */, - 33CC10E92044A3C60003C045 /* Sources */, - 33CC10EA2044A3C60003C045 /* Frameworks */, - 33CC10EB2044A3C60003C045 /* Resources */, - 33CC110E2044A8840003C045 /* Bundle Framework */, - 3399D490228B24CF009A79C7 /* ShellScript */, - 86416C488D6732C2DB9D683A /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 33CC11202044C79F0003C045 /* PBXTargetDependency */, - ); - name = Runner; - productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* gemini_io_talk.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 33CC10E52044A3C60003C045 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1510; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 331C80D4294CF70F00263BE5 = { - CreatedOnToolsVersion = 14.0; - TestTargetID = 33CC10EC2044A3C60003C045; - }; - 33CC10EC2044A3C60003C045 = { - CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1100; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.Sandbox = { - enabled = 1; - }; - }; - }; - 33CC111A2044C6BA0003C045 = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Manual; - }; - }; - }; - buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 33CC10E42044A3C60003C045; - productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 33CC10EC2044A3C60003C045 /* Runner */, - 331C80D4294CF70F00263BE5 /* RunnerTests */, - 33CC111A2044C6BA0003C045 /* Flutter Assemble */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 331C80D3294CF70F00263BE5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10EB2044A3C60003C045 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, - 045ED23A4B33E4F2FA434896 /* GoogleService-Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 1DCEDE898738D93BCB6F7DE0 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 3399D490228B24CF009A79C7 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; - }; - 33CC111E2044C6BF0003C045 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - Flutter/ephemeral/FlutterInputs.xcfilelist, - ); - inputPaths = ( - Flutter/ephemeral/tripwire, - ); - outputFileListPaths = ( - Flutter/ephemeral/FlutterOutputs.xcfilelist, - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; - }; - 86416C488D6732C2DB9D683A /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - D55612DEAFE1622F2EAF6516 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 331C80D1294CF70F00263BE5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10E92044A3C60003C045 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 33CC10EC2044A3C60003C045 /* Runner */; - targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; - }; - 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; - targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - 33CC10F52044A3C60003C045 /* Base */, - ); - name = MainMenu.xib; - path = Runner; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 331C80DB294CF71000263BE5 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = B8C09668FAC2FC05DF59B887 /* Pods-RunnerTests.debug.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gemini_io_talk.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gemini_io_talk"; - }; - name = Debug; - }; - 331C80DC294CF71000263BE5 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 20E24AD12C2A08D4C5838D8F /* Pods-RunnerTests.release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gemini_io_talk.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gemini_io_talk"; - }; - name = Release; - }; - 331C80DD294CF71000263BE5 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7DC58890B42AAC39F0F3C3BA /* Pods-RunnerTests.profile.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gemini_io_talk.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gemini_io_talk"; - }; - name = Profile; - }; - 338D0CE9231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Profile; - }; - 338D0CEA231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Profile; - }; - 338D0CEB231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Profile; - }; - 33CC10F92044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 33CC10FA2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Release; - }; - 33CC10FC2044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 33CC10FD2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - 33CC111C2044C6BA0003C045 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 33CC111D2044C6BA0003C045 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 331C80DB294CF71000263BE5 /* Debug */, - 331C80DC294CF71000263BE5 /* Release */, - 331C80DD294CF71000263BE5 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10F92044A3C60003C045 /* Debug */, - 33CC10FA2044A3C60003C045 /* Release */, - 338D0CE9231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10FC2044A3C60003C045 /* Debug */, - 33CC10FD2044A3C60003C045 /* Release */, - 338D0CEA231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC111C2044C6BA0003C045 /* Debug */, - 33CC111D2044C6BA0003C045 /* Release */, - 338D0CEB231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 33CC10E52044A3C60003C045 /* Project object */; -} diff --git a/ai_recipe_generation/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ai_recipe_generation/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/ai_recipe_generation/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/ai_recipe_generation/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ai_recipe_generation/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index f9c57d700..000000000 --- a/ai_recipe_generation/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/macos/Runner.xcworkspace/contents.xcworkspacedata b/ai_recipe_generation/macos/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14c..000000000 --- a/ai_recipe_generation/macos/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/ai_recipe_generation/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ai_recipe_generation/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/ai_recipe_generation/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/ai_recipe_generation/macos/Runner/AppDelegate.swift b/ai_recipe_generation/macos/Runner/AppDelegate.swift deleted file mode 100644 index d53ef6437..000000000 --- a/ai_recipe_generation/macos/Runner/AppDelegate.swift +++ /dev/null @@ -1,9 +0,0 @@ -import Cocoa -import FlutterMacOS - -@NSApplicationMain -class AppDelegate: FlutterAppDelegate { - override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { - return true - } -} diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a2ec33f19..000000000 --- a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_16.png", - "scale" : "1x" - }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_64.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_1024.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png deleted file mode 100644 index 82b6f9d9a33e198f5747104729e1fcef999772a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102994 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ⅅ8MglG&ER{i5lN315cO?EdHNLrg? zgxkP+ytd)OMWe7QvTf8yj4;V=?m172!BEt@6*TPUT4m3)yir}esnIodFGatGnsSfJ z**;;yw=1VCb2J|A7cBz-F5QFOQh2JDQFLarE>;4ZMzQ$s^)fOscIVv2-o{?ct3~Zv zy{0zU>3`+-PluS|ADraI9n~=3#Tvfx{pDr^5i$^-h5tL*CV@AeQFLxv4Y<$xI{9y< zZ}li*WIQ+XS!IK;?IVD0)C?pNBA(DMxqozMy1L#j+ba1Cd+2w&{^d-OEWSSHmNH>9 z%1Ldo(}5*>a8rjQF&@%Ka`-M|HM+m<^E#bJtVg&YM}uMb7UVJ|OVQI-zt-*BqQ zG&mq`Bn7EY;;+b%Obs9i{gC^%>kUz`{Qnc=ps7ra_UxEP$!?f&|5fHnU(rr?7?)D z$3m9e{&;Zu6yfa1ixTr;80IP7KLgkKCbgv1%f_weZK6b7tY+AS%fyjf6dR(wQa9TD zYG9`#!N4DqpMim|{uViKVf0B+Vmsr7p)Y+;*T~-2HFr!IOedrpiXXz+BDppd5BTf3 ztsg4U?0wR?9@~`iV*nwGmtYFGnq`X< zf?G%=o!t50?gk^qN#J(~!sxi=_yeg?Vio04*w<2iBT+NYX>V#CFuQGLsX^u8dPIkP zPraQK?ro`rqA4t7yUbGYk;pw6Z})Bv=!l-a5^R5Ra^TjoXI?=Qdup)rtyhwo<(c9_ zF>6P%-6Aqxb8gf?wY1z!4*hagIch)&A4treifFk=E9v@kRXyMm?V*~^LEu%Y%0u(| z52VvVF?P^D<|fG)_au(!iqo~1<5eF$Sc5?)*$4P3MAlSircZ|F+9T66-$)0VUD6>e zl2zlSl_QQ?>ULUA~H?QbWazYeh61%B!!u;c(cs`;J|l z=7?q+vo^T#kzddr>C;VZ5h*;De8^F2y{iA#9|(|5@zYh4^FZ-3r)xej=GghMN3K2Y z=(xE`TM%V8UHc4`6Cdhz4%i0OY^%DSguLUXQ?Y3LP+5x3jyN)-UDVhEC}AI5wImt; zHY|*=UW}^bS3va-@L$-fJz2P2LbCl)XybkY)p%2MjPJd-FzkdyWW~NBC@NlPJkz{v z+6k6#nif`E>>KCGaP34oY*c#nBFm#G8a0^px1S6mm6Cs+d}E8{J;DX=NEHb|{fZm0 z@Ors@ebTgbf^Jg&DzVS|h&Or)56$+;%&sh0)`&6VkS@QxQ=#6WxF5g+FWSr7Lp9uF zV#rc`yLe?f*u6oZoi3WpOkKFf^>lHb2GC6t!)dyGaQbK7&BNZ7oyP)hUX1Y(LdW-I z6LI2$i%+g!zsjT(5l}5ROLb)8`9kkldbklcq6tfLSrAyh#s(C1U2Sz9`h3#T9eX#Hryi1AU^!uv*&6I~qdM_B7-@`~8#O^jN&t7+S zTKI6;T$1@`Kky-;;$rU1*TdY;cUyg$JXalGc&3-Rh zJ&7kx=}~4lEx*%NUJA??g8eIeavDIDC7hTvojgRIT$=MlpU}ff0BTTTvjsZ0=wR)8 z?{xmc((XLburb0!&SA&fc%%46KU0e&QkA%_?9ZrZU%9Wt{*5DCUbqIBR%T#Ksp?)3 z%qL(XlnM!>F!=q@jE>x_P?EU=J!{G!BQq3k#mvFR%lJO2EU2M8egD?0r!2s*lL2Y} zdrmy`XvEarM&qTUz4c@>Zn}39Xi2h?n#)r3C4wosel_RUiL8$t;FSuga{9}-%FuOU z!R9L$Q!njtyY!^070-)|#E8My)w*~4k#hi%Y77)c5zfs6o(0zaj~nla0Vt&7bUqfD zrZmH~A50GOvk73qiyfXX6R9x3Qh)K=>#g^^D65<$5wbZjtrtWxfG4w1f<2CzsKj@e zvdsQ$$f6N=-%GJk~N7G(+-29R)Cbz8SIn_u|(VYVSAnlWZhPp8z6qm5=hvS$Y zULkbE?8HQ}vkwD!V*wW7BDBOGc|75qLVkyIWo~3<#nAT6?H_YSsvS+%l_X$}aUj7o z>A9&3f2i-`__#MiM#|ORNbK!HZ|N&jKNL<-pFkqAwuMJi=(jlv5zAN6EW`ex#;d^Z z<;gldpFcVD&mpfJ1d7><79BnCn~z8U*4qo0-{i@1$CCaw+<$T{29l1S2A|8n9ccx0!1Pyf;)aGWQ15lwEEyU35_Y zQS8y~9j9ZiByE-#BV7eknm>ba75<_d1^*% zB_xp#q`bpV1f9o6C(vbhN((A-K+f#~3EJtjWVhRm+g$1$f2scX!eZkfa%EIZd2ZVG z6sbBo@~`iwZQC4rH9w84rlHjd!|fHc9~12Il&?-FldyN50A`jzt~?_4`OWmc$qkgI zD_@7^L@cwg4WdL(sWrBYmkH;OjZGE^0*^iWZM3HBfYNw(hxh5>k@MH>AerLNqUg*Og9LiYmTgPw zX9IiqU)s?_obULF(#f~YeK#6P>;21x+cJ$KTL}|$xeG?i`zO;dAk0{Uj6GhT-p-=f zP2NJUcRJ{fZy=bbsN1Jk3q}(!&|Fkt_~GYdcBd7^JIt)Q!!7L8`3@so@|GM9b(D$+ zlD&69JhPnT>;xlr(W#x`JJvf*DPX(4^OQ%1{t@)Lkw5nc5zLVmRt|s+v zn(25v*1Z(c8RP@=3l_c6j{{=M$=*aO^ zPMUbbEKO7m2Q$4Xn>GIdwm#P_P4`or_w0+J+joK&qIP#uEiCo&RdOaP_7Z;PvfMh@ zsXUTn>ppdoEINmmq5T1BO&57*?QNLolW-8iz-jv7VAIgoV&o<<-vbD)--SD%FFOLd z>T$u+V>)4Dl6?A24xd1vgm}MovrQjf-@YH7cIk6tP^eq-xYFymnoSxcw}{lsbCP1g zE_sX|c_nq(+INR3iq+Oj^TwkjhbdOo}FmpPS2*#NGxNgl98|H0M*lu)Cu0TrA|*t=i`KIqoUl(Q7jN zb6!H-rO*!&_>-t)vG5jG>WR6z#O9O&IvA-4ho9g;as~hSnt!oF5 z6w(4pxz|WpO?HO<>sC_OB4MW)l`-E9DZJ$!=ytzO}fWXwnP>`8yWm5tYw`b1KDdg zp@oD;g===H+sj+^v6DCpEu7R?fh7>@pz>f74V5&#PvBN+95?28`mIdGR@f*L@j2%% z%;Rz5R>l#1U zYCS_5_)zUjgq#0SdO#)xEfYJ)JrHLXfe8^GK3F*CA(Y)jsSPJ{j&Ae!SeWN%Ev727 zxdd3Y0n^OBOtBSKdglEBL)i5=NdKfqK=1n~6LX`ja;#Tr!II$AAH{Z#sp%`rwNGT5 zvHT%(LJB+kD{5N}7c_Rk6}@tikIeq%@MqxX%$P!(238YD(H<_d;xxo*oMiv^1io>g zt5z&6`}cjci90q2r0hutQXr!UA~|4e*u=k81D(Cp7n{4LVCa+u0%-8Uha+sqI#Om~ z!&)KN(#Zone^~&@Ja{|l?X64Dxk)q>tLRv{=0|t$`Kdaj z#{AJr>{_BtpS|XEgTVJ4WMvBRk-(mk@ZYGdY1VwI z81;z(MBGV|2j*Cj%dvl8?b2{{B#e0B7&7wfv+>g`R2^Ai5C_WUx|CnTrHm+RFGXrt zs<~zBtk@?Niu%|o6IEL+y60Q>zJlv``ePCa07C%*O~lj?74|}&A0!uA)3V7ST8b_- z6CBP1;x+S@xTzgOY2#s%@=bhZ@i@BwmS)neQG&=9KUtRf^K=MvjC5JnqLqykCE_P0 zjf#V4SdH2#%2EuDb!>FLHK7j;nd6VLW|$3gJuegpEl3DZ`BpJU$<}}A(rW?<6OB@9 zKP9G3An?T5BztrLdlximA;{>Tr7GAeSU=^<*y;%RHj+7;v+tonyh(8d;Izn}2{oz& zW)fsZ9gHYpI?B|uekS3zHUue3mI zb7?0+&Zm>Kq(F>~%VYEn)0b32I3~O^?Wx-HI|Zu?1-OA2yfyJ;gWygLOeU;)vRm3u z5J4vDIQYztnEm=QauX2(WJO{yzI0HUFl+oO&isMf!Yh2pu@p}65)|0EdWRbg(@J6qo5_Els>#|_2a1p0&y&UP z8x#Z69q=d663NPPi>DHx3|QhJl5Ka$Cfqbvl*oRLYYXiH>g8*vriy!0XgmT~&jh3l z+!|~l=oCj<*PD>1EY*#+^a{rVk3T(66rJ^DxGt|~XTNnJf$vix1v1qdYu+d@Jn~bh z!7`a`y+IEcS#O*fSzA;I`e_T~XYzpW7alC%&?1nr);tSkNwO&J`JnX+7X1Q8fRh_d zx%)Xh_YjI3hwTCmGUeq_Z@H#ovkk_b(`osa$`aNmt`9A#t&<^jvuf z1E1DrW(%7PpAOQGwURz@luEW9-)L!`Jy*aC*4mcD?Si~mb=3Kn#M#1il9%`C0wkZ` zbpJ-qEPaOE5Y5iv_z%Wr{y4jh#U+o^KtP{pPCq-Qf&!=Uu)cEE(Iu9`uT#oHwHj+w z_R=kr7vmr~{^5sxXkj|WzNhAlXkW^oB4V)BZ{({~4ylOcM#O>DR)ZhD;RWwmf|(}y zDn)>%iwCE=*82>zP0db>I4jN#uxcYWod+<;#RtdMGPDpQW;riE;3cu``1toL|FaWa zK)MVA%ogXt3q55(Q&q+sjOG`?h=UJE9P;8i#gI*#f}@JbV(DuGEkee;La*9{p&Z?;~lE!&-kUFCtoDHY*MS zzj+S$L9+aTs(F^4ufZe6>SBg;m@>0&+kEZMFmD*~p~sx?rx=!>Ge;KYw<33y#*&77 zFZI`YE(Iz?+tH;Fq;y=MaSqT{Ayh*HFv0(z{_?Q+7@nE%p?S8%X6c!+y;!0NLXwJV8Co_}R3*7>n+oMsQpv8}8ZS-P@(Rg|gmxZHzf=nMOUAAY}AZGfWVzZjE@4$=7xkIrs8BE%606aVU%kxz_04ipig51k& z(>c9rJL2q%xvU%Zj#GR9C9)HLCR;#zQBB@x;e_9$ayn(JmSg_*0G?+wOF?&iu@}S{ zt$;TPf*Lj$3=d<}Q3o!Hq@3~lFxoiCyeEt}o3fihIn{x2s1)e2@3##&GYDq~YO|!q zUs0P-zy)+ohl-VQ`bhvUpC{-d$lkpML_M%Kl6@#_@A}w{jWCDsPa#cSbWA#C4Sf|*C*&Z{ zz?hOU7Cc`?>H$WGqITA2P~fYudnQHxB8^;0ZFKC;19F#~n_2P@{cE{Czq-#K5L_8| zc3aOEwq4%zL5>YU_mc9fc-p~{fBTWUkxTiZvxt9FOqC{s#TBp(#dWc+{Ee{dZ#B!g zHnaOJ8;KO1G;QU2ciodE+#Z$Wuz*Hc6NRO!AUMi|gov=>=cwcZeL&`>Jfn!35hV1J z;B2@0!bIR853w%T*m6)gQ?DPnQ)o6EtKaN3L;o?*q<83d&lG&U=A|6hcT?f0)4h6{ zGIZ0|!}-?*n{zr}-}cC}qWxEN%g60+{my)o^57{QEn(tSrmD7o)|r0+HVpQPopFu; z0<S}pW8W2vXzSxEqGD+qePj^x?R$e2LO&*ewsLo{+_Z)Wl|Z1K47j zsKoNRlX)h2z^ls_>IZ0!2X5t&irUs%RAO$Dr>0o$-D+$!Kb9puSgpoWza1jnX6(eG zTg-U z6|kf1atI!_>#@|=d01Ro@Rg)BD?mY3XBsG7U9%lmq>4;Gf&2k3_oyEOdEN&X6Hl5K zCz^hyt67G;IE&@w1n~%ji_{sob_ssP#Ke|qd!Xx?J&+|2K=^`WfwZ-zt|sklFouxC zXZeDgluD2a?Zd3e{MtE$gQfAY9eO@KLX;@8N`(?1-m`?AWp!a8bA%UN>QTntIcJX zvbY+C-GD&F?>E?jo$xhyKa@ps9$Dnwq>&)GB=W~2V3m)k;GNR$JoPRk%#f3#hgVdZ zhW3?cSQ*((Fog26jiEeNvum-6ID-fbfJ?q1ZU#)dgnJ^FCm`+sdP?g;d4VD$3XKx{ zs|Y4ePJp|93fpu)RL+#lIN9Ormd;<_5|oN!k5CENnpO>{60X;DN>vgHCX$QZYtgrj z*1{bEA1LKi8#U%oa!4W-4G+458~`5O4S1&tuyv>%H9DjLip7cC~RRS@HvdJ<|c z$TxEL=)r)XTfTgVxaG!gtZhLL`$#=gz1X=j|I@n~eHDUCW39r=o_ml@B z0cDx$5;3OA2l)&41kiKY^z7sO_U%1=)Ka4gV(P#(<^ z_zhThw=}tRG|2|1m4EP|p{Swfq#eNzDdi&QcVWwP+7920UQB*DpO0(tZHvLVMIGJl zdZ5;2J%a!N1lzxFwAkq05DPUg2*6SxcLRsSNI6dLiK0&JRuYAqwL}Z!YVJ$?mdnDF z82)J_t=jbY&le6Hq$Qs}@AOZGpB1}$Ah#i;&SzD1QQNwi6&1ddUf7UG0*@kX?E zDCbHypPZ9+H~KnDwBeOXZ-W-Y80wpoGB*A) z_;26Z`#s0tKrf~QBi2rl2=>;CS1w)rcD3-sB!8NI*1iQo59PJ>OLnqeV4iK7`RBi^ zFW{*6;nlD&cSunmU3v4JKj|K4xeN(q>H%;SsY8yDdw5BJ75q8>Ov)&D5OPZ`XiRHl z;)mAA0Woy6f!xCK(9H2rq?qzp83liZAIpBPl-dQ&$2=&H?Im~%g;vnIw1I+8q|kr! z36&^9}CMmR(U2rf|j12oG=vb%Ypsq8u9Kq}U*ANX*)9uK}fAi8;V_7Z;0_4*iydDxN-? zv?qJ=T*{MzL~-xUv{_Kh_q9#F{8gPV!yPUUS8pEq*=}2-#1d=sC_|U-rX~F0 zBLawgCWy#?#ax{~DAnDvh^`}wyUO`ioMK~jgh%L7^}#h?beSyvQ_g>+`2`}`-1h7# zg*?qJdm=53hwN8~B=^|LPmYtOVrQ(W{sNm4uofq=4P@dUA%$onWbw_m-KWia&n9iv zi)!9#OJ#^}eg8tE{wSb9(c0D^PS1 z9EBS5*ypSiVRS_G0v?$hyoZOS7hFWlp4qbYkf9Y&{%OzhsIdHskLptn96@k6@^K@U zszd8POehITDK+AyW#JKpnWY;ju#MC$JjB1Y*~(E6N%{p#kO+bVxG3X<34n3fW=k{A zCZt|KP%x^GQ9%mU)KE0{LA=vaZvRQbxSlK~eAkwWo2Z<{j5eS5NVTMe`m%re8%~7K zZLtU&b~YDN%~uA9wPf>x2=PI=MA6_oVe>Ek$s5&&Z=8vvF5EODP4Av(b|dlNgF1O8 zy83W0WRdzjz2iNA~t1piEqlyU&`$yZtqR`6X_PmuP>W+D|8iH;FQ zN{JuU#Tz9mV=4R_IewROL1|mK^`lLat#LcIBfggzM(iO$pQT*-c_ z94^LUWw#5B9~sp2W1p`c)Y(xfR<{O^9n4E6vDDw{#-R4UMBKo{>Hqlqn*a9rl_>+0 zS5MwJC~nCC`1X%VCyWFsiDX;bfAJQAUkU#105f_s5U-8rqO}n8fA1{b>Fr6Q|Ea(V z5B11Lo^ooWF?`^{-U#?iatokWI-e$632frzY?Yzzx(xJc@LFM4A~-eg!u|tl{)8Nx ztZLXsSC*68g%9TFu(f&J9nmc^9hgyy#uUOMJFCaifSaDcyQ&6=8e9=t zIFEAQ{EK{|73{($!a4=!wj4ABcQrUQp#+gGM?wEUp(w@+Fzi{!lt}|3`PM%&d-seeR zB$}BrFGD3R10CE>Hsb>;PrP}pd` zaY4}6+Wu(`#uAV+E5SV7VIT7ES#b(U0%%DgN1}USJH>)mm;CHPv>}B18&0F~Kj@1= z&^Jyo+z-E)GRT4U*7$8wJO1OibWg0Jw>C$%Ge|=YwV@Y1(4fR>cV#6aGtRoF@I`*w_V4;)V231NzNqb6g@jdpjmjv*<2j02yU$F8ZS$fTvCC`%|Yn#x< zXUnP&b!GLpOY-TY3d?<-Hhxom_LM9`JC9LEX2{t1P-Nj%nG+0Vq)vQwvO^}coPH-> zAo8w#s>Je^Yy*#PlK=XDxpVS~pFe-j#jN-(As&LRewOf(kN-aKF(H+s*{*!0xrlZw zchJu@XAvQWX7DI1E8?F}Wc8m46eT+C<0eXVB+Z^(g=Kl@FG-cn@u$suj)1V2(KNg_ zh29ws6&6(q~+sOAoHY^o86A<#n*?Pg2)cK$+y;cY$hJLq4)4V84=j+3ShSr##Tk5kgmxB zkW+8A1GtceEx~^Ebhwm36U?oA)h)!mt=eg0QE$D1QsLNZ_T3NH?=B&0j~#298!6iv zhc0|-{46*3`Rx&nKSXnf1&w-Rs>#PGAGuY@cBTU-j|Fxbn3z49S#6KBaP^Lx*AOXxIibr z!1ysMi(&kr!1wwQB5w`BDH2~>T4bI`T1}A2RM0zd7ikC&kuBRsB`Z2@J!Udm{AmSN zrr0k6_qCZL**=)xRW`MFu(OY=OT;3G8eF~ z2mmkXZ9X(sjuKmq+_<=LSjphB$~R1o^Yb=rO!j!(4ErIox^x55o{pXSE9X$!76^*$ zoKhlAX6y%n^U=C~@!vIlEgXQGD@>oOU=_(aXF-Sjas*$AKESfRzxQ8#3yOj|y0OCU z>6Z-0%LCcjla&7I+CXm&caKp@@jQ!5M`(_{CL=@4#JJ}cHeZw>^b6fpv269LSV?gV5Q{kk?4;;y9RIsy5vk%DIRiL(9xe1aA@4!VX zDh2}xgUd5X?6nji%&7-%QuyKSYA-Z{PwJijUQ}In+EJl|x@dF1P<5bPa5W3&&?^h$ zZCo8LepKo0a(Fsln*cHL;D(gu9MMkoiM0*n31u)jHqX5x^F95tnI&^}^yKx3YwEm@ zo8?EZ710ykx@19{=yz5IXb8w4yjdveWb{IVL6Z(Cs>!a_0X^1E27o!4e&b43+J*u2Gb(59k2uK0goLwhO{ujLS ziI9LA9`&x~Y$6JNX!aEXR``}LUI}Gr#=<^wBHmg%v<)zRWDVtq)kT$-P7iU1R)2XZ zi~bYhV@EZ`@prgK(cs{>2jn$pxg$<|KjJ7%26Km>%KcXh^bU@y@V_Lf@=j1x%R4{v zOcQn{I}!2W<~08FOVnoV>zOTH=+>v9!jFo|q)ucqIe!N4{U5_G`>>*sVD{8I~4FqyU8imZ**-Gy`~Xd z4w35GMf%7^i65HdX{Iz|f2Kg193#KhPIeR)-=eYx3Z!%RM=JjwLrdk^B#6rg!ym2w zPbFqYyO4>W_Z6PonAwiu7?!h=x%sR-T+_*xZOGh2wWhWr%}%2^$$ zQvACIB~pi=m|`hXIMvoq`TOCx=J_D2>pi6$NPy3&8#vy|oX)=kM0Z}$BR$r0G}MzOk-OqG+VmZtOZoj6x4(tLh|5h) zBv64Y{DPHsy&_H(5_l(&Y}FhVvr9m_*_Q~Zy-}V9+VmGnvndEjYW4qt4K~N&Y&6g| zfpz*V=A#^mVmuOAz)(KVI<%v5NY0%Goy!{9&o41upsPWk(yFuRP|A4q6NMnX%V~MT zi_Rb-Bno2kI+j0Cw`@ydy{e%ARS#Z%b6I%_yfo_ZKXr4BLVoHzBKJ^ZG z-2>2IzU)55@9C|?_P$ew^-7zEiAKG1XAi{!3h%1m#9s%^pGy6S9wKFYY4<$djeoJP z{GI}Vd%idY$4_fh(7NXm7#;cC!DS&-{tGr!Qze{^%bUx2jgG@-kMta^q-EwrKB}d8 z{%FT>rFk_bzW<{lc%eYlrsiYTZXGgzD1&lmRyp+c1O=0=zAX=KV62bx-a~JP{cPF4 zU$-XT#(9&T>l@bMu3nSr{)%-5lV+0t&bxip4DVJ~vlL$J2P6X~ zd{FS8vm{Lhrieul*7&(AgPuXhjpGila%6_?-+k#b)cdk#M1jB*nE>G6NGOr+Ek{`= z9b%S1`$`=g0CC$>0$Db;l_szReLYVmce*(()9%Zz1`*fNXhI*oRlerWHarD(v^W^c zuc1Vuw6Gbp7ZsoRH>QGt#&lv;5G~Ovt$%7VFd*-rN2>UjbOWBFGNGO`bru7CFB4tn zL`^?69Lj_g_TA&`9`dSI8s|)K|QM0 zybvV7!>xDY|6c6y;Q}qs`){1+WQu_5Dgd8Qe|q}}bxjH+joQQtqs1IVZn6{e7T{ia zF|=^xa%eWO%(x<7j*QZbcU_;aVaVP!arexOLOtoSNt*hvsRL%}%)jPetSich(`b-^ zMZ$PM9%s@%*jPVz0Z^W*cK_>G4f}+eEVX`HOaHg#!B`<4v;x}zDLMR*M27`kNfp!! zOfdt(>k-g>7jf^{Se@3$8<+;R*cYtw+wD_Z8Pl~!JDCUEPq{Ea*!J9`%ihyNJZ30i zmfve}S5<$Uso}_?SuI$ks|{-ddGLu9WR9`^9)Kdi@Vs;x#SY-xp}wHPU0|vEA7234 z@BN1z7OF=OOQtPF$4twn3!HTVlUVD_)ubMM7PEPoiC6lQgL2q9PK4~e8v-OuH%lie z?NgBLkIdPMG$QBq(>r^AOHB`|*1#*!2Z? zuU8H|FD`OBRu^(R?Z-Vhr0j;FLpS~a34KREnd}B=EYHS*>Hm+f%tgJt!4J8Q`qn^4 z9F=tO#JRJ}tzA`vx$nZ)O%wC?Uiv0+_nz}5Lj4ki*&=K&*#U`=rv z`Q@Q{+IhAj@6lrNK2B=8Yln!O2%zomfRehFT~;!O@(@Xy|1Jlw*uOB-M$#6K^)QBm z_7%#QVUDPwnW{iOV-grMQQU|3{=BQMh}c5(yMGdoQf*)k9-B zMQ(^GdJh+y)>qJprknS!%WxqM>HlHOP#7UVdy>%PW$!l72J`n-p7j(DBKoGxXWh(Y z>BFDZl|7knU_jg_SSbvFk8)39%2)Hu5W0}HKlh>EaqvFoXI&56Yy)3) zQkE4X^P0QnPn?iUUVHJZXzPp`s5uv?pG{K9IgGoHvcmlBxubi|iF7n{)mhenIcxGs zgr0OpQy#Y#u=5lOyiECfE_Sn?Fj1LyoRKcbTgX{p<T*v!CGkPc)pcA2D=4Ekp0Gb*wpy7S88C%Ywsbr?MI(3UdsCM?XJ1X%*hNjB)XqZ*W(qDdtSb z<3XN74ARXL3=c^bfW~F%NM^5*Zx92>Wq`&M625p~j$8mYwLbk%Kf)jbn#<2z$%vP5 zy#b>-tF-S2_AB4;R^K&^-1LJrUmi@9rB^FLF)-k&YHK8P+k@RCJ1qSTZ@=kHxA3l$ zmK_ZG)l6(nmCR1a8|;QF-B5e_ELnjJ1$m-;4UXX?WytF_wz7#&AjwZYTMVieLbq@R z3t-q|G4^BB#EpNu4uyfDebB+-uu_$9>y-dzB30Y9F=R zrW-Heqnj*InPTWHgR9v^R7~hokldh&h8=HDhMW(EFfim1*{)5Lc1-+eBVkK-2!u=N zuZKABgJs3I--NbjE;>Undg6uK`^U>AQ6V zhc!RhYgvrmeGNsftr+(C<_MtuV$`5RZTf#5r=DR?gWG->#})#=(td%C3`oO+2B7im zUqY}&a_QNTn?s+?=mNXiREN%x_=(H)L|DtYPY>SR3pQfBOel7G_jR_{!9`dSj8Up-`JgcB;=Oor)U=_EVjF3C5{Sqh8cq=~bRjoBpoc$kJCgtTyZGSpQ4= zYi$6b$-dGmuTDF&@amhV?cU05g(AZV&v2$4m&j_~GZk;&keSO(@LRESRZ&p`dV*6w z2$em~p*8yM6j;SYorw`M5K2mluJq7P5Yn$VtZj8DEs2Zk=O@4T&Q}>~f31Z{uk}`E z{Dp{KObh1kk~~MfLUod72{Pk6G@T$_0_N??lOrdR=Z;VV#m0l)&@hz{Z?)@sgImi-&i1@95g53rON83v!yVPDHRU*Mzc4yZ(-Fr z{8{WXmIJf7jeswk$;6s~Qac6QyM3W&`}m#gRt=rr95A+Ad&wSAgvXZ|F))rBJVJ5W1CsjN`QaOzct2ocq#0!v zmj#075)C!3oS>&N;aHS@<+c>RHL)8j^p)k(8#7$LEx!1g_1^02!4_qA=;uhKW=+ix zGX%+vBMiRiF^^jm{mdO(?GdWJ#unO#_F^7mhT8)s(z_WlwFyJ#Xh)k5+RG2f;LC*K**1dr`#}~6A=0B=I&V;%zDA1)d@G!X#Rng)7G*2k8Kg447r0ox> z5NK`d(H-afBwo9feDOUi>;BbPsu!2|=@g=3j*PY}@YrOb+SX6?#Yb2xaaK!?>SX1J z_!VsB`2n1=wwSftkydm!39|-1?c%Epx?TO<(#GO~I&{f4+)XwRk<7RQ1~5>QcKH|D z?!}j1ueO0Lk;FZ{k4FA_(S`Ot0w~tl&m0duID*f6RY#bkw||o;kZ# zISYNTb|{~|X$m$Q-Jv#uxyw)eM0gIv`V#wOAp&Vv@>X4_tSZ&L#juM@$S9 zx_X_tLh<_^-F;LAQ09s@sPb%PMTrcw*HUV0P=RYSlM&AXEOI&&R&YCm_S<7DRBx^L zA^R^iwW+LMk(r*$Pq-fKU5X@=mQ=`ErO30H@@&qqnI7zJcrbSh+H<V ze&7Uli0xj@WrW#&-9%*FP~kPYF_YYM_hs5~|ExMynQ%qvq`leRB6W0yhC@pCb8>_P zlf=F~WMv_u*-DV=UaVu#2rlzK{q8D95VwZrfV?gj@rSNWXFvktUq)V5+YrlxwX302ae(;aG4e>L-M@3J+-f3IT{b9l!kg*2M zC1+ND9}6m^()LE87Mt+^Q|)!y#suc&v26C=0W88%a{?)E8Yvo@kM&KNMaOst#|-_CbUTm}WS@-c>nRb;&z^ zYr)+IE$1=jov(CZ%3uR+`~NI>1&Gs6W(jaamjcN$a`2!*nO}l|b%?)Q%%UWzw>A`C zR@px(P*7j$TK?jbv*%x)e^|jcLsv}aF(Z0=7(%Oa7+1wY>{B>d+i&ZA$}k(qgZPZY z;VkW~8eWnU&HPIAbco?&tc2O1$6=7n{u|^Y*nXoac{o1W-6aXfy~KlNbJfLoq~6;+ zDYmnv--Fhqrl+UV#k@_(1=gWNtqhyVKN=9CZ-{Ohi>e=~bm4IKbhM%%W zW8oXE!rGpV7Wt(_^4nndH1_imheaWzDi|I})9ZVZ9>pN+P%dVc5wG`Ze*4`@rjn1^ z`ln(;vPBHQUb}y8S>=8q__r7g+=z$>!pReVB0@XKchAvyGjLQs-u>+w%`frV4FeIG zj=7n~hGrwx*&5aHy(7X$bDZ7YhcP%(*>G^lAYMK;qG~V8Jz@b7oNg;IA1z$9@TbzW z;@I51@Ekef#qbxnG$Y8Z%bm~ibZ=4#%yKr%#b)CDrfKN`ujIY?tA4h9)i~dZ4E;ZM znvb$n2)zn$Wx&zlW%mJZDh28ox$@%`w3i7YFepXUChw}$UXKI=-TM51`M#FH=tdr*mQ!c=aB1296Lu>iTTKZWss0f z5~ihdImPN$aTle_AdbYC^31}_^EK|9R&l#%3hbx;8vJ+Gp^tm{9JDILu*1PW!rh^Dn9p<)h#Sl4kKM%nm<+!ESSk* zC;lLNT$fgr-!+{aBsSx$41b}yy6o>r3F#1&iv3cfY2N<+`0qJ+>=&Qxs}JOEkD?^l-F5i`t5+zNuvJf z3Fh4$mNqiFXL-aq4U4K@Ae$fq-TDT`rvrx;gqx96w^*@s=mcthCaIyPe(w)6kI{EqV10tcShHU9eeAPs)s?6#vrq}>y3FeTJu$Udha+z zs7}rmA@yR(L&>35sNjQqrw}o^)UitMU!5g6nnG)(tgst!^`FKJEzI1(d@j_w@;^hr zgYxlIRYjho4U$bhczfq&YySCqCE(5_d>l(4tk1v9!V7PB%Vx{QO=G2NC@c1%3rEzw zN<6i?h;CJX>h)kn49Sr)g#Em6km6ESP`1qc5C3ZHizN>r>V-fSS=X1nT{+Thh@kC! z(H=PlqDt7V6gOYezXUK-dretz!1?IUD6&eL2b!4=9h+HUO&DYZKMM>|YhlEEg?q?S z^XT4$2Fd|zT=x3U#L1|F;-#`to-Y6hiYkWdO=rRC)meY72pIfl`3zEGDU8($iWR^K zI$nq80aSJII<;#W5Pj>^_T&013BJ*O89Uoq z5>;Paa^E}xar^r=!pexg&OTM8wluk4R~Ru=)Hgk`Y#i_$jk{jc8hx}?(dW*X!l4vs z6_%$s#duJJFmaFc-5#>v6Yea=I~)s_pXGS>Tkz?s+WS}>Qp<9MappMLXpkXpSM~SmH6u)`Z5>o02kJs;w@KhdiZ3}29y*xr|6tMo zBHzGic+b+dTd!xOJ;p{Rguh^corJ;K?R6daayQKm+0rf7|AXg0qs!R9eS7t4{G=fs z1$=?kK1Ih=gEkI>@jgXDWHZt*C7FUEWs|u^pE3Z``^K|1KEC^sbN*4nQUfRc_AyE0 zn)?RrGjgPkzfE~_s!rDB!fDsV+*|kEX4+DyS#8%!cshn;s8svwBXSsDGX2ZRa0={* z=`p1F{zD17*Rk>Uk_cw3t5j=9-d6$}MoM~z{v{t^M!g75-+o8_XkP@CZWUQ2z!^26 zCNOu~hgrrK)y>bgqb{`Q_1^zrG4;cGarP!nb4E~(ZKWc`LVeEq;IewVneLp^ZU2+% z95PgN*M5v7Q;ZlGvM#`&u2NdHm%&gZ{bZM5wBCp&?HeZhwU87wyT_z!n4z+1?=RvXZ^72d*%+R1s1$KbAFtR|= zw;MEq=O7pMIKpFwKH6$OOszJAf<_Z<1)36cB>D>|Z6$gJL~jH`n3MMou$#Si%rDAu z4pSkJspG|^CJ86vg6kkfXsA_`8@8iOryOe!Qhn8SV6}mPlof3=WJRVqAr_b;e->`Z zMR(p|K|$L0^6;u~USxg#B6-ZNc%E1dv*^P=|2k*^NOBni#G%9Y?##{=)8KZwh85OL zSBG9|gb|hdmY^gn(ziY&O5#@I?W)W;361Yb^VQNpz0A7&^(7HRAsUvw#)fvhocvja zLxV65J0_$>&cVRctJFsn^qLos^tG`+B0_gQ{NeOwKt-!C^gGFufdtPT*Vi>l#X1|V z2XxsAcixN)Ekq=a##_^=k_^BFH5_zpvPDRP>u6+3$}i&b zy0@FdzAHw?i9OqnlTts_w5D@Nd#eM)KKEuN#m{|AJyscxa}(eA?z4&4yvXo{OBS65 z-?gW;<+;+ntM}U_yTmHm6*2zj0Imj<&ZgE9Wj|gfsXhrVH-c0p$7HXnR8bxDYOi z=_r3FA~u`L&2;Vir8}P3)k|@c?sK1U@&iWo{HEXcoy>6wQSuJ+b4l%aTBuigs&k@Y<2c=S3Ef?p zH>ki4yDuXdo_eu>X1{E$g(Q-u#zVXN^&%70guoizo7x(kQ0OZ}H$O9UB}(FaX8Ct1 zFpx~}EbHf2r6V;x=@8GH$C2|6*?K~?LrtMYd^bw*WYXhA z_))@RMH;nZedW3+qfWbv<|_#BYOxX^rhbN+!za)|!|8K*LRs(R$O*2SDM{g9k7e{u zN4VIdi}e#0&h?sBxu$>Yy%)j(k1V2fuhp8r!}gfF@b;F?U`6}YnnMh1&sSU&lR^?# zu!61+lGsuFEfDraX3+$QZibCbKzc{75G^T7@WZSQ)j5898G1AOXB*H*TSd`f<`IK# zm1%&t?i|2Z-a&r!pJehzg@!awNp)R)aa?q_SqGrxE5u+T#f?K2;GAHV?O&>!W@Q*k)7=g2vDW+7K zbyY9i{|nOF*SbMYoRQSAbSH2y$bE5(@d6xKxcF#@TE~X#3o=;`0sc!RupdRmQsML? z&>SCwS{FOpSr+@6Uuz3m`hj}(^g`Jz|6?({!%WVJn$H|ugxW+x-GEA?J&U^ugj3Nb z;65~)W<}iH2PJ@st8LtLfSOLXYgj=9<;?ih7rq$bXW9J#!B8!Wu6#U`A$wlcoC*&` z_9Js~7%m79#+edeT&P`@_Ng@e&5J+pqpx%31tAF71)pcz~-yJ>P5yX(nuM4;bUHDa8E(~~l{j~JeCGkX>nHJDpgSf&bTHEf)qw8{Q~CBPEVen|MW2P3vmf`8X9-g|>>ddp zcgfjbl~(?3Wa*NzQH>4nsM$3}Ul>pX1xC0oF3TZXe7=V!9!n?WgvH|R zpbruczmB%z=zkZ>=1R|gXwGThLELqD5KCUhtiRGT*JwKIvzbzV%ZU!e!VcNHSSX3> zObH|oohc8nvQZ2}q??C}@>!fe3gH+HF@4(qWqi>;ag~md#D;cl8&gQb^?2a@5cikT z=7r78@&5gV3Ggc9f=<<8v~yz`NcEGvbX1V_`IL(&+Z>LB zM~$ok2qXzod@1$TEl*U~H$V5g$er{Uj^($sWb7Nr{gsIbE(`$LRGECTOraXiU%=uq z0zvpi1S%)RxTjzoVcR4#10)fs()4Mtsa@e?9j)Bk!LsYyXIZga2q7d%`vQE!V@<1Y zmkpH3LeXJNO9f7l>F84g;huc=4nk(UnU}RLZmYk2TtB#lv34K(?8~gyx-mN%g=U44 zOPdr_!j-;IEbe|l9-buuKEy^Q9MLjSKG$S6dz)!U_32{1)N}L)3+COmlg=nY1@od$ zJ<0z-B%sisAR1yh>z-RfQQb6M4i-d#vxvb~f69M{JLPZv1JSCh1$gQ*LxOF-tH9!k zbQ0ZW)S7)qCSF|=2`q_A3}OHBNBueZwTTz^ar~gz#2KA74&&D)KHt~m4F_nK<^*7_ z!!pN@xiGkq%>1N(rNxw$zu-=1t*IpAy$ z4~dD0w%9;E?(greVWZ3(o9ux`elM>Rek#0 zO=#-(4p5B+wFzlEU7^k{3EdL6sIp|K*>xrriI`}E8ze|z-$YpN`^_teL_7P`%e>IN z7tNiH619P+0Q1hBR|W#POOta)1|LkIRtgz zMJ9VOxXN#o)mlXS=u%`Q>~PBuKEmOWsIuQRp{y%!ty{fEyL0gV)$LQeL#pqX3L@SR zJ2Gb^E9+KVd?;joVOXlGie3?z6>(>u(i!(qGz(W( ze~^xj&IRF<98ypEis{Y_FoHn%C0bW(XeF#Lj=2WUEBqKNPPFppEH?_a3}-h906X}C zSYKcZFU`Om5YlWhh@ogzCn3NvuM~F9jOX|xe-X*!YL+#ceh_tJoHXz`aTnvSrOAZ| zOtdGz?QdT!oAJr3(XL2G(p%2X4{xEohU&vd_zQ(U%ihHOlKPWnb$&YYhx48?|R++>`5?sxvM?!;ru|9 zZ#nwuTK^S%ce<+ggdJBE&fRrXN7O!{nu`%q`M{2Ef_+IRad2cf01P9pST9AOK>y75c!9}~)Et^6$`&Nm{wzWcm4c0j9DF!xJTpGrMp3esI4D_iiDe`sswXSu{dQZE_`^A11 z?Z@Hw=65mVu^%X`>;$mciK}XiZ{xw7I_!t)S00^JuxdCXhIRO~S*lPS(S^je`DH4E zxbKNs8RL`N?gCQ@YSOU=>0FE#Ku#DRO7JA&fu-X8b;3!^#{=7`WsDXUxfUsE(FKSQ z&=N`A7IwLq%+vt(F;z+T=uZNl=@K4|E%p{p^o5(BGjsE|WOR`%8+XgGW8xJTFJc4L zVY#L`OdnSM{HyS$fX1)3_JuNNH1aDsDqi>CzCT5=kY5zV<~29bX)c^I8R5n&ymHkx zj(QC4t#mDK;2xi8O%V;C{HqDQeM64=b4@sa*N_K0a&ro4+8LY6cFHz< ze|!g}zF|tDrP=`+U7KwKl20gdW1%!iN>1=uxA|NZJ2peruBOj?RBPb~8G;s6xIi6- z?_odhafsxoxiBf zwZZ)c*)FLc0#wE~bXw0TPBYl+h9hs|DYr_B4LR_YL@S1hQs=p zNEh%_fUvWZCbJtaF#kP5=(O#{8|g&Kmz1&8{@Lufw^DhtvKx955~aqxi2C=)Z-!Kd z+m-u+#^U4(HYn6a1w652kO0bYBt&goyx(n?MR^kI+{Q?0Y{G~W2) z0dS3fuJ?SU(6ZDp=kUley%PK}K_;YQyK|U|?7t9SHiyIfpT4a_kUVIhH4PSaj@3mo z`z}|mHhx1Pq?@(3vTBb5HTXuFAzFZEt0D-fw_kd=XvwIUh3VXTm{wbDA~cESd5cI1 zd>6=&AvG3yu+)`9oxmfrDQ(1fzv(_0l?bp{a364dXLRRBI8kBv!KsL;brY)#E3`o{ z3TlWUsS0{Voci?6MejccG9x_KiqN>So*1{25r6BSl9jUyR}1TgXBLL7Pr6Wv~Nu47;fbiU7TbL}>qmtl36YSZ() zVf@nqW(As~#`@bIC+AxSw!O5Pocf&rYaCFm?Jd?XR)p#@{!|5^Ws@wd855)mI^8y{ zws+VvGXW6%xoj@JkGb=~%oJ~7m6+uhOv?bH+jJJ~eFgp+}~*^C+3>R-MY!IZQoabCh( zN(T+z@Oyc^C)WqQESmh{d!!T8zS(!wX=R#hEKxMXy(eg zZ+Cwm1a%?;RH$h2_ws|nRjn8ZY!>3gn+6Ep4xT|AeFox7!rac2Lw?jsz}JqPE?5JG zok0}q1P;cuzs%Yrze|&d$oTr<`Lx{fbq2OV=!3v-ODq(n?|WxuhtmwJBIoW^^FB+D z-?Ok9HBKc5@)L(W&vmI{prL?4^OE9TR)bELS=<>*w%&aKjzi*@;5#P3moG@dm{Eke zhE#Is;&=o|{2GWai}7LYEI+gmc^Kj4K7w7n)+9godg?yB2?xs}pF1<*!Sv?D~Uvbkgs9xx9s#6zBv9l@ox>d#H6eqw^KZO;Vg}h!q zI33^$4}yF*q+q{DsJsa(SsV!YQ#zi^IF9MQV6i{SiN4dWWCi%YQ+hNc1r!^+<(YnB zG62-D`M3w3Q2;@X{S`n`{QO>migDpz0FK`->sYDOESs6u>-~<}_XN_6><2g7U#XC{ z$#Ig;n{_yEMnlvx-lP*;ts#DHV0r8j518>~33?Ak#jocW>uk>6V||p7{4rov#RS9c zdPD6r`qF1om9r!zS4Jk1>7fn#GCnmD=JIt1Na`X)=*LP7R!3XATgk`;&U*P<(0d z9p<0T&eYqQ9jot39FxpfuPSPYlfQ$s-*;+c1KL+cHIVcG5`H~^Ryu1Hk7%Nf$TCwR!SzG31@NHpm`mcp8v!wyWM49TjTxASJ-8JP*MTHLC}hF==PUOh8kaaXeGFGd<|e29vSDaS ztPeu&zv0^wN}Hahi`$pcDs~FVt2F;K!q}q*Y@{7i#stWfU`u2La4aerBKhV`^zG~j zJWvtZpcHIP7x*tfLSQcng6D(`HVp4=LWp_0Xt=2wEHjK)!DSz_Z?5J@>awRyk?azj zU-kdSs~cp))*pfJ_q7u`IsCq8F|OShB~D56S(Mwwlt?{yURE7#eI&WcpVq(@9Fd~g zeUiD!a4w51Nj(YzLnau+O3MDub|?loF0=<#jLztAM>PruE7yNDD0L}y=Ayuc?^?Ni zf~%GK=iEhn2}xKp7GonJx!JpDmDsco$|$XtRdUDwbM9$9s7x9-of2nKNj~?b@UOKz z9{`=Irz^ba-c&1vSQxSh;I2`cKc8-4)aCy%#bam;3_8vSJ-jw`_}lyukEC~z00EbC zI*dU3F21A)dSZr{qA5QF+{a%D`h#?8o%M?)*hWxuqnQD(TpcmfNq&UN$BmB)0!r8) zxno@Q?$_D&*4(rW6b+?-Y^5|*P`DHmJ%pI<6*yP)o}2^?>d7P#bd2j=vvx2mfLW@R zQLD`%buR*}nzNYNf%68w-D$7%v|=bXg1mYrdZy~}(@RRZ-U+Gx=nmCjVxr5Ag# zLw3R29-MHJl|`mRxj#sv@EfyR#-q>BE-XFEENbV$#dWM?!VjU8~kKZsd@G=HPrI{HiqN&j<92*-3$^M*;n@rG*i! zvi#?j;lc5w>@+r!6*CVUrN9as=S3?(ZBT979$5R#ZpPm?2VjIyQcEFp9orGR>f;G? zK<~FiYY6ow-&}|v7k?+03TC++so$)2~rN``u z>N%j$AbNQLX_!evzG8abf=15260vIXdz7K^a$YS)iw{@x5<|Rr#ii|ov=LJ{eu>dZYe_ip$ZuzvRu1dpjQK1BvP zH~m#t=2_wy>9+YkdNF-z` zQ*#7=^r%R*pIi2AI`>n9>(QJVE1k8?Ilav<)NUjW^O$}^yZZ{_Uwn!4Fq1`aslX;Y zj`XDIm`E1sz|wShA=?a@ZGKDSMU#Z3$E!1nZ)g^Eg3ZDoSN6@RXrGVCHvMIauS7d> zuJltXf9)LdTWdF!n%-iA9b#2$W#i??K)zYho^((ZqluvhAr@{H{diy0%@-~VW zKYC|2Ma)2^=skdLT@ZVqJfiCDqS@~qIGexL(BKy6Aw9ch0hoHN&E+m3*uka9+AIh3gTWdSe~W({-&^oFw`!j7$DcsF$7`pO?kRMK<9h=SV?cmyJIe`$4|zoI(6u9#qY9zM?#zNe^!Dl2>Z^dH`>`wSY# ztU;V*+g0R0DH6EnJA$U{QL&T~&s{`smeC2I-5mzv=v$l@iF;yN0hMibU=CG^e>J;+9k`Si9PzLaj$>}QKI6lWmO_o+_( zmhxA*0|-Na`+*J1qEMIXZf9rb#;pcOw>EDeDjb!|GumQ2!1ac;YqU|X;F@l1_lemzTN0J|U zFJF(kO21aHg)*KfuKT=BA{VDkOvlx(b{f|A9D69_BHUm#S$F>~`Mt@GesjLp3;reY zP~q>6Tt;`XkjqV?i7lqPbWGh`y<7dq<}pDHl-dDA4QG6`QDq)+vq_&HfW!}P6Cp4d zt>Qnli5ri*I1ILEOGD~3Y!@2^Jmcy1xDXmKolC?at}_6;neEfca0rLHT}NLpoUYh` zDbCtfZnYN&>}m-(F{5d1=)bBuZ?OcP`GmsQV@kn%JMJUIep`Avon#8=ATpEo-@hg& z12f-)R=HCD%pUjvbWa|P!}u)=wInpZG*LHKrZDMeC>Qils^IyY)x;kDRs4c3!DDOG zAptSsf#1X>kSli|Qka@S)6O4un-2aKL?bcV;$*>KSxHovjrfZ^-+c#>;(42yj71K| zzRyFiLrwv$rPcNA{mtv=o(*JDA0kS93>OE0D{KMJzLk$cc_5dCLWnJcFJd6_>BpE< z?aW9;^!;arQcIjloW&YL+~MkNO&a>N=pmhg>{SM<@`a&VeUA`ay*P@R$_+WS2%r?_ zs&Z%c`>ie+%!I=Lz>$9$7a`-`hoc&*dl60^whsaQ;~9~@JYn1Oc_bmgVVyAzUOYgZ z#j{`#D_YZ)(wa5;qzR#zo4a|-ANJjBB90r4Iun3*BkMxw_Ti>SjhktsmR|BPCLt>9 zZ_3eQjweI*-8+HNt)$9^s|+10w@sU!PY{`#BnF!ULS=#{k0Zr5`yOS?p8PfWbKT`6 z@T+PeRJ4`fj5t8bMs)0>o9|C>mBTlfQ*nFG#Rri-Q7}E}+eaz`LmO!`Y_pHkoAruu z`&!5VNnA3IG$}Pz)V&pt&AF!$E{J-;or3vWv3&Sl&9KzG+ae73Zf}=aP*SCI1{?0T z9SAC)W(?DSKOkcmW$(K5Bl?c@(5#>J#j@eq#ctX~$TIjkl>Wrfv%Ey+bl1Z-v?NxJ zwZ9!ae-MsHPUx&_W22?9$mCE%&~lzVG?hDXM%~gXGk+Q!Jf0BspkMWxy;^!n<6JIrSYjv z6F%~$8)0^qbUho9Sdf97b_n({$;|XH9-RHrohHuPcro@03KEPFejN&q?&nJFoIQY; zSI#uL6>2^^yOR!51OLO65xGas55dPG;3=uQ35ZYW04#+~byXQf^7Vq`G z zKpxF`G*X(YOz2^@7i#D+s-~A1E;3&x%%qL5hkiy^JhYjJ74{hvVmAx*6BH`M`!qGC zO9pjEsR)A-n1`6KLACSL%FS_Kcm+?4*z-V?WAZPs?RkzoijIr~I+oh1^~T`q^dCFvG$Gbd8AnTYBjLKYUmayaQz#S1le7Q^Hyr#;X&h*1wDpm+gZC!rSKom zq|+o&UGpeXtlQ1;?@JukKG!8PGS1Io0z6O}ZeL&DsON^I0K+>Mxv#ohK+;ByAZ`Eb z2orY{j0Pa3edA(#-pJA0AaJ6h& z81Gl(pd#j~mrizktoid14K5ig7u8FvZmLLP%l@dl05IprCyqDB?mA2fc*6UB+49lb zZ8`V9epdo=OeZoiY%zw-w`8DNwTORV_>>3T{r)1-YsGSo0E2s>tix9OBqKFBjg#}G z`pgkCblKMYs!Z)r^(qT_c+}gLhR|gnq!1~Qr|~kt&2@_yswx{i$KEn`8J1W8BGljl zr@GEG#W(s#AKKyuqLp+cl1C}7%`m#-!$15XF{M(M*-fD%+i#mFbP35jlgN3{8#A-dmj&OQtG)!031jTwGMal=&YtPfq2AUWekP9J-JT(p099!L`+yen$ zVH1?kRrhV7(mGKkm_jPP_U@Xd;x=ppk}4WY0Rbr> z0MJM_;$GGxL*P68y%KBqHntF{>X&<{aeI4m6+{TQ%~Zp}v%Pujr)zg5mV;cFKqeA- zQm5`#Sd{B6Rc*4PS-rO(vf>YEdXmOK?>K@`L5}|9q}#t_IE%g+U<-1qw3mr5&v;2A zCQ}BEn9_u;;>n5N#dP0RhCF-_UplC+U(i~Zjh>U5+b8%@p3HK(R*IMQwE!uritb}< zF)AK2?+0@-aE3LYkg`B*&N&m~JWB9>(Z>`aqRwgioU)0w{U1K4?>-#i|ZfhNa9hV)2)(%ch zJMH1twoeZWwkE@I!dz$ma+;9GeACv>Ncupl@+gBSeU_uzfj!$+h&@EACkZG_vwLGA z(?^;rcJu1$5H~xI@6lHIYC-$+b&hF1p`AoAOKqw{t0Fu#X`OGt$)7Q!nmJ=&)xjq@ zHoxT4pcYKSPT5(4yzIuQ^S*N2NJpR4v0?rB-^JuaXNLis?E(l>Jo8mUw(gsFLLOy? zEszHWGaCn|lw$LSwoj{G7Uq(zK0W^VVWu#ms8BMRlF2z%-g`fOXmndgC(na8fc)s` zz$GAoxP+l|+T_S4$r1sLwkV77ew1Gug*`|HiE*?FGLm1q; z^p0A0eqqbmk3?|!CB9DBN1Zof6d7+ zJSn!`VD~tVaqy<*Mw^8dM5v3Bvj2VdVFb=)U3L2eDM3@>n(P z?Rr_=I17+r4fE{>1LBQG0&o97nef67n-aNnVP<{dd6*B!Q344 zZbsAof&jw+;CLeK2d87t9s~YZ5?6Qwf&{NPEBN+)LbjOcZRXNcR&h)x`TtdpI+b!>$E~h0o1L*2OddpR9!Gw~-E^Cj(7i69S<66ak$)AYMv|xG+;uR(`;h zGIV3}?+Qxdjz)s;s}jHY{JPmeo@-tN$H@hxaV@)}K?y~ts~E6H(F|SlsN5oH8g7*h zGiC!8c1doE3U|D}Vul1yPmXuCk*hmyU4MG2ml#V0+(G5I+`L_=3cD$%$I=@*8m-LU-!fn&-sZO1%ls63+w}AiAK`Jv z>`q~ztr&&(gCkFpci+*1Ekdv*MhBCzGfPBj9dM|YEjZk(tWBuz4?MGeq+*)t>Q=z6UXF_w z{QDUT4^JQ8J%hW;d2xGB>Fl4Y-bRT!ttP2GE5jYoI1e(eVK0&V5W+>zludt=nf|UN zi1IV;MK$Fy%$yw<oGeW?JIGjmfGLH$Y;l|T0p1V!N*Jvu zHSAG0WpwPip0vm7%VRq8$2O2>P5b!WBfTz*6dZ4Wd6O9Y(8A;nOuG((y?F`ac_u2( z#~17CoTK)1G<~~Z4jXlout{e&nZbDHyHf(=a?OtaJ(2Q(!g#)Ugw-QQ?A?mN#yN%T zBtJ`sA6Lpg`k>Pi8a7GssiY$eG0Be8LCoQL{GDqi-;j0pLmT!Z)szldvbN7GVcu*S zzb1rEq|M)1qa7rM*I8!<#w7FnQ?{v^? z0`MlS3+`#ZB5$DT4+`7e-Hlp_2G0`*F@STbRJ|!tk3cC~1T%NR-p4s=sTT+RqsMjF zyrp-Jv?CD4Y3N&Zb1gr=%`MFR8;|r)uxQ6*X{OpEhQ~+tu}^n8Wijiy`pSMw0uKNi zSNX^Z1y;WirM0o_x%zft0U2GcLm_2BS`b{Z>g|9VOVr%QF*R?pTpiJsEbj4jLVAyd zTA;x15=f~b0^(e*Vo;Tn;WTJSxpI9LmL($Lxob<^S!k7mGhnnVNnAC*g!$ms0#Q|q zs=25I0<>fUw_&+KU`}5P9wlmjRWdMYh%Np6n?AAHQ;JzG?s(Z9UR`pNh79Nzk~DF+ zX~jy>>f-2bl?drlM8 z3NfIQnrT@pLmv+QA6efWPv!sqe;mh3_RcOj5>Ya;4hhN13dtx*_TJ-=kX_kZQDkPz zIw}#e_dK%au@1*L&iUP^cfH?zf1iK)tHv=t|>-9mMT!;;Vg|svSzWkN7q#t$c4N$Q;tl3EYwef_4q>GO<#I89VhY;`X*hz$n*GZ%f+;uViG z?uLlxD1OIeid}0r9%Ssoc7@vJjZIsZlU9zvYpjhYiOrzD5sq3OC zpf-X;Nb!DLpxqX^zDIK%=46-Z3%i-bac`RIBS5*wcw5Pu>G|kF>TQP$dGRYh#1hwD z{|cbbTOKL>Gb1-;X6?vWLC+KJ_^Ij?KzJ7eZ?^8XNgoYU9^z&>d zsIjX*uOK`#Wu!`>L@y!=XpQcW+mBaRjm|XrB@etLdr}Ob57e7EkE;7a*t7=M#XFL6 za;KHHk-rBNTjp-gS^;ehKNv>K>+_jPQ45J%4><1HyKJ?;T9#~k_23?xD}B&@Wp{%H z($hU+nWR?g!9dsJkgVz(J_Yrdns+m~9V_gQ7Sb`&F4wZZ!k}##j$>O{4{?avCbCZfyW zO$)m7LE=P?$CXHDU_RUD+sYwT;nKI7 zSs_XTv!BuxpJ!7(b~uYfsgzt~mj5(vf2r~`LHwpePs!o2A3zEr@#sxo8HEe8>V||d zBiz0@e&6}p*}!6jsm}I0bN9Mc2(c#jg@;Nu6!Kv&4&P8-UcQ-00WJIO%4OuUn;^jU z;I3r=T3KQtiMQ7&x32eVtB`mCe)9ws^7u%2P`B%Xc}=Qc&O^{FmS^{~Rho}^s`B+H z=1_T);9LRK?{$Vx22!5m)Er8aoPOA8&{7fyt`t@~Vw%gtx~+g3qs8LFR%(2Uny28A6dFYnNQgcUa>Sq=%alFh&8#@1o_qgwve* zVFimnUtL{4aHP6s?FB%bu2SP=e*VGqXC8iuZ-JOc{5%Lx0g|VvyWkdh&FD^Gkc!0N zhoolXvp6GC8wj?Y+V;r*EN+<1ac`-+!8Mqb@Nz)=OqV?4gxhR^t7*+^+AfxxVt(n{ z+fkk|-xSGqmkZa@Q%`;;r`-Z|? z0fR6b@l%pTwK*@xY+(MwBUwf^z+F*~piC64BWTrz}-HS1-XF-IA%?Zs_#F8 zcmUuEZ6Of>YIJOe$&{V;3vIBw7|jSGPeS6cvTMdj96Y~pI-z7InGW;(DhFqaiTTO9@KWvQi9__j0btLZ9 zAa~-Po%^sDFfme4@Yiq}r`BgnYK2eTwCjg9_zC4V{{&_GTm-!qHGVR6JXDjw;}GzF z6lXA{xo1+tQM{9vwb1&sRXPdGDHbEMbnwh}t+%tvcw5p4J4r#hEpDl=A{;Mjc%0)T zsG}v<$^HhdcE)5IJ^iBWK{7?Zn)vb%c!5eIj4 zbT}CGO*u)Od@^LuIC@_2{=AP2-O99NglFudj{!T}0e8wtTQcB@F9QW6$J!0Ye`T+U zXDx84b$!hD#4YzSyZLy~!IIZuFa3%eU zG4eg5?}sZ6Yj29P^-PcXG*8%VzLL$0!oL?c(!oQ+G!kORsa+lsf5YER>PX83R4LgF zgPNQJ#Bo#)MXU%J9k?RWD;c>|as5b5p>xAwau=X5XbERX`_ZHB8_XSNDe`s?n(e>) zGF$G%n6o+W{6A-@4hsIK0*J%jpB#Y*G^B48eQD(CDZR5oBl-P=)r7fH^PLf?!aK6V zwkIM35?l*I6p@;^H}JIDNs-fF*IFN?k?kj(M)QKM%%?dSkf1d$Nly2z(>)oq8z}0H zH?Qa{x&36#W@y04!9zx@x7un@ob$&)V8#f~0n1|jF0kFs4aZ{ND1~QjWHToIY5)LY zrgKDCj@dFCx&-w$QMi=CqD*=`$NqC~2k366pPXl#>Y7A=iQD}f`)+B-pS@LIW_M?9 zlBS_)(vGz!L$#P`?<3Hvonw@B1uJ244y)M?0)z0-hq++sJ0GZ+{oiiH;lFi&wy(C! z0Bv9z^M;`4@)USP)7dhg@K5K&U&|7&-@I0Sk>I+ZH75_xEn>qh9qmc%aA@NEKBsVBgUuK zC=b{w-0oU|)~tAVI zyJ3BAB}%rsjz7qZ?x_XCWe6!_u-{e_3u68Asso0IvwKdxq1lN#%4w>J zi>}P;$JZ>58(ZAjsmSJl6BWUTe`0eGEf3f_yS#H6vx;UJWO7CCK!{)4C}`C$j5gNj|k znb$4QRurEE3tPEe!JzG-a0DmvXePO zSD#Q-qOAjTMm|=aBSnvwHoEbgyVIz@J$hT*legak-hhb}e#%cm2$nR2 zV9A{kc)WT$np=5coPQIskbGMO@Fn2NxPv$@SJZdG6}jV;+%(cH+*RFQ(+DjsJlman zy`D(yN?8MCtjWD3w}Q|jQccb$}BDW%M$zZZnri2+5ls)@@(wQD`jt_GpTKL_^CO&SSCcHbfMX#JXYFI^*947 zPh&S-G=l*C@`E5CU1$m7ao(Q&oSmY7)ZZ#5_fEyYzLsFJwJ%GfErFeRN@7lUbUrL| z$6;gQSNsI91LJvT+$Zb0>g<4g8T{B!U05lfKmoSRH^pB^^8sJ3{8PzVq0NeypMF5k zU3qOqksdq{>AUjm3O~dZx^vS6C$ldgCWszl?xd8-sJ;-kPnISB*-f=L*8XggOx$?u zg%B-QovSjBbj}%sShZv~r?`*6PiiQW;nee<-=+y4}S#}q_BgXIJoSOf$YbE7vXt4;Np zrKzZf6Ny0aES8(-cqmnIGMg&ieYWryBZ0VTB=4<*@auP4NdIk&q(Mt(OLPm|Yl za!0OpC9sA#tk>OsaCSx0;!$5r6naw ztzLBo>#LKaxxsO=yWe%yGilL`A|6E#TK! z+1VRQlo*D?(k0-mlRM+`OMT8kVB*-%ZGv}Aj1u^j!wu*~>L<-T+u?6sX!3C}lQte- zk(6_=iwXsQ0JbRvJDwMnk!c99w~s~uD_4vMB=m~-ft-*|z~$*g4g;pgG~Ap1m@@Fx zWS)8IKSN6`^vVQ8hv^Oc+O(Rt7!U%wVsGP+Y6fyS%GG+v+dIdVfCXPzAV~~li+3m5 ztFQmbE)(#2#Oi@k$1#zUS6ijD_yYsa{+BHZAw+^zAEI3bc(h0qm?|pNf?oS}Km#OG zrOfCKn_-CVO;}DXu|5YE#d8I2o>}vUxYlv&>=+I28WY>a1;uI)HUM_IvpF;Ln4ROT zf!=1rpKihNFUo=R@sD-pT!EOm%%ncl43f;aem^;|A#s3`b6vjeAzO!M-gwc`-Kj~{ zBX)tq64*kJl#TrgW4o%hTY3x$P01nD6a6s2#MmwM$vyX5PU|YngU*wXGK*?f?#Eg$~^OWW3I@of-=XVuu-b%A1Z|nqY_2 z;~jD&=QnB#WGU>;RwFq(I< z34K1fCMwf9F}G%k(&?~2EY&)W*-_z0ReS$;7+I1)zz`)M zpAF{5ZHLPMJhYU z;GE*@hM1NM{G{L94dL$!Y-h6A9K9W=I6AYb`Y=v{(tpyLQz^^Aibea(q()R*TU|-m zozpyr!|-BZ_Dn+$*2|vq2Y@ghHo!-`WjVtU-bab(SJp2*2i-}$UP9^qnF_OIFS~-< zYj^VS!)Wu}vn6!LDIt!HJ1SU-@ce>z8f4cT4R9V@O^Xg9)4`VpjsXm*~@%l^Ux;Rf#Zck`BNXu0Y(!C zj%Z}UAmD00nsOS%Uull)dU(fZgJ$bo>3Oa`8h~Wt)EM?v(ndlTS1p0|E9Pg>=&>58 zghD~%R;YpqZAw;F;M(lx5b_wkVbnd+ER+6A-SYj^1XUgNGn0I~ES|f|5emjyPIW)S z0z8i6)BZt&h(qQxih4HbFYa6~jyeKbc_`QEdLD@9SBGButjw|b^l*oQjDk<7Nig08IK zb`ATVGzK%LP+>9aFM0hr8t+m`uNr?h&8o3Rp$T&ql||K}7GgobFhCViaDH~+F#yC- zt>7T3&_PZ*feTKTyd6vlF~JmEA1f+*>CCE4ex}5N^$4o)YuxX&3T$P0(IS!+kan^J z_p>v#1J8bWELml|S02YAQe-&yVew+kipZr~H-I@yc$=8#rZ-8L<_nDx&Qv3dJDwUX z!)@=h1`~R2M{$J8bM^1O&Gy2oxe1T;K?NA{iv_eYuhpLyc3%xu%z`dVc}Z}%cHGHQ<7P!Q|e?dwnSpL!AUf!B^!?#^Q#W!Ry+7ofwPZ1mZq z(Id0{htmX1W?2cAYWZo_lOtT#+Us-nlP$=CGK|Ri4x0Xh>(|iN9y1 z=9y26A4Y}ViRi9Fxzm{>J`YM>GX1D|$4BY9xJrY{oY2~Z&};B{Zq9Pp!pox`8e#0C z-h~@fohA74(#ws!{7kIe4v6XUX<)9bd)g66Bz%^Y4p0~OF+rY;l$v&7T<3~4y!bv> zR$r#LblZcVgy2lq!ff+>yuR4qCcljQa03x|dTcG7`CHcxh#POtGKt6ymNd_0qF7Wf zBj_KC8{jl!zZ>0neDp19n3sD?HC=|WM3!}cK4zCnu6Uoj*hbV1<#F2BD)@A~y%@VXx+u}Hcn=_s-({PxzmMZ^xJ1SV zoZMY*FarYvO_@z8Lr2ep)%HgIL7rhYa~#X&&V8oYSw zA4m{3{hw1Vb~~26K^xro&e7i9eg^SqK0i}kG3z(!_~E?sjJlSWIWXJqKiHAWTG*SpPcCMD`kEc1gx`R^YkYWz zEN4vEIkj@&e4tC!(_~x`-K$w6CU%X7U2Y z)Y}T5stEyoSsB{H{+xfST3tov~6@lO}2gx#N(rHXiOAHT!dp6FiV8V)B4{L_P_% zmX0rPa^-{1xG6|#uEGo+!v)QAOjRe|jg2ICcXU!|Cr+LMbLHlhJ)ErR*P9*z$NLlt zmYjAUbljq004ZyOco?HJovV7M*Wb2nF8vT2D;3kGi%F)6Kr#TVW>}zTHnUQxoGmD0CY9J`|d%8@}n;_co2q zWr98`R_c@PQbMi}x3bWo4XZj{it6qYj+o*XvNoS4>rF;7WNn;vA*|A!3H}Wh-uk@n z*hV0S+XnX;K;BOoz?&*9_{NnM25s4^^QUt|>R!()^Z6#G3OmL{CU^-IG_M7_a~B+& zCrV;ouC1ljbK(K=ygqAE_-}ewnH2&&t0enS7}I4i0wJgNvCf|P$`|DHku`K`HfDa2=n@DCg8MRi_)vpMR2Mxy4PE2Qe! zD||kNXy=0WeU(43v%md9Hg9Zu#CP%d%C67gk_#pfXs8lf>M=betm(}0fdDKq0{26# z_c?J!Cgo-~*=wswLXkR|W8d+rDdV00`22Ouv=_Hod9bmB!=D$I4r@7DZX7e+0tO!9 zR{0d}A6^K#yRx@ykotO4(WUJsmFvN)d-o-wZ(wcDSUS`8jO-JSAMa4y@MK4fDP`(P zzxQ2})ofiauWKj9{Rm$Yw^?g=?`oO(Vf|T^I+-A+o1#F`>tn59d=FtgVJAV=y;G&` z0GMvtEeil5;e$Ln8-41(UeMl2kYLk%vPl?0+Egg_;g)494o5FsvdeZKP;&&fjw7o{ z|B+e%Z|)8Ts?=>@p|hr!nYXgV=ZjI4Cp#$E>+g^6r7Nd3<>-t=G%B5IyZUI{e{49G zqnIXEB=M@5Ndf1J#l5YWcLG=A4ufF8S{z5Kz-uM?Ni{{%mr);=l0=473h#cIc{K3> zZ-VUw_Ng5^HgWQhs5tQU@qv-YBej9`R$a^|lknX<*+sSVXue8M0#EPBJ6_Liwl*8l z_zoD#!l%WIXJZ$jm?|zUu0LdeP&8IW*(|39&QzKGnem$6--u{ZGtHt#Hro*h)?lu zXGKo-4Hv1WP*VLj;uA6UwGSV*6ro%PRbwR{@tXoCOb=OFTB4ru-|Id!rP5Y6LF*-D zy|t0qDSVPo$ffyoj#CIZV?l3VsPRYye$F^xxv~Z78_fwlCWbwW!nYCR2nx0_+@tg3C_UDMVa2Br=X3hfP}^Cp4Yg=#OK}K zKYVY`V9jEKD!UrCbSX6Xym2T-cg}!n;?;o{mM|zWj0P@D|FO-rQ zKt#ApEh#AX%_f%9!G6`I*K=bSnMIhQ%W5&BOMntzVr*eS;WR;FgM)+k`#+Vze*z&V zkU^I-R|!Nwy<~>eeQ~hJqa2|DdpX15kD=6U73Du;T|VarycBP^n#IZeIJ&H3S9#@oec~poZELqX$DAc>XZyuIqd^GK0Jq~0kI=d zA7gMo8%zmkEdnqMh)tkp?V0I;Tm3`>aU3^~dXw zlhdd3=iygnUgYu#GRhxln}4D?Gokczq?T;RjCk0=fUHy18$lt!-q!%sNxee7No^+N$9d?Es*``)0UJ4SC&FNY0pf z_MlbGdUy$|F}YDvJ9GTCkZbsNKj3DL5;=BGBx8xI;n)=A0d0j6MP7Mi6MQdk@Tux2Qy`oI_&*%EQ0bE?|R>P$rDhcFa8O?JIK zPOpFDa?-L*+Q7RrCg#y5z$l0d>n@+OYo3g>-Z*x&`Jj5|=*UOYaJer6;FAbdtt0O? zrFGUE?!XeUG}G8wMgeTs%+r;3uUU;Nq5EuU{h-g&UOBKhdS`;J=m!~xn*ztv_p@dD zR)tR!P=~5kX)FRsx9)uyuu?0dh%Ht7`PTM@e#Cq!z2ts;O;L)tQ1ipDiWqbGz@o_p z^D=UKR#`S7HAt4vQtD(_SeWyj_av~#tJKlb9>-s5Ykuzx_E1ZNl4)~f=zG$*;-y=T z2ozmFva9az<{2&63fQ?(Q8{IPx@t1LuFcxP-LXVctWh3AwazVTt2)w^*Zn-#eB`bD zSHoAusjOBK5(>uQPGj=ijdOH3jqG?(<5#C{*JQ?Lt~@zow=Ii4Al$Vr!#+Cf-gx)A z`_h(>b@7?*6bYM8%628gGW^rwWoG$mK_eCk`}B&llStfwHf12*{5spmTeNH$4{gCY z@Yuwr*k@%m;T<60bw9z6^WpWi@Bu^qe-g;YAzI+VjgsuZaGA=^G*I{KLy@rIjSpWb zFQNsCp2T;S$VaJtZ<(waRu8y7^X;>YhsWp zM)mKgCeE@K;J4vQSV z&-(Gl5AJCp>K*2-`U|4i;u3p8xo6(isu-38>cY zml1Eo&FBBKJpour?}q&nggpFiGM%m+YX`ng8P+uRnJiMyWcv*_AZ8KAB$w;rfmN8C z<-2EB6TqZO>A~P{*<);wYqZgxQS8E*syOXvGkGxF@s(scud0uv?T)fQ z(DGrwM7lvpitUG~6!*}kZUpBn9PuP`5^nMK@($xI^0Q~axP5qU>L~uF{R_<9&m z({}$$WuD1y-QzMVb3jLPk`~bDJNkw(Dv-6cKUb4uzD= z-w?i0NZ2K}AbT}Zi^uOZ32xmSxJw+6(3j%a!~Tdy-@RxVx6YUw2|V6JX+mSJNclfl zF~SD#eo+lnB=ZpHLl{)E+`sI^-V1Vn!6#Ml_W4aH*Pe(++sNI`M=5L3?X1z0;CJeE zJiX5Mp6JH*=R9W0t(1@>>1y=lP^F=yJil6JxU~I}EpTsBx?rJ5LbCbQ zuLBmmX1MO&!E}khx=+#hCesIB53`IWwqyFtR{AUv7vJ{Q^dn1S0@*^UOmRwctFy&> zd={(J@avBzmu$MbyamRMt_$kfHY<*v)%%&nY4hUDH=$k)$8LHlUG0G3Kv#T~-vQjw z)hXbsNIg?~b-jRw)ir5Q(gfwM+Zk+0haf z+4ER%>T8RnKAoJ-(s&tu&-iZ@A?^J|d z6md=9C4am*v2r=aa&a?~37bc($n#wQ<8UGXL+!RtrRXGSj-2INJ#+3J=}e6nOC}G8 zN~lvCS@rxoq7w$CLg-wx!%V%ymw>~xhUw4cADX*$A}D~{21F$!Y61aHwpdL!QcrsN zl~$s5kk%7HWHkZ43%mOcwlk3RcbKGQ*}K(Fxput)rpE0zH0vY(EyY=blQZ`odG#hD z)~{&r6XkSE(^csqsaMm>2c%xsT2&g_Nab1bTY%fIoNHatDY@C@Ei~v@19|F?szU6SWRS)uDXqNY!48RlAb;S*ijqus; zp;bteR835>3BXML2CewOM<^q3M*ubU`}gnI-oS&(vf=GF|JJB-inGOH_dc1xb|iqR zWgrcNy?1*8)vAlAaiBE%K3Q>5Ygy-#Wf$>FqL|Kvgb&6H?iQC*Z|PN)xZJhH#d#=a z@s9O0oea6Lg}submzNZ{iZ*_okZ$6G*h5YO!dE=7c4=YA9g$y%1xjkVl#|1DShEjM zH3(sS?uRfB3mhW5Wrm} zrY>KpBxM&CC;s5Ie_{o}upN{vdb8x<_$5iiQN49`z`+Zz`&E`yLAim;X&}$HAfKmT zkO2Dgdno95mWMH~h2c4);H=MigT8hyzl|4g;dU7F;p^X>w!fa0zf{^rf?>~ z0w{=F_R}ru{g5i@&xwC%R-!-1x|(k6pSb5_)$f`zyErIvSCs{z`iVvU4x_znFKti!!av6BkRX_=+kEc;*`_rla zB`g4ruCJGT3XVTTrlh3Yj>1>PNIy?sV%Yo*=qaBIOY87_?P04yx6TV?_{~K? zOHEo3|2EA2JAMPYZM!H<{|!s-$r>l5{19icxV`Wf-{<0I>{v&H4FZaCy$B6Ludz{v zRH!!HV#JGP?5(L!Zp#}NlOODgWqjO+yo~+LasPYxH+ht2KjdfCFQr(oovP3?vkFK^5FvPJ4^LD=DpYQi4tUXuY1;erJaBQ79 zHcp(>mKvoD+)bq5SX9siR>(%CL??*D>Snn%p}NfGO4(RY^puLI+j$Pw)NZLb5bKo{s|0L~ z-A3R~;QHMg0bHSgESOM&N&@oF4|8gkPF-nVM=sQ;d}wcS{{!iW-)yQ``D6t#xlh(O zRF0Z@O>0uMz9g)u{P))ptV5lH2(gC8I5i(FDRG5Gp1bgBydKgxJy5gBfK(#D7NzZU zatG}S^z#KL*Do5=K*F7hk(`mbdgI1XoM!8*-};#UzNtEG@Nki#`7)GfV;VlfW^)=` zBaAjK5>gx@wf_D!B!2C6xBK^K4%x|+#?P@5N7tlfWo6xWJD~Wz^cnPfFF($Ixt4!j z9%x^1$on56XZB0Irm^kw-*rd1YVO;(*LbB21@7OPJspo%WO676#~oUMws(zP#+shG+$ns0IC3W z_{kYU>N5<_6=j>*0d}r-?8U+--eXfy2M+opoYL|=I932TMp=&k#tzJ^72OtRJ8BVOvTYPh;@EE=LJLeOk`y?d|Dd9%fWlhON^LnB^6x0LyZqz@imyogJ`$C@Lr9Z4o)ZQz>NCavG$$@e2#r3 z4I=}I5KgV>wl)~_Ja7gLQGju0c1{h%cV&6c`doWWv$>q*=ZLc8J{hBiKXNK?zx2Nr zz!pph;BLU2OaZTv>Pzj(VpSp2&OWNCF<~>NgL!nezhxEgj;&2 zl>z@V#>sykFCnFL?|(j)J3SFr|FFa`n@KbhC2pZB7 z#3>qIn&~mG_Vki=p8_x&CFeD4V7MvgJlk^G7H;(apFxr+7Gc0+1KfI6$@aeF+d7DJ~_-A|H=0?Da#&^Cqb=!=fVz>giW5nw=jWQBS%L^t1EZ@ zCm9;qlG{($@0W3T&l17ownc5pWhfM8Mwn-fLtb7H|IYl)8@QikEc_Le+s60x?&B*m z5kObB5{BD}gGr7l84~vP{N)C~3V;xhBWd%=^j0&KBw3T3-HU`;hqWA3OWW~<8nl-M zfYn-BI0_?g`3$_;&Exw<(G{QM|8)Kq28x9NF-F$>r@_BO)t^T*i-U1bX01<)zC_uE zR@8qEQQ#cm$YbXIUPVO?z7KI$pw@r=-V{V@>dC9Hn==1QBVy_b;#*jR+&f*$AwCl?o&G?2Uk4=*Ej zFK^Yvw*HTO9n!XRBWe++o3)4O!OC9PC=_l_<$M(W8(Akk`zv5?nJifb^rH3N?Hhio zo$=nNmSEz_QFHj|XF!vQEcdqPyZz_4|M_GBH)k)KA9XGRlTJD;3*y1c#?ZWkeaQM* z^`Bf04#Z)ARgrE4rMmlk8E5F=NpaW8xKNd3)-orW$m+kh(W12jQbQ7oi z)=#qbmhkplt}u`FC0sV9sdnb5$E!zX_xlA{4wW&j0*DCm`=1;Sh_sB1xiH@C89Z93;8d)EUk=lPNIZ`o3H`Vd+Ig`=CV}#?PAXvzWk{x96fn z0(rYh<>?PJ>Hd8v@c8=*vm+)>P1k@i2>yMaKw2nihLV6Z;wcdc*E2{8=xNh(FkEe3 zq_pc;ISw&}`?lqKx<4vIa67!xu|P}G$c3MDyg?u^InS?uM6Zzys0QM9ChW>g-ypzA zkOUSfvhTTWq{_>TJ{+kpgwX{@>P5ptiJ1NTO5)8 z8BiLUY_!*AJ$V386^TicK@z0qOPWP#Ea5?}!$_&fQ zOcRKuR^tLX*&CM(ahYftiNg!a=uU|He)2nU2(~iX@Yo|foZp906;o=d%aK09YEW7_ z-yX*;XE#z@?zZ&fQ?2fYX!T8@-$(K5Jo+AkyOM+(944x4B%2NR&avFFJY^9_br5UtzSX5@gmYYm@ z@S$jtqFn18bXQr0IYhQ=+2~ZDB_DRW3d=*B+3q`-*1P$i!GVIG(AMp=vBQ#^_mNxp z(;4Iz#_~&9jZ}}7oW?R;_x8&h?b0N326NJq4~>W^TeI^!o4=G5G{|9ff|`NN5+?ns zL@IWva(*@PXPmVGQ#rgIOY*nnoqNDDy$hd2uMT>wBgzg>YT&BV2U{k1ah1(1j_v0` z@o;6~SUGW=!+j!oa9ko_2^G75?VolPmWk=Pb-h{k=phZga( z88Rp7QzbHkpYG!aug9e^DF63Bi|1#CeAW^CpakO9DTT!p$yhuT8Aq10^cl2O@Zl-2RXr`+zCPj#_FqXs}W2{Qvn2Y{BmNsG45? zB{BF_rVgT$u0 zE8o6|@C>uOK1Ba}!V zx!M$9J1B7#_JSs90cKlucib?T&HqQpLE9YV1?v{gh2NWKEt9FX8;3DePnCL5Z=k)Flp=?-i$<5H4zc z`?2ZZ+p~Y8FYr;m3Vn2(u5Z`Av6#S}zkpQpZ|vNP0DY^I-oa$HXzg+ajQC7%wldRN zfOAL!UwFtuphqqR41v|3He4cQF5;UU9M~lti-k<HSTs^#>-Tf|C2&~#m%6WZAy1jz!Q_-IbpZP z8ht8}UG13lz+N-7+01+RlE)6OT^3px7fn@1|_b7^{bhPet}< z_)77(<^>8-qQ2X(n4faVhm@T0@Z{5HFSWs~EDXtV@7IAMbVUP6;v8^%l3PZ#wOZ-* z*Vk4lRj6OYpAZ_$*`t|tYKmLar&&{5{d+5cst)rQTn`n8>Xi+0zXc6YbTPMgzewFg z23F=+`8=FXXF6b*CDVN$v3|6iy;TSFSYh$qrbhKDcT^U9l zj}3g#zty{k*>s8S+>t|cng#3@Rz`z}njy{*?90mV6_Mkvv=iL9pb0ttHf$7;TxkX1 z-klTGb`2~-Mxx6~+{b-KiFd3XG`p?+6-0PMorB#Q@TY_CH5)En#5WrmHqj;@Fvi1A zeGpO@wuYIPOgRY&02e-U+j7!$LZ#5mS72R3MJS^gfheL5`kQV_n{8}KXaj)V%4b~As zFrQ7yZal}~{ELX@8c#V?2LlM@)g(|;VvcBjEuTJ=`WkOem{DL!+7Lr!U;F!mGm_^~ z+V^T?%bz+8noq9{ybcq16Gzd^fS2`skac)@6|;8X8l6Q19epZ@l^3@1ES!x2XLNA4 z_FI8#x5sq7hXVr83D;_5$sU!*Ye}zyx1wMC?Q{DSgrUx#fM?_Fj@{syA2x2yL^J{S zPPLkQ#O+9E9a^H*USdriL6rGHDt$B!vu~t7^)@_e=(<|SVd!MenX48AP(Z$4WoC9_ zeN;I;hEAr{ZvB^gK*1AWfI~5H0a{Y#2UBjn9`7;3JDrI5leeufemoZol*pDlVTSHP z3#8@6kxsJwUFg9(;)>Xm!{nsFC<7}Xwv_?o=eP)$>vvvj>yw z=YS7{pIOg(u@mJ%G0G^TM@L6>l)?_{_e`(yLxmX%h*D zMJS13@e!}HFR{?GNtq;%=4#zUgfFP^$g|Ax1<`vC&qIPbwGNo}3>ZM?=Evk6r|J&S zi$UD-za)A$kcqu)8)1mG z{FI*zS4{wM6S3;RP-!$0&8!6*;>|%T%HJxZt}cmap#~4vD0Pkx22gBbPo~=2iEMFa zSN<~qRz>jf54?e)>3%j;Gc6C1_YO0C|CDQDt7+bE({$0($tizZ)xn2L?@6_ zR3$`yiwH?E%X*^k*^oQ=z!1GA|E&fXHPR=rIEGq4%0=SGvror2Y%k#d`aPmx5@~7a zdkmPa1d-<`6M%& zp9rn|?C(5SRowEcasXoE$)s`=GvJk9wPt|2VX31T2F}6x3#(&IMqZND*a1muBh9?X zX_HSLo?$y$a;qFx^U1W|YAd%)Gaf|AEHqZ*{PW96FF*&nO-@c?c6t5=K_z@2f$8<^ zY}d|9NRviy7sF$61>@bV$B3*VeDg4DX3qScxVTL~5Go^T?}aG+th- z2`EduJx~ZcSssR;yX%oW&ze|$TF?;>HGHp~Eq?$w&SAD?d#s$$|4F@l*T7}X$7>}7 zRvPwxrPaLO5X-qYiQ7{P^4Ui2GDbq&DJ3Yu`)8zfMi1{>HEq`+uR1bJ4x!#n0D6_M8Zs_# z3mc%u30aK|avL-!XI&?{^%v4OXUr4OzaL*|-HV&M5GPx)SUqYMWw@Ex;%DHx^&FOD zncjYHD@AiYbGx1O(rsKW>Eg}cid)6bqA}!r!G{?x#)c?^k+q_uv%Xh3ha^A^{%wnpRPY({1LqK{NQy>!UjUc8f7x2` zgyLiGpsKlFO75ee2#drn3Glyna)PvUP}e(t6P z(8^W6g23+fzT5gZQQ^L-Yg#^P;QK8FTZAe)*|CKS6(I>8a2aoN+XEkYf2jAF!Zi3! zjS($tF@bu(ypeC>`IZtF;jz`F6A-Y7ZUQBuZxp&q4zHb9cc*!1`T3p9xL9`nWhNVr z!2lf=fCA>;1E&E|yfmrHqB#XnUCu28b*4#eZ{lLL(42#`ui?BO&uZj|d_Fh!Bw8g$ zn@2uezsJz@^XM(T{!CEw+EyG*eaF`FuTN%C zOZg)khBpDobCl(3ud$bhr>EdmuQ^l^Cic|y2m>LM+gsZGYKUAeJE5YUX9}j^JDoojv<}Cm&t+agmp?JE0%d#fo}m_cYogpjn5&egilTvDFz-Df}1i zB4)bXfn$dqb!cCa13DdCgMNehaa&${n5Mw&bxeKfNmHq%e{T_H@WB!H3QgFK2gNpB zP<;xkez-y-Lr(0^P^G!YH~WLut`0=mPXbVN64iv6Nd`s=eUQ;?V((+QU0&B4SF3*{Pm$AVrq;v&)c>VLy_UCe45VEsI@ZWM2TaB# zRU6XaLx0^H=0)Z!$rIu`3*s{Z!W7pU@6aHvX*vUuzME+!B5H}k_gFD)3=f;nI zi1|B!@iO%p;L{!JSEI~vyUByf_{HY=;RuAK##-h!06XFwxYi?xl}oWStJ*P{OcVe~ z_v(y8!+BaLQB`(D(XrL0ReKMn$R)8mU2@$q$Pq; zbZq-$IkP4V(`m}e<)cwnZLrjiA-X0@VY~Gi5-PKX20#Eag!JOw1br%7Rr}`(v@d!u zCo@&wE1SwM=zt~$K!eJ**9GAv!}Cogn9(d0X~BwPkU4gaWh?WVRcE3N?C%_R_D)Vw z(YmJTJ_0~fhItqHPqoIFGQYE2!~?aSRa{vjcDWhy5>oT zGOMFTWfL`aLx-!QL(9r?~D6y9Uhq=af8z!rqg#p zXk%gE-;=@G>MUv7p@P#ni@zP*$YQwA0Dlc21`%pV;p!_F@xI(^eA5&SZ{rU?^Wj}! z6Y%C^eMYilc_~MAwqV`h=I0;WA)MqJ^$IvyJ-O0)*RuLYjTL1TWd|(NbhIZ;nOop( z`4bc=fsxaeI@zc!vvYFFetFRKSMjef2_#oIzzPIxZ4oB0sxKOzX4Wltz#G@LD2Qr5 zm9o~xF;EU*_!O`}IigC{sU%1^$$B@>Fa_H0*>*1Amc^7tnKxcPpr8zZTme`6(0@J| zXfBE;0)lcuv%tqq05V8P2B^)Nhq~qdR|1KCfe>(GeuFaNc)T~zvma>o)FZv;sVD@D zynx%jpd8m<{zI zz44BQcmN85TNhy2plu`Nt$b;sKELSBpW)my@*ZnL{lFaD|7-8c-;zw*wh@(1yH+~o zQd6mwOU~P(B4CS|mX=v+F44&NRvMbQpcpDmU!|BhndzGgrsa}~;RGs*v>~aLX|A9$ zxrCyC3y6ZiciVh3@BH@t1LJY%FM8{e94DY4JQ} zYS0fcOC|N!{@iq*a@H$Qe9ONriBWJrhLhC?o5K2)!=~i)0hGh-mMd~RkqdIGCB(fU zy5*IvHssJ&gxudt>g(3w2{)axskJ_#h96qTc~<{c!`n^f zg+SOfdm8=UI!4%}d%RkXd}yWU1H66h)eDTsQr!qkcZE^zbI#F$k(dn7l7z}@YSv1+ zIcEYw{HJjfg()x7R@zQ&o;LdJ2vi6Fkl?OHM-Ga!%w}co(6=I5LZ>n{9pr~6!z|S$ zq_VfE7##n|{H(t$wPI-D`~L#((@V(MZ>p6Eb8k%4{lIGT;hZ9cg%~HhcbDCd%0RbM zs?uZG1wSL{Z0f+NzDiO?w9~XT^dWptKJ@M~0(@5*az*ZgabU465JN9eFY7vD8Wdz_ zlAIonnlivB;uDXov3sIgoKx2>G6a;@?v0qg;r`RnZ{4wMw2%}(e*c8k`R7sNT@>H} zfUU~mHR~8!4rJTHVlT=v3wz2kx&95Nz?@Tj8)s5E}t{|AFA=d_Y zOTqb{ATx>U``k~NJ2hYk3r#Gn1}|1Xj}jq!9%;{k(?9!WZt1z#{OATvapC-}#$LWi zi2R>~v0v6A<|?Eg)Ye#VyRyr7RJ$N4vFEFfmb1jHF(yZN^rc!ULDen>KWu(D9Z5!P ze(qg(G2HmSqyi2B&W`vo@N=3l?+dXbWn-`1LrY1^_mSilpKLLxQp}@s?=Tqw6Do5Pui*IhPZtaT|GAE&MF$;(4s9Bt5f+vbITElRv3( ze&@3GgY%ltiz;PZXq||TeA+sP9bc(#*G<2ck&zF3W?0$Bxit`EwvZb7jke;810>h3 zb}}!oS_xUbJ^$_PWrSlJ-;v4qq!@|L9uM#ALcMu|+|fni+AqPpu+CtjBrs#Y1jKVU zEc6L$d!2l-MgMi5&7?{Dfxj)qn;mIZudn7I6V$88%05A!PtCQTGSxXKMGh;qXa|fE zJBUmhM!}@e#A?s%bajm+=Ka1WxHZWaj;k#XT{T#;bH9c5zA8txVHEz(EeE*PP9eD9 z<2|evdxmVLj_n@`lp>6@ zy_ZTczm54_lGjPwPaq$dF1HdIks&Mp;%bge$QZnnp${}#&Z3)z95ei@b9;c=kJpY- z$G#RZbgyTi3&d4=3%+gXOSp|g^~^%K1id>re4gTka;7m@WA}bFo`GUbT8-n19VVdO}IkuW(H_iil_S}@$xy(Q*fCcNaD60 zxqsWK5lESLWnKgy^ci@da#k9^aW5)oLzbFxlUVBA&UM~79PF7=rW@Ot`>9(Gju3N{A4%EK0dPuz{=J_LUv|Pe^*x3eq_ExMNjB3?{$+xH^_Y z;e5pH)*~Lo@y=;b=P$Iqp9KR|j(>D-kaI4WeI&&HPFRtbZBMiQ^PwE`pF$Z7#(@UF zP2~&InXDTNx3`4)H2mD8yHl{Jk(|C(VA2vwY}3IRqo*qy9HvN7a!$$hlZqjmb6tZy zp1fLd^be5LmcI`_d3@@A`jLDS!b0qXVvP%y>+DfL86Ie=*TZ)PL??Lk^F};4=dwv; zPRBV>*)f&NE0vtjYHw@vs9l(Dk*g-}ARSciwv!f)E361d_9y<;9b7)PBw$3dh`AZi zAY4)BVh3t>;gR=s)nZW3PT_3bOLDK)eTZT^*m%P!HdC!FvK=Z=_iA>Bg!`SsC|P3u zz+oMr^PUcTebccFK>bqp475+?5RUC{Y7klp^p=Q;ZM+c8Zq6wBtH*5c=QHlp7wZS%6AszeebN>>_2^H7uuK@g%1{vF}DT>U{h`}c+u5ubXcFMH)fZ6-l z!y=qVN>jqgj)3T!mALcM;1!8}PDcMCU6<9?l#euNff${zE=b0d%;TcPFfw`y>zjLg#_WgnwatH|t}Y&WrR32m5W_AWNa`OqIc{ zW{_mX(Ck1psRCgMhJ*hXhcAG1ocb_kuY)%9rlYzq8h$K;X}=5m+8CYpJ4Yw6zLi%S zpu}dkAc_hVv>NfWy9eLsQ-6OzoBl{WAkRi|U;anmJ5dFwz(C9~-A(!Vfw z(E!S5ua;@}(q5GrIc6|PAOSPg{il$s$UBI}tk5xuP-VedGyZd}xqXvWvU_`{;Cf0> z5fN79T(#iq-q$RLb(of0ZA0lfepj^!a2-6 zv{v^7r2J*xmj&XVgZ>Wd=RqwGGe1`-Svll~bz(-y7*N1ooU5J*aY@&5ea5ss6n(a? z`N9l?w~=^1g2wLDVRD5ovqLc^Z#YRDFR+QYV4emH*fzOpzer3>Pudh??f``be>dD3 z)xB}1O6bZpnt=j(m92Fxq0dz89n>B05xx10QDL-YDz&e>h_u@9+RG)Pv4{2IYNiMy z8auH}j+fW*;q%Ymtbq+KI_r4gxGUeYJ>hq~vbe!N3%NntH+Dyh7I70!cu(qE_`Vp; z07NvH4Q2s#9;mKj;>umoviK|H+#CbgGq`D+QxI*$r6&D`yf%-M^{H;6gi4*j3?c9c z8$}NK?0I4%b?c`p2;SvL3*xY`0fe_KIZqPm`M%{DCrPUt{bS|zlhbHBNlUe7zcK}E z$L2zIl+z#Z!thJW!}{G&JAC@Pg`H(}GLM_m;uV}C9Yt(vF+F0Dy7{`k zY&v=ZZf?8^qSD>~2iP#{qQK632aMplZye6Q3X>dctS@JHSz2)zJaqXvFEZlr>9$oY z^&9^4pN`1EJcEw_wi@P{zJqQX470?WZTB*5Y7F!3#xJO^z|Gw@)bFoY5#daTP5OgI zcbKI$Ok(|9g_%#If*$3ga=U0_n%|#}eWwyeW~(19Te+!xF*(rd=LU(nM15;<7Z&oA zrqIw#r7}&_qgCdvS7+!|3?8w7JNRtHQ$~8Yyw(xC+n=- z7SQBo3+)tbg2NJn^=lukNOCkiEsgt~4tCrZ{aSnrHRMk@_?1^whFrEn3mT1NSC9B&c-(JrWu@FUhSNf+(>-_%kX#@LYnzq`^M#XX}(*!_LZCY za24(5Y$WH^=;GY^#0c{Y4{_!GPvm_bd#&6ypUpfwu%|+=UEe^Q+oe$7cXnyF@O67L3%SKO#rdayD^4^vH2hG{w%vp|_*jKf4 z=jb?40UP4S+Mi~(Uz(^cvgVB+r+Rt|;wnFRYcz(i=&Q14Ok=V-tTPw4%v&;ZrxI#w z6&rvLjj#yzBr5~N*7o09CkIE=>EWwo`ceL*@Y=504RB*xY#SY{)p3Gvn9zBL_FCN0 zl^axu8p~su8HpiDNi{%5ojAv1{0?t7*mflF9&Y_x4#)X(jyLl~c+s6*I1G7{zBI;tH*_ z94)o##4$cU4ohj~e#C^E><)3E`d;ftdwTQZpDmp)9)n5^+h%BE?)8LI2A`L!zjTBL zPYE&+#0&jDFc&4Tg}VC}E@4ZGyWbiK2dvn6Mpu!cQT_^6!RG!7)fE>V>?PNFm?vc5 z>A8gcW=5Xm2#LEW_;XgMQ$=Y-#lc|zs2}}2ny_4Kb%D@Vrtu6rOmUe!ph7;;L`XHi zXcDHc;OYbIk44?|A9-=Ml{Xap)^{jb5$Kl?v`CIT`bDXV*x{h+UARtzOd}#US>a%X zOdU`5^_P@lkQxB*B<&RQB?FgJOH2-~rMnXf_{5%~s&OlUM^i30FeOM{`XOXs)3_BU zEAyNr%bz8RJ=Cvw8y=)3p z`K|i!j$l~LqQ)kabHK}7WeyB$x*({t#cQWf98qh&X{R*Y--9)~g)?XCL>&z;v9#hY zTFY?DV&1fPE&*z}6Ki`Y5#(-eVYB;OzZjPSDnN%ArA8D>wODpQT4Jt}ah556JE+G_! z_P0uQ!qDhR94VdpAqajIOl4~>oTaQ8H5yXaTZUOb%cRAkWYV?KSNlTqgSM=Wgf)JP zz=?Q5f5zPEVO!NbOCbqEwP^Ff_O_`gdm67#U{Mp^_bKcq2IoO%zcJb(M5z`cjv1Ck z+!awNRhwjj6CQqu+xC#{UWo^3+h?6ymzq3r?3JV}<|u_9x=MWAm`1AqAnOsJ*@)^4 zr|`FkZlg{Cd!#Chmhn=_ZQe;~-DTUOv>)Tbmh0{z_42vWa|vNUO% z_5KA1xNHBgw0zjUH|s5xg$b4k z@Koa#-AFizrr6h2#$k*41tm7_jp$yL4X*DZcklq!u+>9E0WnhcOFPn7Vh^ao@~tno z@RwY)*+8&|Hpdq)`a=L*Teuw;_B@u;o!a!YaOO@bs-?*gqpm?nRkXl~mKFfF z+OVzE%RlC`M5-+KM_GXZ@9b;=2C(sq+R&Ko_RzZ%5P~kDieK3yzV4BN*{$E%KY;4k z)s?*vacHYN~u+?SoI`e@S2!9Co!cdvz;@N@{yj`0-9^8osR(V7PR-O&gM)x3owqs5oJpIwc zgY`#VzjI$V>YYDrIr8D;0JK<10@ycefw z;;oV(!gUR*xBg%xTl-#d>u(5}#jFrLKo}q0b{IuuZhuO7n++ zo@9)d#`(AT$mbW5g;c;&z>1_2Nk%;L?TIhfeK%PYp>5N<5wdihxw4-qvVsN6t@bol zDFgi~t`B&ZU3ek!#fXVE5Ao$7AwI+@amT_m2SclwQE{cLcv3kwhokq+!S%>Fe_*(Z z75)vhq@YqZqa~Hf$0S?T@nr_%mV%*aT${~4)6|(P@Bq_Q!VC4tZa`7?ra`4?oV+wSr2`TVSUmKS_>V@3%0*S#!+L=3f@oF=4k9U9xv0p1;Fx&}V;X2J~h zcz^}G3|;s8JyEFR*LB*fPUm+?f+ofnBQ5uK%NrwA+RV_~h<6-mw_wU?NGRI!zNTh% z&>ty6x8&gW75gdW)?p->&%?{*brS|k@b|(>&<^nyO55Pi_q*eK)=J*Uunw2cw--p%E!VXuDa? ztZ$HPKJ6$Sh7!UrpxVBLFSnpZOw$(ftvg!Nk1LVfL+FL(u zh1Abu(oCSmgqQ2IrE;Zz2f2DAD%T4XO6tU&)2IB}vV3{^xpz1MYFEPy_09RP2QvmA zIqw<(UaCnCs!mFX$+3sjnV*(O5)y`jW!*wzF-l^K`Bxgap+0Ej z@c^nf{Ic`6I5#9bcE7fwiiP8JZ9dr3FsD~SBiW_`8{UgFt*{$@qj#E)90JYra>Zs3 z$sCTuzOye2GdTO;4@;wgJK@!ij-|c--insluCR}{#q=D6Xz#nL6;`rkc*UzLTR%Y{ zN2YK;Zcz4YY=+|(0_?E=#~3U@I1fIyRiBF zIeWj=id+b|L;kSMs>NMfeB^(={IdrC;NYJy_$L+olL`OdOqgH0OpSa?FTRhwb<|%A Pe7HEdAEg|=c=LY&YVNkY diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png deleted file mode 100644 index 13b35eba55c6dabc3aac36f33d859266c18fa0d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5680 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 diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png deleted file mode 100644 index 0a3f5fa40fb3d1e0710331a48de5d256da3f275d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 520 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 diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png deleted file mode 100644 index 2f1632cfddf3d9dade342351e627a0a75609fb46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2218 zcmV;b2vzrqP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91K%fHv1ONa40RR91KmY&$07g+lumAuE6iGxuRCodHTWf3-RTMruyW6Fu zQYeUM04eX6D5c0FCjKKPrco1(K`<0SL=crI{PC3-^hZU0kQie$gh-5!7z6SH6Q0J% zqot*`H1q{R5fHFYS}dje@;kG=v$L0(yY0?wY2%*c?A&{2?!D*x?m71{of2gv!$5|C z3>qG_BW}7K_yUcT3A5C6QD<+{aq?x;MAUyAiJn#Jv8_zZtQ{P zTRzbL3U9!qVuZzS$xKU10KiW~Bgdcv1-!uAhQxf3a7q+dU6lj?yoO4Lq4TUN4}h{N z*fIM=SS8|C2$(T>w$`t@3Tka!(r!7W`x z-isCVgQD^mG-MJ;XtJuK3V{Vy72GQ83KRWsHU?e*wrhKk=ApIYeDqLi;JI1e zuvv}5^Dc=k7F7?nm3nIw$NVmU-+R>> zyqOR$-2SDpJ}Pt;^RkJytDVXNTsu|mI1`~G7yw`EJR?VkGfNdqK9^^8P`JdtTV&tX4CNcV4 z&N06nZa??Fw1AgQOUSE2AmPE@WO(Fvo`%m`cDgiv(fAeRA%3AGXUbsGw{7Q`cY;1BI#ac3iN$$Hw z0LT0;xc%=q)me?Y*$xI@GRAw?+}>=9D+KTk??-HJ4=A>`V&vKFS75@MKdSF1JTq{S zc1!^8?YA|t+uKigaq!sT;Z!&0F2=k7F0PIU;F$leJLaw2UI6FL^w}OG&!;+b%ya1c z1n+6-inU<0VM-Y_s5iTElq)ThyF?StVcebpGI znw#+zLx2@ah{$_2jn+@}(zJZ{+}_N9BM;z)0yr|gF-4=Iyu@hI*Lk=-A8f#bAzc9f z`Kd6K--x@t04swJVC3JK1cHY-Hq+=|PN-VO;?^_C#;coU6TDP7Bt`;{JTG;!+jj(` zw5cLQ-(Cz-Tlb`A^w7|R56Ce;Wmr0)$KWOUZ6ai0PhzPeHwdl0H(etP zUV`va_i0s-4#DkNM8lUlqI7>YQLf)(lz9Q3Uw`)nc(z3{m5ZE77Ul$V%m)E}3&8L0 z-XaU|eB~Is08eORPk;=<>!1w)Kf}FOVS2l&9~A+@R#koFJ$Czd%Y(ENTV&A~U(IPI z;UY+gf+&6ioZ=roly<0Yst8ck>(M=S?B-ys3mLdM&)ex!hbt+ol|T6CTS+Sc0jv(& z7ijdvFwBq;0a{%3GGwkDKTeG`b+lyj0jjS1OMkYnepCdoosNY`*zmBIo*981BU%%U z@~$z0V`OVtIbEx5pa|Tct|Lg#ZQf5OYMUMRD>Wdxm5SAqV2}3!ceE-M2 z@O~lQ0OiKQp}o9I;?uxCgYVV?FH|?Riri*U$Zi_`V2eiA>l zdSm6;SEm6#T+SpcE8Ro_f2AwxzI z44hfe^WE3!h@W3RDyA_H440cpmYkv*)6m1XazTqw%=E5Xv7^@^^T7Q2wxr+Z2kVYr - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/macos/Runner/Configs/AppInfo.xcconfig b/ai_recipe_generation/macos/Runner/Configs/AppInfo.xcconfig deleted file mode 100644 index 63f79321d..000000000 --- a/ai_recipe_generation/macos/Runner/Configs/AppInfo.xcconfig +++ /dev/null @@ -1,14 +0,0 @@ -// Application-level settings for the Runner target. -// -// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the -// future. If not, the values below would default to using the project name when this becomes a -// 'flutter create' template. - -// The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = gemini_io_talk - -// The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk - -// The copyright displayed in application information -PRODUCT_COPYRIGHT = Copyright © 2024 com.example. All rights reserved. diff --git a/ai_recipe_generation/macos/Runner/Configs/Debug.xcconfig b/ai_recipe_generation/macos/Runner/Configs/Debug.xcconfig deleted file mode 100644 index 36b0fd946..000000000 --- a/ai_recipe_generation/macos/Runner/Configs/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Debug.xcconfig" -#include "Warnings.xcconfig" diff --git a/ai_recipe_generation/macos/Runner/Configs/Release.xcconfig b/ai_recipe_generation/macos/Runner/Configs/Release.xcconfig deleted file mode 100644 index dff4f4956..000000000 --- a/ai_recipe_generation/macos/Runner/Configs/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Release.xcconfig" -#include "Warnings.xcconfig" diff --git a/ai_recipe_generation/macos/Runner/Configs/Warnings.xcconfig b/ai_recipe_generation/macos/Runner/Configs/Warnings.xcconfig deleted file mode 100644 index 42bcbf478..000000000 --- a/ai_recipe_generation/macos/Runner/Configs/Warnings.xcconfig +++ /dev/null @@ -1,13 +0,0 @@ -WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings -GCC_WARN_UNDECLARED_SELECTOR = YES -CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES -CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE -CLANG_WARN__DUPLICATE_METHOD_MATCH = YES -CLANG_WARN_PRAGMA_PACK = YES -CLANG_WARN_STRICT_PROTOTYPES = YES -CLANG_WARN_COMMA = YES -GCC_WARN_STRICT_SELECTOR_MATCH = YES -CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES -CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES -GCC_WARN_SHADOW = YES -CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/ai_recipe_generation/macos/Runner/DebugProfile.entitlements b/ai_recipe_generation/macos/Runner/DebugProfile.entitlements deleted file mode 100644 index 58268b7ac..000000000 --- a/ai_recipe_generation/macos/Runner/DebugProfile.entitlements +++ /dev/null @@ -1,16 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.cs.allow-jit - - com.apple.security.network.server - - com.apple.security.files.user-selected.read-only - - com.apple.security.network.client - - - diff --git a/ai_recipe_generation/macos/Runner/GoogleService-Info.plist b/ai_recipe_generation/macos/Runner/GoogleService-Info.plist deleted file mode 100644 index 6f047004f..000000000 --- a/ai_recipe_generation/macos/Runner/GoogleService-Info.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - API_KEY - AIzaSyBNEtAHdjm3oFV6JZ6nbx5t6Pfyj4w4hbo - GCM_SENDER_ID - 44885228795 - PLIST_VERSION - 1 - BUNDLE_ID - com.example.geminiIoTalk.RunnerTests - PROJECT_ID - gemini-cat-chef - STORAGE_BUCKET - gemini-cat-chef.appspot.com - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:44885228795:ios:9585fdfdf50acdd18f845e - - \ No newline at end of file diff --git a/ai_recipe_generation/macos/Runner/Info.plist b/ai_recipe_generation/macos/Runner/Info.plist deleted file mode 100644 index 49ba8eb6a..000000000 --- a/ai_recipe_generation/macos/Runner/Info.plist +++ /dev/null @@ -1,36 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - $(PRODUCT_COPYRIGHT) - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - NSCameraUsageDescription - Explanation on why the camera access is needed. - NSMicrophoneUsageDescription - Explanation on why the microphone access is needed. - - diff --git a/ai_recipe_generation/macos/Runner/MainFlutterWindow.swift b/ai_recipe_generation/macos/Runner/MainFlutterWindow.swift deleted file mode 100644 index 3cc05eb23..000000000 --- a/ai_recipe_generation/macos/Runner/MainFlutterWindow.swift +++ /dev/null @@ -1,15 +0,0 @@ -import Cocoa -import FlutterMacOS - -class MainFlutterWindow: NSWindow { - override func awakeFromNib() { - let flutterViewController = FlutterViewController() - let windowFrame = self.frame - self.contentViewController = flutterViewController - self.setFrame(windowFrame, display: true) - - RegisterGeneratedPlugins(registry: flutterViewController) - - super.awakeFromNib() - } -} diff --git a/ai_recipe_generation/macos/Runner/Release.entitlements b/ai_recipe_generation/macos/Runner/Release.entitlements deleted file mode 100644 index b03a19487..000000000 --- a/ai_recipe_generation/macos/Runner/Release.entitlements +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.network.client - - - diff --git a/ai_recipe_generation/macos/RunnerTests/RunnerTests.swift b/ai_recipe_generation/macos/RunnerTests/RunnerTests.swift deleted file mode 100644 index 5418c9f53..000000000 --- a/ai_recipe_generation/macos/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import FlutterMacOS -import Cocoa -import XCTest - -class RunnerTests: XCTestCase { - - func testExample() { - // If you add code to the Runner application, consider adding tests here. - // See https://developer.apple.com/documentation/xctest for more information about using XCTest. - } - -} diff --git a/ai_recipe_generation/macos/firebase_app_id_file.json b/ai_recipe_generation/macos/firebase_app_id_file.json deleted file mode 100644 index a98a4b36f..000000000 --- a/ai_recipe_generation/macos/firebase_app_id_file.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "file_generated_by": "FlutterFire CLI", - "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", - "GOOGLE_APP_ID": "1:44885228795:ios:9585fdfdf50acdd18f845e", - "FIREBASE_PROJECT_ID": "gemini-cat-chef", - "GCM_SENDER_ID": "44885228795" -} \ No newline at end of file diff --git a/ai_recipe_generation/pubspec.yaml b/ai_recipe_generation/pubspec.yaml deleted file mode 100644 index c4d1cc4e0..000000000 --- a/ai_recipe_generation/pubspec.yaml +++ /dev/null @@ -1,40 +0,0 @@ -name: ai_recipe_generation -description: "A new Flutter project." -publish_to: 'none' -version: 0.1.0 - -environment: - sdk: ^3.5.0 - -dependencies: - async: ^2.11.0 - camera: ^0.10.5+9 - cloud_firestore: ^4.15.7 - device_info_plus: ^9.1.2 - firebase_core: ^2.26.0 - flutter: - sdk: flutter - flutter_floating_bottom_bar: ^1.2.0 - flutter_markdown: ^0.7.3 - flutter_svg: ^2.0.9 - google_fonts: 6.1.0 - google_generative_ai: ^0.4.0 - image_picker: ^1.0.7 - material_symbols_icons: ^4.2719.1 - path: ^1.9.0 - path_provider: ^2.1.2 - provider: ^6.1.1 - shared_preferences: ^2.2.2 - sticky_headers: ^0.3.0+2 - -dev_dependencies: - flutter_test: - sdk: flutter - analysis_defaults: - path: ../analysis_defaults - -flutter: - uses-material-design: true - - assets: - - assets/ diff --git a/ai_recipe_generation/web/favicon.png b/ai_recipe_generation/web/favicon.png deleted file mode 100644 index 8aaa46ac1ae21512746f852a42ba87e4165dfdd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM diff --git a/ai_recipe_generation/web/icons/Icon-192.png b/ai_recipe_generation/web/icons/Icon-192.png deleted file mode 100644 index b749bfef07473333cf1dd31e9eed89862a5d52aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5292 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 diff --git a/ai_recipe_generation/web/icons/Icon-512.png b/ai_recipe_generation/web/icons/Icon-512.png deleted file mode 100644 index 88cfd48dff1169879ba46840804b412fe02fefd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8252 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 diff --git a/ai_recipe_generation/web/icons/Icon-maskable-192.png b/ai_recipe_generation/web/icons/Icon-maskable-192.png deleted file mode 100644 index eb9b4d76e525556d5d89141648c724331630325d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5594 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 X>c!)3PgKfL&lX^$Z>Cpu&6)6jvi^Z! diff --git a/ai_recipe_generation/web/icons/Icon-maskable-512.png b/ai_recipe_generation/web/icons/Icon-maskable-512.png deleted file mode 100644 index d69c56691fbdb0b7efa65097c7cc1edac12a6d3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20998 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 MPgg&ebxsLQ025IeI{*Lx diff --git a/ai_recipe_generation/web/index.html b/ai_recipe_generation/web/index.html deleted file mode 100644 index 52540c77e..000000000 --- a/ai_recipe_generation/web/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - gemini_io_talk - - - - - - diff --git a/ai_recipe_generation/web/manifest.json b/ai_recipe_generation/web/manifest.json deleted file mode 100644 index 5ac7cda4b..000000000 --- a/ai_recipe_generation/web/manifest.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "gemini_io_talk", - "short_name": "gemini_io_talk", - "start_url": ".", - "display": "standalone", - "background_color": "#0175C2", - "theme_color": "#0175C2", - "description": "A new Flutter project.", - "orientation": "portrait-primary", - "prefer_related_applications": false, - "icons": [ - { - "src": "icons/Icon-192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "icons/Icon-512.png", - "sizes": "512x512", - "type": "image/png" - }, - { - "src": "icons/Icon-maskable-192.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "icons/Icon-maskable-512.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "maskable" - } - ] -} diff --git a/ai_recipe_generation/windows/.gitignore b/ai_recipe_generation/windows/.gitignore deleted file mode 100644 index d492d0d98..000000000 --- a/ai_recipe_generation/windows/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -flutter/ephemeral/ - -# Visual Studio user-specific files. -*.suo -*.user -*.userosscache -*.sln.docstates - -# Visual Studio build-related files. -x64/ -x86/ - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ diff --git a/ai_recipe_generation/windows/CMakeLists.txt b/ai_recipe_generation/windows/CMakeLists.txt deleted file mode 100644 index 28eca8f13..000000000 --- a/ai_recipe_generation/windows/CMakeLists.txt +++ /dev/null @@ -1,108 +0,0 @@ -# Project-level configuration. -cmake_minimum_required(VERSION 3.14) -project(gemini_io_talk LANGUAGES CXX) - -# The name of the executable created for the application. Change this to change -# the on-disk name of your application. -set(BINARY_NAME "gemini_io_talk") - -# Explicitly opt in to modern CMake behaviors to avoid warnings with recent -# versions of CMake. -cmake_policy(VERSION 3.14...3.25) - -# Define build configuration option. -get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) -if(IS_MULTICONFIG) - set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" - CACHE STRING "" FORCE) -else() - if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") - endif() -endif() -# Define settings for the Profile build mode. -set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") -set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") -set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") -set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") - -# Use Unicode for all projects. -add_definitions(-DUNICODE -D_UNICODE) - -# Compilation settings that should be applied to most targets. -# -# Be cautious about adding new options here, as plugins use this function by -# default. In most cases, you should add new options to specific targets instead -# of modifying this function. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_17) - target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") - target_compile_options(${TARGET} PRIVATE /EHsc) - target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") - target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") -endfunction() - -# Flutter library and tool build rules. -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# Application build; see runner/CMakeLists.txt. -add_subdirectory("runner") - - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - - -# === Installation === -# Support files are copied into place next to the executable, so that it can -# run in place. This is done instead of making a separate bundle (as on Linux) -# so that building and running from within Visual Studio will work. -set(BUILD_BUNDLE_DIR "$") -# Make the "install" step default, as it's required to run. -set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -if(PLUGIN_BUNDLED_LIBRARIES) - install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() - -# Copy the native assets provided by the build.dart from all packages. -set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") -install(DIRECTORY "${NATIVE_ASSETS_DIR}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - CONFIGURATIONS Profile;Release - COMPONENT Runtime) diff --git a/ai_recipe_generation/windows/flutter/CMakeLists.txt b/ai_recipe_generation/windows/flutter/CMakeLists.txt deleted file mode 100644 index 903f4899d..000000000 --- a/ai_recipe_generation/windows/flutter/CMakeLists.txt +++ /dev/null @@ -1,109 +0,0 @@ -# This file controls Flutter-level build steps. It should not be edited. -cmake_minimum_required(VERSION 3.14) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. -set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") - -# Set fallback configurations for older versions of the flutter tool. -if (NOT DEFINED FLUTTER_TARGET_PLATFORM) - set(FLUTTER_TARGET_PLATFORM "windows-x64") -endif() - -# === Flutter Library === -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "flutter_export.h" - "flutter_windows.h" - "flutter_messenger.h" - "flutter_plugin_registrar.h" - "flutter_texture_registrar.h" -) -list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") -add_dependencies(flutter flutter_assemble) - -# === Wrapper === -list(APPEND CPP_WRAPPER_SOURCES_CORE - "core_implementations.cc" - "standard_codec.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_PLUGIN - "plugin_registrar.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_APP - "flutter_engine.cc" - "flutter_view_controller.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") - -# Wrapper sources needed for a plugin. -add_library(flutter_wrapper_plugin STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} -) -apply_standard_settings(flutter_wrapper_plugin) -set_target_properties(flutter_wrapper_plugin PROPERTIES - POSITION_INDEPENDENT_CODE ON) -set_target_properties(flutter_wrapper_plugin PROPERTIES - CXX_VISIBILITY_PRESET hidden) -target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) -target_include_directories(flutter_wrapper_plugin PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_plugin flutter_assemble) - -# Wrapper sources needed for the runner. -add_library(flutter_wrapper_app STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_APP} -) -apply_standard_settings(flutter_wrapper_app) -target_link_libraries(flutter_wrapper_app PUBLIC flutter) -target_include_directories(flutter_wrapper_app PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_app flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") -set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} - ${PHONY_OUTPUT} - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" - ${FLUTTER_TARGET_PLATFORM} $ - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} -) diff --git a/ai_recipe_generation/windows/flutter/generated_plugin_registrant.cc b/ai_recipe_generation/windows/flutter/generated_plugin_registrant.cc deleted file mode 100644 index ffc1b3875..000000000 --- a/ai_recipe_generation/windows/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,20 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include -#include -#include - -void RegisterPlugins(flutter::PluginRegistry* registry) { - CloudFirestorePluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("CloudFirestorePluginCApi")); - FileSelectorWindowsRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FileSelectorWindows")); - FirebaseCorePluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); -} diff --git a/ai_recipe_generation/windows/flutter/generated_plugin_registrant.h b/ai_recipe_generation/windows/flutter/generated_plugin_registrant.h deleted file mode 100644 index dc139d85a..000000000 --- a/ai_recipe_generation/windows/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void RegisterPlugins(flutter::PluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/ai_recipe_generation/windows/flutter/generated_plugins.cmake b/ai_recipe_generation/windows/flutter/generated_plugins.cmake deleted file mode 100644 index 3cd460216..000000000 --- a/ai_recipe_generation/windows/flutter/generated_plugins.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - cloud_firestore - file_selector_windows - firebase_core -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/ai_recipe_generation/windows/runner/CMakeLists.txt b/ai_recipe_generation/windows/runner/CMakeLists.txt deleted file mode 100644 index 394917c05..000000000 --- a/ai_recipe_generation/windows/runner/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(runner LANGUAGES CXX) - -# Define the application target. To change its name, change BINARY_NAME in the -# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer -# work. -# -# Any new source files that you add to the application should be added here. -add_executable(${BINARY_NAME} WIN32 - "flutter_window.cpp" - "main.cpp" - "utils.cpp" - "win32_window.cpp" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" - "Runner.rc" - "runner.exe.manifest" -) - -# Apply the standard set of build settings. This can be removed for applications -# that need different build settings. -apply_standard_settings(${BINARY_NAME}) - -# Add preprocessor definitions for the build version. -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") - -# Disable Windows macros that collide with C++ standard library functions. -target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") - -# Add dependency libraries and include directories. Add any application-specific -# dependencies here. -target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) -target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") -target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") - -# Run the Flutter tool portions of the build. This must not be removed. -add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/ai_recipe_generation/windows/runner/Runner.rc b/ai_recipe_generation/windows/runner/Runner.rc deleted file mode 100644 index 5458ca734..000000000 --- a/ai_recipe_generation/windows/runner/Runner.rc +++ /dev/null @@ -1,121 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#pragma code_page(65001) -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_APP_ICON ICON "resources\\app_icon.ico" - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) -#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD -#else -#define VERSION_AS_NUMBER 1,0,0,0 -#endif - -#if defined(FLUTTER_VERSION) -#define VERSION_AS_STRING FLUTTER_VERSION -#else -#define VERSION_AS_STRING "1.0.0" -#endif - -VS_VERSION_INFO VERSIONINFO - FILEVERSION VERSION_AS_NUMBER - PRODUCTVERSION VERSION_AS_NUMBER - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_APP - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "CompanyName", "com.example" "\0" - VALUE "FileDescription", "gemini_io_talk" "\0" - VALUE "FileVersion", VERSION_AS_STRING "\0" - VALUE "InternalName", "gemini_io_talk" "\0" - VALUE "LegalCopyright", "Copyright (C) 2024 com.example. All rights reserved." "\0" - VALUE "OriginalFilename", "gemini_io_talk.exe" "\0" - VALUE "ProductName", "gemini_io_talk" "\0" - VALUE "ProductVersion", VERSION_AS_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED diff --git a/ai_recipe_generation/windows/runner/flutter_window.cpp b/ai_recipe_generation/windows/runner/flutter_window.cpp deleted file mode 100644 index 955ee3038..000000000 --- a/ai_recipe_generation/windows/runner/flutter_window.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "flutter_window.h" - -#include - -#include "flutter/generated_plugin_registrant.h" - -FlutterWindow::FlutterWindow(const flutter::DartProject& project) - : project_(project) {} - -FlutterWindow::~FlutterWindow() {} - -bool FlutterWindow::OnCreate() { - if (!Win32Window::OnCreate()) { - return false; - } - - RECT frame = GetClientArea(); - - // The size here must match the window dimensions to avoid unnecessary surface - // creation / destruction in the startup path. - flutter_controller_ = std::make_unique( - frame.right - frame.left, frame.bottom - frame.top, project_); - // Ensure that basic setup of the controller was successful. - if (!flutter_controller_->engine() || !flutter_controller_->view()) { - return false; - } - RegisterPlugins(flutter_controller_->engine()); - SetChildContent(flutter_controller_->view()->GetNativeWindow()); - - flutter_controller_->engine()->SetNextFrameCallback([&]() { - this->Show(); - }); - - // Flutter can complete the first frame before the "show window" callback is - // registered. The following call ensures a frame is pending to ensure the - // window is shown. It is a no-op if the first frame hasn't completed yet. - flutter_controller_->ForceRedraw(); - - return true; -} - -void FlutterWindow::OnDestroy() { - if (flutter_controller_) { - flutter_controller_ = nullptr; - } - - Win32Window::OnDestroy(); -} - -LRESULT -FlutterWindow::MessageHandler(HWND hwnd, UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - // Give Flutter, including plugins, an opportunity to handle window messages. - if (flutter_controller_) { - std::optional result = - flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, - lparam); - if (result) { - return *result; - } - } - - switch (message) { - case WM_FONTCHANGE: - flutter_controller_->engine()->ReloadSystemFonts(); - break; - } - - return Win32Window::MessageHandler(hwnd, message, wparam, lparam); -} diff --git a/ai_recipe_generation/windows/runner/flutter_window.h b/ai_recipe_generation/windows/runner/flutter_window.h deleted file mode 100644 index 6da0652f0..000000000 --- a/ai_recipe_generation/windows/runner/flutter_window.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef RUNNER_FLUTTER_WINDOW_H_ -#define RUNNER_FLUTTER_WINDOW_H_ - -#include -#include - -#include - -#include "win32_window.h" - -// A window that does nothing but host a Flutter view. -class FlutterWindow : public Win32Window { - public: - // Creates a new FlutterWindow hosting a Flutter view running |project|. - explicit FlutterWindow(const flutter::DartProject& project); - virtual ~FlutterWindow(); - - protected: - // Win32Window: - bool OnCreate() override; - void OnDestroy() override; - LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, - LPARAM const lparam) noexcept override; - - private: - // The project to run. - flutter::DartProject project_; - - // The Flutter instance hosted by this window. - std::unique_ptr flutter_controller_; -}; - -#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/ai_recipe_generation/windows/runner/main.cpp b/ai_recipe_generation/windows/runner/main.cpp deleted file mode 100644 index 2d644bc14..000000000 --- a/ai_recipe_generation/windows/runner/main.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -#include "flutter_window.h" -#include "utils.h" - -int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, - _In_ wchar_t *command_line, _In_ int show_command) { - // Attach to console when present (e.g., 'flutter run') or create a - // new console when running with a debugger. - if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { - CreateAndAttachConsole(); - } - - // Initialize COM, so that it is available for use in the library and/or - // plugins. - ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); - - flutter::DartProject project(L"data"); - - std::vector command_line_arguments = - GetCommandLineArguments(); - - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - FlutterWindow window(project); - Win32Window::Point origin(10, 10); - Win32Window::Size size(1280, 720); - if (!window.Create(L"gemini_io_talk", origin, size)) { - return EXIT_FAILURE; - } - window.SetQuitOnClose(true); - - ::MSG msg; - while (::GetMessage(&msg, nullptr, 0, 0)) { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - - ::CoUninitialize(); - return EXIT_SUCCESS; -} diff --git a/ai_recipe_generation/windows/runner/resource.h b/ai_recipe_generation/windows/runner/resource.h deleted file mode 100644 index 66a65d1e4..000000000 --- a/ai_recipe_generation/windows/runner/resource.h +++ /dev/null @@ -1,16 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Runner.rc -// -#define IDI_APP_ICON 101 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/ai_recipe_generation/windows/runner/resources/app_icon.ico b/ai_recipe_generation/windows/runner/resources/app_icon.ico deleted file mode 100644 index c04e20caf6370ebb9253ad831cc31de4a9c965f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33772 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 diff --git a/ai_recipe_generation/windows/runner/runner.exe.manifest b/ai_recipe_generation/windows/runner/runner.exe.manifest deleted file mode 100644 index a42ea7687..000000000 --- a/ai_recipe_generation/windows/runner/runner.exe.manifest +++ /dev/null @@ -1,20 +0,0 @@ - - - - - PerMonitorV2 - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/windows/runner/utils.cpp b/ai_recipe_generation/windows/runner/utils.cpp deleted file mode 100644 index b2b08734d..000000000 --- a/ai_recipe_generation/windows/runner/utils.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "utils.h" - -#include -#include -#include -#include - -#include - -void CreateAndAttachConsole() { - if (::AllocConsole()) { - FILE *unused; - if (freopen_s(&unused, "CONOUT$", "w", stdout)) { - _dup2(_fileno(stdout), 1); - } - if (freopen_s(&unused, "CONOUT$", "w", stderr)) { - _dup2(_fileno(stdout), 2); - } - std::ios::sync_with_stdio(); - FlutterDesktopResyncOutputStreams(); - } -} - -std::vector GetCommandLineArguments() { - // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. - int argc; - wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); - if (argv == nullptr) { - return std::vector(); - } - - std::vector command_line_arguments; - - // Skip the first argument as it's the binary name. - for (int i = 1; i < argc; i++) { - command_line_arguments.push_back(Utf8FromUtf16(argv[i])); - } - - ::LocalFree(argv); - - return command_line_arguments; -} - -std::string Utf8FromUtf16(const wchar_t* utf16_string) { - if (utf16_string == nullptr) { - return std::string(); - } - int target_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - -1, nullptr, 0, nullptr, nullptr) - -1; // remove the trailing null character - int input_length = (int)wcslen(utf16_string); - std::string utf8_string; - if (target_length <= 0 || target_length > utf8_string.max_size()) { - return utf8_string; - } - utf8_string.resize(target_length); - int converted_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - input_length, utf8_string.data(), target_length, nullptr, nullptr); - if (converted_length == 0) { - return std::string(); - } - return utf8_string; -} diff --git a/ai_recipe_generation/windows/runner/utils.h b/ai_recipe_generation/windows/runner/utils.h deleted file mode 100644 index 3879d5475..000000000 --- a/ai_recipe_generation/windows/runner/utils.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef RUNNER_UTILS_H_ -#define RUNNER_UTILS_H_ - -#include -#include - -// Creates a console for the process, and redirects stdout and stderr to -// it for both the runner and the Flutter library. -void CreateAndAttachConsole(); - -// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string -// encoded in UTF-8. Returns an empty std::string on failure. -std::string Utf8FromUtf16(const wchar_t* utf16_string); - -// Gets the command line arguments passed in as a std::vector, -// encoded in UTF-8. Returns an empty std::vector on failure. -std::vector GetCommandLineArguments(); - -#endif // RUNNER_UTILS_H_ diff --git a/ai_recipe_generation/windows/runner/win32_window.cpp b/ai_recipe_generation/windows/runner/win32_window.cpp deleted file mode 100644 index 60608d0fe..000000000 --- a/ai_recipe_generation/windows/runner/win32_window.cpp +++ /dev/null @@ -1,288 +0,0 @@ -#include "win32_window.h" - -#include -#include - -#include "resource.h" - -namespace { - -/// Window attribute that enables dark mode window decorations. -/// -/// Redefined in case the developer's machine has a Windows SDK older than -/// version 10.0.22000.0. -/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute -#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE -#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 -#endif - -constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; - -/// Registry key for app theme preference. -/// -/// A value of 0 indicates apps should use dark mode. A non-zero or missing -/// value indicates apps should use light mode. -constexpr const wchar_t kGetPreferredBrightnessRegKey[] = - L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; -constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; - -// The number of Win32Window objects that currently exist. -static int g_active_window_count = 0; - -using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); - -// Scale helper to convert logical scaler values to physical using passed in -// scale factor -int Scale(int source, double scale_factor) { - return static_cast(source * scale_factor); -} - -// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. -// This API is only needed for PerMonitor V1 awareness mode. -void EnableFullDpiSupportIfAvailable(HWND hwnd) { - HMODULE user32_module = LoadLibraryA("User32.dll"); - if (!user32_module) { - return; - } - auto enable_non_client_dpi_scaling = - reinterpret_cast( - GetProcAddress(user32_module, "EnableNonClientDpiScaling")); - if (enable_non_client_dpi_scaling != nullptr) { - enable_non_client_dpi_scaling(hwnd); - } - FreeLibrary(user32_module); -} - -} // namespace - -// Manages the Win32Window's window class registration. -class WindowClassRegistrar { - public: - ~WindowClassRegistrar() = default; - - // Returns the singleton registrar instance. - static WindowClassRegistrar* GetInstance() { - if (!instance_) { - instance_ = new WindowClassRegistrar(); - } - return instance_; - } - - // Returns the name of the window class, registering the class if it hasn't - // previously been registered. - const wchar_t* GetWindowClass(); - - // Unregisters the window class. Should only be called if there are no - // instances of the window. - void UnregisterWindowClass(); - - private: - WindowClassRegistrar() = default; - - static WindowClassRegistrar* instance_; - - bool class_registered_ = false; -}; - -WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; - -const wchar_t* WindowClassRegistrar::GetWindowClass() { - if (!class_registered_) { - WNDCLASS window_class{}; - window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); - window_class.lpszClassName = kWindowClassName; - window_class.style = CS_HREDRAW | CS_VREDRAW; - window_class.cbClsExtra = 0; - window_class.cbWndExtra = 0; - window_class.hInstance = GetModuleHandle(nullptr); - window_class.hIcon = - LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); - window_class.hbrBackground = 0; - window_class.lpszMenuName = nullptr; - window_class.lpfnWndProc = Win32Window::WndProc; - RegisterClass(&window_class); - class_registered_ = true; - } - return kWindowClassName; -} - -void WindowClassRegistrar::UnregisterWindowClass() { - UnregisterClass(kWindowClassName, nullptr); - class_registered_ = false; -} - -Win32Window::Win32Window() { - ++g_active_window_count; -} - -Win32Window::~Win32Window() { - --g_active_window_count; - Destroy(); -} - -bool Win32Window::Create(const std::wstring& title, - const Point& origin, - const Size& size) { - Destroy(); - - const wchar_t* window_class = - WindowClassRegistrar::GetInstance()->GetWindowClass(); - - const POINT target_point = {static_cast(origin.x), - static_cast(origin.y)}; - HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); - UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); - double scale_factor = dpi / 96.0; - - HWND window = CreateWindow( - window_class, title.c_str(), WS_OVERLAPPEDWINDOW, - Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), - Scale(size.width, scale_factor), Scale(size.height, scale_factor), - nullptr, nullptr, GetModuleHandle(nullptr), this); - - if (!window) { - return false; - } - - UpdateTheme(window); - - return OnCreate(); -} - -bool Win32Window::Show() { - return ShowWindow(window_handle_, SW_SHOWNORMAL); -} - -// static -LRESULT CALLBACK Win32Window::WndProc(HWND const window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - if (message == WM_NCCREATE) { - auto window_struct = reinterpret_cast(lparam); - SetWindowLongPtr(window, GWLP_USERDATA, - reinterpret_cast(window_struct->lpCreateParams)); - - auto that = static_cast(window_struct->lpCreateParams); - EnableFullDpiSupportIfAvailable(window); - that->window_handle_ = window; - } else if (Win32Window* that = GetThisFromHandle(window)) { - return that->MessageHandler(window, message, wparam, lparam); - } - - return DefWindowProc(window, message, wparam, lparam); -} - -LRESULT -Win32Window::MessageHandler(HWND hwnd, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - switch (message) { - case WM_DESTROY: - window_handle_ = nullptr; - Destroy(); - if (quit_on_close_) { - PostQuitMessage(0); - } - return 0; - - case WM_DPICHANGED: { - auto newRectSize = reinterpret_cast(lparam); - LONG newWidth = newRectSize->right - newRectSize->left; - LONG newHeight = newRectSize->bottom - newRectSize->top; - - SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, - newHeight, SWP_NOZORDER | SWP_NOACTIVATE); - - return 0; - } - case WM_SIZE: { - RECT rect = GetClientArea(); - if (child_content_ != nullptr) { - // Size and position the child window. - MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, - rect.bottom - rect.top, TRUE); - } - return 0; - } - - case WM_ACTIVATE: - if (child_content_ != nullptr) { - SetFocus(child_content_); - } - return 0; - - case WM_DWMCOLORIZATIONCOLORCHANGED: - UpdateTheme(hwnd); - return 0; - } - - return DefWindowProc(window_handle_, message, wparam, lparam); -} - -void Win32Window::Destroy() { - OnDestroy(); - - if (window_handle_) { - DestroyWindow(window_handle_); - window_handle_ = nullptr; - } - if (g_active_window_count == 0) { - WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); - } -} - -Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { - return reinterpret_cast( - GetWindowLongPtr(window, GWLP_USERDATA)); -} - -void Win32Window::SetChildContent(HWND content) { - child_content_ = content; - SetParent(content, window_handle_); - RECT frame = GetClientArea(); - - MoveWindow(content, frame.left, frame.top, frame.right - frame.left, - frame.bottom - frame.top, true); - - SetFocus(child_content_); -} - -RECT Win32Window::GetClientArea() { - RECT frame; - GetClientRect(window_handle_, &frame); - return frame; -} - -HWND Win32Window::GetHandle() { - return window_handle_; -} - -void Win32Window::SetQuitOnClose(bool quit_on_close) { - quit_on_close_ = quit_on_close; -} - -bool Win32Window::OnCreate() { - // No-op; provided for subclasses. - return true; -} - -void Win32Window::OnDestroy() { - // No-op; provided for subclasses. -} - -void Win32Window::UpdateTheme(HWND const window) { - DWORD light_mode; - DWORD light_mode_size = sizeof(light_mode); - LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, - kGetPreferredBrightnessRegValue, - RRF_RT_REG_DWORD, nullptr, &light_mode, - &light_mode_size); - - if (result == ERROR_SUCCESS) { - BOOL enable_dark_mode = light_mode == 0; - DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, - &enable_dark_mode, sizeof(enable_dark_mode)); - } -} diff --git a/ai_recipe_generation/windows/runner/win32_window.h b/ai_recipe_generation/windows/runner/win32_window.h deleted file mode 100644 index e901dde68..000000000 --- a/ai_recipe_generation/windows/runner/win32_window.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef RUNNER_WIN32_WINDOW_H_ -#define RUNNER_WIN32_WINDOW_H_ - -#include - -#include -#include -#include - -// A class abstraction for a high DPI-aware Win32 Window. Intended to be -// inherited from by classes that wish to specialize with custom -// rendering and input handling -class Win32Window { - public: - struct Point { - unsigned int x; - unsigned int y; - Point(unsigned int x, unsigned int y) : x(x), y(y) {} - }; - - struct Size { - unsigned int width; - unsigned int height; - Size(unsigned int width, unsigned int height) - : width(width), height(height) {} - }; - - Win32Window(); - virtual ~Win32Window(); - - // Creates a win32 window with |title| that is positioned and sized using - // |origin| and |size|. New windows are created on the default monitor. Window - // sizes are specified to the OS in physical pixels, hence to ensure a - // consistent size this function will scale the inputted width and height as - // as appropriate for the default monitor. The window is invisible until - // |Show| is called. Returns true if the window was created successfully. - bool Create(const std::wstring& title, const Point& origin, const Size& size); - - // Show the current window. Returns true if the window was successfully shown. - bool Show(); - - // Release OS resources associated with window. - void Destroy(); - - // Inserts |content| into the window tree. - void SetChildContent(HWND content); - - // Returns the backing Window handle to enable clients to set icon and other - // window properties. Returns nullptr if the window has been destroyed. - HWND GetHandle(); - - // If true, closing this window will quit the application. - void SetQuitOnClose(bool quit_on_close); - - // Return a RECT representing the bounds of the current client area. - RECT GetClientArea(); - - protected: - // Processes and route salient window messages for mouse handling, - // size change and DPI. Delegates handling of these to member overloads that - // inheriting classes can handle. - virtual LRESULT MessageHandler(HWND window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Called when CreateAndShow is called, allowing subclass window-related - // setup. Subclasses should return false if setup fails. - virtual bool OnCreate(); - - // Called when Destroy is called. - virtual void OnDestroy(); - - private: - friend class WindowClassRegistrar; - - // OS callback called by message pump. Handles the WM_NCCREATE message which - // is passed when the non-client area is being created and enables automatic - // non-client DPI scaling so that the non-client area automatically - // responds to changes in DPI. All other messages are handled by - // MessageHandler. - static LRESULT CALLBACK WndProc(HWND const window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Retrieves a class instance pointer for |window| - static Win32Window* GetThisFromHandle(HWND const window) noexcept; - - // Update the window frame's theme to match the system theme. - static void UpdateTheme(HWND const window); - - bool quit_on_close_ = false; - - // window handle for top level window. - HWND window_handle_ = nullptr; - - // window handle for hosted content. - HWND child_content_ = nullptr; -}; - -#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/tool/flutter_ci_script_beta.sh b/tool/flutter_ci_script_beta.sh index c314cdd88..a1a43fe3c 100755 --- a/tool/flutter_ci_script_beta.sh +++ b/tool/flutter_ci_script_beta.sh @@ -14,7 +14,6 @@ declare -ar PROJECT_NAMES=( "add_to_app/multiple_flutters/multiple_flutters_module" "add_to_app/plugin/flutter_module_using_plugin" "add_to_app/prebuilt_module/flutter_module" - "ai_recipe_generation" "analysis_defaults" "android_splash_screen" "animations" diff --git a/tool/flutter_ci_script_master.sh b/tool/flutter_ci_script_master.sh index 7abc49091..a3e0243e1 100755 --- a/tool/flutter_ci_script_master.sh +++ b/tool/flutter_ci_script_master.sh @@ -14,7 +14,6 @@ declare -ar PROJECT_NAMES=( "add_to_app/multiple_flutters/multiple_flutters_module" "add_to_app/plugin/flutter_module_using_plugin" "add_to_app/prebuilt_module/flutter_module" - "ai_recipe_generation" "analysis_defaults" "android_splash_screen" "animations" diff --git a/tool/flutter_ci_script_stable.sh b/tool/flutter_ci_script_stable.sh index b1171a4d4..ee14b2b49 100755 --- a/tool/flutter_ci_script_stable.sh +++ b/tool/flutter_ci_script_stable.sh @@ -14,7 +14,6 @@ declare -ar PROJECT_NAMES=( "add_to_app/multiple_flutters/multiple_flutters_module" "add_to_app/plugin/flutter_module_using_plugin" "add_to_app/prebuilt_module/flutter_module" - "ai_recipe_generation" "analysis_defaults" "android_splash_screen" "animations" From 07b0156299393676ae0247ef53573d182a86b28d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 06:59:47 +0000 Subject: [PATCH 07/30] Bump subosito/flutter-action from 2.16.0 to 2.17.0 (#2491) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [subosito/flutter-action](https://github.com/subosito/flutter-action) from 2.16.0 to 2.17.0.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=subosito/flutter-action&package-manager=github_actions&previous-version=2.16.0&new-version=2.17.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .github/workflows/beta.yml | 6 +++--- .github/workflows/gh-pages.yml | 2 +- .github/workflows/main.yml | 8 ++++---- .github/workflows/verify-web-demos.yml | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml index b42e880fd..1352a3b5d 100644 --- a/.github/workflows/beta.yml +++ b/.github/workflows/beta.yml @@ -31,7 +31,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 with: channel: beta - run: ./tool/flutter_ci_script_stable.sh @@ -47,7 +47,7 @@ jobs: # with: # distribution: 'zulu' # java-version: '17' - # - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + # - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 # with: # channel: beta # - run: ./tool/android_ci_script.sh @@ -63,7 +63,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 with: channel: beta - run: ./tool/ios_ci_script.sh diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index eaa28cec1..8f98c7a74 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -21,7 +21,7 @@ jobs: submodules: true fetch-depth: 0 - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 - name: Init scripts run: dart pub get diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f87b47949..b0ce27019 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,7 +32,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 with: channel: ${{ matrix.flutter_version }} - run: ./tool/flutter_ci_script_${{ matrix.flutter_version }}.sh @@ -42,7 +42,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 - run: | dart pub get dart run grinder generate @@ -57,7 +57,7 @@ jobs: # with: # distribution: 'zulu' # java-version: '17' - # - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + # - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 # with: # channel: stable # - run: ./tool/android_ci_script.sh @@ -71,7 +71,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 with: channel: stable - run: ./tool/ios_ci_script.sh diff --git a/.github/workflows/verify-web-demos.yml b/.github/workflows/verify-web-demos.yml index 3d579e468..0a11de3a3 100644 --- a/.github/workflows/verify-web-demos.yml +++ b/.github/workflows/verify-web-demos.yml @@ -25,7 +25,7 @@ jobs: with: submodules: true fetch-depth: 0 - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 with: channel: ${{ matrix.flutter_version }} - name: Init scripts From 10b21a4567fe657898d41cc89ac9ff06f0710742 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 07:17:10 +0000 Subject: [PATCH 08/30] Bump @angular/animations from 18.2.12 to 19.0.0 in /web_embedding/ng-flutter (#2495) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@angular/animations](https://github.com/angular/angular/tree/HEAD/packages/animations) from 18.2.12 to 19.0.0.
Release notes

Sourced from @​angular/animations's releases.

v19.0.0

19.0.0 (2024-11-19)

Explore Angular v19 with a blog post from the Angular team: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Breaking Changes

compiler

  • this.foo property reads no longer refer to template context variables. If you intended to read the template variable, do not use this..

core

  • Angular directives, components and pipes are now standalone by default.

    • Specify standalone: false for declarations that are currently declared in @NgModules.
    • ng update for v19 will take care of this automatically.
  • TypeScript versions less than 5.5 are no longer supported.

  • Timing changes for effect API (in developer preview):

    • effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the specifics of application/test setup, this can result in them executing earlier or later (or requiring additional test steps to trigger; see below examples).

    • effects which are triggered during change detection (e.g. by input signals) run earlier, before the component's template.

  • ExperimentalPendingTasks has been renamed to PendingTasks.

  • The autoDetect feature of ComponentFixture will now attach the fixture to the ApplicationRef. As a result, errors during automatic change detection of the fixture be reported to the ErrorHandler. This change may cause custom error handlers to observe new failures that were previously unreported.

  • createComponent will now render default fallback with empty projectableNodes.

    • When passing an empty array to projectableNodes in the createComponent API, the default fallback content of the ng-content will be rendered if present. To prevent rendering the default content, pass document.createTextNode('') as a projectableNode.
    // The first ng-content will render the default fallback content if present
    createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });
    

    // To prevent projecting the default fallback content: createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });

  • Errors that are thrown during ApplicationRef.tick will now be rethrown when using TestBed. These errors should be resolved by ensuring the test environment is set up correctly to complete change detection successfully. There are two alternatives to catch the errors:

    • Instead of waiting for automatic change detection to happen, trigger

... (truncated)

Changelog

Sourced from @​angular/animations's changelog.

19.0.0 (2024-11-19)

Blog post: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Breaking Changes

compiler

  • this.foo property reads no longer refer to template context variables. If you intended to read the template variable, do not use this..

core

  • Angular directives, components and pipes are now standalone by default.

    • Specify standalone: false for declarations that are currently declared in @NgModules.
    • ng update for v19 will take care of this automatically.
  • TypeScript versions less than 5.5 are no longer supported.

  • Timing changes for effect API (in developer preview):

    • effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the specifics of application/test setup, this can result in them executing earlier or later (or requiring additional test steps to trigger; see below examples).

    • effects which are triggered during change detection (e.g. by input signals) run earlier, before the component's template.

  • ExperimentalPendingTasks has been renamed to PendingTasks.

  • The autoDetect feature of ComponentFixture will now attach the fixture to the ApplicationRef. As a result, errors during automatic change detection of the fixture be reported to the ErrorHandler. This change may cause custom error handlers to observe new failures that were previously unreported.

  • createComponent will now render default fallback with empty projectableNodes.

    • When passing an empty array to projectableNodes in the createComponent API, the default fallback content of the ng-content will be rendered if present. To prevent rendering the default content, pass document.createTextNode('') as a projectableNode.
    // The first ng-content will render the default fallback content if present
    createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });
    

    // To prevent projecting the default fallback content: createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });

  • Errors that are thrown during ApplicationRef.tick will now be rethrown when using TestBed. These errors should be resolved by ensuring the test environment is set up correctly to complete change detection successfully. There are two alternatives to catch the errors:

    • Instead of waiting for automatic change detection to happen, trigger it synchronously and expect the error. For example, a jasmine test could write expect(() => TestBed.inject(ApplicationRef).tick()).toThrow()

... (truncated)

Commits
  • 09df589 refactor(core): Migrate all packages with the explicit-standalone-flag sche...
  • 84b6896 refactor(platform-server): Add an ssr benchmark setup. (#57647)
  • 9dbe6fc refactor: update license text to point to angular.dev (#57901)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/animations&package-manager=npm_and_yarn&previous-version=18.2.12&new-version=19.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index eaf1aff5b..5d7f9c937 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -11,7 +11,7 @@ }, "private": true, "dependencies": { - "@angular/animations": "^18.0.1", + "@angular/animations": "^19.0.0", "@angular/cdk": "^18.0.1", "@angular/common": "^18.0.1", "@angular/compiler": "^18.0.1", From 75335564596333994aa115b19c8aa440915fa605 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 07:19:40 +0000 Subject: [PATCH 09/30] Bump @angular/platform-browser-dynamic from 18.2.12 to 19.0.0 in /web_embedding/ng-flutter (#2492) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@angular/platform-browser-dynamic](https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic) from 18.2.12 to 19.0.0.
Release notes

Sourced from @​angular/platform-browser-dynamic's releases.

v19.0.0

19.0.0 (2024-11-19)

Explore Angular v19 with a blog post from the Angular team: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Breaking Changes

compiler

  • this.foo property reads no longer refer to template context variables. If you intended to read the template variable, do not use this..

core

  • Angular directives, components and pipes are now standalone by default.

    • Specify standalone: false for declarations that are currently declared in @NgModules.
    • ng update for v19 will take care of this automatically.
  • TypeScript versions less than 5.5 are no longer supported.

  • Timing changes for effect API (in developer preview):

    • effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the specifics of application/test setup, this can result in them executing earlier or later (or requiring additional test steps to trigger; see below examples).

    • effects which are triggered during change detection (e.g. by input signals) run earlier, before the component's template.

  • ExperimentalPendingTasks has been renamed to PendingTasks.

  • The autoDetect feature of ComponentFixture will now attach the fixture to the ApplicationRef. As a result, errors during automatic change detection of the fixture be reported to the ErrorHandler. This change may cause custom error handlers to observe new failures that were previously unreported.

  • createComponent will now render default fallback with empty projectableNodes.

    • When passing an empty array to projectableNodes in the createComponent API, the default fallback content of the ng-content will be rendered if present. To prevent rendering the default content, pass document.createTextNode('') as a projectableNode.
    // The first ng-content will render the default fallback content if present
    createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });
    

    // To prevent projecting the default fallback content: createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });

  • Errors that are thrown during ApplicationRef.tick will now be rethrown when using TestBed. These errors should be resolved by ensuring the test environment is set up correctly to complete change detection successfully. There are two alternatives to catch the errors:

    • Instead of waiting for automatic change detection to happen, trigger

... (truncated)

Changelog

Sourced from @​angular/platform-browser-dynamic's changelog.

19.0.0 (2024-11-19)

Blog post: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Breaking Changes

compiler

  • this.foo property reads no longer refer to template context variables. If you intended to read the template variable, do not use this..

core

  • Angular directives, components and pipes are now standalone by default.

    • Specify standalone: false for declarations that are currently declared in @NgModules.
    • ng update for v19 will take care of this automatically.
  • TypeScript versions less than 5.5 are no longer supported.

  • Timing changes for effect API (in developer preview):

    • effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the specifics of application/test setup, this can result in them executing earlier or later (or requiring additional test steps to trigger; see below examples).

    • effects which are triggered during change detection (e.g. by input signals) run earlier, before the component's template.

  • ExperimentalPendingTasks has been renamed to PendingTasks.

  • The autoDetect feature of ComponentFixture will now attach the fixture to the ApplicationRef. As a result, errors during automatic change detection of the fixture be reported to the ErrorHandler. This change may cause custom error handlers to observe new failures that were previously unreported.

  • createComponent will now render default fallback with empty projectableNodes.

    • When passing an empty array to projectableNodes in the createComponent API, the default fallback content of the ng-content will be rendered if present. To prevent rendering the default content, pass document.createTextNode('') as a projectableNode.
    // The first ng-content will render the default fallback content if present
    createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });
    

    // To prevent projecting the default fallback content: createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });

  • Errors that are thrown during ApplicationRef.tick will now be rethrown when using TestBed. These errors should be resolved by ensuring the test environment is set up correctly to complete change detection successfully. There are two alternatives to catch the errors:

    • Instead of waiting for automatic change detection to happen, trigger it synchronously and expect the error. For example, a jasmine test could write expect(() => TestBed.inject(ApplicationRef).tick()).toThrow()

... (truncated)

Commits
  • 09df589 refactor(core): Migrate all packages with the explicit-standalone-flag sche...
  • 84b6896 refactor(platform-server): Add an ssr benchmark setup. (#57647)
  • 9dbe6fc refactor: update license text to point to angular.dev (#57901)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/platform-browser-dynamic&package-manager=npm_and_yarn&previous-version=18.2.12&new-version=19.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 5d7f9c937..96be07a42 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -19,7 +19,7 @@ "@angular/forms": "^18.0.1", "@angular/material": "^18.0.1", "@angular/platform-browser": "^18.0.1", - "@angular/platform-browser-dynamic": "^18.0.1", + "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^18.0.1", "rxjs": "~7.8.1", "tslib": "^2.6.2", From b869a51104b8345418272ecbe21416f93e2518a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 07:44:22 +0000 Subject: [PATCH 10/30] Bump @angular/cdk from 18.2.14 to 19.0.0 in /web_embedding/ng-flutter (#2493) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- Bumps [@angular/cdk](https://github.com/angular/components) from 18.2.14 to 19.0.0.
Release notes

Sourced from @​angular/cdk's releases.

v19.0.0

19.0.0 "hafnium-hippo" (2024-11-19)

cdk

Commit Description
feat - f4a02adb7 a11y: use native media query for high contrast detection (#29678)
feat - 9b4085c6e private: create cdk-visually-hidden style loader (#29757)
fix - df21d2b09 overlay: avoid having to manually load structural styles
fix - 560878a23 overlay: load structural styles in a cascade layer (#29725)
fix - 873eb01e0 portal: remove ComponentFactoryResolver usages (#27427)
fix - 5439460d1 scrolling: adds ngTemplateContextGuard (#27276)
fix - ad18e6d74 text-field: avoid having to manually load text field styles
fix - bd84c2a67 tree: fix issue where isExpanded wouldn't be set if placed before isExpandable (#29565)
fix - 3b4ade5a0 tree: only handle keyboard events directly from the node (#29861)
fix - f6066c23f tree: warn if mixed node types are used within the same tree

material

Commit Description
feat - 9122335b2 checkbox: add new aria properties to MatCheckbox (#29457)
feat - 64ed7ca71 core: add experimental theme demo (#29636)
feat - a58e6f671 core: add theme-overrides mixin (#29858)
feat - d206225c5 core: create focus-indicator structural styles loader (#29763)
feat - b519b4785 core: default to color-scheme theme type (#29907)
feat - ea0d1ba7b core: deprecate the core mixin (#29906)
feat - 486990912 core: rename theme mixin (#29857)
feat - 4b49d7354 core: switch system prefix from sys to mat-sys (#29908)
feat - 1abb484aa input: add the ability to interact with disabled inputs (#29574)
feat - 4adc3725d schematics: create v19 core removal schematic (#29768)
feat - 9c3af284f schematics: Switch custom theme schematic to use theme mixin instead of define-theme and add high contrast override mixins (#29642)
feat - 3fc1f9a1b schematics: Update custom theme schematic to work with light-dark and use theme-overrides mixin (#29911)
feat - ff3d342fd tabs: add alignTabs in MatTabsConfig (#29779)
feat - 371446a7c theming: Disambiguate token names in theme overrides (#29859)
feat - 9546fe77e timepicker: add test harnesses
feat - 2646e0885 timepicker: add timepicker component
fix - de6c20686 bottom-sheet: add height minHeight maxHeight to config (#29794)
fix - fcb76d3ed core: add missing system variables (#29624)
fix - 5ad133d07 core: allow optgroup overrides through core-overrides (#29897)
fix - 0fb4247ce core: avoid browser inconsistencies when parsing time
fix - 855ed4948 core: avoid having to manually load ripple styles
fix - d0d59b784 core: change ng-add to use mat.theme (#29990)
fix - a8e40ec34 core: correctly identify color input (#29909)
fix - edce90652 core: delete deprecated APIs (#29651)
fix - 54875a325 core: drop sanity checks (#29688)
fix - ef14c2869 core: option showing double selected indicator in high contrast mode
fix - 5403b4b07 core: remove unused motion system vars (#29920)
fix - 613cf5406 core: rename sys vars from mat-app to mat-sys (#29879)
fix - d0e178b75 core: stop manually instantiating MatRipple directive (#29630)
fix - d55ec612c core: update prebuilt themes to use mat.theme (#29989)
fix - 7cf8c6c46 datepicker: calendar font tokens not being picked up (#29610)

... (truncated)

Changelog

Sourced from @​angular/cdk's changelog.

19.0.0 "hafnium-hippo" (2024-11-19)

Breaking Changes

cdk

    • Since cdk.high-contrast targets a media query instead of a class, the specificity of the styles it emits is lower than before.
    • The overlay stays are now loaded slightly later than before which can change their specificity. You may have to update any overlay style overrides.
    • Virtual scrolling lists now have proper type checking which can reveal some previously-hidden compilation errors.

    • fix(cdk/scrolling): adds ngTemplateContextGuard

    implements ngTemplateContextGuard for CdkVirtualForOf directive

material

    • The ripples styles are now loaded slightly later than before which can change their specificity. You may have to update any ripple style overrides.
    • mixinColor and CanColor have been removed. Use a host binding instead.
    • mixinDisableRipple and CanDisableRipple have been removed. Use input transforms instead.
    • mixinDisabled and CanDisable have been removed. Use input transforms instead.
    • mixinInitialized and HasInitialized have been removed. Use a Subject that emits in ngOnInit instead.
    • mixinTabIndex and HasTabIndex have been removed. Use input transforms instead.

google-maps

    • The new @​googlemaps/markerclusterer API should be imported instead of the old one. Read more at: https://github.com/googlemaps/js-markerclusterer
    • The MapMarkerClusterer class has been renamed to DeprecatedMapMarkerClusterer.
    • The map-marker-clusterer selector has been changed to deprecated-map-marker-clusterer.

multiple

    • In order for Material to be compatible with recent changes in Sass and upcoming changes in the CSS standard, tokens are now emitted in-place, rather the being hoisted to the top of the selector. As a result, some token overrides might not apply anymore. This is relevant primarily for the cases like @include mat.button-theme($theme); --mat-button-color: red;. It can be resolved by wrapping the overrides with & {}, for example @include mat.button-theme($theme); & { --mat-button-color: red; }.
    • MatButton.ripple is no longer available.
    • MatCheckbox.ripple is no longer available.
    • MatChip.ripple is no longer available.

material-date-fns-adapter

Commit Type Description
234e5e0e8 feat add support for date-fns 4 (#29744)

youtube-player

Commit Type Description
09da06b42 fix ready event not emitting
288598750 fix startSeconds not applied when using placeholder

google-maps

Commit Type Description
1bd976c6a feat Add support for some mouse events #29741 (#29747)
a05475e76 feat deprecate marker cluster component
c70aae15b feat implement new marker clusterer
b9deeee85 fix add schematic to switch to the new clusterer name
a6709497f fix expose all clusterer types (#29905)
74c2a081f fix resolve CLI errors in ng update schematic (#29947)

material

Commit Type Description
9122335b2 feat checkbox: add new aria properties to MatCheckbox (#29457)
64ed7ca71 feat core: add experimental theme demo (#29636)
a58e6f671 feat core: add theme-overrides mixin (#29858)

... (truncated)

Commits
  • 2f3cea1 release: cut the v19.0.0 release
  • 56834a2 build: update to v19 final (#30045)
  • 734f296 docs: fix broken links (#30038)
  • 370e6cc release: cut the v19.0.0-rc.3 release
  • 05c78af fix(cdk/table): run differ for all columns (#30012)
  • 3a4158e refactor(cdk/testing): fix out of sync file (#30021)
  • dbcb921 fix(material/menu): handle keyboard events through dispatcher (#29997)
  • 5345a87 fix(material/input): preserve aria-describedby set externally
  • 5ba9792 fix(material/form-field): avoid touching the DOM on each state change
  • 13beab5 release: cut the v19.0.0-rc.2 release
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/cdk&package-manager=npm_and_yarn&previous-version=18.2.14&new-version=19.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 96be07a42..95b62c60b 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -12,7 +12,7 @@ "private": true, "dependencies": { "@angular/animations": "^19.0.0", - "@angular/cdk": "^18.0.1", + "@angular/cdk": "^19.0.0", "@angular/common": "^18.0.1", "@angular/compiler": "^18.0.1", "@angular/core": "^18.0.1", From ce5238b4fae513542bf22d0f9a441402f8236227 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 07:45:32 +0000 Subject: [PATCH 11/30] Bump @angular/compiler from 18.2.12 to 19.0.0 in /web_embedding/ng-flutter (#2494) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- Bumps [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) from 18.2.12 to 19.0.0.
Release notes

Sourced from @​angular/compiler's releases.

v19.0.0

19.0.0 (2024-11-19)

Explore Angular v19 with a blog post from the Angular team: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Breaking Changes

compiler

  • this.foo property reads no longer refer to template context variables. If you intended to read the template variable, do not use this..

core

  • Angular directives, components and pipes are now standalone by default.

    • Specify standalone: false for declarations that are currently declared in @NgModules.
    • ng update for v19 will take care of this automatically.
  • TypeScript versions less than 5.5 are no longer supported.

  • Timing changes for effect API (in developer preview):

    • effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the specifics of application/test setup, this can result in them executing earlier or later (or requiring additional test steps to trigger; see below examples).

    • effects which are triggered during change detection (e.g. by input signals) run earlier, before the component's template.

  • ExperimentalPendingTasks has been renamed to PendingTasks.

  • The autoDetect feature of ComponentFixture will now attach the fixture to the ApplicationRef. As a result, errors during automatic change detection of the fixture be reported to the ErrorHandler. This change may cause custom error handlers to observe new failures that were previously unreported.

  • createComponent will now render default fallback with empty projectableNodes.

    • When passing an empty array to projectableNodes in the createComponent API, the default fallback content of the ng-content will be rendered if present. To prevent rendering the default content, pass document.createTextNode('') as a projectableNode.
    // The first ng-content will render the default fallback content if present
    createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });
    

    // To prevent projecting the default fallback content: createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });

  • Errors that are thrown during ApplicationRef.tick will now be rethrown when using TestBed. These errors should be resolved by ensuring the test environment is set up correctly to complete change detection successfully. There are two alternatives to catch the errors:

    • Instead of waiting for automatic change detection to happen, trigger

... (truncated)

Changelog

Sourced from @​angular/compiler's changelog.

19.0.0 (2024-11-19)

Blog post: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Breaking Changes

compiler

  • this.foo property reads no longer refer to template context variables. If you intended to read the template variable, do not use this..

core

  • Angular directives, components and pipes are now standalone by default.

    • Specify standalone: false for declarations that are currently declared in @NgModules.
    • ng update for v19 will take care of this automatically.
  • TypeScript versions less than 5.5 are no longer supported.

  • Timing changes for effect API (in developer preview):

    • effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the specifics of application/test setup, this can result in them executing earlier or later (or requiring additional test steps to trigger; see below examples).

    • effects which are triggered during change detection (e.g. by input signals) run earlier, before the component's template.

  • ExperimentalPendingTasks has been renamed to PendingTasks.

  • The autoDetect feature of ComponentFixture will now attach the fixture to the ApplicationRef. As a result, errors during automatic change detection of the fixture be reported to the ErrorHandler. This change may cause custom error handlers to observe new failures that were previously unreported.

  • createComponent will now render default fallback with empty projectableNodes.

    • When passing an empty array to projectableNodes in the createComponent API, the default fallback content of the ng-content will be rendered if present. To prevent rendering the default content, pass document.createTextNode('') as a projectableNode.
    // The first ng-content will render the default fallback content if present
    createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });
    

    // To prevent projecting the default fallback content: createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });

  • Errors that are thrown during ApplicationRef.tick will now be rethrown when using TestBed. These errors should be resolved by ensuring the test environment is set up correctly to complete change detection successfully. There are two alternatives to catch the errors:

    • Instead of waiting for automatic change detection to happen, trigger it synchronously and expect the error. For example, a jasmine test could write expect(() => TestBed.inject(ApplicationRef).tick()).toThrow()

... (truncated)

Commits
  • 806a61b fix(compiler): fix multiline selectors (#58681)
  • e5d3abb fix(compiler): resolve :host:host-context(.foo) (#58681)
  • 80f5695 fix(compiler): transform chained pseudo-selectors (#58681)
  • 2be161d fix(compiler): fix :host parsing in pseudo-selectors (#58681)
  • 560282a fix(compiler): control flow nodes with root at the end projected incorrectly ...
  • 86d8f6b refactor(compiler): trigger hmr load on initialization (#58465)
  • abd0da7 refactor(compiler): remove unused field from output AST (#58444)
  • b25121e fix(compiler): avoid having to duplicate core environment (#58444)
  • 98804fd fix(compiler): add more specific matcher for hydrate never block (#58360)
  • c79b62c refactor(core): remove the standalone feature (#58288)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/compiler&package-manager=npm_and_yarn&previous-version=18.2.12&new-version=19.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 95b62c60b..7d546bb58 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -14,7 +14,7 @@ "@angular/animations": "^19.0.0", "@angular/cdk": "^19.0.0", "@angular/common": "^18.0.1", - "@angular/compiler": "^18.0.1", + "@angular/compiler": "^19.0.0", "@angular/core": "^18.0.1", "@angular/forms": "^18.0.1", "@angular/material": "^18.0.1", From 16c3c021e857e71e11c74ecf5f444dbbced41197 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 08:14:15 +0000 Subject: [PATCH 12/30] Bump @angular/common from 18.2.12 to 19.0.0 in /web_embedding/ng-flutter (#2496) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- Bumps [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) from 18.2.12 to 19.0.0.
Release notes

Sourced from @​angular/common's releases.

v19.0.0

19.0.0 (2024-11-19)

Explore Angular v19 with a blog post from the Angular team: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Breaking Changes

compiler

  • this.foo property reads no longer refer to template context variables. If you intended to read the template variable, do not use this..

core

  • Angular directives, components and pipes are now standalone by default.

    • Specify standalone: false for declarations that are currently declared in @NgModules.
    • ng update for v19 will take care of this automatically.
  • TypeScript versions less than 5.5 are no longer supported.

  • Timing changes for effect API (in developer preview):

    • effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the specifics of application/test setup, this can result in them executing earlier or later (or requiring additional test steps to trigger; see below examples).

    • effects which are triggered during change detection (e.g. by input signals) run earlier, before the component's template.

  • ExperimentalPendingTasks has been renamed to PendingTasks.

  • The autoDetect feature of ComponentFixture will now attach the fixture to the ApplicationRef. As a result, errors during automatic change detection of the fixture be reported to the ErrorHandler. This change may cause custom error handlers to observe new failures that were previously unreported.

  • createComponent will now render default fallback with empty projectableNodes.

    • When passing an empty array to projectableNodes in the createComponent API, the default fallback content of the ng-content will be rendered if present. To prevent rendering the default content, pass document.createTextNode('') as a projectableNode.
    // The first ng-content will render the default fallback content if present
    createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });
    

    // To prevent projecting the default fallback content: createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });

  • Errors that are thrown during ApplicationRef.tick will now be rethrown when using TestBed. These errors should be resolved by ensuring the test environment is set up correctly to complete change detection successfully. There are two alternatives to catch the errors:

    • Instead of waiting for automatic change detection to happen, trigger

... (truncated)

Changelog

Sourced from @​angular/common's changelog.

19.0.0 (2024-11-19)

Blog post: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Breaking Changes

compiler

  • this.foo property reads no longer refer to template context variables. If you intended to read the template variable, do not use this..

core

  • Angular directives, components and pipes are now standalone by default.

    • Specify standalone: false for declarations that are currently declared in @NgModules.
    • ng update for v19 will take care of this automatically.
  • TypeScript versions less than 5.5 are no longer supported.

  • Timing changes for effect API (in developer preview):

    • effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the specifics of application/test setup, this can result in them executing earlier or later (or requiring additional test steps to trigger; see below examples).

    • effects which are triggered during change detection (e.g. by input signals) run earlier, before the component's template.

  • ExperimentalPendingTasks has been renamed to PendingTasks.

  • The autoDetect feature of ComponentFixture will now attach the fixture to the ApplicationRef. As a result, errors during automatic change detection of the fixture be reported to the ErrorHandler. This change may cause custom error handlers to observe new failures that were previously unreported.

  • createComponent will now render default fallback with empty projectableNodes.

    • When passing an empty array to projectableNodes in the createComponent API, the default fallback content of the ng-content will be rendered if present. To prevent rendering the default content, pass document.createTextNode('') as a projectableNode.
    // The first ng-content will render the default fallback content if present
    createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });
    

    // To prevent projecting the default fallback content: createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });

  • Errors that are thrown during ApplicationRef.tick will now be rethrown when using TestBed. These errors should be resolved by ensuring the test environment is set up correctly to complete change detection successfully. There are two alternatives to catch the errors:

    • Instead of waiting for automatic change detection to happen, trigger it synchronously and expect the error. For example, a jasmine test could write expect(() => TestBed.inject(ApplicationRef).tick()).toThrow()

... (truncated)

Commits
  • 7dfb127 refactor: add @__PURE__ next to @pureOrBreakMyCode for improved bundler c...
  • da9c0c5 refactor: cleanup initializers that use ctor params (#58349)
  • 24c6373 feat(common): add optional rounded transform support in cloudinary image load...
  • 4b9accd feat(http): promote withRequestsMadeViaParent to stable. (#58221)
  • 13c1306 feat(common): disable keyvalue sorting using null compareFn (#57487)
  • 09df589 refactor(core): Migrate all packages with the explicit-standalone-flag sche...
  • 08b4a8a docs: move JSDoc below constructor (#57187)
  • a36744e docs: move JSDoc before functions (#58087)
  • 0eb1c5c docs(common): Minor typo in code example (#58085)
  • 84b6896 refactor(platform-server): Add an ssr benchmark setup. (#57647)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/common&package-manager=npm_and_yarn&previous-version=18.2.12&new-version=19.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 7d546bb58..253161ba8 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -13,7 +13,7 @@ "dependencies": { "@angular/animations": "^19.0.0", "@angular/cdk": "^19.0.0", - "@angular/common": "^18.0.1", + "@angular/common": "^19.0.0", "@angular/compiler": "^19.0.0", "@angular/core": "^18.0.1", "@angular/forms": "^18.0.1", From c6c931801aeafb2868bda8ad09e41145f1e5c579 Mon Sep 17 00:00:00 2001 From: Eric Windmill Date: Thu, 28 Nov 2024 08:28:16 -0500 Subject: [PATCH 13/30] Update contributing guidelines for repository (#2500) Update contributing guidelines to reflect new policies for 2025. Related to #2497, but does not complete it. ## Pre-launch Checklist - [x] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [x] I signed the [CLA]. - [x] I read the [Contributors Guide]. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] All existing and new tests are passing. --- CONTRIBUTING.md | 283 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 209 insertions(+), 74 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1a3d0b818..68fdd7e8c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,46 +1,45 @@ # Contributing -_See also: [Flutter's code of conduct](https://github.com/flutter/flutter/blob/master/CODE_OF_CONDUCT.md)_ - Want to contribute to the Flutter sample ecosystem? Great! First, read this page (including the small print at the end). -## Is this the right place for your contribution? +Do you work at Google? Great! You should **definitely** read this page before submitting a PR :) + +* [Before you contribute] +* [Contribute enhancements and fixes] +* [Write a new sample] +* [Sample checklist] + +_See also: [Flutter's code of conduct]_ + +
+ +# Before you contribute -This repo is used by members of the Flutter team and a few partners as a place -to store example apps and demos. It's not meant to be the one and only source of -truth for Flutter samples or the only place people go to learn about the best -ways to build with Flutter. What that means in practice is that if you've -written a great example app, it doesn't need to be maintained here in order to -get noticed, be of help to new Flutter devs, and have an impact on the -community. -You can maintain your sample app in your own repo (or with another source -control provider) and still be as important a part of the Flutter-verse as -anything you see here. You can let us know on the -[FlutterDev Google Group](https://groups.google.com/forum/#!forum/flutter-dev) -when you've published something and Tweet about it with the -[#FlutterDev](https://twitter.com/search?q=%23FlutterDev) hashtag. +## Is this the right place for your sample? -## So what should be contributed here, then? +In most cases, if you've written a great sample app, it should be maintained +in your own repoistory. You can maintain your sample app in your own repo +(or with another source control provider) and still be as important a part of +the Flutter-verse as anything you see here. -Fixes and necessary improvements to the existing samples, mostly. +**What should be contributed here, then?** -## Before you contribute +Fixes and necessary improvements to the existing samples, mostly. -### File an issue first! +## File an issue first! If you see a bug or have an idea for a feature that you feel would improve one -of the samples already in the repo, **please -[file an issue](https://github.com/flutter/samples/issues/new) before you begin +of the samples already in the repo, **please [file an issue] before you begin coding or send a PR**. This will help prevent duplicate work by letting us know what you're up to. It will help avoid a situation in which you spend a lot of time coding something that's not quite right for the repo or its goals. -### Sign the license agreement. +## Sign the license agreement. Before we can use your code, you must sign the -[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual) +[Google Individual Contributor License Agreement] (CLA), which you can do online. The CLA is necessary mainly because you own the copyright to your changes, even after your contribution becomes part of our codebase, so we need your permission to use and distribute your code. We also @@ -54,47 +53,177 @@ us first through the issue tracker with your idea so that we can help out and possibly guide you. Coordinating up front makes it much easier to avoid frustration later on. -## A few ground rules - -This is monorepo containing a bunch of projects. While different codebases have -different needs, there are a few basic conventions that every project here is -expected to follow. All of them are based on our experience over the last -couple years keeping the repo tidy and running smooth. - -Each app should: - -* Be designed to build against the current - [stable](https://github.com/flutter/flutter/blob/master/docs/releases/Flutter-build-release-channels.md) - release of the Flutter SDK. -* Include the top level - [`analysis_options.yaml`](analysis_options.yaml) - file used throughout the repo. This file include a base set of analyzer - conventions and lints. -* Have no analyzer errors or warnings. -* Be formatted with `dart format`. -* Include at least one working test in its `test` folder. -* Be wired into the list of projects in the CI scripts for [stable](tool/flutter_ci_script_stable.sh), - [beta](tool/flutter_ci_script_beta.sh), and [master](tool/flutter_ci_script_master.sh), - which runs the analyzer, the formatter, and `flutter test`. -* Add the new project directory to the [dependabot](.github/dependabot.yaml) configuration - to keep dependencies updated in an on-going basis. -* Avoid adding an onerous amount of blobs (typically images or other assets) to - the repo. - -In addition, sample code is, at the end of the day, still code. It should be -written with at least as much care as the Flutter code you'd find in the SDK -itself. For that reason, most of the -[Flutter style guide](https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md) -also applies to code in this repo. +
+ +# Contribute enhancements and fixes + +Enhancements and bug fixes are welcome and appreciated. +If you spot an [issue] that you might want to fix but aren't sure how to get started, +feel free to comment on the issue and tag @ericwindmill with questions. + +## Filing issues and evaluating existing samples + +You can also contribute by filing issues against existing samples. This is thankless work +and is _greatly_ appreciated. It's also a good way to familiarize yourself with the repository. + +To evaluate a sample for possible issues, use the [Sample checklist] below. + +
+ +# Writing a new sample + +Before filing an issue for a new sample or submitting a PR, you must read the rest of this page. + +## What is a sample? + +Samples are reference materials that teach developers how to solve a specific problem. +Samples contain **correct and concise code** that developers can +**quickly understand** and **easily reuse** with minimal side effects. + +### What samples should we have? + +Samples in this repo demonstrates how to **use current features** of the **Flutter and Dart SDKs** using **best practices**. +In other words, a sample should meet the following criteria: + +* Demonstrates _how to use the SDKS_ rather than show an end-product. +* Covers a critical developer journey in the SDK that is useful to >80% of developers. +* Prefers primitives in the SDK over libraries. +* Demonstrates features available on the stable channel of Flutter. + +These guidelines can be broken in rare cases. For example, this is likely the best place in the +Flutter github org for demo apps, but those demo apps must be justified. + +## Is this the right place for your sample? (revisited) + +Validate your idea against the following criteria: + +1. **The sample solves a single problem or set of tightly coupled problems.**
+ If not, you're either writing a Demo app or an extended sample. These might + still be appropriate for the samples repos, but need to be justified. + +2. **The target audience for the sample isn’t beginners.** +3. **The sample code isn’t so complex that it needs video or text explanation.**
+ Samples are reference materials, and the code should speak for itself. If either of these aren't true, + you may prefer to write a blogpost or tutorial. + +5. **The sample isn’t tied to an event.**
+ If it is, you should likely use a personal repository. + +5. **The sample isn’t tied to a library or package.**
+ If it is, the usage example should likely be in the [repository of that package]. + +6. **The topic doesn’t have crossover with any existing samples.**
+ If it does, ensure that it wouldn't be better to update the existing sample. + +## What are your ongoing maintenance resposibilities? + +All sample code has an unbound maintenance cost. If you cannot commit to maintaining a sample +(for the forseeable future, barring changes in life circumstances), then you should talk to the +[primary maintainers] of this project, particularly @ericwindmill, before submitting a PR. + +Any new sample **must** have a CODEOWNER, and that owner is most likely you (the author). + +## What type of sample are your writing? + +This repository contains two types of sample apps: **quickstarts** and **demo apps**. + +### Quickstarts + +* **Purpose**: Provides starting points that a developer can extend. + Solves specific problems or implements generic app features. +* **Size**: <= 200 lines of code, not including boiler plate (guide, not rule) +* **Qualities:** + * Contains one feature or a small set of related features, but generally runnable. + * Generic and un-opinionated about the context in which it is used. + * Prioritizes being generic over best practices. + * The code is Copy+paste-able. + * In Flutter, this means that the code that is being demonstrated should be separated from and boiler plate (i.e. `runApp`) +* **Audience:** + * Developers with Flutter and Dart experience that don't need code explained to them. +* **Answers the questions:** + * “What’s the minimal amount of code needed to implement this feature…” + * “... so I can understand how it works?” + * “... so I can understand how to add it to my app?” + * “How can I make sure I know how to extend this feature without missing anything?” + * "What code should I use as a starting point given I want to solve a very similar problem?" + +### Demo apps + +* **Purpose**: Meant to be built and ran. Demos the _product_, not how to write code. +* **Criteria**: Demo apps _only_ belong here if they... + * ...aren't tied to an event or moment in time. + * ...aren't tied to another resource (website, workshop, etc). + * ...don't require explanation (other than a short README). + * ...aren't primarily used to demonstrate an SDK feature. + +### Other sample types + +Other sample types, like demo apps that accompany docs or events, do not belong in this repository. +They should be maintained alongside the accompanying resources (i.e. in the website repository), or in a personal repository. ### The `experimental` folder -Projects in the repo's top-level `experimental` directory are allowed to skirt -some of the above rules. These apps are either experimental in nature or use -APIs that haven't landed in the SDK's `stable` channel. They build against -`main`, and aren't (by default) wired into our CI system. +The experimental folder is being deprecated. If you have an experiemental sample project, +you should manage it in a personal repository until it runs on the stable channel. + +
+ +# Sample checklist + +Every piece of code will have value to someone, but it is easy for maintenance costs to grow over time. +The more items checked on this list, the higher the value and lower the maintenance costs. + +Use this checklist to write new samples and evaluate existing ones. + +**NB:** Demo apps have looser requirements. Use your best judgement when following the guidelines. + +* Code + - [ ] Be designed to build against the current [stable] + release of the Flutter SDK. + - [ ] Sample is the only one for the API in question (across all Dash samples) + - [ ] Repository and pubspec name are titled for its ingredients (i.e. mvvm_architecture instead of compass_app) + - [ ] Only includes the minimal required code to demonstrate the feature or API and run the code. + - [ ] Sample favors 1P dependencies over 3P. + - [ ] Code has been sufficiently explained with doc comments. + - [ ] The sample app separates its bespoke code from general Flutter or Dart code. + - [ ] Favor readability over best practices unless readability requires an anti pattern. Use your best judgment. + - [ ] Avoid adding an onerous amount of blobs (typically images or other assets) to the repo. + - [ ] All files in the project must start with the appropriate [file headers]. + +* Tests, style and maintenance + - [ ] Sample has Dart tests that cover the business logic + - [ ] Sample is wired into the list of projects in the CI scripts for [stable](tool/flutter_ci_script_stable.sh), + [beta](tool/flutter_ci_script_beta.sh), and [master](tool/flutter_ci_script_master.sh), + which runs the analyzer, the formatter, and `flutter test`. + - [ ] Sample has a codeowner (it's likely you, the author) + - [ ] Sample is formatted with `dart format`. + - [ ] Sample has no analyzer errors or warnings. + - [ ] Add the new project directory to the [dependabot](.github/dependabot.yaml) configuration + to keep dependencies updated in an on-going basis. + - [ ] Follows the [Flutter style guide] + - [ ] Include the top level [`analysis_options.yaml`](analysis_options.yaml) + file used throughout the repo. This file include a base set of analyzer + conventions and lints. + +* README + - [ ] Describes the apps design and purpose. + - [ ] Describes common errors and debugging steps. + - [ ] Describes any steps necessary to build and run. + - [ ] Has ‘Open in IDX’ button, and a nix file (if compatible with IDX). + +## File headers + +All files in the project must start with the following header. + +``` +// Copyright 2024 The Flutter team. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +``` + +
-## Code reviews +# Code reviews All submissions, including submissions by project members, require review. @@ -107,7 +236,7 @@ primary maintainers, though, are: * [@domesticmouse](https://github.com/domesticmouse) * [@ericwindmill](https://github.com/ericwindmill) -You are free to add one of these folks (particularly @RedBrogdon) as a reviewer +You are free to add one of these folks (particularly @ericwindmill) as a reviewer to any PR sent to this repo. We're happy to comment, answer (or ask) questions, and provide feedback. @@ -121,18 +250,24 @@ before, or changing something that's a meta-concern like the CI setup, web hosting, project setup, etc., please include one of the primary maintainers as a reviewer. -## File headers - -All files in the project must start with the following header. - -``` -// Copyright 2024 The Flutter team. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -``` +
-## The small print +# The small print Contributions made by corporations are covered by a different agreement than the -one above, the -[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate). +one above, the [Software Grant and Corporate Contributor License Agreement]. + +[Flutter's code of conduct]: https://github.com/flutter/flutter/blob/master/CODE_OF_CONDUCT.md +[Before you contribute]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#before-you-contribute +[Contribute enhancements and fixes]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#contribute-enhancements-and-fixes +[Write a new sample]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#write-a-new-sample +[Sample checklist]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#samples-checklist +[file headers]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#file-headers +[Software Grant and Corporate Contributor License Agreement]: https://developers.google.com/open-source/cla/corporate +[issue]: https://github.com/flutter/samples/issues +[file an issue]: https://github.com/flutter/samples/issues/new +[repository of that package]: https://dart.dev/tools/pub/package-layout#examples +[stable]: https://github.com/flutter/flutter/blob/master/docs/releases/Flutter-build-release-channels.md +[Flutter style guide]: (https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md) +[Google Individual Contributor License Agreement]: https://cla.developers.google.com/about/google-individual +[primary maintainers]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#code-reviews From 87c2dcbfd1d136349366d4c05ac682bfe953da09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 07:03:04 +0000 Subject: [PATCH 14/30] Bump @angular-devkit/build-angular from 18.2.12 to 19.0.2 in /web_embedding/ng-flutter (#2502) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 18.2.12 to 19.0.2.
Release notes

Sourced from @​angular-devkit/build-angular's releases.

v19.0.2

19.0.2 (2024-11-25)

@​schematics/angular

Commit Description
fix - 2f53e2af5 skip SSR routing prompt in webcontainer

@​angular/build

Commit Description
fix - f9da163f8 minimize reliance on esbuild inject to prevent code reordering
fix - c497749e6 prevent errors with parameterized routes when getPrerenderParams is undefined

@​angular/ssr

Commit Description
fix - c8cd90e0f handle nested redirects not explicitly defined in router config

v19.0.1

19.0.1 (2024-11-21)

@​angular-devkit/build-angular

Commit Description
fix - b63123f20 use stylePreprocessorOptions

@​angular/build

Commit Description
fix - 74461da64 ensure accurate content length for server assets
fix - 1b4dcedd5 use sha256 instead of sha-256 as hash algorithm name

@​angular/ssr

Commit Description
fix - 8bd2b260e handle baseHref that start with ./

v19.0.0

19.0.0 (2024-11-19)

@​angular/cli

Commit Description
feat - 201b60e1d handle string key/value pairs, e.g. --define
fix - b847d4460 recommend optional application update migration during v19 update
perf - f249e7e85 enable Node.js compile code cache when available
perf - ecc107d83 enable Node.js compile code cache when available

@​schematics/angular

Commit Description
feat - a381a3db1 add option to export component as default
feat - 755f3a07f add option to setup new workspace or application as zoneless mode
feat - cfca5442e integrate withEventReplay() in provideClientHydration for new SSR apps

... (truncated)

Changelog

Sourced from @​angular-devkit/build-angular's changelog.

19.0.2 (2024-11-25)

@​schematics/angular

Commit Type Description
2f53e2af5 fix skip SSR routing prompt in webcontainer

@​angular/build

Commit Type Description
f9da163f8 fix minimize reliance on esbuild inject to prevent code reordering
c497749e6 fix prevent errors with parameterized routes when getPrerenderParams is undefined

@​angular/ssr

Commit Type Description
c8cd90e0f fix handle nested redirects not explicitly defined in router config

19.0.1 (2024-11-21)

@​angular-devkit/build-angular

Commit Type Description
b63123f20 fix use stylePreprocessorOptions

@​angular/build

Commit Type Description
74461da64 fix ensure accurate content length for server assets
1b4dcedd5 fix use sha256 instead of sha-256 as hash algorithm name

@​angular/ssr

Commit Type Description
8bd2b260e fix handle baseHref that start with ./

... (truncated)

Commits
  • d261246 release: cut the v19.0.2 release
  • c497749 fix(@​angular/build): prevent errors with parameterized routes when `getPreren...
  • d8cbf3b refactor(@​angular/build): maintain previous compiler plugin factory signature
  • 2f53e2a fix(@​schematics/angular): skip SSR routing prompt in webcontainer
  • f9da163 fix(@​angular/build): minimize reliance on esbuild inject to prevent code re...
  • 5ac03f4 refactor(@​angular/ssr): use appRef.whenStable instead of util function from a...
  • 0eb5870 refactor(@​angular/ssr): replace :params with *
  • c8cd90e fix(@​angular/ssr): handle nested redirects not explicitly defined in router c...
  • 8cd6aa9 release: cut the v19.0.1 release
  • 1b4dced fix(@​angular/build): use sha256 instead of sha-256 as hash algorithm name
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular-devkit/build-angular&package-manager=npm_and_yarn&previous-version=18.2.12&new-version=19.0.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 253161ba8..3e8b3993c 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -26,7 +26,7 @@ "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.0.2", + "@angular-devkit/build-angular": "^19.0.2", "@angular/cli": "~18.2.0", "@angular/compiler-cli": "^18.0.1", "@types/jasmine": "~5.1.0", From c909c6b4b87ccc0e41d8d2800475a1cc58f4aece Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 07:04:26 +0000 Subject: [PATCH 15/30] Bump @angular/router from 18.2.13 to 19.0.1 in /web_embedding/ng-flutter (#2503) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@angular/router](https://github.com/angular/angular/tree/HEAD/packages/router) from 18.2.13 to 19.0.1.
Release notes

Sourced from @​angular/router's releases.

v19.0.1

19.0.1 (2024-11-26)

compiler-cli

Commit Description
fix - fb1fa8b0fc more accurate diagnostics for host binding parser errors (#58870)

core

Commit Description
fix - 502ee0e722 correctly clear template HMR internal renderer cache (#58724)
fix - 99715104a1 correctly perform lazy routes migration for components with additional decorators (#58796)
fix - 118803035f Ensure _tick is always run within the TracingSnapshot. (#58881)
fix - 08b9452f01 Ensure resource sets an error (#58855)
fix - 84f45ea3ff make component id generation more stable between client and server builds (#58813)
fix - d3491c7cee Prevents race condition of cleanup for incremental hydration (#58722)

forms

Commit Description
fix - 4dfe5b6cef work around TypeScript 5.7 issue (#58731)

language-service

Commit Description
fix - a983865bff add fix for individual unused imports (#58719)
fix - e6e7a4e22b allow fixes to run without template info (#58719)

migrations

Commit Description
fix - 5ce10264a4 fix provide-initializer migration when using useFactory (#58518)
fix - d4f5c85f60 handle parameters with initializers in inject migration (#58769)
fix - a6d2d2dc10 Mark hoisted properties as removed in inject migration (#58804)

v19.0.0

19.0.0 (2024-11-19)

Explore Angular v19 with a blog post from the Angular team: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Breaking Changes

compiler

  • this.foo property reads no longer refer to template context variables. If you intended to read the template variable, do not use this..

core

  • Angular directives, components and pipes are now standalone by default.

    • Specify standalone: false for declarations that are currently declared in @NgModules.
    • ng update for v19 will take care of this automatically.
  • TypeScript versions less than 5.5 are no longer supported.

  • Timing changes for effect API (in developer preview):

    • effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the

... (truncated)

Changelog

Sourced from @​angular/router's changelog.

18.2.13 (2024-11-26)

migrations

Commit Type Description
06d70a25ea fix take care of tests that import both HttpClientModule & HttpClientTestingModule. (#58777)

19.1.0-next.0 (2024-11-26)

common

Commit Type Description
e4c50b3bea feat expose component instance in NgComponentOutlet (#58698)

core

Commit Type Description
bd1f1294ae feat support TypeScript 5.7 (#58609)

19.0.1 (2024-11-26)

compiler-cli

Commit Type Description
fb1fa8b0fc fix more accurate diagnostics for host binding parser errors (#58870)

core

Commit Type Description
502ee0e722 fix correctly clear template HMR internal renderer cache (#58724)
99715104a1 fix correctly perform lazy routes migration for components with additional decorators (#58796)
118803035f fix Ensure _tick is always run within the TracingSnapshot. (#58881)
08b9452f01 fix Ensure resource sets an error (#58855)
84f45ea3ff fix make component id generation more stable between client and server builds (#58813)
d3491c7cee fix Prevents race condition of cleanup for incremental hydration (#58722)

forms

Commit Type Description
4dfe5b6cef fix work around TypeScript 5.7 issue (#58731)

language-service

Commit Type Description
a983865bff fix add fix for individual unused imports (#58719)
e6e7a4e22b fix allow fixes to run without template info (#58719)

migrations

Commit Type Description
5ce10264a4 fix fix provide-initializer migration when using useFactory (#58518)
d4f5c85f60 fix handle parameters with initializers in inject migration (#58769)

... (truncated)

Commits
  • 0c86d3e refactor(router): remove unused default error handler function (#58819)
  • a49c35e fix(router): remove setter for injector on OutletContext (#58343)
  • da9c0c5 refactor: cleanup initializers that use ctor params (#58349)
  • a36b54d docs(router): document segment consumption during route evaluation (#58069)
  • 0ea9b88 test(router): adding test for getLoadedRoutes (#58199)
  • 0674965 refactor(router): publishing getLoadedRoutes using the global utils function ...
  • 09df589 refactor(core): Migrate all packages with the explicit-standalone-flag sche...
  • 84b6896 refactor(platform-server): Add an ssr benchmark setup. (#57647)
  • ed57c5c docs: export ComponentInputBindingFeature which is part of the public API (#5...
  • 2ece9df docs(router): Document missing input for route binding (#57697)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/router&package-manager=npm_and_yarn&previous-version=18.2.13&new-version=19.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 3e8b3993c..ac25c79ea 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -20,7 +20,7 @@ "@angular/material": "^18.0.1", "@angular/platform-browser": "^18.0.1", "@angular/platform-browser-dynamic": "^19.0.0", - "@angular/router": "^18.0.1", + "@angular/router": "^19.0.1", "rxjs": "~7.8.1", "tslib": "^2.6.2", "zone.js": "~0.15.0" From 9db1ce1fbe9e5984c0ca01c238aef790efada4aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 07:04:29 +0000 Subject: [PATCH 16/30] Bump @angular/forms from 18.2.13 to 19.0.1 in /web_embedding/ng-flutter (#2501) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@angular/forms](https://github.com/angular/angular/tree/HEAD/packages/forms) from 18.2.13 to 19.0.1.
Release notes

Sourced from @​angular/forms's releases.

v19.0.1

19.0.1 (2024-11-26)

compiler-cli

Commit Description
fix - fb1fa8b0fc more accurate diagnostics for host binding parser errors (#58870)

core

Commit Description
fix - 502ee0e722 correctly clear template HMR internal renderer cache (#58724)
fix - 99715104a1 correctly perform lazy routes migration for components with additional decorators (#58796)
fix - 118803035f Ensure _tick is always run within the TracingSnapshot. (#58881)
fix - 08b9452f01 Ensure resource sets an error (#58855)
fix - 84f45ea3ff make component id generation more stable between client and server builds (#58813)
fix - d3491c7cee Prevents race condition of cleanup for incremental hydration (#58722)

forms

Commit Description
fix - 4dfe5b6cef work around TypeScript 5.7 issue (#58731)

language-service

Commit Description
fix - a983865bff add fix for individual unused imports (#58719)
fix - e6e7a4e22b allow fixes to run without template info (#58719)

migrations

Commit Description
fix - 5ce10264a4 fix provide-initializer migration when using useFactory (#58518)
fix - d4f5c85f60 handle parameters with initializers in inject migration (#58769)
fix - a6d2d2dc10 Mark hoisted properties as removed in inject migration (#58804)

v19.0.0

19.0.0 (2024-11-19)

Explore Angular v19 with a blog post from the Angular team: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Breaking Changes

compiler

  • this.foo property reads no longer refer to template context variables. If you intended to read the template variable, do not use this..

core

  • Angular directives, components and pipes are now standalone by default.

    • Specify standalone: false for declarations that are currently declared in @NgModules.
    • ng update for v19 will take care of this automatically.
  • TypeScript versions less than 5.5 are no longer supported.

  • Timing changes for effect API (in developer preview):

    • effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the

... (truncated)

Changelog

Sourced from @​angular/forms's changelog.

18.2.13 (2024-11-26)

migrations

Commit Type Description
06d70a25ea fix take care of tests that import both HttpClientModule & HttpClientTestingModule. (#58777)

19.1.0-next.0 (2024-11-26)

common

Commit Type Description
e4c50b3bea feat expose component instance in NgComponentOutlet (#58698)

core

Commit Type Description
bd1f1294ae feat support TypeScript 5.7 (#58609)

19.0.1 (2024-11-26)

compiler-cli

Commit Type Description
fb1fa8b0fc fix more accurate diagnostics for host binding parser errors (#58870)

core

Commit Type Description
502ee0e722 fix correctly clear template HMR internal renderer cache (#58724)
99715104a1 fix correctly perform lazy routes migration for components with additional decorators (#58796)
118803035f fix Ensure _tick is always run within the TracingSnapshot. (#58881)
08b9452f01 fix Ensure resource sets an error (#58855)
84f45ea3ff fix make component id generation more stable between client and server builds (#58813)
d3491c7cee fix Prevents race condition of cleanup for incremental hydration (#58722)

forms

Commit Type Description
4dfe5b6cef fix work around TypeScript 5.7 issue (#58731)

language-service

Commit Type Description
a983865bff fix add fix for individual unused imports (#58719)
e6e7a4e22b fix allow fixes to run without template info (#58719)

migrations

Commit Type Description
5ce10264a4 fix fix provide-initializer migration when using useFactory (#58518)
d4f5c85f60 fix handle parameters with initializers in inject migration (#58769)

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/forms&package-manager=npm_and_yarn&previous-version=18.2.13&new-version=19.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index ac25c79ea..beaff561f 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -16,7 +16,7 @@ "@angular/common": "^19.0.0", "@angular/compiler": "^19.0.0", "@angular/core": "^18.0.1", - "@angular/forms": "^18.0.1", + "@angular/forms": "^19.0.1", "@angular/material": "^18.0.1", "@angular/platform-browser": "^18.0.1", "@angular/platform-browser-dynamic": "^19.0.0", From c2439c69bd854c18bc29f3f9b9dfbc156488b28a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 07:29:28 +0000 Subject: [PATCH 17/30] Bump @angular/compiler-cli from 18.2.13 to 19.0.1 in /web_embedding/ng-flutter (#2505) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@angular/compiler-cli](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli) from 18.2.13 to 19.0.1.
Release notes

Sourced from @​angular/compiler-cli's releases.

v19.0.1

19.0.1 (2024-11-26)

compiler-cli

Commit Description
fix - fb1fa8b0fc more accurate diagnostics for host binding parser errors (#58870)

core

Commit Description
fix - 502ee0e722 correctly clear template HMR internal renderer cache (#58724)
fix - 99715104a1 correctly perform lazy routes migration for components with additional decorators (#58796)
fix - 118803035f Ensure _tick is always run within the TracingSnapshot. (#58881)
fix - 08b9452f01 Ensure resource sets an error (#58855)
fix - 84f45ea3ff make component id generation more stable between client and server builds (#58813)
fix - d3491c7cee Prevents race condition of cleanup for incremental hydration (#58722)

forms

Commit Description
fix - 4dfe5b6cef work around TypeScript 5.7 issue (#58731)

language-service

Commit Description
fix - a983865bff add fix for individual unused imports (#58719)
fix - e6e7a4e22b allow fixes to run without template info (#58719)

migrations

Commit Description
fix - 5ce10264a4 fix provide-initializer migration when using useFactory (#58518)
fix - d4f5c85f60 handle parameters with initializers in inject migration (#58769)
fix - a6d2d2dc10 Mark hoisted properties as removed in inject migration (#58804)

v19.0.0

19.0.0 (2024-11-19)

Explore Angular v19 with a blog post from the Angular team: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84

Breaking Changes

compiler

  • this.foo property reads no longer refer to template context variables. If you intended to read the template variable, do not use this..

core

  • Angular directives, components and pipes are now standalone by default.

    • Specify standalone: false for declarations that are currently declared in @NgModules.
    • ng update for v19 will take care of this automatically.
  • TypeScript versions less than 5.5 are no longer supported.

  • Timing changes for effect API (in developer preview):

    • effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the

... (truncated)

Changelog

Sourced from @​angular/compiler-cli's changelog.

18.2.13 (2024-11-26)

migrations

Commit Type Description
06d70a25ea fix take care of tests that import both HttpClientModule & HttpClientTestingModule. (#58777)

19.1.0-next.0 (2024-11-26)

common

Commit Type Description
e4c50b3bea feat expose component instance in NgComponentOutlet (#58698)

core

Commit Type Description
bd1f1294ae feat support TypeScript 5.7 (#58609)

19.0.1 (2024-11-26)

compiler-cli

Commit Type Description
fb1fa8b0fc fix more accurate diagnostics for host binding parser errors (#58870)

core

Commit Type Description
502ee0e722 fix correctly clear template HMR internal renderer cache (#58724)
99715104a1 fix correctly perform lazy routes migration for components with additional decorators (#58796)
118803035f fix Ensure _tick is always run within the TracingSnapshot. (#58881)
08b9452f01 fix Ensure resource sets an error (#58855)
84f45ea3ff fix make component id generation more stable between client and server builds (#58813)
d3491c7cee fix Prevents race condition of cleanup for incremental hydration (#58722)

forms

Commit Type Description
4dfe5b6cef fix work around TypeScript 5.7 issue (#58731)

language-service

Commit Type Description
a983865bff fix add fix for individual unused imports (#58719)
e6e7a4e22b fix allow fixes to run without template info (#58719)

migrations

Commit Type Description
5ce10264a4 fix fix provide-initializer migration when using useFactory (#58518)
d4f5c85f60 fix handle parameters with initializers in inject migration (#58769)

... (truncated)

Commits
  • fb1fa8b fix(compiler-cli): more accurate diagnostics for host binding parser errors (...
  • 9971510 fix(core): correctly perform lazy routes migration for components with additi...
  • f503c15 refactor(compiler-cli): parse angularCompilerOptions from bazel options as ...
  • c570be3 refactor(compiler-cli): broaden type of getPotentialImportsFor (#58627)
  • 560282a fix(compiler): control flow nodes with root at the end projected incorrectly ...
  • 9bbb01c fix(compiler-cli): report individual diagnostics for unused imports (#58589)
  • c53ad70 refactor(migrations): support running existing migrations with plain TS progr...
  • 791ee32 fix(compiler-cli): correct extraction of generics from type aliases (#58548)
  • c4a8492 refactor(compiler-cli): Improved filterMethodOverloads to Include Members w...
  • 728bfbb refactor(migrations): speed up code refactoring action for queries (#58525)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/compiler-cli&package-manager=npm_and_yarn&previous-version=18.2.13&new-version=19.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index beaff561f..9720d5642 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -28,7 +28,7 @@ "devDependencies": { "@angular-devkit/build-angular": "^19.0.2", "@angular/cli": "~18.2.0", - "@angular/compiler-cli": "^18.0.1", + "@angular/compiler-cli": "^19.0.1", "@types/jasmine": "~5.1.0", "jasmine-core": "~5.4.0", "karma": "~6.4.2", From 5bea6f62f2a6ca1113153873f22e57b17bd148b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 07:55:28 +0000 Subject: [PATCH 18/30] Bump @angular/cli from 18.2.12 to 19.0.2 in /web_embedding/ng-flutter (#2504) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- Bumps [@angular/cli](https://github.com/angular/angular-cli) from 18.2.12 to 19.0.2.
Release notes

Sourced from @​angular/cli's releases.

v19.0.2

19.0.2 (2024-11-25)

@​schematics/angular

Commit Description
fix - 2f53e2af5 skip SSR routing prompt in webcontainer

@​angular/build

Commit Description
fix - f9da163f8 minimize reliance on esbuild inject to prevent code reordering
fix - c497749e6 prevent errors with parameterized routes when getPrerenderParams is undefined

@​angular/ssr

Commit Description
fix - c8cd90e0f handle nested redirects not explicitly defined in router config

v19.0.1

19.0.1 (2024-11-21)

@​angular-devkit/build-angular

Commit Description
fix - b63123f20 use stylePreprocessorOptions

@​angular/build

Commit Description
fix - 74461da64 ensure accurate content length for server assets
fix - 1b4dcedd5 use sha256 instead of sha-256 as hash algorithm name

@​angular/ssr

Commit Description
fix - 8bd2b260e handle baseHref that start with ./

v19.0.0

19.0.0 (2024-11-19)

@​angular/cli

Commit Description
feat - 201b60e1d handle string key/value pairs, e.g. --define
fix - b847d4460 recommend optional application update migration during v19 update
perf - f249e7e85 enable Node.js compile code cache when available
perf - ecc107d83 enable Node.js compile code cache when available

@​schematics/angular

Commit Description
feat - a381a3db1 add option to export component as default
feat - 755f3a07f add option to setup new workspace or application as zoneless mode
feat - cfca5442e integrate withEventReplay() in provideClientHydration for new SSR apps

... (truncated)

Changelog

Sourced from @​angular/cli's changelog.

19.0.2 (2024-11-25)

@​schematics/angular

Commit Type Description
2f53e2af5 fix skip SSR routing prompt in webcontainer

@​angular/build

Commit Type Description
f9da163f8 fix minimize reliance on esbuild inject to prevent code reordering
c497749e6 fix prevent errors with parameterized routes when getPrerenderParams is undefined

@​angular/ssr

Commit Type Description
c8cd90e0f fix handle nested redirects not explicitly defined in router config

19.0.1 (2024-11-21)

@​angular-devkit/build-angular

Commit Type Description
b63123f20 fix use stylePreprocessorOptions

@​angular/build

Commit Type Description
74461da64 fix ensure accurate content length for server assets
1b4dcedd5 fix use sha256 instead of sha-256 as hash algorithm name

@​angular/ssr

Commit Type Description
8bd2b260e fix handle baseHref that start with ./

... (truncated)

Commits
  • d261246 release: cut the v19.0.2 release
  • c497749 fix(@​angular/build): prevent errors with parameterized routes when `getPreren...
  • d8cbf3b refactor(@​angular/build): maintain previous compiler plugin factory signature
  • 2f53e2a fix(@​schematics/angular): skip SSR routing prompt in webcontainer
  • f9da163 fix(@​angular/build): minimize reliance on esbuild inject to prevent code re...
  • 5ac03f4 refactor(@​angular/ssr): use appRef.whenStable instead of util function from a...
  • 0eb5870 refactor(@​angular/ssr): replace :params with *
  • c8cd90e fix(@​angular/ssr): handle nested redirects not explicitly defined in router c...
  • 8cd6aa9 release: cut the v19.0.1 release
  • 1b4dced fix(@​angular/build): use sha256 instead of sha-256 as hash algorithm name
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/cli&package-manager=npm_and_yarn&previous-version=18.2.12&new-version=19.0.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 9720d5642..08d971e77 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -27,7 +27,7 @@ }, "devDependencies": { "@angular-devkit/build-angular": "^19.0.2", - "@angular/cli": "~18.2.0", + "@angular/cli": "~19.0.2", "@angular/compiler-cli": "^19.0.1", "@types/jasmine": "~5.1.0", "jasmine-core": "~5.4.0", From c5925c407d5614575595bde9e06dd47ad78d0138 Mon Sep 17 00:00:00 2001 From: Eric Windmill Date: Tue, 3 Dec 2024 13:07:36 -0500 Subject: [PATCH 19/30] Update readme, add changelog (#2535) Adds sample index to readme. Completes #2497 Completes #2536 ## Pre-launch Checklist - [x] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [x] I signed the [CLA]. - [x] I read the [Contributors Guide]. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] All existing and new tests are passing. --- .github/PULL_REQUEST_TEMPLATE.md | 6 +- CHANGELOG.md | 32 ++++++ README.md | 184 +++++++++++++++++++++++++++---- 3 files changed, 201 insertions(+), 21 deletions(-) create mode 100644 CHANGELOG.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b43254094..ae93fcaa8 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,8 +8,9 @@ reduce redundant work.* - [ ] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [ ] I signed the [CLA]. - [ ] I read the [Contributors Guide]. +- [ ] I have added sample code updates to the [changelog]. - [ ] I updated/added relevant documentation (doc comments with `///`). -- [ ] All existing and new tests are passing. + If you need help, consider asking for advice on the #hackers-devrel channel on [Discord]. @@ -17,4 +18,5 @@ If you need help, consider asking for advice on the #hackers-devrel channel on [ [Flutter Style Guide]: https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md [CLA]: https://cla.developers.google.com/ [Discord]: https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md -[Contributors Guide]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md \ No newline at end of file +[Contributors Guide]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md +[changelog]: ../CHANGELOG.md \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..7d8e5b733 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,32 @@ +# Changelog + +The purpose of this changelog is to track the freshness of samples and which +samples reflect *current best practices*. It describes **human-made, significant +** changes made to the repository or samples in the repository. + +While all samples in this repository build and run, some of them were written +long ago, and no longer reflect what we want developers to learn. For example, +samples should have been refactored when Dart 3 released to include patterns and +records, where appropriate. + +* **DO include:** + * The addition of new samples. + * The removal of existing samples. + * Considerable refactoring of any given sample. + +* **DO NOT include:** + * Simple changes that reflect minor version bumps in Flutter. For example, + in a recent Flutter update, `Color.red` became `Color.r`. + * Dependency updates. + * Bug fixes. + * Any changes made to simply 'keep the lights on'. + +# Log + +| DATE (YYYY-MM-DD) | Sample(s) | author | Changes | +|-------------------|-------------------|--------------|-----------------------------------------------| +| NEXT GOES HERE | | | | +| | | | | +| 2024-12-04 | N/A - repo change | ericwindmill | Added changelog | +| 2024-11-27 | fake_sample | ericwindmill | Refactored fake_sample to use Dart 3 features | +| 2020-04-17 | fake_sample | ericwindmill | Created fake_sample | diff --git a/README.md b/README.md index 854013835..b2fdcd257 100644 --- a/README.md +++ b/README.md @@ -3,26 +3,112 @@ [![Build Status](https://github.com/flutter/samples/workflows/Main%20Branch%20CI/badge.svg)](https://github.com/flutter/samples/actions?workflow=Main%20Branch%20CI) A collection of open source samples that illustrate best practices for -[Flutter](https://flutter.dev). - -## Visual samples index - -The easiest way to browse through the samples in this repo (as well as a few others!) -is the [visual samples index](https://flutter.github.io/samples). - -## Tip: minimize download size - -As this repository is quite big, you can use svn to download a single example. +[Flutter]. + +## Index + +### Quickstarts + +* [`asset_transformation`] - Demonstrates how to transform images' color scales and formats. +* [`background_isolate_channels`] - Demonstrates how to use long-lived isolates. +* [`code_sharing`] - Demonstrates how to share business logic between Flutter client and Dart server using [`package:shelf`] ) +* [`context_menus`] - This sample shows how to create and customize cross-platform context menus, such as the text selection toolbar on mobile or the right click menu on desktop. +* [`desktop_photo_search`] - Demonstrates desktop features in both Material and FluentUI design systems. +* [`dynamic_theme`] - A developer sample demonstrating how to call on-device Flutter APIs based on output from the Gemini API. +* [`form_app`] - A sample demonstrating different types of forms and best practices. +* [`game_template`] - (**note: deprecated!**) A starter game in Flutter with all the bells and whistles of a mobile (iOS & Android) game. +* [`gemini_tasks`] - A developer sample written in Flutter demonstrating how to interact with a to-do list in natural language using the Gemini API. +* [`google_maps`] - Demonstrates the Google Maps for Flutter plugin. +* [`infinite_list`] - A Flutter sample app that shows an implementation of the "infinite list" UX pattern. +* [`isolate_example`] - A sample application that demonstrate best practices when using [isolates]. +* [`navigation_and_routing`] - A sample that shows how to use [go_router] API to handle common navigation scenarios. +* [`place_tracker`] - A sample place tracking app that uses the [google_maps_flutter plugin]. +* [`platform_design`] - This sample project shows a Flutter app that maximizes application code reuse while adhering to different design patterns on Android and iOS. +* [`provider_counter`] - The starter Flutter application, but using [package:provider] to manage state. +* [`provider_shopper`] - A Flutter sample app that shows a state management approach using [package:provider]. +* [`simple_shader`] - A simple [Flutter fragment shaders] sample project. +* [`simplistic_calculator`] - A calculator to demonstrate a simple start for a desktop Flutter app. +* [`simplistic_editor`] - This sample text editor showcases the use of [TextEditingDeltas] and a DeltaTextInputClient to expand and contract styled ranges of text. +* [`testing_app`] - A sample app that shows different types of testing in Flutter. +* [`web_embedding`] - This directory contains examples of how to embed Flutter in web apps (without iframes). + * [`element_embedding_demo`] - Modifies the index.html of a flutter app so it is launched in a custom hostElement. This is the most basic embedding example. + * [`ng-flutter`] - A simple Angular app (and component) that replicates the above example, but in an Angular style. + +### Native platform samples + +* [`add-to-app`] - Collection of samples that demonstrate embedding Flutter a view into a native app. + * [`fullscreen`] — Embeds a full screen instance of + Flutter into an existing iOS or Android app. + * [`prebuilt_module`] — Embeds a full screen + instance of Flutter as a prebuilt library that can be loaded into an existing + iOS or Android app. + * [`plugin`] — Embeds a full screen Flutter instance that + is using plugins into an existing iOS or Android app. + * [`books`] — Mimics a real world use-case of embedding Flutter into an + existing Android app and demonstrates using [Pigeon] to communicate between Flutter and + the host application. + * [`multiple_flutters`] — Shows the usage of the Flutter + Engine Group APIs to embed multiple instances of Flutter into an existing app + with low memory cost. + * [`android_view`] — Shows how to integrate a Flutter + add-to-app module at a view level for Android. +* [`android_splash_screen`] +* [`ios_app_clip`] +* [`platform_channels`] - A sample app which demonstrates how to use MethodChannel, EventChannel, BasicMessageChannel and MessageCodec in Flutter. +* [`platform_view_swift`] - A Flutter sample app that combines a native iOS UIViewController with a full-screen Flutter view. + +### Demo galleries + +* [`animations`] - Showcases Flutter's animation features +* [`material_3_demo`] - showcases [Material 3] features in the Flutter Material library. + +### Demo apps + +* [`compass_app`] - A sample application that implements MVVM architecture. +* [`deeplink_store_example`] - A demo app that implements deep-linking with go_router. +* [`veggie_seasons`] - A demo application. + +## Flutter sample code + +Samples are **correct and concise code** that developers +can **quickly understand** and **easily reuse** with minimal side effects. +Samples teach developers how to be successful using Flutter and Dart. +They are maintained on an ongoing basis +to reflect changing APIs and best practices. + +### Types of samples + +There are two types of sample code in this repository: + +* **Quickstarts** provide a starting point to extend. They answer the question, + "What is the minimal amount of code needed to implement this feature?" +* **Demo apps** are meant to be built and ran. They demo the _product_, + not how to write code. + +A majority of samples in this repository are quickstarts. + +## Usage + +Every sample in this repo is fully runnable. To run an example, +use `flutter run` inside that example's directory. +See the [getting started guide] to install the `flutter` tool. + +> [!IMPORTANT] +> If you want to run an add-to-app sample, there are additional requirements. +> We suggest reading the [add-to-app documentation]. + +### Tip: minimize download size + +As this repository is quite big, you can use +[svn] to download a single example. For example: ``` svn co https://github.com/flutter/samples/trunk/provider_shopper ``` -You can also use a -[partial clone](https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/) -to skip blob objects that aren't currently checked out, -while including the full commit history: +You can also use a [partial clone] to skip blob objects +that aren't currently checked out, while including the full commit history: ``` git clone --filter=blob:none https://github.com/flutter/samples.git @@ -30,16 +116,76 @@ git clone --filter=blob:none https://github.com/flutter/samples.git ## Interested in contributing? -See the [contributor's guide](CONTRIBUTING.md)! +See the [contributor's guide]! ## Questions or issues? If you have a general question about one of these samples or how to adapt its techniques for one of your own apps, try one of these resources: -* [The FlutterDev Discord](https://discord.gg/rflutterdev) -* [StackOverflow](https://stackoverflow.com/questions/tagged/flutter) +* [The FlutterDev Discord] +* [The Flutter Community forum] If you run into a bug in one of the samples, please file an issue in the -[`flutter/samples` issue tracker](https://github.com/flutter/samples/issues). - +[`flutter/samples` issue tracker]. + + +[`asset_transformation`]: ./asset_transformation +[`background_isolate_channels`]: ./background_isolate_channels +[`code_sharing`]: ./code_sharing +[`context_menus`]: ./context_menus +[`desktop_photo_search`]: ./desktop_photo_search +[`dynamic_theme`]: ./dynamic_theme +[`form_app`]: ./form_app +[`game_template`]: ./game_template +[`gemini_tasks`]: ./gemini_tasks +[`google_maps`]: ./google_maps +[`infinite_list`]: ./infinite_list +[`isolate_example`]: ./isolate_example +[`navigation_and_routing`]: ./navigation_and_routing +[`place_tracker`]: ./place_tracker +[`platform_design`]: ./platform_design +[`provider_counter`]: ./provider_counter +[`provider_shopper`]: ./provider_shopper +[`simple_shader`]: ./simple_shader +[`simplistic_calculator`]: ./simplistic_calculator +[`simplistic_editor`]: ./simplistic_editor +[`testing_app`]: ./testing_app +[`web_embedding`]: ./web_embedding +[`element_embedding_demo`]: ./web_embedding/element_embedding_demo +[`ng-flutter`]: ./web_embedding/ng-flutter +[`add-to-app`]: ./add_to_app +[`fullscreen`]: ./add_to_app/fullscreen +[`prebuilt_module`]: ./add_to_app/prebuilt_module +[`plugin`]: ./add_to_app/plugin +[`books`]: ./add_to_app/books +[`multiple_flutters`]: ./add_to_app/multiple_flutters +[`android_view`]: ./add_to_app/android_view +[`android_splash_screen`]: ./android_splash_screen +[`ios_app_clip`]: ./ios_app_clip +[`platform_channels`]: ./platform_channels +[`platform_view_swift`]: ./platform_view_swift +[`animations`]: ./animations +[`material_3_demo`]: ./material_3_demo +[`compass_app`]: ./compass_app +[`deeplink_store_example`]: ./deeplink_store_example +[`veggie_seasons`]: ./veggieseasons + +[Flutter]: https://flutter.dev +[getting started guide]: https://docs.flutter.dev/get-started/install +[add-to-app documentation]: https://docs.flutter.dev/add-to-app +[isolates]: https://api.dart.dev/dart-isolate/Isolate-class.html +[Material 3]: https://m3.material.io +[go_router]: https://pub.dev/packages/go_router +[google_maps_flutter plugin]: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter +[package:provider]: https://pub.dev/packages/provider +[Flutter fragment shaders]: https://docs.flutter.dev/development/ui/advanced/shaders +[TextEditingDeltas]: https://api.flutter.dev/flutter/services/TextEditingDelta-class.html +[Pigeon]: https://pub.dev/packages/pigeon +[`package:shelf`]: https://pub.dev/packages/shelf +[svn]: https://subversion.apache.org/ +[partial clone]: https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/ +[contributing guide]: CONTRIBUTING.md +[The FlutterDev Discord]: https://discord.gg/rflutterdev +[The Flutter Community forum]: https://forum.itsallwidgets.com/latest +[`flutter/samples` issue tracker]: https://github.com/flutter/samples/issues From 33701ce1c593b7071f0c33ad1221e96b5e818ab5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 07:25:14 +0000 Subject: [PATCH 20/30] Bump subosito/flutter-action from 2.17.0 to 2.18.0 (#2537) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [subosito/flutter-action](https://github.com/subosito/flutter-action) from 2.17.0 to 2.18.0.
Release notes

Sourced from subosito/flutter-action's releases.

v2.18.0

What's Changed

New Contributors

Full Changelog: https://github.com/subosito/flutter-action/compare/v2.17.0...v2.18.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=subosito/flutter-action&package-manager=github_actions&previous-version=2.17.0&new-version=2.18.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .github/workflows/beta.yml | 6 +++--- .github/workflows/gh-pages.yml | 2 +- .github/workflows/main.yml | 8 ++++---- .github/workflows/verify-web-demos.yml | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml index 1352a3b5d..b2484eaf4 100644 --- a/.github/workflows/beta.yml +++ b/.github/workflows/beta.yml @@ -31,7 +31,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff with: channel: beta - run: ./tool/flutter_ci_script_stable.sh @@ -47,7 +47,7 @@ jobs: # with: # distribution: 'zulu' # java-version: '17' - # - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 + # - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff # with: # channel: beta # - run: ./tool/android_ci_script.sh @@ -63,7 +63,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff with: channel: beta - run: ./tool/ios_ci_script.sh diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 8f98c7a74..76cbe1e07 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -21,7 +21,7 @@ jobs: submodules: true fetch-depth: 0 - - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff - name: Init scripts run: dart pub get diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b0ce27019..ba65d80a2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,7 +32,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff with: channel: ${{ matrix.flutter_version }} - run: ./tool/flutter_ci_script_${{ matrix.flutter_version }}.sh @@ -42,7 +42,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff - run: | dart pub get dart run grinder generate @@ -57,7 +57,7 @@ jobs: # with: # distribution: 'zulu' # java-version: '17' - # - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 + # - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff # with: # channel: stable # - run: ./tool/android_ci_script.sh @@ -71,7 +71,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff with: channel: stable - run: ./tool/ios_ci_script.sh diff --git a/.github/workflows/verify-web-demos.yml b/.github/workflows/verify-web-demos.yml index 0a11de3a3..8a1e92650 100644 --- a/.github/workflows/verify-web-demos.yml +++ b/.github/workflows/verify-web-demos.yml @@ -25,7 +25,7 @@ jobs: with: submodules: true fetch-depth: 0 - - uses: subosito/flutter-action@74af56c5ed2697ba4621264652728e8d217e53d3 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff with: channel: ${{ matrix.flutter_version }} - name: Init scripts From c3c93a82f5af47e7b95a58f62cf027cf70578ba9 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 5 Dec 2024 21:38:14 +0800 Subject: [PATCH 21/30] [compass_app] Standardize on `Result` factories rather than constructors (#2538) From my review of the recipes PR in https://github.com/flutter/website/pull/11444#pullrequestreview-2480423811. --- .../repositories/auth/auth_repository_dev.dart | 4 ++-- .../booking/booking_repository_local.dart | 4 ++-- .../itinerary_config_repository_memory.dart | 2 +- .../app/lib/data/services/api/api_client.dart | 18 +++++++++--------- .../lib/data/services/api/auth_api_client.dart | 2 +- .../services/shared_preferences_service.dart | 2 +- .../booking/booking_create_use_case.dart | 2 +- .../booking/booking_share_use_case.dart | 2 +- .../booking/view_models/booking_viewmodel.dart | 2 +- compass_app/app/lib/utils/result.dart | 12 ++++++------ .../fakes/services/fake_auth_api_client.dart | 2 +- 11 files changed, 26 insertions(+), 26 deletions(-) diff --git a/compass_app/app/lib/data/repositories/auth/auth_repository_dev.dart b/compass_app/app/lib/data/repositories/auth/auth_repository_dev.dart index 5c56b9621..aba56512f 100644 --- a/compass_app/app/lib/data/repositories/auth/auth_repository_dev.dart +++ b/compass_app/app/lib/data/repositories/auth/auth_repository_dev.dart @@ -16,12 +16,12 @@ class AuthRepositoryDev extends AuthRepository { required String email, required String password, }) async { - return Result.ok(null); + return const Result.ok(null); } /// Logout is always successful in dev scenarios @override Future> logout() async { - return Result.ok(null); + return const Result.ok(null); } } diff --git a/compass_app/app/lib/data/repositories/booking/booking_repository_local.dart b/compass_app/app/lib/data/repositories/booking/booking_repository_local.dart index 4a340d7c2..a41660257 100644 --- a/compass_app/app/lib/data/repositories/booking/booking_repository_local.dart +++ b/compass_app/app/lib/data/repositories/booking/booking_repository_local.dart @@ -31,7 +31,7 @@ class BookingRepositoryLocal implements BookingRepository { // Bookings created come without id, we need to assign one final bookingWithId = booking.copyWith(id: _sequentialId++); _bookings.add(bookingWithId); - return Result.ok(null); + return const Result.ok(null); } @override @@ -92,6 +92,6 @@ class BookingRepositoryLocal implements BookingRepository { @override Future> delete(int id) async { _bookings.removeWhere((booking) => booking.id == id); - return Result.ok(null); + return const Result.ok(null); } } diff --git a/compass_app/app/lib/data/repositories/itinerary_config/itinerary_config_repository_memory.dart b/compass_app/app/lib/data/repositories/itinerary_config/itinerary_config_repository_memory.dart index 5bd9cc0d5..c819c7fef 100644 --- a/compass_app/app/lib/data/repositories/itinerary_config/itinerary_config_repository_memory.dart +++ b/compass_app/app/lib/data/repositories/itinerary_config/itinerary_config_repository_memory.dart @@ -22,6 +22,6 @@ class ItineraryConfigRepositoryMemory implements ItineraryConfigRepository { ItineraryConfig itineraryConfig, ) async { _itineraryConfig = itineraryConfig; - return Result.ok(true); + return const Result.ok(true); } } diff --git a/compass_app/app/lib/data/services/api/api_client.dart b/compass_app/app/lib/data/services/api/api_client.dart index 58f2d7a0a..5068c443b 100644 --- a/compass_app/app/lib/data/services/api/api_client.dart +++ b/compass_app/app/lib/data/services/api/api_client.dart @@ -53,7 +53,7 @@ class ApiClient { return Result.ok( json.map((element) => Continent.fromJson(element)).toList()); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -74,7 +74,7 @@ class ApiClient { return Result.ok( json.map((element) => Destination.fromJson(element)).toList()); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -97,7 +97,7 @@ class ApiClient { json.map((element) => Activity.fromJson(element)).toList(); return Result.ok(activities); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -119,7 +119,7 @@ class ApiClient { json.map((element) => BookingApiModel.fromJson(element)).toList(); return Result.ok(bookings); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -139,7 +139,7 @@ class ApiClient { final booking = BookingApiModel.fromJson(jsonDecode(stringData)); return Result.ok(booking); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -160,7 +160,7 @@ class ApiClient { final booking = BookingApiModel.fromJson(jsonDecode(stringData)); return Result.ok(booking); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -180,7 +180,7 @@ class ApiClient { final user = UserApiModel.fromJson(jsonDecode(stringData)); return Result.ok(user); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -197,9 +197,9 @@ class ApiClient { final response = await request.close(); // Response 204 "No Content", delete was successful if (response.statusCode == 204) { - return Result.ok(null); + return const Result.ok(null); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); diff --git a/compass_app/app/lib/data/services/api/auth_api_client.dart b/compass_app/app/lib/data/services/api/auth_api_client.dart index 7c2191b46..89e309674 100644 --- a/compass_app/app/lib/data/services/api/auth_api_client.dart +++ b/compass_app/app/lib/data/services/api/auth_api_client.dart @@ -32,7 +32,7 @@ class AuthApiClient { final stringData = await response.transform(utf8.decoder).join(); return Result.ok(LoginResponse.fromJson(jsonDecode(stringData))); } else { - return Result.error(const HttpException("Login error")); + return const Result.error(HttpException("Login error")); } } on Exception catch (error) { return Result.error(error); diff --git a/compass_app/app/lib/data/services/shared_preferences_service.dart b/compass_app/app/lib/data/services/shared_preferences_service.dart index 05a684601..24a67a9b5 100644 --- a/compass_app/app/lib/data/services/shared_preferences_service.dart +++ b/compass_app/app/lib/data/services/shared_preferences_service.dart @@ -32,7 +32,7 @@ class SharedPreferencesService { _log.finer('Replaced token'); await sharedPreferences.setString(_tokenKey, token); } - return Result.ok(null); + return const Result.ok(null); } on Exception catch (e) { _log.warning('Failed to set token', e); return Result.error(e); diff --git a/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart b/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart index eff951159..4b750f0a3 100644 --- a/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart +++ b/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart @@ -98,7 +98,7 @@ class BookingCreateUseCase { case Ok>(): final destination = result.value .firstWhere((destination) => destination.ref == destinationRef); - return Ok(destination); + return Result.ok(destination); case Error>(): return Result.error(result.error); } diff --git a/compass_app/app/lib/domain/use_cases/booking/booking_share_use_case.dart b/compass_app/app/lib/domain/use_cases/booking/booking_share_use_case.dart index cff2f852b..b7d66f0c7 100644 --- a/compass_app/app/lib/domain/use_cases/booking/booking_share_use_case.dart +++ b/compass_app/app/lib/domain/use_cases/booking/booking_share_use_case.dart @@ -37,7 +37,7 @@ class BookingShareUseCase { try { await _share(text); _log.fine('Shared booking'); - return Result.ok(null); + return const Result.ok(null); } on Exception catch (error) { _log.severe('Failed to share booking', error); return Result.error(error); diff --git a/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart b/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart index c2e44ead6..725d478eb 100644 --- a/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart +++ b/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart @@ -61,7 +61,7 @@ class BookingViewModel extends ChangeNotifier { _log.fine('Created Booking'); _booking = result.value; notifyListeners(); - return Result.ok(null); + return const Result.ok(null); case Error(): _log.warning('Booking error: ${result.error}'); notifyListeners(); diff --git a/compass_app/app/lib/utils/result.dart b/compass_app/app/lib/utils/result.dart index 5370700b0..8512963e4 100644 --- a/compass_app/app/lib/utils/result.dart +++ b/compass_app/app/lib/utils/result.dart @@ -18,11 +18,11 @@ sealed class Result { const Result(); - /// Creates an instance of Result containing a value - factory Result.ok(T value) => Ok(value); + /// Creates a successful [Result], completed with the specified [value]. + const factory Result.ok(T value) = Ok._; - /// Create an instance of Result containing an error - factory Result.error(Exception error) => Error(error); + /// Creates an error [Result], completed with the specified [error]. + const factory Result.error(Exception error) = Error._; /// Convenience method to cast to Ok Ok get asOk => this as Ok; @@ -33,7 +33,7 @@ sealed class Result { /// Subclass of Result for values final class Ok extends Result { - const Ok(this.value); + const Ok._(this.value); /// Returned value in result final T value; @@ -44,7 +44,7 @@ final class Ok extends Result { /// Subclass of Result for errors final class Error extends Result { - const Error(this.error); + const Error._(this.error); /// Returned error in result final Exception error; diff --git a/compass_app/app/testing/fakes/services/fake_auth_api_client.dart b/compass_app/app/testing/fakes/services/fake_auth_api_client.dart index 714e2e7c3..af4ea340c 100644 --- a/compass_app/app/testing/fakes/services/fake_auth_api_client.dart +++ b/compass_app/app/testing/fakes/services/fake_auth_api_client.dart @@ -11,7 +11,7 @@ class FakeAuthApiClient implements AuthApiClient { @override Future> login(LoginRequest loginRequest) async { if (loginRequest.email == 'EMAIL' && loginRequest.password == 'PASSWORD') { - return Result.ok(const LoginResponse(token: 'TOKEN', userId: '123')); + return const Result.ok(LoginResponse(token: 'TOKEN', userId: '123')); } return Result.error(Exception('ERROR!')); } From 754ddf0375194dbb81e7965ba4b4c4e726e8b9c6 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 5 Dec 2024 21:38:44 +0800 Subject: [PATCH 22/30] [compass_app/server] Misc consistency improvements (#2539) --- compass_app/server/lib/routes/booking.dart | 2 +- compass_app/server/lib/routes/login.dart | 2 +- compass_app/server/lib/routes/user.dart | 3 ++- compass_app/server/pubspec.yaml | 2 +- compass_app/server/test/server_test.dart | 6 +++--- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/compass_app/server/lib/routes/booking.dart b/compass_app/server/lib/routes/booking.dart index 90519c41d..83941bfc2 100644 --- a/compass_app/server/lib/routes/booking.dart +++ b/compass_app/server/lib/routes/booking.dart @@ -22,7 +22,7 @@ import '../model/booking/booking.dart'; class BookingApi { BookingApi() { // Create a default booking - var destination = Assets.destinations.first; + final destination = Assets.destinations.first; final activitiesRef = Assets.activities .where((activity) => activity.destinationRef == destination.ref) .map((activity) => activity.ref) diff --git a/compass_app/server/lib/routes/login.dart b/compass_app/server/lib/routes/login.dart index f5939fe77..35b3473b6 100644 --- a/compass_app/server/lib/routes/login.dart +++ b/compass_app/server/lib/routes/login.dart @@ -4,10 +4,10 @@ import 'dart:convert'; -import 'package:compass_server/config/constants.dart'; import 'package:shelf/shelf.dart'; import 'package:shelf_router/shelf_router.dart'; +import '../config/constants.dart'; import '../model/login_request/login_request.dart'; import '../model/login_response/login_response.dart'; diff --git a/compass_app/server/lib/routes/user.dart b/compass_app/server/lib/routes/user.dart index 534d8f8ff..045442e1f 100644 --- a/compass_app/server/lib/routes/user.dart +++ b/compass_app/server/lib/routes/user.dart @@ -4,10 +4,11 @@ import 'dart:convert'; -import 'package:compass_server/config/constants.dart'; import 'package:shelf/shelf.dart'; import 'package:shelf_router/shelf_router.dart'; +import '../config/constants.dart'; + /// Implements a simple user API. /// /// This API only returns a hardcoded user for demonstration purposes. diff --git a/compass_app/server/pubspec.yaml b/compass_app/server/pubspec.yaml index ba47e5e9d..2cb38cff4 100644 --- a/compass_app/server/pubspec.yaml +++ b/compass_app/server/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: dev_dependencies: http: ^1.1.0 - lints: ^3.0.0 + lints: ^5.0.0 test: ^1.24.0 build_runner: ^2.4.11 freezed: ^2.5.7 diff --git a/compass_app/server/test/server_test.dart b/compass_app/server/test/server_test.dart index 20140d9f1..2020a9519 100644 --- a/compass_app/server/test/server_test.dart +++ b/compass_app/server/test/server_test.dart @@ -21,7 +21,7 @@ void main() { final host = 'http://127.0.0.1:$port'; late Process p; - var headers = { + final headers = { 'Authorization': 'Bearer ${Constants.token}', }; @@ -116,7 +116,7 @@ void main() { headers: headers, body: jsonEncode( Booking( - name: "DESTINATION, CONTINENT", + name: 'DESTINATION, CONTINENT', startDate: DateTime(2024, 1, 1), endDate: DateTime(2024, 2, 2), destinationRef: 'REF', @@ -139,7 +139,7 @@ void main() { headers: headers, body: jsonEncode( Booking( - name: "DESTINATION, CONTINENT", + name: 'DESTINATION, CONTINENT', startDate: DateTime(2024, 1, 1), endDate: DateTime(2024, 2, 2), destinationRef: 'REF', From 90cd385ef47548dcb7720781e805d5156a710604 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 5 Dec 2024 21:39:19 +0800 Subject: [PATCH 23/30] [compass_app] Mark classes used for namespacing as `abstract final` (#2540) As they are just used for namespacing static properties, these classes shouldn't be extended, implemented, or instantiated. --- compass_app/app/lib/config/assets.dart | 2 +- compass_app/app/lib/routing/routes.dart | 2 +- compass_app/app/lib/ui/core/themes/colors.dart | 2 +- compass_app/app/lib/ui/core/themes/theme.dart | 2 +- compass_app/server/lib/config/assets.dart | 2 +- compass_app/server/lib/config/constants.dart | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compass_app/app/lib/config/assets.dart b/compass_app/app/lib/config/assets.dart index b60059e0a..cbbbc4ed1 100644 --- a/compass_app/app/lib/config/assets.dart +++ b/compass_app/app/lib/config/assets.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -class Assets { +abstract final class Assets { static const activities = 'assets/activities.json'; static const destinations = 'assets/destinations.json'; } diff --git a/compass_app/app/lib/routing/routes.dart b/compass_app/app/lib/routing/routes.dart index bba607532..86ea0b789 100644 --- a/compass_app/app/lib/routing/routes.dart +++ b/compass_app/app/lib/routing/routes.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -class Routes { +abstract final class Routes { static const home = '/'; static const login = '/login'; static const search = '/$searchRelative'; diff --git a/compass_app/app/lib/ui/core/themes/colors.dart b/compass_app/app/lib/ui/core/themes/colors.dart index 9e42e36ec..8c98c8c70 100644 --- a/compass_app/app/lib/ui/core/themes/colors.dart +++ b/compass_app/app/lib/ui/core/themes/colors.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; -class AppColors { +abstract final class AppColors { static const black1 = Color(0xFF101010); static const white1 = Color(0xFFFFF7FA); static const grey1 = Color(0xFFF2F2F2); diff --git a/compass_app/app/lib/ui/core/themes/theme.dart b/compass_app/app/lib/ui/core/themes/theme.dart index 34ae0c989..98483bcfc 100644 --- a/compass_app/app/lib/ui/core/themes/theme.dart +++ b/compass_app/app/lib/ui/core/themes/theme.dart @@ -6,7 +6,7 @@ import 'colors.dart'; import '../ui/tag_chip.dart'; import 'package:flutter/material.dart'; -class AppTheme { +abstract final class AppTheme { static const _textTheme = TextTheme( headlineLarge: TextStyle( fontSize: 32, diff --git a/compass_app/server/lib/config/assets.dart b/compass_app/server/lib/config/assets.dart index 6ee55cf86..e2bec536d 100644 --- a/compass_app/server/lib/config/assets.dart +++ b/compass_app/server/lib/config/assets.dart @@ -8,7 +8,7 @@ import 'dart:io'; import '../model/activity/activity.dart'; import '../model/destination/destination.dart'; -class Assets { +abstract final class Assets { static const _activities = '../app/assets/activities.json'; static const _destinations = '../app/assets/destinations.json'; diff --git a/compass_app/server/lib/config/constants.dart b/compass_app/server/lib/config/constants.dart index 60f35b40d..a3cc6d67d 100644 --- a/compass_app/server/lib/config/constants.dart +++ b/compass_app/server/lib/config/constants.dart @@ -4,7 +4,7 @@ import '../model/user/user.dart'; -class Constants { +abstract final class Constants { /// Email for the hardcoded login. static const email = 'email@example.com'; From 5adcda364082294c2432f1454063b818dcdba311 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 5 Dec 2024 21:39:35 +0800 Subject: [PATCH 24/30] [compass_app] Don't expose Dimens subclasses (#2541) Avoid exposing the subclasses as they shouldn't be instantiated again or overridden. Also consistently use fields and getters in the declarations. --- .../app/lib/ui/core/themes/dimens.dart | 34 +++++++++---------- .../ui/results/widgets/results_screen.dart | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/compass_app/app/lib/ui/core/themes/dimens.dart b/compass_app/app/lib/ui/core/themes/dimens.dart index c2c895ae8..d665bcc4c 100644 --- a/compass_app/app/lib/ui/core/themes/dimens.dart +++ b/compass_app/app/lib/ui/core/themes/dimens.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; -sealed class Dimens { +abstract final class Dimens { const Dimens(); /// General horizontal padding used to separate UI items @@ -14,10 +14,12 @@ sealed class Dimens { static const paddingVertical = 24.0; /// Horizontal padding for screen edges - abstract final double paddingScreenHorizontal; + double get paddingScreenHorizontal; /// Vertical padding for screen edges - abstract final double paddingScreenVertical; + double get paddingScreenVertical; + + double get profilePictureSize; /// Horizontal symmetric padding for screen edges EdgeInsets get edgeInsetsScreenHorizontal => @@ -27,39 +29,37 @@ sealed class Dimens { EdgeInsets get edgeInsetsScreenSymmetric => EdgeInsets.symmetric( horizontal: paddingScreenHorizontal, vertical: paddingScreenVertical); - static final dimensDesktop = DimensDesktop(); - static final dimensMobile = DimensMobile(); + static final Dimens desktop = _DimensDesktop(); + static final Dimens mobile = _DimensMobile(); /// Get dimensions definition based on screen size factory Dimens.of(BuildContext context) => switch (MediaQuery.sizeOf(context).width) { - > 600 => dimensDesktop, - _ => dimensMobile, + > 600 => desktop, + _ => mobile, }; - - abstract final double profilePictureSize; } /// Mobile dimensions -class DimensMobile extends Dimens { +final class _DimensMobile extends Dimens { @override - double paddingScreenHorizontal = Dimens.paddingHorizontal; + final double paddingScreenHorizontal = Dimens.paddingHorizontal; @override - double paddingScreenVertical = Dimens.paddingVertical; + final double paddingScreenVertical = Dimens.paddingVertical; @override - double get profilePictureSize => 64.0; + final double profilePictureSize = 64.0; } /// Desktop/Web dimensions -class DimensDesktop extends Dimens { +final class _DimensDesktop extends Dimens { @override - double paddingScreenHorizontal = 100.0; + final double paddingScreenHorizontal = 100.0; @override - double paddingScreenVertical = 64.0; + final double paddingScreenVertical = 64.0; @override - double get profilePictureSize => 128.0; + final double profilePictureSize = 128.0; } diff --git a/compass_app/app/lib/ui/results/widgets/results_screen.dart b/compass_app/app/lib/ui/results/widgets/results_screen.dart index cbe9778a5..2a93bcd40 100644 --- a/compass_app/app/lib/ui/results/widgets/results_screen.dart +++ b/compass_app/app/lib/ui/results/widgets/results_screen.dart @@ -132,7 +132,7 @@ class _AppSearchBar extends StatelessWidget { child: Padding( padding: EdgeInsets.only( top: Dimens.of(context).paddingScreenVertical, - bottom: Dimens.dimensMobile.paddingScreenVertical, + bottom: Dimens.mobile.paddingScreenVertical, ), child: AppSearchBar( config: widget.viewModel.config, From 57ecb5f7ba97704754c4d110497ec084f5d46f46 Mon Sep 17 00:00:00 2001 From: Miguel Beltran Date: Thu, 5 Dec 2024 19:16:04 +0100 Subject: [PATCH 25/30] refactor Result class, remove asOk and asError (#2542) As discussed in the PR for the Result pattern implementation (https://github.com/flutter/website/pull/11444) @parlough recommended that `asError` and `asOk` should be not be used, and instead we should use proper exhaustiveness checking. This PR removes the two "convenience" methods and refactors code. In some cases, it was enough with writing a proper `if` clause, while in others it was necessary to use a `switch`. Still, they are present in the `testing` folder, as they can be useful for testing purposes. ## Pre-launch Checklist - [x] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [x] I signed the [CLA]. - [x] I read the [Contributors Guide]. - [x] I have added sample code updates to the [changelog]. - [x] I updated/added relevant documentation (doc comments with `///`). If you need help, consider asking for advice on the #hackers-devrel channel on [Discord]. [Flutter Style Guide]: https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md [CLA]: https://cla.developers.google.com/ [Discord]: https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md [Contributors Guide]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md [changelog]: ../CHANGELOG.md --- .../activity/activity_repository_remote.dart | 4 +- .../booking/booking_repository_remote.dart | 53 +++++++++++-------- .../continent_repository_remote.dart | 4 +- .../destination_repository_remote.dart | 4 +- .../booking/booking_create_use_case.dart | 22 ++++---- .../view_models/activities_viewmodel.dart | 37 +++++++------ .../view_models/booking_viewmodel.dart | 2 +- .../view_models/results_viewmodel.dart | 34 ++++++------ .../view_models/search_form_viewmodel.dart | 44 +++++++-------- compass_app/app/lib/utils/result.dart | 6 --- .../activity_repository_local_test.dart | 2 + .../activity_repository_remote_test.dart | 1 + .../booking_repository_remote_test.dart | 1 + .../continent_repository_remote_test.dart | 1 + .../destination_repository_local_test.dart | 2 + .../destination_repository_remote_test.dart | 1 + .../data/services/api/api_client_test.dart | 1 + .../services/api/auth_api_client_test.dart | 1 + .../booking/booking_create_use_case_test.dart | 1 + compass_app/app/test/utils/command_test.dart | 4 +- compass_app/app/testing/utils/result.dart | 9 ++++ 21 files changed, 131 insertions(+), 103 deletions(-) create mode 100644 compass_app/app/testing/utils/result.dart diff --git a/compass_app/app/lib/data/repositories/activity/activity_repository_remote.dart b/compass_app/app/lib/data/repositories/activity/activity_repository_remote.dart index 6d2d0bcc5..be7ce02c6 100644 --- a/compass_app/app/lib/data/repositories/activity/activity_repository_remote.dart +++ b/compass_app/app/lib/data/repositories/activity/activity_repository_remote.dart @@ -24,8 +24,8 @@ class ActivityRepositoryRemote implements ActivityRepository { if (!_cachedData.containsKey(ref)) { // No cached data, request activities final result = await _apiClient.getActivityByDestination(ref); - if (result is Ok) { - _cachedData[ref] = result.asOk.value; + if (result is Ok>) { + _cachedData[ref] = result.value; } return result; } else { diff --git a/compass_app/app/lib/data/repositories/booking/booking_repository_remote.dart b/compass_app/app/lib/data/repositories/booking/booking_repository_remote.dart index 1ac1cd7cd..cdb66b86d 100644 --- a/compass_app/app/lib/data/repositories/booking/booking_repository_remote.dart +++ b/compass_app/app/lib/data/repositories/booking/booking_repository_remote.dart @@ -42,18 +42,22 @@ class BookingRepositoryRemote implements BookingRepository { try { // Get booking by ID from server final resultBooking = await _apiClient.getBooking(id); - if (resultBooking is Error) { - return Result.error(resultBooking.error); + switch (resultBooking) { + case Error(): + return Result.error(resultBooking.error); + case Ok(): } - final booking = resultBooking.asOk.value; + final booking = resultBooking.value; // Load destinations if not loaded yet if (_cachedDestinations == null) { final resultDestination = await _apiClient.getDestinations(); - if (resultDestination is Error>) { - return Result.error(resultDestination.error); + switch (resultDestination) { + case Error>(): + return Result.error(resultDestination.error); + case Ok>(): } - _cachedDestinations = resultDestination.asOk.value; + _cachedDestinations = resultDestination.value; } // Get destination for booking @@ -62,11 +66,12 @@ class BookingRepositoryRemote implements BookingRepository { final resultActivities = await _apiClient.getActivityByDestination(destination.ref); - - if (resultActivities is Error>) { - return Result.error(resultActivities.error); + switch (resultActivities) { + case Error>(): + return Result.error(resultActivities.error); + case Ok>(): } - final activities = resultActivities.asOk.value + final activities = resultActivities.value .where((activity) => booking.activitiesRef.contains(activity.ref)) .toList(); @@ -88,20 +93,22 @@ class BookingRepositoryRemote implements BookingRepository { Future>> getBookingsList() async { try { final result = await _apiClient.getBookings(); - if (result is Error>) { - return Result.error(result.error); + switch (result) { + case Ok>(): + final bookingsApi = result.value; + return Result.ok(bookingsApi + .map( + (bookingApi) => BookingSummary( + id: bookingApi.id!, + name: bookingApi.name, + startDate: bookingApi.startDate, + endDate: bookingApi.endDate, + ), + ) + .toList()); + case Error>(): + return Result.error(result.error); } - final bookingsApi = result.asOk.value; - return Result.ok(bookingsApi - .map( - (bookingApi) => BookingSummary( - id: bookingApi.id!, - name: bookingApi.name, - startDate: bookingApi.startDate, - endDate: bookingApi.endDate, - ), - ) - .toList()); } on Exception catch (e) { return Result.error(e); } diff --git a/compass_app/app/lib/data/repositories/continent/continent_repository_remote.dart b/compass_app/app/lib/data/repositories/continent/continent_repository_remote.dart index 58a6e439e..a9b32f686 100644 --- a/compass_app/app/lib/data/repositories/continent/continent_repository_remote.dart +++ b/compass_app/app/lib/data/repositories/continent/continent_repository_remote.dart @@ -24,9 +24,9 @@ class ContinentRepositoryRemote implements ContinentRepository { if (_cachedData == null) { // No cached data, request continents final result = await _apiClient.getContinents(); - if (result is Ok) { + if (result is Ok>) { // Store value if result Ok - _cachedData = result.asOk.value; + _cachedData = result.value; } return result; } else { diff --git a/compass_app/app/lib/data/repositories/destination/destination_repository_remote.dart b/compass_app/app/lib/data/repositories/destination/destination_repository_remote.dart index 191b2a6ed..a2357ba90 100644 --- a/compass_app/app/lib/data/repositories/destination/destination_repository_remote.dart +++ b/compass_app/app/lib/data/repositories/destination/destination_repository_remote.dart @@ -24,9 +24,9 @@ class DestinationRepositoryRemote implements DestinationRepository { if (_cachedData == null) { // No cached data, request destinations final result = await _apiClient.getDestinations(); - if (result is Ok) { + if (result is Ok>) { // Store value if result Ok - _cachedData = result.asOk.value; + _cachedData = result.value; } return result; } else { diff --git a/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart b/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart index 4b750f0a3..001ed7fc1 100644 --- a/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart +++ b/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart @@ -40,11 +40,13 @@ class BookingCreateUseCase { } final destinationResult = await _fetchDestination(itineraryConfig.destination!); - if (destinationResult is Error) { - _log.warning('Error fetching destination: ${destinationResult.error}'); - return Result.error(destinationResult.error); + switch (destinationResult) { + case Ok(): + _log.fine('Destination loaded: ${destinationResult.value.ref}'); + case Error(): + _log.warning('Error fetching destination: ${destinationResult.error}'); + return Result.error(destinationResult.error); } - _log.fine('Destination loaded: ${destinationResult.asOk.value.ref}'); // Get Activity objects from repository if (itineraryConfig.activities.isEmpty) { @@ -54,11 +56,13 @@ class BookingCreateUseCase { final activitiesResult = await _activityRepository.getByDestination( itineraryConfig.destination!, ); - if (activitiesResult is Error>) { - _log.warning('Error fetching activities: ${activitiesResult.error}'); - return Result.error(activitiesResult.error); + switch (activitiesResult) { + case Error>(): + _log.warning('Error fetching activities: ${activitiesResult.error}'); + return Result.error(activitiesResult.error); + case Ok>(): } - final activities = activitiesResult.asOk.value + final activities = activitiesResult.value .where( (activity) => itineraryConfig.activities.contains(activity.ref), ) @@ -74,7 +78,7 @@ class BookingCreateUseCase { final booking = Booking( startDate: itineraryConfig.startDate!, endDate: itineraryConfig.endDate!, - destination: destinationResult.asOk.value, + destination: destinationResult.value, activity: activities, ); diff --git a/compass_app/app/lib/ui/activities/view_models/activities_viewmodel.dart b/compass_app/app/lib/ui/activities/view_models/activities_viewmodel.dart index dc86b6f48..5c6fa4af9 100644 --- a/compass_app/app/lib/ui/activities/view_models/activities_viewmodel.dart +++ b/compass_app/app/lib/ui/activities/view_models/activities_viewmodel.dart @@ -8,6 +8,7 @@ import 'package:logging/logging.dart'; import '../../../data/repositories/activity/activity_repository.dart'; import '../../../data/repositories/itinerary_config/itinerary_config_repository.dart'; import '../../../domain/models/activity/activity.dart'; +import '../../../domain/models/itinerary_config/itinerary_config.dart'; import '../../../utils/command.dart'; import '../../../utils/result.dart'; @@ -45,21 +46,23 @@ class ActivitiesViewModel extends ChangeNotifier { Future> _loadActivities() async { final result = await _itineraryConfigRepository.getItineraryConfig(); - if (result is Error) { - _log.warning( - 'Failed to load stored ItineraryConfig', - result.asError.error, - ); - return result; + switch (result) { + case Error(): + _log.warning( + 'Failed to load stored ItineraryConfig', + result.error, + ); + return result; + case Ok(): } - final destinationRef = result.asOk.value.destination; + final destinationRef = result.value.destination; if (destinationRef == null) { _log.severe('Destination missing in ItineraryConfig'); return Result.error(Exception('Destination not found')); } - _selectedActivities.addAll(result.asOk.value.activities); + _selectedActivities.addAll(result.value.activities); final resultActivities = await _activityRepository.getByDestination(destinationRef); @@ -120,21 +123,23 @@ class ActivitiesViewModel extends ChangeNotifier { Future> _saveActivities() async { final resultConfig = await _itineraryConfigRepository.getItineraryConfig(); - if (resultConfig is Error) { - _log.warning( - 'Failed to load stored ItineraryConfig', - resultConfig.asError.error, - ); - return resultConfig; + switch (resultConfig) { + case Error(): + _log.warning( + 'Failed to load stored ItineraryConfig', + resultConfig.error, + ); + return resultConfig; + case Ok(): } - final itineraryConfig = resultConfig.asOk.value; + final itineraryConfig = resultConfig.value; final result = await _itineraryConfigRepository.setItineraryConfig( itineraryConfig.copyWith(activities: _selectedActivities.toList())); if (result is Error) { _log.warning( 'Failed to store ItineraryConfig', - result.asError.error, + result.error, ); } return result; diff --git a/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart b/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart index 725d478eb..f32d1a4bb 100644 --- a/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart +++ b/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart @@ -65,7 +65,7 @@ class BookingViewModel extends ChangeNotifier { case Error(): _log.warning('Booking error: ${result.error}'); notifyListeners(); - return Result.error(result.asError.error); + return Result.error(result.error); } case Error(): _log.warning('ItineraryConfig error: ${itineraryConfig.error}'); diff --git a/compass_app/app/lib/ui/results/view_models/results_viewmodel.dart b/compass_app/app/lib/ui/results/view_models/results_viewmodel.dart index 5a2690ab9..94d1f5d2d 100644 --- a/compass_app/app/lib/ui/results/view_models/results_viewmodel.dart +++ b/compass_app/app/lib/ui/results/view_models/results_viewmodel.dart @@ -50,14 +50,16 @@ class ResultsViewModel extends ChangeNotifier { Future> _search() async { // Load current itinerary config final resultConfig = await _itineraryConfigRepository.getItineraryConfig(); - if (resultConfig is Error) { - _log.warning( - 'Failed to load stored ItineraryConfig', - resultConfig.asError.error, - ); - return resultConfig; + switch (resultConfig) { + case Error(): + _log.warning( + 'Failed to load stored ItineraryConfig', + resultConfig.error, + ); + return resultConfig; + case Ok(): } - _itineraryConfig = resultConfig.asOk.value; + _itineraryConfig = resultConfig.value; notifyListeners(); final result = await _destinationRepository.getDestinations(); @@ -86,15 +88,17 @@ class ResultsViewModel extends ChangeNotifier { assert(destinationRef.isNotEmpty, "destinationRef should not be empty"); final resultConfig = await _itineraryConfigRepository.getItineraryConfig(); - if (resultConfig is Error) { - _log.warning( - 'Failed to load stored ItineraryConfig', - resultConfig.asError.error, - ); - return resultConfig; + switch (resultConfig) { + case Error(): + _log.warning( + 'Failed to load stored ItineraryConfig', + resultConfig.error, + ); + return resultConfig; + case Ok(): } - final itineraryConfig = resultConfig.asOk.value; + final itineraryConfig = resultConfig.value; final result = await _itineraryConfigRepository .setItineraryConfig(itineraryConfig.copyWith( destination: destinationRef, @@ -103,7 +107,7 @@ class ResultsViewModel extends ChangeNotifier { if (result is Error) { _log.warning( 'Failed to store ItineraryConfig', - result.asError.error, + result.error, ); } return result; diff --git a/compass_app/app/lib/ui/search_form/view_models/search_form_viewmodel.dart b/compass_app/app/lib/ui/search_form/view_models/search_form_viewmodel.dart index 565e5fc0f..c1eed2f92 100644 --- a/compass_app/app/lib/ui/search_form/view_models/search_form_viewmodel.dart +++ b/compass_app/app/lib/ui/search_form/view_models/search_form_viewmodel.dart @@ -99,14 +99,10 @@ class SearchFormViewModel extends ChangeNotifier { final result = await _continentRepository.getContinents(); switch (result) { case Ok(): - { - _continents = result.value; - _log.fine('Continents (${_continents.length}) loaded'); - } + _continents = result.value; + _log.fine('Continents (${_continents.length}) loaded'); case Error(): - { - _log.warning('Failed to load continents', result.asError.error); - } + _log.warning('Failed to load continents', result.error); } notifyListeners(); return result; @@ -116,27 +112,23 @@ class SearchFormViewModel extends ChangeNotifier { final result = await _itineraryConfigRepository.getItineraryConfig(); switch (result) { case Ok(): - { - final itineraryConfig = result.value; - _selectedContinent = itineraryConfig.continent; - if (itineraryConfig.startDate != null && - itineraryConfig.endDate != null) { - _dateRange = DateTimeRange( - start: itineraryConfig.startDate!, - end: itineraryConfig.endDate!, - ); - } - _guests = itineraryConfig.guests ?? 0; - _log.fine('ItineraryConfig loaded'); - notifyListeners(); - } - case Error(): - { - _log.warning( - 'Failed to load stored ItineraryConfig', - result.asError.error, + final itineraryConfig = result.value; + _selectedContinent = itineraryConfig.continent; + if (itineraryConfig.startDate != null && + itineraryConfig.endDate != null) { + _dateRange = DateTimeRange( + start: itineraryConfig.startDate!, + end: itineraryConfig.endDate!, ); } + _guests = itineraryConfig.guests ?? 0; + _log.fine('ItineraryConfig loaded'); + notifyListeners(); + case Error(): + _log.warning( + 'Failed to load stored ItineraryConfig', + result.error, + ); } return result; } diff --git a/compass_app/app/lib/utils/result.dart b/compass_app/app/lib/utils/result.dart index 8512963e4..407b11ca1 100644 --- a/compass_app/app/lib/utils/result.dart +++ b/compass_app/app/lib/utils/result.dart @@ -23,12 +23,6 @@ sealed class Result { /// Creates an error [Result], completed with the specified [error]. const factory Result.error(Exception error) = Error._; - - /// Convenience method to cast to Ok - Ok get asOk => this as Ok; - - /// Convenience method to cast to Error - Error get asError => this as Error; } /// Subclass of Result for values diff --git a/compass_app/app/test/data/repositories/activity/activity_repository_local_test.dart b/compass_app/app/test/data/repositories/activity/activity_repository_local_test.dart index 739f35084..a49702f9c 100644 --- a/compass_app/app/test/data/repositories/activity/activity_repository_local_test.dart +++ b/compass_app/app/test/data/repositories/activity/activity_repository_local_test.dart @@ -7,6 +7,8 @@ import 'package:compass_app/data/services/local/local_data_service.dart'; import 'package:compass_app/utils/result.dart'; import 'package:flutter_test/flutter_test.dart'; +import '../../../../testing/utils/result.dart'; + void main() { group('ActivityRepositoryLocal tests', () { // To load assets diff --git a/compass_app/app/test/data/repositories/activity/activity_repository_remote_test.dart b/compass_app/app/test/data/repositories/activity/activity_repository_remote_test.dart index a75734e54..18cb5a5e7 100644 --- a/compass_app/app/test/data/repositories/activity/activity_repository_remote_test.dart +++ b/compass_app/app/test/data/repositories/activity/activity_repository_remote_test.dart @@ -8,6 +8,7 @@ import 'package:compass_app/utils/result.dart'; import 'package:flutter_test/flutter_test.dart'; import '../../../../testing/fakes/services/fake_api_client.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('ActivityRepositoryRemote tests', () { diff --git a/compass_app/app/test/data/repositories/booking/booking_repository_remote_test.dart b/compass_app/app/test/data/repositories/booking/booking_repository_remote_test.dart index 54b907c1d..822405060 100644 --- a/compass_app/app/test/data/repositories/booking/booking_repository_remote_test.dart +++ b/compass_app/app/test/data/repositories/booking/booking_repository_remote_test.dart @@ -9,6 +9,7 @@ import 'package:flutter_test/flutter_test.dart'; import '../../../../testing/fakes/services/fake_api_client.dart'; import '../../../../testing/models/booking.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('BookingRepositoryRemote tests', () { diff --git a/compass_app/app/test/data/repositories/continent/continent_repository_remote_test.dart b/compass_app/app/test/data/repositories/continent/continent_repository_remote_test.dart index 4a41120b7..37ae24bac 100644 --- a/compass_app/app/test/data/repositories/continent/continent_repository_remote_test.dart +++ b/compass_app/app/test/data/repositories/continent/continent_repository_remote_test.dart @@ -8,6 +8,7 @@ import 'package:compass_app/utils/result.dart'; import 'package:flutter_test/flutter_test.dart'; import '../../../../testing/fakes/services/fake_api_client.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('ContinentRepositoryRemote tests', () { diff --git a/compass_app/app/test/data/repositories/destination/destination_repository_local_test.dart b/compass_app/app/test/data/repositories/destination/destination_repository_local_test.dart index 62fa01357..f53cf77b4 100644 --- a/compass_app/app/test/data/repositories/destination/destination_repository_local_test.dart +++ b/compass_app/app/test/data/repositories/destination/destination_repository_local_test.dart @@ -7,6 +7,8 @@ import 'package:compass_app/utils/result.dart'; import 'package:compass_app/data/repositories/destination/destination_repository_local.dart'; import 'package:flutter_test/flutter_test.dart'; +import '../../../../testing/utils/result.dart'; + void main() { group('DestinationRepositoryLocal tests', () { // To load assets diff --git a/compass_app/app/test/data/repositories/destination/destination_repository_remote_test.dart b/compass_app/app/test/data/repositories/destination/destination_repository_remote_test.dart index 2559f030e..d918f8789 100644 --- a/compass_app/app/test/data/repositories/destination/destination_repository_remote_test.dart +++ b/compass_app/app/test/data/repositories/destination/destination_repository_remote_test.dart @@ -8,6 +8,7 @@ import 'package:compass_app/utils/result.dart'; import 'package:flutter_test/flutter_test.dart'; import '../../../../testing/fakes/services/fake_api_client.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('DestinationRepositoryRemote tests', () { diff --git a/compass_app/app/test/data/services/api/api_client_test.dart b/compass_app/app/test/data/services/api/api_client_test.dart index e3965e4e3..2bcf8de3f 100644 --- a/compass_app/app/test/data/services/api/api_client_test.dart +++ b/compass_app/app/test/data/services/api/api_client_test.dart @@ -12,6 +12,7 @@ import '../../../../testing/models/activity.dart'; import '../../../../testing/models/booking.dart'; import '../../../../testing/models/destination.dart'; import '../../../../testing/models/user.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('ApiClient', () { diff --git a/compass_app/app/test/data/services/api/auth_api_client_test.dart b/compass_app/app/test/data/services/api/auth_api_client_test.dart index 50d20e561..18222ba62 100644 --- a/compass_app/app/test/data/services/api/auth_api_client_test.dart +++ b/compass_app/app/test/data/services/api/auth_api_client_test.dart @@ -8,6 +8,7 @@ import 'package:compass_app/data/services/api/model/login_response/login_respons import 'package:flutter_test/flutter_test.dart'; import '../../../../testing/mocks.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('AuthApiClient', () { diff --git a/compass_app/app/test/domain/use_cases/booking/booking_create_use_case_test.dart b/compass_app/app/test/domain/use_cases/booking/booking_create_use_case_test.dart index e148eb582..6e22287d1 100644 --- a/compass_app/app/test/domain/use_cases/booking/booking_create_use_case_test.dart +++ b/compass_app/app/test/domain/use_cases/booking/booking_create_use_case_test.dart @@ -12,6 +12,7 @@ import '../../../../testing/fakes/repositories/fake_destination_repository.dart' import '../../../../testing/models/activity.dart'; import '../../../../testing/models/booking.dart'; import '../../../../testing/models/destination.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('BookingCreateUseCase tests', () { diff --git a/compass_app/app/test/utils/command_test.dart b/compass_app/app/test/utils/command_test.dart index a2b1c8870..964baf403 100644 --- a/compass_app/app/test/utils/command_test.dart +++ b/compass_app/app/test/utils/command_test.dart @@ -6,6 +6,8 @@ import 'package:compass_app/utils/command.dart'; import 'package:compass_app/utils/result.dart'; import 'package:flutter_test/flutter_test.dart'; +import '../../testing/utils/result.dart'; + void main() { group('Command0 tests', () { test('should complete void command', () async { @@ -89,7 +91,7 @@ void main() { test('should complete bool command, bool argument', () async { // Action that returns bool argument final command = - Command1((a) => Future.value(Result.ok(true))); + Command1((a) => Future.value(const Result.ok(true))); // Run action with result and argument await command.execute(true); diff --git a/compass_app/app/testing/utils/result.dart b/compass_app/app/testing/utils/result.dart new file mode 100644 index 000000000..457003cb5 --- /dev/null +++ b/compass_app/app/testing/utils/result.dart @@ -0,0 +1,9 @@ +import 'package:compass_app/utils/result.dart'; + +extension ResultCast on Result { + /// Convenience method to cast to Ok + Ok get asOk => this as Ok; + + /// Convenience method to cast to Error + Error get asError => this as Error; +} From 5ff06429264b989c29915ed700e6c4b68d77af90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 06:34:40 +0000 Subject: [PATCH 26/30] Bump @angular/material from 18.2.14 to 19.0.2 in /web_embedding/ng-flutter (#2547) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@angular/material](https://github.com/angular/components) from 18.2.14 to 19.0.2.
Release notes

Sourced from @​angular/material's releases.

v19.0.2

19.0.2 "plastic-rhino" (2024-12-04)

youtube-player

Commit Description
fix - 1d3905a208 update to latest typings (#30126)

material

Commit Description
fix - 0ed9869529 button-toggle: unable to tab into ngModel-based group on first render (#30103)
fix - 72ff6fcce3 core: optgroup label color not inferred correctly (#30085)
fix - c395585446 schematics: avoid parsing stylesheets that don't include Material
fix - 5b3350a60e schematics: error if stylesheet contains syntax errors
fix - 1235ad28bc sort: simplify animations (#30057)
fix - 5b165067e8 tabs: ink bar not showing when same tab is re-selected (#30121)

cdk

Commit Description
fix - 460f971b27 accordion: improve accessibility in example code (#30087)
fix - 6306a12c12 menu: disable flexible dimensions (#30086)

v19.0.1

19.0.1 "mercury-mailbox" (2024-11-27)

material

Commit Description
fix - 2d7e078bb button-toggle: animate checkbox (#30025)
fix - edac40645 chips: emit state changes when chip grid is disabled (#30033)
fix - 18f7f4bb9 datepicker: adds comparison ids and aria-describedby spans (#30040)
fix - 375435497 slider: update documentation (#30029)
fix - a31201475 timepicker: make disabled input public (#30063)

docs

Commit Description
fix - f9d9d2c81 update errorState example to cover handle missing state (#30059)

multiple

Commit Description
fix - 59b7f436a use cross-compatible type for setTimeout (#30073)

v19.0.0

19.0.0 "hafnium-hippo" (2024-11-19)

cdk

Commit Description
feat - f4a02adb7 a11y: use native media query for high contrast detection (#29678)
feat - 9b4085c6e private: create cdk-visually-hidden style loader (#29757)

... (truncated)

Changelog

Sourced from @​angular/material's changelog.

19.0.2 "plastic-rhino" (2024-12-04)

cdk

Commit Type Description
460f971b27 fix accordion: improve accessibility in example code (#30087)
6306a12c12 fix menu: disable flexible dimensions (#30086)

material

Commit Type Description
0ed9869529 fix button-toggle: unable to tab into ngModel-based group on first render (#30103)
72ff6fcce3 fix core: optgroup label color not inferred correctly (#30085)
c395585446 fix schematics: avoid parsing stylesheets that don't include Material
5b3350a60e fix schematics: error if stylesheet contains syntax errors
1235ad28bc fix sort: simplify animations (#30057)
5b165067e8 fix tabs: ink bar not showing when same tab is re-selected (#30121)

youtube-player

Commit Type Description
1d3905a208 fix update to latest typings (#30126)

19.1.0-next.0 "hassium-ham" (2024-11-27)

material

Commit Type Description
f47f5f9a1 feat schematics: Add CSS output to custom theme schematic (#30004)

multiple

Commit Type Description
3a7724e95 fix remove webkit-overflow-scrolling (#30003)

19.0.1 "mercury-mailbox" (2024-11-27)

material

Commit Type Description
2d7e078bb fix button-toggle: animate checkbox (#30025)
edac40645 fix chips: emit state changes when chip grid is disabled (#30033)
18f7f4bb9 fix datepicker: adds comparison ids and aria-describedby spans (#30040)
375435497 fix slider: update documentation (#30029)
a31201475 fix timepicker: make disabled input public (#30063)

docs

Commit Type Description
f9d9d2c81 fix update errorState example to cover handle missing state (#30059)

multiple

... (truncated)

Commits
  • 8f2b8f3 release: cut the v19.0.2 release
  • 5b16506 fix(material/tabs): ink bar not showing when same tab is re-selected (#30121)
  • 1d3905a fix(youtube-player): update to latest typings (#30126)
  • 341bd14 docs(material/tabs): remove duplicated tabs example (#30109)
  • c395585 fix(material/schematics): avoid parsing stylesheets that don't include Material
  • 5b3350a fix(material/schematics): error if stylesheet contains syntax errors
  • 0ed9869 fix(material/button-toggle): unable to tab into ngModel-based group on first ...
  • 460f971 fix(cdk/accordion): improve accessibility in example code (#30087)
  • dfe4f2f docs(material/timepicker): fix missing icon in example (#30096)
  • 66e9093 docs(material/button): avoid clipping icon (#30095)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/material&package-manager=npm_and_yarn&previous-version=18.2.14&new-version=19.0.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 08d971e77..3140ef80c 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -17,7 +17,7 @@ "@angular/compiler": "^19.0.0", "@angular/core": "^18.0.1", "@angular/forms": "^19.0.1", - "@angular/material": "^18.0.1", + "@angular/material": "^19.0.2", "@angular/platform-browser": "^18.0.1", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.1", From 04eba1f01aa5f8cd12d566e1411e444241b766ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 06:34:42 +0000 Subject: [PATCH 27/30] Bump @angular/core from 18.2.13 to 19.0.3 in /web_embedding/ng-flutter (#2546) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@angular/core](https://github.com/angular/angular/tree/HEAD/packages/core) from 18.2.13 to 19.0.3.
Release notes

Sourced from @​angular/core's releases.

v19.0.3

19.0.3 (2024-12-04)

v19.0.2

19.0.2 (2024-12-04)

compiler-cli

Commit Description
fix - 9f99196d23 account for multiple generated namespace imports in HMR (#58924)

core

Commit Description
fix - 4792db9a6d Explicitly manage TracingSnapshot lifecycle and dispose of it once it's been used. (#58929)

migrations

Commit Description
fix - 7b5bacc228 class content being deleted in some edge cases (#58959)
fix - d1cbdd6acb correctly strip away parameters surrounded by comments in inject migration (#58959)
fix - e17ff71c31 don't migrate classes with parameters that can't be injected (#58959)
fix - 7c5f990001 inject migration aggressively removing imports (#58959)
fix - 4392ccedf9 inject migration dropping code if everything except super is removed (#58959)
fix - 9cbebc6dda preserve type literals and tuples in inject migrations (#58959)

platform-server

Commit Description
fix - f3c388ecda remove peer dependency on animations (#58997)

v19.0.1

19.0.1 (2024-11-26)

compiler-cli

Commit Description
fix - fb1fa8b0fc more accurate diagnostics for host binding parser errors (#58870)

core

Commit Description
fix - 502ee0e722 correctly clear template HMR internal renderer cache (#58724)
fix - 99715104a1 correctly perform lazy routes migration for components with additional decorators (#58796)
fix - 118803035f Ensure _tick is always run within the TracingSnapshot. (#58881)
fix - 08b9452f01 Ensure resource sets an error (#58855)
fix - 84f45ea3ff make component id generation more stable between client and server builds (#58813)
fix - d3491c7cee Prevents race condition of cleanup for incremental hydration (#58722)

forms

Commit Description
fix - 4dfe5b6cef work around TypeScript 5.7 issue (#58731)

language-service

... (truncated)

Changelog

Sourced from @​angular/core's changelog.

19.0.3 (2024-12-04)

19.1.0-next.1 (2024-12-04)

compiler-cli

Commit Type Description
f280467398 fix account for multiple generated namespace imports in HMR (#58924)

core

Commit Type Description
e894a5daea feat set kind field on template and effect nodes (#58865)
3b765367f3 fix Explicitly manage TracingSnapshot lifecycle and dispose of it once it's been used. (#58929)

migrations

Commit Type Description
e31e52e177 fix class content being deleted in some edge cases (#58959)
508d3a1b3b fix correctly strip away parameters surrounded by comments in inject migration (#58959)
7191aa6e09 fix don't migrate classes with parameters that can't be injected (#58959)
a4924af6d5 fix inject migration aggressively removing imports (#58959)
35165d152d fix inject migration dropping code if everything except super is removed (#58959)
68e5ba7a3a fix preserve type literals and tuples in inject migrations (#58959)

platform-server

Commit Type Description
1cfbfc66d3 fix remove peer dependency on animations (#58997)

19.0.2 (2024-12-04)

compiler-cli

Commit Type Description
9f99196d23 fix account for multiple generated namespace imports in HMR (#58924)

core

Commit Type Description
4792db9a6d fix Explicitly manage TracingSnapshot lifecycle and dispose of it once it's been used. (#58929)

migrations

Commit Type Description
7b5bacc228 fix class content being deleted in some edge cases (#58959)
d1cbdd6acb fix correctly strip away parameters surrounded by comments in inject migration (#58959)
e17ff71c31 fix don't migrate classes with parameters that can't be injected (#58959)
7c5f990001 fix inject migration aggressively removing imports (#58959)
4392ccedf9 fix inject migration dropping code if everything except super is removed (#58959)
9cbebc6dda fix preserve type literals and tuples in inject migrations (#58959)

... (truncated)

Commits
  • 0c40bb2 refactor(docs-infra): convert code-example-s that have only region param to @...
  • 5f3ba06 docs: set syntax highlighting of code examples MD code blocks (#59026)
  • b8a2ae0 docs: fix missing alert block styles in the API reference (#59020)
  • c453f5d docs(core): fix eventCoalescing comment (#57097)
  • 4392cce fix(migrations): inject migration dropping code if everything except super is...
  • e17ff71 fix(migrations): don't migrate classes with parameters that can't be injected...
  • 9cbebc6 fix(migrations): preserve type literals and tuples in inject migrations (#58959)
  • 7c5f990 fix(migrations): inject migration aggressively removing imports (#58959)
  • d1cbdd6 fix(migrations): correctly strip away parameters surrounded by comments in in...
  • 7b5bacc fix(migrations): class content being deleted in some edge cases (#58959)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/core&package-manager=npm_and_yarn&previous-version=18.2.13&new-version=19.0.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 3140ef80c..02dab944c 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -15,7 +15,7 @@ "@angular/cdk": "^19.0.0", "@angular/common": "^19.0.0", "@angular/compiler": "^19.0.0", - "@angular/core": "^18.0.1", + "@angular/core": "^19.0.3", "@angular/forms": "^19.0.1", "@angular/material": "^19.0.2", "@angular/platform-browser": "^18.0.1", From ad86bf554be00c8345c8678a6fa0efaff02e9c29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 06:36:07 +0000 Subject: [PATCH 28/30] Bump @angular/platform-browser from 18.2.13 to 19.0.3 in /web_embedding/ng-flutter (#2548) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- Bumps [@angular/platform-browser](https://github.com/angular/angular/tree/HEAD/packages/platform-browser) from 18.2.13 to 19.0.3.
Release notes

Sourced from @​angular/platform-browser's releases.

v19.0.3

19.0.3 (2024-12-04)

v19.0.2

19.0.2 (2024-12-04)

compiler-cli

Commit Description
fix - 9f99196d23 account for multiple generated namespace imports in HMR (#58924)

core

Commit Description
fix - 4792db9a6d Explicitly manage TracingSnapshot lifecycle and dispose of it once it's been used. (#58929)

migrations

Commit Description
fix - 7b5bacc228 class content being deleted in some edge cases (#58959)
fix - d1cbdd6acb correctly strip away parameters surrounded by comments in inject migration (#58959)
fix - e17ff71c31 don't migrate classes with parameters that can't be injected (#58959)
fix - 7c5f990001 inject migration aggressively removing imports (#58959)
fix - 4392ccedf9 inject migration dropping code if everything except super is removed (#58959)
fix - 9cbebc6dda preserve type literals and tuples in inject migrations (#58959)

platform-server

Commit Description
fix - f3c388ecda remove peer dependency on animations (#58997)

v19.0.1

19.0.1 (2024-11-26)

compiler-cli

Commit Description
fix - fb1fa8b0fc more accurate diagnostics for host binding parser errors (#58870)

core

Commit Description
fix - 502ee0e722 correctly clear template HMR internal renderer cache (#58724)
fix - 99715104a1 correctly perform lazy routes migration for components with additional decorators (#58796)
fix - 118803035f Ensure _tick is always run within the TracingSnapshot. (#58881)
fix - 08b9452f01 Ensure resource sets an error (#58855)
fix - 84f45ea3ff make component id generation more stable between client and server builds (#58813)
fix - d3491c7cee Prevents race condition of cleanup for incremental hydration (#58722)

forms

Commit Description
fix - 4dfe5b6cef work around TypeScript 5.7 issue (#58731)

language-service

... (truncated)

Changelog

Sourced from @​angular/platform-browser's changelog.

19.0.3 (2024-12-04)

19.1.0-next.1 (2024-12-04)

compiler-cli

Commit Type Description
f280467398 fix account for multiple generated namespace imports in HMR (#58924)

core

Commit Type Description
e894a5daea feat set kind field on template and effect nodes (#58865)
3b765367f3 fix Explicitly manage TracingSnapshot lifecycle and dispose of it once it's been used. (#58929)

migrations

Commit Type Description
e31e52e177 fix class content being deleted in some edge cases (#58959)
508d3a1b3b fix correctly strip away parameters surrounded by comments in inject migration (#58959)
7191aa6e09 fix don't migrate classes with parameters that can't be injected (#58959)
a4924af6d5 fix inject migration aggressively removing imports (#58959)
35165d152d fix inject migration dropping code if everything except super is removed (#58959)
68e5ba7a3a fix preserve type literals and tuples in inject migrations (#58959)

platform-server

Commit Type Description
1cfbfc66d3 fix remove peer dependency on animations (#58997)

19.0.2 (2024-12-04)

compiler-cli

Commit Type Description
9f99196d23 fix account for multiple generated namespace imports in HMR (#58924)

core

Commit Type Description
4792db9a6d fix Explicitly manage TracingSnapshot lifecycle and dispose of it once it's been used. (#58929)

migrations

Commit Type Description
7b5bacc228 fix class content being deleted in some edge cases (#58959)
d1cbdd6acb fix correctly strip away parameters surrounded by comments in inject migration (#58959)
e17ff71c31 fix don't migrate classes with parameters that can't be injected (#58959)
7c5f990001 fix inject migration aggressively removing imports (#58959)
4392ccedf9 fix inject migration dropping code if everything except super is removed (#58959)
9cbebc6dda fix preserve type literals and tuples in inject migrations (#58959)

... (truncated)

Commits
  • 5f3ba06 docs: set syntax highlighting of code examples MD code blocks (#59026)
  • c36a1c0 fix(platform-browser): correctly add external stylesheets to ShadowDOM compon...
  • 917e99d docs(platform-browser): update usage notes for incremental hydration (#58339)
  • 19edf2c feat(core): add syntactic sugar for initializers (#53152)
  • 69fc5ae feat(core): Add incremental hydration public api (#58249)
  • 9544930 refactor(core): add incremental hydration infrastructure (#58193)
  • b542f15 docs: removed typos of withHttpTransferCacheOptions description (#58244)
  • 09df589 refactor(core): Migrate all packages with the explicit-standalone-flag sche...
  • 5c61f46 refactor(platform-browser): remove deprecated `BrowserModule.withServerTransi...
  • 84b6896 refactor(platform-server): Add an ssr benchmark setup. (#57647)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@angular/platform-browser&package-manager=npm_and_yarn&previous-version=18.2.13&new-version=19.0.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 02dab944c..dff961d1e 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -18,7 +18,7 @@ "@angular/core": "^19.0.3", "@angular/forms": "^19.0.1", "@angular/material": "^19.0.2", - "@angular/platform-browser": "^18.0.1", + "@angular/platform-browser": "^19.0.3", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.1", "rxjs": "~7.8.1", From a7def8bbe35f4d9b0326e03b2e843765e4c0fab3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 06:46:10 +0000 Subject: [PATCH 29/30] Bump typescript from 5.6.3 to 5.7.2 in /web_embedding/ng-flutter (#2544) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.6.3 to 5.7.2.
Release notes

Sourced from typescript's releases.

TypeScript 5.7

For release notes, check out the release announcement.

Downloads are available on:

TypeScript 5.7 RC

For release notes, check out the release announcement.

For the complete list of fixed issues, check out the

Downloads are available on:

TypeScript 5.7 Beta

For release notes, check out the release announcement.

For the complete list of fixed issues, check out the

Downloads are available on:

Commits
  • d701d90 Bump version to 5.7.2 and LKG
  • 0503a63 🤖 Pick PR #60450 (Move to file: fix detection of refe...) into release-5.7 (#...
  • 3140dbb 🤖 Pick PR #60488 (Stub out copilotRelated command) into release-5.7 (#60495)
  • c1216de Update LKG
  • 3ee2b95 🤖 Pick PR #60415 (Fix false positive rewriteRelativeI...) into release-5.7 (#...
  • 44bd3f2 Bump version to 5.7.1-rc and LKG
  • 5925c81 Update LKG
  • 84d58cf Merge remote-tracking branch 'origin/main' into release-5.7
  • 0ec4d30 Fixing exception on unsaved file (#60362)
  • 11b2930 Add compatible overloads that accept ArrayBuffer to BigInt64Array/BigUint64Ar...
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=typescript&package-manager=npm_and_yarn&previous-version=5.6.3&new-version=5.7.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index dff961d1e..6465edd59 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -36,7 +36,7 @@ "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", - "typescript": "~5.6.2" + "typescript": "~5.7.2" }, "sideEffects": false } From 1ccce7c9e14ec1f20917c8443483a3713eb9d131 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 06:51:46 +0000 Subject: [PATCH 30/30] Bump jasmine-core from 5.4.0 to 5.5.0 in /web_embedding/ng-flutter (#2545) Bumps [jasmine-core](https://github.com/jasmine/jasmine) from 5.4.0 to 5.5.0.
Release notes

Sourced from jasmine-core's releases.

v5.5.0

Please see the release notes.

Commits
  • 483d4ab Bump version to 5.5.0
  • 663dfe5 Updated release instructions
  • ce9c752 Added debug logging to flaky test
  • d5e7bc9 Optionally enforce uniqueness of spec and suite names
  • 744e765 Update copyright date
  • 29551ba Prettier
  • bd9a3b2 Include property value mismatches in diffs even when there are missing or ext...
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jasmine-core&package-manager=npm_and_yarn&previous-version=5.4.0&new-version=5.5.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- web_embedding/ng-flutter/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 6465edd59..9edd8767e 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -30,7 +30,7 @@ "@angular/cli": "~19.0.2", "@angular/compiler-cli": "^19.0.1", "@types/jasmine": "~5.1.0", - "jasmine-core": "~5.4.0", + "jasmine-core": "~5.5.0", "karma": "~6.4.2", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0",
Release notes

Sourced from subosito/flutter-action's releases.

v2.17.0

This release adds support for older yq versions, as added in PR #329. Thanks for contributing, @​ThomasAunvik!