From 98ae26dd89cd161db5becf580f73b54a0e00e48e Mon Sep 17 00:00:00 2001 From: b3ni15 Date: Mon, 25 Aug 2025 17:07:40 +0200 Subject: [PATCH 001/148] Update dependencies in pubspec.lock for compatibility and security --- pubspec.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index bea641d..5cecf01 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.3" flutter: dependency: "direct main" description: flutter @@ -148,26 +148,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "11.0.1" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: @@ -265,18 +265,18 @@ packages: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.6" vector_math: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: @@ -294,5 +294,5 @@ packages: source: hosted version: "1.1.1" sdks: - dart: ">=3.7.2 <4.0.0" + dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.24.0" From dc1ea8317e7d633e69906f0ae562d48f5e646670 Mon Sep 17 00:00:00 2001 From: devbeni Date: Mon, 25 Aug 2025 17:08:58 +0200 Subject: [PATCH 002/148] Delete pubspec.lock --- pubspec.lock | 298 --------------------------------------------------- 1 file changed, 298 deletions(-) delete mode 100644 pubspec.lock diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index 5cecf01..0000000 --- a/pubspec.lock +++ /dev/null @@ -1,298 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 - url: "https://pub.dev" - source: hosted - version: "2.12.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - characters: - dependency: transitive - description: - name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 - url: "https://pub.dev" - source: hosted - version: "1.4.0" - clock: - dependency: transitive - description: - name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://pub.dev" - source: hosted - version: "1.1.2" - collection: - dependency: transitive - description: - name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://pub.dev" - source: hosted - version: "1.19.1" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" - url: "https://pub.dev" - source: hosted - version: "1.3.3" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_inappwebview: - dependency: "direct main" - description: - name: flutter_inappwebview - sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5" - url: "https://pub.dev" - source: hosted - version: "6.1.5" - flutter_inappwebview_android: - dependency: transitive - description: - name: flutter_inappwebview_android - sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba" - url: "https://pub.dev" - source: hosted - version: "1.1.3" - flutter_inappwebview_internal_annotations: - dependency: transitive - description: - name: flutter_inappwebview_internal_annotations - sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - flutter_inappwebview_ios: - dependency: transitive - description: - name: flutter_inappwebview_ios - sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d" - url: "https://pub.dev" - source: hosted - version: "1.1.2" - flutter_inappwebview_macos: - dependency: transitive - description: - name: flutter_inappwebview_macos - sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1 - url: "https://pub.dev" - source: hosted - version: "1.1.2" - flutter_inappwebview_platform_interface: - dependency: transitive - description: - name: flutter_inappwebview_platform_interface - sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500 - url: "https://pub.dev" - source: hosted - version: "1.3.0+1" - flutter_inappwebview_web: - dependency: transitive - description: - name: flutter_inappwebview_web - sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598" - url: "https://pub.dev" - source: hosted - version: "1.1.2" - flutter_inappwebview_windows: - dependency: transitive - description: - name: flutter_inappwebview_windows - sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055" - url: "https://pub.dev" - source: hosted - version: "0.6.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" - url: "https://pub.dev" - source: hosted - version: "5.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: "direct main" - description: - name: font_awesome_flutter - sha256: d3a89184101baec7f4600d58840a764d2ef760fe1c5a20ef9e6b0e9b24a07a3a - url: "https://pub.dev" - source: hosted - version: "10.8.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" - url: "https://pub.dev" - source: hosted - version: "11.0.1" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" - url: "https://pub.dev" - source: hosted - version: "3.0.10" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - lints: - dependency: transitive - description: - name: lints - sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 - url: "https://pub.dev" - source: hosted - version: "5.1.1" - matcher: - dependency: transitive - description: - name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 - url: "https://pub.dev" - source: hosted - version: "0.12.17" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" - source: hosted - version: "0.11.1" - meta: - dependency: transitive - description: - name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c - url: "https://pub.dev" - source: hosted - version: "1.16.0" - path: - dependency: transitive - description: - name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://pub.dev" - source: hosted - version: "1.9.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" - source: hosted - version: "2.1.8" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - source_span: - dependency: transitive - description: - name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" - url: "https://pub.dev" - source: hosted - version: "1.10.1" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://pub.dev" - source: hosted - version: "1.12.1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://pub.dev" - source: hosted - version: "1.4.1" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://pub.dev" - source: hosted - version: "1.2.2" - test_api: - dependency: transitive - description: - name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" - url: "https://pub.dev" - source: hosted - version: "0.7.6" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b - url: "https://pub.dev" - source: hosted - version: "2.2.0" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" - url: "https://pub.dev" - source: hosted - version: "14.3.1" - web: - dependency: transitive - description: - name: web - sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://pub.dev" - source: hosted - version: "1.1.1" -sdks: - dart: ">=3.8.0-0 <4.0.0" - flutter: ">=3.24.0" From 59382013a507eff448d4b8530ad40638b1e0149d Mon Sep 17 00:00:00 2001 From: b3ni15 Date: Mon, 25 Aug 2025 17:09:54 +0200 Subject: [PATCH 003/148] Add pubspec.lock file with package dependencies --- pubspec.lock | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 pubspec.lock diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..4496490 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,298 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + url: "https://pub.dev" + source: hosted + version: "2.13.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + characters: + dependency: transitive + description: + name: characters + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_inappwebview: + dependency: "direct main" + description: + name: flutter_inappwebview + sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5" + url: "https://pub.dev" + source: hosted + version: "6.1.5" + flutter_inappwebview_android: + dependency: transitive + description: + name: flutter_inappwebview_android + sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba" + url: "https://pub.dev" + source: hosted + version: "1.1.3" + flutter_inappwebview_internal_annotations: + dependency: transitive + description: + name: flutter_inappwebview_internal_annotations + sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + flutter_inappwebview_ios: + dependency: transitive + description: + name: flutter_inappwebview_ios + sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_inappwebview_macos: + dependency: transitive + description: + name: flutter_inappwebview_macos + sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1 + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_inappwebview_platform_interface: + dependency: transitive + description: + name: flutter_inappwebview_platform_interface + sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500 + url: "https://pub.dev" + source: hosted + version: "1.3.0+1" + flutter_inappwebview_web: + dependency: transitive + description: + name: flutter_inappwebview_web + sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_inappwebview_windows: + dependency: transitive + description: + name: flutter_inappwebview_windows + sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055" + url: "https://pub.dev" + source: hosted + version: "0.6.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" + url: "https://pub.dev" + source: hosted + version: "5.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + font_awesome_flutter: + dependency: "direct main" + description: + name: font_awesome_flutter + sha256: "27af5982e6c510dec1ba038eff634fa284676ee84e3fd807225c80c4ad869177" + url: "https://pub.dev" + source: hosted + version: "10.10.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" + url: "https://pub.dev" + source: hosted + version: "11.0.1" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + lints: + dependency: transitive + description: + name: lints + sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 + url: "https://pub.dev" + source: hosted + version: "5.1.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + url: "https://pub.dev" + source: hosted + version: "0.12.17" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + url: "https://pub.dev" + source: hosted + version: "1.16.0" + path: + dependency: transitive + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + source_span: + dependency: transitive + description: + name: source_span + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + url: "https://pub.dev" + source: hosted + version: "1.10.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test_api: + dependency: transitive + description: + name: test_api + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + url: "https://pub.dev" + source: hosted + version: "0.7.6" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + url: "https://pub.dev" + source: hosted + version: "2.2.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + url: "https://pub.dev" + source: hosted + version: "15.0.2" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" +sdks: + dart: ">=3.9.0 <4.0.0" + flutter: ">=3.27.0" From fd9991cef1ea61b95bc806f9b5253e874dae8134 Mon Sep 17 00:00:00 2001 From: b3ni15 Date: Mon, 25 Aug 2025 17:11:06 +0200 Subject: [PATCH 004/148] Update Podfile and project configuration for iOS compatibility and add Podfile.lock with dependencies --- ios/Podfile | 2 +- ios/Podfile.lock | 33 ++++++ ios/Runner.xcodeproj/project.pbxproj | 112 ++++++++++++++++++ .../contents.xcworkspacedata | 3 + 4 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 ios/Podfile.lock diff --git a/ios/Podfile b/ios/Podfile index e549ee2..620e46e 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '12.0' +# platform :ios, '13.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 0000000..3def93f --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,33 @@ +PODS: + - Flutter (1.0.0) + - flutter_inappwebview_ios (0.0.1): + - Flutter + - flutter_inappwebview_ios/Core (= 0.0.1) + - OrderedSet (~> 6.0.3) + - flutter_inappwebview_ios/Core (0.0.1): + - Flutter + - OrderedSet (~> 6.0.3) + - OrderedSet (6.0.3) + +DEPENDENCIES: + - Flutter (from `Flutter`) + - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`) + +SPEC REPOS: + trunk: + - OrderedSet + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + flutter_inappwebview_ios: + :path: ".symlinks/plugins/flutter_inappwebview_ios/ios" + +SPEC CHECKSUMS: + Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 + flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99 + OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 + +PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e + +COCOAPODS: 1.16.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 5d5c9b3..24807b8 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -10,10 +10,12 @@ 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 */; }; + 63DA7AEB0EF7ED9CB9C0BB86 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 332A963F04F5DC47C01DA891 /* Pods_RunnerTests.framework */; }; 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 */; }; + A42FC9ECC1401BE3A04C9405 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7494A4433CF87971D87CEA76 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -42,11 +44,14 @@ /* 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 = ""; }; + 2909EC3ADE6D5D6826EDE1EE /* 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 = ""; }; 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; }; + 332A963F04F5DC47C01DA891 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; 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 = ""; }; + 7494A4433CF87971D87CEA76 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.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 = ""; }; @@ -55,6 +60,11 @@ 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 = ""; }; + A365E92106BC124B048DEB7F /* 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 = ""; }; + C6BA81CA8F2AD1C35B680CAF /* 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 = ""; }; + C8CDE3B24CC10455B8765937 /* 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 = ""; }; + EBF28D50FA2B6D4541FD549F /* 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 = ""; }; + FA61076B2739B38F699A0F6D /* 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 */ @@ -62,12 +72,35 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + A42FC9ECC1401BE3A04C9405 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C62567BAC54BE23C3B81B78E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 63DA7AEB0EF7ED9CB9C0BB86 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 08BBBB42223F44BB828034D9 /* Pods */ = { + isa = PBXGroup; + children = ( + FA61076B2739B38F699A0F6D /* Pods-Runner.debug.xcconfig */, + C6BA81CA8F2AD1C35B680CAF /* Pods-Runner.release.xcconfig */, + 2909EC3ADE6D5D6826EDE1EE /* Pods-Runner.profile.xcconfig */, + C8CDE3B24CC10455B8765937 /* Pods-RunnerTests.debug.xcconfig */, + EBF28D50FA2B6D4541FD549F /* Pods-RunnerTests.release.xcconfig */, + A365E92106BC124B048DEB7F /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 331C8082294A63A400263BE5 /* RunnerTests */ = { isa = PBXGroup; children = ( @@ -76,6 +109,15 @@ path = RunnerTests; sourceTree = ""; }; + 7EA6068D706EE8E33E17BDEB /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7494A4433CF87971D87CEA76 /* Pods_Runner.framework */, + 332A963F04F5DC47C01DA891 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -94,6 +136,8 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, + 08BBBB42223F44BB828034D9 /* Pods */, + 7EA6068D706EE8E33E17BDEB /* Frameworks */, ); sourceTree = ""; }; @@ -128,8 +172,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 08809EE9385D5C1010EB3277 /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, + C62567BAC54BE23C3B81B78E /* Frameworks */, ); buildRules = ( ); @@ -145,12 +191,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + FEC2CA1929134711CA635730 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 539C3DFA07D07F0498315A36 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -222,6 +270,28 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 08809EE9385D5C1010EB3277 /* [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; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -238,6 +308,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 539C3DFA07D07F0498315A36 /* [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; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -253,6 +340,28 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + FEC2CA1929134711CA635730 /* [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 */ @@ -387,6 +496,7 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = C8CDE3B24CC10455B8765937 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -405,6 +515,7 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = EBF28D50FA2B6D4541FD549F /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -421,6 +532,7 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = A365E92106BC124B048DEB7F /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + From d031828593ec35bbe3ef400414d499170b5d1c0e Mon Sep 17 00:00:00 2001 From: devbeni Date: Mon, 25 Aug 2025 17:20:23 +0200 Subject: [PATCH 005/148] Update dependencies and add logo asset - Updated `fake_async` from version 1.3.2 to 1.3.3 - Updated `leak_tracker` from version 10.0.8 to 11.0.1 - Updated `leak_tracker_flutter_testing` from version 3.0.9 to 3.0.10 - Updated `leak_tracker_testing` from version 3.0.1 to 3.0.2 - Updated `test_api` from version 0.7.4 to 0.7.6 - Updated `vector_math` from version 2.1.4 to 2.2.0 - Updated Dart SDK constraint from ">=3.7.2 <4.0.0" to ">=3.8.0-0 <4.0.0" - Added new logo asset located at `assets/logo.png` --- assets/logo.png | Bin 0 -> 13295 bytes lib/screens/login_screen.dart | 269 +++++++++++++++++++++++++++++----- pubspec.lock | 26 ++-- 3 files changed, 248 insertions(+), 47 deletions(-) create mode 100644 assets/logo.png diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5e87ff0b31e8f0fa0388911c85fd54736e928bda GIT binary patch literal 13295 zcmV9!o`mHL4DmQ8Y&L-zzyuN)aLB=&A;Z8h zB)|*|b6_%=4DmpKaY#%OVH`V-vB3uKvSe*7S!${Ge(&8%Ro(il{;FH|^=qkHlASuI z`);-V`~TPS#K4L(B%}Z!;gfpBAMHE3$SALWEN*0}Fx3~n_xWrcrW?{dOZSq>N|u%N zLYEP|i{(BA-4(K^m5s%>5{*rNNsI@sRL<@tqK<_1AXSfu>YT4kRgzIZdQ0^Jt{Q+A zNe&57^@JD#NYIWfz6)Wlf^|NqN_tuoww%96U#%&ErGfmou5L>`%V?v;DWzp{nPgB;cD!0yl5W1aVyq>EI0=v%S6t70ssPC`R_Cp%v$s@t zI?Qr3NktJQu$JiSK#3|2%+w(umh4YdwypwzoG9H2qq>L*s=#nrlBWWO5U4|$G>#?W6G{;lo#35wVj?*oPvQ@~hl7gtH z1E?mVZgtI{>Xno$qkGTBAc-JL-+ZUYXpB`t!F#MMCp1$}j%3R7LejdXq*YT4#eqbi zYJDCl5{Q=3xZ_6--z0;{D05tpi)(t9SG-TvJ)ZO`FJn8!9-Znjwl)AaO8Ue;TF4O4T{Lv5{z&K%NGzEF>RnmS%3K};iZ{>=f_da)p2GS zwKE@A$8|1TwD+3oA-5NulH3)FzL+aXf(Vh4>+8sPlO-u3gR2af!j{pxoKR_9)wr)d zyG-QouJ6BT6QakFdX-@I;xgyCW-xP0aPFyxsDEvG^+9sK}b8iB8#K@QFyfzOJ1r_051OF~~c_1{_goL-|qxMCqgZ7f61XNpBKpe7H zjugj{kJ?EQ6wfQ8{7aYW2)aNa(lRFyCpx{$fh<`bmMGA|V*-JThcKQX<9C81i)ttg z&=9O-tB5l4yQYYH0||pJbL9q%E0Y=v=gzIxx4h;+sj__Xea$E*c zS)N2xrYfbpiIXP*>Lu=jZ~&D?)KXB`=PQQH`Mb=m?un2twI5H$8>}=h2*b|{NM2yjg;M10Cb7STO_>AUQqY%hJ`b@d{77C+TV^z#l$CK}^Fsz#WPg38c> z4va|R@|feiox$4?0Y`bcA|x4nBDjXGCXJ!O$g4EC=HvYNkXYeal>T!5>;bmTDN*p7+_mc*!GEp91 z()~*TzpA~|bGP?ZWmCkubSX1Um^N~F31nGZ`l~}b=QxKn7c*q9s*uk;$dKTqWa`Jh z59|XBiTdOtUng$_!lKsAxgzM8Gt3wV z`(-v^UT4`0L}HwDGgk%neX>5D*i4~_)fK&mM<%Z*z>o06Lk4UXJ-c!e0rdp4mDGk^ z3Ram?$dA9Bx@05(aj+DeTNz<6B7wal#^#Lv~5xRf+UUipHr%zE1VfRih5mqYS&w{C;i#7J6O= zWlGYM$_BQCS2ux_jp4!(ETRtqR})7w#EY1#qkG+#EZJdy%`D+L_%H&LDee~0J$D-a03$81cw~#q1(yIc#XhlZf5RWBA6ww$?2MLfus1)uWoGfQBj)QQ{^|N)+7b1*O*fq(G}x7 zMX6pwzU1@ll8qsry5%}pL_qL02>%FAP)MkQDvpR0HdRPE-XS}St~QS*s*k!Y{ZVBp-&?gQi!$JhNc{~p{E5peY&*!XN8+=7*k9dE}Y-yl&T zJXe2cTWL`DM39k+X!|-yD!8BtmkeAgoH|0NdyCrZY;VE=j*?B1(Us+61mb5_rLQ}g z7#F%*()W@0=7=_b4HzV6b^pygHy8m}Nf8i&h}xy`NroKae5?C&jkuN-@okHAi+JE})O%pn$q4s_Dv<2nsZE=)kl-@m{V+Y@#635}xRDp@ z^14TCfbgb$*C_rp!Zkf-P0RJ_xu%|5s^0N&b)AOjuc5YaBbsYhqrQ42`iGjx)#vt1 z8?7gfp*=Q+xxEJ<$0t=)s*YvLfxgUgcDvwqBN1A~bKbB>pR*F6X7lJVsB50t_YpDh zLnW$I?@3DKP_P#R{>BnSu|}|v3R1FJL5^RZBsUNuX+o0E>3qTTx&~m3bV78~5(HiQ zEHM-kK-8L$GYY^*Mp559f>kej9@brT1(rX3E1FxD6$GL2G^^0jvMsCUTEFeCYQA-3 z8WRuf!{J-+#1l8~z|7C?2ZmMv!|E@e^_(u|3WRGy&_tjs(nKIE@@agT@Npvou#*Hi z(&6NjlZ2=bNjD4Vu)=1&n2HL+KM7+oe1UnIhL6>gm2Npct9hhn4Uc>x0F87*0CcbN z*3|Xj5!9A7vGL8X!x?Y-6%1@$j@BWC(D7nO>_89)Zyv*nziXmsu2Y0EHG}mRNP z;Ke@|=aeDY*O=3J{lx8--5kf)m=4znjgan;-N)|LwV|&252AU_7CikU@4}iFUxe8` z674Cw48>|0p|Ukr7hTa&iB3CLBEMw-Utim=S{KSB5LN;xoXx;5ZqmbVNDQ1QFn-@Y z+<(I#WBjjw1e~#15y5OB70e$IfknRl=7?Ypfw8FV2jRipI=(YHuJAHzb+byf+^CNF`sHYDScl<@ z&%vtg7h}!#vy?>X!|Z-(@K=a(iT*7Dti&lz)~-}(%N_GeZiwbaAdgp%?z7R;?*?f5#%<5W$R<2=qs)g4BfdGQeXETmmdTAt(YE@Mtt%kqo!w1%_U%EfUC= zGE$}}@)+2Y<RR<4# z`dirdm2ayUjViNhNWs?X-Mk%&Te^1y%KMagb)<=6Tp?@h2v)u3N?h=vH>xfTWA=c8 zQ%xA@F}Nke9j|&nChmI_V#T0ha4ij{tqPd&5`okN5kbz~O0EhdPL?XDiLCKaVghZE z(%Cxk%D*rrIGZQt+WUJ#yg(S(X)t$=>3PTTgX%h31Kk7Hu@5y)XhG)iZqZINKE)1Es!GaeCnY^d3Lde%s4s{XE2NZ)%D zyFd92OdU9cGk)Va%Fa+Q>L_(^NaCz(U!wT8fuqW65Gz+9Wl}k$x=;uifHH#FNmKy} zxROWyDiJSJE}TSK3b0p#ncH9%zYFY;=;z2M0#L|Th&TFvbPSu{@dj-Bz?(4jNMW7z ztr3_R9mQS0{t>0lm2?4@@~F>2cVcYqNP(^*&oW)ll%7J zg3o^d>tAxQBF5YduemnE(L3(OPu~1Nh%K9xv{Gs$pDKvY*a6d_(I~k}XnUKWBng%- zDFWy(TX%f=wzNw(HukuRKxF(eDZv9h!U7i7e>VhRt$M@p{f6tc_*ZVKLjDn)^B>-c zkvF^)v-_k8%?_Pk!-Jo?341>C=fK&@8lRhrIGcrNgLr-lutcO$7&-_k+kR>r#Q2Bm z@4!*4xMCZg^R@S3{DEB2v@$`5BxZI$j3582>l6`eP((0kiC{+ilh!7f3DtqIFk8$f z;Qa)ak_apTaKv)1h#Qt6qT^?-83H0;dOyWgj{8aH4_L9UkUutwv)=m_Y`OZ?#u}HM z9Lp}K;f_~)Oj-R0f#s@9i*s4qb3cdx81e%G;BprTRuKg=i6pIT07?^p?r%fcC7n95 zxnsEUw$EdFPchC++10a;J%qbn{cecO8@wbSLf|%miAYhuZKN^T*QH6BzfB-JxMy@i zacr&%_!@!OL=cgfjSWDj|1~iX_bahKnPc56ufmq!ezoCzjr^gf)v)7|YcaW3an>?b zZcbT&?TLcB@)>`Xk>wp2U#(F5I=`Lr%_jb)tzoDB+LJ|_a}#Q)v&fgN#NVF(Ry5bl znC0`iia`vVvkg!C+=n3#sGvfb z+7-;vItHwN`E#-U4KD|#q>W?rdoPEp71(=3tD2ldS~`MIk)EbM9<=Ik1!tuS@IxNT zS6{6U`jFpGkv_8e`>d#MI+1V0ze28PC$e4d5UAp+Ad*i%^80BJ731^6D`#RLjI&T`Xm$W#Mv}u3l?mFB?j}? zX7`#{65psEL@R)tyJ)41Q3+E@=%{{e7{RSq{d){6g4H!n+?(U_|NoyMAKzu|8!O?^ zNT@-!iV4gfSwaa=5I|t%vwOE3TA*b7`G+WRsld63NB&sw$3_2|Hq6_Hp^MH}G5u#M zxM$|m*gxElgE!p@slvX-r#D=~5#J7xMaVWmd|H+z{X5f5>FpUaj5q*e%bI&m6tOBH zYraqkQmLc4qaED)dtb-EI@N#W8MLPdaOU-I2PS9zTt>|rzZ~(->ktfP5=&12Ndr(Y zTuP=HD%1oeyE()@*o)=xhr);;o7tbOIHUaH)v<;uuYfu2nn?z!$yAl7dLW~aTr4}5&hnO094oMjBzHsF+5 z*VEnC81R`oqIX%15p2flq_MG;!k~pBZL8M{A`n|Q;m2?OxQbT@v*&V3*#zf*@_NX_ z#~9}~87vZuS)G%%bcSG7#xis1T#D=h_l~YvlubnajYXUtH29RS`csDAGd_AXW|Y4V zHQCZp@%JM){k>=!u+hF>!gVm{N9#t}%jZz^yr`Q9k~y9{tsrT#s}C-&5HD#9mbY_Nuw(=P1S@wO zr*n*U2@D1KSXS`RFWCaMh|)R0n;5$MS*WjBX-)^}-z@Oc5B@j9NobR=?5`ytf-J--bN5pIf67Y;zDJ(~TNXw7 zOfmxCD}N4;;p}(*CT1QlBv5-|0^_&brKBv2>}k$NoBfedCm7dTqN-8EuHPfG-tQ4z zvvUsa*%AcZn>zY^KJ(mQ;+mv^H4$jPiLp_X*Z+xDjgfRp& zprxhmRT5wxZ|gWxy@WV!($~6lrsC|A7&#?JTmt%UTn#z_<4FA$|G4Zp9mB8iduMHz z85TPxP)8}C6Q`K_tCB<*xniy$QFF$`9A5<_Gpu~xWk$v8)VBs0{qw(q98eQOtyFM? z{C0c((D*St`&sAX)1SN%;}bL3cJ`)XldCqqX67(E+d``?arEe zd)Hx1KQyL3t-$O7V9T3ciTkeoxKa^37QngR!pDr0)TcZF=B!S2hrCJzb1sSPfrwy; zvoa>Oga}2N3ktFI`o|`*@f9z^+!N9uX8hj$=p0ql(AQ+f72B3YlO={BI=JK)&cW?F z{+C1gQm0RT>^*qaMceSkH~+5U@D)}VQ6MRUj~Cb_WKzwe|X6`&C8fV@#d!NTcmvZl`z~H5~f> zZD_77K#?i+(Rbe2DEN;Izj&^MU3Nx7Xn2$AdotG76E{9Kt{S_+FgMlq=moIXPuie9;eD#3A8#6y^S2 zjbrZ7eJUU{XR@`P09Ic9Y;}{vZ(nEn--&&&D-djxU!+tKX6k0`r{1$-?#lIl#=g-Y z?0W@({Whpiu58;Nwb`R%UYEp zw^mA9S03z`)~lv2x%}6Vt=S6ai3AHyas-P#&Gxbe#(#dml-Kd1<-d55nkAfplK_%n zVy|w`1mJ+T_yQn4BZ!h*z&jF6!W&kx_zxmmB<}3{xg3M%pNo8=sHS~X&8bf*MLE>) zT*MDy;K#RUf>Gh(#>m;Ybo=YjRH9Xg0cDuARUAp0wuJJtGv&Ky$~zEQ0Z6mINrc+e zomoiUgGPKuPeZrNpMKp`24SWMc4}-7YOBsPn|}(Afoie4efXIILaB{v zI#x>MUMRX>8RM$JO0Gs9CLi5X*nKUn>Q-9th%&5#1vE?&_ZjEB@+cu0R3;p5d9;68;7p`Z` z_c58QSgZkCIwQ+XW#h=UI90;V(}^$#YNfR07&}I9XedNe=(9B0xVa8iCqVn z=wuEvEJl36?k5rTJp!yV8#v-~#__xlygdCy)5|KB&^~gsU^!Ez%HJG@SDmao0_Av5 zX|KiNBsPmvl>~ZDBK95xdyEVj(rZf3*7|DRjOcVM;uzNl$c}&<7+pZ1E=YpJbvZyv zHgpaHMr>3cKQ)Y>^ile4B{qCc0IF<9t16pa6F_a*fCEzivl2C+OJ7ecRmemRbXoCj zzVG(lJaXXK1{& z!g_YCQ!p$8`aHqN-wtOJkTAtQdc9+b@L21 zpJ0n9NQ#h3N%ooLMdX5U0tsgSL>gqVl%R65P<4$Bt4$2RsJfOuO|63x*C(%FW0%0< zs(^0dJRW5?vCs3z9nZtOTvRIwFgJS0P1-frEQfRPg2N*Sxhz=X&Jm(TAbc`~#Twjf zB;#z;FM+_#itQB_lee>oZn+k<9}$WWQTfcjSGXSBy1{q=dg#*!)Xgkegg~$)KUP_? z3hpPK>ebv&4GMNYU($IpR?Kp{WO_0fToEUqd}x=M0@f2HeItWr?p$(2N_!6$P$KTu zDOh9@Evs@O97y`y^gbEHav9(PJm!o5;mbI}q&$`|g7|*T%y%q1@2q0;k7{P_iDPDG zu?rfN&K?HS`#^a`_Tr@a{D`eoM2YwIN+OpmXA>;sem%wXRZ_Ze>cO365l+D@8Jg#g zVD=ablX5~Z9GJr`%TkDF)SGA>+J{C6tK7o`~e>%?Ah*DkgIGUCq0)^0{_dE_Ai`RQB z*1za7vqa1v{#cJhyBG2K#58XFqmN6NEK{%vqu|7l*cM=_VG&d0)9`C- z>Gztr=w#y44VEwHw1Z!{9Q(ib_h>9DewB39_Oq0fZ`lQzP51>Q7NA_e&rRU6OP-07 zniQh9p1E0dzk|Rq4LF~cd#k^(DU7`4D$E^_CM-O?Zw&3dPeicD%P@;=Cecj_A76?h z6FhOtexXUSep|}Ta|8=I_>pPK6+HCaThO*9)KBbob+o59MG3vMnn4W+}^BeXTFXW|yT+U4ex$FSiQmzV`FdY$QkZ{4Pd-Y$3nlZ0*! zK{yc=7=ou-D6;-_m^}oX{r1=5 zuGfAD*r41(vysA{&Pfp?%O#?o;qP|*6j#0Mt+??I-;Y_dMvskAG94bNc7ms{R=@wf zr=n{mTO{|mBpBlc(?!3dMq_|vZEI+kDc9COt*=;iKvzxGWyjiH82}pC*XGs z)A?(u*KV6lyh*bS<~pYCaoSTS3|^%+3R3SjB$p+k7VLw|wET{Tn1 z)I&eRz3=#sYW{uD0*Y-9qm{z2lSgLuFAf03!%GcSGFJ`=r5F&#_wAos1VW;p#J%0{ zS+m657{Z8)`C&YbG(75Q9B zr0)GSTYTgLf#ph;zdM?Z8-i@phaT**Re0pTen%e>U`{Jr_mXFzIkG~*)*ce+j*R8Y zsB6ASs>dwHp0gV^=h((g0-sx%%qvNk8p5^x_OJ^r1$OVn z#hJ&Kd6&o^((Jb1iap;sQ!@*_rC875SupI_Gph|w9z#<6oOm- z02XABR}lf#Q`D(P@KG#!ieuriSkAniK>G#Bs#juj>hUMA;ib<}%qmb{HHfwfwoKgp zn3^c4mpLImrOaHpHJu~5vN-1)mM8usf<+&6Lmy`lod4ra1j!4pLo!c_9r( zh)xyd{SDQgig$;Go*j(qFY z2xa`q(WBV*2X9x?+8a$j8Y=`I`OLS~2t!IpF)0-mXH7d z1R>0X|4(P*IjS#2p=?c?knm66^F{P;$_&h>b_-l_`{yAa+F2aNRO|PaTlkFq^FgAKp_%NTk6FQYxC$DgA;egHfF z;Pb_KhIw>Ks1yD6gp<6D()ob$c(~rezVxn~Z;1&2zB4Ym6%hc5?+zX9X3z2+5E%W_ z@8Iw)cN*=Wg;i&EIWD{PvycxyW{JQbBwa`Z9X6(e7U&2zwgD5-)p-+jln!iiyLDN8 zf=)DLuB<*COrL5tHj53vdI_F>!@t4I9=)GHV(46f+h6e8z?RMSY$NM|NHRK^0hqI3 z5MO+Xg@}L7?P8vMVTmP7q(em+$h1FS#D_y$ecHDiQn^x>?f8-KYZ@B znAN+S^zRC}GYzLb()p3Ga@N~J?il+{ML$!iyPiiW7)14ECyM}dsxeoP=~8!AFgq_e z^WwFT1lqEG9GBhpWp%&Nz|j0)gEA8Dd;ixk`af@m*gB$MIAeW$CJFK?w~BcMfx(oB zV)Agd=6V&AkmGYE*th-LpHvJyWbmnt$>kSj*m3FG)Ffp`nG-D=>7!$8$?E4v(2_df zXBrZbvXFFFG%W=2VVRRe0GzvGu}YCMK3_mbvkW?wAo`U$*trK6fBg@!a{EP?Igp!L zo9i>o?%RjE-tq~wkG3Gz4%?rDVJC~Y!y}n)6Qh1L<}}c= zuK!J(^X?a8{AV3=7N8zV--bE-@X~9LYn#9v0zKuC9-Iowe_x2={RsmQNL*8J?FRFh zz(Yx~M1i1g9pZ^*qlLdZ`-OGd%+DymtX`|Q{X1w)O=I)xmB>A)VXD6`!?x>x1lc)ly zap8@u;HVgyP2-bBbe^!iYUF6SJDH=ovZiL))I^b3fw?hh=IHgWAP#I5IP_QdUyrH09F*NN)kcL!Rg>m_iv#@ILQP+oggCMvxNyO z+npcW$D)SCZweUK>#<$feBHms`5$@%rg!H`{R=lFJ@1}RPGkRH-i-q{@4&=84=KGp zQ?#r1A~wm$vqYd5c6_g4MtD3mAFDm00nt5p!I)f;;#fG2`jkEe8cHzTlH8Jr3Npk|ppU^vhE z-ocMYMdH~Rh&BMD4_us<=9eMQ{oQwB>sw!l8Ko9l$D~~&0Q1{H{cDA(vNbws<{2g* z-LJU#7~0BKFi~H{?ft8V(Z69G`nRsZ;MSFj7HgP0TzGFr13?<0FnG4Wk=q`{&))ZG z%1#G`)rWTL%efQC=o#Hwh`>AV9M`ff}rwQsnjVT0BV{O z0iQ334v`l2AVdo&ZnZ+k}+Z1 z=QAsWYHB7=FIB6xap0S`^%w_t~HVf3D20$}QZs|5a&GO#Cpl6~L~mgYY%N3(H#<`-RYa1{L)oP&+8dnwkw z@DeOLZ+$T(bhJ2cnp|ydSCYNS1yNHmwccLPIyj9Zx893A|M&Zt*zpgLeaniFZYTQ1 zG50H>#N|xX)9(Rw$Q`8<&-fe(P;K~iLp+cY>+|QMSErN!Ob_feD-!`pgBpc%nZ*u5 zdfgI19pNvJ+2^U2IYUqk^`ZaVGckP8`BykM%`@UY0b5j+L%^e#S@s? zxf@6Cc>vQ7Jc`c2!^P%}q1bp-quMx5)(bUm$J%8O-e;e=12WR4$x3wb9k zyiaN*uv>~Gf!p)PWAWTmXhbfZK1;|F3b}YrYEZ;6E3EoC1?09u!1Rotc%eS%ynTvz z`kQ8zGE%FTgSY}sL9;xd4T3UP6GnqiB=2|k}T&UOA`X0trJx*b{>G&NiF8`lMoZkRnCI8h^lr@cB6?S)*SmeIc<0V8BF-1!2Tk<2 zH}GU74X6xmafX45)maXJd7(qi?*wQBYeeu>I)r>4Y|1=Axp1$o((MS2#Bv}7h#>6A zpMo#q@OvDCpM>Y-lE~+&8>iEE0hB_z6)C0}f~h;-Aaiw|W)eUrZWD+CIT>5P!NoaE zESZ6kZ^w2I1#1uKp5z|2AsGZ>0$^f0k2h}cmArZMjZZkSh@)$RuHC@T4oc4V^6)8i98~t2`NG%s8kuJr47JS-0_T2Ga;MZJ4s>RrSfpM(^XA65=idI z4Qv52;t~>qpNCKq_uObpadHZ=F)So1^}93rM7dmS1d1nx1mKBxlcWJB2omcVLW#kM zLGUZpnQDq7P`|L-v1Ftc%sZyvON0X;8PMTvr=AlCMBd^>*T4I=aJiMM%|C5aZNj+Wh-gz&mK)&uv zB;~l8W4WJ11VAaKXhJ*Pito6{pJ{^RO|d z2*r&Z3@-FZu-+9Jo`eLTlbHWL5cdpVfpNr*LCIhli*W{`%3V6WfKepMFr$T;yZ1zAM8P9hZZDXPo3#H8uGxCeS0(Nj3} z%JJQh6xUT{yro2aRlOoAM)|UI{z%;WQ3xhD^iSQ%AWyk3PkI|*v6EO}-YVn+WdcZ* zM+M@0P+hLLu(o`tHN2&d>bjnKHo%FbZpKRw^Xwn*;Rev-;0WzOXs>5a=UvF>Ha;%B|vI;3*q8k>h7UFjwE_fCDMtL zBQ7uJvjl){_4+bApQjV?RF?o%qI(_@9S}`7qijCpi%5eAxbSheGBVB^DCJ^23%X5f~g%_!VHH+^&1FKbdPJQdVl> zNtjZI>d`Rk%H=(jjcJJ3wA-(o@w|`$0TCyMt@Kcr@D@Qiua^&165&Zi04c8RflGt( z!2BZKa!2ZPu26v@9l)WFiF<~iq9v~QtqwOdR1vy$ZTfcs6e2r=gb7y-NRRl*n&v}l zuf!q}W!QW3Dz?%@x#=oB9|)*4SCeHf!CgB}Jnj-|z?<}a&gGe(>!ee=ehu-3P*W&peLGS=whh%cnSR~boS5Mg;|>LZRCgev4T zOrpm;F$bmyrU&sKD$_J$lhqwGD=Gw32yTY}^H?QK;<82k-UWj%$@6`ys)s)lkQw&{Tu%V%W>kVPl1Sz#2WG;&3Hu$Muz+wW t7ZH_j-$6ltN*I-VJwRZW^1SxLKLa}aZ1gvd%;Nw6002ovPDHLkV1mNfkwX9g literal 0 HcmV?d00001 diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index d1af928..d604eee 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -1,14 +1,23 @@ import 'dart:ui'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -class LoginScreen extends StatelessWidget { +class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); + @override + State createState() => _LoginScreenState(); +} + +class _LoginScreenState extends State { + bool _remember = true; + final TextEditingController _emailController = TextEditingController(); + final TextEditingController _passwordController = TextEditingController(); + void _loginWithDiscord(BuildContext context) { - // Cseréld le a saját Discord OAuth2 URL-edre final Uri discordAuthUrl = Uri.parse( 'https://discord.com/api/oauth2/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=identify%20email'); @@ -31,52 +40,244 @@ class LoginScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - body: Center( - child: ClipRRect( - borderRadius: BorderRadius.circular(16.0), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - padding: const EdgeInsets.all(32.0), - width: 350, - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.05), - borderRadius: BorderRadius.circular(16.0), + body: Stack( + children: [ + // Background gradient + Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [Color(0xFF03040A), Color(0xFF071026)], ), + ), + ), + + // Center content + Center( + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 48), child: Column( mainAxisSize: MainAxisSize.min, children: [ - const Text( - 'Login', - style: TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - ), - const SizedBox(height: 40), - ElevatedButton.icon( - onPressed: () => _loginWithDiscord(context), - icon: const FaIcon(FontAwesomeIcons.discord, color: Colors.white), - label: const Text( - 'Login with Discord', - style: TextStyle(color: Colors.white, fontSize: 16), + // Neon badge / logo + Container( + width: 84, + height: 84, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: const LinearGradient( + colors: [Color(0xFF0EA5FF), Color(0xFF2C82FF)], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + boxShadow: [ + BoxShadow( + color: const Color(0xFF2C82FF).withOpacity(0.4), + blurRadius: 18, + spreadRadius: 4, + ), + ], ), - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF5865F2), - minimumSize: const Size(double.infinity, 50), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.0), + child: const Center( + child: Icon( + Icons.menu, + color: Colors.white, + size: 36, ), - padding: const EdgeInsets.symmetric(vertical: 12), + ), + ), + + const SizedBox(height: 24), + + // Frosted glass card + GlassCard( + width: 360, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 10), + const Text( + 'LOGIN', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + letterSpacing: 2, + ), + ), + const SizedBox(height: 8), + // Accent underline + Container( + width: 120, + height: 3, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(2), + gradient: const LinearGradient( + colors: [Color(0xFF2C82FF), Color(0xFF0EA5FF)], + ), + ), + ), + const SizedBox(height: 20), + + // Email field + _TransparentField( + controller: _emailController, + hint: 'Email or username', + prefix: const Icon(Icons.person, color: Colors.white70, size: 18), + ), + const SizedBox(height: 12), + // Password field + _TransparentField( + controller: _passwordController, + hint: 'Password', + prefix: const Icon(Icons.lock, color: Colors.white70, size: 18), + obscure: true, + ), + + const SizedBox(height: 12), + Row( + children: [ + Expanded( + child: Row( + children: [ + CupertinoSwitch( + value: _remember, + activeColor: const Color(0xFF2C82FF), + onChanged: (v) => setState(() => _remember = v), + ), + const SizedBox(width: 8), + const Text('Remember me', style: TextStyle(color: Colors.white70)), + ], + ), + ), + TextButton( + onPressed: () {}, + child: const Text('Forgot?', style: TextStyle(color: Colors.white70)), + ), + ], + ), + + const SizedBox(height: 12), + // Login button (neon) + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 14), + backgroundColor: Colors.transparent, + elevation: 0, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), + ), + child: Ink( + decoration: BoxDecoration( + gradient: const LinearGradient(colors: [Color(0xFF2C82FF), Color(0xFF0EA5FF)]), + borderRadius: BorderRadius.circular(24), + boxShadow: [BoxShadow(color: const Color(0xFF2C82FF).withOpacity(0.3), blurRadius: 14, spreadRadius: 1)], + ), + child: Container( + height: 46, + alignment: Alignment.center, + child: const Text('LOGIN', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + ), + ), + ), + ), + + const SizedBox(height: 14), + Row(children: const [Expanded(child: Divider(color: Colors.white12)), Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: Text('OR', style: TextStyle(color: Colors.white54))), Expanded(child: Divider(color: Colors.white12))]), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + IconButton( + onPressed: () => _loginWithDiscord(context), + icon: const FaIcon(FontAwesomeIcons.discord, color: Colors.white), + splashRadius: 26, + ), + const SizedBox(width: 16), + IconButton( + onPressed: () {}, + icon: const FaIcon(FontAwesomeIcons.apple, color: Colors.white), + splashRadius: 26, + ), + ], + ), + const SizedBox(height: 12), + const Text('By continuing you agree to our Terms', style: TextStyle(color: Colors.white38, fontSize: 12)), + const SizedBox(height: 10), + ], ), ), ], ), ), ), + ], + ), + ); + } +} + + +class GlassCard extends StatelessWidget { + final double width; + final Widget child; + + const GlassCard({super.key, required this.width, required this.child}); + + @override + Widget build(BuildContext context) { + return ClipRRect( + borderRadius: BorderRadius.circular(18), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 14, sigmaY: 14), + child: Container( + width: width, + padding: const EdgeInsets.all(18), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(18), + gradient: LinearGradient(colors: [Colors.white.withOpacity(0.04), Colors.white.withOpacity(0.02)], begin: Alignment.topLeft, end: Alignment.bottomRight), + border: Border.all(color: Colors.white.withOpacity(0.06)), + boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.4), blurRadius: 20, offset: const Offset(0, 8))], + ), + child: child, ), ), ); } } + + +class _TransparentField extends StatelessWidget { + final TextEditingController controller; + final String hint; + final Widget? prefix; + final bool obscure; + + const _TransparentField({Key? key, required this.controller, required this.hint, this.prefix, this.obscure = false}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.02), + borderRadius: BorderRadius.circular(12), + ), + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), + child: TextField( + controller: controller, + obscureText: obscure, + style: const TextStyle(color: Colors.white), + cursorColor: const Color(0xFF2C82FF), + decoration: InputDecoration( + prefixIcon: prefix == null ? null : Padding(padding: const EdgeInsets.only(right: 8), child: prefix), + hintText: hint, + hintStyle: const TextStyle(color: Colors.white54), + border: InputBorder.none, + focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: const Color(0xFF2C82FF).withOpacity(0.9))), + ), + ), + ); + } +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index bea641d..5cecf01 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.3" flutter: dependency: "direct main" description: flutter @@ -148,26 +148,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "11.0.1" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: @@ -265,18 +265,18 @@ packages: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.6" vector_math: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: @@ -294,5 +294,5 @@ packages: source: hosted version: "1.1.1" sdks: - dart: ">=3.7.2 <4.0.0" + dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.24.0" From ae5f6f05607fa659a914d5b3e7836ae70c8202bc Mon Sep 17 00:00:00 2001 From: devbeni Date: Mon, 25 Aug 2025 17:26:17 +0200 Subject: [PATCH 006/148] Implement login validation and toggle password visibility in LoginScreen --- lib/screens/login_screen.dart | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index d604eee..d1863bc 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -14,6 +14,7 @@ class LoginScreen extends StatefulWidget { class _LoginScreenState extends State { bool _remember = true; + bool _obscurePassword = true; final TextEditingController _emailController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); @@ -37,6 +38,27 @@ class _LoginScreenState extends State { ); } + void _handleLogin() { + final email = _emailController.text.trim(); + final password = _passwordController.text; + + if (email.isEmpty || password.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Please fill in both email and password'))); + return; + } + + // Simple email check + final emailValid = RegExp(r"^[^@\s]+@[^@\s]+\.[^@\s]+$").hasMatch(email); + if (!emailValid) { + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Please enter a valid email'))); + return; + } + + // Mock authentication success + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Logged in as $email'))); + // TODO: replace with real authentication; persist session if _remember + } + @override Widget build(BuildContext context) { return Scaffold( @@ -131,7 +153,11 @@ class _LoginScreenState extends State { controller: _passwordController, hint: 'Password', prefix: const Icon(Icons.lock, color: Colors.white70, size: 18), - obscure: true, + obscure: _obscurePassword, + suffix: IconButton( + icon: Icon(_obscurePassword ? Icons.visibility : Icons.visibility_off, color: Colors.white70, size: 18), + onPressed: () => setState(() => _obscurePassword = !_obscurePassword), + ), ), const SizedBox(height: 12), @@ -162,7 +188,7 @@ class _LoginScreenState extends State { SizedBox( width: double.infinity, child: ElevatedButton( - onPressed: () {}, + onPressed: _handleLogin, style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 14), backgroundColor: Colors.transparent, @@ -253,9 +279,10 @@ class _TransparentField extends StatelessWidget { final TextEditingController controller; final String hint; final Widget? prefix; + final Widget? suffix; final bool obscure; - const _TransparentField({Key? key, required this.controller, required this.hint, this.prefix, this.obscure = false}) : super(key: key); + const _TransparentField({Key? key, required this.controller, required this.hint, this.prefix, this.suffix, this.obscure = false}) : super(key: key); @override Widget build(BuildContext context) { @@ -272,6 +299,7 @@ class _TransparentField extends StatelessWidget { cursorColor: const Color(0xFF2C82FF), decoration: InputDecoration( prefixIcon: prefix == null ? null : Padding(padding: const EdgeInsets.only(right: 8), child: prefix), + suffixIcon: suffix, hintText: hint, hintStyle: const TextStyle(color: Colors.white54), border: InputBorder.none, From 582bfe40c57abc1a660b5338ad2e59d880d2c8f7 Mon Sep 17 00:00:00 2001 From: devbeni Date: Mon, 25 Aug 2025 17:30:24 +0200 Subject: [PATCH 007/148] Fix switch active color and remove unnecessary key parameter in TransparentField --- lib/screens/login_screen.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index d1863bc..bc279e9 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -168,7 +168,7 @@ class _LoginScreenState extends State { children: [ CupertinoSwitch( value: _remember, - activeColor: const Color(0xFF2C82FF), + activeTrackColor: const Color(0xFF2C82FF), onChanged: (v) => setState(() => _remember = v), ), const SizedBox(width: 8), @@ -282,7 +282,7 @@ class _TransparentField extends StatelessWidget { final Widget? suffix; final bool obscure; - const _TransparentField({Key? key, required this.controller, required this.hint, this.prefix, this.suffix, this.obscure = false}) : super(key: key); + const _TransparentField({required this.controller, required this.hint, this.prefix, this.suffix, this.obscure = false}); @override Widget build(BuildContext context) { From 841dfbabed95f9566763ac09af4b53e3dc68a6c0 Mon Sep 17 00:00:00 2001 From: b3ni15 Date: Wed, 27 Aug 2025 10:33:55 +0200 Subject: [PATCH 008/148] Implement user authentication with login and registration screens, including API integration and shared preferences for token storage --- ios/Podfile.lock | 7 + lib/screens/home_screen.dart | 15 ++ lib/screens/login_screen.dart | 159 +++++++------------- lib/screens/register_screen.dart | 245 +++++++++++++++++++++++++++++++ lib/services/api.dart | 37 +++++ lib/widgets/glass_widgets.dart | 66 +++++++++ pubspec.lock | 138 ++++++++++++++++- pubspec.yaml | 2 + 8 files changed, 563 insertions(+), 106 deletions(-) create mode 100644 lib/screens/home_screen.dart create mode 100644 lib/screens/register_screen.dart create mode 100644 lib/services/api.dart create mode 100644 lib/widgets/glass_widgets.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 3def93f..07c8f66 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -8,10 +8,14 @@ PODS: - Flutter - OrderedSet (~> 6.0.3) - OrderedSet (6.0.3) + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS DEPENDENCIES: - Flutter (from `Flutter`) - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) SPEC REPOS: trunk: @@ -22,11 +26,14 @@ EXTERNAL SOURCES: :path: Flutter flutter_inappwebview_ios: :path: ".symlinks/plugins/flutter_inappwebview_ios/ios" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" SPEC CHECKSUMS: Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99 OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 + shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart new file mode 100644 index 0000000..818347b --- /dev/null +++ b/lib/screens/home_screen.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class HomeScreen extends StatelessWidget { + final Map? user; + const HomeScreen({super.key, this.user}); + + @override + Widget build(BuildContext context) { + final name = user != null ? (user!['username'] ?? user!['email']) : 'User'; + return Scaffold( + appBar: AppBar(title: const Text('Home')), + body: Center(child: Text('Welcome, $name', style: const TextStyle(fontSize: 18))), + ); + } +} diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index bc279e9..b961886 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -2,8 +2,12 @@ import 'dart:ui'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_inappwebview/flutter_inappwebview.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import '../services/api.dart'; +import 'register_screen.dart'; +import 'dart:convert'; +import 'package:shared_preferences/shared_preferences.dart'; +import '../widgets/glass_widgets.dart'; +import 'home_screen.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @@ -18,26 +22,6 @@ class _LoginScreenState extends State { final TextEditingController _emailController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); - void _loginWithDiscord(BuildContext context) { - final Uri discordAuthUrl = Uri.parse( - 'https://discord.com/api/oauth2/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=identify%20email'); - - final browser = InAppBrowser(); - browser.openUrlRequest( - urlRequest: URLRequest(url: WebUri.uri(discordAuthUrl)), - options: InAppBrowserClassOptions( - crossPlatform: InAppBrowserOptions( - toolbarTopBackgroundColor: const Color(0xFF1E1F22), - ), - inAppWebViewGroupOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - javaScriptEnabled: true, - ), - ), - ), - ); - } - void _handleLogin() { final email = _emailController.text.trim(); final password = _passwordController.text; @@ -54,9 +38,47 @@ class _LoginScreenState extends State { return; } - // Mock authentication success - ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Logged in as $email'))); - // TODO: replace with real authentication; persist session if _remember + // Call backend login + _performLogin(email, password); + } + + Future _performLogin(String email, String password) async { + try { + final res = await Api.post('/v1/auth/login', {'email': email, 'password': password}); + if (res.statusCode == 200) { + final body = jsonDecode(res.body); + final token = body['token'] as String?; + if (token != null) { + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('auth_token', token); + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Login success'))); + // fetch user + final meRes = await Api.get('/v1/user/me', headers: Api.authHeaders(token)); + if (meRes.statusCode == 200) { + final user = jsonDecode(meRes.body); + // In real app, navigate to home with user + if (!mounted) return; + Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_) => HomeScreen(user: user))); + } + } else { + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('No token in response'))); + } + } else { + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Login failed: ${res.body}'))); + } + } catch (e) { + final msg = e.toString(); + if (msg.contains('Connection refused')) { + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Kapcsolódási hiba: a backend nem fut (http://localhost:3000)'))); + } else { + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error: $e'))); + } + } } @override @@ -142,14 +164,14 @@ class _LoginScreenState extends State { const SizedBox(height: 20), // Email field - _TransparentField( + TransparentField( controller: _emailController, hint: 'Email or username', prefix: const Icon(Icons.person, color: Colors.white70, size: 18), ), const SizedBox(height: 12), // Password field - _TransparentField( + TransparentField( controller: _passwordController, hint: 'Password', prefix: const Icon(Icons.lock, color: Colors.white70, size: 18), @@ -213,21 +235,10 @@ class _LoginScreenState extends State { const SizedBox(height: 14), Row(children: const [Expanded(child: Divider(color: Colors.white12)), Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: Text('OR', style: TextStyle(color: Colors.white54))), Expanded(child: Divider(color: Colors.white12))]), const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - IconButton( - onPressed: () => _loginWithDiscord(context), - icon: const FaIcon(FontAwesomeIcons.discord, color: Colors.white), - splashRadius: 26, - ), - const SizedBox(width: 16), - IconButton( - onPressed: () {}, - icon: const FaIcon(FontAwesomeIcons.apple, color: Colors.white), - splashRadius: 26, - ), - ], + // Social login removed per request + TextButton( + onPressed: () => Navigator.of(context).push(MaterialPageRoute(builder: (_) => const RegisterScreen())), + child: const Text('Don\'t have an account? Register', style: TextStyle(color: Colors.white70)), ), const SizedBox(height: 12), const Text('By continuing you agree to our Terms', style: TextStyle(color: Colors.white38, fontSize: 12)), @@ -246,66 +257,4 @@ class _LoginScreenState extends State { } -class GlassCard extends StatelessWidget { - final double width; - final Widget child; - - const GlassCard({super.key, required this.width, required this.child}); - - @override - Widget build(BuildContext context) { - return ClipRRect( - borderRadius: BorderRadius.circular(18), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 14, sigmaY: 14), - child: Container( - width: width, - padding: const EdgeInsets.all(18), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(18), - gradient: LinearGradient(colors: [Colors.white.withOpacity(0.04), Colors.white.withOpacity(0.02)], begin: Alignment.topLeft, end: Alignment.bottomRight), - border: Border.all(color: Colors.white.withOpacity(0.06)), - boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.4), blurRadius: 20, offset: const Offset(0, 8))], - ), - child: child, - ), - ), - ); - } -} - - -class _TransparentField extends StatelessWidget { - final TextEditingController controller; - final String hint; - final Widget? prefix; - final Widget? suffix; - final bool obscure; - - const _TransparentField({required this.controller, required this.hint, this.prefix, this.suffix, this.obscure = false}); - - @override - Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.02), - borderRadius: BorderRadius.circular(12), - ), - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), - child: TextField( - controller: controller, - obscureText: obscure, - style: const TextStyle(color: Colors.white), - cursorColor: const Color(0xFF2C82FF), - decoration: InputDecoration( - prefixIcon: prefix == null ? null : Padding(padding: const EdgeInsets.only(right: 8), child: prefix), - suffixIcon: suffix, - hintText: hint, - hintStyle: const TextStyle(color: Colors.white54), - border: InputBorder.none, - focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: const Color(0xFF2C82FF).withOpacity(0.9))), - ), - ), - ); - } -} \ No newline at end of file +// uses shared GlassCard / TransparentField from widgets/glass_widgets.dart \ No newline at end of file diff --git a/lib/screens/register_screen.dart b/lib/screens/register_screen.dart new file mode 100644 index 0000000..a9dc66c --- /dev/null +++ b/lib/screens/register_screen.dart @@ -0,0 +1,245 @@ +import 'package:flutter/material.dart'; +import '../services/api.dart'; +import '../widgets/glass_widgets.dart'; + +import 'login_screen.dart'; + +class RegisterScreen extends StatefulWidget { + const RegisterScreen({super.key}); + + @override + State createState() => _RegisterScreenState(); +} + +class _RegisterScreenState extends State { + final TextEditingController _username = TextEditingController(); + final TextEditingController _email = TextEditingController(); + final TextEditingController _password = TextEditingController(); + final TextEditingController _password2 = TextEditingController(); + bool _loading = false; + + Future _register() async { + final u = _username.text.trim(); + final e = _email.text.trim(); + final p = _password.text; + final p2 = _password2.text; + + if (u.isEmpty || e.isEmpty || p.isEmpty || p2.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('All fields are required'))); + return; + } + if (p != p2) { + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Passwords do not match'))); + return; + } + + setState(() => _loading = true); + try { + final res = await Api.post('/v1/auth/register', {'email': e, 'username': u, 'password': p}); + if (res.statusCode == 200 || res.statusCode == 201) { + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Registered — please check email'))); + Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_) => VerifyScreen(email: e))); + } else { + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Register failed: ${res.body}'))); + } + } catch (e) { + final msg = e.toString(); + if (!mounted) return; + if (msg.contains('Connection refused')) { + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Kapcsolódási hiba: a backend nem fut (http://localhost:3000)'))); + } else { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error: $e'))); + } + } finally { + setState(() => _loading = false); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [Color(0xFF03040A), Color(0xFF071026)], + ), + ), + ), + Center( + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 48), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 84, + height: 84, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: const LinearGradient( + colors: [Color(0xFF0EA5FF), Color(0xFF2C82FF)], begin: Alignment.topCenter, end: Alignment.bottomCenter), + boxShadow: [BoxShadow(color: const Color(0xFF2C82FF).withOpacity(0.4), blurRadius: 18, spreadRadius: 4)], + ), + child: const Center(child: Icon(Icons.menu, color: Colors.white, size: 36)), + ), + const SizedBox(height: 24), + GlassCard( + width: 360, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 10), + const Text('REGISTER', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, letterSpacing: 2)), + const SizedBox(height: 8), + Container( + width: 120, + height: 3, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(2), gradient: const LinearGradient(colors: [Color(0xFF2C82FF), Color(0xFF0EA5FF)])), + ), + const SizedBox(height: 20), + TransparentField(controller: _username, hint: 'Username', prefix: const Icon(Icons.person, color: Colors.white70, size: 18)), + const SizedBox(height: 12), + TransparentField(controller: _email, hint: 'Email', prefix: const Icon(Icons.email, color: Colors.white70, size: 18)), + const SizedBox(height: 12), + TransparentField(controller: _password, hint: 'Password', prefix: const Icon(Icons.lock, color: Colors.white70, size: 18), obscure: true), + const SizedBox(height: 12), + TransparentField(controller: _password2, hint: 'Confirm password', prefix: const Icon(Icons.lock, color: Colors.white70, size: 18), obscure: true), + const SizedBox(height: 16), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: _loading ? null : _register, + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 14), backgroundColor: Colors.transparent, elevation: 0, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24))), + child: Ink( + decoration: BoxDecoration( + gradient: const LinearGradient(colors: [Color(0xFF2C82FF), Color(0xFF0EA5FF)]), borderRadius: BorderRadius.circular(24), boxShadow: [BoxShadow(color: const Color(0xFF2C82FF).withOpacity(0.3), blurRadius: 14, spreadRadius: 1)]), + child: Container(height: 46, alignment: Alignment.center, child: _loading ? const CircularProgressIndicator() : const Text('REGISTER', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))), + ), + ), + ), + const SizedBox(height: 12), + TextButton(onPressed: () => Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_) => const LoginScreen())), child: const Text('Already have an account? Login', style: TextStyle(color: Colors.white70))), + const SizedBox(height: 10), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ); + } +} + +class VerifyScreen extends StatefulWidget { + final String email; + const VerifyScreen({super.key, required this.email}); + + @override + State createState() => _VerifyScreenState(); +} + +class _VerifyScreenState extends State { + final TextEditingController _code = TextEditingController(); + bool _loading = false; + + Future _verify() async { + final c = _code.text.trim(); + if (c.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Please enter code'))); + return; + } + setState(() => _loading = true); + try { + final res = await Api.post('/v1/auth/verify', {'email': widget.email, 'code': c}); + if (res.statusCode == 200) { + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Verified'))); + Navigator.of(context).popUntil((route) => route.isFirst); + } else { + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Verify failed: ${res.body}'))); + } + } catch (e) { + final msg = e.toString(); + if (!mounted) return; + if (msg.contains('Connection refused')) { + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Kapcsolódási hiba: a backend nem fut (http://localhost:3000)'))); + } else { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error: $e'))); + } + } finally { + setState(() => _loading = false); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [Color(0xFF03040A), Color(0xFF071026)], + ), + ), + ), + Center( + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 48), + child: GlassCard( + width: 360, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text('VERIFY', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, letterSpacing: 2)), + const SizedBox(height: 20), + Text('A verification code was sent to ${widget.email}', style: const TextStyle(color: Colors.white70)), + const SizedBox(height: 12), + TransparentField(controller: _code, hint: 'Code'), + const SizedBox(height: 12), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: _loading ? null : _verify, + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 14), + backgroundColor: Colors.transparent, + elevation: 0, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), + ), + child: Ink( + decoration: BoxDecoration( + gradient: const LinearGradient(colors: [Color(0xFF2C82FF), Color(0xFF0EA5FF)]), + borderRadius: BorderRadius.circular(24), + ), + child: Container( + height: 46, + alignment: Alignment.center, + child: _loading ? const CircularProgressIndicator() : const Text('VERIFY', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + ), + ), + ), + ), + ], + ), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/services/api.dart b/lib/services/api.dart new file mode 100644 index 0000000..a576281 --- /dev/null +++ b/lib/services/api.dart @@ -0,0 +1,37 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; +import 'dart:io'; + +class Api { + static const String baseUrl = 'http://localhost:3000/'; + + static Future post(String path, Map body, {Map? headers}) async { + final uri = Uri.parse('$baseUrl$path'); + final h = {'Content-Type': 'application/json', if (headers != null) ...headers}; + try { + final res = await http.post(uri, headers: h, body: jsonEncode(body)).timeout(const Duration(seconds: 8)); + return res; + } catch (e) { + if (e is SocketException) { + throw Exception('Connection refused (is backend running at $baseUrl)?'); + } + throw Exception('Network error: $e'); + } + } + + static Future get(String path, {Map? headers}) async { + final uri = Uri.parse('$baseUrl$path'); + final h = {'Content-Type': 'application/json', if (headers != null) ...headers}; + try { + final res = await http.get(uri, headers: h).timeout(const Duration(seconds: 8)); + return res; + } catch (e) { + if (e is SocketException) { + throw Exception('Connection refused (is backend running at $baseUrl)?'); + } + throw Exception('Network error: $e'); + } + } + + static Map authHeaders(String token) => {'Authorization': 'Bearer $token', 'Content-Type': 'application/json'}; +} diff --git a/lib/widgets/glass_widgets.dart b/lib/widgets/glass_widgets.dart new file mode 100644 index 0000000..50596af --- /dev/null +++ b/lib/widgets/glass_widgets.dart @@ -0,0 +1,66 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +class GlassCard extends StatelessWidget { + final double width; + final Widget child; + + const GlassCard({super.key, required this.width, required this.child}); + + @override + Widget build(BuildContext context) { + return ClipRRect( + borderRadius: BorderRadius.circular(18), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 14, sigmaY: 14), + child: Container( + width: width, + padding: const EdgeInsets.all(18), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(18), + gradient: LinearGradient(colors: [Colors.white.withOpacity(0.04), Colors.white.withOpacity(0.02)], begin: Alignment.topLeft, end: Alignment.bottomRight), + border: Border.all(color: Colors.white.withOpacity(0.06)), + boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.4), blurRadius: 20, offset: const Offset(0, 8))], + ), + child: child, + ), + ), + ); + } +} + +class TransparentField extends StatelessWidget { + final TextEditingController controller; + final String hint; + final Widget? prefix; + final Widget? suffix; + final bool obscure; + + const TransparentField({required this.controller, required this.hint, this.prefix, this.suffix, this.obscure = false, super.key}); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.02), + borderRadius: BorderRadius.circular(12), + ), + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), + child: TextField( + controller: controller, + obscureText: obscure, + style: const TextStyle(color: Colors.white), + cursorColor: const Color(0xFF2C82FF), + decoration: InputDecoration( + prefixIcon: prefix == null ? null : Padding(padding: const EdgeInsets.only(right: 8), child: prefix), + suffixIcon: suffix, + hintText: hint, + hintStyle: const TextStyle(color: Colors.white54), + border: InputBorder.none, + focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: const Color(0xFF2C82FF).withOpacity(0.9))), + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 4496490..c82ce80 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,6 +49,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" flutter: dependency: "direct main" description: flutter @@ -144,6 +160,22 @@ packages: url: "https://pub.dev" source: hosted version: "10.10.0" + http: + dependency: "direct main" + description: + name: http + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" + url: "https://pub.dev" + source: hosted + version: "0.13.6" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" leak_tracker: dependency: transitive description: @@ -208,6 +240,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -216,6 +280,62 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" + url: "https://pub.dev" + source: hosted + version: "2.5.3" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: a2608114b1ffdcbc9c120eb71a0e207c71da56202852d4aab8a5e30a82269e74 + url: "https://pub.dev" + source: hosted + version: "2.4.12" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" + url: "https://pub.dev" + source: hosted + version: "2.5.4" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" sky_engine: dependency: transitive description: flutter @@ -269,6 +389,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.6" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" vector_math: dependency: transitive description: @@ -293,6 +421,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" sdks: dart: ">=3.9.0 <4.0.0" - flutter: ">=3.27.0" + flutter: ">=3.29.0" diff --git a/pubspec.yaml b/pubspec.yaml index 54c0ef5..f956473 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,6 +11,8 @@ dependencies: sdk: flutter flutter_inappwebview: ^6.0.0 font_awesome_flutter: ^10.7.0 + http: ^0.13.6 + shared_preferences: ^2.1.1 dev_dependencies: flutter_test: From cb2568a866589dac6729f49b22a0b30ac4f8d56b Mon Sep 17 00:00:00 2001 From: b3ni15 Date: Wed, 27 Aug 2025 10:47:57 +0200 Subject: [PATCH 009/148] Add AppIcon image for iOS application --- .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 544 -> 5011 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 442 -> 2625 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 721 -> 8383 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1031 -> 14267 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 1443 -> 22635 bytes ios/Runner.xcodeproj/project.pbxproj | 4 +- .../Icon-App-1024x1024@1x.png | Bin 10932 -> 224066 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 295 -> 750 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 406 -> 1977 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 450 -> 3627 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 282 -> 1284 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 462 -> 3499 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 704 -> 7018 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 406 -> 1977 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 586 -> 6029 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 862 -> 12420 bytes .../AppIcon.appiconset/Icon-App-50x50@1x.png | Bin 0 -> 2747 bytes .../AppIcon.appiconset/Icon-App-50x50@2x.png | Bin 0 -> 9009 bytes .../AppIcon.appiconset/Icon-App-57x57@1x.png | Bin 0 -> 3350 bytes .../AppIcon.appiconset/Icon-App-57x57@2x.png | Bin 0 -> 11326 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 862 -> 12420 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 1674 -> 19501 bytes .../AppIcon.appiconset/Icon-App-72x72@1x.png | Bin 0 -> 5011 bytes .../AppIcon.appiconset/Icon-App-72x72@2x.png | Bin 0 -> 14267 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 762 -> 5526 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 1226 -> 15313 bytes .../Icon-App-83.5x83.5@2x.png | Bin 1418 -> 17458 bytes lib/screens/home_screen.dart | 95 +++++++++++++++++- lib/screens/login_screen.dart | 4 +- lib/screens/register_screen.dart | 8 +- lib/services/api.dart | 2 +- lib/widgets/glass_widgets.dart | 10 +- pubspec.lock | 88 ++++++++++++++++ pubspec.yaml | 10 +- 34 files changed, 203 insertions(+), 18 deletions(-) create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index db77bb4b7b0906d62b1847e87f15cdcacf6a4f29..5bbca0e6d237ffa4c5a481762254ebd06469a1d0 100644 GIT binary patch literal 5011 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 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/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 17987b79bb8a35cc66c3c1fd44f5a5526c1b78be..f288cac1164fd4f36435b206e146ecc170088c65 100644 GIT binary patch literal 2625 zcmV-H3cmG;P)Y=Vl^wxAf3meK&}L$sPer>vvck| z&iuab`+dLjowIgb(*lng0DjP4-dDdp{|vv+e|X~ThMpJKV7?1ArW{vYDDvC5hEms9 zfU%DCsj^?|~C9|-kfj1}&e0vqj@yXG6f z)QZ!YfHQth&~ID#Mn0#w?&am-=IBy}`nlkmcj*za!Cp?Xu16hXzc7n!=m}(9X`C3U`Y3kBXyz+qX&;+V9&pa zL1aX3Oh%DAB+sK_CV6#6*n##(C#C3Qq&&~*VH0q>Spv7`pn1g#EWH04J7+Ej3{rW6%ZOO6{Gt@NOpCh zZ^u8d@ZK-sldJB<>>HM$YyDHfC)~WG5OX66RWx^F#|LEfZGoStotmfB)=;YNLod~l-Kf6uq%QW9*ju?ta_QWUIP}cz6YcG4-@$R0NIbo z^90_Tl%9v;Ff*y?`2`{z8j~K&490M7>rS+P|JxXT`yfUSB$Xo3!APws@zX^xeZU z%1*6}7PqoOvx@^a17N8Mt41a;DG-;+!Ch|>)j8+s@W@+~OP{`OFsXZYv7gOG(C<%*jTNk4h2A9V}bm7^35b%7X_`LF>MszIFtkREATvILod z6ge*d&yNcqjo@29dQ#Ov36(dN9z>4M6@~-O>-xu51zr~Ep&`s#)G8e%92Sd|7e2^g!569xiKo`mBDn(eyEP~|yGCoNOzV?66QMv}|J&7?^uY5;RhQAMi|f#@Q{ zMJ_c(b5WfFY=YEhsOj)`t23ZN6X3O%b4YggkXqCtHoHky zn4B_114hr>ecMVTYDfk}6qvE7(Q^%VLJn{5KZ^c=i|{A6SOWE}El3XxOG*_icFG!1 z?jhxQ!SkHpypx>3=7TtBa^g>ttDyXhz#t zK9AZfuf)kmHj;DHD$UVVX?gnaF{?1ZQxwWb&+wv+K7QuKZCL*6pJT}b_n>FvR{v2c zt)48zMD$b?m;%rEx|x=si7U{!XffKpekXdL*({s_XIw=fT?KulW2!KKHs&C$fj&F@E#!O)x$zXH&h#Sn{yFsj_-{y^e4pM+%H?NnSeE2^uc#<^R`NVe19&s? z!I#*qNIsWnaAD^#tCi*qBUMrneg*l_{TBvusArC;qOS-expsUCsZ}z-9N64A3nv3p%JRL%p{n z&hcQAR|C@9i=vFyhf{_!g$17mEfzU!S~6OyDX(cmm|px8*`0=Kl+@bWl@irBvuIyd zzB4qyG(>q>M8qhu3-(vbmC7Z&?)Qx-P+x7Z5XH0=Fy!SC1P)f_q-(g-C{#JA`)Q9=^KQ;=L zp+~eI1#WnkMeg~AAh>^-4XEJdkd~XzL@A>+CXmd)>)|NO(12p9Qo3$2RV4UFVK@hv j!F&IjdX7cB&)fe2>In3UJH@5<00000NkvXXu0mjfotFsQ 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@Uz$RG%UV$`^@q9%q!;}BdiMiMjVBBI8XL`}rRS(23) zhl~nQ6BlN{DGQCpNSwd{jSMy|bVEZ=K#zZZ!>!bCPSvTp_r3qS|L+D%A9t=>wa+>G zoH|wacRsjey@JXBD7c~zd6$me|5bF%_p9h;6&;6t`3&Ea(X}F6=6A?ClK1)QGKEaE zD?`#ob0%q9ybVuXFaQujER}#<`coSO?85JLf=A)>S|y0Ec=b%8=&-h)Mvh5{-|QK}faA z3{u{&q?c}h^R>CG;Y6;LOP*@C?Y2YHpRwDLb1n<63`PQa#x|M_J_II3`L$~!M5fKtvv5@Kc{W&S_$Gck2!r1dGl zqRuL-7lIW$7(X9B5WTbe_4!9K3n{tO@DQzt=6LQF0#fo=K9f?A@^w^E5d6K8U}E7$ zAf_4}8b`88tv<;#sfB zT{PMcq{M#IwzNp$R8dbaa8pOU@X%A1Jmz8uXIn&c;&3iRThnKRKx8Z*`IwmQ!ufKY z5vbmjMCbh|whEM9){~A}dzF(7wP(}S2L_b2=xo^t>y6`XuIQ_zh@ zRIKTd=Fg?IRmW+YdzEgX>f#hT5DVH`PEN7%sj55?|0lsMfE!LY`4&D>i5+|NlC+XI zf=cPW6!`%22m5$(Jrx~Ygp#vH##|o80Y1V}0niNogm~12kTUJS=?#8?y{{;QOG#)( zo|2`KnN+-;cac6|u9x*{z~Ypg>kJ7sp@9OJQs%J~N{WORoeEY^m5)d|!lqVANM&Io ztCCzEoo7p`ct=n0WF?DFHQh=sBNL^v5^)IwTod`2dois_*Xx%2a0v&B}LK~|&P zny`pWSVmesD~2M+ULfSQ3It&+#4#^k$r)TPfB$|FU5H(GJ3DUInGmcbninZm(y>ek z$!NI8ye7_(=G%MgWD%)=5d4QN3^;+D6$rp1oaaD8QklP}my=%Hk~{8ZzIXrS{*>}E zsk7t%Mk!}`IW>D(B!~iJ4?6F&AnJ5aEm%RR@N^`BZneKdKXZ=ut*|->^dzD_f3B+j z#V^r(fXM|h@0W0sF}*+Mw4Mc(X>e3ZIbJ(uhq3^o0XG6Wr)zp!)8{Sl^aI_?&vVe= z8%AJyz|DSJ2%#nRYY5gN`p4}%Wl<0{-t{G3)sS+fqiyMki{K}ac|k@kb)Te?b5bjcV!BLf_=$VT?^01B?V$^q z0E%g(Mxa{9%Agy78)Cm-UvAJnbe<{5JY!0y2vI|wC&_dY6g5FlKv)P+pxnvDEqS178Rm$h5aog7U@MCTTk>Hk1R&yit5tc>>Y4z(HlTm~ zWC{K5*gR+UJNnu2ab5Kc^7ZS`Sh*Ynr>)SJ>S)ijF}vqs%W+f=aQ2l;IYGz;P6Mnrkn87LtbxdJU*ODKysQIy0&;3$S^L<3&$r(+Fr zeSppx0Sq|}@6>eES;z1b&%v^bw_@nbvoUb`1`MoQt}o}dT7xh9ck4Rzwlm$r)C2o4 z_2awH+Is*8Z{3c`d+q@SN1XQCpB6?oMS^bGceysUC?LwnkHEd46s9g-$tx@Or_%7U zDy)>?%i%mlC|>i4YK->RNxQA~Yi+F$lK?dM4gK5y2-aQoBAors-_V+^(4NYCb>{Zm z$Vk7ZHPJ#b-A2B005!8xPLC5*s}FZJyEEeHC?-ng;?t$40u2%`@2ZRM?sY-2MKy4qtqJcy1ds%KlG~+cU!9I4_a?D z-T-g*J2~>%8Jv6LUtr{kXKO8X)#YOb^fr!s{~_%A;8$_@_Pfz}cpPeW)=@;gKz(c! z16$T(^!zPY_rhmj^z73xyI-OCsFCv;Ty*{0@Zdk*gk9I&fNbRo=N3S1&#dA5FMThL?R*5v1U&6&O-&ug-A$vqJb;oT*m@YaHTuvVKa9gan84vX?#0e) zugA)lJQLfleHHShtFihQuEdhdFT(%5=#9wMuGW@hBuIllMg7P`2wE^mpm#5#0OVqY zte0eczF+WBWR)38)Z<6Fc?dUaWC8U-eR=>RTi4@)>mB&@!3^z*NAR`tuhoh<=p3X0 zyffo?+fqd{fFI2@)Lax}-dS*HOVQ7!)!G^V7~9|ScR2U`uhvdlVQAwvoPWc+aL2E` z30S+rg{{_-Y0O}QpfAvGvcc!PI>P8XAM0AGi_wK6MK)ronF>)4v(#B#YSqJf{*O5Cr8x2;KbJCWIY? z(mvTcv>v0%tG5R=@+R zhTY~v!#MYYSL^t^K%dt9Z(Q;kwEJ|Z)7As6_N3Ez3qFN|R{J}_0;B+>^H)4^!%+=6 zQd>H{ea7NV9g}oOpdAr-ERGd~ zTu?8^tEAbb_cHLwfQv1_Yd=v?v%uCrc_k*d7upYJxbM$DhL$r(EEc+@wKP_KDJzQ1y(-iXL076e;Xrbti;X_|Emj) zt@AaZa?6FL<{9G?pv3zNEVTG2DDDh9Sdq`E^!#iI6;7A)I(Br+{6B=@Ez7a|*-uAj zLSf=ZJ8p&Sc7jZ`i8B4e2e@O^kFEKpS?&t$|>1iY*uwIygF-1pZvqp@}! zM$bAQYhL`zIQY#U;pm-ryE^KeM>4|ib2R9e)_~r(Fd>A2SU^AE%B#buy7qthdsuVjGtswn6IML;dD!)S zO+&+jF8nn=V|~UKsGNk!)25YS;PDDT0?iHO!fC>)7l{u0=|mCpv(_65s`sOB)oED! zqGw~~A>i?kjjLXu;>%GAg3Pog z1fm3P_&_B1SCGGJTMZY#7q1)8k_trpLE z$(AY$On;+}zIqLfM$IoPs_C8E@7|4Xe)kSd|Ax@Ogwbv1=s=+l^%X1789x~J1w6h$prQqoJOaA}e$}x&FHNx)|3p5fZ_66ghx=^; z^uT9saa3b8-~Kqo&~`E%UV?YO>w~!H#t&j_bR=2?;N1+O9nqdZrI8A01t~PZ-@0u( zf)9Y()(Cvlj!p|RyB-CerGqnVq$5w*tS#aQrKZ^*ai3|Bw{QzMp2DEZtw@B)_@ASq zmcrOGpKPtXb#w+TLqE$01?}+9IZIWq<17DnKbEh43i8GXI?cArh3SaO%o)`3+yZKs z!bgL1MH;E=(7vM6Zfaaxx(@9V8hw~LvIp6+4G4)mIoT4Hu1xJeVuLqhphMbfkN%KX zVaT;fwGiSi%mwuF0afQc=Y(UgmVA!Qlg?>nAKtjeDtr6jQNf+b5<(y2XK0xe^w=tN zOoxYD$CVapAs2I%nkw2N@GqgiTwSTkFFE3B7W^ zXd6XACnkwF3JSeRdnW*{IF4u`83;|!U~v63Lc6P!wtI<*kT+XO@_?V?ilNYQH=W$=aoL@_TKk;&$QIITxez<{N zQN;On2l>c=+Z~_K0;m)HsN^TW@Z%A=fR=~-8T{u=ew(zbU?-dY7<{^qnN+l+F!Rj( zCOtL?;7dVpqf$JMzf|}Dm29gjmtiRnZUCPqi0&&~e#o0WcY-xGeTM2`3n;Zs4!~0I z#cNC5$l?<=sVCp2rU-4*arDf?hcL2D4=hdM z&1l#FV$Sv@?MO;{Rc)1iNwg~yzDT9-km;59oi#lc@N%A>s(5b|CMWKN^XiA^>rj$L zWpaTm?e{k@{lG)k)CV`N(!qxbHya_c;E8 zlq3dE5w*Cw8!MKeb;MQOI?@W=^Qn-;;ul!*YOoUxuPoeQzO^Vf(wx(rKY8zN8`|Z| zhBOu?eB{(FJ5`Z*GoVBxYWYhdEGdMDNo15(bEEYl0h=do>_|SWx^9e(xb&1VnUWd! z`3Da?Qy^2>ap7GmT`XWeHM655llGj-5eE&hY8{M!?+%SofnuhH(Pumf$L_qB^6WIc zw_B&7nFb`A8OQ5>_ezY8jRw$=Mn5U7RQW8|M)U5YhmPW}KlYzGv?VJ@S6kEZ@cL!8 z>1Hw54k}_zu(uSUft+Hn8P7I~W7C+~cNF!pW!U)ZSK!X8 z-={63&y7MA4ccs79jK{ky!V~2#~ZKtjYZ7`6*|P6(f;ReZu}pjJdv;B8N7NQ`p;Nn zyWLn0O#OIgP$V9)gO{%hi&#KOobX)Zfwb^-IY%m&j*!+Y9mCY_-55J}8J1mo1}SvI z%>#fx#Gno}Cve#%7c8h#l|>74iKZ9-v0pTeN;6+arZBYO3>(HyYlSJyO6viUuZsF9 zBDDnwAsL9BKt)PKJYec+lg6}MrZI0|^6tAZdhP{i9j#&MQ_jPYJGQ%-vZ5KBu&HP1 z8oc6FZ^6eu@@{O}bh>y^g*7CBPr3Q-L|(69`;Pl?<7dC_oV1OKIBiZVHtPN8UtPoS zS?iJO@c-^VxZWiV{Twy*$q(uz4J}9j3o&y=4pB~)Q+AQTFWmOvtv|xX-^#QAfMu6& z#nF2n&~0zqHA3!d7I-1*`ly@A1VR$^$|S~L%8?SJ#fkgZ;=u|5(kTFhC<&${Mjj&z)Y=(tA| zbUZ@f=zyG6MpJz?THj+A%#PvvuXqQ}|NFOUgK2tJaU zO~T46i>M3Rak%33(*{(!M;y_!!Fcy zQ-g}K+@!??tp}1{y30jbeid_7p-|Pv`t;?cT(4?qCm%sJFoF%gayib*Zg5usCj?nK~?YZV?0^Ik^y^vDr4=>I1XVS@-+l8*akp-}zN^Ci`*r zpS}zafAQOPaO|c8$jRC2DC#J9@l#a_n*}eL;q&yoPLzdEUM!q72BCI6gq6?v8GGNz zSsC_!={C)pvjn(UtK?_z(uKjtgOe136U5?LfGxC`)@mGm3Sx~}<#>N756g8nJ6nA?$OCP{OKZ#8n3ZT+k3jufxs{d>WH??F2@axsNOCl0{y&$bN+>AO(XmrT#1XJS+^>gTYKw z+xq8Sf)zjiY&10BjU^iVPv4APe|xj8cG6jCdn(Y6UAxpIN6e`RsrgkFkcOO9B_s80msOwYtcANfPf?%Rj&z4Yx+qvmTy zv3#+R8cFYx+9nfg_IrffMOfy;kG*?w;Z1KxzT^yjOAYyO2j6#R|eG<-l z_q#CjXrIPaVPI{Bd*1T5C@@E01)aXk4`*J+yAjC|<|tor%qW7RKe&0U#k188F6p8c3KOC0wf(ztZAfz>gx z;WUh#yAea1mTIP|+YhwuTeQ{=uFG)v)?K*cx8IIVzqXE+1{hOBJG1mz6h}QXw9hFB znFT!_%}=RF3L^|2Pm%!mMJxok4q2K&@D2XMk6Lit4IKpyEye9GeG}Hb;tFi~%_}sG zkD+-8m^omcZJ@DwBl_2E^bx0@2hs{Xv(Hqc?95xgjw&a1?8eug_8zn!)ZDguiH