From a8ff7802489b6fefb605e3f2a0ce8d3186ab1532 Mon Sep 17 00:00:00 2001 From: tkrmagid Date: Sat, 22 Aug 2026 15:08:51 +0900 Subject: [PATCH] Revert to spec's free web plan + PWA install (iPhone/Android, $0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 명세서 준수: 네이티브(Flutter/Kotlin) 경로 폐기 — 유료 iOS 개발자 등록·맥이 필요해 비용 0 원칙과 명세서에 어긋남. - app/(Flutter) 전부 제거, 원래 웹 클라이언트 복원. - PWA 추가: manifest.webmanifest + sw.js(오프라인 캐시) + 앱 아이콘(192/512/apple-touch). → iPhone Safari·Android Chrome에서 '홈화면에 추가'로 전체화면 앱처럼 실행, 스토어/맥/등록비 불필요. - Cloudflare Pages 무료 배포 대상. 서버(Workers) 계획 불변. --- README.md | 4 +- app/.gitignore | 48 -- app/.metadata | 33 - app/README.md | 17 - app/analysis_options.yaml | 38 - app/android/.gitignore | 14 - app/android/app/build.gradle.kts | 49 -- app/android/app/src/debug/AndroidManifest.xml | 7 - app/android/app/src/main/AndroidManifest.xml | 45 -- .../kotlin/kr/tkrmagid/tetrig/MainActivity.kt | 5 - .../res/drawable-v21/launch_background.xml | 12 - .../main/res/drawable/launch_background.xml | 12 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 544 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 442 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 721 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1031 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 1443 -> 0 bytes .../app/src/main/res/values-night/styles.xml | 18 - .../app/src/main/res/values/styles.xml | 18 - .../app/src/profile/AndroidManifest.xml | 7 - app/android/build.gradle.kts | 24 - app/android/gradle.properties | 6 - .../gradle/wrapper/gradle-wrapper.properties | 5 - app/android/settings.gradle.kts | 26 - app/ios/.gitignore | 34 - app/ios/Flutter/AppFrameworkInfo.plist | 24 - app/ios/Flutter/Debug.xcconfig | 1 - app/ios/Flutter/Release.xcconfig | 1 - app/ios/Runner.xcodeproj/project.pbxproj | 647 ------------------ .../contents.xcworkspacedata | 7 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/WorkspaceSettings.xcsettings | 8 - .../xcshareddata/xcschemes/Runner.xcscheme | 119 ---- .../contents.xcworkspacedata | 7 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/WorkspaceSettings.xcsettings | 8 - app/ios/Runner/AppDelegate.swift | 16 - .../AppIcon.appiconset/Contents.json | 122 ---- .../Icon-App-1024x1024@1x.png | Bin 10932 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 295 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 406 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 450 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 282 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 462 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 704 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 406 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 586 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 862 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 862 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 1674 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 762 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 1226 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 1418 -> 0 bytes .../LaunchImage.imageset/Contents.json | 23 - .../LaunchImage.imageset/LaunchImage.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/README.md | 5 - .../Runner/Base.lproj/LaunchScreen.storyboard | 37 - app/ios/Runner/Base.lproj/Main.storyboard | 26 - app/ios/Runner/Info.plist | 70 -- app/ios/Runner/Runner-Bridging-Header.h | 1 - app/ios/Runner/SceneDelegate.swift | 6 - app/ios/RunnerTests/RunnerTests.swift | 12 - app/lib/engine.dart | 403 ----------- app/lib/main.dart | 34 - app/pubspec.lock | 213 ------ app/pubspec.yaml | 89 --- app/test/engine_test.dart | 204 ------ apple-touch-icon.png | Bin 0 -> 20316 bytes icon-192.png | Bin 0 -> 19670 bytes icon-512.png | Bin 0 -> 24935 bytes index.html | 10 + manifest.webmanifest | 17 + src/index.template.html | 10 + sw.js | 32 + 76 files changed, 70 insertions(+), 2520 deletions(-) delete mode 100644 app/.gitignore delete mode 100644 app/.metadata delete mode 100644 app/README.md delete mode 100644 app/analysis_options.yaml delete mode 100644 app/android/.gitignore delete mode 100644 app/android/app/build.gradle.kts delete mode 100644 app/android/app/src/debug/AndroidManifest.xml delete mode 100644 app/android/app/src/main/AndroidManifest.xml delete mode 100644 app/android/app/src/main/kotlin/kr/tkrmagid/tetrig/MainActivity.kt delete mode 100644 app/android/app/src/main/res/drawable-v21/launch_background.xml delete mode 100644 app/android/app/src/main/res/drawable/launch_background.xml delete mode 100644 app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 app/android/app/src/main/res/values-night/styles.xml delete mode 100644 app/android/app/src/main/res/values/styles.xml delete mode 100644 app/android/app/src/profile/AndroidManifest.xml delete mode 100644 app/android/build.gradle.kts delete mode 100644 app/android/gradle.properties delete mode 100644 app/android/gradle/wrapper/gradle-wrapper.properties delete mode 100644 app/android/settings.gradle.kts delete mode 100644 app/ios/.gitignore delete mode 100644 app/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 app/ios/Flutter/Debug.xcconfig delete mode 100644 app/ios/Flutter/Release.xcconfig delete mode 100644 app/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings delete mode 100644 app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 app/ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings delete mode 100644 app/ios/Runner/AppDelegate.swift delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json delete mode 100644 app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png delete mode 100644 app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png delete mode 100644 app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png delete mode 100644 app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md delete mode 100644 app/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 app/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 app/ios/Runner/Info.plist delete mode 100644 app/ios/Runner/Runner-Bridging-Header.h delete mode 100644 app/ios/Runner/SceneDelegate.swift delete mode 100644 app/ios/RunnerTests/RunnerTests.swift delete mode 100644 app/lib/engine.dart delete mode 100644 app/lib/main.dart delete mode 100644 app/pubspec.lock delete mode 100644 app/pubspec.yaml delete mode 100644 app/test/engine_test.dart create mode 100644 apple-touch-icon.png create mode 100644 icon-192.png create mode 100644 icon-512.png create mode 100644 manifest.webmanifest create mode 100644 sw.js diff --git a/README.md b/README.md index a290774..455345b 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,7 @@ TETR.IO 스타일의 **모바일 실시간 대전 블록 스태커** 웹 게임. 이 문서는 앱 제작을 위한 **최종 빌드 진입점(entry point)** 이다. 모든 설계 결정·수치·에셋의 **정본(source of truth)은 [`TETRIG-최종명세서.md`](./TETRIG-최종명세서.md)** 이며, 구현 시 반드시 명세서와 UX 목업을 함께 열어 작업한다. -> **클라이언트 변경 (2026-08-22 사용자 결정)**: 플레이스토어 + 앱스토어(아이폰) 동시 출시를 위해 클라이언트를 **크로스플랫폼 Flutter (Dart, Android + iOS)** 로 제작한다. 소스는 [`app/`](./app). 코어 게임 로직은 UI와 분리된 순수 Dart 모듈 [`app/lib/engine.dart`](./app/lib/engine.dart) 에 있고 `flutter test` 로 검증한다(SRS 킥테이블·7-bag·T-spin 판정·점수·좌표 등 §4·§13 데이터는 그대로 이식됨). 서버 계획(Cloudflare Workers + D1 + WebSocket)은 변경 없이 유지된다. 초기 웹(HTML) 프로토타입(`src/`, `index.html`)은 검증된 **동작 레퍼런스**로 남겨둔다. -> -> **iOS 빌드 제약**: Android(APK/AAB)는 리눅스에서 빌드 가능하나, iOS(.ipa)·앱스토어 제출은 **macOS + Xcode** 가 필수다. 맥 한 대 또는 클라우드 맥 CI(Codemagic 등) + **Apple Developer Program($99/년)** 이 필요하다. 이 저장소는 iOS 코드베이스와 CI 설정까지 포함하되 실제 iOS 바이너리는 맥 환경에서 빌드한다. +> **비용 0 · 아이폰/안드로이드 모두 지원 (2026-08-22 확정)**: 명세서대로 **웹 게임 + PWA(홈화면 설치)** 로 간다. Cloudflare Pages(무료)에 배포하면 iPhone Safari·Android Chrome에서 그대로 돌아가고, "홈 화면에 추가"로 전체화면 앱처럼 실행된다(`manifest.webmanifest` + `sw.js` 오프라인 캐시 + 앱 아이콘). **맥·Xcode·앱스토어/구글플레이 등록비·Apple Developer 멤버십이 전혀 필요 없다.** (네이티브 iOS 앱만 유료·맥 필수라 웹/PWA 경로가 무료로 크로스플랫폼을 달성하는 유일한 방법이다.) 클라이언트 진입점은 [`index.html`](./index.html)(빌드 산출물), 소스는 [`src/`](./src), 서버 계획(Cloudflare Workers + D1 + WebSocket)은 명세서 그대로. --- diff --git a/app/.gitignore b/app/.gitignore deleted file mode 100644 index 79f7eca..0000000 --- a/app/.gitignore +++ /dev/null @@ -1,48 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.build/ -.buildlog/ -.history -.svn/ -.swiftpm/ -migrate_working_dir/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -**/ios/Flutter/.last_build_id -.dart_tool/ -.flutter-plugins-dependencies -.pub-cache/ -.pub/ -/build/ -/coverage/ - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json - -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release - -# Widget Preview related -.widget_preview/ diff --git a/app/.metadata b/app/.metadata deleted file mode 100644 index a069333..0000000 --- a/app/.metadata +++ /dev/null @@ -1,33 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: "6655482ec06e547f90abf8ae7590466f4415978d" - channel: "stable" - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: 6655482ec06e547f90abf8ae7590466f4415978d - base_revision: 6655482ec06e547f90abf8ae7590466f4415978d - - platform: android - create_revision: 6655482ec06e547f90abf8ae7590466f4415978d - base_revision: 6655482ec06e547f90abf8ae7590466f4415978d - - platform: ios - create_revision: 6655482ec06e547f90abf8ae7590466f4415978d - base_revision: 6655482ec06e547f90abf8ae7590466f4415978d - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/app/README.md b/app/README.md deleted file mode 100644 index ab9daaa..0000000 --- a/app/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# tetrig - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter) -- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) -- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources) - -For help getting started with Flutter development, view the -[online documentation](https://docs.flutter.dev/), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/app/analysis_options.yaml b/app/analysis_options.yaml deleted file mode 100644 index cedcc10..0000000 --- a/app/analysis_options.yaml +++ /dev/null @@ -1,38 +0,0 @@ -# This file configures the analyzer, which statically analyzes Dart code to -# check for errors, warnings, and lints. -# -# The issues identified by the analyzer are surfaced in the UI of Dart-enabled -# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be -# invoked from the command line by running `flutter analyze`. - -# The following line activates a set of recommended lints for Flutter apps, -# packages, and plugins designed to encourage good coding practices. -include: package:flutter_lints/flutter.yaml - -analyzer: - exclude: - - build/** - - android/** - - ios/** - - web/** - - windows/** - - macos/** - - linux/** - -linter: - # The lint rules applied to this project can be customized in the - # section below to disable rules from the `package:flutter_lints/flutter.yaml` - # included above or to enable additional rules. A list of all available lints - # and their documentation is published at https://dart.dev/lints. - # - # Instead of disabling a lint rule for the entire project in the - # section below, it can also be suppressed for a single line of code - # or a specific dart file by using the `// ignore: name_of_lint` and - # `// ignore_for_file: name_of_lint` syntax on the line or in the file - # producing the lint. - rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options diff --git a/app/android/.gitignore b/app/android/.gitignore deleted file mode 100644 index be3943c..0000000 --- a/app/android/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java -.cxx/ - -# Remember to never publicly share your keystore. -# See https://flutter.dev/to/reference-keystore -key.properties -**/*.keystore -**/*.jks diff --git a/app/android/app/build.gradle.kts b/app/android/app/build.gradle.kts deleted file mode 100644 index 2e04cc9..0000000 --- a/app/android/app/build.gradle.kts +++ /dev/null @@ -1,49 +0,0 @@ -plugins { - id("com.android.application") - // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. - id("dev.flutter.flutter-gradle-plugin") -} - -android { - namespace = "kr.tkrmagid.tetrig" - compileSdk = flutter.compileSdkVersion - ndkVersion = flutter.ndkVersion - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId = "kr.tkrmagid.tetrig" - // You can update the following values to match your application needs. - // For more information, see: https://flutter.dev/to/review-gradle-config. - minSdk = flutter.minSdkVersion - targetSdk = flutter.targetSdkVersion - // Uses the version code from pubspec.yaml. When using split APKs, 1000 * ABI_VERSION - // is added automatically by Flutter. (https://developer.android.com/studio/build/configure-apk-splits#configure-APK-versions) - // You can force using the value of versionCode by specifying the `-P force-version-code-ignoring-abi=true` - // flag during build. - versionCode = flutter.versionCode - versionName = flutter.versionName - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig = signingConfigs.getByName("debug") - } - } -} - -kotlin { - compilerOptions { - jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 - } -} - -flutter { - source = "../.." -} diff --git a/app/android/app/src/debug/AndroidManifest.xml b/app/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index 399f698..0000000 --- a/app/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index acb7358..0000000 --- a/app/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/app/android/app/src/main/kotlin/kr/tkrmagid/tetrig/MainActivity.kt b/app/android/app/src/main/kotlin/kr/tkrmagid/tetrig/MainActivity.kt deleted file mode 100644 index 7931963..0000000 --- a/app/android/app/src/main/kotlin/kr/tkrmagid/tetrig/MainActivity.kt +++ /dev/null @@ -1,5 +0,0 @@ -package kr.tkrmagid.tetrig - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity : FlutterActivity() diff --git a/app/android/app/src/main/res/drawable-v21/launch_background.xml b/app/android/app/src/main/res/drawable-v21/launch_background.xml deleted file mode 100644 index f74085f..0000000 --- a/app/android/app/src/main/res/drawable-v21/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/app/android/app/src/main/res/drawable/launch_background.xml b/app/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f..0000000 --- a/app/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4b7b0906d62b1847e87f15cdcacf6a4f29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ diff --git a/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b79bb8a35cc66c3c1fd44f5a5526c1b78be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ diff --git a/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d34e7a88e3f88bea192c3a370d44689c3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof diff --git a/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372eebdb28e45604e46eeda8dd24651419bc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` diff --git a/app/android/app/src/main/res/values-night/styles.xml b/app/android/app/src/main/res/values-night/styles.xml deleted file mode 100644 index 06952be..0000000 --- a/app/android/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/app/android/app/src/main/res/values/styles.xml b/app/android/app/src/main/res/values/styles.xml deleted file mode 100644 index cb1ef88..0000000 --- a/app/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/app/android/app/src/profile/AndroidManifest.xml b/app/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index 399f698..0000000 --- a/app/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/app/android/build.gradle.kts b/app/android/build.gradle.kts deleted file mode 100644 index dbee657..0000000 --- a/app/android/build.gradle.kts +++ /dev/null @@ -1,24 +0,0 @@ -allprojects { - repositories { - google() - mavenCentral() - } -} - -val newBuildDir: Directory = - rootProject.layout.buildDirectory - .dir("../../build") - .get() -rootProject.layout.buildDirectory.value(newBuildDir) - -subprojects { - val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) - project.layout.buildDirectory.value(newSubprojectBuildDir) -} -subprojects { - project.evaluationDependsOn(":app") -} - -tasks.register("clean") { - delete(rootProject.layout.buildDirectory) -} diff --git a/app/android/gradle.properties b/app/android/gradle.properties deleted file mode 100644 index e96108c..0000000 --- a/app/android/gradle.properties +++ /dev/null @@ -1,6 +0,0 @@ -org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError -android.useAndroidX=true -# This newDsl flag was added by the Flutter template -android.newDsl=false -# This builtInKotlin flag was added by the Flutter template -android.builtInKotlin=false diff --git a/app/android/gradle/wrapper/gradle-wrapper.properties b/app/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index a20f2c4..0000000 --- a/app/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-all.zip diff --git a/app/android/settings.gradle.kts b/app/android/settings.gradle.kts deleted file mode 100644 index b28021a..0000000 --- a/app/android/settings.gradle.kts +++ /dev/null @@ -1,26 +0,0 @@ -pluginManagement { - val flutterSdkPath = - run { - val properties = java.util.Properties() - file("local.properties").inputStream().use { properties.load(it) } - val flutterSdkPath = properties.getProperty("flutter.sdk") - require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } - flutterSdkPath - } - - includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") - - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} - -plugins { - id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "9.1.0" apply false - id("org.jetbrains.kotlin.android") version "2.4.0" apply false -} - -include(":app") diff --git a/app/ios/.gitignore b/app/ios/.gitignore deleted file mode 100644 index 7a7f987..0000000 --- a/app/ios/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -**/dgph -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Flutter.podspec -Flutter/Generated.xcconfig -Flutter/ephemeral/ -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/app/ios/Flutter/AppFrameworkInfo.plist b/app/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 391a902..0000000 --- a/app/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - - diff --git a/app/ios/Flutter/Debug.xcconfig b/app/ios/Flutter/Debug.xcconfig deleted file mode 100644 index 592ceee..0000000 --- a/app/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Generated.xcconfig" diff --git a/app/ios/Flutter/Release.xcconfig b/app/ios/Flutter/Release.xcconfig deleted file mode 100644 index 592ceee..0000000 --- a/app/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Generated.xcconfig" diff --git a/app/ios/Runner.xcodeproj/project.pbxproj b/app/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 9d05f23..0000000 --- a/app/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,647 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; }; - 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; - 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 */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 97C146E61CF9000F007C117D /* Project object */; - proxyType = 1; - remoteGlobalIDString = 97C146ED1CF9000F007C117D; - remoteInfo = Runner; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 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; }; - 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 = ""; }; - 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; - 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 = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 331C8082294A63A400263BE5 /* RunnerTests */ = { - isa = PBXGroup; - children = ( - 331C807B294A618700263BE5 /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 331C8082294A63A400263BE5 /* RunnerTests */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - 331C8081294A63A400263BE5 /* RunnerTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 331C8080294A63A400263BE5 /* RunnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; - buildPhases = ( - 331C807D294A63A400263BE5 /* Sources */, - 331C807F294A63A400263BE5 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 331C8086294A63A400263BE5 /* PBXTargetDependency */, - ); - name = RunnerTests; - productName = RunnerTests; - productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - packageProductDependencies = ( - 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, - ); - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 1510; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 331C8080294A63A400263BE5 = { - CreatedOnToolsVersion = 14.0; - TestTargetID = 97C146ED1CF9000F007C117D; - }; - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - packageReferences = ( - 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */, - ); - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - 331C8080294A63A400263BE5 /* RunnerTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 331C807F294A63A400263BE5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 331C807D294A63A400263BE5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 97C146ED1CF9000F007C117D /* Runner */; - targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - STRING_CATALOG_GENERATE_SYMBOLS = YES; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = kr.tkrmagid.tetrig; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 331C8088294A63A400263BE5 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = kr.tkrmagid.tetrig.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Debug; - }; - 331C8089294A63A400263BE5 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = kr.tkrmagid.tetrig.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Release; - }; - 331C808A294A63A400263BE5 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = kr.tkrmagid.tetrig.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - STRING_CATALOG_GENERATE_SYMBOLS = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - STRING_CATALOG_GENERATE_SYMBOLS = YES; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = kr.tkrmagid.tetrig; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = kr.tkrmagid.tetrig; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 331C8088294A63A400263BE5 /* Debug */, - 331C8089294A63A400263BE5 /* Release */, - 331C808A294A63A400263BE5 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - -/* Begin XCLocalSwiftPackageReference section */ - 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = { - isa = XCLocalSwiftPackageReference; - relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; - }; -/* End XCLocalSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { - isa = XCSwiftPackageProductDependency; - productName = FlutterGeneratedPluginSwiftPackage; - }; -/* End XCSwiftPackageProductDependency section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a..0000000 --- a/app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c..0000000 --- a/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index c3fedb2..0000000 --- a/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/ios/Runner.xcworkspace/contents.xcworkspacedata b/app/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a1..0000000 --- a/app/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c..0000000 --- a/app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/app/ios/Runner/AppDelegate.swift b/app/ios/Runner/AppDelegate.swift deleted file mode 100644 index c30b367..0000000 --- a/app/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,16 +0,0 @@ -import Flutter -import UIKit - -@main -@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } - - func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { - GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) - } -} diff --git a/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fa..0000000 --- a/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada4725e9b0ddb1deab583e5b5102493aa332..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10932 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 diff --git a/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 797d452e458972bab9d994556c8305db4c827017..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 406 zcmV;H0crk;P))>cdjpWt&rLJgVp-t?DREyuq1A%0Z4)6_WsQ7{nzjN zo!X zGXV)2i3kcZIL~_j>uIKPK_zib+3T+Nt3Mb&Br)s)UIaA}@p{wDda>7=Q|mGRp7pqY zkJ!7E{MNz$9nOwoVqpFb)}$IP24Wn2JJ=Cw(!`OXJBr45rP>>AQr$6c7slJWvbpNW z@KTwna6d?PP>hvXCcp=4F;=GR@R4E7{4VU^0p4F>v^#A|>07*qoM6N<$f*5nx ACIA2c diff --git a/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index 6ed2d933e1120817fe9182483a228007b18ab6ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 450 zcmV;z0X_bSP)iGWQ_5NJQ_~rNh*z)}eT%KUb z`7gNk0#AwF^#0T0?hIa^`~Ck;!}#m+_uT050aTR(J!bU#|IzRL%^UsMS#KsYnTF*!YeDOytlP4VhV?b} z%rz_<=#CPc)tU1MZTq~*2=8~iZ!lSa<{9b@2Jl;?IEV8)=fG217*|@)CCYgFze-x? zIFODUIA>nWKpE+bn~n7;-89sa>#DR>TSlqWk*!2hSN6D~Qb#VqbP~4Fk&m`@1$JGr zXPIdeRE&b2Thd#{MtDK$px*d3-Wx``>!oimf%|A-&-q*6KAH)e$3|6JV%HX{Hig)k suLT-RhftRq8b9;(V=235Wa|I=027H2wCDra;{X5v07*qoM6N<$f;9x^2LJ#7 diff --git a/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cd7b0099ca80c806f8fe495613e8d6c69460d76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 282 zcmV+#0p(^bcu7P-R4C8Q z&e;xxFbF_Vrezo%_kH*OKhshZ6BFpG-Y1e10`QXJKbND7AMQ&cMj60B5TNObaZxYybcN07*qoM6N<$g3m;S%K!iX diff --git a/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index fe730945a01f64a61e2235dbe3f45b08f7729182..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 462 zcmV;<0WtoGP)-}iV`2<;=$?g5M=KQbZ{F&YRNy7Nn@%_*5{gvDM0aKI4?ESmw z{NnZg)A0R`+4?NF_RZexyVB&^^ZvN!{I28tr{Vje;QNTz`dG&Jz0~Ek&f2;*Z7>B|cg}xYpxEFY+0YrKLF;^Q+-HreN0P{&i zK~zY`?b7ECf-n?@;d<&orQ*Q7KoR%4|C>{W^h6@&01>0SKS`dn{Q}GT%Qj_{PLZ_& zs`MFI#j-(>?bvdZ!8^xTwlY{qA)T4QLbY@j(!YJ7aXJervHy6HaG_2SB`6CC{He}f zHVw(fJWApwPq!6VY7r1w-Fs)@ox~N+q|w~e;JI~C4Vf^@d>Wvj=fl`^u9x9wd9 zR%3*Q+)t%S!MU_`id^@&Y{y7-r98lZX0?YrHlfmwb?#}^1b{8g&KzmkE(L>Z&)179 zp<)v6Y}pRl100G2FL_t(o!|l{-Q-VMg#&MKg7c{O0 z2wJImOS3Gy*Z2Qifdv~JYOp;v+U)a|nLoc7hNH;I$;lzDt$}rkaFw1mYK5_0Q(Sut zvbEloxON7$+HSOgC9Z8ltuC&0OSF!-mXv5caV>#bc3@hBPX@I$58-z}(ZZE!t-aOG zpjNkbau@>yEzH(5Yj4kZiMH32XI!4~gVXNnjAvRx;Sdg^`>2DpUEwoMhTs_st8pKG z(%SHyHdU&v%f36~uERh!bd`!T2dw;z6PrOTQ7Vt*#9F2uHlUVnb#ev_o^fh}Dzmq} zWtlk35}k=?xj28uO|5>>$yXadTUE@@IPpgH`gJ~Ro4>jd1IF|(+IX>8M4Ps{PNvmI zNj4D+XgN83gPt_Gm}`Ybv{;+&yu-C(Grdiahmo~BjG-l&mWM+{e5M1sm&=xduwgM9 z`8OEh`=F3r`^E{n_;%9weN{cf2%7=VzC@cYj+lg>+3|D|_1C@{hcU(DyQG_BvBWe? zvTv``=%b1zrol#=R`JB)>cdjpWt&rLJgVp-t?DREyuq1A%0Z4)6_WsQ7{nzjN zo!X zGXV)2i3kcZIL~_j>uIKPK_zib+3T+Nt3Mb&Br)s)UIaA}@p{wDda>7=Q|mGRp7pqY zkJ!7E{MNz$9nOwoVqpFb)}$IP24Wn2JJ=Cw(!`OXJBr45rP>>AQr$6c7slJWvbpNW z@KTwna6d?PP>hvXCcp=4F;=GR@R4E7{4VU^0p4F>v^#A|>07*qoM6N<$f*5nx ACIA2c diff --git a/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index 502f463a9bc882b461c96aadf492d1729e49e725..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 586 zcmV-Q0=4~#P)+}#`wDE{8-2Mebf5<{{PqV{TgVcv*r8?UZ3{-|G?_}T*&y;@cqf{ z{Q*~+qr%%p!1pS*_Uicl#q9lc(D`!D`LN62sNwq{oYw(Wmhk)k<@f$!$@ng~_5)Ru z0Z)trIA5^j{DIW^c+vT2%lW+2<(RtE2wR;4O@)Tm`Xr*?A(qYoM}7i5Yxw>D(&6ou zxz!_Xr~yNF+waPe00049Nkl*;a!v6h%{rlvIH#gW3s8p;bFr=l}mRqpW2h zw=OA%hdyL~z+UHOzl0eKhEr$YYOL-c-%Y<)=j?(bzDweB7{b+%_ypvm_cG{SvM=DK zhv{K@m>#Bw>2W$eUI#iU)Wdgs8Y3U+A$Gd&{+j)d)BmGKx+43U_!tik_YlN)>$7G! zhkE!s;%oku3;IwG3U^2kw?z+HM)jB{@zFhK8P#KMSytSthr+4!c(5c%+^UBn`0X*2 zy3(k600_CSZj?O$Qu%&$;|TGUJrptR(HzyIx>5E(2r{eA(<6t3e3I0B)7d6s7?Z5J zZ!rtKvA{MiEBm&KFtoifx>5P^Z=vl)95XJn()aS5%ad(s?4-=Tkis9IGu{`Fy8r+H07*qoM6N<$f20Z)wqMt%V?S?~D#06};F zA3KcL`Wb+>5ObvgQIG&ig8(;V04hz?@cqy3{mSh8o!|U|)cI!1_+!fWH@o*8vh^CU z^ws0;(c$gI+2~q^tO#GDHf@=;DncUw00J^eL_t(&-tE|HQ`%4vfZ;WsBqu-$0nu1R zq^Vj;p$clf^?twn|KHO+IGt^q#a3X?w9dXC@*yxhv&l}F322(8Y1&=P&I}~G@#h6; z1CV9ecD9ZEe87{{NtI*)_aJ<`kJa z?5=RBtFF50s;jQLFil-`)m2wrb=6h(&brpj%nG_U&ut~$?8Rokzxi8zJoWr#2dto5 zOX_URcc<1`Iky+jc;A%Vzx}1QU{2$|cKPom2Vf1{8m`vja4{F>HS?^Nc^rp}xo+Nh zxd}eOm`fm3@MQC1< zIk&aCjb~Yh%5+Yq0`)D;q{#-Uqlv*o+Oor zE!I71Z@ASH3grl8&P^L0WpavHoP|UX4e?!igT`4?AZk$hu*@%6WJ;zDOGlw7kj@ zY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f~t1N9smFU diff --git a/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index 0ec303439225b78712f49115768196d8d76f6790..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 862 zcmV-k1EKthP)20Z)wqMt%V?S?~D#06};F zA3KcL`Wb+>5ObvgQIG&ig8(;V04hz?@cqy3{mSh8o!|U|)cI!1_+!fWH@o*8vh^CU z^ws0;(c$gI+2~q^tO#GDHf@=;DncUw00J^eL_t(&-tE|HQ`%4vfZ;WsBqu-$0nu1R zq^Vj;p$clf^?twn|KHO+IGt^q#a3X?w9dXC@*yxhv&l}F322(8Y1&=P&I}~G@#h6; z1CV9ecD9ZEe87{{NtI*)_aJ<`kJa z?5=RBtFF50s;jQLFil-`)m2wrb=6h(&brpj%nG_U&ut~$?8Rokzxi8zJoWr#2dto5 zOX_URcc<1`Iky+jc;A%Vzx}1QU{2$|cKPom2Vf1{8m`vja4{F>HS?^Nc^rp}xo+Nh zxd}eOm`fm3@MQC1< zIk&aCjb~Yh%5+Yq0`)D;q{#-Uqlv*o+Oor zE!I71Z@ASH3grl8&P^L0WpavHoP|UX4e?!igT`4?AZk$hu*@%6WJ;zDOGlw7kj@ zY5!B-0ft0f?Lgb>C;$Ke07*qoM6N<$f~t1N9smFU diff --git a/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index e9f5fea27c705180eb716271f41b582e76dcbd90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1674 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 diff --git a/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index 0467bf12aa4d28f374bb26596605a46dcbb3e7c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1418 zcmV;51$Fv~P)q zKfU)WzW*n(@|xWGCA9ScMt*e9`2kdxPQ&&>|-UCa7_51w+ zLUsW@ZzZSW0y$)Hp~e9%PvP|a03ks1`~K?q{u;6NC8*{AOqIUq{CL&;p56Lf$oQGq z^={4hPQv)y=I|4n+?>7Fim=dxt1 z2H+Dm+1+fh+IF>G0SjJMkQQre1x4|G*Z==(Ot&kCnUrL4I(rf(ucITwmuHf^hXiJT zkdTm&kdTm&kdTm&kdP`esgWG0BcWCVkVZ&2dUwN`cgM8QJb`Z7Z~e<&Yj2(}>Tmf` zm1{eLgw!b{bXkjWbF%dTkTZEJWyWOb##Lfw4EK2}<0d6%>AGS{po>WCOy&f$Tay_> z?NBlkpo@s-O;0V%Y_Xa-G#_O08q5LR*~F%&)}{}r&L%Sbs8AS4t7Y0NEx*{soY=0MZExqA5XHQkqi#4gW3 zqODM^iyZl;dvf)-bOXtOru(s)Uc7~BFx{w-FK;2{`VA?(g&@3z&bfLFyctOH!cVsF z7IL=fo-qBndRUm;kAdXR4e6>k-z|21AaN%ubeVrHl*<|s&Ax@W-t?LR(P-24A5=>a z*R9#QvjzF8n%@1Nw@?CG@6(%>+-0ASK~jEmCV|&a*7-GKT72W<(TbSjf)&Eme6nGE z>Gkj4Sq&2e+-G%|+NM8OOm5zVl9{Z8Dd8A5z3y8mZ=4Bv4%>as_{9cN#bm~;h>62( zdqY93Zy}v&c4n($Vv!UybR8ocs7#zbfX1IY-*w~)p}XyZ-SFC~4w>BvMVr`dFbelV{lLL0bx7@*ZZdebr3`sP;? zVImji)kG)(6Juv0lz@q`F!k1FE;CQ(D0iG$wchPbKZQELlsZ#~rt8#90Y_Xh&3U-< z{s<&cCV_1`^TD^ia9!*mQDq& zn2{r`j};V|uV%_wsP!zB?m%;FeaRe+X47K0e+KE!8C{gAWF8)lCd1u1%~|M!XNRvw zvtqy3iz0WSpWdhn6$hP8PaRBmp)q`#PCA`Vd#Tc$@f1tAcM>f_I@bC)hkI9|o(Iqv zo}Piadq!j76}004RBio<`)70k^`K1NK)q>w?p^C6J2ZC!+UppiK6&y3Kmbv&O!oYF z34$0Z;QO!JOY#!`qyGH<3Pd}Pt@q*A0V=3SVtWKRR8d8Z&@)3qLPA19LPA19LPEUC YUoZo%k(ykuW&i*H07*qoM6N<$f+CH{y8r+H diff --git a/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json deleted file mode 100644 index 0bedcf2..0000000 --- a/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "LaunchImage.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725..0000000 --- a/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/app/ios/Runner/Base.lproj/LaunchScreen.storyboard b/app/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c..0000000 --- a/app/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/ios/Runner/Base.lproj/Main.storyboard b/app/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c2851..0000000 --- a/app/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/ios/Runner/Info.plist b/app/ios/Runner/Info.plist deleted file mode 100644 index 56ea290..0000000 --- a/app/ios/Runner/Info.plist +++ /dev/null @@ -1,70 +0,0 @@ - - - - - CADisableMinimumFrameDurationOnPhone - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Tetrig - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - tetrig - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - UISceneConfigurations - - UIWindowSceneSessionRoleApplication - - - UISceneClassName - UIWindowScene - UISceneConfigurationName - flutter - UISceneDelegateClassName - $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main - - - - - UIApplicationSupportsIndirectInputEvents - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/app/ios/Runner/Runner-Bridging-Header.h b/app/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 308a2a5..0000000 --- a/app/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" diff --git a/app/ios/Runner/SceneDelegate.swift b/app/ios/Runner/SceneDelegate.swift deleted file mode 100644 index b9ce8ea..0000000 --- a/app/ios/Runner/SceneDelegate.swift +++ /dev/null @@ -1,6 +0,0 @@ -import Flutter -import UIKit - -class SceneDelegate: FlutterSceneDelegate { - -} diff --git a/app/ios/RunnerTests/RunnerTests.swift b/app/ios/RunnerTests/RunnerTests.swift deleted file mode 100644 index 86a7c3b..0000000 --- a/app/ios/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Flutter -import UIKit -import XCTest - -class RunnerTests: XCTestCase { - - func testExample() { - // If you add code to the Runner application, consider adding tests here. - // See https://developer.apple.com/documentation/xctest for more information about using XCTest. - } - -} diff --git a/app/lib/engine.dart b/app/lib/engine.dart deleted file mode 100644 index 9e2e5ba..0000000 --- a/app/lib/engine.dart +++ /dev/null @@ -1,403 +0,0 @@ -/// TETRIG 코어 엔진 (Dart 이식) — Phase 1. -/// 순수 로직만: Flutter/렌더/타이머 의존 없음. UI 위젯이 타이밍을 구동한다. -/// -/// 좌표 규약 (명세서 §4.1): -/// - 보드 (x, y): x 오른쪽 증가, y 위쪽 증가. y=0 이 맨 아래. -/// - 킥 오프셋 (dx, dy): dy 양수 = 위쪽. 그대로 py += dy 로 적용. -/// - 회전 상태: 0=스폰, 1=CW, 2=180, 3=CCW. -/// -/// (웹 레퍼런스 src/engine.js, Kotlin 이식판과 동일 알고리즘·데이터) -library; - -/// 튜닝 상수 (조정 대상은 여기 한 곳). -class Config { - static const int boardW = 10; - static const int boardH = 40; // 내부 높이 (하단 20행만 표시) - static const int visibleH = 20; - static const int nextCount = 5; - static const int lockDelayMs = 500; - static const int maxLockResets = 15; - static const int defaultGravityMs = 800; // Phase 1 기본 (SPRINT) - static const int dasMs = 133; - static const int arrMs = 10; - static const int sdf = 20; -} - -const List pieceTypes = ['I', 'O', 'T', 'S', 'Z', 'J', 'L']; - -/// 피스 색 (명세서 §13 v2 확정). 'G' = 가비지. -const Map pieceColors = { - 'I': '#3EC1B6', 'O': '#F5C531', 'T': '#A76BF2', 'S': '#7FCC4C', - 'Z': '#F25C4C', 'J': '#4C7DF2', 'L': '#F2913D', 'G': '#46464F', -}; - -// ── 피스 스폰 셀 (박스-로컬, y 위쪽 증가) + 박스 크기 ── -class _Spawn { - final int box; - final List> cells; - const _Spawn(this.box, this.cells); -} - -const Map _spawn = { - 'I': _Spawn(4, [[0, 2], [1, 2], [2, 2], [3, 2]]), - 'O': _Spawn(2, [[0, 0], [1, 0], [0, 1], [1, 1]]), - 'T': _Spawn(3, [[0, 1], [1, 1], [2, 1], [1, 2]]), - 'S': _Spawn(3, [[0, 1], [1, 1], [1, 2], [2, 2]]), - 'Z': _Spawn(3, [[0, 2], [1, 2], [1, 1], [2, 1]]), - 'J': _Spawn(3, [[0, 2], [0, 1], [1, 1], [2, 1]]), - 'L': _Spawn(3, [[2, 2], [0, 1], [1, 1], [2, 1]]), -}; - -/// 스폰 시 박스 원점의 보드 위치 (px, py). -const Map> _spawnPos = { - 'I': [3, 19], 'O': [4, 21], 'T': [3, 20], - 'S': [3, 20], 'Z': [3, 20], 'J': [3, 20], 'L': [3, 20], -}; - -/// CW 회전: 박스 b 에서 (x,y) -> (y, (b-1)-x). -List> _rotateCW(List> cells, int b) => - cells.map((c) => [c[1], (b - 1) - c[0]]).toList(); - -List>> _buildStates(String type) { - final sp = _spawn[type]!; - if (type == 'O') return [sp.cells, sp.cells, sp.cells, sp.cells]; - final s0 = sp.cells; - final s1 = _rotateCW(s0, sp.box); - final s2 = _rotateCW(s1, sp.box); - final s3 = _rotateCW(s2, sp.box); - return [s0, s1, s2, s3]; -} - -/// STATES[type][state] = 셀 목록. -final Map>>> states = { - for (final t in pieceTypes) t: _buildStates(t), -}; - -// ── 킥테이블 (명세서 §4.1) ── -const Map>> _kicksJlstz = { - '0>1': [[0, 0], [-1, 0], [-1, 1], [0, -2], [-1, -2]], - '1>0': [[0, 0], [1, 0], [1, -1], [0, 2], [1, 2]], - '1>2': [[0, 0], [1, 0], [1, -1], [0, 2], [1, 2]], - '2>1': [[0, 0], [-1, 0], [-1, 1], [0, -2], [-1, -2]], - '2>3': [[0, 0], [1, 0], [1, 1], [0, -2], [1, -2]], - '3>2': [[0, 0], [-1, 0], [-1, -1], [0, 2], [-1, 2]], - '3>0': [[0, 0], [-1, 0], [-1, -1], [0, 2], [-1, 2]], - '0>3': [[0, 0], [1, 0], [1, 1], [0, -2], [1, -2]], - // 180° (SRS+) - '0>2': [[0, 0], [0, 1], [1, 1], [-1, 1], [1, 0], [-1, 0]], - '2>0': [[0, 0], [0, -1], [-1, -1], [1, -1], [-1, 0], [1, 0]], - '1>3': [[0, 0], [1, 0], [1, 2], [1, 1], [0, 2], [0, 1]], - '3>1': [[0, 0], [-1, 0], [-1, 2], [-1, 1], [0, 2], [0, 1]], -}; - -const Map>> _kicksI = { - '0>1': [[0, 0], [-2, 0], [1, 0], [-2, -1], [1, 2]], - '1>0': [[0, 0], [2, 0], [-1, 0], [2, 1], [-1, -2]], - '1>2': [[0, 0], [-1, 0], [2, 0], [-1, 2], [2, -1]], - '2>1': [[0, 0], [1, 0], [-2, 0], [1, -2], [-2, 1]], - '2>3': [[0, 0], [2, 0], [-1, 0], [2, 1], [-1, -2]], - '3>2': [[0, 0], [-2, 0], [1, 0], [-2, -1], [1, 2]], - '3>0': [[0, 0], [1, 0], [-2, 0], [1, -2], [-2, 1]], - '0>3': [[0, 0], [-1, 0], [2, 0], [-1, 2], [2, -1]], - // I 180°는 (0,0)만 - '0>2': [[0, 0]], '2>0': [[0, 0]], '1>3': [[0, 0]], '3>1': [[0, 0]], -}; - -const List> _origin = [[0, 0]]; - -List> kickTable(String type, int from, int to) { - final key = '$from>$to'; - if (type == 'O') return _origin; - if (type == 'I') return _kicksI[key] ?? _origin; - return _kicksJlstz[key] ?? _origin; -} - -/// 시드 가능 난수 (mulberry32). -double Function() makeRng(int seed) { - int a = seed & 0xFFFFFFFF; - return () { - a = (a + 0x6D2B79F5) & 0xFFFFFFFF; - final x = (a ^ (a >>> 15)) & 0xFFFFFFFF; - int t = (x * ((1 | a) & 0xFFFFFFFF)) & 0xFFFFFFFF; - final y = (t ^ (t >>> 7)) & 0xFFFFFFFF; - final m = (y * ((61 | t) & 0xFFFFFFFF)) & 0xFFFFFFFF; - t = ((t + m) & 0xFFFFFFFF) ^ t; - t &= 0xFFFFFFFF; - return ((t ^ (t >>> 14)) & 0xFFFFFFFF) / 4294967296.0; - }; -} - -/// 7-bag. -class SevenBag { - final double Function() rng; - final List _q = []; - SevenBag([double Function()? rng]) : rng = rng ?? (() => 0.0) { - _refill(); - _refill(); - } - void _refill() { - final bag = List.from(pieceTypes); - for (int i = bag.length - 1; i > 0; i--) { - final j = (rng() * (i + 1)).floor(); - final tmp = bag[i]; - bag[i] = bag[j]; - bag[j] = tmp; - } - _q.addAll(bag); - } - - String next() { - if (_q.length <= Config.nextCount + 1) _refill(); - return _q.removeAt(0); - } - - List peek([int n = Config.nextCount]) { - while (_q.length < n) { - _refill(); - } - return _q.sublist(0, n); - } -} - -// ── 보드 유틸 ── -List> createBoard([int w = Config.boardW, int h = Config.boardH]) => - List.generate(h, (_) => List.filled(w, null)); - -List> pieceCells(String type, int state, int px, int py) => - states[type]![state].map((c) => [px + c[0], py + c[1]]).toList(); - -/// x 범위 밖 / 바닥 아래(y<0) / 점유 = 충돌. y >= H (버퍼 위)는 허용. -bool collides(List> board, List> cells) { - final w = board[0].length, h = board.length; - for (final c in cells) { - final x = c[0], y = c[1]; - if (x < 0 || x >= w || y < 0) return true; - if (y < h && board[y][x] != null) return true; - } - return false; -} - -/// 가득 찬 행 제거 후 위에서 빈 행 보충. 제거된 행 수 반환. -int clearLines(List> board) { - final w = board[0].length, h = board.length; - final rows = []; - for (int y = 0; y < h; y++) { - if (board[y].every((c) => c != null)) rows.add(y); - } - if (rows.isEmpty) return 0; - final rowSet = rows.toSet(); - final kept = >[ - for (int y = 0; y < h; y++) - if (!rowSet.contains(y)) board[y] - ]; - while (kept.length < h) { - kept.add(List.filled(w, null)); - } - for (int y = 0; y < h; y++) { - board[y] = kept[y]; - } - return rows.length; -} - -bool isBoardEmpty(List> board) => - board.every((row) => row.every((c) => c == null)); - -/// T-spin 판정 (명세서 §4.2). 'none' | 'mini' | 'tspin'. -String detectTSpin(List> board, String type, int state, int px, - int py, bool lastMoveRotation) { - if (type != 'T' || !lastMoveRotation) return 'none'; - final w = board[0].length, h = board.length; - final cx = px + 1, cy = py + 1; - bool filled(int dx, int dy) { - final x = cx + dx, y = cy + dy; - if (x < 0 || x >= w || y < 0) return true; // 벽/바닥 = 채움 - if (y >= h) return false; // 버퍼 위 = 빔 - return board[y][x] != null; - } - - final tl = filled(-1, 1), tr = filled(1, 1), bl = filled(-1, -1), br = filled(1, -1); - final count = [tl, tr, bl, br].where((v) => v).length; - if (count < 3) return 'none'; - late List front; - switch (state) { - case 0: - front = [tl, tr]; - break; - case 1: - front = [tr, br]; - break; - case 2: - front = [bl, br]; - break; - default: - front = [tl, bl]; - } - return (front[0] && front[1]) ? 'tspin' : 'mini'; -} - -/// B2B 대상("어려운" 클리어): Quad 또는 라인 동반 T-spin 계열. -bool isDifficult(int lines, String tspin) => - lines == 4 || (tspin != 'none' && lines >= 1); - -class LockResult { - final String type; - final int lines; - final String tspin; - final bool allClear; - final int combo; - final int b2b; - final bool difficult; - const LockResult(this.type, this.lines, this.tspin, this.allClear, this.combo, - this.b2b, this.difficult); -} - -class Active { - String type; - int state; - int x; - int y; - Active(this.type, this.state, this.x, this.y); -} - -/// 게임 상태 (UI 가 타이밍을 구동). -class TetrigGame { - List> board = createBoard(); - final SevenBag _bag; - String? hold; - bool holdUsed = false; - bool over = false; - bool lastMoveRotation = false; - int lockResets = 0; - int combo = -1; - int b2b = -1; - LockResult? lastClear; - late Active active; - - TetrigGame({int seed = 1}) : _bag = SevenBag(makeRng(seed)) { - spawn(); - } - - List> cells([Active? a]) { - a ??= active; - return pieceCells(a.type, a.state, a.x, a.y); - } - - bool spawn([String? type]) { - type ??= _bag.next(); - final pos = _spawnPos[type]!; - active = Active(type, 0, pos[0], pos[1]); - lastMoveRotation = false; - lockResets = 0; - if (collides(board, cells())) { - over = true; - return false; - } - return true; - } - - List peekNext([int n = Config.nextCount]) => _bag.peek(n); - - bool canFall() { - final c = cells().map((p) => [p[0], p[1] - 1]).toList(); - return !collides(board, c); - } - - bool resetLockDelay() { - if (lockResets >= Config.maxLockResets) return false; - lockResets++; - return true; - } - - bool move(int dx) { - if (over) return false; - final c = pieceCells(active.type, active.state, active.x + dx, active.y); - if (collides(board, c)) return false; - active.x += dx; - lastMoveRotation = false; - return true; - } - - bool softDrop() { - if (over) return false; - final c = pieceCells(active.type, active.state, active.x, active.y - 1); - if (collides(board, c)) return false; - active.y -= 1; - lastMoveRotation = false; - return true; - } - - /// dir: 'cw' | 'ccw' | '180'. - bool rotate(String dir) { - if (over) return false; - final a = active; - final to = dir == 'cw' - ? (a.state + 1) % 4 - : dir == 'ccw' - ? (a.state + 3) % 4 - : (a.state + 2) % 4; - for (final k in kickTable(a.type, a.state, to)) { - final nx = a.x + k[0], ny = a.y + k[1]; - if (!collides(board, pieceCells(a.type, to, nx, ny))) { - a.state = to; - a.x = nx; - a.y = ny; - lastMoveRotation = true; - return true; - } - } - return false; - } - - List> ghostCells() { - final a = active; - int dy = 0; - while (!collides(board, pieceCells(a.type, a.state, a.x, a.y - dy - 1))) { - dy++; - } - return pieceCells(a.type, a.state, a.x, a.y - dy); - } - - LockResult? hardDrop() { - if (over) return null; - final a = active; - int d = 0; - while (!collides(board, pieceCells(a.type, a.state, a.x, a.y - d - 1))) { - d++; - } - a.y -= d; - return lock(); - } - - bool holdSwap() { - if (over || holdUsed) return false; - final cur = active.type; - if (hold == null) { - hold = cur; - spawn(); - } else { - final swap = hold!; - hold = cur; - spawn(swap); - } - holdUsed = true; - return true; - } - - LockResult lock() { - final a = active; - final tspin = detectTSpin(board, a.type, a.state, a.x, a.y, lastMoveRotation); - for (final c in cells()) { - if (c[1] >= 0 && c[1] < board.length) board[c[1]][c[0]] = a.type; - } - final cleared = clearLines(board); - final allClear = cleared > 0 && isBoardEmpty(board); - combo = cleared > 0 ? combo + 1 : -1; - final diff = isDifficult(cleared, tspin); - if (cleared > 0) b2b = diff ? b2b + 1 : -1; - final result = LockResult(a.type, cleared, tspin, allClear, combo, b2b, diff); - lastClear = result; - holdUsed = false; - spawn(); - return result; - } -} diff --git a/app/lib/main.dart b/app/lib/main.dart deleted file mode 100644 index 77c1995..0000000 --- a/app/lib/main.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; - -// TETRIG 진입점 (Flutter, Android + iOS). -// 게임 UI(목업 ② 인게임 + §11 터치 버튼)는 다음 단계에서 이 자리에 붙는다. -// 코어 로직은 lib/engine.dart (UI와 분리, Dart 테스트로 검증됨). - -void main() => runApp(const TetrigApp()); - -class TetrigApp extends StatelessWidget { - const TetrigApp({super.key}); - - @override - Widget build(BuildContext context) { - return const MaterialApp( - title: 'TETRIG', - debugShowCheckedModeBanner: false, - home: Scaffold( - backgroundColor: Color(0xFF17161B), // INK - body: Center( - child: Text( - 'TETRIG', - style: TextStyle( - color: Color(0xFFEDE7DA), // BONE - fontSize: 44, - fontWeight: FontWeight.w900, - fontStyle: FontStyle.italic, - letterSpacing: 1, - ), - ), - ), - ), - ); - } -} diff --git a/app/pubspec.lock b/app/pubspec.lock deleted file mode 100644 index d6e40dc..0000000 --- a/app/pubspec.lock +++ /dev/null @@ -1,213 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 - url: "https://pub.dev" - source: hosted - version: "2.13.1" - 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: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b - url: "https://pub.dev" - source: hosted - version: "1.4.1" - 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" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd" - url: "https://pub.dev" - source: hosted - version: "1.0.9" - 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_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" - url: "https://pub.dev" - source: hosted - version: "6.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" - url: "https://pub.dev" - source: hosted - version: "11.0.2" - 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: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" - url: "https://pub.dev" - source: hosted - version: "6.1.0" - matcher: - dependency: transitive - description: - name: matcher - sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" - url: "https://pub.dev" - source: hosted - version: "0.12.20" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" - url: "https://pub.dev" - source: hosted - version: "0.13.0" - meta: - dependency: transitive - description: - name: meta - sha256: c82594181e3312f3d0695fc95aaaf7758d75b8d4ae2bbecf223b9fd5109a059d - url: "https://pub.dev" - source: hosted - version: "1.18.3" - path: - dependency: transitive - description: - name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://pub.dev" - source: hosted - version: "1.9.1" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - source_span: - dependency: transitive - description: - name: source_span - sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" - url: "https://pub.dev" - source: hosted - version: "1.10.2" - 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: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" - url: "https://pub.dev" - source: hosted - version: "0.7.12" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "1d774bbdf6b72a0b12122fc1560c9c2d2a67db5a4a4cc2bd8a5c990ab20e3188" - url: "https://pub.dev" - source: hosted - version: "2.4.0" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "5f37239c4851efcef929cea7824e76df7f2f0970aef85d66bbc430afa40e72f0" - url: "https://pub.dev" - source: hosted - version: "15.3.0" -sdks: - dart: ">=3.13.1 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" diff --git a/app/pubspec.yaml b/app/pubspec.yaml deleted file mode 100644 index 571fe00..0000000 --- a/app/pubspec.yaml +++ /dev/null @@ -1,89 +0,0 @@ -name: tetrig -description: "A new Flutter project." -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -# In Windows, build-name is used as the major, minor, and patch parts -# of the product and file versions while build-number is used as the build suffix. -version: 1.0.0+1 - -environment: - sdk: ^3.13.1 - -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.8 - -dev_dependencies: - flutter_test: - sdk: flutter - - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. - flutter_lints: ^6.0.0 - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter packages. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/to/resolution-aware-images - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/to/asset-from-package - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/to/font-from-package diff --git a/app/test/engine_test.dart b/app/test/engine_test.dart deleted file mode 100644 index 10aa490..0000000 --- a/app/test/engine_test.dart +++ /dev/null @@ -1,204 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:tetrig/engine.dart'; - -Set _cellSet(List> cells) => - cells.map((c) => '${c[0]},${c[1]}').toSet(); - -String _kickStr(List> k) => k.map((c) => '${c[0]},${c[1]}').join(' '); - -void main() { - // ── 피스 상태/회전 ── - test('T 스폰 셀 = 위-포인팅', () { - expect(_cellSet(states['T']![0]), {'0,1', '1,1', '2,1', '1,2'}); - }); - - test('T CW(state1) = 오른쪽-포인팅', () { - expect(_cellSet(states['T']![1]), {'1,0', '1,1', '1,2', '2,1'}); - }); - - test('I CW(state1) = 세로', () { - expect(_cellSet(states['I']![1]), {'2,0', '2,1', '2,2', '2,3'}); - }); - - test('O는 회전 불변', () { - final s0 = _cellSet(states['O']![0]); - expect(_cellSet(states['O']![1]), s0); - expect(_cellSet(states['O']![3]), s0); - }); - - test('모든 피스 4상태', () { - for (final t in pieceTypes) { - expect(states[t]!.length, 4); - } - }); - - // ── 킥테이블 ── - test('킥테이블 내용 (명세서 §4.1)', () { - expect(_kickStr(kickTable('T', 0, 1)), '0,0 -1,0 -1,1 0,-2 -1,-2'); - expect(_kickStr(kickTable('I', 0, 1)), '0,0 -2,0 1,0 -2,-1 1,2'); - expect(_kickStr(kickTable('T', 0, 2)), '0,0 0,1 1,1 -1,1 1,0 -1,0'); - expect(_kickStr(kickTable('I', 0, 2)), '0,0'); - expect(_kickStr(kickTable('O', 0, 1)), '0,0'); - }); - - test('벽킥: (0,0) 막히면 다음 오프셋으로 성사', () { - final board = createBoard(); - board[5][5] = 'X'; - expect(collides(board, pieceCells('T', 1, 4, 5)), true); - expect(collides(board, pieceCells('T', 1, 3, 5)), false); // (-1,0) - }); - - // ── 7-bag ── - test('7-bag: 연속 7개는 7종 모두', () { - final bag = SevenBag(makeRng(42)); - for (int r = 0; r < 20; r++) { - final seven = [for (int i = 0; i < 7; i++) bag.next()]..sort(); - expect(seven, (List.from(pieceTypes)..sort())); - } - }); - - test('peek(5)==소비순서', () { - final bag = SevenBag(makeRng(7)); - final peek = bag.peek(5); - expect(peek.length, 5); - for (int i = 0; i < 5; i++) { - expect(bag.next(), peek[i]); - } - }); - - test('시드 동일 → 동일 시퀀스', () { - final a = SevenBag(makeRng(123)), b = SevenBag(makeRng(123)); - for (int i = 0; i < 30; i++) { - expect(a.next(), b.next()); - } - }); - - // ── 충돌/클리어 ── - test('collides 벽/바닥/점유', () { - final bd = createBoard(); - expect(collides(bd, [[-1, 0]]), true); - expect(collides(bd, [[10, 0]]), true); - expect(collides(bd, [[0, -1]]), true); - expect(collides(bd, [[5, 45]]), false); - bd[3][4] = 'T'; - expect(collides(bd, [[4, 3]]), true); - }); - - test('clearLines 제거+하강', () { - final bd = createBoard(); - for (int x = 0; x < 10; x++) bd[0][x] = 'I'; - bd[1][0] = 'T'; - expect(clearLines(bd), 1); - expect(bd[0][0], 'T'); - for (int x = 1; x < 10; x++) expect(bd[0][x], null); - }); - - test('isBoardEmpty', () { - final bd = createBoard(); - expect(isBoardEmpty(bd), true); - bd[0][0] = 'I'; - expect(isBoardEmpty(bd), false); - }); - - // ── T-spin 판정 ── - test('T-spin full', () { - final bd = createBoard(10, 6); - bd[1][4] = 'X'; bd[1][6] = 'X'; bd[3][4] = 'X'; - expect(detectTSpin(bd, 'T', 2, 4, 1, true), 'tspin'); - }); - - test('T-spin mini', () { - final bd = createBoard(10, 6); - bd[1][4] = 'X'; bd[3][4] = 'X'; bd[3][6] = 'X'; - expect(detectTSpin(bd, 'T', 2, 4, 1, true), 'mini'); - }); - - test('T-spin none (모서리 부족)', () { - final bd = createBoard(10, 6); - bd[1][4] = 'X'; - expect(detectTSpin(bd, 'T', 2, 4, 1, true), 'none'); - }); - - test('T-spin none (회전 아님)', () { - final bd = createBoard(10, 6); - bd[1][4] = 'X'; bd[1][6] = 'X'; bd[3][4] = 'X'; - expect(detectTSpin(bd, 'T', 2, 4, 1, false), 'none'); - }); - - test('T-spin 바닥은 채움 취급', () { - final bd = createBoard(10, 6); - expect(detectTSpin(bd, 'T', 2, 4, -1, true), 'none'); - bd[1][4] = 'X'; - expect(detectTSpin(bd, 'T', 2, 4, -1, true), 'tspin'); - }); - - test('isDifficult 규칙', () { - expect(isDifficult(4, 'none'), true); - expect(isDifficult(2, 'tspin'), true); - expect(isDifficult(1, 'mini'), true); - expect(isDifficult(3, 'none'), false); - expect(isDifficult(0, 'tspin'), false); - }); - - // ── 게임 흐름 ── - test('락 딜레이 리셋 최대 15', () { - final g = TetrigGame(seed: 1); - int ok = 0; - for (int i = 0; i < 25; i++) { - if (g.resetLockDelay()) ok++; - } - expect(ok, Config.maxLockResets); - }); - - test('스폰/하드드롭 사이클', () { - final g = TetrigGame(seed: 3); - expect(g.over, false); - final before = g.active.type; - final res = g.hardDrop()!; - expect(res.type, before); - expect(g.holdUsed, false); - }); - - test('홀드 1회/피스', () { - final g = TetrigGame(seed: 9); - final first = g.active.type; - expect(g.holdSwap(), true); - expect(g.hold, first); - expect(g.holdSwap(), false); - g.hardDrop(); - expect(g.holdUsed, false); - expect(g.holdSwap(), true); - }); - - test('콤보/B2B 누적', () { - final g = TetrigGame(seed: 2); - LockResult quad() { - for (int y = 0; y < 4; y++) { - for (int x = 1; x < 10; x++) g.board[y][x] = 'X'; - } - final a = g.active; - a.type = 'I'; - a.state = 1; - a.x = -2; - a.y = 0; - g.lastMoveRotation = false; - return g.hardDrop()!; - } - - final r1 = quad(); - expect(r1.lines, 4); - expect(r1.b2b, 0); - final r2 = quad(); - expect(r2.lines, 4); - expect(r2.b2b, 1); - }); - - test('톱아웃', () { - final g = TetrigGame(seed: 1); - for (int y = 18; y < 24; y++) { - for (int x = 0; x < 10; x++) g.board[y][x] = 'X'; - } - expect(g.spawn('T'), false); - expect(g.over, true); - }); -} diff --git a/apple-touch-icon.png b/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3c7f2a4e920f79b31d478d418d936ec3857c0073 GIT binary patch literal 20316 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 N#)jqw_}hQK_&<>N&+7mH literal 0 HcmV?d00001 diff --git a/icon-192.png b/icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..99b209e3479b6f7fbab6267db0e99892c53f8ce5 GIT binary patch literal 19670 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 JPDHLkV1j0?w^0B9 literal 0 HcmV?d00001 diff --git a/icon-512.png b/icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..e8e292f661238baccd3aa19d9d3a3392a4591611 GIT binary patch literal 24935 zcmdRWhd19=`OyF9>!AQbUi7>D*HoD+5FHIn|Yt&Eh5f2W9omcFGYUjlHw4 zNjbCoDixChN!}q9x^A;pvrqkvcx+zc;~&uFk}~fcb6=lhW8c5=lr3>5$B}<;)yHE% z9jT$Axi1%r$|2LG;+KU#LShOaR7BP?F)I;71u4K|r@SJlk&hbwu(Ju^;`Ni0Lk2Kh zNRTi?ha&4n;o=QsDp#ABwzkeHRm_RDM!adtJtl#8PnuXOu6y@>K2_PG)E*V2{+L|M zX&!<9;vEiEd%ZAQR^}7P7*CJbGy&&@Gr1nilcx6ecFL(mBSSWG_#jz~Wr7?c*`ENl zi3n_jZQ@{te^wZm(TtYTX=#sUO#XhPl1lIv@o8wf;b#9Q!@=q4pc2EHtP($B2(!AM zotMO75nP-w9NL;C{!1ie zJ7$lWtfDV>-{RG)dMWvFlL|*VfpZf+0{YqO`-0x%&|NHJ~VlYaMC^>KM z$>=bAmNr?=KbEpY$8R5FrxF-EI zZ%vqzWD#7}^nfPn4=d~OOC529j0WqsQLlHY$ z)@AaOJ5N4HF!}5VAp%59nWLB=dUwj{$cC@p$0$!kJ0I@l4=KDWh3$U(rJ||5Wk;Ao z!XkcNH?Z28WWw7P#@ydJHg{iM`Cex{IR$&=!tc)_&pTiu%kywP_rCDbF}!(g+{>c7 ze;&N9)=0k>@h)E1Q*j8=($UF%kz9SrOqFsEZPZ#ufFt93*pK6TydcqcVJtaRvAH1fH~eN-fA{uf3G-|9?R({p{wR&yvn6d436gdEjNF$-6)0TGYn)%| z)P5EfyDYtZcop_=?h;~Bvyf1}&6Xweyvl%oDdueP*dhkw@Y4g#qeS>yrvJKcb-q>J zFOh_Y`JvC@gUbf`r3EXttWNl7Eoe{>Vd8tjeRrea=Nu+rtR|v~5(ATxQG5MRw>6%#Z+{WQziHCGY zByVHH+h(2iT3I$W0lK`_&-3 zQ2rS6CYY=!b85@nY!lwq@e%#;YV&1eNAAk;4F!4mP+j%dm{$X0)Ep^%lsd{*jSpeP zG!ZUdarS-U&OE$-uGhiH&C_bTwO4Nl%PW5VT!kRV*)pugOfAUy zSy0mbq1P~(!&Q@m`_E{-H3=wb3w^7->rJr3Htle)rFj36>~X(D&Qvz+1rIusc+*0M z#DJAQu^fR6w%sD(T$F(*(SzZaW5xkAG13=gf`V=Srs)%Q-^Yh;@jHLli(-60WYHOo z`Bsq~o0>|!KX8Xl>CVU879-8D1nIJNGU?K`m|k7;_8y_}I-zRif*4wUk};!Kto}7) z4hu=X(B+D5wa&Pm=9I9$pR z0^i}4&cWewUgO?(n9sbE; zFL0>XSud$6C^Yh_tKG3?HS2Y>l&^NiB;+EpGVMa0tNMZ5zd$M2+dIzhpdsI{i-q5} zZnR#9Ih(WR0Yn7NucnX9cSM|(yNpie`-P6$w6_GDOGbiszhs8(!w%j^!K<2mMmexN8#b2#YmR$7^xG6f#zKzf8$0Tt{r`2VyI=vHHKqE?jk_wr|+ zN{flAH0eVH)@7c@|+@CjcB1)M@j5t8*BE%`}DaZq?= z3)buvbrZO}kz&cG)QjwpD74%0>8dsLNFtQm5Wk6S33j&iR(~~ZsKoFVTh{Z#i{am% z$8nYw$7jq0=f*x;q6m-vT2d711Y*H;QVX>2JB-L`duby}MVkvFmrbU#`88V#>B7|; zjCr|MB*JUvPOLCHjRUjw3t7ZJ+Ljf?5e@2WY;;eX(wYg$B>yt#ls=QpIJ(Q#(+NM) zF`eXjFK(hC#dlJix00Cj5Yf=H_COx4j*aK~IgQ2816W4kX6i?&seFnb~R^JXadHK4k>guIE4wJU# zt9_H>i@3Q)X`2<2X_ueW#auEsq=6cp@nqqhDn2xwArvyS(VzYJB<1&c6*tDAgzNrsw-Lte6k5|_)$o}1mxkI(%r9>rknsddeImiIJ@ z;=;q<>9UZw^I4^=4Srzh2=eY^<$e+LLBN%2s(J)*4et>9?Eqy@B7! zS-YVqFF&FJ2-F-nr&N=;cq*?W7bt_R#Q?U;&NzU zc-)^tal!T`Jp6QFPjIpFo@2+m7t)I9wgMlVdfz53sdX~k@Rpf(#EY&-lCPCF!v73g zW7s{qhA#g1kNbGTOBY3T`56Q}@A(@~#;u*|qmYF;7Niq^B&*)d|b&xh^t{#86gHDaXNzQT4rbtXsA>xRg? zM+7+Ejw|W++LPuKn+G%=GesFXHeJ8*MHFBAIt2yFVZAclX@UJ=MuFFt5wF6+#c0tl z&dUn~uZ_uje&a>+lXYaYF|`-NoNAw~-&LBDfa-}^oqh||EWo=9{3EjFgZ2k7C#xx> zs5fU>ujS?CB`3?xD1S7X3Ktg6JYD_Je`h*ipkHJS;|D_$W~OMY(eB42Q`H717r(z3 z!l$25eFcp(LQLmV4~7@Y3c0u(>TtgNkPKb`mKG{(-p1E(9`pEfXFka3o(cJo-rzl< zfT%bZZ^rm+T~_2fKjycF#5@kgaR}{K&o=jYl~Wyokj}VumyV?wnIiv&hlgjCX0R|1 zNS~n(CIzL^$!MPWGU}8Vli?|7u+G{zm8Ftr3)IVB4A(Wi+|r03cf?U|I&r7?(Y$L= zP<6rm^1*ifYVPh9IU8G6NTr)C0Z-lLqrNNmiV-h%c9iFD=9tW!970IgAY`0-ioaCq z4vMV@fzIKL z@Ivq}8ZWjxpRSrXUEXBa1*RsaYGcEd=DDo;Wm@kNxv=-1+pdS*O`Q&zNOsOsN{)hMMid~ngg zh>-IL2QwgD*7Ak--0-OO?%lhdYcPjRIeGc+7vDpizb*YL`n>IXwR-5WH`JL9heFtx zY+Xy3Z@e{NbAZkx{)XdF0d=1C+<-rgyqI>KVV@pO0^WLVb$Y%&?8|wgtBwL2EZ4;nXJ{9hbzvulU_cLw3t6Dg137zglInGQ58af8>o&RomD`czs z=HSa`I<%=$=Ua#fCy-^kNjG4L-@T78#c##BvWf!4c`pv8hm;RUC)JMjO#B+jcLGFc zKsLfO{j65@Y7u8<&Edc3PWW2_^4vP~sBpM=WVHI>$(?EMeeH6+CvhV{oduV*r#(d@ zA`VuMv8hkuV5m>K%$Lt>?*>L@AWqm%1T-urCboP0^J?${mY3#AlKX^-S{PI;uJ`l~$SFE!mRi68PrjYS?IsZj|0))hUHNiq582rKqL!O?g*?|y%Caje z6vyb*lKDs<|43ogBnHbq?d|KsxP9UM<#!(RTAAO&*lNm@)hVx!DDZ;GilT)W%JFJ6 zKHoRF8Z{c(yk{w+P0;X^75knjaO8UgZ?tikJ&*NqgJq!P5v}@vw;NXvKMc|f+bQ71 zzk<#8dq~MzXnrYuIAggp!v{_pjY8z$<%eSfP3lLbfz5Wu)H_W_ifhDyh9P=(L$8d} z5lGdDD_4kJmhgPZ#Bq%a7vf224-5eNjH{eda{86-X41Db#BoWQK1T+Na&Wc0&>s-> zo6FX9;(>fG+kNfE%N2Dg2sUdT=3QVFVo*Ool%o2bxlw1`bd~4Q+pE`2>hZR(lP$M* zQjF=L7~4@-*d`Hl<$I!Hga?86l~#JD2a=mV`oO92G#@a`bV~1^_wJqrLws2Uzr1_{ zI*%ry{6cSGNK3oE!gS%O5p&bjK|!*hbIOmWAXCWa4P!nf0O3BW)WX(gWA~CE9R~`* z*s;o|7ZDwfLnEUlT_G4nXm>JTE;!e^PU?IhFFj*J1iNN>7Uws0bD74x^eYdMFL{D> zW6aZI6_UabfHkb3i9jT|W8+0;DH)?w1IgJ|ecm=UHOUV+yYlDVtlYnC)afu@ehnPp z?bnFeJrzwl|BXXd5h4^206$<7On$wWX|CVnQjS1GrGnF>U0Kd_HjN0`s)>$k9`29N zMxUveKLqFu@jMH3objr@}DomkXM1tl!heZ7b7^i z!6^*^gaPQw&qG!ab(5>_C0($yu|=?JYdcSN2MoK}DcjOZT^=YyXmXK~&ZCV>l)I9t zG_>AgN)Ar4IU91MsTI-$S6Iae%8r(x{qW&tU9{h7V@zv6iiU1YOZC!`hk}DMCv^Y9 z3{SY`>z`9}u;pgif6}2#j*4<+a9#_ni#95Ex@%)A37HC8Us8IUU;aa&gXEz34aXaQ zyk8kA@{e6`09Pu{!4QyBx+JL5>a!E3gHOV{J!Yf}pWiEXfoKUJ6Tj@8e^=m0g@;;y z^;rgpKO!r&fP* zHwLf`)BwffHA5fE(ZVXHu@M|};i<}F*Q?p;$B^tM0_sh?z-5(hcC_LDRMELzuM`h3 zHTfZ@w#7*sDE43 ztZM?ACRXP{t~^a&ym+DOR0Iv4eE$KJyMAcGNA3_{9oWIe9@@{9vBqjhz;2?F8hZM( z*f4;`-v|#axS!Y!-3LHoZ-Bw)4TQ&sLPtxmU$%%QIO(|I7}7U@1-+AWp8(3oISVt< zg&{Tg@StC%Q&9TA*v==AII3RV0;6x$m*9$T2|gODAg1AkLxh3SAtuCcVT19C5P&A} zjT{AE_HjyG0oF%+@pJppapvCgZkO4ksK_wxnq57dj~dK*ff}P%p(`s}VgZ3>d_r^8 zu3@xjEVHVL5$a1sztGM20wc%ZLICD$EPY7#&|T}c8YM`i(t3XZ8e^k#-dMSa!5?&^BcXhebL!Q1XL>lgVja`jvo+6L7@2<>_| z?t0R>HFhWS-(us6$7ZCqJ^O>cTE)^C|?-JlZrZ!y< zVzgN2anUwOhGX<1ssAp?0Bu<^8ag(QU%q_Q+=&+~1Mo~1 zPC-2&56H55N`?3Pw<>Tc(|Xq+_1CmTTmab-6cXAHn=pP#rH@VUsVHyt^a6=HYp#(( zxJufYoOlpGsIxYfryEkb3b9lrbMo?zx;?W$c4!W|PQ4%wiP59a8>SU({v+9W`~WfN zXk~>1agwuhp`SojHj~90%PG%PVSomKcR@kEMxCP`!Vr#91s9qMvYM+zjdjQf|w zKrLUP9-E%G@okq8f+h-a^kA4BvNbVLROiQ5@KDh6@883jR7YD!0*H`B8wD)yr(0$F zcYJhsc$dOcO`y@MM<*~y=?EXQ`qP5|V~zKwAYTCk zTBamx2LVyPBd3P|KW?{S*XO+U|L3FU(H<~)`FK48gQ;?_SNHC}q_nGE^h}bYFvqfI z%G%B*bV@tS#sl$e+u+-@P=0A)VA1}@uV4R4Eg~cSI`=4c&huKP5Eivx?<`cj0T_~X zn=J(0`E#6lg-4frdfPy&-d5enDAGn30a7g2=Jd{=;bF{Pr0Kr@gwp)ad6rjyca(ZY za0x>o&sE@~l~2uM8Z9;W_G}@x?3&+J>FX(N;`BM@!vUjO7onF%u8fy^-*17uP9q>7 zLJIrRwKir#%vNde6eH=em{#qylN-K&YA3u|nl@?D|JmgOW1kDg6qmpJ&L_U_T7jgx zkiJsPg+;dNTculd-X8U`H7i9kRltfftPL7^H%CA1_;=y6$dm&?)5#lF+r92JiY&D8 z;2f{VYXo0UPdhx5L|ANp6+h;q4e4&{gdTN*Sve!Xq5hA=+x$Y8%*si|Q_BSUv^sCk zKlJL_MsQa7hTf=~&C=ngr;p;}K?#ZK4*^znu5ojhU|;z46H@cD(8cKL)M{w!zfJsA z?U_XDp>rOJAZHDj&(%wnV-nCV02OmcYck9-|)D{cwqbE@w1&VJ0 zQS4toeiQ@8m9gF54~fgIHLEi7y4WM@ysqTZHmZ!99rbIWg7ij`IR}Ewi?16jPk$0r zh!I%;8n10c@;0}Qj`dGC*n3Ab7n1sYVJME23Y^r7{ME}8T&`#FjCw143P!0RYfx*$ z%~QMhGPD_{?Z!DMJ~Y&D`8cQXLjK7{X4)PpM1fMVu%LXlEvBVgU&HOBX#@u#ex<+z zY-F7OWqh6Gd>JPNL%n<}kln2SOBjBb;B1FamiD zvo}OOtLmM(xmjf--lOfoqrGwHedZgpbK`!?mx1P}PY&Nm9*~_`v{ikxwW+Y$Bcn)H ztI%B^or5_2dHXh!TBWUbXmwFDSVsUMS;*yq8YUI-eBEy7MI_ai+P;~j^DxqKkF#~0 z3z`_43Cxg2W1*d_BfXmKG1!<)h4yc4K5oscz1%u3`G6SNKg9G<*6jr{+3zzCIS*;r)2#aVN*-yz=c>J6%u_6)X&T&1#U+E-P9 z2#hI^Q#{M$RE?{YV_9HP-Ts76P0>kcXxkLZVQBFMMe3^Sc$Og{$|ynYFDVkPOU7Ua zJR(U}jnOh!(e$pT1XzX6rM^pB=dt@}()-lceSIXQy^f{{j4lZD8xIH{usciUyV0_L zQAr6Su!621iRqUwYN##1DTzNnB1`5U1$y`wNqapt8$0(S>Y-?`8&r4nr@oQVvDPJP z`4WK0u+yROAJU^`fFCE!yz3$)#5CgdM`Oo&p2sD) z>v!SIw(aMtYq_Cx`TcI_L2}n9+4AS(jz3;aPC&FqpViu_*3!Mce}IA`5fFRo=U)Hs z=Q}r+0D51S+vO$kR?Y!!l$C$BY4lvkf3(WJc=2p2H6D}SJ?`?InvjHf?vTzBht@=U zj#%z8v>@&Q44;x7QljJWK$JEv@bIwO@@*qF%qk8VbDO;`T%OPE>wZo3BKG|$r%Wh5 z4$-C^m?InDeEH*$`qTU(Tg=tP$y1=5XVS^|3EM-9Es#KZ8B)1|GSF;kp`50(nvaf; z2md(`Ru}o74f^`Te0yu#$ErGa+&@WCpPUTo@7e!ICF4Iw6h2+y;$M4wY8xQeORdHt zElpNXP_VW(Kd+qq&V(c!Xb1=o{CU=N5{GY7dq+Z(@@A^v8M(Qs#7xy0^u1&_%4>CQ zf3eCYDfzdyMSIl2S9s@B;JHZ#tqm!s6*10-JAR#?#&}*&4ij>VGrRlngCaH66wY1q zr~Qmj)n|%`IRdkaj(oO1(Fh2k2Q0}xm7w&8&{|QUkx_kD?M#(Z{l+{QZqD2oGvWMi z-8lf^_U=vpJh~;#`!MS?@&4Hx_&G^wPo8<6U}|>zYjpP^@z+gXku7#Rh{Wy{Qbrjm zQ$1S+g%FnD4Yn4OVFSqsZ~9!bJt!Hd)NGm8Y_ZXhbT~vz{}F1Q|6}Xe`9N(Nj*6?# zg3#58%Z6sWLt1W}L&_g0S!F`=-^NU^179+ z?at)cj5cFk#7GYbpN2IZ08?+2P9@?lO+Ewrsg2a3@*cBaMCiePjmR(H^s;vo!# zBA$Q*7&fl#3u2b6*PLlYV>tGz-)wcCng~B~HNNXeNuRdqySMwpnN%1GrCA?HG><_b zan@{UYI}OPzEaIz4glh|JG>orFNfl4xI1{ z!OWY%$u0Z?$W>JO^UKQS9KfPB5C8n30~zvy>>aUdtn=<;nGFqEr_bseLx44po&}cB z#pc$K5#r0KAOjhN4Jm}R>&y+9QKf}))wTOj3uJ08(N1@TAS3sPqkqQZVK0wB|Fj0> z1Afl%ELq6Oi#kf_{gk-zz4F$D@(LJVc_=!Fn=ZDrhHNlM{nMWeYB6&InhMz9i=VkR z=XC{iquU<`yG|T5m;Y>hT9iWZeE1e{%%oE#_0`BOnBK->Roajarj5$5BWXBeK+JuG z2Rhi|i-;Qa?FxHoM=AZByZ?!9nlNhO^(P#5v`twM|MmXVf}wtVQ}S}y8j6p$P1@v= z_wsVsHoxSst)Ah}$nHPou4lt%`^LQkk)|hJ6z6kIVbx!D&M4@dSIbd@+sk>c5`j zf5`=5emn+>al#0d;+eYsl{Va-7Ns4BHZyW_Nz2YxQ$ecH7~81yB=v|6!st9Dd9S$Y z{)&obSQADs$J)}4jw*ZVeh1otNQi_X@#Lf5HT*NESWtg&cM;t9Rp^?N#diU>8 z-B{@?7og*uz_WOA=zz2W3KTTaxALRw8(ju}1#Dc#O^7CwuQCIgerMYh;z<2U(bS^o z@a``0n+(F!Ob3UM2|HP54YN(6Y}k8aM0v%HK~L5jwsw%aX_elh5zb+@(mx&kbZQP< zm5|)XZuMFYq-_5F-QAwPL{j{WYQeT*CL%L$h4~H)8Tnn>1!+2@;wp7Vm4HAYbI`B;iRA-e0 z8@MJKmugL)e2;B}o7$||Z8HGDrEcCQ)0FJAXs4q`Gm0<@b4E<_veG?Ec<006Hgji1 zJ8Qu{0$B4bj8AI)u}1@({1w)IQnh>k>vCuSJ`O z1z31vh88?~Ke|d60=l$oeET2)c`La)nUU0sHt^fuEE4%(y&ATOe*Ok8%-^z1XywjP> z^n0w)YD?Q=h`${_g8-mET|a(Ac-$NbQ=y24nJUnx19>^YG2+l8nsquRDtfTO!t$29 zT+u(S*bgi@cGiKFRS0YA0??Kdt#2ggG;G`9F-0CuEP3yUwtBrL&haZVDeH7KXr1P5FP|@<~ltrx{5b&elHo8d$ujIMfMd zNFlPqGQi@MCHBV>R~i`1l}6B|o>Qwu@CZYG^Y-RTMe)xb&W>R011Vo`4!9e_F+ka9td~@W0Q1Qj-tl2yUz}lF z0^WhIfq{=6YK?ULf3FAecj&VFu(zz6U%NFt3V}766vlQl)` zZbfX7s?t0VTc2uMz(;Gs5Nel}z5GxG1}qVgg?V`ot7ru4_ulj))X$~BQI?JSZGUPU z%9{W^B}t!tZi5B}O>769w)CT->_OrY+2_j7TFp&wyL5}`*83(UJNux;BQ_54$Rba= zlmo7`X)=~OBCq@h%pi zRe>Ah8OF2t_9J-De$gE14D^oq9A)nN={Zf*`lM*Iv|;vp6TZ+-lI#(Mgt~hN)LDccBWX%-*20^MIKae=FPAjF=e%Ao@A*Zc9URxfXsYpg;`wzrw zBI141Dgz5GYERZ#hTdY|188x1%_uY^M*16zp5e{t8?q(9^7x$ z&zoqq-=~a2YnZ7w9US5Y(<4HpXl$~jEQL>aWmg-KSAoDP7089e;$6y<7f^Nev^(3h z=?50*N3%1ERKpt*uB8VGLoN77f>N%RzJG~3oa*$lVy`CLc?dwb+GU&BeUlXoh{1AA zn=y_Xzb(CFuiKH4p6-4J_*MZ62OdEzo{FZ$PPiRtRq*C5^lla#1Kia2?-|T>c4lGV z*RBXPUlX9xRQQv+mLBbnKt36Tq%svz6@IK0>!IVSr(11*~*U;Te>VBk4^(AJpwli%U@u%9jsP*7&Lt#+3r6 z1em~K%ubiSDFSKwfw)wh{YsN%sVKpC?adOD^%{Xz#rh?X5!By^TCg|I zexF7(-lY#a_&au=e#^i+!Aw#(d`(?>k$cTtrhz#g>{uX&n1BY2e4^8`l7?@WRmDTl>k^#~i%mhn)Y<+QqQ zA5t*U_kVff!QRff$ zuc>mRQ_~wI=%Vx^E=@>n8i{G8V5(sV<-`lB)*dSsLD)B6q8`lyX`t<-{rX(P9dRmp;2`P_&>7tvOWjB!X|K8vkG zcU`+Yscp}QxMNqpVnN%RIzDer+StAr_DChP)d9Y1(f3E`jt&arK+UO!*P|&IuZO2p zjPv_0U5{qq(<1zzXv(Gl8#x3$n$r}{(qg^J2xSA8()AlniP8?kdA=dtWSdAp?=ka~ z3iEQb4yQ>%J7b)!&X_(i3vo^)MKpp>!)K$^(5v8S2i+D)1qR}(JzNy=dNp$2($;nO zo}^1^*jyJsal9U6IHv8hDy@kdQGz2}G#%gI$v^sv#Z(Z>@O#&mKoTqNKgEI!4H;6L zo3Vbc3 zn`zZKZ*TrH=ZwH%t-XI2kruA&%^>^M=Lk(E8BAc8sE&zw@-z0s?FURKZ`B56+UtOW zmEsZLgs)en8+ZrOw$$NdG|aHGmQnH+{=2_FI5}EBIP{R>Gro>vu0{a2OzOc&rmm5OA*6Y(M6oK4 zi#tz={3x&RkPl7mGwkjtz-S+ub`<`9E1t7PXuCzW|Xg%`viPX$(bfPBhsfi_q zAhL&LSYXMB4RwtkO*qadeBOtTDHjvWm}Rc>9#OV0Mh$+rR^Qrz&w_tCg(~eUTsLk| z46OwD@-Ln6ulLtqRpE#~8QsV>(MqwW*+r>ZP2df>M9RWU1Q-D3H_JZE00UTyKrcJ;I9zdTS(jeyXgG2j4r` zL2Q^g8^9RFjsk$!|mX}-tzk90(bKd$iV zUpMHip%YUFC=RHEzy#_ab6DdPxcn*~z(W6NVHiEYzNk4X2*>Z^WDg5IzwLxMy7&E_ zdECe7>gFFZzvg&eFCIPmOcj@Sv+n6YjmHl!GL!Bp^1d3G=f6?EUxgoFr7oTnCDc$z zI?;}n{n_3Vme7%vl3baOL)u$ywA3T!@s79*7 zrV_X<|8l!}b?2mdu;diSXRS)sP(GOA4K{zr1sX$X?lbiKPP2zEH)OgTZU)Zn^7cl4 z_j@7~JR_b>kk)r4e72(fCHhh7#;vumpo~{kIKRaaYmzwGdFK1vWi55PxAgptq0c2Z z*=|{$86M!dTj7z0$B$gj#dfibL-Ji_ye*S%^#3U=E6WLCMioUw4ctbF>xcM}>$J-h zoWF3hW>`DpK1xo1RpPkPfz@R4<}MZN{mm^7qninqE8opuA9*}jxR~kVqjELgQKoUm|V7{s4D1~2dJ#JailY$;k(3<8XV&{3;p0sd8a3;Yk-5(+F z^VeW?d8+PKE0{B>AI;40@?KE2*{<3+C1ZdH%wTqqVNj8Z8_?7SfRe2d^OLHjdR}^L z?`b#6av@|X2IF&eMp86Z99GCxJ`rJ7lZ3IZX<5G?_|r^ob~@nJ)>dAYzSLnzeHR6a z8mO}K677=MeQESfFF%v2qqdP&PDfBtw@i0aN?&ze{kFDdO(R;;RckNlz0LNR3S@z7 z%kx@DIk8HX@aDIFQLfw3KAjuwsY?e7JTCGb-|<;weQ`}m?h^6c*EUV+V~OS^GM}?M zxp&1Ux!>TERRM$ec8!)n9S`7jGH!0%g)>4<^|l(CnglA8wBj#slS*$QMJ7BcQ6Og^ z1UE83M+csKcG}_B?k5!}*Tx(DM$03FN6}+0kI(4z{QYeEN4dvnW<^2m*sHlKCmtrhMZA=g)%Q+A#m$)Ki(mY+0?py%tSAlB z8XAkGjvmjXcY{%1BU9>XVgI4WN@-R>iMk|JQkD4M$xmlcrME|x4>Ak99!!I4SoIsS ztaDyMJMLqc--Re;+bOgX32u<*=|n(ghf$cgWAhE7PB=M&kRAJ%)qP%<{RqDhu_?vWER; zwepRxcSRP)Z{h#m4-W-(PB_LHl5?aHt>Ul5$DGw?n;Hr5;#03b7&KZIR0+=e70ji} z**62Kt%Y)|CNo}mJNqc%Zvr>cJpZsWc=Va6Yu8dUzpJFq zJ)DnO6THf4oS*W;FD90bc9CI)&!B#QT3>Z357p-X%0KR}FE`!CGIFa+=kQ{pa;kp? zn+V%|U(;v>imvh99L@*5nT7PIV3w;kZl6;(2FW(2RZ0a>!82T@s+FC^2FA{9tJNT8 z3;0RtCHe9AZ6iJ6_6czE3-&U8XvTP}!9fA&zapsEftrU3BTiu3HBU)l`$AAJ5QOX? zeAB;e&U-wWYIlj$6DMnHpVY+iDi47?sqWn>kIR(RYf@asTWkUFFVyy{Gk6={$>RQX z_ws3%z~rr>f)h0dw+fB?X+#0;IXQV+s(v&ggjp)sAv(6v zm>ks8tBfrKnznrZ?0j-gLaA;uD(lmn7csaZaChq8Yu;*FE3^^LxY)iO^5*;l1S-%m zMs8thNuBe*02$WBv*z(KaBKsWn&(_!^sk5Op@iGv?#RQ8!a97}-PMWIUdD+!ggn)E zd{Z=+!#4(w6mKR2!>R1cS<#grQ+o?V|FrCCjO^0l9u0DQi`< zXbh?)19&%XY%W;tz7Y9_o}3R|+(9RP==7rtKgHm)5P|;2n3_3H*g)eh(d?Be&$LjLIu#zc=iwx_=`^m4 zJ#skkwygbTwrJ~U=TxRpV6?flhEU4M3B6Iho^qYW|B}fyN`6r4*^zw!D0bixCoQaw z+G-eWk@g4gq>wr0+;!>xUbUy2)BKNoq=POWA;c&23na3W+sPmzR5LjX`_?m&=W)G> zQnq#~qk#C#3Y(f)?gfO;JzJHhAi<{?5!B;Oob%U5Iqfw^^f$GFqPX+z;^F zU9dcRR+@-EcREweBG;K(37CuK=6LpF2G?5QeZTW8EFAW}dt}4lcMHz!yZF&D9+wtb z%duDg^t`}bilqvU@vk>E64ctieZ91l&iUa-%~nrtNG54PUdW~d;sySP#DUZ$_mLwW zmsXJBEb2@xvP&<5?&*lBRn56VF{-EyAF?bS>m4b?4imwvXOISmFckbm`MWqIzRgB+ z-&MBvF1m|*q$={6gyhxtdnx{wrU_DS3{P92V&&D$CCqyZU2+W^GdN#Y==AK~od;k0 z7_3CwrwDv4yKGUagvv?{MN#3o)_UJO^&5IKq_n(#r>%eD8tcfvp4HZhZyI~emg}o8 z{YXcfUYopL@zfSm9(Aa0#jB9SqW-%K$BUx)qeBbriQI-uAnD5-zIQa2R?xzjtrUJ8 z;6ft1DiZ_+>CH?#0+8z`wy~c)E+7Jn;_dP9J3M__3=Xhz4v34)oTqwAGPS#3|>PbHS&wtb&tSRh-= z&BaAT2~;(cJIgZUf-g~3K{ENDBvY;-afKo0rSx)fgHkX2o4hly{akHH<{Zw!%Kc1g zG4Bb~4^p!&9~x1*cI=?Rl^k2MqSpE8@x ze#6;4V-eWmlJ$1)kRg!50OGy^#%FIp@yeye5gma_c=4VKR%R(;IWpA)&zxUQKt! zLeKILs9zs;JMe}U{w;eG*Uf{UBfJaR7chXsYB#>zM7=%%RhUzjdfM26iW}sooh0N4 z5Ujx!6>ynJuITXIuI+UdB!T&8DSh#-^v!U{R^zV2Iup$_#+BW@UnBair5!UE|Z2gRaO% zDiebE>XqbCxp+db*>#L0EULfkZvLS&3ridcXw(sNx`W=+RuYC72o<_PT{n(2<(jE4 z0HYL0LGJ}4DEsU=^Ruvtg1x!U--4Fj+e1%Mh!hn68%hf3lsG8>FfwN?Xs;M%1@{O< zC-kvQQ)d?^jHSoXc!w?Wzi+jU@whe;R!E8`pnL}KKPCb3E{tkw_(T?Ak6OqU3{XIe9oP3=lg%mT+gT|B-fq-PiL~ zEoAF^Yz-V@2f&`ZSOTz=1;rf#%ws6N4Lc$}HT5;X%CVSK{$}i1!b=eP6r;dWxb<%} zVQ-&cTN|2gDs?8(YRh3u@!_|@p|=9`Ep&kE)8y+dfYPAWZhXvIp_m9MT7e8Ka{b%g zSb)zWk!(g_1x2Sy7@q`?8o+knftw&~*Hj${pLNR2JZ}fH z$%4ki;o+xPcMy06Rsda43h&<9!e~Dp*q}>P)O{KG3q!lUVP{@^hw1orU44-4%MCO+ zD36-!lE=vahQDhAm7-2bSokTHk=J$Mf>P0NmOsp3aYa&&9f&sd;0gMXFck0m-z-@1 z84+W&2HMe_C!pi#-Lk6_KTG!e0NnWq4R-ksELBg<%$SOADF5f-PM4!~={*V1@5rzd z78ZW*poSq-yh$)C-Yjb|8bb0NK)E?_7zj-5-oo&<{)h9%*}~La%-~3>{|<>ZSeXKK z2?ZL9%YfAvF;%?Vf53r1ix8~6^xgzfF8nBg{3htH$RZS}Wd=nhE*6bBKrad%14Whf z+ym^?gx&21^hO|^H7NRCYW_!@5~$6AUL$r;mA!ovO&ztN*BVl12wJYqR3 z0FNSKe|9@Vk91Zw=c%uA;0CKd^fA{ViyOkuM-DVk7~E!*`^$s8)d^Go3!1g4SV1d> z@8A0W6b&n73Ku7EmGFJqHQ+Jg<*|fywNybQYX00%DZWB?FxXj$2tMZc|B4p0J#xyr zKfb1w5b!#xc$nji5P+hZf9D-}vk3M3UQ$u7bYhDbpO^1LnsNx1uUK`v57Z4Gy#z&- z`~vk@ML`&hc_cA+oLc@l3-$?SeO?5*MNEX*N)mtkTMMal{lCBd0QEc(>ezhC|9&%D zy@kaA|D%!tP>Fy*#VGx}6x2G9-GK;b2#R+h&j2O?K;J5eQxxo<4hqZ0jbNkU6Z{5< zF9ZV>gRld0a&lOBc^_h{P~RB%GzPGh2EbP(P~aoyRfv3p!n~xQO)X`W#6J?y2KpffpzSQqc}8@X zK7fQ#8EtfR@5l&z*V55H3tJe%5Hvu&L&X4xH0I~ck&TsHIPOJAFD`ZSA#fJro>wlR zdxAf$@xc~0s19tLljxlne+Cs^xxSnkQ$$@~k-3C^)N$0GNE8Z|;nP?UN)jo)gP4#ScHD({;-tJ#G$1 z+(%kRgbo7)+t%u~pMD`yKLS~xEtk72P$!2P6lR-cCvOLyEsOJmlwaWj9i$D5;GW9u zO2{RQH$ZW20;u{kVUCMXEYpd*G>FIlcd+PIyv5$1jh&W_L()mhkJNxeoGPPy_g_qD z`&e_;1QvvK8<}gB_OAi{`F~r;DISUbRMt#2Hs?zwAD_l-NDZ?*E^K_&=Bux? zO6^yO{|VLhB4S#7h4~=>1!k}B2!xx1prk>?2yPAY8Q%YP_>aI1LHI;lZeujbtzOb3 zvGDcf2Z0cR@tbeELons3^E0bfo<~v)>hE3W;q25{5xBRR5t#2Z<}MsQybQyOOw9UR zMUBG4a}u$~X5U|vFza7iKj25zogH{4eG&xcg`n4}Rwz;{)Q`dRS41o>#1!{$!s6c1 z?OcC@PYw7)+cnVJE*c<7y?TB)GD|ib1TZjMc(Crc`U?TMUf#e&BZ#}k$`C^%MseR2 z*;@m2!F4_CADFPWUa_Y^S!Xczy zF?nq&%!Ibio2K^lpv(8N3E1m>>Ni<$052G<@wzKQoYY`t)NWES13W>Anh+<$wt`?X z5PW-_&V0DXH4O?TQw|s6jNeoaG`lTXPs6_!dnPH!i({?jam%pA9*<1Y|EcE6|DpcA z|7!?k8!D-UN=3-n%5Jo2duK^W@3&p3lr>8jgG3SPttdn(Tgi}pm>K(2_UwC%EMbNW zGnnOjhqq7f&*wk*{xUrtJ>1tl_ndRjIrrZ4d`g~ab(6R~VUSn4Xa7;Xp@UnW9sug{ z7)vb`KV>fUtSh6mtLm`lsV@jIA+fnPAAABPt^_)Ncb*_--`aovI#7*ZHPTg^aTO`x z?Zw^Etx^Z9@=}T0s_cO03(R`C@K1kGcG@kCR`aKWWWbqzkYpEyDU5V8eVljz*@W% z#^B2rc6gP-M6AIUhUDZvcY1rGP8I|@f??a$nl2u}#xyhw+sr8FUxD3%y#|ob?k_?@ z(V}8&2!gi4dj+{9PfyQk^lej~XMaL+ij4p!P+qL`cOOS4!^EV;LD=V}CSFL+0LQ-% zeBoV|N%t3mYffYy04wf~d@z0pBKIe&=>)>uH?p^d7!%JhDt6q^eN{(hqDbUvQEeP8x%oPa%^Q7Ch(29DMD*)p}rCmVYKa;E1!C z_vj#qSAZYn*M*iglrCiH(|LqGNow(ywgEI5veGz#A2rF?mV4})veI9P{bN6|W48e= z^e{FSzA03bQr-K4J!?NW@kdJGwv<4s(%6q5RJ400yJAV$_2t5AG70v5Ttcbl5m7pO zm7bBI11YL_3Jn89`5)m@&nQchYN)(RS5Mw6-{QaKU~_|l>^XPzJ@^;z8)J2?aB zi&vRyox&;kNT~{%Q#Mx0Z}O(@YIOrPR^#PmUDoGUJv86)Y5j>zu@4?YJOyn#e?0e< zT-qAAVmImg_UiQ=+0biw`usNq*LZ$5;1m)>hZD%8T`ce~vc?7xPOzkd$F1Yt9uD=7 zH#3hLcxmogl!q#o#@YI-^mc?ddMA{OCQk{Xw{S)Zat86%An(<%ISfF6p$Qu!3GQ8? z@4XW?u3V596!dXr5&4N5rg1x~1EpA#I?^)N9SeREs^*NzbA%rm3UdoBE1&GClcHIr zvoOXSDKgr?ncJNx2`@V%EZvp6Y6c5DiVn#o?c~Tv2-=vI02;LcX;g=I^T55~@15Pl zr;S{fE&*&66#UCGvm?|%;cD*bJ0CM!9R6pZG!)M)-CAX9a^_A(E+OvawU=HYu0o)| zo-fBDC4)t{ye3fX)3h~}{GJYZ8}LTmeI@R?wb4mU^^+$O!XAaRcn-HDHaQKRhAJ}` z@Z@=KppMiLj5PQ`+y{%KxVF(6?xw<_w}$a0=9e$4a}Vwgj*MLWc_>=i46$G+Ab#W| z3Ptk4s4zIwF*%a%0t-a@-nlbNA0diihq_!Oys$x)TS^$Lr zT@4Id;fz%UBiWKoY;pjd$waa#N(5z$LSe~;r(4g=>qVy7*3PLu{-%YQdqq2;$NgVM zaHiA7rroGb^#W$wd9GcXV$ZDj6S<9aS*67;7`!s+Z7iXZ8;<-qeGx$z13=aAjp@+Y zSdO?`9_?fS-V-=qD&WTA9i(Uk`duT2J{V4aKww==Y|JiQDfo1W&q>PT2|3RW2)ttCs48}^|qw~O15hYj?gJ>Ip)ze%@>ue&6$z!haAw2D>V{hJz)$gW*enx5l=+3=|?8@5h(AI163lgSY{gkjTAgA|Elp4X=&bnsmc z)z6+kKPqn$4^*{qS9#6NaGa?*T8gz*ekhybe~vZ}JxNN6cEMmLJ5%u8&V6#NtR+sEuR~WHS_~md zdV#jR5sU<9sq0F$%L+q6$vQ5_`uh63rBlJ+OliWI?LCH#Q&X!bS9XH)@KiC5Hn939 zbQ2|6^7e;<`SEsjs}S%4y=H#wG{+4N3Z~Ctz@~3x8?n*E-rkpfqfd2I?v0lISYG-h zl_^L~(k`D-U0%*bgyG@VxN&i-sO{@Z05NOb`%WHV*r1qJgT$mGPP&UdgB)_E%NGaQ z`aPJ3j7=XgJtJ@j)JF~MRV$fr{pgsO7;8eyf6H*di_Ts7Lp(J)+w2fz5RmINfcDqP z9j0byWzEgv`tmzu4uUv_v^An#UfacK6H%+dH@xLzeu~3?wwy-*U+0-=O z5u=xZ9A-c5=kVCf`s#gKJPI_iI##KzxNR0u{9*l*bPb=G53I6-P{AxLWZIEluN2H;&e zF65X_J$YbQ>su6qK%Lo^QUgckxi|F*X_DU+h;H5_BVUZzSUum`Qs8AvKLzH|nNk9f zNKk&jNS+7N`pvX)y3v_E^F%e6?aT{NO;*p#Z>N_c{!#U!?V7`IpxB!8bQ387+eayL zeEV-ezwS5;fmc_);3$OdHXfekPi}1rYvC6p7*6b!{yKv3YQiarC)1okBQj)QVA|3e zkaCwBf--{H7SNwYK0BOjIw_jmRvY^P4#uP9B9MD&w}Sv#ispFM{TiDf=YnX~IZ7D- z^Z=f)t`k`;P$h>@1Vw9OBZ_7Jy*^||jZN3g2Lu2doTMrS;7>|#}m^w0ZW5H zu2_~T;G{F8>i>IG%iQo#mD&=~wLLQ&FEVPw!}C_bu{pLB20^F4-+Sap?bIt!jr5eN2?9rgrQeP{J`#|@<{#RpO#?qsR9^E!5dX~E*m4@4m~`EoF0jgI zaGR&cA*QtB*PW3FJhH)-E^AIVPSh06OunlQ8Nj;4wCZ)Ye_0hQg_&$W_~hl^KJI{t zaHbLP9gvK1Jrsoee@|{P;+FqHc_QA$R`n%xx~;K#>wKs#w<`pFFJ7hCsFNz0DKTS~ z`!?m4Pr2q;mSKq$PO|$?j%3&JqajU7ayy5b0}9?>Nc8PiRqJC4=)G z#mQ2xng5(K^mILWQl?ppEw8Sw&b980oNNp7G`m)Sos%OtfSOo*^A|gK$K{J^yelcD zIAHN^YgAnu-~(*Z(9z!ilUw=bsOFxa$&k`jJTbl50eG|{CyuRur%f0Qm992Vt1RRp z!|^7{nU%+u>O=6(9TE`q!n^re3vRwE!r2HANdnHb=ls!Ue-8zYKzM8s#(qR>s%?5j znAk4YurTY8af*a;_y$3hSFT!O85IS_NzVY{O(C~TNIFOzaVWKB-F_QF*o(3_75fE* zuHc6{u6?cfP7XLP3XbObxITcG1MA7Nv%Y0?KKp{)ez)l^;bi~%2Np&CsLM#sCIeO6 znlFHF)$V63EG*2`D;RS~icI!)xxLrAK^sJ~uN4j<-`|JIB~(U(g^#x8CvlA!U${_5 zLYK=>(fiM@>vE%(G*qk}wm(Ly3UDKTZ2}L$SlPr8cx@gi>IUrMx?K|ebs@U~F;cHA z<#=)JHv*1RQv6Go`J2(85n{UOs?Qy2fq&Bq#;1Qew&3l`zK0&bDi4}f++0qSSwcGj zPoEU(hH#F#OD*Leci#98PzR(uJ)q{^@sy7nGS9J?UGW>@Vj|COQE>yzUY}LQ!5hC6 zSMXGO#`mFe*C+hlc@+beGXT3kNL+W(aDw%^VIHte)tqg+?qzaAL39tt)d38lCp|4~ zzsMrIdhbyPGO?BLddXG61uZTLwW>1-$~B3JNgiLP#O+4X(wR~XK)0MP`mdE-_F^o) z8MY2!k?904qZi^8;epF_)p`o@cc*YUau#Rzv z(J$QCJpYo+I>4xATkHS~@CclaLbu}So+FJq!0OB_w28+3A>cjPvZ=c4_7?nr%WI0) zuSaJbmO8~N?T`85Hj?;%^8N9bus)Diuus&=k%ynI1;p}a(L*T7KP|>1vlTG6)d9+;GfAT31 z3C?>*urj88rm%eoFp*%S`BwBndukZTNMAxaP@Qw2=tk*oWJ|GzeilcbPoGrh2CLKQ zw}%)myb6pE%^}!k9cH1KK6{dcpk_KeTQ4Rat(OvlY}PDoRd0TdSpqH;?5nB|zR;nR z1FY`k8=bc-0DS2OVIhIFOku*2)Jk}@4STUM?rBn-WP8i?H9KwHNVQBIz|qH;4QWl( z1S}HUQqfv$MwKwS67q$ro3$2NFh;5Pg?T_Fw-fXxXwpJm@;n?IJCN%s??T5~ZDC8N zT{PX^s7(`W)TZ2(iws?}5@WPqja*6zK^rdKr*>_Nh0k6Dl$fYsAD-8MQB6$=JI1Sc zZON=-XuWRu{jDajsk$ORxOX(}f`Sh=#IH^?Gs%+{#*5QYZ-9MnWL*o$*k7y0WrEU| zUL#H%V!2mR$|uO>qrI7ANBVT_Z)aSMPfd;Bqu|P1?y#kUEPGi$#06+MrKFfis}aM! zWCzISvaQ5Ig}pgD3(^PvrQ?d@)vylOqPT;J&iDW1KZ~GK{*wM_9r9#7pK#)l8Y4i% z@t0r4{8uxp5rTc)t?qcHdh@C+D^ z685V8``=NlNEB^~iPT@uG4M4qn@1Hg2+3hMT5^nY$|~n9f?3_O zE?}%_jZM3HvYN}Wadi1vnijLyd*U1?2aMe9fuIwwNeS;0WqgL2wA9nHC({n>0~RV} ztu)Y5*qt=#9Lpl5Ls6Tyi-pH;jsG2gl^G7=EYM!;w>lWhApw2!@uL;ZnObMBGE(7X zMAUMA#UFQ=Ivk$%&_>=xgM8HcXO&8So7>*486dbuMj|s=pPFeSnW-q8jq=XNE=M>! za^rZvG9oR=J3m-`(2q%=IFJW0Bk)rc6$YTw9O+8JRF~$<)F5t}xSt8RGZSsP`ef(X zEZ)5{zb+uK)Hq{&1*X{ynU@U{<&^vzvARtFeX%|7`jj#KJLw)BR2OZndwmm1kW*7P zOUJ4U+`pbX<7>4jAXfxCz5KT6m^S$>V>RxH5CmDGnU2lgE*eZq147)WQ(cJA@1mVy z^eTA5nhvk9c5Bq9#r)+=ntUtV^*bQc%>e?b62PR{&ofK{3_9N%FygOsbC1(jzW_#8 zR_RLQf^Erj2-n z9>5lH#Cd^q#i&#HD8X)bof^L%Ac8D`FpF#2(SS|tm3N2!FVO+mMFYUIAEa$ zNc{3MwE*^A4{F7k#BMkwk|tkcudiHm;~8uAhS1&-kon!q%*8Y0z6Nmh$S}~8{S-V= z(ia)INVxrY$~iM5!+w;m@cbz2_82|70Py6S#*0UCM6_g*a?{ z`96b&g7q)*{vJKisLgJnx0^=XEgy{ictWmwt#Di5vbQ~}4%q?j6}Y;*}ZDS@?Z0A?f%;r z!hXofX=Ib9jjc;r83D096=ikqNz#CXhjC5O$h|i#R_w$af(iF==_g>K=@045}X|8irM99O3#Z!X8Gs%DGE>3bzq9^D& ziLJGk;Jo$R?3mr1JqnMr-!{j<_g%dMD7EDp znwsiCX5J;t_JLJcw`N%8Jl^#dJ?0g99?Sc>{DTsno_18?m}N28JTig$Hr@Q_=`J@w z7mkX7>!(BrNdQpKAK=b7WMJU7E|acj5Bl30uEeRzmiRTg%;(-zKIjdW&@Xf~y3d)7 zBEM4gV7!5fCCFv|O^6qOIPL`!trBE`SIrRkLqybcCjFg7es@Z{RksytVfgMNc&Pcb^$fgGI0Gbqx>Z6BQaexTQ zSLHReP+i52af3D|`om58ynri#wW2d{|8ffGW}Q4~Hrs;c=j~V!i^EEUeTMD-YY4Cu z@)}*a0)R?(jW0$x-JJC?yB-)%1U-mFE~gPmX9N+`JGDINvEXQkiD_2w`xzP;S$tfn zw-o@FF53|LdcWVo&W#XLlFIJ(8p~*0G0&X3w?`QepU>!ebM4-pXgb{baD2Q8-1-(4 zxxvB=E-0`A4($K>`D{eHX=rlt9so()2Ot||WmCTW%^b2@Z*s=mlT3 zL5l-+t|XOP*YCMxx8t=5a_qS3oPh*+a)lZDTkN@qLIz>-^0|txZq!#jd1d#)Gv9dJ z!eze6dyhTTG|^uye;|SO;}_m?=qgf)qN5&9i(ZPy>zTgZlo~{~NkTI`euO6{&p7tJ zyyn&J={bbS%4%i5spZ|9C@(MH$ohCOz^ylJR?U7aFB>ofz7sNu-TG zm$dk>S)6$A&o!N)5ZlaH+t3m{TNj+R* + + + + + TETRIG