diff --git a/README.md b/README.md index f56e643..0110868 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,31 @@ An infitite runner game powered by Firo. ## Getting Started -This project is a starting point for a Flutter application. +To build follow [tutorials](https://youtu.be/x0uinJvhNxI?t=1114) on setting up a flutter development enviornment. -A few resources to get you started if this is your first Flutter project: +Once you can build a default flutter application, you should be able to build the program. -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) +Simply git clone this repository, and open it up in an editor of your choice whether Android Studio or Visual Code, and if you have flutter and Dart plugins installed you should be able to build for any device. -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +If solely using the command line +1) set up your flutter development enviornment +2) git clone the repository +3) go into repository with terminal +4) type: flutter pub get +5) type depending on what device you are building for: +``` +flutter build apk --bundle-sksl-path flutter_01.sksl.json --release +// or +flutter build web --web-renderer canvaskit --release +``` + +To connect to the server in tournament mode, set the variables in main.dart to the correct values of the server +``` +const SERVER = "http://serveripaddress"; +const PORT = "portnumber"; +``` + +If you are not interested in playing in tournament mode, simply set the following variable to true in main.dart +``` +const NO_TOURNAMENT = true; +``` \ No newline at end of file diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..ae08714 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,29 @@ +# 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 + +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-lang.github.io/linter/lints/index.html. + # + # 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/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 2c1c6c4..fff9634 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,41 +1,43 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/android/app/src/main/res/mipmap-hdpi/launcher_icon.png new file mode 100644 index 0000000..33f47f8 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/android/app/src/main/res/mipmap-mdpi/launcher_icon.png new file mode 100644 index 0000000..834a362 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png new file mode 100644 index 0000000..b969279 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png new file mode 100644 index 0000000..87c773e Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png new file mode 100644 index 0000000..e428344 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ diff --git a/assets/audio/Infinite_Menu.mp3 b/assets/audio/Infinite_Menu.mp3 new file mode 100644 index 0000000..e88f8d1 Binary files /dev/null and b/assets/audio/Infinite_Menu.mp3 differ diff --git a/assets/audio/Infinite_Spankage_M.mp3 b/assets/audio/Infinite_Spankage_M.mp3 new file mode 100644 index 0000000..7bf2b7a Binary files /dev/null and b/assets/audio/Infinite_Spankage_M.mp3 differ diff --git a/assets/audio/sfx/bug_death1.mp3 b/assets/audio/sfx/bug_death1.mp3 new file mode 100644 index 0000000..4a6f502 Binary files /dev/null and b/assets/audio/sfx/bug_death1.mp3 differ diff --git a/assets/audio/sfx/button_click.mp3 b/assets/audio/sfx/button_click.mp3 new file mode 100644 index 0000000..eff2b70 Binary files /dev/null and b/assets/audio/sfx/button_click.mp3 differ diff --git a/assets/audio/sfx/coin_catch.mp3 b/assets/audio/sfx/coin_catch.mp3 new file mode 100644 index 0000000..1804fdf Binary files /dev/null and b/assets/audio/sfx/coin_catch.mp3 differ diff --git a/assets/audio/sfx/fall_death_speed.mp3 b/assets/audio/sfx/fall_death_speed.mp3 new file mode 100644 index 0000000..986aee3 Binary files /dev/null and b/assets/audio/sfx/fall_death_speed.mp3 differ diff --git a/assets/audio/sfx/fireworks.mp3 b/assets/audio/sfx/fireworks.mp3 new file mode 100644 index 0000000..716b377 Binary files /dev/null and b/assets/audio/sfx/fireworks.mp3 differ diff --git a/assets/audio/sfx/glitch_death.mp3 b/assets/audio/sfx/glitch_death.mp3 new file mode 100644 index 0000000..294df51 Binary files /dev/null and b/assets/audio/sfx/glitch_death.mp3 differ diff --git a/assets/audio/sfx/jet_boost.mp3 b/assets/audio/sfx/jet_boost.mp3 new file mode 100644 index 0000000..98e3990 Binary files /dev/null and b/assets/audio/sfx/jet_boost.mp3 differ diff --git a/assets/audio/sfx/land.mp3 b/assets/audio/sfx/land.mp3 new file mode 100644 index 0000000..ae8be57 Binary files /dev/null and b/assets/audio/sfx/land.mp3 differ diff --git a/assets/audio/sfx/laser.mp3 b/assets/audio/sfx/laser.mp3 new file mode 100644 index 0000000..80c21c8 Binary files /dev/null and b/assets/audio/sfx/laser.mp3 differ diff --git a/assets/audio/sfx/menu_button.mp3 b/assets/audio/sfx/menu_button.mp3 new file mode 100644 index 0000000..6a70fe3 Binary files /dev/null and b/assets/audio/sfx/menu_button.mp3 differ diff --git a/assets/audio/sfx/obstacle_death.mp3 b/assets/audio/sfx/obstacle_death.mp3 new file mode 100644 index 0000000..1d960dd Binary files /dev/null and b/assets/audio/sfx/obstacle_death.mp3 differ diff --git a/assets/audio/sfx/robot_friend_beep.mp3 b/assets/audio/sfx/robot_friend_beep.mp3 new file mode 100644 index 0000000..ebce8af Binary files /dev/null and b/assets/audio/sfx/robot_friend_beep.mp3 differ diff --git a/assets/audio/sfx/shield.mp3 b/assets/audio/sfx/shield.mp3 new file mode 100644 index 0000000..a2e943b Binary files /dev/null and b/assets/audio/sfx/shield.mp3 differ diff --git a/assets/fonts/Codystar-Light.ttf b/assets/fonts/Codystar-Light.ttf new file mode 100644 index 0000000..4266df9 Binary files /dev/null and b/assets/fonts/Codystar-Light.ttf differ diff --git a/assets/fonts/Codystar-Regular.ttf b/assets/fonts/Codystar-Regular.ttf new file mode 100644 index 0000000..cb4a382 Binary files /dev/null and b/assets/fonts/Codystar-Regular.ttf differ diff --git a/assets/fonts/OFL.txt b/assets/fonts/OFL.txt new file mode 100644 index 0000000..e4c734f --- /dev/null +++ b/assets/fonts/OFL.txt @@ -0,0 +1,94 @@ +Copyright (c) 2012, Font Diner (www.fontdiner.com), +with Reserved Font Name "Codystar". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/assets/icon/head-logo.png b/assets/icon/head-logo.png new file mode 100644 index 0000000..1b6b6f4 Binary files /dev/null and b/assets/icon/head-logo.png differ diff --git a/assets/images/bg-city-shadow.png b/assets/images/bg-city-shadow.png new file mode 100644 index 0000000..e87d94b Binary files /dev/null and b/assets/images/bg-city-shadow.png differ diff --git a/assets/images/bg.png b/assets/images/bg.png index 25cea32..31e06b7 100644 Binary files a/assets/images/bg.png and b/assets/images/bg.png differ diff --git a/assets/images/bug.png b/assets/images/bug.png deleted file mode 100644 index e1b091a..0000000 Binary files a/assets/images/bug.png and /dev/null differ diff --git a/assets/images/bug/bug_0.png b/assets/images/bug/bug_0.png new file mode 100644 index 0000000..6b89f29 Binary files /dev/null and b/assets/images/bug/bug_0.png differ diff --git a/assets/images/bug/bug_1.png b/assets/images/bug/bug_1.png new file mode 100644 index 0000000..6b89f29 Binary files /dev/null and b/assets/images/bug/bug_1.png differ diff --git a/assets/images/bug/bug_2.png b/assets/images/bug/bug_2.png new file mode 100644 index 0000000..6b89f29 Binary files /dev/null and b/assets/images/bug/bug_2.png differ diff --git a/assets/images/bug/bug_3.png b/assets/images/bug/bug_3.png new file mode 100644 index 0000000..8c9f255 Binary files /dev/null and b/assets/images/bug/bug_3.png differ diff --git a/assets/images/bug/bug_4.png b/assets/images/bug/bug_4.png new file mode 100644 index 0000000..51a8669 Binary files /dev/null and b/assets/images/bug/bug_4.png differ diff --git a/assets/images/bug/bug_5.png b/assets/images/bug/bug_5.png new file mode 100644 index 0000000..b2c8d00 Binary files /dev/null and b/assets/images/bug/bug_5.png differ diff --git a/assets/images/bug/bug_6.png b/assets/images/bug/bug_6.png new file mode 100644 index 0000000..ce0015f Binary files /dev/null and b/assets/images/bug/bug_6.png differ diff --git a/assets/images/bug/bug_7.png b/assets/images/bug/bug_7.png new file mode 100644 index 0000000..b09da05 Binary files /dev/null and b/assets/images/bug/bug_7.png differ diff --git a/assets/images/bug/bug_break_0.png b/assets/images/bug/bug_break_0.png new file mode 100644 index 0000000..9db7097 Binary files /dev/null and b/assets/images/bug/bug_break_0.png differ diff --git a/assets/images/bug/bug_break_1.png b/assets/images/bug/bug_break_1.png new file mode 100644 index 0000000..9db7097 Binary files /dev/null and b/assets/images/bug/bug_break_1.png differ diff --git a/assets/images/bug/bug_break_10.png b/assets/images/bug/bug_break_10.png new file mode 100644 index 0000000..3538109 Binary files /dev/null and b/assets/images/bug/bug_break_10.png differ diff --git a/assets/images/bug/bug_break_11.png b/assets/images/bug/bug_break_11.png new file mode 100644 index 0000000..ff70b10 Binary files /dev/null and b/assets/images/bug/bug_break_11.png differ diff --git a/assets/images/bug/bug_break_12.png b/assets/images/bug/bug_break_12.png new file mode 100644 index 0000000..c431cac Binary files /dev/null and b/assets/images/bug/bug_break_12.png differ diff --git a/assets/images/bug/bug_break_2.png b/assets/images/bug/bug_break_2.png new file mode 100644 index 0000000..9db7097 Binary files /dev/null and b/assets/images/bug/bug_break_2.png differ diff --git a/assets/images/bug/bug_break_3.png b/assets/images/bug/bug_break_3.png new file mode 100644 index 0000000..634653d Binary files /dev/null and b/assets/images/bug/bug_break_3.png differ diff --git a/assets/images/bug/bug_break_4.png b/assets/images/bug/bug_break_4.png new file mode 100644 index 0000000..cc1428d Binary files /dev/null and b/assets/images/bug/bug_break_4.png differ diff --git a/assets/images/bug/bug_break_5.png b/assets/images/bug/bug_break_5.png new file mode 100644 index 0000000..36d1017 Binary files /dev/null and b/assets/images/bug/bug_break_5.png differ diff --git a/assets/images/bug/bug_break_6.png b/assets/images/bug/bug_break_6.png new file mode 100644 index 0000000..0849c33 Binary files /dev/null and b/assets/images/bug/bug_break_6.png differ diff --git a/assets/images/bug/bug_break_7.png b/assets/images/bug/bug_break_7.png new file mode 100644 index 0000000..41d9d33 Binary files /dev/null and b/assets/images/bug/bug_break_7.png differ diff --git a/assets/images/bug/bug_break_8.png b/assets/images/bug/bug_break_8.png new file mode 100644 index 0000000..9fc4c7d Binary files /dev/null and b/assets/images/bug/bug_break_8.png differ diff --git a/assets/images/bug/bug_break_9.png b/assets/images/bug/bug_break_9.png new file mode 100644 index 0000000..cdadca3 Binary files /dev/null and b/assets/images/bug/bug_break_9.png differ diff --git a/assets/images/button-new.png b/assets/images/button-new.png new file mode 100644 index 0000000..bf1ff23 Binary files /dev/null and b/assets/images/button-new.png differ diff --git a/assets/images/button.png b/assets/images/button.png new file mode 100644 index 0000000..3de2a6b Binary files /dev/null and b/assets/images/button.png differ diff --git a/assets/images/coin.png b/assets/images/coin.png deleted file mode 100644 index a247944..0000000 Binary files a/assets/images/coin.png and /dev/null differ diff --git a/assets/images/coin/coin_0.png b/assets/images/coin/coin_0.png new file mode 100644 index 0000000..01bf97f Binary files /dev/null and b/assets/images/coin/coin_0.png differ diff --git a/assets/images/coin/coin_1.png b/assets/images/coin/coin_1.png new file mode 100644 index 0000000..5b82ced Binary files /dev/null and b/assets/images/coin/coin_1.png differ diff --git a/assets/images/coin/coin_10.png b/assets/images/coin/coin_10.png new file mode 100644 index 0000000..c2cfc70 Binary files /dev/null and b/assets/images/coin/coin_10.png differ diff --git a/assets/images/coin/coin_11.png b/assets/images/coin/coin_11.png new file mode 100644 index 0000000..12cfc80 Binary files /dev/null and b/assets/images/coin/coin_11.png differ diff --git a/assets/images/coin/coin_2.png b/assets/images/coin/coin_2.png new file mode 100644 index 0000000..a68d077 Binary files /dev/null and b/assets/images/coin/coin_2.png differ diff --git a/assets/images/coin/coin_3.png b/assets/images/coin/coin_3.png new file mode 100644 index 0000000..7b55dff Binary files /dev/null and b/assets/images/coin/coin_3.png differ diff --git a/assets/images/coin/coin_4.png b/assets/images/coin/coin_4.png new file mode 100644 index 0000000..0abb6b8 Binary files /dev/null and b/assets/images/coin/coin_4.png differ diff --git a/assets/images/coin/coin_5.png b/assets/images/coin/coin_5.png new file mode 100644 index 0000000..180feb4 Binary files /dev/null and b/assets/images/coin/coin_5.png differ diff --git a/assets/images/coin/coin_6.png b/assets/images/coin/coin_6.png new file mode 100644 index 0000000..73f0d11 Binary files /dev/null and b/assets/images/coin/coin_6.png differ diff --git a/assets/images/coin/coin_7.png b/assets/images/coin/coin_7.png new file mode 100644 index 0000000..61f9361 Binary files /dev/null and b/assets/images/coin/coin_7.png differ diff --git a/assets/images/coin/coin_8.png b/assets/images/coin/coin_8.png new file mode 100644 index 0000000..a7eab18 Binary files /dev/null and b/assets/images/coin/coin_8.png differ diff --git a/assets/images/coin/coin_9.png b/assets/images/coin/coin_9.png new file mode 100644 index 0000000..f26997e Binary files /dev/null and b/assets/images/coin/coin_9.png differ diff --git a/assets/images/debris/debris_0.png b/assets/images/debris/debris_0.png new file mode 100644 index 0000000..8c0b1da Binary files /dev/null and b/assets/images/debris/debris_0.png differ diff --git a/assets/images/debris/debris_1.png b/assets/images/debris/debris_1.png new file mode 100644 index 0000000..ee706c0 Binary files /dev/null and b/assets/images/debris/debris_1.png differ diff --git a/assets/images/debris/debris_10.png b/assets/images/debris/debris_10.png new file mode 100644 index 0000000..d96e54a Binary files /dev/null and b/assets/images/debris/debris_10.png differ diff --git a/assets/images/debris/debris_11.png b/assets/images/debris/debris_11.png new file mode 100644 index 0000000..ea4e1de Binary files /dev/null and b/assets/images/debris/debris_11.png differ diff --git a/assets/images/debris/debris_12.png b/assets/images/debris/debris_12.png new file mode 100644 index 0000000..02ab069 Binary files /dev/null and b/assets/images/debris/debris_12.png differ diff --git a/assets/images/debris/debris_13.png b/assets/images/debris/debris_13.png new file mode 100644 index 0000000..d57762a Binary files /dev/null and b/assets/images/debris/debris_13.png differ diff --git a/assets/images/debris/debris_14.png b/assets/images/debris/debris_14.png new file mode 100644 index 0000000..798103f Binary files /dev/null and b/assets/images/debris/debris_14.png differ diff --git a/assets/images/debris/debris_15.png b/assets/images/debris/debris_15.png new file mode 100644 index 0000000..886d609 Binary files /dev/null and b/assets/images/debris/debris_15.png differ diff --git a/assets/images/debris/debris_16.png b/assets/images/debris/debris_16.png new file mode 100644 index 0000000..7116035 Binary files /dev/null and b/assets/images/debris/debris_16.png differ diff --git a/assets/images/debris/debris_17.png b/assets/images/debris/debris_17.png new file mode 100644 index 0000000..8bc8de9 Binary files /dev/null and b/assets/images/debris/debris_17.png differ diff --git a/assets/images/debris/debris_18.png b/assets/images/debris/debris_18.png new file mode 100644 index 0000000..2e6dadd Binary files /dev/null and b/assets/images/debris/debris_18.png differ diff --git a/assets/images/debris/debris_19.png b/assets/images/debris/debris_19.png new file mode 100644 index 0000000..ee706c0 Binary files /dev/null and b/assets/images/debris/debris_19.png differ diff --git a/assets/images/debris/debris_2.png b/assets/images/debris/debris_2.png new file mode 100644 index 0000000..2e6dadd Binary files /dev/null and b/assets/images/debris/debris_2.png differ diff --git a/assets/images/debris/debris_20.png b/assets/images/debris/debris_20.png new file mode 100644 index 0000000..8c0b1da Binary files /dev/null and b/assets/images/debris/debris_20.png differ diff --git a/assets/images/debris/debris_3.png b/assets/images/debris/debris_3.png new file mode 100644 index 0000000..8bc8de9 Binary files /dev/null and b/assets/images/debris/debris_3.png differ diff --git a/assets/images/debris/debris_4.png b/assets/images/debris/debris_4.png new file mode 100644 index 0000000..7116035 Binary files /dev/null and b/assets/images/debris/debris_4.png differ diff --git a/assets/images/debris/debris_5.png b/assets/images/debris/debris_5.png new file mode 100644 index 0000000..886d609 Binary files /dev/null and b/assets/images/debris/debris_5.png differ diff --git a/assets/images/debris/debris_6.png b/assets/images/debris/debris_6.png new file mode 100644 index 0000000..798103f Binary files /dev/null and b/assets/images/debris/debris_6.png differ diff --git a/assets/images/debris/debris_7.png b/assets/images/debris/debris_7.png new file mode 100644 index 0000000..d57762a Binary files /dev/null and b/assets/images/debris/debris_7.png differ diff --git a/assets/images/debris/debris_8.png b/assets/images/debris/debris_8.png new file mode 100644 index 0000000..02ab069 Binary files /dev/null and b/assets/images/debris/debris_8.png differ diff --git a/assets/images/debris/debris_9.png b/assets/images/debris/debris_9.png new file mode 100644 index 0000000..ea4e1de Binary files /dev/null and b/assets/images/debris/debris_9.png differ diff --git a/assets/images/firework/firework_0.png b/assets/images/firework/firework_0.png new file mode 100644 index 0000000..bb88dcc Binary files /dev/null and b/assets/images/firework/firework_0.png differ diff --git a/assets/images/firework/firework_1.png b/assets/images/firework/firework_1.png new file mode 100644 index 0000000..8739fcf Binary files /dev/null and b/assets/images/firework/firework_1.png differ diff --git a/assets/images/firework/firework_2.png b/assets/images/firework/firework_2.png new file mode 100644 index 0000000..aebb234 Binary files /dev/null and b/assets/images/firework/firework_2.png differ diff --git a/assets/images/firework/firework_3.png b/assets/images/firework/firework_3.png new file mode 100644 index 0000000..d2c9380 Binary files /dev/null and b/assets/images/firework/firework_3.png differ diff --git a/assets/images/firework/firework_4.png b/assets/images/firework/firework_4.png new file mode 100644 index 0000000..609fa1d Binary files /dev/null and b/assets/images/firework/firework_4.png differ diff --git a/assets/images/firework/firework_5.png b/assets/images/firework/firework_5.png new file mode 100644 index 0000000..694c1fe Binary files /dev/null and b/assets/images/firework/firework_5.png differ diff --git a/assets/images/firework/firework_6.png b/assets/images/firework/firework_6.png new file mode 100644 index 0000000..a0c9391 Binary files /dev/null and b/assets/images/firework/firework_6.png differ diff --git a/assets/images/firework/firework_7.png b/assets/images/firework/firework_7.png new file mode 100644 index 0000000..76aeaa4 Binary files /dev/null and b/assets/images/firework/firework_7.png differ diff --git a/assets/images/firework/firework_8.png b/assets/images/firework/firework_8.png new file mode 100644 index 0000000..da58695 Binary files /dev/null and b/assets/images/firework/firework_8.png differ diff --git a/assets/images/firework/firework_9.png b/assets/images/firework/firework_9.png new file mode 100644 index 0000000..f6d476d Binary files /dev/null and b/assets/images/firework/firework_9.png differ diff --git a/assets/images/mm3.gif b/assets/images/mm3.gif new file mode 100644 index 0000000..efee561 Binary files /dev/null and b/assets/images/mm3.gif differ diff --git a/assets/images/overlay100.png b/assets/images/overlay100.png new file mode 100644 index 0000000..30af602 Binary files /dev/null and b/assets/images/overlay100.png differ diff --git a/assets/images/overlay40.png b/assets/images/overlay40.png new file mode 100644 index 0000000..5b8ad93 Binary files /dev/null and b/assets/images/overlay40.png differ diff --git a/assets/images/overlay50.png b/assets/images/overlay50.png new file mode 100644 index 0000000..243d327 Binary files /dev/null and b/assets/images/overlay50.png differ diff --git a/assets/images/overlay60.png b/assets/images/overlay60.png new file mode 100644 index 0000000..e59df0c Binary files /dev/null and b/assets/images/overlay60.png differ diff --git a/assets/images/overlay70.png b/assets/images/overlay70.png new file mode 100644 index 0000000..fcdd3c1 Binary files /dev/null and b/assets/images/overlay70.png differ diff --git a/assets/images/overlay80.png b/assets/images/overlay80.png new file mode 100644 index 0000000..eaf3f54 Binary files /dev/null and b/assets/images/overlay80.png differ diff --git a/assets/images/overlay90.png b/assets/images/overlay90.png new file mode 100644 index 0000000..426be2a Binary files /dev/null and b/assets/images/overlay90.png differ diff --git a/assets/images/platform/platform-left-nowire-frames_0.png b/assets/images/platform/platform-left-nowire-frames_0.png new file mode 100644 index 0000000..163712c Binary files /dev/null and b/assets/images/platform/platform-left-nowire-frames_0.png differ diff --git a/assets/images/platform/platform-left-nowire-frames_1.png b/assets/images/platform/platform-left-nowire-frames_1.png new file mode 100644 index 0000000..cb57c00 Binary files /dev/null and b/assets/images/platform/platform-left-nowire-frames_1.png differ diff --git a/assets/images/platform/platform-left-nowire-frames_2.png b/assets/images/platform/platform-left-nowire-frames_2.png new file mode 100644 index 0000000..c215160 Binary files /dev/null and b/assets/images/platform/platform-left-nowire-frames_2.png differ diff --git a/assets/images/platform/platform-left-nowire-frames_3.png b/assets/images/platform/platform-left-nowire-frames_3.png new file mode 100644 index 0000000..d0f7ad2 Binary files /dev/null and b/assets/images/platform/platform-left-nowire-frames_3.png differ diff --git a/assets/images/platform/platform-left-nowire-frames_4.png b/assets/images/platform/platform-left-nowire-frames_4.png new file mode 100644 index 0000000..62343d6 Binary files /dev/null and b/assets/images/platform/platform-left-nowire-frames_4.png differ diff --git a/assets/images/platform/platform-left-wire-frames_0.png b/assets/images/platform/platform-left-wire-frames_0.png new file mode 100644 index 0000000..f72c734 Binary files /dev/null and b/assets/images/platform/platform-left-wire-frames_0.png differ diff --git a/assets/images/platform/platform-left-wire-frames_1.png b/assets/images/platform/platform-left-wire-frames_1.png new file mode 100644 index 0000000..bc2667d Binary files /dev/null and b/assets/images/platform/platform-left-wire-frames_1.png differ diff --git a/assets/images/platform/platform-left-wire-frames_2.png b/assets/images/platform/platform-left-wire-frames_2.png new file mode 100644 index 0000000..6b0b90d Binary files /dev/null and b/assets/images/platform/platform-left-wire-frames_2.png differ diff --git a/assets/images/platform/platform-left-wire-frames_3.png b/assets/images/platform/platform-left-wire-frames_3.png new file mode 100644 index 0000000..5726609 Binary files /dev/null and b/assets/images/platform/platform-left-wire-frames_3.png differ diff --git a/assets/images/platform/platform-left-wire-frames_4.png b/assets/images/platform/platform-left-wire-frames_4.png new file mode 100644 index 0000000..b7df846 Binary files /dev/null and b/assets/images/platform/platform-left-wire-frames_4.png differ diff --git a/assets/images/platform/platform-mid-nowire-frames_0.png b/assets/images/platform/platform-mid-nowire-frames_0.png new file mode 100644 index 0000000..579c077 Binary files /dev/null and b/assets/images/platform/platform-mid-nowire-frames_0.png differ diff --git a/assets/images/platform/platform-mid-nowire-frames_1.png b/assets/images/platform/platform-mid-nowire-frames_1.png new file mode 100644 index 0000000..68679df Binary files /dev/null and b/assets/images/platform/platform-mid-nowire-frames_1.png differ diff --git a/assets/images/platform/platform-mid-nowire-frames_2.png b/assets/images/platform/platform-mid-nowire-frames_2.png new file mode 100644 index 0000000..1be06a8 Binary files /dev/null and b/assets/images/platform/platform-mid-nowire-frames_2.png differ diff --git a/assets/images/platform/platform-mid-nowire-frames_3.png b/assets/images/platform/platform-mid-nowire-frames_3.png new file mode 100644 index 0000000..352f85b Binary files /dev/null and b/assets/images/platform/platform-mid-nowire-frames_3.png differ diff --git a/assets/images/platform/platform-mid-nowire-frames_4.png b/assets/images/platform/platform-mid-nowire-frames_4.png new file mode 100644 index 0000000..3bd6fa1 Binary files /dev/null and b/assets/images/platform/platform-mid-nowire-frames_4.png differ diff --git a/assets/images/platform/platform-mid-wire-frames_0.png b/assets/images/platform/platform-mid-wire-frames_0.png new file mode 100644 index 0000000..7803ed3 Binary files /dev/null and b/assets/images/platform/platform-mid-wire-frames_0.png differ diff --git a/assets/images/platform/platform-mid-wire-frames_1.png b/assets/images/platform/platform-mid-wire-frames_1.png new file mode 100644 index 0000000..54b6abb Binary files /dev/null and b/assets/images/platform/platform-mid-wire-frames_1.png differ diff --git a/assets/images/platform/platform-mid-wire-frames_2.png b/assets/images/platform/platform-mid-wire-frames_2.png new file mode 100644 index 0000000..164ff62 Binary files /dev/null and b/assets/images/platform/platform-mid-wire-frames_2.png differ diff --git a/assets/images/platform/platform-mid-wire-frames_3.png b/assets/images/platform/platform-mid-wire-frames_3.png new file mode 100644 index 0000000..fdf3eff Binary files /dev/null and b/assets/images/platform/platform-mid-wire-frames_3.png differ diff --git a/assets/images/platform/platform-mid-wire-frames_4.png b/assets/images/platform/platform-mid-wire-frames_4.png new file mode 100644 index 0000000..44a34c7 Binary files /dev/null and b/assets/images/platform/platform-mid-wire-frames_4.png differ diff --git a/assets/images/platform/platform-right-nowire-frames_0.png b/assets/images/platform/platform-right-nowire-frames_0.png new file mode 100644 index 0000000..f7ac271 Binary files /dev/null and b/assets/images/platform/platform-right-nowire-frames_0.png differ diff --git a/assets/images/platform/platform-right-nowire-frames_1.png b/assets/images/platform/platform-right-nowire-frames_1.png new file mode 100644 index 0000000..84aef7a Binary files /dev/null and b/assets/images/platform/platform-right-nowire-frames_1.png differ diff --git a/assets/images/platform/platform-right-nowire-frames_2.png b/assets/images/platform/platform-right-nowire-frames_2.png new file mode 100644 index 0000000..174f360 Binary files /dev/null and b/assets/images/platform/platform-right-nowire-frames_2.png differ diff --git a/assets/images/platform/platform-right-nowire-frames_3.png b/assets/images/platform/platform-right-nowire-frames_3.png new file mode 100644 index 0000000..68ab27c Binary files /dev/null and b/assets/images/platform/platform-right-nowire-frames_3.png differ diff --git a/assets/images/platform/platform-right-nowire-frames_4.png b/assets/images/platform/platform-right-nowire-frames_4.png new file mode 100644 index 0000000..d2c39a8 Binary files /dev/null and b/assets/images/platform/platform-right-nowire-frames_4.png differ diff --git a/assets/images/platform/platform-right-wire-frames_0.png b/assets/images/platform/platform-right-wire-frames_0.png new file mode 100644 index 0000000..5071874 Binary files /dev/null and b/assets/images/platform/platform-right-wire-frames_0.png differ diff --git a/assets/images/platform/platform-right-wire-frames_1.png b/assets/images/platform/platform-right-wire-frames_1.png new file mode 100644 index 0000000..7849c35 Binary files /dev/null and b/assets/images/platform/platform-right-wire-frames_1.png differ diff --git a/assets/images/platform/platform-right-wire-frames_2.png b/assets/images/platform/platform-right-wire-frames_2.png new file mode 100644 index 0000000..d935324 Binary files /dev/null and b/assets/images/platform/platform-right-wire-frames_2.png differ diff --git a/assets/images/platform/platform-right-wire-frames_3.png b/assets/images/platform/platform-right-wire-frames_3.png new file mode 100644 index 0000000..f58a9d3 Binary files /dev/null and b/assets/images/platform/platform-right-wire-frames_3.png differ diff --git a/assets/images/platform/platform-right-wire-frames_4.png b/assets/images/platform/platform-right-wire-frames_4.png new file mode 100644 index 0000000..2983c7e Binary files /dev/null and b/assets/images/platform/platform-right-wire-frames_4.png differ diff --git a/assets/images/platform/platform-single-nowire-frames_0.png b/assets/images/platform/platform-single-nowire-frames_0.png new file mode 100644 index 0000000..ff0f4f3 Binary files /dev/null and b/assets/images/platform/platform-single-nowire-frames_0.png differ diff --git a/assets/images/platform/platform-single-nowire-frames_1.png b/assets/images/platform/platform-single-nowire-frames_1.png new file mode 100644 index 0000000..c18e358 Binary files /dev/null and b/assets/images/platform/platform-single-nowire-frames_1.png differ diff --git a/assets/images/platform/platform-single-nowire-frames_2.png b/assets/images/platform/platform-single-nowire-frames_2.png new file mode 100644 index 0000000..c93694b Binary files /dev/null and b/assets/images/platform/platform-single-nowire-frames_2.png differ diff --git a/assets/images/platform/platform-single-nowire-frames_3.png b/assets/images/platform/platform-single-nowire-frames_3.png new file mode 100644 index 0000000..f58a4b5 Binary files /dev/null and b/assets/images/platform/platform-single-nowire-frames_3.png differ diff --git a/assets/images/platform/platform-single-nowire-frames_4.png b/assets/images/platform/platform-single-nowire-frames_4.png new file mode 100644 index 0000000..0170ffd Binary files /dev/null and b/assets/images/platform/platform-single-nowire-frames_4.png differ diff --git a/assets/images/platform/platform-single-wire-frames_0.png b/assets/images/platform/platform-single-wire-frames_0.png new file mode 100644 index 0000000..b2e8c63 Binary files /dev/null and b/assets/images/platform/platform-single-wire-frames_0.png differ diff --git a/assets/images/platform/platform-single-wire-frames_1.png b/assets/images/platform/platform-single-wire-frames_1.png new file mode 100644 index 0000000..3d60943 Binary files /dev/null and b/assets/images/platform/platform-single-wire-frames_1.png differ diff --git a/assets/images/platform/platform-single-wire-frames_2.png b/assets/images/platform/platform-single-wire-frames_2.png new file mode 100644 index 0000000..36972dc Binary files /dev/null and b/assets/images/platform/platform-single-wire-frames_2.png differ diff --git a/assets/images/platform/platform-single-wire-frames_3.png b/assets/images/platform/platform-single-wire-frames_3.png new file mode 100644 index 0000000..27dce00 Binary files /dev/null and b/assets/images/platform/platform-single-wire-frames_3.png differ diff --git a/assets/images/platform/platform-single-wire-frames_4.png b/assets/images/platform/platform-single-wire-frames_4.png new file mode 100644 index 0000000..68280ac Binary files /dev/null and b/assets/images/platform/platform-single-wire-frames_4.png differ diff --git a/assets/images/platform1.png b/assets/images/platform1.png deleted file mode 100644 index 04853c9..0000000 Binary files a/assets/images/platform1.png and /dev/null differ diff --git a/assets/images/platform2.png b/assets/images/platform2.png deleted file mode 100644 index ea6b3a4..0000000 Binary files a/assets/images/platform2.png and /dev/null differ diff --git a/assets/images/platform3.png b/assets/images/platform3.png deleted file mode 100644 index a30d4cf..0000000 Binary files a/assets/images/platform3.png and /dev/null differ diff --git a/assets/images/run-frames.png b/assets/images/run-frames.png deleted file mode 100644 index e049169..0000000 Binary files a/assets/images/run-frames.png and /dev/null differ diff --git a/assets/images/runner/attack1/attack10001.png b/assets/images/runner/attack1/attack10001.png new file mode 100644 index 0000000..87c8aee Binary files /dev/null and b/assets/images/runner/attack1/attack10001.png differ diff --git a/assets/images/runner/attack1/attack10002.png b/assets/images/runner/attack1/attack10002.png new file mode 100644 index 0000000..c9080c4 Binary files /dev/null and b/assets/images/runner/attack1/attack10002.png differ diff --git a/assets/images/runner/attack1/attack10003.png b/assets/images/runner/attack1/attack10003.png new file mode 100644 index 0000000..61d8475 Binary files /dev/null and b/assets/images/runner/attack1/attack10003.png differ diff --git a/assets/images/runner/attack1/attack10004.png b/assets/images/runner/attack1/attack10004.png new file mode 100644 index 0000000..e28539f Binary files /dev/null and b/assets/images/runner/attack1/attack10004.png differ diff --git a/assets/images/runner/attack1/attack10005.png b/assets/images/runner/attack1/attack10005.png new file mode 100644 index 0000000..326a45e Binary files /dev/null and b/assets/images/runner/attack1/attack10005.png differ diff --git a/assets/images/runner/attack1/attack10006.png b/assets/images/runner/attack1/attack10006.png new file mode 100644 index 0000000..871f9b5 Binary files /dev/null and b/assets/images/runner/attack1/attack10006.png differ diff --git a/assets/images/runner/attack1/attack10007.png b/assets/images/runner/attack1/attack10007.png new file mode 100644 index 0000000..daa2f4f Binary files /dev/null and b/assets/images/runner/attack1/attack10007.png differ diff --git a/assets/images/runner/attack1/attack10008.png b/assets/images/runner/attack1/attack10008.png new file mode 100644 index 0000000..7f80be6 Binary files /dev/null and b/assets/images/runner/attack1/attack10008.png differ diff --git a/assets/images/runner/attack1/attack10009.png b/assets/images/runner/attack1/attack10009.png new file mode 100644 index 0000000..d2c195c Binary files /dev/null and b/assets/images/runner/attack1/attack10009.png differ diff --git a/assets/images/runner/attack1/attack10010.png b/assets/images/runner/attack1/attack10010.png new file mode 100644 index 0000000..1f8af4b Binary files /dev/null and b/assets/images/runner/attack1/attack10010.png differ diff --git a/assets/images/runner/attack1/attack10011.png b/assets/images/runner/attack1/attack10011.png new file mode 100644 index 0000000..6c56cbd Binary files /dev/null and b/assets/images/runner/attack1/attack10011.png differ diff --git a/assets/images/runner/attack1/attack10012.png b/assets/images/runner/attack1/attack10012.png new file mode 100644 index 0000000..d0617bb Binary files /dev/null and b/assets/images/runner/attack1/attack10012.png differ diff --git a/assets/images/runner/attack1/attack10013.png b/assets/images/runner/attack1/attack10013.png new file mode 100644 index 0000000..0124a6d Binary files /dev/null and b/assets/images/runner/attack1/attack10013.png differ diff --git a/assets/images/runner/attack1/attack10014.png b/assets/images/runner/attack1/attack10014.png new file mode 100644 index 0000000..f92b0d9 Binary files /dev/null and b/assets/images/runner/attack1/attack10014.png differ diff --git a/assets/images/runner/attack1/attack10015.png b/assets/images/runner/attack1/attack10015.png new file mode 100644 index 0000000..8a0fd00 Binary files /dev/null and b/assets/images/runner/attack1/attack10015.png differ diff --git a/assets/images/runner/attack1/attack10016.png b/assets/images/runner/attack1/attack10016.png new file mode 100644 index 0000000..2478d27 Binary files /dev/null and b/assets/images/runner/attack1/attack10016.png differ diff --git a/assets/images/runner/attack1/attack10017.png b/assets/images/runner/attack1/attack10017.png new file mode 100644 index 0000000..8d7a27f Binary files /dev/null and b/assets/images/runner/attack1/attack10017.png differ diff --git a/assets/images/runner/attack1/attack10018.png b/assets/images/runner/attack1/attack10018.png new file mode 100644 index 0000000..0c27f55 Binary files /dev/null and b/assets/images/runner/attack1/attack10018.png differ diff --git a/assets/images/runner/attack1/attack10019.png b/assets/images/runner/attack1/attack10019.png new file mode 100644 index 0000000..dd06d54 Binary files /dev/null and b/assets/images/runner/attack1/attack10019.png differ diff --git a/assets/images/runner/attack1/attack10020.png b/assets/images/runner/attack1/attack10020.png new file mode 100644 index 0000000..4a6150c Binary files /dev/null and b/assets/images/runner/attack1/attack10020.png differ diff --git a/assets/images/runner/attack1/attack10021.png b/assets/images/runner/attack1/attack10021.png new file mode 100644 index 0000000..afc75e5 Binary files /dev/null and b/assets/images/runner/attack1/attack10021.png differ diff --git a/assets/images/runner/attack1/attack10022.png b/assets/images/runner/attack1/attack10022.png new file mode 100644 index 0000000..12c3f91 Binary files /dev/null and b/assets/images/runner/attack1/attack10022.png differ diff --git a/assets/images/runner/attack1/attack10023.png b/assets/images/runner/attack1/attack10023.png new file mode 100644 index 0000000..b42b0e1 Binary files /dev/null and b/assets/images/runner/attack1/attack10023.png differ diff --git a/assets/images/runner/attack1/attack10024.png b/assets/images/runner/attack1/attack10024.png new file mode 100644 index 0000000..bac415c Binary files /dev/null and b/assets/images/runner/attack1/attack10024.png differ diff --git a/assets/images/runner/attack1/attack10025.png b/assets/images/runner/attack1/attack10025.png new file mode 100644 index 0000000..d286340 Binary files /dev/null and b/assets/images/runner/attack1/attack10025.png differ diff --git a/assets/images/runner/attack1/attack10026.png b/assets/images/runner/attack1/attack10026.png new file mode 100644 index 0000000..0496ce0 Binary files /dev/null and b/assets/images/runner/attack1/attack10026.png differ diff --git a/assets/images/runner/attack1/attack10027.png b/assets/images/runner/attack1/attack10027.png new file mode 100644 index 0000000..a3d3e7b Binary files /dev/null and b/assets/images/runner/attack1/attack10027.png differ diff --git a/assets/images/runner/attack1/attack10028.png b/assets/images/runner/attack1/attack10028.png new file mode 100644 index 0000000..8a6b05b Binary files /dev/null and b/assets/images/runner/attack1/attack10028.png differ diff --git a/assets/images/runner/attack1/attack10029.png b/assets/images/runner/attack1/attack10029.png new file mode 100644 index 0000000..4e199de Binary files /dev/null and b/assets/images/runner/attack1/attack10029.png differ diff --git a/assets/images/runner/attack1/attack10030.png b/assets/images/runner/attack1/attack10030.png new file mode 100644 index 0000000..5828c23 Binary files /dev/null and b/assets/images/runner/attack1/attack10030.png differ diff --git a/assets/images/runner/attack1/attack10031.png b/assets/images/runner/attack1/attack10031.png new file mode 100644 index 0000000..68ef757 Binary files /dev/null and b/assets/images/runner/attack1/attack10031.png differ diff --git a/assets/images/runner/attack1/attack10032.png b/assets/images/runner/attack1/attack10032.png new file mode 100644 index 0000000..3b0b1ff Binary files /dev/null and b/assets/images/runner/attack1/attack10032.png differ diff --git a/assets/images/runner/attack1/attack10033.png b/assets/images/runner/attack1/attack10033.png new file mode 100644 index 0000000..37effae Binary files /dev/null and b/assets/images/runner/attack1/attack10033.png differ diff --git a/assets/images/runner/attack1/attack10034.png b/assets/images/runner/attack1/attack10034.png new file mode 100644 index 0000000..da72f20 Binary files /dev/null and b/assets/images/runner/attack1/attack10034.png differ diff --git a/assets/images/runner/attack1/attack10035.png b/assets/images/runner/attack1/attack10035.png new file mode 100644 index 0000000..04381bc Binary files /dev/null and b/assets/images/runner/attack1/attack10035.png differ diff --git a/assets/images/runner/attack1/attack10036.png b/assets/images/runner/attack1/attack10036.png new file mode 100644 index 0000000..27fbf26 Binary files /dev/null and b/assets/images/runner/attack1/attack10036.png differ diff --git a/assets/images/runner/attack1/attack10037.png b/assets/images/runner/attack1/attack10037.png new file mode 100644 index 0000000..3ed102d Binary files /dev/null and b/assets/images/runner/attack1/attack10037.png differ diff --git a/assets/images/runner/attack1/attack10038.png b/assets/images/runner/attack1/attack10038.png new file mode 100644 index 0000000..e5b6d73 Binary files /dev/null and b/assets/images/runner/attack1/attack10038.png differ diff --git a/assets/images/runner/attack2/attack20001.png b/assets/images/runner/attack2/attack20001.png new file mode 100644 index 0000000..87c8aee Binary files /dev/null and b/assets/images/runner/attack2/attack20001.png differ diff --git a/assets/images/runner/attack2/attack20002.png b/assets/images/runner/attack2/attack20002.png new file mode 100644 index 0000000..0cc729f Binary files /dev/null and b/assets/images/runner/attack2/attack20002.png differ diff --git a/assets/images/runner/attack2/attack20003.png b/assets/images/runner/attack2/attack20003.png new file mode 100644 index 0000000..5f64878 Binary files /dev/null and b/assets/images/runner/attack2/attack20003.png differ diff --git a/assets/images/runner/attack2/attack20004.png b/assets/images/runner/attack2/attack20004.png new file mode 100644 index 0000000..d262b30 Binary files /dev/null and b/assets/images/runner/attack2/attack20004.png differ diff --git a/assets/images/runner/attack2/attack20005.png b/assets/images/runner/attack2/attack20005.png new file mode 100644 index 0000000..e5fe124 Binary files /dev/null and b/assets/images/runner/attack2/attack20005.png differ diff --git a/assets/images/runner/attack2/attack20006.png b/assets/images/runner/attack2/attack20006.png new file mode 100644 index 0000000..fb4826b Binary files /dev/null and b/assets/images/runner/attack2/attack20006.png differ diff --git a/assets/images/runner/attack2/attack20007.png b/assets/images/runner/attack2/attack20007.png new file mode 100644 index 0000000..daa2f4f Binary files /dev/null and b/assets/images/runner/attack2/attack20007.png differ diff --git a/assets/images/runner/attack2/attack20008.png b/assets/images/runner/attack2/attack20008.png new file mode 100644 index 0000000..7f80be6 Binary files /dev/null and b/assets/images/runner/attack2/attack20008.png differ diff --git a/assets/images/runner/attack2/attack20009.png b/assets/images/runner/attack2/attack20009.png new file mode 100644 index 0000000..d2c195c Binary files /dev/null and b/assets/images/runner/attack2/attack20009.png differ diff --git a/assets/images/runner/attack2/attack20010.png b/assets/images/runner/attack2/attack20010.png new file mode 100644 index 0000000..1f8af4b Binary files /dev/null and b/assets/images/runner/attack2/attack20010.png differ diff --git a/assets/images/runner/attack2/attack20011.png b/assets/images/runner/attack2/attack20011.png new file mode 100644 index 0000000..6c56cbd Binary files /dev/null and b/assets/images/runner/attack2/attack20011.png differ diff --git a/assets/images/runner/attack2/attack20012.png b/assets/images/runner/attack2/attack20012.png new file mode 100644 index 0000000..d0617bb Binary files /dev/null and b/assets/images/runner/attack2/attack20012.png differ diff --git a/assets/images/runner/attack2/attack20013.png b/assets/images/runner/attack2/attack20013.png new file mode 100644 index 0000000..0124a6d Binary files /dev/null and b/assets/images/runner/attack2/attack20013.png differ diff --git a/assets/images/runner/attack2/attack20014.png b/assets/images/runner/attack2/attack20014.png new file mode 100644 index 0000000..f92b0d9 Binary files /dev/null and b/assets/images/runner/attack2/attack20014.png differ diff --git a/assets/images/runner/attack2/attack20015.png b/assets/images/runner/attack2/attack20015.png new file mode 100644 index 0000000..8a0fd00 Binary files /dev/null and b/assets/images/runner/attack2/attack20015.png differ diff --git a/assets/images/runner/attack2/attack20016.png b/assets/images/runner/attack2/attack20016.png new file mode 100644 index 0000000..2478d27 Binary files /dev/null and b/assets/images/runner/attack2/attack20016.png differ diff --git a/assets/images/runner/attack2/attack20017.png b/assets/images/runner/attack2/attack20017.png new file mode 100644 index 0000000..8d7a27f Binary files /dev/null and b/assets/images/runner/attack2/attack20017.png differ diff --git a/assets/images/runner/attack2/attack20018.png b/assets/images/runner/attack2/attack20018.png new file mode 100644 index 0000000..0c27f55 Binary files /dev/null and b/assets/images/runner/attack2/attack20018.png differ diff --git a/assets/images/runner/attack2/attack20019.png b/assets/images/runner/attack2/attack20019.png new file mode 100644 index 0000000..dd06d54 Binary files /dev/null and b/assets/images/runner/attack2/attack20019.png differ diff --git a/assets/images/runner/attack2/attack20020.png b/assets/images/runner/attack2/attack20020.png new file mode 100644 index 0000000..4a6150c Binary files /dev/null and b/assets/images/runner/attack2/attack20020.png differ diff --git a/assets/images/runner/attack2/attack20021.png b/assets/images/runner/attack2/attack20021.png new file mode 100644 index 0000000..afc75e5 Binary files /dev/null and b/assets/images/runner/attack2/attack20021.png differ diff --git a/assets/images/runner/attack2/attack20022.png b/assets/images/runner/attack2/attack20022.png new file mode 100644 index 0000000..12c3f91 Binary files /dev/null and b/assets/images/runner/attack2/attack20022.png differ diff --git a/assets/images/runner/attack2/attack20023.png b/assets/images/runner/attack2/attack20023.png new file mode 100644 index 0000000..b42b0e1 Binary files /dev/null and b/assets/images/runner/attack2/attack20023.png differ diff --git a/assets/images/runner/attack2/attack20024.png b/assets/images/runner/attack2/attack20024.png new file mode 100644 index 0000000..bac415c Binary files /dev/null and b/assets/images/runner/attack2/attack20024.png differ diff --git a/assets/images/runner/attack2/attack20025.png b/assets/images/runner/attack2/attack20025.png new file mode 100644 index 0000000..d286340 Binary files /dev/null and b/assets/images/runner/attack2/attack20025.png differ diff --git a/assets/images/runner/attack2/attack20026.png b/assets/images/runner/attack2/attack20026.png new file mode 100644 index 0000000..0496ce0 Binary files /dev/null and b/assets/images/runner/attack2/attack20026.png differ diff --git a/assets/images/runner/attack2/attack20027.png b/assets/images/runner/attack2/attack20027.png new file mode 100644 index 0000000..a3d3e7b Binary files /dev/null and b/assets/images/runner/attack2/attack20027.png differ diff --git a/assets/images/runner/attack2/attack20028.png b/assets/images/runner/attack2/attack20028.png new file mode 100644 index 0000000..8a6b05b Binary files /dev/null and b/assets/images/runner/attack2/attack20028.png differ diff --git a/assets/images/runner/attack2/attack20029.png b/assets/images/runner/attack2/attack20029.png new file mode 100644 index 0000000..4e199de Binary files /dev/null and b/assets/images/runner/attack2/attack20029.png differ diff --git a/assets/images/runner/attack2/attack20030.png b/assets/images/runner/attack2/attack20030.png new file mode 100644 index 0000000..5828c23 Binary files /dev/null and b/assets/images/runner/attack2/attack20030.png differ diff --git a/assets/images/runner/attack2/attack20031.png b/assets/images/runner/attack2/attack20031.png new file mode 100644 index 0000000..68ef757 Binary files /dev/null and b/assets/images/runner/attack2/attack20031.png differ diff --git a/assets/images/runner/attack2/attack20032.png b/assets/images/runner/attack2/attack20032.png new file mode 100644 index 0000000..3b0b1ff Binary files /dev/null and b/assets/images/runner/attack2/attack20032.png differ diff --git a/assets/images/runner/attack2/attack20033.png b/assets/images/runner/attack2/attack20033.png new file mode 100644 index 0000000..37effae Binary files /dev/null and b/assets/images/runner/attack2/attack20033.png differ diff --git a/assets/images/runner/attack2/attack20034.png b/assets/images/runner/attack2/attack20034.png new file mode 100644 index 0000000..da72f20 Binary files /dev/null and b/assets/images/runner/attack2/attack20034.png differ diff --git a/assets/images/runner/attack2/attack20035.png b/assets/images/runner/attack2/attack20035.png new file mode 100644 index 0000000..04381bc Binary files /dev/null and b/assets/images/runner/attack2/attack20035.png differ diff --git a/assets/images/runner/attack2/attack20036.png b/assets/images/runner/attack2/attack20036.png new file mode 100644 index 0000000..27fbf26 Binary files /dev/null and b/assets/images/runner/attack2/attack20036.png differ diff --git a/assets/images/runner/attack2/attack20037.png b/assets/images/runner/attack2/attack20037.png new file mode 100644 index 0000000..3ed102d Binary files /dev/null and b/assets/images/runner/attack2/attack20037.png differ diff --git a/assets/images/runner/attack2/attack20038.png b/assets/images/runner/attack2/attack20038.png new file mode 100644 index 0000000..e5b6d73 Binary files /dev/null and b/assets/images/runner/attack2/attack20038.png differ diff --git a/assets/images/runner/attack3/attack30001.png b/assets/images/runner/attack3/attack30001.png new file mode 100644 index 0000000..87c8aee Binary files /dev/null and b/assets/images/runner/attack3/attack30001.png differ diff --git a/assets/images/runner/attack3/attack30002.png b/assets/images/runner/attack3/attack30002.png new file mode 100644 index 0000000..45b2c70 Binary files /dev/null and b/assets/images/runner/attack3/attack30002.png differ diff --git a/assets/images/runner/attack3/attack30003.png b/assets/images/runner/attack3/attack30003.png new file mode 100644 index 0000000..ccdce50 Binary files /dev/null and b/assets/images/runner/attack3/attack30003.png differ diff --git a/assets/images/runner/attack3/attack30004.png b/assets/images/runner/attack3/attack30004.png new file mode 100644 index 0000000..9f2ad47 Binary files /dev/null and b/assets/images/runner/attack3/attack30004.png differ diff --git a/assets/images/runner/attack3/attack30005.png b/assets/images/runner/attack3/attack30005.png new file mode 100644 index 0000000..6d94e7f Binary files /dev/null and b/assets/images/runner/attack3/attack30005.png differ diff --git a/assets/images/runner/attack3/attack30006.png b/assets/images/runner/attack3/attack30006.png new file mode 100644 index 0000000..ca06aa7 Binary files /dev/null and b/assets/images/runner/attack3/attack30006.png differ diff --git a/assets/images/runner/attack3/attack30007.png b/assets/images/runner/attack3/attack30007.png new file mode 100644 index 0000000..5a1e0f9 Binary files /dev/null and b/assets/images/runner/attack3/attack30007.png differ diff --git a/assets/images/runner/attack3/attack30008.png b/assets/images/runner/attack3/attack30008.png new file mode 100644 index 0000000..e8bc4f9 Binary files /dev/null and b/assets/images/runner/attack3/attack30008.png differ diff --git a/assets/images/runner/attack3/attack30009.png b/assets/images/runner/attack3/attack30009.png new file mode 100644 index 0000000..d2c195c Binary files /dev/null and b/assets/images/runner/attack3/attack30009.png differ diff --git a/assets/images/runner/attack3/attack30010.png b/assets/images/runner/attack3/attack30010.png new file mode 100644 index 0000000..1f8af4b Binary files /dev/null and b/assets/images/runner/attack3/attack30010.png differ diff --git a/assets/images/runner/attack3/attack30011.png b/assets/images/runner/attack3/attack30011.png new file mode 100644 index 0000000..6c56cbd Binary files /dev/null and b/assets/images/runner/attack3/attack30011.png differ diff --git a/assets/images/runner/attack3/attack30012.png b/assets/images/runner/attack3/attack30012.png new file mode 100644 index 0000000..d0617bb Binary files /dev/null and b/assets/images/runner/attack3/attack30012.png differ diff --git a/assets/images/runner/attack3/attack30013.png b/assets/images/runner/attack3/attack30013.png new file mode 100644 index 0000000..0124a6d Binary files /dev/null and b/assets/images/runner/attack3/attack30013.png differ diff --git a/assets/images/runner/attack3/attack30014.png b/assets/images/runner/attack3/attack30014.png new file mode 100644 index 0000000..f92b0d9 Binary files /dev/null and b/assets/images/runner/attack3/attack30014.png differ diff --git a/assets/images/runner/attack3/attack30015.png b/assets/images/runner/attack3/attack30015.png new file mode 100644 index 0000000..8a0fd00 Binary files /dev/null and b/assets/images/runner/attack3/attack30015.png differ diff --git a/assets/images/runner/attack3/attack30016.png b/assets/images/runner/attack3/attack30016.png new file mode 100644 index 0000000..2478d27 Binary files /dev/null and b/assets/images/runner/attack3/attack30016.png differ diff --git a/assets/images/runner/attack3/attack30017.png b/assets/images/runner/attack3/attack30017.png new file mode 100644 index 0000000..8d7a27f Binary files /dev/null and b/assets/images/runner/attack3/attack30017.png differ diff --git a/assets/images/runner/attack3/attack30018.png b/assets/images/runner/attack3/attack30018.png new file mode 100644 index 0000000..0c27f55 Binary files /dev/null and b/assets/images/runner/attack3/attack30018.png differ diff --git a/assets/images/runner/attack3/attack30019.png b/assets/images/runner/attack3/attack30019.png new file mode 100644 index 0000000..dd06d54 Binary files /dev/null and b/assets/images/runner/attack3/attack30019.png differ diff --git a/assets/images/runner/attack3/attack30020.png b/assets/images/runner/attack3/attack30020.png new file mode 100644 index 0000000..4a6150c Binary files /dev/null and b/assets/images/runner/attack3/attack30020.png differ diff --git a/assets/images/runner/attack3/attack30021.png b/assets/images/runner/attack3/attack30021.png new file mode 100644 index 0000000..afc75e5 Binary files /dev/null and b/assets/images/runner/attack3/attack30021.png differ diff --git a/assets/images/runner/attack3/attack30022.png b/assets/images/runner/attack3/attack30022.png new file mode 100644 index 0000000..12c3f91 Binary files /dev/null and b/assets/images/runner/attack3/attack30022.png differ diff --git a/assets/images/runner/attack3/attack30023.png b/assets/images/runner/attack3/attack30023.png new file mode 100644 index 0000000..b42b0e1 Binary files /dev/null and b/assets/images/runner/attack3/attack30023.png differ diff --git a/assets/images/runner/attack3/attack30024.png b/assets/images/runner/attack3/attack30024.png new file mode 100644 index 0000000..bac415c Binary files /dev/null and b/assets/images/runner/attack3/attack30024.png differ diff --git a/assets/images/runner/attack3/attack30025.png b/assets/images/runner/attack3/attack30025.png new file mode 100644 index 0000000..d286340 Binary files /dev/null and b/assets/images/runner/attack3/attack30025.png differ diff --git a/assets/images/runner/attack3/attack30026.png b/assets/images/runner/attack3/attack30026.png new file mode 100644 index 0000000..0496ce0 Binary files /dev/null and b/assets/images/runner/attack3/attack30026.png differ diff --git a/assets/images/runner/attack3/attack30027.png b/assets/images/runner/attack3/attack30027.png new file mode 100644 index 0000000..a3d3e7b Binary files /dev/null and b/assets/images/runner/attack3/attack30027.png differ diff --git a/assets/images/runner/attack3/attack30028.png b/assets/images/runner/attack3/attack30028.png new file mode 100644 index 0000000..8a6b05b Binary files /dev/null and b/assets/images/runner/attack3/attack30028.png differ diff --git a/assets/images/runner/attack3/attack30029.png b/assets/images/runner/attack3/attack30029.png new file mode 100644 index 0000000..4e199de Binary files /dev/null and b/assets/images/runner/attack3/attack30029.png differ diff --git a/assets/images/runner/attack3/attack30030.png b/assets/images/runner/attack3/attack30030.png new file mode 100644 index 0000000..5828c23 Binary files /dev/null and b/assets/images/runner/attack3/attack30030.png differ diff --git a/assets/images/runner/attack3/attack30031.png b/assets/images/runner/attack3/attack30031.png new file mode 100644 index 0000000..68ef757 Binary files /dev/null and b/assets/images/runner/attack3/attack30031.png differ diff --git a/assets/images/runner/attack3/attack30032.png b/assets/images/runner/attack3/attack30032.png new file mode 100644 index 0000000..3b0b1ff Binary files /dev/null and b/assets/images/runner/attack3/attack30032.png differ diff --git a/assets/images/runner/attack3/attack30033.png b/assets/images/runner/attack3/attack30033.png new file mode 100644 index 0000000..37effae Binary files /dev/null and b/assets/images/runner/attack3/attack30033.png differ diff --git a/assets/images/runner/attack3/attack30034.png b/assets/images/runner/attack3/attack30034.png new file mode 100644 index 0000000..da72f20 Binary files /dev/null and b/assets/images/runner/attack3/attack30034.png differ diff --git a/assets/images/runner/attack3/attack30035.png b/assets/images/runner/attack3/attack30035.png new file mode 100644 index 0000000..04381bc Binary files /dev/null and b/assets/images/runner/attack3/attack30035.png differ diff --git a/assets/images/runner/attack3/attack30036.png b/assets/images/runner/attack3/attack30036.png new file mode 100644 index 0000000..27fbf26 Binary files /dev/null and b/assets/images/runner/attack3/attack30036.png differ diff --git a/assets/images/runner/attack3/attack30037.png b/assets/images/runner/attack3/attack30037.png new file mode 100644 index 0000000..3ed102d Binary files /dev/null and b/assets/images/runner/attack3/attack30037.png differ diff --git a/assets/images/runner/attack3/attack30038.png b/assets/images/runner/attack3/attack30038.png new file mode 100644 index 0000000..e5b6d73 Binary files /dev/null and b/assets/images/runner/attack3/attack30038.png differ diff --git a/assets/images/runner/death1/death10001.png b/assets/images/runner/death1/death10001.png new file mode 100644 index 0000000..6c5a811 Binary files /dev/null and b/assets/images/runner/death1/death10001.png differ diff --git a/assets/images/runner/death1/death10002.png b/assets/images/runner/death1/death10002.png new file mode 100644 index 0000000..ac18d44 Binary files /dev/null and b/assets/images/runner/death1/death10002.png differ diff --git a/assets/images/runner/death1/death10003.png b/assets/images/runner/death1/death10003.png new file mode 100644 index 0000000..e883885 Binary files /dev/null and b/assets/images/runner/death1/death10003.png differ diff --git a/assets/images/runner/death1/death10004.png b/assets/images/runner/death1/death10004.png new file mode 100644 index 0000000..42236ce Binary files /dev/null and b/assets/images/runner/death1/death10004.png differ diff --git a/assets/images/runner/death1/death10005.png b/assets/images/runner/death1/death10005.png new file mode 100644 index 0000000..1cbfda2 Binary files /dev/null and b/assets/images/runner/death1/death10005.png differ diff --git a/assets/images/runner/death1/death10006.png b/assets/images/runner/death1/death10006.png new file mode 100644 index 0000000..948a4d3 Binary files /dev/null and b/assets/images/runner/death1/death10006.png differ diff --git a/assets/images/runner/death1/death10007.png b/assets/images/runner/death1/death10007.png new file mode 100644 index 0000000..6f5e7bf Binary files /dev/null and b/assets/images/runner/death1/death10007.png differ diff --git a/assets/images/runner/death1/death10008.png b/assets/images/runner/death1/death10008.png new file mode 100644 index 0000000..755eb20 Binary files /dev/null and b/assets/images/runner/death1/death10008.png differ diff --git a/assets/images/runner/death1/death10009.png b/assets/images/runner/death1/death10009.png new file mode 100644 index 0000000..8bc6a2e Binary files /dev/null and b/assets/images/runner/death1/death10009.png differ diff --git a/assets/images/runner/death1/death10010.png b/assets/images/runner/death1/death10010.png new file mode 100644 index 0000000..ebd2aaf Binary files /dev/null and b/assets/images/runner/death1/death10010.png differ diff --git a/assets/images/runner/death1/death10011.png b/assets/images/runner/death1/death10011.png new file mode 100644 index 0000000..2c53538 Binary files /dev/null and b/assets/images/runner/death1/death10011.png differ diff --git a/assets/images/runner/death1/death10012.png b/assets/images/runner/death1/death10012.png new file mode 100644 index 0000000..6a9fedf Binary files /dev/null and b/assets/images/runner/death1/death10012.png differ diff --git a/assets/images/runner/death1/death10013.png b/assets/images/runner/death1/death10013.png new file mode 100644 index 0000000..4efc4f9 Binary files /dev/null and b/assets/images/runner/death1/death10013.png differ diff --git a/assets/images/runner/death1/death10014.png b/assets/images/runner/death1/death10014.png new file mode 100644 index 0000000..1ee868f Binary files /dev/null and b/assets/images/runner/death1/death10014.png differ diff --git a/assets/images/runner/death1/death10015.png b/assets/images/runner/death1/death10015.png new file mode 100644 index 0000000..cf8ddca Binary files /dev/null and b/assets/images/runner/death1/death10015.png differ diff --git a/assets/images/runner/death1/death10016.png b/assets/images/runner/death1/death10016.png new file mode 100644 index 0000000..cc1d15b Binary files /dev/null and b/assets/images/runner/death1/death10016.png differ diff --git a/assets/images/runner/death1/death10017.png b/assets/images/runner/death1/death10017.png new file mode 100644 index 0000000..a4986bc Binary files /dev/null and b/assets/images/runner/death1/death10017.png differ diff --git a/assets/images/runner/death1/death10018.png b/assets/images/runner/death1/death10018.png new file mode 100644 index 0000000..97f6a09 Binary files /dev/null and b/assets/images/runner/death1/death10018.png differ diff --git a/assets/images/runner/death1/death10019.png b/assets/images/runner/death1/death10019.png new file mode 100644 index 0000000..dcfbe46 Binary files /dev/null and b/assets/images/runner/death1/death10019.png differ diff --git a/assets/images/runner/death1/death10020.png b/assets/images/runner/death1/death10020.png new file mode 100644 index 0000000..69e4996 Binary files /dev/null and b/assets/images/runner/death1/death10020.png differ diff --git a/assets/images/runner/death1/death10021.png b/assets/images/runner/death1/death10021.png new file mode 100644 index 0000000..6a0cbf5 Binary files /dev/null and b/assets/images/runner/death1/death10021.png differ diff --git a/assets/images/runner/death1/death10022.png b/assets/images/runner/death1/death10022.png new file mode 100644 index 0000000..afd77e5 Binary files /dev/null and b/assets/images/runner/death1/death10022.png differ diff --git a/assets/images/runner/death1/death10023.png b/assets/images/runner/death1/death10023.png new file mode 100644 index 0000000..e3da528 Binary files /dev/null and b/assets/images/runner/death1/death10023.png differ diff --git a/assets/images/runner/death1/death10024.png b/assets/images/runner/death1/death10024.png new file mode 100644 index 0000000..6498427 Binary files /dev/null and b/assets/images/runner/death1/death10024.png differ diff --git a/assets/images/runner/death1/death10025.png b/assets/images/runner/death1/death10025.png new file mode 100644 index 0000000..44c495e Binary files /dev/null and b/assets/images/runner/death1/death10025.png differ diff --git a/assets/images/runner/death1/death10026.png b/assets/images/runner/death1/death10026.png new file mode 100644 index 0000000..cfaf9d9 Binary files /dev/null and b/assets/images/runner/death1/death10026.png differ diff --git a/assets/images/runner/death1/death10027.png b/assets/images/runner/death1/death10027.png new file mode 100644 index 0000000..3f1bdf8 Binary files /dev/null and b/assets/images/runner/death1/death10027.png differ diff --git a/assets/images/runner/death1/death10028.png b/assets/images/runner/death1/death10028.png new file mode 100644 index 0000000..880c05e Binary files /dev/null and b/assets/images/runner/death1/death10028.png differ diff --git a/assets/images/runner/death1/death10029.png b/assets/images/runner/death1/death10029.png new file mode 100644 index 0000000..8337d5e Binary files /dev/null and b/assets/images/runner/death1/death10029.png differ diff --git a/assets/images/runner/death1/death10030.png b/assets/images/runner/death1/death10030.png new file mode 100644 index 0000000..5f6c89a Binary files /dev/null and b/assets/images/runner/death1/death10030.png differ diff --git a/assets/images/runner/death1/death10031.png b/assets/images/runner/death1/death10031.png new file mode 100644 index 0000000..5a1abb8 Binary files /dev/null and b/assets/images/runner/death1/death10031.png differ diff --git a/assets/images/runner/death1/death10032.png b/assets/images/runner/death1/death10032.png new file mode 100644 index 0000000..db280f0 Binary files /dev/null and b/assets/images/runner/death1/death10032.png differ diff --git a/assets/images/runner/death1/death10033.png b/assets/images/runner/death1/death10033.png new file mode 100644 index 0000000..7783657 Binary files /dev/null and b/assets/images/runner/death1/death10033.png differ diff --git a/assets/images/runner/death1/death10034.png b/assets/images/runner/death1/death10034.png new file mode 100644 index 0000000..0a7fabb Binary files /dev/null and b/assets/images/runner/death1/death10034.png differ diff --git a/assets/images/runner/death1/death10035.png b/assets/images/runner/death1/death10035.png new file mode 100644 index 0000000..0158769 Binary files /dev/null and b/assets/images/runner/death1/death10035.png differ diff --git a/assets/images/runner/death1/death10036.png b/assets/images/runner/death1/death10036.png new file mode 100644 index 0000000..8ade631 Binary files /dev/null and b/assets/images/runner/death1/death10036.png differ diff --git a/assets/images/runner/death1/death10037.png b/assets/images/runner/death1/death10037.png new file mode 100644 index 0000000..c8a1363 Binary files /dev/null and b/assets/images/runner/death1/death10037.png differ diff --git a/assets/images/runner/death1/death10038.png b/assets/images/runner/death1/death10038.png new file mode 100644 index 0000000..8596b7c Binary files /dev/null and b/assets/images/runner/death1/death10038.png differ diff --git a/assets/images/runner/death1/death10039.png b/assets/images/runner/death1/death10039.png new file mode 100644 index 0000000..f152149 Binary files /dev/null and b/assets/images/runner/death1/death10039.png differ diff --git a/assets/images/runner/death1/death10040.png b/assets/images/runner/death1/death10040.png new file mode 100644 index 0000000..5913337 Binary files /dev/null and b/assets/images/runner/death1/death10040.png differ diff --git a/assets/images/runner/death1/death10041.png b/assets/images/runner/death1/death10041.png new file mode 100644 index 0000000..74cb6e4 Binary files /dev/null and b/assets/images/runner/death1/death10041.png differ diff --git a/assets/images/runner/death1/death10042.png b/assets/images/runner/death1/death10042.png new file mode 100644 index 0000000..c96ff26 Binary files /dev/null and b/assets/images/runner/death1/death10042.png differ diff --git a/assets/images/runner/death1/death10043.png b/assets/images/runner/death1/death10043.png new file mode 100644 index 0000000..6342024 Binary files /dev/null and b/assets/images/runner/death1/death10043.png differ diff --git a/assets/images/runner/death1/death10044.png b/assets/images/runner/death1/death10044.png new file mode 100644 index 0000000..fc7a8b6 Binary files /dev/null and b/assets/images/runner/death1/death10044.png differ diff --git a/assets/images/runner/death1/death10045.png b/assets/images/runner/death1/death10045.png new file mode 100644 index 0000000..2d6033b Binary files /dev/null and b/assets/images/runner/death1/death10045.png differ diff --git a/assets/images/runner/death1/death10046.png b/assets/images/runner/death1/death10046.png new file mode 100644 index 0000000..a1d4a4b Binary files /dev/null and b/assets/images/runner/death1/death10046.png differ diff --git a/assets/images/runner/death1/death10047.png b/assets/images/runner/death1/death10047.png new file mode 100644 index 0000000..e691d98 Binary files /dev/null and b/assets/images/runner/death1/death10047.png differ diff --git a/assets/images/runner/death1/death10048.png b/assets/images/runner/death1/death10048.png new file mode 100644 index 0000000..cd2302c Binary files /dev/null and b/assets/images/runner/death1/death10048.png differ diff --git a/assets/images/runner/death1/death10049.png b/assets/images/runner/death1/death10049.png new file mode 100644 index 0000000..7822a25 Binary files /dev/null and b/assets/images/runner/death1/death10049.png differ diff --git a/assets/images/runner/death1/death10050.png b/assets/images/runner/death1/death10050.png new file mode 100644 index 0000000..0899a52 Binary files /dev/null and b/assets/images/runner/death1/death10050.png differ diff --git a/assets/images/runner/death1/death10051.png b/assets/images/runner/death1/death10051.png new file mode 100644 index 0000000..d76f8b5 Binary files /dev/null and b/assets/images/runner/death1/death10051.png differ diff --git a/assets/images/runner/death1/death10052.png b/assets/images/runner/death1/death10052.png new file mode 100644 index 0000000..b198f6c Binary files /dev/null and b/assets/images/runner/death1/death10052.png differ diff --git a/assets/images/runner/death1/death10053.png b/assets/images/runner/death1/death10053.png new file mode 100644 index 0000000..eb9932a Binary files /dev/null and b/assets/images/runner/death1/death10053.png differ diff --git a/assets/images/runner/death1/death10054.png b/assets/images/runner/death1/death10054.png new file mode 100644 index 0000000..1cac4ce Binary files /dev/null and b/assets/images/runner/death1/death10054.png differ diff --git a/assets/images/runner/death1/death10055.png b/assets/images/runner/death1/death10055.png new file mode 100644 index 0000000..56425d2 Binary files /dev/null and b/assets/images/runner/death1/death10055.png differ diff --git a/assets/images/runner/death1/death10056.png b/assets/images/runner/death1/death10056.png new file mode 100644 index 0000000..d91427a Binary files /dev/null and b/assets/images/runner/death1/death10056.png differ diff --git a/assets/images/runner/death1/death10057.png b/assets/images/runner/death1/death10057.png new file mode 100644 index 0000000..7ae54d8 Binary files /dev/null and b/assets/images/runner/death1/death10057.png differ diff --git a/assets/images/runner/death1/death10058.png b/assets/images/runner/death1/death10058.png new file mode 100644 index 0000000..7ae54d8 Binary files /dev/null and b/assets/images/runner/death1/death10058.png differ diff --git a/assets/images/runner/death1/death10059.png b/assets/images/runner/death1/death10059.png new file mode 100644 index 0000000..32b67cb Binary files /dev/null and b/assets/images/runner/death1/death10059.png differ diff --git a/assets/images/runner/death1/death10060.png b/assets/images/runner/death1/death10060.png new file mode 100644 index 0000000..32b67cb Binary files /dev/null and b/assets/images/runner/death1/death10060.png differ diff --git a/assets/images/runner/death1/death10061.png b/assets/images/runner/death1/death10061.png new file mode 100644 index 0000000..8926355 Binary files /dev/null and b/assets/images/runner/death1/death10061.png differ diff --git a/assets/images/runner/death1/death10062.png b/assets/images/runner/death1/death10062.png new file mode 100644 index 0000000..8926355 Binary files /dev/null and b/assets/images/runner/death1/death10062.png differ diff --git a/assets/images/runner/death1/death10063.png b/assets/images/runner/death1/death10063.png new file mode 100644 index 0000000..19abbb1 Binary files /dev/null and b/assets/images/runner/death1/death10063.png differ diff --git a/assets/images/runner/death1/death10064.png b/assets/images/runner/death1/death10064.png new file mode 100644 index 0000000..0466772 Binary files /dev/null and b/assets/images/runner/death1/death10064.png differ diff --git a/assets/images/runner/death1/death10065.png b/assets/images/runner/death1/death10065.png new file mode 100644 index 0000000..0466772 Binary files /dev/null and b/assets/images/runner/death1/death10065.png differ diff --git a/assets/images/runner/death1/death10066.png b/assets/images/runner/death1/death10066.png new file mode 100644 index 0000000..c304365 Binary files /dev/null and b/assets/images/runner/death1/death10066.png differ diff --git a/assets/images/runner/death1/death10067.png b/assets/images/runner/death1/death10067.png new file mode 100644 index 0000000..c304365 Binary files /dev/null and b/assets/images/runner/death1/death10067.png differ diff --git a/assets/images/runner/death1/death10068.png b/assets/images/runner/death1/death10068.png new file mode 100644 index 0000000..7ee79b9 Binary files /dev/null and b/assets/images/runner/death1/death10068.png differ diff --git a/assets/images/runner/death1/death10069.png b/assets/images/runner/death1/death10069.png new file mode 100644 index 0000000..7ee79b9 Binary files /dev/null and b/assets/images/runner/death1/death10069.png differ diff --git a/assets/images/runner/death1/death10070.png b/assets/images/runner/death1/death10070.png new file mode 100644 index 0000000..805090b Binary files /dev/null and b/assets/images/runner/death1/death10070.png differ diff --git a/assets/images/runner/death1/death10071.png b/assets/images/runner/death1/death10071.png new file mode 100644 index 0000000..805090b Binary files /dev/null and b/assets/images/runner/death1/death10071.png differ diff --git a/assets/images/runner/death1/death10072.png b/assets/images/runner/death1/death10072.png new file mode 100644 index 0000000..5a67c28 Binary files /dev/null and b/assets/images/runner/death1/death10072.png differ diff --git a/assets/images/runner/death1/death10073.png b/assets/images/runner/death1/death10073.png new file mode 100644 index 0000000..8df628b Binary files /dev/null and b/assets/images/runner/death1/death10073.png differ diff --git a/assets/images/runner/death1/death10074.png b/assets/images/runner/death1/death10074.png new file mode 100644 index 0000000..8df628b Binary files /dev/null and b/assets/images/runner/death1/death10074.png differ diff --git a/assets/images/runner/death1/death10075.png b/assets/images/runner/death1/death10075.png new file mode 100644 index 0000000..cbf579d Binary files /dev/null and b/assets/images/runner/death1/death10075.png differ diff --git a/assets/images/runner/death1/death10076.png b/assets/images/runner/death1/death10076.png new file mode 100644 index 0000000..cbf579d Binary files /dev/null and b/assets/images/runner/death1/death10076.png differ diff --git a/assets/images/runner/death1/death10077.png b/assets/images/runner/death1/death10077.png new file mode 100644 index 0000000..f8c78a9 Binary files /dev/null and b/assets/images/runner/death1/death10077.png differ diff --git a/assets/images/runner/death1/death10078.png b/assets/images/runner/death1/death10078.png new file mode 100644 index 0000000..9db5e02 Binary files /dev/null and b/assets/images/runner/death1/death10078.png differ diff --git a/assets/images/runner/death1/death10079.png b/assets/images/runner/death1/death10079.png new file mode 100644 index 0000000..8d54762 Binary files /dev/null and b/assets/images/runner/death1/death10079.png differ diff --git a/assets/images/runner/death1/death10080.png b/assets/images/runner/death1/death10080.png new file mode 100644 index 0000000..fa1f7b6 Binary files /dev/null and b/assets/images/runner/death1/death10080.png differ diff --git a/assets/images/runner/death1/death10081.png b/assets/images/runner/death1/death10081.png new file mode 100644 index 0000000..fa1f7b6 Binary files /dev/null and b/assets/images/runner/death1/death10081.png differ diff --git a/assets/images/runner/death1/death10082.png b/assets/images/runner/death1/death10082.png new file mode 100644 index 0000000..b19c51b Binary files /dev/null and b/assets/images/runner/death1/death10082.png differ diff --git a/assets/images/runner/death2/death20001.png b/assets/images/runner/death2/death20001.png new file mode 100644 index 0000000..ac76318 Binary files /dev/null and b/assets/images/runner/death2/death20001.png differ diff --git a/assets/images/runner/death2/death20002.png b/assets/images/runner/death2/death20002.png new file mode 100644 index 0000000..c612238 Binary files /dev/null and b/assets/images/runner/death2/death20002.png differ diff --git a/assets/images/runner/death2/death20003.png b/assets/images/runner/death2/death20003.png new file mode 100644 index 0000000..8238dfb Binary files /dev/null and b/assets/images/runner/death2/death20003.png differ diff --git a/assets/images/runner/death2/death20004.png b/assets/images/runner/death2/death20004.png new file mode 100644 index 0000000..8e15475 Binary files /dev/null and b/assets/images/runner/death2/death20004.png differ diff --git a/assets/images/runner/death2/death20005.png b/assets/images/runner/death2/death20005.png new file mode 100644 index 0000000..1a3e9c5 Binary files /dev/null and b/assets/images/runner/death2/death20005.png differ diff --git a/assets/images/runner/death2/death20006.png b/assets/images/runner/death2/death20006.png new file mode 100644 index 0000000..00b3087 Binary files /dev/null and b/assets/images/runner/death2/death20006.png differ diff --git a/assets/images/runner/death2/death20007.png b/assets/images/runner/death2/death20007.png new file mode 100644 index 0000000..a41047f Binary files /dev/null and b/assets/images/runner/death2/death20007.png differ diff --git a/assets/images/runner/death2/death20008.png b/assets/images/runner/death2/death20008.png new file mode 100644 index 0000000..279d6a6 Binary files /dev/null and b/assets/images/runner/death2/death20008.png differ diff --git a/assets/images/runner/death2/death20009.png b/assets/images/runner/death2/death20009.png new file mode 100644 index 0000000..23226cb Binary files /dev/null and b/assets/images/runner/death2/death20009.png differ diff --git a/assets/images/runner/death2/death20010.png b/assets/images/runner/death2/death20010.png new file mode 100644 index 0000000..4b1cc24 Binary files /dev/null and b/assets/images/runner/death2/death20010.png differ diff --git a/assets/images/runner/death2/death20011.png b/assets/images/runner/death2/death20011.png new file mode 100644 index 0000000..5c70118 Binary files /dev/null and b/assets/images/runner/death2/death20011.png differ diff --git a/assets/images/runner/death2/death20012.png b/assets/images/runner/death2/death20012.png new file mode 100644 index 0000000..c23ad03 Binary files /dev/null and b/assets/images/runner/death2/death20012.png differ diff --git a/assets/images/runner/death2/death20013.png b/assets/images/runner/death2/death20013.png new file mode 100644 index 0000000..a509d10 Binary files /dev/null and b/assets/images/runner/death2/death20013.png differ diff --git a/assets/images/runner/death2/death20014.png b/assets/images/runner/death2/death20014.png new file mode 100644 index 0000000..929e96a Binary files /dev/null and b/assets/images/runner/death2/death20014.png differ diff --git a/assets/images/runner/death2/death20015.png b/assets/images/runner/death2/death20015.png new file mode 100644 index 0000000..6da85d0 Binary files /dev/null and b/assets/images/runner/death2/death20015.png differ diff --git a/assets/images/runner/death2/death20016.png b/assets/images/runner/death2/death20016.png new file mode 100644 index 0000000..2e4a26c Binary files /dev/null and b/assets/images/runner/death2/death20016.png differ diff --git a/assets/images/runner/death2/death20017.png b/assets/images/runner/death2/death20017.png new file mode 100644 index 0000000..502ad0d Binary files /dev/null and b/assets/images/runner/death2/death20017.png differ diff --git a/assets/images/runner/death2/death20018.png b/assets/images/runner/death2/death20018.png new file mode 100644 index 0000000..38d98f1 Binary files /dev/null and b/assets/images/runner/death2/death20018.png differ diff --git a/assets/images/runner/death2/death20019.png b/assets/images/runner/death2/death20019.png new file mode 100644 index 0000000..cbd1acd Binary files /dev/null and b/assets/images/runner/death2/death20019.png differ diff --git a/assets/images/runner/death2/death20020.png b/assets/images/runner/death2/death20020.png new file mode 100644 index 0000000..395f9ab Binary files /dev/null and b/assets/images/runner/death2/death20020.png differ diff --git a/assets/images/runner/death2/death20021.png b/assets/images/runner/death2/death20021.png new file mode 100644 index 0000000..8d1093b Binary files /dev/null and b/assets/images/runner/death2/death20021.png differ diff --git a/assets/images/runner/death2/death20022.png b/assets/images/runner/death2/death20022.png new file mode 100644 index 0000000..1c64153 Binary files /dev/null and b/assets/images/runner/death2/death20022.png differ diff --git a/assets/images/runner/death2/death20023.png b/assets/images/runner/death2/death20023.png new file mode 100644 index 0000000..1d65e96 Binary files /dev/null and b/assets/images/runner/death2/death20023.png differ diff --git a/assets/images/runner/death2/death20024.png b/assets/images/runner/death2/death20024.png new file mode 100644 index 0000000..29f655d Binary files /dev/null and b/assets/images/runner/death2/death20024.png differ diff --git a/assets/images/runner/death2/death20025.png b/assets/images/runner/death2/death20025.png new file mode 100644 index 0000000..3f004e3 Binary files /dev/null and b/assets/images/runner/death2/death20025.png differ diff --git a/assets/images/runner/death2/death20026.png b/assets/images/runner/death2/death20026.png new file mode 100644 index 0000000..905ab52 Binary files /dev/null and b/assets/images/runner/death2/death20026.png differ diff --git a/assets/images/runner/death2/death20027.png b/assets/images/runner/death2/death20027.png new file mode 100644 index 0000000..ca25d3a Binary files /dev/null and b/assets/images/runner/death2/death20027.png differ diff --git a/assets/images/runner/death2/death20028.png b/assets/images/runner/death2/death20028.png new file mode 100644 index 0000000..9296f45 Binary files /dev/null and b/assets/images/runner/death2/death20028.png differ diff --git a/assets/images/runner/death2/death20029.png b/assets/images/runner/death2/death20029.png new file mode 100644 index 0000000..b24aed6 Binary files /dev/null and b/assets/images/runner/death2/death20029.png differ diff --git a/assets/images/runner/death2/death20030.png b/assets/images/runner/death2/death20030.png new file mode 100644 index 0000000..2a782bd Binary files /dev/null and b/assets/images/runner/death2/death20030.png differ diff --git a/assets/images/runner/death2/death20031.png b/assets/images/runner/death2/death20031.png new file mode 100644 index 0000000..ec17403 Binary files /dev/null and b/assets/images/runner/death2/death20031.png differ diff --git a/assets/images/runner/death2/death20032.png b/assets/images/runner/death2/death20032.png new file mode 100644 index 0000000..f7863b2 Binary files /dev/null and b/assets/images/runner/death2/death20032.png differ diff --git a/assets/images/runner/death2/death20033.png b/assets/images/runner/death2/death20033.png new file mode 100644 index 0000000..4de372b Binary files /dev/null and b/assets/images/runner/death2/death20033.png differ diff --git a/assets/images/runner/death2/death20034.png b/assets/images/runner/death2/death20034.png new file mode 100644 index 0000000..ba3d23a Binary files /dev/null and b/assets/images/runner/death2/death20034.png differ diff --git a/assets/images/runner/death2/death20035.png b/assets/images/runner/death2/death20035.png new file mode 100644 index 0000000..d34e35d Binary files /dev/null and b/assets/images/runner/death2/death20035.png differ diff --git a/assets/images/runner/death2/death20036.png b/assets/images/runner/death2/death20036.png new file mode 100644 index 0000000..3f75d3a Binary files /dev/null and b/assets/images/runner/death2/death20036.png differ diff --git a/assets/images/runner/death2/death20037.png b/assets/images/runner/death2/death20037.png new file mode 100644 index 0000000..f6bc04c Binary files /dev/null and b/assets/images/runner/death2/death20037.png differ diff --git a/assets/images/runner/death2/death20038.png b/assets/images/runner/death2/death20038.png new file mode 100644 index 0000000..08b1b84 Binary files /dev/null and b/assets/images/runner/death2/death20038.png differ diff --git a/assets/images/runner/death2/death20039.png b/assets/images/runner/death2/death20039.png new file mode 100644 index 0000000..805e4d8 Binary files /dev/null and b/assets/images/runner/death2/death20039.png differ diff --git a/assets/images/runner/death2/death20040.png b/assets/images/runner/death2/death20040.png new file mode 100644 index 0000000..369bed9 Binary files /dev/null and b/assets/images/runner/death2/death20040.png differ diff --git a/assets/images/runner/death2/death20041.png b/assets/images/runner/death2/death20041.png new file mode 100644 index 0000000..959b190 Binary files /dev/null and b/assets/images/runner/death2/death20041.png differ diff --git a/assets/images/runner/death2/death20042.png b/assets/images/runner/death2/death20042.png new file mode 100644 index 0000000..4d860e6 Binary files /dev/null and b/assets/images/runner/death2/death20042.png differ diff --git a/assets/images/runner/death2/death20043.png b/assets/images/runner/death2/death20043.png new file mode 100644 index 0000000..c65e5a4 Binary files /dev/null and b/assets/images/runner/death2/death20043.png differ diff --git a/assets/images/runner/death2/death20044.png b/assets/images/runner/death2/death20044.png new file mode 100644 index 0000000..709fe9a Binary files /dev/null and b/assets/images/runner/death2/death20044.png differ diff --git a/assets/images/runner/death2/death20045.png b/assets/images/runner/death2/death20045.png new file mode 100644 index 0000000..efcbf3f Binary files /dev/null and b/assets/images/runner/death2/death20045.png differ diff --git a/assets/images/runner/death2/death20046.png b/assets/images/runner/death2/death20046.png new file mode 100644 index 0000000..af66dac Binary files /dev/null and b/assets/images/runner/death2/death20046.png differ diff --git a/assets/images/runner/death2/death20047.png b/assets/images/runner/death2/death20047.png new file mode 100644 index 0000000..f47445c Binary files /dev/null and b/assets/images/runner/death2/death20047.png differ diff --git a/assets/images/runner/death2/death20048.png b/assets/images/runner/death2/death20048.png new file mode 100644 index 0000000..cf0eda7 Binary files /dev/null and b/assets/images/runner/death2/death20048.png differ diff --git a/assets/images/runner/death2/death20049.png b/assets/images/runner/death2/death20049.png new file mode 100644 index 0000000..af0c9f9 Binary files /dev/null and b/assets/images/runner/death2/death20049.png differ diff --git a/assets/images/runner/death2/death20050.png b/assets/images/runner/death2/death20050.png new file mode 100644 index 0000000..a0fb4b5 Binary files /dev/null and b/assets/images/runner/death2/death20050.png differ diff --git a/assets/images/runner/death2/death20051.png b/assets/images/runner/death2/death20051.png new file mode 100644 index 0000000..656d8f3 Binary files /dev/null and b/assets/images/runner/death2/death20051.png differ diff --git a/assets/images/runner/death2/death20052.png b/assets/images/runner/death2/death20052.png new file mode 100644 index 0000000..c4c2771 Binary files /dev/null and b/assets/images/runner/death2/death20052.png differ diff --git a/assets/images/runner/death2/death20053.png b/assets/images/runner/death2/death20053.png new file mode 100644 index 0000000..1619e68 Binary files /dev/null and b/assets/images/runner/death2/death20053.png differ diff --git a/assets/images/runner/death2/death20054.png b/assets/images/runner/death2/death20054.png new file mode 100644 index 0000000..ff9dbc2 Binary files /dev/null and b/assets/images/runner/death2/death20054.png differ diff --git a/assets/images/runner/death2/death20055.png b/assets/images/runner/death2/death20055.png new file mode 100644 index 0000000..419cf95 Binary files /dev/null and b/assets/images/runner/death2/death20055.png differ diff --git a/assets/images/runner/death2/death20056.png b/assets/images/runner/death2/death20056.png new file mode 100644 index 0000000..1ee52fd Binary files /dev/null and b/assets/images/runner/death2/death20056.png differ diff --git a/assets/images/runner/death2/death20057.png b/assets/images/runner/death2/death20057.png new file mode 100644 index 0000000..b1e8646 Binary files /dev/null and b/assets/images/runner/death2/death20057.png differ diff --git a/assets/images/runner/duck1/duck10001.png b/assets/images/runner/duck1/duck10001.png new file mode 100644 index 0000000..17dcb1c Binary files /dev/null and b/assets/images/runner/duck1/duck10001.png differ diff --git a/assets/images/runner/duck1/duck10002.png b/assets/images/runner/duck1/duck10002.png new file mode 100644 index 0000000..cce4a21 Binary files /dev/null and b/assets/images/runner/duck1/duck10002.png differ diff --git a/assets/images/runner/duck1/duck10003.png b/assets/images/runner/duck1/duck10003.png new file mode 100644 index 0000000..7897c29 Binary files /dev/null and b/assets/images/runner/duck1/duck10003.png differ diff --git a/assets/images/runner/duck1/duck10004.png b/assets/images/runner/duck1/duck10004.png new file mode 100644 index 0000000..0ea2e5c Binary files /dev/null and b/assets/images/runner/duck1/duck10004.png differ diff --git a/assets/images/runner/duck1/duck10005.png b/assets/images/runner/duck1/duck10005.png new file mode 100644 index 0000000..83b17eb Binary files /dev/null and b/assets/images/runner/duck1/duck10005.png differ diff --git a/assets/images/runner/duck1/duck10006.png b/assets/images/runner/duck1/duck10006.png new file mode 100644 index 0000000..f64b6a5 Binary files /dev/null and b/assets/images/runner/duck1/duck10006.png differ diff --git a/assets/images/runner/duck1/duck10007.png b/assets/images/runner/duck1/duck10007.png new file mode 100644 index 0000000..2f267d9 Binary files /dev/null and b/assets/images/runner/duck1/duck10007.png differ diff --git a/assets/images/runner/duck1/duck10008.png b/assets/images/runner/duck1/duck10008.png new file mode 100644 index 0000000..70d2cc7 Binary files /dev/null and b/assets/images/runner/duck1/duck10008.png differ diff --git a/assets/images/runner/duck1/duck10009.png b/assets/images/runner/duck1/duck10009.png new file mode 100644 index 0000000..9ff738d Binary files /dev/null and b/assets/images/runner/duck1/duck10009.png differ diff --git a/assets/images/runner/duck1/duck10010.png b/assets/images/runner/duck1/duck10010.png new file mode 100644 index 0000000..bc06b3b Binary files /dev/null and b/assets/images/runner/duck1/duck10010.png differ diff --git a/assets/images/runner/duck1/duck10011.png b/assets/images/runner/duck1/duck10011.png new file mode 100644 index 0000000..892ebb8 Binary files /dev/null and b/assets/images/runner/duck1/duck10011.png differ diff --git a/assets/images/runner/duck1/duck10012.png b/assets/images/runner/duck1/duck10012.png new file mode 100644 index 0000000..125cbbd Binary files /dev/null and b/assets/images/runner/duck1/duck10012.png differ diff --git a/assets/images/runner/duck1/duck10013.png b/assets/images/runner/duck1/duck10013.png new file mode 100644 index 0000000..3d9e9f8 Binary files /dev/null and b/assets/images/runner/duck1/duck10013.png differ diff --git a/assets/images/runner/duck1/duck10014.png b/assets/images/runner/duck1/duck10014.png new file mode 100644 index 0000000..6c713e8 Binary files /dev/null and b/assets/images/runner/duck1/duck10014.png differ diff --git a/assets/images/runner/duck1/duck10015.png b/assets/images/runner/duck1/duck10015.png new file mode 100644 index 0000000..f8ea9f5 Binary files /dev/null and b/assets/images/runner/duck1/duck10015.png differ diff --git a/assets/images/runner/duck1/duck10016.png b/assets/images/runner/duck1/duck10016.png new file mode 100644 index 0000000..cab3515 Binary files /dev/null and b/assets/images/runner/duck1/duck10016.png differ diff --git a/assets/images/runner/duck1/duck10017.png b/assets/images/runner/duck1/duck10017.png new file mode 100644 index 0000000..dce47fd Binary files /dev/null and b/assets/images/runner/duck1/duck10017.png differ diff --git a/assets/images/runner/duck1/duck10018.png b/assets/images/runner/duck1/duck10018.png new file mode 100644 index 0000000..263ab48 Binary files /dev/null and b/assets/images/runner/duck1/duck10018.png differ diff --git a/assets/images/runner/duck1/duck10019.png b/assets/images/runner/duck1/duck10019.png new file mode 100644 index 0000000..8a28358 Binary files /dev/null and b/assets/images/runner/duck1/duck10019.png differ diff --git a/assets/images/runner/duck1/duck10020.png b/assets/images/runner/duck1/duck10020.png new file mode 100644 index 0000000..77d4d78 Binary files /dev/null and b/assets/images/runner/duck1/duck10020.png differ diff --git a/assets/images/runner/duck1/duck10021.png b/assets/images/runner/duck1/duck10021.png new file mode 100644 index 0000000..66a4a29 Binary files /dev/null and b/assets/images/runner/duck1/duck10021.png differ diff --git a/assets/images/runner/duck1/duck10022.png b/assets/images/runner/duck1/duck10022.png new file mode 100644 index 0000000..a76db00 Binary files /dev/null and b/assets/images/runner/duck1/duck10022.png differ diff --git a/assets/images/runner/duck1/duck10023.png b/assets/images/runner/duck1/duck10023.png new file mode 100644 index 0000000..f35f407 Binary files /dev/null and b/assets/images/runner/duck1/duck10023.png differ diff --git a/assets/images/runner/duck1/duck10024.png b/assets/images/runner/duck1/duck10024.png new file mode 100644 index 0000000..b9efcf4 Binary files /dev/null and b/assets/images/runner/duck1/duck10024.png differ diff --git a/assets/images/runner/duck1/duck10025.png b/assets/images/runner/duck1/duck10025.png new file mode 100644 index 0000000..8ad6937 Binary files /dev/null and b/assets/images/runner/duck1/duck10025.png differ diff --git a/assets/images/runner/duck1/duck10026.png b/assets/images/runner/duck1/duck10026.png new file mode 100644 index 0000000..21c604a Binary files /dev/null and b/assets/images/runner/duck1/duck10026.png differ diff --git a/assets/images/runner/duck1/duck10027.png b/assets/images/runner/duck1/duck10027.png new file mode 100644 index 0000000..108599c Binary files /dev/null and b/assets/images/runner/duck1/duck10027.png differ diff --git a/assets/images/runner/duck1/duck10028.png b/assets/images/runner/duck1/duck10028.png new file mode 100644 index 0000000..78b2f62 Binary files /dev/null and b/assets/images/runner/duck1/duck10028.png differ diff --git a/assets/images/runner/duck1/duck10029.png b/assets/images/runner/duck1/duck10029.png new file mode 100644 index 0000000..d78162e Binary files /dev/null and b/assets/images/runner/duck1/duck10029.png differ diff --git a/assets/images/runner/duck1/duck10030.png b/assets/images/runner/duck1/duck10030.png new file mode 100644 index 0000000..7c5f807 Binary files /dev/null and b/assets/images/runner/duck1/duck10030.png differ diff --git a/assets/images/runner/duck1/duck10031.png b/assets/images/runner/duck1/duck10031.png new file mode 100644 index 0000000..8fcffba Binary files /dev/null and b/assets/images/runner/duck1/duck10031.png differ diff --git a/assets/images/runner/duck1/duck10032.png b/assets/images/runner/duck1/duck10032.png new file mode 100644 index 0000000..1dedfa8 Binary files /dev/null and b/assets/images/runner/duck1/duck10032.png differ diff --git a/assets/images/runner/duck1/duck10033.png b/assets/images/runner/duck1/duck10033.png new file mode 100644 index 0000000..ac1a34a Binary files /dev/null and b/assets/images/runner/duck1/duck10033.png differ diff --git a/assets/images/runner/duck1/duck10034.png b/assets/images/runner/duck1/duck10034.png new file mode 100644 index 0000000..835da68 Binary files /dev/null and b/assets/images/runner/duck1/duck10034.png differ diff --git a/assets/images/runner/duck1/duck10035.png b/assets/images/runner/duck1/duck10035.png new file mode 100644 index 0000000..a817b54 Binary files /dev/null and b/assets/images/runner/duck1/duck10035.png differ diff --git a/assets/images/runner/duck1/duck10036.png b/assets/images/runner/duck1/duck10036.png new file mode 100644 index 0000000..4c9e08e Binary files /dev/null and b/assets/images/runner/duck1/duck10036.png differ diff --git a/assets/images/runner/duck1/duck10037.png b/assets/images/runner/duck1/duck10037.png new file mode 100644 index 0000000..878b168 Binary files /dev/null and b/assets/images/runner/duck1/duck10037.png differ diff --git a/assets/images/runner/duck1/duck10038.png b/assets/images/runner/duck1/duck10038.png new file mode 100644 index 0000000..7666053 Binary files /dev/null and b/assets/images/runner/duck1/duck10038.png differ diff --git a/assets/images/runner/duck2/duck20001.png b/assets/images/runner/duck2/duck20001.png new file mode 100644 index 0000000..a23e9ae Binary files /dev/null and b/assets/images/runner/duck2/duck20001.png differ diff --git a/assets/images/runner/duck2/duck20002.png b/assets/images/runner/duck2/duck20002.png new file mode 100644 index 0000000..9d139b5 Binary files /dev/null and b/assets/images/runner/duck2/duck20002.png differ diff --git a/assets/images/runner/duck2/duck20003.png b/assets/images/runner/duck2/duck20003.png new file mode 100644 index 0000000..095d5ed Binary files /dev/null and b/assets/images/runner/duck2/duck20003.png differ diff --git a/assets/images/runner/duck2/duck20004.png b/assets/images/runner/duck2/duck20004.png new file mode 100644 index 0000000..8e7d13c Binary files /dev/null and b/assets/images/runner/duck2/duck20004.png differ diff --git a/assets/images/runner/duck2/duck20005.png b/assets/images/runner/duck2/duck20005.png new file mode 100644 index 0000000..1fede45 Binary files /dev/null and b/assets/images/runner/duck2/duck20005.png differ diff --git a/assets/images/runner/duck2/duck20006.png b/assets/images/runner/duck2/duck20006.png new file mode 100644 index 0000000..7bce12e Binary files /dev/null and b/assets/images/runner/duck2/duck20006.png differ diff --git a/assets/images/runner/duck2/duck20007.png b/assets/images/runner/duck2/duck20007.png new file mode 100644 index 0000000..1b9e281 Binary files /dev/null and b/assets/images/runner/duck2/duck20007.png differ diff --git a/assets/images/runner/duck2/duck20008.png b/assets/images/runner/duck2/duck20008.png new file mode 100644 index 0000000..5451e5b Binary files /dev/null and b/assets/images/runner/duck2/duck20008.png differ diff --git a/assets/images/runner/duck2/duck20009.png b/assets/images/runner/duck2/duck20009.png new file mode 100644 index 0000000..eb5e27b Binary files /dev/null and b/assets/images/runner/duck2/duck20009.png differ diff --git a/assets/images/runner/duck2/duck20010.png b/assets/images/runner/duck2/duck20010.png new file mode 100644 index 0000000..79e9e8b Binary files /dev/null and b/assets/images/runner/duck2/duck20010.png differ diff --git a/assets/images/runner/duck2/duck20011.png b/assets/images/runner/duck2/duck20011.png new file mode 100644 index 0000000..14688da Binary files /dev/null and b/assets/images/runner/duck2/duck20011.png differ diff --git a/assets/images/runner/duck2/duck20012.png b/assets/images/runner/duck2/duck20012.png new file mode 100644 index 0000000..21ecdf5 Binary files /dev/null and b/assets/images/runner/duck2/duck20012.png differ diff --git a/assets/images/runner/duck2/duck20013.png b/assets/images/runner/duck2/duck20013.png new file mode 100644 index 0000000..3136273 Binary files /dev/null and b/assets/images/runner/duck2/duck20013.png differ diff --git a/assets/images/runner/duck2/duck20014.png b/assets/images/runner/duck2/duck20014.png new file mode 100644 index 0000000..eaa4eba Binary files /dev/null and b/assets/images/runner/duck2/duck20014.png differ diff --git a/assets/images/runner/duck2/duck20015.png b/assets/images/runner/duck2/duck20015.png new file mode 100644 index 0000000..da3d1dc Binary files /dev/null and b/assets/images/runner/duck2/duck20015.png differ diff --git a/assets/images/runner/duck2/duck20016.png b/assets/images/runner/duck2/duck20016.png new file mode 100644 index 0000000..0963898 Binary files /dev/null and b/assets/images/runner/duck2/duck20016.png differ diff --git a/assets/images/runner/duck2/duck20017.png b/assets/images/runner/duck2/duck20017.png new file mode 100644 index 0000000..6955d8b Binary files /dev/null and b/assets/images/runner/duck2/duck20017.png differ diff --git a/assets/images/runner/duck2/duck20018.png b/assets/images/runner/duck2/duck20018.png new file mode 100644 index 0000000..57e49fe Binary files /dev/null and b/assets/images/runner/duck2/duck20018.png differ diff --git a/assets/images/runner/duck2/duck20019.png b/assets/images/runner/duck2/duck20019.png new file mode 100644 index 0000000..3e98484 Binary files /dev/null and b/assets/images/runner/duck2/duck20019.png differ diff --git a/assets/images/runner/duck2/duck20020.png b/assets/images/runner/duck2/duck20020.png new file mode 100644 index 0000000..3014b5d Binary files /dev/null and b/assets/images/runner/duck2/duck20020.png differ diff --git a/assets/images/runner/duck2/duck20021.png b/assets/images/runner/duck2/duck20021.png new file mode 100644 index 0000000..4df169b Binary files /dev/null and b/assets/images/runner/duck2/duck20021.png differ diff --git a/assets/images/runner/duck2/duck20022.png b/assets/images/runner/duck2/duck20022.png new file mode 100644 index 0000000..4c7241b Binary files /dev/null and b/assets/images/runner/duck2/duck20022.png differ diff --git a/assets/images/runner/duck2/duck20023.png b/assets/images/runner/duck2/duck20023.png new file mode 100644 index 0000000..6e47c06 Binary files /dev/null and b/assets/images/runner/duck2/duck20023.png differ diff --git a/assets/images/runner/duck2/duck20024.png b/assets/images/runner/duck2/duck20024.png new file mode 100644 index 0000000..49f3bb4 Binary files /dev/null and b/assets/images/runner/duck2/duck20024.png differ diff --git a/assets/images/runner/duck2/duck20025.png b/assets/images/runner/duck2/duck20025.png new file mode 100644 index 0000000..0e4ac9d Binary files /dev/null and b/assets/images/runner/duck2/duck20025.png differ diff --git a/assets/images/runner/duck2/duck20026.png b/assets/images/runner/duck2/duck20026.png new file mode 100644 index 0000000..bf4e693 Binary files /dev/null and b/assets/images/runner/duck2/duck20026.png differ diff --git a/assets/images/runner/duck2/duck20027.png b/assets/images/runner/duck2/duck20027.png new file mode 100644 index 0000000..08ee2f3 Binary files /dev/null and b/assets/images/runner/duck2/duck20027.png differ diff --git a/assets/images/runner/duck2/duck20028.png b/assets/images/runner/duck2/duck20028.png new file mode 100644 index 0000000..5c5c994 Binary files /dev/null and b/assets/images/runner/duck2/duck20028.png differ diff --git a/assets/images/runner/duck2/duck20029.png b/assets/images/runner/duck2/duck20029.png new file mode 100644 index 0000000..5a20711 Binary files /dev/null and b/assets/images/runner/duck2/duck20029.png differ diff --git a/assets/images/runner/duck2/duck20030.png b/assets/images/runner/duck2/duck20030.png new file mode 100644 index 0000000..fbd7e7b Binary files /dev/null and b/assets/images/runner/duck2/duck20030.png differ diff --git a/assets/images/runner/duck2/duck20031.png b/assets/images/runner/duck2/duck20031.png new file mode 100644 index 0000000..6737894 Binary files /dev/null and b/assets/images/runner/duck2/duck20031.png differ diff --git a/assets/images/runner/duck2/duck20032.png b/assets/images/runner/duck2/duck20032.png new file mode 100644 index 0000000..e3c5e47 Binary files /dev/null and b/assets/images/runner/duck2/duck20032.png differ diff --git a/assets/images/runner/duck2/duck20033.png b/assets/images/runner/duck2/duck20033.png new file mode 100644 index 0000000..577deee Binary files /dev/null and b/assets/images/runner/duck2/duck20033.png differ diff --git a/assets/images/runner/duck2/duck20034.png b/assets/images/runner/duck2/duck20034.png new file mode 100644 index 0000000..de4af71 Binary files /dev/null and b/assets/images/runner/duck2/duck20034.png differ diff --git a/assets/images/runner/duck2/duck20035.png b/assets/images/runner/duck2/duck20035.png new file mode 100644 index 0000000..c5acfc6 Binary files /dev/null and b/assets/images/runner/duck2/duck20035.png differ diff --git a/assets/images/runner/duck2/duck20036.png b/assets/images/runner/duck2/duck20036.png new file mode 100644 index 0000000..c3dd21c Binary files /dev/null and b/assets/images/runner/duck2/duck20036.png differ diff --git a/assets/images/runner/duck2/duck20037.png b/assets/images/runner/duck2/duck20037.png new file mode 100644 index 0000000..2c0ade7 Binary files /dev/null and b/assets/images/runner/duck2/duck20037.png differ diff --git a/assets/images/runner/duck2/duck20038.png b/assets/images/runner/duck2/duck20038.png new file mode 100644 index 0000000..d53a283 Binary files /dev/null and b/assets/images/runner/duck2/duck20038.png differ diff --git a/assets/images/runner/duck3/duck30001.png b/assets/images/runner/duck3/duck30001.png new file mode 100644 index 0000000..c737c5c Binary files /dev/null and b/assets/images/runner/duck3/duck30001.png differ diff --git a/assets/images/runner/duck3/duck30002.png b/assets/images/runner/duck3/duck30002.png new file mode 100644 index 0000000..aa2ab68 Binary files /dev/null and b/assets/images/runner/duck3/duck30002.png differ diff --git a/assets/images/runner/duck3/duck30003.png b/assets/images/runner/duck3/duck30003.png new file mode 100644 index 0000000..1f3df35 Binary files /dev/null and b/assets/images/runner/duck3/duck30003.png differ diff --git a/assets/images/runner/duck3/duck30004.png b/assets/images/runner/duck3/duck30004.png new file mode 100644 index 0000000..1d95714 Binary files /dev/null and b/assets/images/runner/duck3/duck30004.png differ diff --git a/assets/images/runner/duck3/duck30005.png b/assets/images/runner/duck3/duck30005.png new file mode 100644 index 0000000..1624a98 Binary files /dev/null and b/assets/images/runner/duck3/duck30005.png differ diff --git a/assets/images/runner/duck3/duck30006.png b/assets/images/runner/duck3/duck30006.png new file mode 100644 index 0000000..842b7ce Binary files /dev/null and b/assets/images/runner/duck3/duck30006.png differ diff --git a/assets/images/runner/duck3/duck30007.png b/assets/images/runner/duck3/duck30007.png new file mode 100644 index 0000000..7282dae Binary files /dev/null and b/assets/images/runner/duck3/duck30007.png differ diff --git a/assets/images/runner/duck3/duck30008.png b/assets/images/runner/duck3/duck30008.png new file mode 100644 index 0000000..df2bfef Binary files /dev/null and b/assets/images/runner/duck3/duck30008.png differ diff --git a/assets/images/runner/duck3/duck30009.png b/assets/images/runner/duck3/duck30009.png new file mode 100644 index 0000000..fc8b069 Binary files /dev/null and b/assets/images/runner/duck3/duck30009.png differ diff --git a/assets/images/runner/duck3/duck30010.png b/assets/images/runner/duck3/duck30010.png new file mode 100644 index 0000000..2bd1827 Binary files /dev/null and b/assets/images/runner/duck3/duck30010.png differ diff --git a/assets/images/runner/duck3/duck30011.png b/assets/images/runner/duck3/duck30011.png new file mode 100644 index 0000000..86e41c7 Binary files /dev/null and b/assets/images/runner/duck3/duck30011.png differ diff --git a/assets/images/runner/duck3/duck30012.png b/assets/images/runner/duck3/duck30012.png new file mode 100644 index 0000000..7b50989 Binary files /dev/null and b/assets/images/runner/duck3/duck30012.png differ diff --git a/assets/images/runner/duck3/duck30013.png b/assets/images/runner/duck3/duck30013.png new file mode 100644 index 0000000..8fb7088 Binary files /dev/null and b/assets/images/runner/duck3/duck30013.png differ diff --git a/assets/images/runner/duck3/duck30014.png b/assets/images/runner/duck3/duck30014.png new file mode 100644 index 0000000..d12fa0b Binary files /dev/null and b/assets/images/runner/duck3/duck30014.png differ diff --git a/assets/images/runner/duck3/duck30015.png b/assets/images/runner/duck3/duck30015.png new file mode 100644 index 0000000..39dc554 Binary files /dev/null and b/assets/images/runner/duck3/duck30015.png differ diff --git a/assets/images/runner/duck3/duck30016.png b/assets/images/runner/duck3/duck30016.png new file mode 100644 index 0000000..bb75926 Binary files /dev/null and b/assets/images/runner/duck3/duck30016.png differ diff --git a/assets/images/runner/duck3/duck30017.png b/assets/images/runner/duck3/duck30017.png new file mode 100644 index 0000000..b669c52 Binary files /dev/null and b/assets/images/runner/duck3/duck30017.png differ diff --git a/assets/images/runner/duck3/duck30018.png b/assets/images/runner/duck3/duck30018.png new file mode 100644 index 0000000..2812c75 Binary files /dev/null and b/assets/images/runner/duck3/duck30018.png differ diff --git a/assets/images/runner/duck3/duck30019.png b/assets/images/runner/duck3/duck30019.png new file mode 100644 index 0000000..68738df Binary files /dev/null and b/assets/images/runner/duck3/duck30019.png differ diff --git a/assets/images/runner/duck3/duck30020.png b/assets/images/runner/duck3/duck30020.png new file mode 100644 index 0000000..aa411ef Binary files /dev/null and b/assets/images/runner/duck3/duck30020.png differ diff --git a/assets/images/runner/duck3/duck30021.png b/assets/images/runner/duck3/duck30021.png new file mode 100644 index 0000000..f36dd30 Binary files /dev/null and b/assets/images/runner/duck3/duck30021.png differ diff --git a/assets/images/runner/duck3/duck30022.png b/assets/images/runner/duck3/duck30022.png new file mode 100644 index 0000000..868a86d Binary files /dev/null and b/assets/images/runner/duck3/duck30022.png differ diff --git a/assets/images/runner/duck3/duck30023.png b/assets/images/runner/duck3/duck30023.png new file mode 100644 index 0000000..2f9f85b Binary files /dev/null and b/assets/images/runner/duck3/duck30023.png differ diff --git a/assets/images/runner/duck3/duck30024.png b/assets/images/runner/duck3/duck30024.png new file mode 100644 index 0000000..3ed0183 Binary files /dev/null and b/assets/images/runner/duck3/duck30024.png differ diff --git a/assets/images/runner/duck3/duck30025.png b/assets/images/runner/duck3/duck30025.png new file mode 100644 index 0000000..d865af4 Binary files /dev/null and b/assets/images/runner/duck3/duck30025.png differ diff --git a/assets/images/runner/duck3/duck30026.png b/assets/images/runner/duck3/duck30026.png new file mode 100644 index 0000000..9d0f3e6 Binary files /dev/null and b/assets/images/runner/duck3/duck30026.png differ diff --git a/assets/images/runner/duck3/duck30027.png b/assets/images/runner/duck3/duck30027.png new file mode 100644 index 0000000..9208683 Binary files /dev/null and b/assets/images/runner/duck3/duck30027.png differ diff --git a/assets/images/runner/duck3/duck30028.png b/assets/images/runner/duck3/duck30028.png new file mode 100644 index 0000000..83b7edb Binary files /dev/null and b/assets/images/runner/duck3/duck30028.png differ diff --git a/assets/images/runner/duck3/duck30029.png b/assets/images/runner/duck3/duck30029.png new file mode 100644 index 0000000..595dc8f Binary files /dev/null and b/assets/images/runner/duck3/duck30029.png differ diff --git a/assets/images/runner/duck3/duck30030.png b/assets/images/runner/duck3/duck30030.png new file mode 100644 index 0000000..33173cb Binary files /dev/null and b/assets/images/runner/duck3/duck30030.png differ diff --git a/assets/images/runner/duck3/duck30031.png b/assets/images/runner/duck3/duck30031.png new file mode 100644 index 0000000..bbbeae2 Binary files /dev/null and b/assets/images/runner/duck3/duck30031.png differ diff --git a/assets/images/runner/duck3/duck30032.png b/assets/images/runner/duck3/duck30032.png new file mode 100644 index 0000000..de7cb19 Binary files /dev/null and b/assets/images/runner/duck3/duck30032.png differ diff --git a/assets/images/runner/duck3/duck30033.png b/assets/images/runner/duck3/duck30033.png new file mode 100644 index 0000000..a05e07b Binary files /dev/null and b/assets/images/runner/duck3/duck30033.png differ diff --git a/assets/images/runner/duck3/duck30034.png b/assets/images/runner/duck3/duck30034.png new file mode 100644 index 0000000..d04f54b Binary files /dev/null and b/assets/images/runner/duck3/duck30034.png differ diff --git a/assets/images/runner/duck3/duck30035.png b/assets/images/runner/duck3/duck30035.png new file mode 100644 index 0000000..2af8014 Binary files /dev/null and b/assets/images/runner/duck3/duck30035.png differ diff --git a/assets/images/runner/duck3/duck30036.png b/assets/images/runner/duck3/duck30036.png new file mode 100644 index 0000000..187b13e Binary files /dev/null and b/assets/images/runner/duck3/duck30036.png differ diff --git a/assets/images/runner/duck3/duck30037.png b/assets/images/runner/duck3/duck30037.png new file mode 100644 index 0000000..9db2539 Binary files /dev/null and b/assets/images/runner/duck3/duck30037.png differ diff --git a/assets/images/runner/duck3/duck30038.png b/assets/images/runner/duck3/duck30038.png new file mode 100644 index 0000000..aa1d63f Binary files /dev/null and b/assets/images/runner/duck3/duck30038.png differ diff --git a/assets/images/runner/fall/fall0001.png b/assets/images/runner/fall/fall0001.png new file mode 100644 index 0000000..08c585a Binary files /dev/null and b/assets/images/runner/fall/fall0001.png differ diff --git a/assets/images/runner/fall/fall0002.png b/assets/images/runner/fall/fall0002.png new file mode 100644 index 0000000..245d42c Binary files /dev/null and b/assets/images/runner/fall/fall0002.png differ diff --git a/assets/images/runner/fall/fall0003.png b/assets/images/runner/fall/fall0003.png new file mode 100644 index 0000000..8141fb1 Binary files /dev/null and b/assets/images/runner/fall/fall0003.png differ diff --git a/assets/images/runner/fall/fall0004.png b/assets/images/runner/fall/fall0004.png new file mode 100644 index 0000000..be6f5b2 Binary files /dev/null and b/assets/images/runner/fall/fall0004.png differ diff --git a/assets/images/runner/fall/fall0005.png b/assets/images/runner/fall/fall0005.png new file mode 100644 index 0000000..da2a7eb Binary files /dev/null and b/assets/images/runner/fall/fall0005.png differ diff --git a/assets/images/runner/fall/fall0006.png b/assets/images/runner/fall/fall0006.png new file mode 100644 index 0000000..51b8542 Binary files /dev/null and b/assets/images/runner/fall/fall0006.png differ diff --git a/assets/images/runner/fall/fall0007.png b/assets/images/runner/fall/fall0007.png new file mode 100644 index 0000000..aa2f222 Binary files /dev/null and b/assets/images/runner/fall/fall0007.png differ diff --git a/assets/images/runner/fall/fall0008.png b/assets/images/runner/fall/fall0008.png new file mode 100644 index 0000000..7eea0b8 Binary files /dev/null and b/assets/images/runner/fall/fall0008.png differ diff --git a/assets/images/runner/fall/fall0009.png b/assets/images/runner/fall/fall0009.png new file mode 100644 index 0000000..a3b77cb Binary files /dev/null and b/assets/images/runner/fall/fall0009.png differ diff --git a/assets/images/runner/fall/fall0010.png b/assets/images/runner/fall/fall0010.png new file mode 100644 index 0000000..ca60699 Binary files /dev/null and b/assets/images/runner/fall/fall0010.png differ diff --git a/assets/images/runner/fall/fall0011.png b/assets/images/runner/fall/fall0011.png new file mode 100644 index 0000000..fec6dfa Binary files /dev/null and b/assets/images/runner/fall/fall0011.png differ diff --git a/assets/images/runner/fall/fall0012.png b/assets/images/runner/fall/fall0012.png new file mode 100644 index 0000000..254e269 Binary files /dev/null and b/assets/images/runner/fall/fall0012.png differ diff --git a/assets/images/runner/fall/fall0013.png b/assets/images/runner/fall/fall0013.png new file mode 100644 index 0000000..b0fb93f Binary files /dev/null and b/assets/images/runner/fall/fall0013.png differ diff --git a/assets/images/runner/fall/fall0014.png b/assets/images/runner/fall/fall0014.png new file mode 100644 index 0000000..3fc2cfd Binary files /dev/null and b/assets/images/runner/fall/fall0014.png differ diff --git a/assets/images/runner/fall/fall0015.png b/assets/images/runner/fall/fall0015.png new file mode 100644 index 0000000..2ef7e1c Binary files /dev/null and b/assets/images/runner/fall/fall0015.png differ diff --git a/assets/images/runner/fall/fall0016.png b/assets/images/runner/fall/fall0016.png new file mode 100644 index 0000000..9edcd0f Binary files /dev/null and b/assets/images/runner/fall/fall0016.png differ diff --git a/assets/images/runner/fall/fall0017.png b/assets/images/runner/fall/fall0017.png new file mode 100644 index 0000000..5e493d8 Binary files /dev/null and b/assets/images/runner/fall/fall0017.png differ diff --git a/assets/images/runner/fall/fall0018.png b/assets/images/runner/fall/fall0018.png new file mode 100644 index 0000000..9bb4181 Binary files /dev/null and b/assets/images/runner/fall/fall0018.png differ diff --git a/assets/images/runner/fall/fall0019.png b/assets/images/runner/fall/fall0019.png new file mode 100644 index 0000000..5fcbe86 Binary files /dev/null and b/assets/images/runner/fall/fall0019.png differ diff --git a/assets/images/runner/fall/fall0020.png b/assets/images/runner/fall/fall0020.png new file mode 100644 index 0000000..aea77c5 Binary files /dev/null and b/assets/images/runner/fall/fall0020.png differ diff --git a/assets/images/runner/hover1/hover10001.png b/assets/images/runner/hover1/hover10001.png new file mode 100644 index 0000000..4df2b77 Binary files /dev/null and b/assets/images/runner/hover1/hover10001.png differ diff --git a/assets/images/runner/hover1/hover10002.png b/assets/images/runner/hover1/hover10002.png new file mode 100644 index 0000000..2ec3795 Binary files /dev/null and b/assets/images/runner/hover1/hover10002.png differ diff --git a/assets/images/runner/hover1/hover10003.png b/assets/images/runner/hover1/hover10003.png new file mode 100644 index 0000000..2a3432e Binary files /dev/null and b/assets/images/runner/hover1/hover10003.png differ diff --git a/assets/images/runner/hover1/hover10004.png b/assets/images/runner/hover1/hover10004.png new file mode 100644 index 0000000..6909287 Binary files /dev/null and b/assets/images/runner/hover1/hover10004.png differ diff --git a/assets/images/runner/hover1/hover10005.png b/assets/images/runner/hover1/hover10005.png new file mode 100644 index 0000000..3ef7e99 Binary files /dev/null and b/assets/images/runner/hover1/hover10005.png differ diff --git a/assets/images/runner/hover1/hover10006.png b/assets/images/runner/hover1/hover10006.png new file mode 100644 index 0000000..5a1be8f Binary files /dev/null and b/assets/images/runner/hover1/hover10006.png differ diff --git a/assets/images/runner/hover1/hover10007.png b/assets/images/runner/hover1/hover10007.png new file mode 100644 index 0000000..7d1e0c0 Binary files /dev/null and b/assets/images/runner/hover1/hover10007.png differ diff --git a/assets/images/runner/hover1/hover10008.png b/assets/images/runner/hover1/hover10008.png new file mode 100644 index 0000000..c6dde1e Binary files /dev/null and b/assets/images/runner/hover1/hover10008.png differ diff --git a/assets/images/runner/hover1/hover10009.png b/assets/images/runner/hover1/hover10009.png new file mode 100644 index 0000000..7f06082 Binary files /dev/null and b/assets/images/runner/hover1/hover10009.png differ diff --git a/assets/images/runner/hover1/hover10010.png b/assets/images/runner/hover1/hover10010.png new file mode 100644 index 0000000..bed2da8 Binary files /dev/null and b/assets/images/runner/hover1/hover10010.png differ diff --git a/assets/images/runner/hover1/hover10011.png b/assets/images/runner/hover1/hover10011.png new file mode 100644 index 0000000..b6b88c0 Binary files /dev/null and b/assets/images/runner/hover1/hover10011.png differ diff --git a/assets/images/runner/hover1/hover10012.png b/assets/images/runner/hover1/hover10012.png new file mode 100644 index 0000000..08afa67 Binary files /dev/null and b/assets/images/runner/hover1/hover10012.png differ diff --git a/assets/images/runner/hover1/hover10013.png b/assets/images/runner/hover1/hover10013.png new file mode 100644 index 0000000..6cf986d Binary files /dev/null and b/assets/images/runner/hover1/hover10013.png differ diff --git a/assets/images/runner/hover1/hover10014.png b/assets/images/runner/hover1/hover10014.png new file mode 100644 index 0000000..abb0e2e Binary files /dev/null and b/assets/images/runner/hover1/hover10014.png differ diff --git a/assets/images/runner/hover1/hover10015.png b/assets/images/runner/hover1/hover10015.png new file mode 100644 index 0000000..f26ac69 Binary files /dev/null and b/assets/images/runner/hover1/hover10015.png differ diff --git a/assets/images/runner/hover1/hover10016.png b/assets/images/runner/hover1/hover10016.png new file mode 100644 index 0000000..7e722b5 Binary files /dev/null and b/assets/images/runner/hover1/hover10016.png differ diff --git a/assets/images/runner/hover1/hover10017.png b/assets/images/runner/hover1/hover10017.png new file mode 100644 index 0000000..5314f6a Binary files /dev/null and b/assets/images/runner/hover1/hover10017.png differ diff --git a/assets/images/runner/hover1/hover10018.png b/assets/images/runner/hover1/hover10018.png new file mode 100644 index 0000000..9a7cd1c Binary files /dev/null and b/assets/images/runner/hover1/hover10018.png differ diff --git a/assets/images/runner/hover1/hover10019.png b/assets/images/runner/hover1/hover10019.png new file mode 100644 index 0000000..4dea000 Binary files /dev/null and b/assets/images/runner/hover1/hover10019.png differ diff --git a/assets/images/runner/hover1/hover10020.png b/assets/images/runner/hover1/hover10020.png new file mode 100644 index 0000000..8952481 Binary files /dev/null and b/assets/images/runner/hover1/hover10020.png differ diff --git a/assets/images/runner/hover1/hover10021.png b/assets/images/runner/hover1/hover10021.png new file mode 100644 index 0000000..e65eca2 Binary files /dev/null and b/assets/images/runner/hover1/hover10021.png differ diff --git a/assets/images/runner/hover1/hover10022.png b/assets/images/runner/hover1/hover10022.png new file mode 100644 index 0000000..399af92 Binary files /dev/null and b/assets/images/runner/hover1/hover10022.png differ diff --git a/assets/images/runner/hover1/hover10023.png b/assets/images/runner/hover1/hover10023.png new file mode 100644 index 0000000..80d8bee Binary files /dev/null and b/assets/images/runner/hover1/hover10023.png differ diff --git a/assets/images/runner/hover1/hover10024.png b/assets/images/runner/hover1/hover10024.png new file mode 100644 index 0000000..86c91d1 Binary files /dev/null and b/assets/images/runner/hover1/hover10024.png differ diff --git a/assets/images/runner/hover1/hover10025.png b/assets/images/runner/hover1/hover10025.png new file mode 100644 index 0000000..0493583 Binary files /dev/null and b/assets/images/runner/hover1/hover10025.png differ diff --git a/assets/images/runner/hover1/hover10026.png b/assets/images/runner/hover1/hover10026.png new file mode 100644 index 0000000..e8793ff Binary files /dev/null and b/assets/images/runner/hover1/hover10026.png differ diff --git a/assets/images/runner/hover1/hover10027.png b/assets/images/runner/hover1/hover10027.png new file mode 100644 index 0000000..7ea2b66 Binary files /dev/null and b/assets/images/runner/hover1/hover10027.png differ diff --git a/assets/images/runner/hover1/hover10028.png b/assets/images/runner/hover1/hover10028.png new file mode 100644 index 0000000..f0a8307 Binary files /dev/null and b/assets/images/runner/hover1/hover10028.png differ diff --git a/assets/images/runner/hover1/hover10029.png b/assets/images/runner/hover1/hover10029.png new file mode 100644 index 0000000..63a15bb Binary files /dev/null and b/assets/images/runner/hover1/hover10029.png differ diff --git a/assets/images/runner/hover1/hover10030.png b/assets/images/runner/hover1/hover10030.png new file mode 100644 index 0000000..f5e3eb8 Binary files /dev/null and b/assets/images/runner/hover1/hover10030.png differ diff --git a/assets/images/runner/hover1/hover10031.png b/assets/images/runner/hover1/hover10031.png new file mode 100644 index 0000000..35b1636 Binary files /dev/null and b/assets/images/runner/hover1/hover10031.png differ diff --git a/assets/images/runner/hover1/hover10032.png b/assets/images/runner/hover1/hover10032.png new file mode 100644 index 0000000..4b1591a Binary files /dev/null and b/assets/images/runner/hover1/hover10032.png differ diff --git a/assets/images/runner/hover1/hover10033.png b/assets/images/runner/hover1/hover10033.png new file mode 100644 index 0000000..f7627b7 Binary files /dev/null and b/assets/images/runner/hover1/hover10033.png differ diff --git a/assets/images/runner/hover1/hover10034.png b/assets/images/runner/hover1/hover10034.png new file mode 100644 index 0000000..2b36f23 Binary files /dev/null and b/assets/images/runner/hover1/hover10034.png differ diff --git a/assets/images/runner/hover1/hover10035.png b/assets/images/runner/hover1/hover10035.png new file mode 100644 index 0000000..30b9db3 Binary files /dev/null and b/assets/images/runner/hover1/hover10035.png differ diff --git a/assets/images/runner/hover1/hover10036.png b/assets/images/runner/hover1/hover10036.png new file mode 100644 index 0000000..ff88bcc Binary files /dev/null and b/assets/images/runner/hover1/hover10036.png differ diff --git a/assets/images/runner/hover1/hover10037.png b/assets/images/runner/hover1/hover10037.png new file mode 100644 index 0000000..b293f77 Binary files /dev/null and b/assets/images/runner/hover1/hover10037.png differ diff --git a/assets/images/runner/hover1/hover10038.png b/assets/images/runner/hover1/hover10038.png new file mode 100644 index 0000000..9e219df Binary files /dev/null and b/assets/images/runner/hover1/hover10038.png differ diff --git a/assets/images/runner/hover1/hover10039.png b/assets/images/runner/hover1/hover10039.png new file mode 100644 index 0000000..3558b6b Binary files /dev/null and b/assets/images/runner/hover1/hover10039.png differ diff --git a/assets/images/runner/hover1/hover10040.png b/assets/images/runner/hover1/hover10040.png new file mode 100644 index 0000000..d60a29f Binary files /dev/null and b/assets/images/runner/hover1/hover10040.png differ diff --git a/assets/images/runner/hover1/hover10041.png b/assets/images/runner/hover1/hover10041.png new file mode 100644 index 0000000..7d97bad Binary files /dev/null and b/assets/images/runner/hover1/hover10041.png differ diff --git a/assets/images/runner/hover1/hover10042.png b/assets/images/runner/hover1/hover10042.png new file mode 100644 index 0000000..27a8b43 Binary files /dev/null and b/assets/images/runner/hover1/hover10042.png differ diff --git a/assets/images/runner/hover1/hover10043.png b/assets/images/runner/hover1/hover10043.png new file mode 100644 index 0000000..c89f515 Binary files /dev/null and b/assets/images/runner/hover1/hover10043.png differ diff --git a/assets/images/runner/hover1/hover10044.png b/assets/images/runner/hover1/hover10044.png new file mode 100644 index 0000000..abe2bf1 Binary files /dev/null and b/assets/images/runner/hover1/hover10044.png differ diff --git a/assets/images/runner/hover2/hover20001.png b/assets/images/runner/hover2/hover20001.png new file mode 100644 index 0000000..2256525 Binary files /dev/null and b/assets/images/runner/hover2/hover20001.png differ diff --git a/assets/images/runner/hover2/hover20002.png b/assets/images/runner/hover2/hover20002.png new file mode 100644 index 0000000..c78f543 Binary files /dev/null and b/assets/images/runner/hover2/hover20002.png differ diff --git a/assets/images/runner/hover2/hover20003.png b/assets/images/runner/hover2/hover20003.png new file mode 100644 index 0000000..0d9862c Binary files /dev/null and b/assets/images/runner/hover2/hover20003.png differ diff --git a/assets/images/runner/hover2/hover20004.png b/assets/images/runner/hover2/hover20004.png new file mode 100644 index 0000000..12cc6be Binary files /dev/null and b/assets/images/runner/hover2/hover20004.png differ diff --git a/assets/images/runner/hover2/hover20005.png b/assets/images/runner/hover2/hover20005.png new file mode 100644 index 0000000..62c94ea Binary files /dev/null and b/assets/images/runner/hover2/hover20005.png differ diff --git a/assets/images/runner/hover2/hover20006.png b/assets/images/runner/hover2/hover20006.png new file mode 100644 index 0000000..6548b58 Binary files /dev/null and b/assets/images/runner/hover2/hover20006.png differ diff --git a/assets/images/runner/hover2/hover20007.png b/assets/images/runner/hover2/hover20007.png new file mode 100644 index 0000000..6724831 Binary files /dev/null and b/assets/images/runner/hover2/hover20007.png differ diff --git a/assets/images/runner/hover2/hover20008.png b/assets/images/runner/hover2/hover20008.png new file mode 100644 index 0000000..b54a782 Binary files /dev/null and b/assets/images/runner/hover2/hover20008.png differ diff --git a/assets/images/runner/hover2/hover20009.png b/assets/images/runner/hover2/hover20009.png new file mode 100644 index 0000000..894a2ba Binary files /dev/null and b/assets/images/runner/hover2/hover20009.png differ diff --git a/assets/images/runner/hover2/hover20010.png b/assets/images/runner/hover2/hover20010.png new file mode 100644 index 0000000..85f45d2 Binary files /dev/null and b/assets/images/runner/hover2/hover20010.png differ diff --git a/assets/images/runner/hover2/hover20011.png b/assets/images/runner/hover2/hover20011.png new file mode 100644 index 0000000..95b21d1 Binary files /dev/null and b/assets/images/runner/hover2/hover20011.png differ diff --git a/assets/images/runner/hover2/hover20012.png b/assets/images/runner/hover2/hover20012.png new file mode 100644 index 0000000..6485728 Binary files /dev/null and b/assets/images/runner/hover2/hover20012.png differ diff --git a/assets/images/runner/hover2/hover20013.png b/assets/images/runner/hover2/hover20013.png new file mode 100644 index 0000000..b03bde2 Binary files /dev/null and b/assets/images/runner/hover2/hover20013.png differ diff --git a/assets/images/runner/hover2/hover20014.png b/assets/images/runner/hover2/hover20014.png new file mode 100644 index 0000000..879fc99 Binary files /dev/null and b/assets/images/runner/hover2/hover20014.png differ diff --git a/assets/images/runner/hover2/hover20015.png b/assets/images/runner/hover2/hover20015.png new file mode 100644 index 0000000..b230e77 Binary files /dev/null and b/assets/images/runner/hover2/hover20015.png differ diff --git a/assets/images/runner/hover2/hover20016.png b/assets/images/runner/hover2/hover20016.png new file mode 100644 index 0000000..1e45974 Binary files /dev/null and b/assets/images/runner/hover2/hover20016.png differ diff --git a/assets/images/runner/hover2/hover20017.png b/assets/images/runner/hover2/hover20017.png new file mode 100644 index 0000000..f7425df Binary files /dev/null and b/assets/images/runner/hover2/hover20017.png differ diff --git a/assets/images/runner/hover2/hover20018.png b/assets/images/runner/hover2/hover20018.png new file mode 100644 index 0000000..36411a8 Binary files /dev/null and b/assets/images/runner/hover2/hover20018.png differ diff --git a/assets/images/runner/hover2/hover20019.png b/assets/images/runner/hover2/hover20019.png new file mode 100644 index 0000000..36c3513 Binary files /dev/null and b/assets/images/runner/hover2/hover20019.png differ diff --git a/assets/images/runner/hover2/hover20020.png b/assets/images/runner/hover2/hover20020.png new file mode 100644 index 0000000..cf43cc8 Binary files /dev/null and b/assets/images/runner/hover2/hover20020.png differ diff --git a/assets/images/runner/hover2/hover20021.png b/assets/images/runner/hover2/hover20021.png new file mode 100644 index 0000000..8ed6e2a Binary files /dev/null and b/assets/images/runner/hover2/hover20021.png differ diff --git a/assets/images/runner/hover2/hover20022.png b/assets/images/runner/hover2/hover20022.png new file mode 100644 index 0000000..2ce34d3 Binary files /dev/null and b/assets/images/runner/hover2/hover20022.png differ diff --git a/assets/images/runner/hover2/hover20023.png b/assets/images/runner/hover2/hover20023.png new file mode 100644 index 0000000..a35adb0 Binary files /dev/null and b/assets/images/runner/hover2/hover20023.png differ diff --git a/assets/images/runner/hover2/hover20024.png b/assets/images/runner/hover2/hover20024.png new file mode 100644 index 0000000..ed5831e Binary files /dev/null and b/assets/images/runner/hover2/hover20024.png differ diff --git a/assets/images/runner/hover2/hover20025.png b/assets/images/runner/hover2/hover20025.png new file mode 100644 index 0000000..539b098 Binary files /dev/null and b/assets/images/runner/hover2/hover20025.png differ diff --git a/assets/images/runner/hover2/hover20026.png b/assets/images/runner/hover2/hover20026.png new file mode 100644 index 0000000..a21426f Binary files /dev/null and b/assets/images/runner/hover2/hover20026.png differ diff --git a/assets/images/runner/hover2/hover20027.png b/assets/images/runner/hover2/hover20027.png new file mode 100644 index 0000000..9773681 Binary files /dev/null and b/assets/images/runner/hover2/hover20027.png differ diff --git a/assets/images/runner/hover2/hover20028.png b/assets/images/runner/hover2/hover20028.png new file mode 100644 index 0000000..b0a4da5 Binary files /dev/null and b/assets/images/runner/hover2/hover20028.png differ diff --git a/assets/images/runner/hover2/hover20029.png b/assets/images/runner/hover2/hover20029.png new file mode 100644 index 0000000..7ab7d8c Binary files /dev/null and b/assets/images/runner/hover2/hover20029.png differ diff --git a/assets/images/runner/hover2/hover20030.png b/assets/images/runner/hover2/hover20030.png new file mode 100644 index 0000000..71ab2b1 Binary files /dev/null and b/assets/images/runner/hover2/hover20030.png differ diff --git a/assets/images/runner/hover2/hover20031.png b/assets/images/runner/hover2/hover20031.png new file mode 100644 index 0000000..170df9f Binary files /dev/null and b/assets/images/runner/hover2/hover20031.png differ diff --git a/assets/images/runner/hover2/hover20032.png b/assets/images/runner/hover2/hover20032.png new file mode 100644 index 0000000..0605cfd Binary files /dev/null and b/assets/images/runner/hover2/hover20032.png differ diff --git a/assets/images/runner/hover2/hover20033.png b/assets/images/runner/hover2/hover20033.png new file mode 100644 index 0000000..841ad57 Binary files /dev/null and b/assets/images/runner/hover2/hover20033.png differ diff --git a/assets/images/runner/hover2/hover20034.png b/assets/images/runner/hover2/hover20034.png new file mode 100644 index 0000000..6938e54 Binary files /dev/null and b/assets/images/runner/hover2/hover20034.png differ diff --git a/assets/images/runner/hover2/hover20035.png b/assets/images/runner/hover2/hover20035.png new file mode 100644 index 0000000..90cbfa5 Binary files /dev/null and b/assets/images/runner/hover2/hover20035.png differ diff --git a/assets/images/runner/hover2/hover20036.png b/assets/images/runner/hover2/hover20036.png new file mode 100644 index 0000000..5da8d94 Binary files /dev/null and b/assets/images/runner/hover2/hover20036.png differ diff --git a/assets/images/runner/hover2/hover20037.png b/assets/images/runner/hover2/hover20037.png new file mode 100644 index 0000000..433c6ce Binary files /dev/null and b/assets/images/runner/hover2/hover20037.png differ diff --git a/assets/images/runner/hover2/hover20038.png b/assets/images/runner/hover2/hover20038.png new file mode 100644 index 0000000..1cf7a46 Binary files /dev/null and b/assets/images/runner/hover2/hover20038.png differ diff --git a/assets/images/runner/hover2/hover20039.png b/assets/images/runner/hover2/hover20039.png new file mode 100644 index 0000000..65cd0dc Binary files /dev/null and b/assets/images/runner/hover2/hover20039.png differ diff --git a/assets/images/runner/hover2/hover20040.png b/assets/images/runner/hover2/hover20040.png new file mode 100644 index 0000000..e4d02d0 Binary files /dev/null and b/assets/images/runner/hover2/hover20040.png differ diff --git a/assets/images/runner/hover2/hover20041.png b/assets/images/runner/hover2/hover20041.png new file mode 100644 index 0000000..40e2844 Binary files /dev/null and b/assets/images/runner/hover2/hover20041.png differ diff --git a/assets/images/runner/hover2/hover20042.png b/assets/images/runner/hover2/hover20042.png new file mode 100644 index 0000000..c0d94e0 Binary files /dev/null and b/assets/images/runner/hover2/hover20042.png differ diff --git a/assets/images/runner/hover2/hover20043.png b/assets/images/runner/hover2/hover20043.png new file mode 100644 index 0000000..553b3ac Binary files /dev/null and b/assets/images/runner/hover2/hover20043.png differ diff --git a/assets/images/runner/hover2/hover20044.png b/assets/images/runner/hover2/hover20044.png new file mode 100644 index 0000000..aee0d6c Binary files /dev/null and b/assets/images/runner/hover2/hover20044.png differ diff --git a/assets/images/runner/hover3/hover30001.png b/assets/images/runner/hover3/hover30001.png new file mode 100644 index 0000000..10d3630 Binary files /dev/null and b/assets/images/runner/hover3/hover30001.png differ diff --git a/assets/images/runner/hover3/hover30002.png b/assets/images/runner/hover3/hover30002.png new file mode 100644 index 0000000..82d97ad Binary files /dev/null and b/assets/images/runner/hover3/hover30002.png differ diff --git a/assets/images/runner/hover3/hover30003.png b/assets/images/runner/hover3/hover30003.png new file mode 100644 index 0000000..f50b562 Binary files /dev/null and b/assets/images/runner/hover3/hover30003.png differ diff --git a/assets/images/runner/hover3/hover30004.png b/assets/images/runner/hover3/hover30004.png new file mode 100644 index 0000000..38fd1ef Binary files /dev/null and b/assets/images/runner/hover3/hover30004.png differ diff --git a/assets/images/runner/hover3/hover30005.png b/assets/images/runner/hover3/hover30005.png new file mode 100644 index 0000000..a93835f Binary files /dev/null and b/assets/images/runner/hover3/hover30005.png differ diff --git a/assets/images/runner/hover3/hover30006.png b/assets/images/runner/hover3/hover30006.png new file mode 100644 index 0000000..1215566 Binary files /dev/null and b/assets/images/runner/hover3/hover30006.png differ diff --git a/assets/images/runner/hover3/hover30007.png b/assets/images/runner/hover3/hover30007.png new file mode 100644 index 0000000..eb7e760 Binary files /dev/null and b/assets/images/runner/hover3/hover30007.png differ diff --git a/assets/images/runner/hover3/hover30008.png b/assets/images/runner/hover3/hover30008.png new file mode 100644 index 0000000..8d3a6c5 Binary files /dev/null and b/assets/images/runner/hover3/hover30008.png differ diff --git a/assets/images/runner/hover3/hover30009.png b/assets/images/runner/hover3/hover30009.png new file mode 100644 index 0000000..ead2c1c Binary files /dev/null and b/assets/images/runner/hover3/hover30009.png differ diff --git a/assets/images/runner/hover3/hover30010.png b/assets/images/runner/hover3/hover30010.png new file mode 100644 index 0000000..aac2dd1 Binary files /dev/null and b/assets/images/runner/hover3/hover30010.png differ diff --git a/assets/images/runner/hover3/hover30011.png b/assets/images/runner/hover3/hover30011.png new file mode 100644 index 0000000..b7a811b Binary files /dev/null and b/assets/images/runner/hover3/hover30011.png differ diff --git a/assets/images/runner/hover3/hover30012.png b/assets/images/runner/hover3/hover30012.png new file mode 100644 index 0000000..8b51801 Binary files /dev/null and b/assets/images/runner/hover3/hover30012.png differ diff --git a/assets/images/runner/hover3/hover30013.png b/assets/images/runner/hover3/hover30013.png new file mode 100644 index 0000000..6902139 Binary files /dev/null and b/assets/images/runner/hover3/hover30013.png differ diff --git a/assets/images/runner/hover3/hover30014.png b/assets/images/runner/hover3/hover30014.png new file mode 100644 index 0000000..af13e92 Binary files /dev/null and b/assets/images/runner/hover3/hover30014.png differ diff --git a/assets/images/runner/hover3/hover30015.png b/assets/images/runner/hover3/hover30015.png new file mode 100644 index 0000000..3191473 Binary files /dev/null and b/assets/images/runner/hover3/hover30015.png differ diff --git a/assets/images/runner/hover3/hover30016.png b/assets/images/runner/hover3/hover30016.png new file mode 100644 index 0000000..24ad1ad Binary files /dev/null and b/assets/images/runner/hover3/hover30016.png differ diff --git a/assets/images/runner/hover3/hover30017.png b/assets/images/runner/hover3/hover30017.png new file mode 100644 index 0000000..dd572f6 Binary files /dev/null and b/assets/images/runner/hover3/hover30017.png differ diff --git a/assets/images/runner/hover3/hover30018.png b/assets/images/runner/hover3/hover30018.png new file mode 100644 index 0000000..f925148 Binary files /dev/null and b/assets/images/runner/hover3/hover30018.png differ diff --git a/assets/images/runner/hover3/hover30019.png b/assets/images/runner/hover3/hover30019.png new file mode 100644 index 0000000..4c90de4 Binary files /dev/null and b/assets/images/runner/hover3/hover30019.png differ diff --git a/assets/images/runner/hover3/hover30020.png b/assets/images/runner/hover3/hover30020.png new file mode 100644 index 0000000..92e2064 Binary files /dev/null and b/assets/images/runner/hover3/hover30020.png differ diff --git a/assets/images/runner/hover3/hover30021.png b/assets/images/runner/hover3/hover30021.png new file mode 100644 index 0000000..bdb9a7c Binary files /dev/null and b/assets/images/runner/hover3/hover30021.png differ diff --git a/assets/images/runner/hover3/hover30022.png b/assets/images/runner/hover3/hover30022.png new file mode 100644 index 0000000..1255fb6 Binary files /dev/null and b/assets/images/runner/hover3/hover30022.png differ diff --git a/assets/images/runner/hover3/hover30023.png b/assets/images/runner/hover3/hover30023.png new file mode 100644 index 0000000..b706361 Binary files /dev/null and b/assets/images/runner/hover3/hover30023.png differ diff --git a/assets/images/runner/hover3/hover30024.png b/assets/images/runner/hover3/hover30024.png new file mode 100644 index 0000000..0ba4d82 Binary files /dev/null and b/assets/images/runner/hover3/hover30024.png differ diff --git a/assets/images/runner/hover3/hover30025.png b/assets/images/runner/hover3/hover30025.png new file mode 100644 index 0000000..3651a1f Binary files /dev/null and b/assets/images/runner/hover3/hover30025.png differ diff --git a/assets/images/runner/hover3/hover30026.png b/assets/images/runner/hover3/hover30026.png new file mode 100644 index 0000000..7bd9cd6 Binary files /dev/null and b/assets/images/runner/hover3/hover30026.png differ diff --git a/assets/images/runner/hover3/hover30027.png b/assets/images/runner/hover3/hover30027.png new file mode 100644 index 0000000..5b8ea33 Binary files /dev/null and b/assets/images/runner/hover3/hover30027.png differ diff --git a/assets/images/runner/hover3/hover30028.png b/assets/images/runner/hover3/hover30028.png new file mode 100644 index 0000000..8dad83a Binary files /dev/null and b/assets/images/runner/hover3/hover30028.png differ diff --git a/assets/images/runner/hover3/hover30029.png b/assets/images/runner/hover3/hover30029.png new file mode 100644 index 0000000..edf4783 Binary files /dev/null and b/assets/images/runner/hover3/hover30029.png differ diff --git a/assets/images/runner/hover3/hover30030.png b/assets/images/runner/hover3/hover30030.png new file mode 100644 index 0000000..124df5c Binary files /dev/null and b/assets/images/runner/hover3/hover30030.png differ diff --git a/assets/images/runner/hover3/hover30031.png b/assets/images/runner/hover3/hover30031.png new file mode 100644 index 0000000..23ea7ca Binary files /dev/null and b/assets/images/runner/hover3/hover30031.png differ diff --git a/assets/images/runner/hover3/hover30032.png b/assets/images/runner/hover3/hover30032.png new file mode 100644 index 0000000..cd42c49 Binary files /dev/null and b/assets/images/runner/hover3/hover30032.png differ diff --git a/assets/images/runner/hover3/hover30033.png b/assets/images/runner/hover3/hover30033.png new file mode 100644 index 0000000..0b97db7 Binary files /dev/null and b/assets/images/runner/hover3/hover30033.png differ diff --git a/assets/images/runner/hover3/hover30034.png b/assets/images/runner/hover3/hover30034.png new file mode 100644 index 0000000..bc4dcef Binary files /dev/null and b/assets/images/runner/hover3/hover30034.png differ diff --git a/assets/images/runner/hover3/hover30035.png b/assets/images/runner/hover3/hover30035.png new file mode 100644 index 0000000..4193aa6 Binary files /dev/null and b/assets/images/runner/hover3/hover30035.png differ diff --git a/assets/images/runner/hover3/hover30036.png b/assets/images/runner/hover3/hover30036.png new file mode 100644 index 0000000..588759c Binary files /dev/null and b/assets/images/runner/hover3/hover30036.png differ diff --git a/assets/images/runner/hover3/hover30037.png b/assets/images/runner/hover3/hover30037.png new file mode 100644 index 0000000..6fe42fa Binary files /dev/null and b/assets/images/runner/hover3/hover30037.png differ diff --git a/assets/images/runner/hover3/hover30038.png b/assets/images/runner/hover3/hover30038.png new file mode 100644 index 0000000..ba9dc5d Binary files /dev/null and b/assets/images/runner/hover3/hover30038.png differ diff --git a/assets/images/runner/hover3/hover30039.png b/assets/images/runner/hover3/hover30039.png new file mode 100644 index 0000000..b93ef59 Binary files /dev/null and b/assets/images/runner/hover3/hover30039.png differ diff --git a/assets/images/runner/hover3/hover30040.png b/assets/images/runner/hover3/hover30040.png new file mode 100644 index 0000000..dd77df8 Binary files /dev/null and b/assets/images/runner/hover3/hover30040.png differ diff --git a/assets/images/runner/hover3/hover30041.png b/assets/images/runner/hover3/hover30041.png new file mode 100644 index 0000000..a121143 Binary files /dev/null and b/assets/images/runner/hover3/hover30041.png differ diff --git a/assets/images/runner/hover3/hover30042.png b/assets/images/runner/hover3/hover30042.png new file mode 100644 index 0000000..6f4a9cb Binary files /dev/null and b/assets/images/runner/hover3/hover30042.png differ diff --git a/assets/images/runner/hover3/hover30043.png b/assets/images/runner/hover3/hover30043.png new file mode 100644 index 0000000..cee0400 Binary files /dev/null and b/assets/images/runner/hover3/hover30043.png differ diff --git a/assets/images/runner/hover3/hover30044.png b/assets/images/runner/hover3/hover30044.png new file mode 100644 index 0000000..71a4106 Binary files /dev/null and b/assets/images/runner/hover3/hover30044.png differ diff --git a/assets/images/runner/jump/jump0001.png b/assets/images/runner/jump/jump0001.png new file mode 100644 index 0000000..f4652cd Binary files /dev/null and b/assets/images/runner/jump/jump0001.png differ diff --git a/assets/images/runner/jump/jump0002.png b/assets/images/runner/jump/jump0002.png new file mode 100644 index 0000000..c6d9ccf Binary files /dev/null and b/assets/images/runner/jump/jump0002.png differ diff --git a/assets/images/runner/jump/jump0003.png b/assets/images/runner/jump/jump0003.png new file mode 100644 index 0000000..5016943 Binary files /dev/null and b/assets/images/runner/jump/jump0003.png differ diff --git a/assets/images/runner/jump/jump0004.png b/assets/images/runner/jump/jump0004.png new file mode 100644 index 0000000..971c5fb Binary files /dev/null and b/assets/images/runner/jump/jump0004.png differ diff --git a/assets/images/runner/jump/jump0005.png b/assets/images/runner/jump/jump0005.png new file mode 100644 index 0000000..8eb9765 Binary files /dev/null and b/assets/images/runner/jump/jump0005.png differ diff --git a/assets/images/runner/jump/jump0006.png b/assets/images/runner/jump/jump0006.png new file mode 100644 index 0000000..4c66d17 Binary files /dev/null and b/assets/images/runner/jump/jump0006.png differ diff --git a/assets/images/runner/run/run0001.png b/assets/images/runner/run/run0001.png new file mode 100644 index 0000000..31b253c Binary files /dev/null and b/assets/images/runner/run/run0001.png differ diff --git a/assets/images/runner/run/run0002.png b/assets/images/runner/run/run0002.png new file mode 100644 index 0000000..f8b77c4 Binary files /dev/null and b/assets/images/runner/run/run0002.png differ diff --git a/assets/images/runner/run/run0003.png b/assets/images/runner/run/run0003.png new file mode 100644 index 0000000..30f44b7 Binary files /dev/null and b/assets/images/runner/run/run0003.png differ diff --git a/assets/images/runner/run/run0004.png b/assets/images/runner/run/run0004.png new file mode 100644 index 0000000..c7a5916 Binary files /dev/null and b/assets/images/runner/run/run0004.png differ diff --git a/assets/images/runner/run/run0005.png b/assets/images/runner/run/run0005.png new file mode 100644 index 0000000..3dd8fb9 Binary files /dev/null and b/assets/images/runner/run/run0005.png differ diff --git a/assets/images/runner/run/run0006.png b/assets/images/runner/run/run0006.png new file mode 100644 index 0000000..e392892 Binary files /dev/null and b/assets/images/runner/run/run0006.png differ diff --git a/assets/images/runner/run/run0007.png b/assets/images/runner/run/run0007.png new file mode 100644 index 0000000..4b2db56 Binary files /dev/null and b/assets/images/runner/run/run0007.png differ diff --git a/assets/images/runner/run/run0008.png b/assets/images/runner/run/run0008.png new file mode 100644 index 0000000..19bf41d Binary files /dev/null and b/assets/images/runner/run/run0008.png differ diff --git a/assets/images/runner/run/run0009.png b/assets/images/runner/run/run0009.png new file mode 100644 index 0000000..943f56a Binary files /dev/null and b/assets/images/runner/run/run0009.png differ diff --git a/assets/images/runner/run/run0010.png b/assets/images/runner/run/run0010.png new file mode 100644 index 0000000..da196d0 Binary files /dev/null and b/assets/images/runner/run/run0010.png differ diff --git a/assets/images/runner/run/run0011.png b/assets/images/runner/run/run0011.png new file mode 100644 index 0000000..7082d3c Binary files /dev/null and b/assets/images/runner/run/run0011.png differ diff --git a/assets/images/runner/run/run0012.png b/assets/images/runner/run/run0012.png new file mode 100644 index 0000000..858fcc5 Binary files /dev/null and b/assets/images/runner/run/run0012.png differ diff --git a/assets/images/runner/run/run0013.png b/assets/images/runner/run/run0013.png new file mode 100644 index 0000000..6a1c554 Binary files /dev/null and b/assets/images/runner/run/run0013.png differ diff --git a/assets/images/runner/run/run0014.png b/assets/images/runner/run/run0014.png new file mode 100644 index 0000000..720f7a5 Binary files /dev/null and b/assets/images/runner/run/run0014.png differ diff --git a/assets/images/runner/run/run0015.png b/assets/images/runner/run/run0015.png new file mode 100644 index 0000000..833741b Binary files /dev/null and b/assets/images/runner/run/run0015.png differ diff --git a/assets/images/runner/run/run0016.png b/assets/images/runner/run/run0016.png new file mode 100644 index 0000000..c39c550 Binary files /dev/null and b/assets/images/runner/run/run0016.png differ diff --git a/assets/images/runner/run/run0017.png b/assets/images/runner/run/run0017.png new file mode 100644 index 0000000..8a82c4d Binary files /dev/null and b/assets/images/runner/run/run0017.png differ diff --git a/assets/images/runner/run/run0018.png b/assets/images/runner/run/run0018.png new file mode 100644 index 0000000..491bd29 Binary files /dev/null and b/assets/images/runner/run/run0018.png differ diff --git a/assets/images/runner/run/run0019.png b/assets/images/runner/run/run0019.png new file mode 100644 index 0000000..49118cc Binary files /dev/null and b/assets/images/runner/run/run0019.png differ diff --git a/assets/images/runner/run/run0020.png b/assets/images/runner/run/run0020.png new file mode 100644 index 0000000..d69c32e Binary files /dev/null and b/assets/images/runner/run/run0020.png differ diff --git a/assets/images/runner/run/run0021.png b/assets/images/runner/run/run0021.png new file mode 100644 index 0000000..24f4abc Binary files /dev/null and b/assets/images/runner/run/run0021.png differ diff --git a/assets/images/runner/run/run0022.png b/assets/images/runner/run/run0022.png new file mode 100644 index 0000000..721049f Binary files /dev/null and b/assets/images/runner/run/run0022.png differ diff --git a/assets/images/runner/run/run0023.png b/assets/images/runner/run/run0023.png new file mode 100644 index 0000000..eb78522 Binary files /dev/null and b/assets/images/runner/run/run0023.png differ diff --git a/assets/images/runner/run/run0024.png b/assets/images/runner/run/run0024.png new file mode 100644 index 0000000..61f04c3 Binary files /dev/null and b/assets/images/runner/run/run0024.png differ diff --git a/assets/images/runner/run/run0025.png b/assets/images/runner/run/run0025.png new file mode 100644 index 0000000..c5c305d Binary files /dev/null and b/assets/images/runner/run/run0025.png differ diff --git a/assets/images/runner/run/run0026.png b/assets/images/runner/run/run0026.png new file mode 100644 index 0000000..9341b5d Binary files /dev/null and b/assets/images/runner/run/run0026.png differ diff --git a/assets/images/runner/run/run0027.png b/assets/images/runner/run/run0027.png new file mode 100644 index 0000000..c0c62c8 Binary files /dev/null and b/assets/images/runner/run/run0027.png differ diff --git a/assets/images/runner/run/run0028.png b/assets/images/runner/run/run0028.png new file mode 100644 index 0000000..b1e6e48 Binary files /dev/null and b/assets/images/runner/run/run0028.png differ diff --git a/assets/images/runner/run/run0029.png b/assets/images/runner/run/run0029.png new file mode 100644 index 0000000..cc09467 Binary files /dev/null and b/assets/images/runner/run/run0029.png differ diff --git a/assets/images/runner/run/run0030.png b/assets/images/runner/run/run0030.png new file mode 100644 index 0000000..8ccb023 Binary files /dev/null and b/assets/images/runner/run/run0030.png differ diff --git a/assets/images/runner/run/run0031.png b/assets/images/runner/run/run0031.png new file mode 100644 index 0000000..d3b35a3 Binary files /dev/null and b/assets/images/runner/run/run0031.png differ diff --git a/assets/images/runner/run/run0032.png b/assets/images/runner/run/run0032.png new file mode 100644 index 0000000..34a1c90 Binary files /dev/null and b/assets/images/runner/run/run0032.png differ diff --git a/assets/images/runner/run/run0033.png b/assets/images/runner/run/run0033.png new file mode 100644 index 0000000..260cfed Binary files /dev/null and b/assets/images/runner/run/run0033.png differ diff --git a/assets/images/runner/run/run0034.png b/assets/images/runner/run/run0034.png new file mode 100644 index 0000000..dee7731 Binary files /dev/null and b/assets/images/runner/run/run0034.png differ diff --git a/assets/images/runner/run/run0035.png b/assets/images/runner/run/run0035.png new file mode 100644 index 0000000..9bcca90 Binary files /dev/null and b/assets/images/runner/run/run0035.png differ diff --git a/assets/images/runner/run/run0036.png b/assets/images/runner/run/run0036.png new file mode 100644 index 0000000..7bfd42e Binary files /dev/null and b/assets/images/runner/run/run0036.png differ diff --git a/assets/images/runner/run/run0037.png b/assets/images/runner/run/run0037.png new file mode 100644 index 0000000..4839ba7 Binary files /dev/null and b/assets/images/runner/run/run0037.png differ diff --git a/assets/images/runner/run/run0038.png b/assets/images/runner/run/run0038.png new file mode 100644 index 0000000..6cb2dee Binary files /dev/null and b/assets/images/runner/run/run0038.png differ diff --git a/assets/images/runner/satellite/satellite0001.png b/assets/images/runner/satellite/satellite0001.png new file mode 100644 index 0000000..d556c4e Binary files /dev/null and b/assets/images/runner/satellite/satellite0001.png differ diff --git a/assets/images/runner/satellite/satellite0002.png b/assets/images/runner/satellite/satellite0002.png new file mode 100644 index 0000000..5e19d8d Binary files /dev/null and b/assets/images/runner/satellite/satellite0002.png differ diff --git a/assets/images/runner/satellite/satellite0003.png b/assets/images/runner/satellite/satellite0003.png new file mode 100644 index 0000000..d895be4 Binary files /dev/null and b/assets/images/runner/satellite/satellite0003.png differ diff --git a/assets/images/runner/satellite/satellite0004.png b/assets/images/runner/satellite/satellite0004.png new file mode 100644 index 0000000..39e1c19 Binary files /dev/null and b/assets/images/runner/satellite/satellite0004.png differ diff --git a/assets/images/runner/satellite/satellite0005.png b/assets/images/runner/satellite/satellite0005.png new file mode 100644 index 0000000..77ea48e Binary files /dev/null and b/assets/images/runner/satellite/satellite0005.png differ diff --git a/assets/images/runner/satellite/satellite0006.png b/assets/images/runner/satellite/satellite0006.png new file mode 100644 index 0000000..2028717 Binary files /dev/null and b/assets/images/runner/satellite/satellite0006.png differ diff --git a/assets/images/runner/satellite/satellite0007.png b/assets/images/runner/satellite/satellite0007.png new file mode 100644 index 0000000..c6b619e Binary files /dev/null and b/assets/images/runner/satellite/satellite0007.png differ diff --git a/assets/images/runner/satellite/satellite0008.png b/assets/images/runner/satellite/satellite0008.png new file mode 100644 index 0000000..4748cf2 Binary files /dev/null and b/assets/images/runner/satellite/satellite0008.png differ diff --git a/assets/images/runner/satellite/satellite0009.png b/assets/images/runner/satellite/satellite0009.png new file mode 100644 index 0000000..9adf90b Binary files /dev/null and b/assets/images/runner/satellite/satellite0009.png differ diff --git a/assets/images/runner/satellite/satellite0010.png b/assets/images/runner/satellite/satellite0010.png new file mode 100644 index 0000000..76e981a Binary files /dev/null and b/assets/images/runner/satellite/satellite0010.png differ diff --git a/assets/images/runner/satellite/satellite0011.png b/assets/images/runner/satellite/satellite0011.png new file mode 100644 index 0000000..b953fda Binary files /dev/null and b/assets/images/runner/satellite/satellite0011.png differ diff --git a/assets/images/runner/satellite/satellite0012.png b/assets/images/runner/satellite/satellite0012.png new file mode 100644 index 0000000..5114a9d Binary files /dev/null and b/assets/images/runner/satellite/satellite0012.png differ diff --git a/assets/images/runner/satellite/satellite0013.png b/assets/images/runner/satellite/satellite0013.png new file mode 100644 index 0000000..76a0d34 Binary files /dev/null and b/assets/images/runner/satellite/satellite0013.png differ diff --git a/assets/images/runner/satellite/satellite0014.png b/assets/images/runner/satellite/satellite0014.png new file mode 100644 index 0000000..efa241b Binary files /dev/null and b/assets/images/runner/satellite/satellite0014.png differ diff --git a/assets/images/runner/satellite/satellite0015.png b/assets/images/runner/satellite/satellite0015.png new file mode 100644 index 0000000..bdaffea Binary files /dev/null and b/assets/images/runner/satellite/satellite0015.png differ diff --git a/assets/images/runner/satellite/satellite0016.png b/assets/images/runner/satellite/satellite0016.png new file mode 100644 index 0000000..fa49ff3 Binary files /dev/null and b/assets/images/runner/satellite/satellite0016.png differ diff --git a/assets/images/runner/satellite/satellite0017.png b/assets/images/runner/satellite/satellite0017.png new file mode 100644 index 0000000..9d4e785 Binary files /dev/null and b/assets/images/runner/satellite/satellite0017.png differ diff --git a/assets/images/runner/satellite/satellite0018.png b/assets/images/runner/satellite/satellite0018.png new file mode 100644 index 0000000..eb80a50 Binary files /dev/null and b/assets/images/runner/satellite/satellite0018.png differ diff --git a/assets/images/runner/satellite/satellite0019.png b/assets/images/runner/satellite/satellite0019.png new file mode 100644 index 0000000..21a7f60 Binary files /dev/null and b/assets/images/runner/satellite/satellite0019.png differ diff --git a/assets/images/runner/satellite/satellite0020.png b/assets/images/runner/satellite/satellite0020.png new file mode 100644 index 0000000..0e99f70 Binary files /dev/null and b/assets/images/runner/satellite/satellite0020.png differ diff --git a/assets/images/runner/satellite/satellite0021.png b/assets/images/runner/satellite/satellite0021.png new file mode 100644 index 0000000..3be21ea Binary files /dev/null and b/assets/images/runner/satellite/satellite0021.png differ diff --git a/assets/images/runner/satellite/satellite0022.png b/assets/images/runner/satellite/satellite0022.png new file mode 100644 index 0000000..f352ce9 Binary files /dev/null and b/assets/images/runner/satellite/satellite0022.png differ diff --git a/assets/images/runner/satellite/satellite0023.png b/assets/images/runner/satellite/satellite0023.png new file mode 100644 index 0000000..eea87a2 Binary files /dev/null and b/assets/images/runner/satellite/satellite0023.png differ diff --git a/assets/images/runner/satellite/satellite0024.png b/assets/images/runner/satellite/satellite0024.png new file mode 100644 index 0000000..e4c813e Binary files /dev/null and b/assets/images/runner/satellite/satellite0024.png differ diff --git a/assets/images/runner/satellite/satellite0025.png b/assets/images/runner/satellite/satellite0025.png new file mode 100644 index 0000000..23ef00d Binary files /dev/null and b/assets/images/runner/satellite/satellite0025.png differ diff --git a/assets/images/runner/satellite/satellite0026.png b/assets/images/runner/satellite/satellite0026.png new file mode 100644 index 0000000..79aaf90 Binary files /dev/null and b/assets/images/runner/satellite/satellite0026.png differ diff --git a/assets/images/runner/satellite/satellite0027.png b/assets/images/runner/satellite/satellite0027.png new file mode 100644 index 0000000..c0dd041 Binary files /dev/null and b/assets/images/runner/satellite/satellite0027.png differ diff --git a/assets/images/runner/satellite/satellite0028.png b/assets/images/runner/satellite/satellite0028.png new file mode 100644 index 0000000..17845ed Binary files /dev/null and b/assets/images/runner/satellite/satellite0028.png differ diff --git a/assets/images/runner/satellite/satellite0029.png b/assets/images/runner/satellite/satellite0029.png new file mode 100644 index 0000000..0326266 Binary files /dev/null and b/assets/images/runner/satellite/satellite0029.png differ diff --git a/assets/images/runner/satellite/satellite0030.png b/assets/images/runner/satellite/satellite0030.png new file mode 100644 index 0000000..2936b0d Binary files /dev/null and b/assets/images/runner/satellite/satellite0030.png differ diff --git a/assets/images/runner/satellite/satellite0031.png b/assets/images/runner/satellite/satellite0031.png new file mode 100644 index 0000000..5c43d17 Binary files /dev/null and b/assets/images/runner/satellite/satellite0031.png differ diff --git a/assets/images/runner/satellite/satellite0032.png b/assets/images/runner/satellite/satellite0032.png new file mode 100644 index 0000000..d32b9c6 Binary files /dev/null and b/assets/images/runner/satellite/satellite0032.png differ diff --git a/assets/images/runner/satellite/satellite0033.png b/assets/images/runner/satellite/satellite0033.png new file mode 100644 index 0000000..2b6e522 Binary files /dev/null and b/assets/images/runner/satellite/satellite0033.png differ diff --git a/assets/images/runner/satellite/satellite0034.png b/assets/images/runner/satellite/satellite0034.png new file mode 100644 index 0000000..1b4967f Binary files /dev/null and b/assets/images/runner/satellite/satellite0034.png differ diff --git a/assets/images/runner/satellite/satellite0035.png b/assets/images/runner/satellite/satellite0035.png new file mode 100644 index 0000000..4a94c1b Binary files /dev/null and b/assets/images/runner/satellite/satellite0035.png differ diff --git a/assets/images/runner/satellite/satellite0036.png b/assets/images/runner/satellite/satellite0036.png new file mode 100644 index 0000000..d9cc4d7 Binary files /dev/null and b/assets/images/runner/satellite/satellite0036.png differ diff --git a/assets/images/runner/satellite/satellite0037.png b/assets/images/runner/satellite/satellite0037.png new file mode 100644 index 0000000..63773c0 Binary files /dev/null and b/assets/images/runner/satellite/satellite0037.png differ diff --git a/assets/images/runner/satellite/satellite0038.png b/assets/images/runner/satellite/satellite0038.png new file mode 100644 index 0000000..d118f6d Binary files /dev/null and b/assets/images/runner/satellite/satellite0038.png differ diff --git a/assets/images/wall/wall_0.png b/assets/images/wall/wall_0.png new file mode 100644 index 0000000..ed43562 Binary files /dev/null and b/assets/images/wall/wall_0.png differ diff --git a/assets/images/wall/wall_1.png b/assets/images/wall/wall_1.png new file mode 100644 index 0000000..750e411 Binary files /dev/null and b/assets/images/wall/wall_1.png differ diff --git a/assets/images/wall/wall_2.png b/assets/images/wall/wall_2.png new file mode 100644 index 0000000..02c8c5b Binary files /dev/null and b/assets/images/wall/wall_2.png differ diff --git a/assets/images/wall/wall_3.png b/assets/images/wall/wall_3.png new file mode 100644 index 0000000..6fde238 Binary files /dev/null and b/assets/images/wall/wall_3.png differ diff --git a/assets/images/wall/wall_4.png b/assets/images/wall/wall_4.png new file mode 100644 index 0000000..161390f Binary files /dev/null and b/assets/images/wall/wall_4.png differ diff --git a/assets/images/windows-0.png b/assets/images/windows-0.png new file mode 100644 index 0000000..cc6c79b Binary files /dev/null and b/assets/images/windows-0.png differ diff --git a/assets/images/windows-1.png b/assets/images/windows-1.png new file mode 100644 index 0000000..e4770df Binary files /dev/null and b/assets/images/windows-1.png differ diff --git a/assets/images/windows-2.png b/assets/images/windows-2.png new file mode 100644 index 0000000..cdb7823 Binary files /dev/null and b/assets/images/windows-2.png differ diff --git a/assets/images/windows-3.png b/assets/images/windows-3.png new file mode 100644 index 0000000..ebd12df Binary files /dev/null and b/assets/images/windows-3.png differ diff --git a/assets/images/windows-4.png b/assets/images/windows-4.png new file mode 100644 index 0000000..180a3a8 Binary files /dev/null and b/assets/images/windows-4.png differ diff --git a/assets/images/windows-5.png b/assets/images/windows-5.png new file mode 100644 index 0000000..e49bdbc Binary files /dev/null and b/assets/images/windows-5.png differ diff --git a/assets/images/windows-6.png b/assets/images/windows-6.png new file mode 100644 index 0000000..efb3b27 Binary files /dev/null and b/assets/images/windows-6.png differ diff --git a/assets/images/wire.png b/assets/images/wire.png deleted file mode 100644 index aa0979e..0000000 Binary files a/assets/images/wire.png and /dev/null differ diff --git a/assets/images/wire/wire_0.png b/assets/images/wire/wire_0.png new file mode 100644 index 0000000..42f45e3 Binary files /dev/null and b/assets/images/wire/wire_0.png differ diff --git a/assets/images/wire/wire_1.png b/assets/images/wire/wire_1.png new file mode 100644 index 0000000..42f45e3 Binary files /dev/null and b/assets/images/wire/wire_1.png differ diff --git a/assets/images/wire/wire_10.png b/assets/images/wire/wire_10.png new file mode 100644 index 0000000..c02be81 Binary files /dev/null and b/assets/images/wire/wire_10.png differ diff --git a/assets/images/wire/wire_11.png b/assets/images/wire/wire_11.png new file mode 100644 index 0000000..c02be81 Binary files /dev/null and b/assets/images/wire/wire_11.png differ diff --git a/assets/images/wire/wire_2.png b/assets/images/wire/wire_2.png new file mode 100644 index 0000000..9655a30 Binary files /dev/null and b/assets/images/wire/wire_2.png differ diff --git a/assets/images/wire/wire_3.png b/assets/images/wire/wire_3.png new file mode 100644 index 0000000..9655a30 Binary files /dev/null and b/assets/images/wire/wire_3.png differ diff --git a/assets/images/wire/wire_4.png b/assets/images/wire/wire_4.png new file mode 100644 index 0000000..39dc72a Binary files /dev/null and b/assets/images/wire/wire_4.png differ diff --git a/assets/images/wire/wire_5.png b/assets/images/wire/wire_5.png new file mode 100644 index 0000000..39dc72a Binary files /dev/null and b/assets/images/wire/wire_5.png differ diff --git a/assets/images/wire/wire_6.png b/assets/images/wire/wire_6.png new file mode 100644 index 0000000..b43ee25 Binary files /dev/null and b/assets/images/wire/wire_6.png differ diff --git a/assets/images/wire/wire_7.png b/assets/images/wire/wire_7.png new file mode 100644 index 0000000..b43ee25 Binary files /dev/null and b/assets/images/wire/wire_7.png differ diff --git a/assets/images/wire/wire_8.png b/assets/images/wire/wire_8.png new file mode 100644 index 0000000..ecafdc1 Binary files /dev/null and b/assets/images/wire/wire_8.png differ diff --git a/assets/images/wire/wire_9.png b/assets/images/wire/wire_9.png new file mode 100644 index 0000000..ecafdc1 Binary files /dev/null and b/assets/images/wire/wire_9.png differ diff --git a/flutter_01.sksl.json b/flutter_01.sksl.json new file mode 100644 index 0000000..58da1dc --- /dev/null +++ b/flutter_01.sksl.json @@ -0,0 +1 @@ +{"platform":"android","name":"Pixel 2 XL","engineRevision":"6ac856380fa4f66469552ce986edf59f65f7cd68","data":{"BWIASAAAAQAAAAABCYIR7777AAOAAAAAAAAAAAAAZAAQAAAACAAAAAEASAAQAAAA":"BwAAAExTS1OaAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfU3RhZ2UwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCWNvbG9yID0gY29sb3IgKiBpbkNvdmVyYWdlOwoJdmNvbG9yX1N0YWdlMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8xX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAAAAAAAAAAAAAIUBAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfU3RhZ2UwOwpvdXQgaGFsZjQgc2tfRnJhZ0NvbG9yOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TdGFnZTA7CglvdXRwdXRDb2xvcl9TdGFnZTAgPSB2Y29sb3JfU3RhZ2UwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfU3RhZ2UwICogb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IACgAAAGluQ292ZXJhZ2UAAAEAAAAAAAAA","HRIAAAAAAAMAAAAAARMPZ72HPQCFR7H7777QGAAAAAAAAAAAIQCQAAACAAAAAZQIAAAAAAAAAAAAAABAA4AAAACAAAAAAACCAYAAAAA":"BwAAAExTS1PmAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfU3RhZ2UxX2MwOwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1N0YWdlMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1N0YWdlMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfU3RhZ2UwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfU3RhZ2UwID0gZmxvYXQzeDIodW1hdHJpeF9TdGFnZTFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAAAAAAAAAAAA6AwAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TdGFnZTFfYzA7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1N0YWdlMTsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TdGFnZTA7Cm91dCBoYWxmNCBza19GcmFnQ29sb3I7CmhhbGY0IFRleHR1cmVFZmZlY3RfU3RhZ2UxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfU3RhZ2UxLCB2VHJhbnNmb3JtZWRDb29yZHNfMl9TdGFnZTApLnJycnI7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1N0YWdlMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TdGFnZTFfYzBfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TdGFnZTA7CglvdXRwdXRDb2xvcl9TdGFnZTAgPSB2Y29sb3JfU3RhZ2UwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfU3RhZ2UxOwoJb3V0cHV0X1N0YWdlMSA9IE1hdHJpeEVmZmVjdF9TdGFnZTFfYzAob3V0cHV0Q292ZXJhZ2VfU3RhZ2UwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TdGFnZTAgKiBvdXRwdXRfU3RhZ2UxOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAABAAAAAAAAAA==","HSJAAAAAAAGAAAAAAIWAAKX674BSZ7X7777QCAAAAABAAAAAABBAMAEQAMAAAABAAAAAAABBAMAAA":"BwAAAExTS1OzAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0IGNvdmVyYWdlOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZsb2NhbENvb3JkX1N0YWdlMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQgdmNvdmVyYWdlX1N0YWdlMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZsb2NhbENvb3JkX1N0YWdlMCA9IGxvY2FsQ29vcmQ7Cgl2Y292ZXJhZ2VfU3RhZ2UwID0gY292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAAAAAAAAAHoCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2bG9jYWxDb29yZF9TdGFnZTA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdmNvdmVyYWdlX1N0YWdlMDsKb3V0IGhhbGY0IHNrX0ZyYWdDb2xvcjsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfU3RhZ2UwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1N0YWdlMDsKCW91dHB1dENvbG9yX1N0YWdlMCA9ICgoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1N0YWdlMCwgdGV4Q29vcmQpICogaGFsZjQoMSkpKTsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1N0YWdlMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1N0YWdlMCA9IGhhbGY0KGhhbGYoY292ZXJhZ2UpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TdGFnZTAgKiBvdXRwdXRDb3ZlcmFnZV9TdGFnZTA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlCgAAAGxvY2FsQ29vcmQAAAEAAAAAAAAA","BWAAQAAAAQAAAAABC3777777AAOAAAAAAAAAAAAAZAAQAAAACAAAAAEASAAQAAAA":"BwAAAExTS1NhAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmIHZpbkNvdmVyYWdlX1N0YWdlMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJdmluQ292ZXJhZ2VfU3RhZ2UwID0gaW5Db3ZlcmFnZTsKCXNrX1Bvc2l0aW9uID0gX3RtcF8xX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAAAAAAAAAAAAAADUAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gaGFsZjQgdUNvbG9yX1N0YWdlMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmIHZpbkNvdmVyYWdlX1N0YWdlMDsKb3V0IGhhbGY0IHNrX0ZyYWdDb2xvcjsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfU3RhZ2UwOwoJb3V0cHV0Q29sb3JfU3RhZ2UwID0gdUNvbG9yX1N0YWdlMDsKCWhhbGYgYWxwaGEgPSAxLjA7CglhbHBoYSA9IHZpbkNvdmVyYWdlX1N0YWdlMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1N0YWdlMCA9IGhhbGY0KGFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TdGFnZTAgKiBvdXRwdXRDb3ZlcmFnZV9TdGFnZTA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAgAAAAoAAABpblBvc2l0aW9uAAAKAAAAaW5Db3ZlcmFnZQAAAQAAAAAAAAA=","AWAQGAAAQAAIXCEPAGGP777777777737AAAAAAAAAAAABZAAAAAAACAAAAAEBSAA":"BwAAAExTS1PrAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gZmxvYXQ0IGluQ2lyY2xlRWRnZTsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TdGFnZTA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1N0YWdlMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1N0YWdlMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMl9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAAAAAAAAAAAAEAMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1N0YWdlMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TdGFnZTA7Cm91dCBoYWxmNCBza19GcmFnQ29sb3I7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TdGFnZTA7CgloYWxmNCBvdXRwdXRDb2xvcl9TdGFnZTA7CglvdXRwdXRDb2xvcl9TdGFnZTAgPSB2aW5Db2xvcl9TdGFnZTA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGYgZGlzdGFuY2VUb0lubmVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKGQgLSBjaXJjbGVFZGdlLncpKTsKCWhhbGYgaW5uZXJBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9Jbm5lckVkZ2UpOwoJZWRnZUFscGhhICo9IGlubmVyQWxwaGE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TdGFnZTAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1N0YWdlMCAqIG91dHB1dENvdmVyYWdlX1N0YWdlMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UBAAAAAAAAAA==","HQQACAAAAAGAAAAAAIWP57ZDH37P7777777QCAAAAAAAAAAAMIAHSAAAAAAQAAAAAA4QAAAAAABAAAAACAZAAAAAAA":"BwAAAExTS1MiAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfU3RhZ2UwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TdGFnZTAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAEAAAAAAAAAAQAAAFcDAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TdGFnZTFfYzA7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1N0YWdlMV9jMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfU3RhZ2UwOwpvdXQgaGFsZjQgc2tfRnJhZ0NvbG9yOwpoYWxmNCBDaXJjdWxhclJSZWN0X1N0YWdlMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfU3RhZ2UxX2MwLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1N0YWdlMV9jMC5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1N0YWdlMV9jMC54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TdGFnZTA7CglvdXRwdXRDb2xvcl9TdGFnZTAgPSB2Y29sb3JfU3RhZ2UwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfU3RhZ2UxOwoJb3V0cHV0X1N0YWdlMSA9IENpcmN1bGFyUlJlY3RfU3RhZ2UxX2MwKG91dHB1dENvdmVyYWdlX1N0YWdlMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfU3RhZ2UwICogb3V0cHV0X1N0YWdlMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAEAAAAAAAAA","HMMAAAAABCYIR6AYYAAAAAAAAAAAAACABYAAAAEAAAAAAAEEBQAA":"BwAAAExTS1OoAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gZmxvYXQ0IGluUXVhZEVkZ2U7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0NCB2UXVhZEVkZ2VfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TdGFnZTA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRFZGdlCgl2UXVhZEVkZ2VfU3RhZ2UwID0gaW5RdWFkRWRnZTsKCXZpbkNvbG9yX1N0YWdlMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAAAAAAAAQAAAMIDAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDQgdlF1YWRFZGdlX1N0YWdlMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TdGFnZTA7Cm91dCBoYWxmNCBza19GcmFnQ29sb3I7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkRWRnZQoJaGFsZjQgb3V0cHV0Q29sb3JfU3RhZ2UwOwoJb3V0cHV0Q29sb3JfU3RhZ2UwID0gdmluQ29sb3JfU3RhZ2UwOwoJaGFsZiBlZGdlQWxwaGE7CgloYWxmMiBkdXZkeCA9IGhhbGYyKGRGZHgodlF1YWRFZGdlX1N0YWdlMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TdGFnZTAueHkpKTsKCWlmICh2UXVhZEVkZ2VfU3RhZ2UwLnogPiAwLjAgJiYgdlF1YWRFZGdlX1N0YWdlMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1N0YWdlMC56LCB2UXVhZEVkZ2VfU3RhZ2UwLncpICsgMC41LCAxLjApKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjIgZ0YgPSBoYWxmMihoYWxmKDIuMCp2UXVhZEVkZ2VfU3RhZ2UwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1N0YWdlMC54KmR1dmR5LnggLSBkdXZkeS55KSk7CgkJZWRnZUFscGhhID0gaGFsZih2UXVhZEVkZ2VfU3RhZ2UwLngqdlF1YWRFZGdlX1N0YWdlMC54IC0gdlF1YWRFZGdlX1N0YWdlMC55KTsKCQllZGdlQWxwaGEgPSBzYXR1cmF0ZSgwLjUgLSBlZGdlQWxwaGEgLyBsZW5ndGgoZ0YpKTsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1N0YWdlMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfU3RhZ2UwICogb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwOwoJfQp9CgAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAKAAAAaW5RdWFkRWRnZQAAAQAAAAAAAAA=","AWAAGAAAQAAIXCEPAGGP777777777737AAAAAAAAAAAABZAAAAAAACAAAAAEBSAA":"BwAAAExTS1PrAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gZmxvYXQ0IGluQ2lyY2xlRWRnZTsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TdGFnZTA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCgl2aW5DaXJjbGVFZGdlX1N0YWdlMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1N0YWdlMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMl9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAAAAAAAAAAAAfwIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1N0YWdlMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TdGFnZTA7Cm91dCBoYWxmNCBza19GcmFnQ29sb3I7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TdGFnZTA7CgloYWxmNCBvdXRwdXRDb2xvcl9TdGFnZTA7CglvdXRwdXRDb2xvcl9TdGFnZTAgPSB2aW5Db2xvcl9TdGFnZTA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1N0YWdlMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfU3RhZ2UwICogb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UBAAAAAAAAAA==","E5QQAAAAMAAGGADDACRQAAAAMAACHQDCABRQAI7CAMAAAAAAHEAAAAAAAIAAAAAQGIAAAAA":"BwAAAExTS1MbDAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDQgcmFkaWlfc2VsZWN0b3I7CmluIGZsb2F0NCBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzOwppbiBmbG9hdDQgYWFfYmxvYXRfYW5kX2NvdmVyYWdlOwppbiBmbG9hdDQgc2tldzsKaW4gZmxvYXQyIHRyYW5zbGF0ZTsKaW4gZmxvYXQ0IHJhZGlpX3g7CmluIGZsb2F0NCByYWRpaV95OwppbiBoYWxmNCBjb2xvcjsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1N0YWdlMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZhcmNjb29yZF9TdGFnZTA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEdyRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1N0YWdlMCA9IGNvbG9yOwoJZmxvYXQgYWFfYmxvYXRfbXVsdGlwbGllciA9IDE7CglmbG9hdDIgY29ybmVyID0gY29ybmVyX2FuZF9yYWRpdXNfb3V0c2V0cy54eTsKCWZsb2F0MiByYWRpdXNfb3V0c2V0ID0gY29ybmVyX2FuZF9yYWRpdXNfb3V0c2V0cy56dzsKCWZsb2F0MiBhYV9ibG9hdF9kaXJlY3Rpb24gPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UueHk7CglmbG9hdCBpc19saW5lYXJfY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UudzsKCWZsb2F0MiBwaXhlbGxlbmd0aCA9IGludmVyc2VzcXJ0KGZsb2F0Mihkb3Qoc2tldy54eiwgc2tldy54eiksIGRvdChza2V3Lnl3LCBza2V3Lnl3KSkpOwoJZmxvYXQ0IG5vcm1hbGl6ZWRfYXhpc19kaXJzID0gc2tldyAqIHBpeGVsbGVuZ3RoLnh5eHk7CglmbG9hdDIgYXhpc3dpZHRocyA9IChhYnMobm9ybWFsaXplZF9heGlzX2RpcnMueHkpICsgYWJzKG5vcm1hbGl6ZWRfYXhpc19kaXJzLnp3KSk7CglmbG9hdDIgYWFfYmxvYXRyYWRpdXMgPSBheGlzd2lkdGhzICogcGl4ZWxsZW5ndGggKiAuNTsKCWZsb2F0NCByYWRpaV9hbmRfbmVpZ2hib3JzID0gcmFkaWlfc2VsZWN0b3IqIGZsb2F0NHg0KHJhZGlpX3gsIHJhZGlpX3ksIHJhZGlpX3gueXh3eiwgcmFkaWlfeS53enl4KTsKCWZsb2F0MiByYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMueHk7CglmbG9hdDIgbmVpZ2hib3JfcmFkaWkgPSByYWRpaV9hbmRfbmVpZ2hib3JzLnp3OwoJZmxvYXQgY292ZXJhZ2VfbXVsdGlwbGllciA9IDE7CglpZiAoYW55KGdyZWF0ZXJUaGFuKGFhX2Jsb2F0cmFkaXVzLCBmbG9hdDIoMSkpKSkgCgl7CgkJY29ybmVyID0gbWF4KGFicyhjb3JuZXIpLCBhYV9ibG9hdHJhZGl1cykgKiBzaWduKGNvcm5lcik7CgkJY292ZXJhZ2VfbXVsdGlwbGllciA9IDEgLyAobWF4KGFhX2Jsb2F0cmFkaXVzLngsIDEpICogbWF4KGFhX2Jsb2F0cmFkaXVzLnksIDEpKTsKCQlyYWRpaSA9IGZsb2F0MigwKTsKCX0KCWZsb2F0IGNvdmVyYWdlID0gYWFfYmxvYXRfYW5kX2NvdmVyYWdlLno7CglpZiAoYW55KGxlc3NUaGFuKHJhZGlpLCBhYV9ibG9hdHJhZGl1cyAqIDEuNSkpKSAKCXsKCQlyYWRpaSA9IGZsb2F0MigwKTsKCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSBzaWduKGNvcm5lcik7CgkJaWYgKGNvdmVyYWdlID4gLjUpIAoJCXsKCQkJYWFfYmxvYXRfZGlyZWN0aW9uID0gLWFhX2Jsb2F0X2RpcmVjdGlvbjsKCQl9CgkJaXNfbGluZWFyX2NvdmVyYWdlID0gMTsKCX0KCWVsc2UgCgl7CgkJcmFkaWkgPSBjbGFtcChyYWRpaSwgcGl4ZWxsZW5ndGggKiAxLjUsIDIgLSBwaXhlbGxlbmd0aCAqIDEuNSk7CgkJbmVpZ2hib3JfcmFkaWkgPSBjbGFtcChuZWlnaGJvcl9yYWRpaSwgcGl4ZWxsZW5ndGggKiAxLjUsIDIgLSBwaXhlbGxlbmd0aCAqIDEuNSk7CgkJZmxvYXQyIHNwYWNpbmcgPSAyIC0gcmFkaWkgLSBuZWlnaGJvcl9yYWRpaTsKCQlmbG9hdDIgZXh0cmFfcGFkID0gbWF4KHBpeGVsbGVuZ3RoICogLjA2MjUgLSBzcGFjaW5nLCBmbG9hdDIoMCkpOwoJCXJhZGlpIC09IGV4dHJhX3BhZCAqIC41OwoJfQoJZmxvYXQyIGFhX291dHNldCA9IGFhX2Jsb2F0X2RpcmVjdGlvbiAqIGFhX2Jsb2F0cmFkaXVzICogYWFfYmxvYXRfbXVsdGlwbGllcjsKCWZsb2F0MiB2ZXJ0ZXhwb3MgPSBjb3JuZXIgKyByYWRpdXNfb3V0c2V0ICogcmFkaWkgKyBhYV9vdXRzZXQ7CglpZiAoY292ZXJhZ2UgPiAuNSkgCgl7CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi54ICE9IDAgJiYgdmVydGV4cG9zLnggKiBjb3JuZXIueCA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueCk7CgkJCXZlcnRleHBvcy54ID0gMDsKCQkJdmVydGV4cG9zLnkgKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLnkpICogcGl4ZWxsZW5ndGgueS9waXhlbGxlbmd0aC54OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueCkgLyAoYWJzKGNvcm5lci54KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJCWlmIChhYV9ibG9hdF9kaXJlY3Rpb24ueSAhPSAwICYmIHZlcnRleHBvcy55ICogY29ybmVyLnkgPCAwKSAKCQl7CgkJCWZsb2F0IGJhY2tzZXQgPSBhYnModmVydGV4cG9zLnkpOwoJCQl2ZXJ0ZXhwb3MueSA9IDA7CgkJCXZlcnRleHBvcy54ICs9IGJhY2tzZXQgKiBzaWduKGNvcm5lci54KSAqIHBpeGVsbGVuZ3RoLngvcGl4ZWxsZW5ndGgueTsKCQkJY292ZXJhZ2UgPSAoY292ZXJhZ2UgLSAuNSkgKiBhYnMoY29ybmVyLnkpIC8gKGFicyhjb3JuZXIueSkgKyBiYWNrc2V0KSArIC41OwoJCX0KCX0KCWZsb2F0MngyIHNrZXdtYXRyaXggPSBmbG9hdDJ4Mihza2V3Lnh5LCBza2V3Lnp3KTsKCWZsb2F0MiBkZXZjb29yZCA9IHZlcnRleHBvcyAqIHNrZXdtYXRyaXggKyB0cmFuc2xhdGU7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TdGFnZTAueHkgPSBmbG9hdDIoMCwgY292ZXJhZ2UgKiBjb3ZlcmFnZV9tdWx0aXBsaWVyKTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQyIGFyY2Nvb3JkID0gMSAtIGFicyhyYWRpdXNfb3V0c2V0KSArIGFhX291dHNldC9yYWRpaSAqIGNvcm5lcjsKCQl2YXJjY29vcmRfU3RhZ2UwLnh5ID0gZmxvYXQyKGFyY2Nvb3JkLngrMSwgYXJjY29vcmQueSk7Cgl9Cglza19Qb3NpdGlvbiA9IGRldmNvb3JkLnh5MDE7Cn0KAAAAAAAAAAAAAAAAANsCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2YXJjY29vcmRfU3RhZ2UwOwpvdXQgaGFsZjQgc2tfRnJhZ0NvbG9yOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgR3JGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TdGFnZTA7CglvdXRwdXRDb2xvcl9TdGFnZTAgPSB2Y29sb3JfU3RhZ2UwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1N0YWdlMC54LCB5PXZhcmNjb29yZF9TdGFnZTAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TdGFnZTAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfU3RhZ2UwICogb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAIAAAADgAAAHJhZGlpX3NlbGVjdG9yAAAZAAAAY29ybmVyX2FuZF9yYWRpdXNfb3V0c2V0cwAAABUAAABhYV9ibG9hdF9hbmRfY292ZXJhZ2UAAAAEAAAAc2tldwkAAAB0cmFuc2xhdGUAAAAHAAAAcmFkaWlfeAAHAAAAcmFkaWlfeQAFAAAAY29sb3IAAAABAAAAAAAAAA==","HQQAAAAAAAGAAAAAAIWP57ZDH37P7777777QCAAAAAAAAAAAMIAHSAAAAAAQAAAAAA4QAAAAAABAAAAACAZAAAAAAA":"BwAAAExTS1MiAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2Y29sb3JfU3RhZ2UwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TdGFnZTAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAEAAAAAAAAAAQAAAFcDAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TdGFnZTFfYzA7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1N0YWdlMV9jMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfU3RhZ2UwOwpvdXQgaGFsZjQgc2tfRnJhZ0NvbG9yOwpoYWxmNCBDaXJjdWxhclJSZWN0X1N0YWdlMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfU3RhZ2UxX2MwLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1N0YWdlMV9jMC5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1N0YWdlMV9jMC54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TdGFnZTA7CglvdXRwdXRDb2xvcl9TdGFnZTAgPSB2Y29sb3JfU3RhZ2UwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfU3RhZ2UxOwoJb3V0cHV0X1N0YWdlMSA9IENpcmN1bGFyUlJlY3RfU3RhZ2UxX2MwKG91dHB1dENvdmVyYWdlX1N0YWdlMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfU3RhZ2UwICogb3V0cHV0X1N0YWdlMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAEAAAAAAAAA","HQJAAAAAAAGAAAAAAIWP577774BSZ7X7777QCAAAAABAAAAAABBAMAEQAMAAAABAAAAAAABBAMAAA":"BwAAAExTS1M4AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgcG9zaXRpb247CmluIGZsb2F0MiBsb2NhbENvb3JkOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdmxvY2FsQ29vcmRfU3RhZ2UwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZsb2NhbENvb3JkX1N0YWdlMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAAAAAAAAJgIAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TdGFnZTA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZsb2NhbENvb3JkX1N0YWdlMDsKb3V0IGhhbGY0IHNrX0ZyYWdDb2xvcjsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfU3RhZ2UwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1N0YWdlMDsKCW91dHB1dENvbG9yX1N0YWdlMCA9ICgoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1N0YWdlMCwgdGV4Q29vcmQpICogaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1N0YWdlMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1N0YWdlMCAqIG91dHB1dENvdmVyYWdlX1N0YWdlMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAQAAAAAAAAA=","BWABSAAAAQAAAAABC3777777AAOAAAAAAAAAAAAAZAAQAAAACAAAAAEASAAQAAAA":"BwAAAExTS1PTAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGhhbGY0IHVDb2xvcl9TdGFnZTA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmIGluQ292ZXJhZ2U7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZjb2xvcl9TdGFnZTA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgY29sb3IgPSB1Q29sb3JfU3RhZ2UwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfU3RhZ2UwID0gY29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfM19pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8xX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAAAAAAAAAAAAhQEAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZjb2xvcl9TdGFnZTA7Cm91dCBoYWxmNCBza19GcmFnQ29sb3I7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1N0YWdlMDsKCW91dHB1dENvbG9yX1N0YWdlMCA9IHZjb2xvcl9TdGFnZTA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TdGFnZTAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TdGFnZTAgKiBvdXRwdXRDb3ZlcmFnZV9TdGFnZTA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAgAAAAoAAABpblBvc2l0aW9uAAAKAAAAaW5Db3ZlcmFnZQAAAQAAAAAAAAA=","F6IAAAAAAIAAAAABCYBR6AAAAAAAAAAAADEACAAAAAIAAAAAQCIACAAAAA":"BwAAAExTS1NbAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5IYWlyUXVhZEVkZ2U7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZIYWlyUXVhZEVkZ2VfU3RhZ2UwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkCgl2SGFpclF1YWRFZGdlX1N0YWdlMCA9IGluSGFpclF1YWRFZGdlOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8xX2luUG9zaXRpb24ueHkwMTsKfQoAAQAAAAAAAAABAAAAhgMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGhhbGY0IHVDb2xvcl9TdGFnZTA7CnVuaWZvcm0gaGFsZiB1Q292ZXJhZ2VfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZIYWlyUXVhZEVkZ2VfU3RhZ2UwOwpvdXQgaGFsZjQgc2tfRnJhZ0NvbG9yOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZAoJaGFsZjQgb3V0cHV0Q29sb3JfU3RhZ2UwOwoJb3V0cHV0Q29sb3JfU3RhZ2UwID0gdUNvbG9yX1N0YWdlMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZIYWlyUXVhZEVkZ2VfU3RhZ2UwLnh5KSk7CgloYWxmMiBkdXZkeSA9IGhhbGYyKGRGZHkodkhhaXJRdWFkRWRnZV9TdGFnZTAueHkpKTsKCWhhbGYyIGdGID0gaGFsZjIoMi4wICogdkhhaXJRdWFkRWRnZV9TdGFnZTAueCAqIGR1dmR4LnggLSBkdXZkeC55LCAgICAgICAgICAgICAgIDIuMCAqIHZIYWlyUXVhZEVkZ2VfU3RhZ2UwLnggKiBkdXZkeS54IC0gZHV2ZHkueSk7CgllZGdlQWxwaGEgPSBoYWxmKHZIYWlyUXVhZEVkZ2VfU3RhZ2UwLnggKiB2SGFpclF1YWRFZGdlX1N0YWdlMC54IC0gdkhhaXJRdWFkRWRnZV9TdGFnZTAueSk7CgllZGdlQWxwaGEgPSBzcXJ0KGVkZ2VBbHBoYSAqIGVkZ2VBbHBoYSAvIGRvdChnRiwgZ0YpKTsKCWVkZ2VBbHBoYSA9IG1heCgxLjAgLSBlZGdlQWxwaGEsIDAuMCk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TdGFnZTAgPSBoYWxmNCh1Q292ZXJhZ2VfU3RhZ2UwICogZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TdGFnZTAgKiBvdXRwdXRDb3ZlcmFnZV9TdGFnZTA7Cgl9Cn0KAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAA4AAABpbkhhaXJRdWFkRWRnZQAAAQAAAAAAAAA=","C4QAAAAAMAAAAABAYAROFA2CAIAAAABAAAAAAAAAAAAAAOIAAAAAAAQAAAABAMQA":"BwAAAExTS1OYAgAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNTaXplSW52X1N0YWdlMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIHVzaG9ydDIgaW5UZXh0dXJlQ29vcmRzOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdDIgdlRleHR1cmVDb29yZHNfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIG91dCBmbG9hdCB2VGV4SW5kZXhfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TdGFnZTA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TdGFnZTAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfU3RhZ2UwOwoJdlRleEluZGV4X1N0YWdlMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TdGFnZTAgPSBpbkNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAAAAAAAAAFsCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TdGFnZTA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQgdlRleEluZGV4X1N0YWdlMDsKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2aW5Db2xvcl9TdGFnZTA7Cm91dCBoYWxmNCBza19GcmFnQ29sb3I7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBCaXRtYXBUZXh0CgloYWxmNCBvdXRwdXRDb2xvcl9TdGFnZTA7CglvdXRwdXRDb2xvcl9TdGFnZTAgPSB2aW5Db2xvcl9TdGFnZTA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TdGFnZTAsIHZUZXh0dXJlQ29vcmRzX1N0YWdlMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1N0YWdlMCA9IHRleENvbG9yOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1N0YWdlMCAqIG91dHB1dENvdmVyYWdlX1N0YWdlMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAEAAAAAAAAA","E5YQAAAAMAAGGADDACRQAAAAMAACHQDCABRQAI7CAMAAAAAAHEAAAAAAAIAAAAAQGIAAAAA":"BwAAAExTS1MbDAAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDQgcmFkaWlfc2VsZWN0b3I7CmluIGZsb2F0NCBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzOwppbiBmbG9hdDQgYWFfYmxvYXRfYW5kX2NvdmVyYWdlOwppbiBmbG9hdDQgc2tldzsKaW4gZmxvYXQyIHRyYW5zbGF0ZTsKaW4gZmxvYXQ0IHJhZGlpX3g7CmluIGZsb2F0NCByYWRpaV95OwppbiBoYWxmNCBjb2xvcjsKbm9wZXJzcGVjdGl2ZSBvdXQgaGFsZjQgdmNvbG9yX1N0YWdlMDsKbm9wZXJzcGVjdGl2ZSBvdXQgZmxvYXQyIHZhcmNjb29yZF9TdGFnZTA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEdyRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1N0YWdlMCA9IGNvbG9yOwoJZmxvYXQgYWFfYmxvYXRfbXVsdGlwbGllciA9IDA7CglmbG9hdDIgY29ybmVyID0gY29ybmVyX2FuZF9yYWRpdXNfb3V0c2V0cy54eTsKCWZsb2F0MiByYWRpdXNfb3V0c2V0ID0gY29ybmVyX2FuZF9yYWRpdXNfb3V0c2V0cy56dzsKCWZsb2F0MiBhYV9ibG9hdF9kaXJlY3Rpb24gPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UueHk7CglmbG9hdCBpc19saW5lYXJfY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UudzsKCWZsb2F0MiBwaXhlbGxlbmd0aCA9IGludmVyc2VzcXJ0KGZsb2F0Mihkb3Qoc2tldy54eiwgc2tldy54eiksIGRvdChza2V3Lnl3LCBza2V3Lnl3KSkpOwoJZmxvYXQ0IG5vcm1hbGl6ZWRfYXhpc19kaXJzID0gc2tldyAqIHBpeGVsbGVuZ3RoLnh5eHk7CglmbG9hdDIgYXhpc3dpZHRocyA9IChhYnMobm9ybWFsaXplZF9heGlzX2RpcnMueHkpICsgYWJzKG5vcm1hbGl6ZWRfYXhpc19kaXJzLnp3KSk7CglmbG9hdDIgYWFfYmxvYXRyYWRpdXMgPSBheGlzd2lkdGhzICogcGl4ZWxsZW5ndGggKiAuNTsKCWZsb2F0NCByYWRpaV9hbmRfbmVpZ2hib3JzID0gcmFkaWlfc2VsZWN0b3IqIGZsb2F0NHg0KHJhZGlpX3gsIHJhZGlpX3ksIHJhZGlpX3gueXh3eiwgcmFkaWlfeS53enl4KTsKCWZsb2F0MiByYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMueHk7CglmbG9hdDIgbmVpZ2hib3JfcmFkaWkgPSByYWRpaV9hbmRfbmVpZ2hib3JzLnp3OwoJZmxvYXQgY292ZXJhZ2VfbXVsdGlwbGllciA9IDE7CglpZiAoYW55KGdyZWF0ZXJUaGFuKGFhX2Jsb2F0cmFkaXVzLCBmbG9hdDIoMSkpKSkgCgl7CgkJY29ybmVyID0gbWF4KGFicyhjb3JuZXIpLCBhYV9ibG9hdHJhZGl1cykgKiBzaWduKGNvcm5lcik7CgkJY292ZXJhZ2VfbXVsdGlwbGllciA9IDEgLyAobWF4KGFhX2Jsb2F0cmFkaXVzLngsIDEpICogbWF4KGFhX2Jsb2F0cmFkaXVzLnksIDEpKTsKCQlyYWRpaSA9IGZsb2F0MigwKTsKCX0KCWZsb2F0IGNvdmVyYWdlID0gYWFfYmxvYXRfYW5kX2NvdmVyYWdlLno7CglpZiAoYW55KGxlc3NUaGFuKHJhZGlpLCBhYV9ibG9hdHJhZGl1cyAqIDEuNSkpKSAKCXsKCQlyYWRpaSA9IGZsb2F0MigwKTsKCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSBzaWduKGNvcm5lcik7CgkJaWYgKGNvdmVyYWdlID4gLjUpIAoJCXsKCQkJYWFfYmxvYXRfZGlyZWN0aW9uID0gLWFhX2Jsb2F0X2RpcmVjdGlvbjsKCQl9CgkJaXNfbGluZWFyX2NvdmVyYWdlID0gMTsKCX0KCWVsc2UgCgl7CgkJcmFkaWkgPSBjbGFtcChyYWRpaSwgcGl4ZWxsZW5ndGggKiAxLjUsIDIgLSBwaXhlbGxlbmd0aCAqIDEuNSk7CgkJbmVpZ2hib3JfcmFkaWkgPSBjbGFtcChuZWlnaGJvcl9yYWRpaSwgcGl4ZWxsZW5ndGggKiAxLjUsIDIgLSBwaXhlbGxlbmd0aCAqIDEuNSk7CgkJZmxvYXQyIHNwYWNpbmcgPSAyIC0gcmFkaWkgLSBuZWlnaGJvcl9yYWRpaTsKCQlmbG9hdDIgZXh0cmFfcGFkID0gbWF4KHBpeGVsbGVuZ3RoICogLjA2MjUgLSBzcGFjaW5nLCBmbG9hdDIoMCkpOwoJCXJhZGlpIC09IGV4dHJhX3BhZCAqIC41OwoJfQoJZmxvYXQyIGFhX291dHNldCA9IGFhX2Jsb2F0X2RpcmVjdGlvbiAqIGFhX2Jsb2F0cmFkaXVzICogYWFfYmxvYXRfbXVsdGlwbGllcjsKCWZsb2F0MiB2ZXJ0ZXhwb3MgPSBjb3JuZXIgKyByYWRpdXNfb3V0c2V0ICogcmFkaWkgKyBhYV9vdXRzZXQ7CglpZiAoY292ZXJhZ2UgPiAuNSkgCgl7CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi54ICE9IDAgJiYgdmVydGV4cG9zLnggKiBjb3JuZXIueCA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueCk7CgkJCXZlcnRleHBvcy54ID0gMDsKCQkJdmVydGV4cG9zLnkgKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLnkpICogcGl4ZWxsZW5ndGgueS9waXhlbGxlbmd0aC54OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueCkgLyAoYWJzKGNvcm5lci54KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJCWlmIChhYV9ibG9hdF9kaXJlY3Rpb24ueSAhPSAwICYmIHZlcnRleHBvcy55ICogY29ybmVyLnkgPCAwKSAKCQl7CgkJCWZsb2F0IGJhY2tzZXQgPSBhYnModmVydGV4cG9zLnkpOwoJCQl2ZXJ0ZXhwb3MueSA9IDA7CgkJCXZlcnRleHBvcy54ICs9IGJhY2tzZXQgKiBzaWduKGNvcm5lci54KSAqIHBpeGVsbGVuZ3RoLngvcGl4ZWxsZW5ndGgueTsKCQkJY292ZXJhZ2UgPSAoY292ZXJhZ2UgLSAuNSkgKiBhYnMoY29ybmVyLnkpIC8gKGFicyhjb3JuZXIueSkgKyBiYWNrc2V0KSArIC41OwoJCX0KCX0KCWZsb2F0MngyIHNrZXdtYXRyaXggPSBmbG9hdDJ4Mihza2V3Lnh5LCBza2V3Lnp3KTsKCWZsb2F0MiBkZXZjb29yZCA9IHZlcnRleHBvcyAqIHNrZXdtYXRyaXggKyB0cmFuc2xhdGU7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TdGFnZTAueHkgPSBmbG9hdDIoMCwgY292ZXJhZ2UgKiBjb3ZlcmFnZV9tdWx0aXBsaWVyKTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQyIGFyY2Nvb3JkID0gMSAtIGFicyhyYWRpdXNfb3V0c2V0KSArIGFhX291dHNldC9yYWRpaSAqIGNvcm5lcjsKCQl2YXJjY29vcmRfU3RhZ2UwLnh5ID0gZmxvYXQyKGFyY2Nvb3JkLngrMSwgYXJjY29vcmQueSk7Cgl9Cglza19Qb3NpdGlvbiA9IGRldmNvb3JkLnh5MDE7Cn0KAAAAAAAAAAAAAAAAAAEDAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKbm9wZXJzcGVjdGl2ZSBpbiBoYWxmNCB2Y29sb3JfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0MiB2YXJjY29vcmRfU3RhZ2UwOwpvdXQgaGFsZjQgc2tfRnJhZ0NvbG9yOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgR3JGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TdGFnZTA7CglvdXRwdXRDb2xvcl9TdGFnZTAgPSB2Y29sb3JfU3RhZ2UwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1N0YWdlMC54LCB5PXZhcmNjb29yZF9TdGFnZTAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9Cgljb3ZlcmFnZSA9IChjb3ZlcmFnZSA+PSAuNSkgPyAxIDogMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1N0YWdlMCA9IGhhbGY0KGNvdmVyYWdlKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TdGFnZTAgKiBvdXRwdXRDb3ZlcmFnZV9TdGFnZTA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABAAAAHNrZXcJAAAAdHJhbnNsYXRlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABQAAAGNvbG9yAAAAAQAAAAAAAAA=","DUBQAAAAAEAAAAADAAAAAAIWCEPRIEQAAAAAAAIAAAAAAAAAADEACAAAAAIAAAAAQCIACAA":"BwAAAExTS1MMAwAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0Owp1bmlmb3JtIGZsb2F0MiB1QXRsYXNEaW1lbnNpb25zSW52X1N0YWdlMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIHVzaG9ydDIgaW5UZXh0dXJlQ29vcmRzOwpub3BlcnNwZWN0aXZlIG91dCBoYWxmNCB2aW5Db2xvcl9TdGFnZTA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TdGFnZTA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0IHZUZXhJbmRleF9TdGFnZTA7Cm5vcGVyc3BlY3RpdmUgb3V0IGZsb2F0MiB2SW50VGV4dHVyZUNvb3Jkc19TdGFnZTA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIERpc3RhbmNlRmllbGRBOFRleHQKCXZpbkNvbG9yX1N0YWdlMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJaW50IHRleElkeCA9IDA7CglmbG9hdDIgdW5vcm1UZXhDb29yZHMgPSBmbG9hdDIoaW5UZXh0dXJlQ29vcmRzLngsIGluVGV4dHVyZUNvb3Jkcy55KTsKCXZUZXh0dXJlQ29vcmRzX1N0YWdlMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzRGltZW5zaW9uc0ludl9TdGFnZTA7Cgl2VGV4SW5kZXhfU3RhZ2UwID0gZmxvYXQodGV4SWR4KTsKCXZJbnRUZXh0dXJlQ29vcmRzX1N0YWdlMCA9IHVub3JtVGV4Q29vcmRzOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAAAAAAAAAqwMAACNleHRlbnNpb24gR0xfTlZfc2hhZGVyX25vcGVyc3BlY3RpdmVfaW50ZXJwb2xhdGlvbjogcmVxdWlyZQp1bmlmb3JtIGhhbGYgdURpc3RhbmNlQWRqdXN0X1N0YWdlMDsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIGluIGhhbGY0IHZpbkNvbG9yX1N0YWdlMDsKbm9wZXJzcGVjdGl2ZSBpbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIGluIGZsb2F0IHZUZXhJbmRleF9TdGFnZTA7Cm5vcGVyc3BlY3RpdmUgaW4gZmxvYXQyIHZJbnRUZXh0dXJlQ29vcmRzX1N0YWdlMDsKb3V0IGhhbGY0IHNrX0ZyYWdDb2xvcjsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERpc3RhbmNlRmllbGRBOFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1N0YWdlMDsKCW91dHB1dENvbG9yX1N0YWdlMCA9IHZpbkNvbG9yX1N0YWdlMDsKCWZsb2F0MiB1diA9IHZUZXh0dXJlQ29vcmRzX1N0YWdlMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1N0YWdlMCwgdXYpLnJycnI7Cgl9CgloYWxmIGRpc3RhbmNlID0gNy45Njg3NSoodGV4Q29sb3IuciAtIDAuNTAxOTYwNzg0MzEpOwoJZGlzdGFuY2UgLT0gdURpc3RhbmNlQWRqdXN0X1N0YWdlMDsKCWhhbGYgYWZ3aWR0aDsKCWFmd2lkdGggPSBhYnMoMC42NSpoYWxmKGRGZHgodkludFRleHR1cmVDb29yZHNfU3RhZ2UwLngpKSk7CgloYWxmIHZhbCA9IHNtb290aHN0ZXAoLWFmd2lkdGgsIGFmd2lkdGgsIGRpc3RhbmNlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1N0YWdlMCA9IGhhbGY0KHZhbCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfU3RhZ2UwICogb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAQAAAAAAAAA=","GABQAAAAAELBCHYCDYAAAAAAAEAAAACAIQAABSABAAAAAEAAAAAIBEABAA":"BwAAAExTS1O9AQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZjQgaW5Db2xvcjsKaW4gaGFsZjMgaW5TaGFkb3dQYXJhbXM7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TdGFnZTA7Cm5vcGVyc3BlY3RpdmUgb3V0IGhhbGY0IHZpbkNvbG9yX1N0YWdlMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUlJlY3RTaGFkb3cKCXZpblNoYWRvd1BhcmFtc19TdGFnZTAgPSBpblNoYWRvd1BhcmFtczsKCXZpbkNvbG9yX1N0YWdlMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAAAAAAAAAAAAAKgCAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfU3RhZ2UwOwpub3BlcnNwZWN0aXZlIGluIGhhbGYzIHZpblNoYWRvd1BhcmFtc19TdGFnZTA7Cm5vcGVyc3BlY3RpdmUgaW4gaGFsZjQgdmluQ29sb3JfU3RhZ2UwOwpvdXQgaGFsZjQgc2tfRnJhZ0NvbG9yOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUlJlY3RTaGFkb3cKCWhhbGYzIHNoYWRvd1BhcmFtczsKCXNoYWRvd1BhcmFtcyA9IHZpblNoYWRvd1BhcmFtc19TdGFnZTA7CgloYWxmNCBvdXRwdXRDb2xvcl9TdGFnZTA7CglvdXRwdXRDb2xvcl9TdGFnZTAgPSB2aW5Db2xvcl9TdGFnZTA7CgloYWxmIGQgPSBsZW5ndGgoc2hhZG93UGFyYW1zLnh5KTsKCWZsb2F0MiB1diA9IGZsb2F0MihzaGFkb3dQYXJhbXMueiAqICgxLjAgLSBkKSwgMC41KTsKCWhhbGYgZmFjdG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1N0YWdlMCwgdXYpLjAwMHIuYTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1N0YWdlMCA9IGhhbGY0KGZhY3Rvcik7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfU3RhZ2UwICogb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADgAAAGluU2hhZG93UGFyYW1zAAABAAAAAAAAAA==","BUAAQAAAAQAAAAABC3777777777QAAAAAAAAAAAAZAAQAAAACAAAAAEASAAQAAAA":"BwAAAExTS1MAAQAAI2V4dGVuc2lvbiBHTF9OVl9zaGFkZXJfbm9wZXJzcGVjdGl2ZV9pbnRlcnBvbGF0aW9uOiByZXF1aXJlCnVuaWZvcm0gZmxvYXQ0IHNrX1JUQWRqdXN0OwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAAAAAAAAAHwBAAAjZXh0ZW5zaW9uIEdMX05WX3NoYWRlcl9ub3BlcnNwZWN0aXZlX2ludGVycG9sYXRpb246IHJlcXVpcmUKdW5pZm9ybSBoYWxmNCB1Q29sb3JfU3RhZ2UwOwpvdXQgaGFsZjQgc2tfRnJhZ0NvbG9yOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TdGFnZTA7CglvdXRwdXRDb2xvcl9TdGFnZTAgPSB1Q29sb3JfU3RhZ2UwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfU3RhZ2UwICogb3V0cHV0Q292ZXJhZ2VfU3RhZ2UwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAKAAAAaW5Qb3NpdGlvbgAAAQAAAAAAAAA="}} \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 7ab1d43..c000573 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -1,471 +1,471 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile 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 = ""; }; - 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 = ""; }; - 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 = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 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; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1020; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 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; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - 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; - 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 */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.firogames.firoRunner; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - 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 = com.firogames.firoRunner; - 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 = com.firogames.firoRunner; - 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 */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile 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 = ""; }; + 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 = ""; }; + 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 = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 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; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 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; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + 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; + 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 */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.firogames.firoRunner; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + 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 = com.firogames.firoRunner; + 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 = com.firogames.firoRunner; + 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 */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} \ No newline at end of file diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png index dc9ada4..b3db423 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png index 28c6bf0..dc1ffa0 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png index 2ccbfd9..c0547c8 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png index f091b6b..82824d2 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png index 4cde121..5abbc31 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png index d0ef06e..817775f 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png index dcdc230..3715143 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png index 2ccbfd9..c0547c8 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png index c8f9ed8..39fe2a1 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png index a6d6b86..b05351a 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png index a6d6b86..b05351a 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png index 75b2d16..d6e804e 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png index c4df70d..20f4dbe 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png index 6a84f41..bfaf1ef 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png index d0e1f58..02b75c7 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/lib/firework.dart b/lib/firework.dart new file mode 100644 index 0000000..75d6e2b --- /dev/null +++ b/lib/firework.dart @@ -0,0 +1,141 @@ +import 'dart:math'; + +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; +import 'package:flame/extensions.dart'; +import 'package:flame/flame.dart'; +import 'package:flame_audio/flame_audio.dart'; +import 'package:audioplayers/src/api/player_mode.dart'; + +enum FireworkState { normal } + +// Class that shoots off fireworks whenever the game speeds up. +class Firework extends Component { + MyGame gameRef; + late SpriteAnimationGroupComponent sprite1; + late SpriteAnimationGroupComponent sprite2; + Firework(this.gameRef); + double timeSinceFirework = 0; + late Random random; + String message = ""; + List messages = [ + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + ]; + + Future load() async { + random = Random(); + List firework = await loadListSprites("firework", "firework", 10); + + SpriteAnimation normal = + SpriteAnimation.spriteList(firework, stepTime: 0.25, loop: false); + + sprite1 = SpriteAnimationGroupComponent( + animations: { + FireworkState.normal: normal, + }, + current: FireworkState.normal, + ); + + sprite1.changePriorityWithoutResorting(FIREWORK_PRIORITY); + sprite1.update(100); + + sprite1.size = + Vector2(gameRef.viewport.canvasSize.y, gameRef.viewport.canvasSize.y); + sprite1.position = Vector2(0, 0); + + sprite2 = SpriteAnimationGroupComponent( + animations: { + FireworkState.normal: normal, + }, + current: FireworkState.normal, + ); + + sprite2.changePriorityWithoutResorting(FIREWORK_PRIORITY); + + sprite2.size = + Vector2(gameRef.viewport.canvasSize.y, gameRef.viewport.canvasSize.y); + sprite2.position = + Vector2(gameRef.viewport.canvasSize.x - sprite2.size.x, 0); + sprite2.update(100); + } + + void setUp() { + message = ""; + timeSinceFirework = 0; + gameRef.add(sprite1); + gameRef.add(sprite2); + } + + @override + void update(double dt) { + if (!(sprite1.animation?.done() ?? false)) { + timeSinceFirework = 0; + } else { + timeSinceFirework += dt; + } + sprite1.update(dt); + sprite2.update(dt); + } + + void renderText(Canvas canvas) { + sprite1.render(canvas); + sprite1.render(canvas); + if ((sprite1.animation?.done() ?? false) && + timeSinceFirework < 1 && + message != "") { + gameRef.fireworksPaint.render( + canvas, + message, + Vector2( + gameRef.size.x / 2 - + gameRef.fireworksPaint.measureTextWidth(message) / 2, + gameRef.size.y / 9 - + gameRef.fireworksPaint.measureTextHeight(message) / 2), + ); + } + } + + void reset() { + message = messages.elementAt(random.nextInt(messages.length)); + sprite1.animation!.reset(); + sprite2.animation!.reset(); + FlameAudio.audioCache + .play("sfx/fireworks.mp3", volume: 0.75, mode: PlayerMode.LOW_LATENCY); + } + + void resize(Vector2 newSize, double xRatio, double yRatio) { + sprite1.x *= xRatio; + sprite1.y *= yRatio; + sprite1.width *= xRatio; + sprite1.height *= yRatio; + + sprite2.x *= xRatio; + sprite2.y *= yRatio; + sprite2.width *= xRatio; + sprite2.height *= yRatio; + } + + Future> loadListSprites( + String folderName, String extraName, int howManyFrames) async { + List sprites = []; + for (int i = 0; i < howManyFrames; i++) { + sprites.add(Sprite( + await Flame.images.load('$folderName/${extraName}_$i.png'), + )); + } + + return sprites; + } +} diff --git a/lib/game_state.dart b/lib/game_state.dart new file mode 100644 index 0000000..7e55e1e --- /dev/null +++ b/lib/game_state.dart @@ -0,0 +1,163 @@ +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; + +// Class the holds the game state and several functions related to score and +// speed. +class GameState extends Component { + int start = 0; + bool isPaused = false; + int numCoins = 0; + int time = 0; + late MyGame gameRef; + int previousLevel = 1; + + @override + void update(double dt) { + super.update(dt); + if (!isPaused) { + time = DateTime.now().microsecondsSinceEpoch - start; + if (previousLevel != getLevel()) { + previousLevel = getLevel(); + gameRef.fireworks.reset(); + } + } + } + + void addCoin() { + numCoins++; + } + + void setUp(MyGame gameRef) { + this.gameRef = gameRef; + numCoins = 0; + time = 0; + previousLevel = 1; + start = DateTime.now().microsecondsSinceEpoch; + isPaused = false; + } + + void setPaused() { + isPaused = true; + } + + // This is the level of the game. + int getLevel() { + if (time > LEVEL7) { + return 7; + } else if (time > LEVEL6) { + return 6; + } else if (time > LEVEL5) { + return 5; + } else if (time > LEVEL4) { + return 4; + } else if (time > LEVEL3) { + return 3; + } else if (time > LEVEL2) { + return 2; + } else { + return 1; + } + } + + // This determines the stages of the games and its animations. + int getScoreLevel() { + int score = getScore(); + if (score > LEVEL7) { + return 12; + } else if (score > LEVEL6 + LEVEL6 / 2) { + return 11; + } else if (score > LEVEL6) { + return 10; + } else if (score > LEVEL5 + LEVEL5 / 2) { + return 9; + } else if (score > LEVEL5) { + return 8; + } else if (score > LEVEL4 + LEVEL4 / 2) { + return 7; + } else if (score > LEVEL4) { + return 6; + } else if (score > LEVEL3 + LEVEL3 / 2) { + return 5; + } else if (score > LEVEL3) { + return 4; + } else if (score > LEVEL2 + LEVEL2 / 2) { + return 3; + } else if (score > LEVEL2) { + return 2; + } else if (score > LEVEL2 - LEVEL2 / 2) { + return 1; + } else { + return 0; + } + } + + // Gets the danger level of the game, this determines the appearance of + // obstacles in the beginning of the game. + int getDangerLevel() { + int score = getScore(); + if (score > LEVEL2 / 2 + LEVEL2 / (2 * 4)) { + return 5; + } else if (score > LEVEL2 / 2) { + return 4; + } else if (score > LEVEL2 / 2 - LEVEL2 / (2 * 4)) { + return 3; + } else if (score > LEVEL2 / 2 - 2 * LEVEL2 / (2 * 4)) { + return 2; + } else if (score > LEVEL2 / 2 - 3 * LEVEL2 / (2 * 4)) { + return 1; + } else { + return 0; + } + } + + // This score is used to determine the danger level of the game, + // and progression. + int getScore() { + return time ~/ 10 + numCoins * 1000000; + } + + // This is the real score that the player sees. + int getPlayerScore() { + return getScore() ~/ 10000; + } + + // Gets how long the player has been playing the game. + int getPlayerTime() { + return time ~/ 1000000; + } + + // Get the relative pixel velocity at the current moment. + double getVelocity() { + if (!isPaused) { + switch (getLevel()) { + case 7: + return gameRef.viewport.canvasSize.x * 0.30; + case 6: + return gameRef.viewport.canvasSize.x * 0.28; + case 5: + return gameRef.viewport.canvasSize.x * 0.26; + case 4: + return gameRef.viewport.canvasSize.x * 0.24; + case 3: + return gameRef.viewport.canvasSize.x * 0.22; + case 2: + return gameRef.viewport.canvasSize.x * 0.20; + default: + return gameRef.viewport.canvasSize.x * 0.18; + } + } else { + return 0; + } + } + + // Returns the level of the Robot, used to determine what animations it uses. + int getRobotLevel() { + if (numCoins > COINS_ROBOT_UPGRADE2) { + return 3; + } else if (numCoins > COINS_ROBOT_UPGRADE1) { + return 2; + } else { + return 1; + } + } +} diff --git a/lib/holders/bug_holder.dart b/lib/holders/bug_holder.dart new file mode 100644 index 0000000..a0b17ea --- /dev/null +++ b/lib/holders/bug_holder.dart @@ -0,0 +1,72 @@ +import 'package:firo_runner/holders/holder.dart'; +import 'package:firo_runner/moving_objects/platform.dart'; +import 'package:flame/components.dart'; + +import 'package:firo_runner/moving_objects/bug.dart'; +import 'package:firo_runner/main.dart'; + +class BugHolder extends Holder { + late List bug; + late List breaking; + + @override + Future load() async { + bug = await loadListSprites("bug", "bug", 8); + breaking = await loadListSprites("bug", "bug_break", 13); + } + + List getBug(String state) { + switch (state) { + case "normal": + return bug; + default: + return breaking; + } + } + + // Generate a bug on the indicated level if it is possible. + bool generateBug(MyGame gameRef, int level, + {bool force = false, double xPosition = 0}) { + if (objects[level].isNotEmpty) { + return false; + } + + if (random.nextInt(100) > 25) { + return true; + } else { + int nearestPlatform = getNearestPlatform(level); + + Platform? platform = + gameRef.platformHolder.getPlatformOffScreen(nearestPlatform); + if (platform != null && platform.prohibitObstacles) { + return false; + } + double xCoordinate = -100; + + if (level == 0) { + xCoordinate = gameRef.size.x; + } else if (platform != null) { + xCoordinate = platform.sprite.x; + } else { + return false; + } + + Bug bug = Bug(gameRef); + bug.setPosition(xCoordinate, gameRef.blockSize * level); + + if (gameRef.isTooNearOtherObstacles(bug.sprite.toRect())) { + return false; + } + + objects[level].add(bug); + gameRef.add(bug.sprite); + if (platform != null) { + platform.removeChildren.add(() { + objects[level].remove(bug); + bug.remove(); + }); + } + return false; + } + } +} diff --git a/lib/holders/coin_holder.dart b/lib/holders/coin_holder.dart new file mode 100644 index 0000000..15df7b8 --- /dev/null +++ b/lib/holders/coin_holder.dart @@ -0,0 +1,94 @@ +import 'package:firo_runner/holders/holder.dart'; +import 'package:flame/components.dart'; + +import 'package:firo_runner/moving_objects/coin.dart'; +import 'package:firo_runner/main.dart'; +import 'package:flame/extensions.dart'; +import 'package:firo_runner/moving_objects/platform.dart'; + +class CoinHolder extends Holder { + late List coin; + late SpriteAnimationGroupComponent sprite; + late MyGame personalGameRef; + + @override + Future load() async { + coin = await loadListSprites("coin", "coin", 12); + SpriteAnimation normal = SpriteAnimation.spriteList(coin, stepTime: 0.1); + + sprite = SpriteAnimationGroupComponent( + animations: { + CoinState.normal: normal, + }, + current: CoinState.normal, + ); + + sprite.changePriorityWithoutResorting(COIN_PRIORITY); + + sprite.size = Vector2(20, 20); + } + + void setPersonalGameRef(MyGame gameRef) { + personalGameRef = gameRef; + } + + @override + void resize(Vector2 newSize, double xRatio, double yRatio) { + super.resize(newSize, xRatio, yRatio); + sprite.x *= xRatio; + sprite.y *= yRatio; + sprite.width *= xRatio; + sprite.height *= yRatio; + } + + void renderCoinScore(Canvas c) { + sprite.position = Vector2(personalGameRef.size.x - 70, 10); + sprite.render(c); + } + + List getCoin() { + return coin; + } + + bool generateCoin(MyGame gameRef, int level, + {bool force = false, double xPosition = 0}) { + if (total() > 5 && !force) { + return false; + } + + if (objects[level].isNotEmpty && !force) { + return false; + } + + if (random.nextInt(100) > 25 && !force) { + return true; + } else { + int nearestPlatform = getNearestPlatform(level); + + Platform? platform = + gameRef.platformHolder.getPlatformOffScreen(nearestPlatform); + double xCoordinate = -100; + + if (force) { + xCoordinate = xPosition; + } else if (level == 0) { + xCoordinate = gameRef.size.x; + } else if (platform != null) { + xCoordinate = platform.sprite.x; + } else { + return false; + } + + Coin coin = Coin(gameRef); + coin.setPosition(xCoordinate, gameRef.blockSize * level); + + if (gameRef.isTooNearOtherObstacles(coin.sprite.toRect()) && !force) { + return false; + } + + objects[level].add(coin); + gameRef.add(coin.sprite); + } + return false; + } +} diff --git a/lib/holders/debris_holder.dart b/lib/holders/debris_holder.dart new file mode 100644 index 0000000..c0d3f59 --- /dev/null +++ b/lib/holders/debris_holder.dart @@ -0,0 +1,67 @@ +import 'package:firo_runner/holders/holder.dart'; +import 'package:firo_runner/moving_objects/platform.dart'; +import 'package:flame/components.dart'; +import 'package:flame/extensions.dart'; +import 'package:flame/flame.dart'; + +import 'package:firo_runner/moving_objects/debris.dart'; +import 'package:firo_runner/main.dart'; + +class DebrisHolder extends Holder { + late List debris; + + @override + Future load() async { + debris = await loadListSprites("debris", "debris", 21); + } + + List getDebris() { + return debris; + } + + bool generateDebris(MyGame gameRef, int level, + {bool force = false, double xPosition = 0}) { + if (objects[level].isNotEmpty) { + return false; + } + + if (random.nextInt(100) > 25) { + return true; + } else { + int nearestPlatform = getNearestPlatform(level); + + Platform? platform = + gameRef.platformHolder.getPlatformOffScreen(nearestPlatform); + if (platform != null && platform.prohibitObstacles) { + return false; + } + double xCoordinate = -100; + + if (level == 0) { + xCoordinate = gameRef.size.x; + } else if (platform != null) { + xCoordinate = platform.sprite.x; + } else { + return false; + } + + Debris debris = Debris(gameRef); + debris.setPosition( + xCoordinate, gameRef.blockSize * level - gameRef.blockSize / 3); + + if (gameRef.isTooNearOtherObstacles(debris.sprite.toRect())) { + return false; + } + + objects[level].add(debris); + gameRef.add(debris.sprite); + if (platform != null) { + platform.removeChildren.add(() { + objects[level].remove(debris); + debris.remove(); + }); + } + return false; + } + } +} diff --git a/lib/holders/holder.dart b/lib/holders/holder.dart new file mode 100644 index 0000000..228bbc7 --- /dev/null +++ b/lib/holders/holder.dart @@ -0,0 +1,89 @@ +import 'dart:math'; + +import 'package:firo_runner/moving_objects/moving_object.dart'; + +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; +import 'package:flame/extensions.dart'; +import 'package:flame/flame.dart'; + +class Holder { + Random random = Random(); + + late List> objects = []; + + // Load method to be overridden by classes that extend this. + Future load() async {} + + // Basic method to reset the state of the holder object. + void setUp() { + for (int i = 0; i < objects.length; i++) { + for (int j = 0; j < objects[i].length; j++) { + remove(objects[i], j); + } + } + objects = []; + for (int i = 0; i < 9; i++) { + objects.add([]); + } + } + + // Get the total amount of objects currently in the logical game. + int total() { + int total = 0; + for (List levelObjects in objects) { + total += levelObjects.length; + } + return total; + } + + // Update every object that this holder holds. + void update(double dt) { + for (List objectLevel in objects) { + for (MovingObject p in objectLevel) { + p.update(dt); + } + } + } + + // Remove and object from this holder. + void remove(List levelHolder, int j) { + levelHolder[j].remove(); + levelHolder.removeAt(j); + } + + // Remove any object is past rendering distance. + void removePast(MyGame gameRef) { + for (List objectLevel in objects) { + for (int i = 0; i < objectLevel.length;) { + if (objectLevel[i].sprite.x + objectLevel[i].sprite.width < 0) { + remove(objectLevel, i); + continue; + } + i++; + } + } + } + + // Resize this object for screen rotations or changing window size. + void resize(Vector2 newSize, double xRatio, double yRatio) { + for (List platformLevel in objects) { + for (MovingObject p in platformLevel) { + p.resize(newSize, xRatio, yRatio); + } + } + } + + // Load sprites dynamically. + Future> loadListSprites( + String folderName, String extraName, int howManyFrames) async { + List sprites = []; + for (int i = 0; i < howManyFrames; i++) { + sprites.add(Sprite( + await Flame.images.load('$folderName/${extraName}_$i.png'), + )); + } + + return sprites; + } +} diff --git a/lib/holders/platform_holder.dart b/lib/holders/platform_holder.dart new file mode 100644 index 0000000..e447d4b --- /dev/null +++ b/lib/holders/platform_holder.dart @@ -0,0 +1,165 @@ +import 'package:firo_runner/holders/holder.dart'; +import 'package:firo_runner/main.dart'; +import 'package:firo_runner/moving_objects/moving_object.dart'; +import 'package:flame/components.dart'; +import 'package:firo_runner/moving_objects/platform.dart'; + +class PlatformHolder extends Holder { + late List l1; + late List l2; + late List m1; + late List m2; + late List r1; + late List r2; + late List o1; + late List o2; + bool noTopObstaclesForNext = false; + bool noMiddleObstaclesForNext = false; + int timeSinceLastTopHole = 0; + int timeSinceLastBottomHole = 0; + + @override + Future load() async { + l1 = await loadListSprites("platform", "platform-left-nowire-frames", 5); + l2 = await loadListSprites("platform", "platform-left-wire-frames", 5); + m1 = await loadListSprites("platform", "platform-mid-nowire-frames", 5); + m2 = await loadListSprites("platform", "platform-mid-wire-frames", 5); + r1 = await loadListSprites("platform", "platform-right-nowire-frames", 5); + r2 = await loadListSprites("platform", "platform-right-wire-frames", 5); + o1 = await loadListSprites("platform", "platform-single-nowire-frames", 5); + o2 = await loadListSprites("platform", "platform-single-wire-frames", 5); + } + + @override + void setUp() { + timeSinceLastTopHole = 0; + timeSinceLastBottomHole = 0; + super.setUp(); + } + + // Removes obstacles from around openings in the floor so that the game is + // not unfair to the player. + void removeUnfairObstacles( + MyGame gameRef, Platform currentPlatform, int from, int to) { + for (int i = from; i <= to; i++) { + if (i == 0) { + // First level has a harder difficulty curve, and no platforms are on + // level -1, so objects have to be removed differently. + List bugLevel = gameRef.bugHolder.objects[0]; + for (MovingObject bug in gameRef.bugHolder.objects[0]) { + if (bug.sprite.x >= currentPlatform.sprite.x && + bug.sprite.x < + currentPlatform.sprite.x + 4 * currentPlatform.sprite.width) { + gameRef.bugHolder.remove(bugLevel, bugLevel.indexOf(bug)); + } + } + List wireLevel = gameRef.wireHolder.objects[0]; + for (MovingObject wire in gameRef.wireHolder.objects[0]) { + if (wire.sprite.x >= currentPlatform.sprite.x && + wire.sprite.x < + currentPlatform.sprite.x + 4 * currentPlatform.sprite.width) { + gameRef.wireHolder.remove(wireLevel, wireLevel.indexOf(wire)); + } + } + } else { + // All other objects on the other levels can be removed simply. + int nearestPlatform = getNearestPlatform(i); + for (MovingObject platform in objects[nearestPlatform]) { + if (platform.sprite.x >= currentPlatform.sprite.x && + platform.sprite.x < + currentPlatform.sprite.x + 4 * currentPlatform.sprite.width) { + (platform as Platform).removeChildrenObjects(); + platform.prohibitObstacles = true; + } + } + } + } + } + + // Generate all the platforms in the game. + // Including top openings, and bottom structures. + void generatePlatforms(MyGame gameRef) { + while (!generatePlatform(gameRef, 2)) { + timeSinceLastTopHole++; + } + while (!generatePlatform(gameRef, 5)) { + timeSinceLastBottomHole++; + } + + int topChance = + random.nextInt(timeSinceLastTopHole > 0 ? timeSinceLastTopHole : 1); + int bottomChance = random + .nextInt(timeSinceLastBottomHole > 0 ? timeSinceLastBottomHole : 1); + + if (topChance > 50) { + removeUnfairObstacles( + gameRef, objects[2][objects[2].length - 4] as Platform, 0, 4); + // Create an opening in the top. + remove(objects[2], objects[2].length - 2); + remove(objects[2], objects[2].length - 2); + + timeSinceLastTopHole = 0; + noTopObstaclesForNext = true; + } + if (bottomChance > 30) { + Platform start = objects[5].elementAt(objects[5].length - 10) as Platform; + generatePlatform(gameRef, 8, xPosition: start.sprite.position.x); + for (int i = 0; i < 8; i++) { + generatePlatform(gameRef, 8); + } + int lastToRemove = objects[5].length - 3; + int firstToRemove = objects[5].length - 10; + + removeUnfairObstacles( + gameRef, objects[5][lastToRemove - 1] as Platform, 3, 7); + remove(objects[5], lastToRemove); + remove(objects[5], lastToRemove); + + removeUnfairObstacles( + gameRef, objects[5][firstToRemove - 1] as Platform, 3, 7); + remove(objects[5], firstToRemove); + remove(objects[5], firstToRemove); + + timeSinceLastBottomHole = 0; + noMiddleObstaclesForNext = true; + } + } + + // Create a platform object. + bool generatePlatform(MyGame gameRef, int level, {double xPosition = 0}) { + double xCoordinate = xPosition; + if (objects[level].isNotEmpty && xPosition == 0) { + xCoordinate = objects[level].last.getRightEnd(); + } + + if (xCoordinate > gameRef.size.x + 2000) { + return true; + } else { + Platform platform = Platform(gameRef); + platform.setPosition(xCoordinate, gameRef.blockSize * level); + platform.row = level; + gameRef.add(platform.sprite); + objects[level].add(platform); + if (level == 2 && noTopObstaclesForNext) { + platform.prohibitObstacles = true; + noTopObstaclesForNext = false; + } else if (level == 5 && noMiddleObstaclesForNext) { + platform.prohibitObstacles = true; + noMiddleObstaclesForNext = false; + } + return false; + } + } + + // Choose a random platform that is off screen from the player. + Platform? getPlatformOffScreen(int level) { + for (int i = 0; i < objects[level].length; i++) { + Platform p = objects[level][i] as Platform; + if (p.sprite.x > p.gameRef.size.x) { + int chosenIndex = random.nextInt(objects[level].length - i) + i; + return objects[level][chosenIndex] as Platform; + } + } + return null; + } +} diff --git a/lib/holders/wall_holder.dart b/lib/holders/wall_holder.dart new file mode 100644 index 0000000..be4bdbe --- /dev/null +++ b/lib/holders/wall_holder.dart @@ -0,0 +1,65 @@ +import 'package:firo_runner/holders/holder.dart'; +import 'package:firo_runner/moving_objects/platform.dart'; +import 'package:flame/components.dart'; + +import 'package:firo_runner/moving_objects/wall.dart'; +import 'package:firo_runner/main.dart'; + +class WallHolder extends Holder { + late List wall; + + @override + Future load() async { + wall = await loadListSprites("wall", "wall", 5); + } + + List getWall() { + return wall; + } + + bool generateWall(MyGame gameRef, int level, + {bool force = false, double xPosition = 0}) { + if (objects[level].isNotEmpty) { + return false; + } + + if (random.nextInt(100) > 25) { + return true; + } else { + int nearestPlatform = getNearestPlatform(level); + + Platform? platform = + gameRef.platformHolder.getPlatformOffScreen(nearestPlatform); + if (platform != null && platform.prohibitObstacles) { + return false; + } + double xCoordinate = -100; + + if (level == 0) { + xCoordinate = gameRef.size.x; + } else if (platform != null) { + xCoordinate = platform.sprite.x; + } else { + return false; + } + + Wall wall = Wall(gameRef); + wall.setPosition(xCoordinate, gameRef.blockSize * level); + wall.bottomPlatformLevel = level + 1; + + if (gameRef.isTooNearOtherObstacles(wall.sprite.toRect())) { + return false; + } + + objects[level].add(wall); + gameRef.add(wall.sprite); + if (platform != null) { + platform.removeChildren.add(() { + objects[level].remove(wall); + wall.remove(); + }); + } + return false; + } + } +} diff --git a/lib/holders/wire_holder.dart b/lib/holders/wire_holder.dart new file mode 100644 index 0000000..f2a8e75 --- /dev/null +++ b/lib/holders/wire_holder.dart @@ -0,0 +1,72 @@ +import 'package:firo_runner/holders/holder.dart'; +import 'package:firo_runner/moving_objects/platform.dart'; +import 'package:flame/components.dart'; + +import 'package:firo_runner/moving_objects/wire.dart'; +import 'package:firo_runner/main.dart'; + +class WireHolder extends Holder { + late List wire; + + @override + Future load() async { + wire = await loadListSprites("wire", "wire", 12); + } + + List getWire() { + return wire; + } + + bool generateWire(MyGame gameRef, int level, + {bool force = false, double xPosition = 0}) { + if (objects[level].isNotEmpty) { + return false; + } + + if (random.nextInt(100) > 100) { + return true; + } else { + int nearestPlatform = getNearestPlatform(level); + + Platform? platform = + gameRef.platformHolder.getPlatformOffScreen(nearestPlatform); + if (platform != null && platform.prohibitObstacles) { + return false; + } + double xCoordinate = -100; + + if (level == 0) { + xCoordinate = gameRef.size.x; + } else if (platform != null) { + xCoordinate = platform.sprite.x; + } else { + return false; + } + + Wire wire = Wire(gameRef); + wire.sprite.renderFlipX = true; + if (level % 3 == 0) { + wire.sprite.renderFlipY = true; + wire.setPosition( + xCoordinate, gameRef.blockSize * level - 2 * gameRef.blockSize / 7); + } else { + wire.setPosition( + xCoordinate, gameRef.blockSize * level + gameRef.blockSize / 10); + } + + if (gameRef.isTooNearOtherObstacles(wire.sprite.toRect())) { + return false; + } + + objects[level].add(wire); + gameRef.add(wire.sprite); + if (platform != null) { + platform.removeChildren.add(() { + objects[level].remove(wire); + wire.remove(); + }); + } + return false; + } + } +} diff --git a/lib/main.dart b/lib/main.dart index b9bfc38..6be2364 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,113 +1,649 @@ -import 'package:flutter/material.dart'; - -void main() { - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - MyHomePage({Key? key, required this.title}) : super(key: key); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - _MyHomePageState createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } -} +import 'dart:async'; +import 'dart:math'; + +import 'package:firo_runner/holders/bug_holder.dart'; +import 'package:firo_runner/moving_objects/circuit_background.dart'; +import 'package:firo_runner/holders/coin_holder.dart'; +import 'package:firo_runner/holders/debris_holder.dart'; +import 'package:firo_runner/overlays/deposit_overlay.dart'; +import 'package:firo_runner/firework.dart'; +import 'package:firo_runner/game_state.dart'; +import 'package:firo_runner/overlays/leader_board_overlay.dart'; +import 'package:firo_runner/moving_objects/moving_object.dart'; +import 'package:firo_runner/moving_objects/platform.dart'; +import 'package:firo_runner/holders/platform_holder.dart'; +import 'package:firo_runner/overlays/sign_in_overlay.dart'; +import 'package:firo_runner/holders/wall_holder.dart'; +import 'package:firo_runner/moving_objects/wire.dart'; +import 'package:firo_runner/holders/wire_holder.dart'; +import 'package:flame/components.dart'; +import 'package:flame/extensions.dart'; +import 'package:flame/flame.dart'; +import 'package:flame/game.dart'; +import 'package:flame/gestures.dart'; +import 'package:flame/keyboard.dart'; +import 'package:flame_audio/flame_audio.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:firo_runner/runner.dart'; +import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:http/http.dart' as http; + +import 'package:firo_runner/overlays/lose_menu_overlay.dart'; +import 'package:firo_runner/overlays/main_menu_overlay.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +// TODO Set NO_TOURNAMENT to false, and then set the SERVER and PORT for the +// firo runner server instance. +const NO_TOURNAMENT = false; +const SERVER = "http://10.0.0.224"; +const PORT = "50067"; + +const FIREWORK_COLOR = Color(0xFFDDC0A3); +const int LOADING_TIME = 2000000; + +// Variables that determine the score cutoff when each new level starts. +const LEVEL2 = 25000000; +const LEVEL3 = 50000000; +const LEVEL4 = 75000000; +const LEVEL5 = 100000000; +const LEVEL6 = 125000000; +const LEVEL7 = 150000000; + +// Variables that determine when to use the new robot animations. +const COINS_ROBOT_UPGRADE1 = 50; +const COINS_ROBOT_UPGRADE2 = 100; + +// Draw priority for objects, not meant to be changed. +const OVERLAY_PRIORITY = 110; +const RUNNER_PRIORITY = 100; +const BUG_PRIORITY = 75; +const COIN_PRIORITY = 70; +const PLATFORM_PRIORITY = 50; +const WALL_PRIORITY = 40; +const DEBRIS_PRIORITY = 30; +const WIRE_PRIORITY = 25; +const FIREWORK_PRIORITY = 15; +const WINDOW_PRIORITY = 10; + +// Preloading images for the overlays. +const AssetImage mainMenuImage = AssetImage('assets/images/mm3.gif'); +const AssetImage lossImage = AssetImage('assets/images/overlay100.png'); +const AssetImage buttonImage = AssetImage('assets/images/button-new.png'); + +// Colors of the overlay Themes. +const Color textColor = Colors.cyan; +const Color cardColor = Color(0xff262b3f); +const Color borderColor = Color(0xdfd675e1); +const Color titleColor = Color(0xff68d9cc); +const Color inactiveColor = Colors.grey; + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Flame.device.fullScreen(); + await Flame.device.setLandscape(); + final myGame = MyGame(); + runApp(MaterialApp( + debugShowCheckedModeBanner: false, + home: GameWidget( + game: myGame, + overlayBuilderMap: { + // Should be used once before all overlays are called. Flame has a slight + // delay when constructing the overlay widgets, so to make the text and + // images load together, all the other overlays should be called in the + // load section, and removed, and the loading black screen should be kept + // up until everything is finished loading. + 'loading': (_, myGame) { + return Center( + child: Container( + height: myGame.viewport.canvasSize.y, + width: myGame.viewport.canvasSize.x, + color: Colors.black, + ), + ); + }, + 'leaderboard': (_, myGame) { + return LeaderBoardOverlay(game: myGame); + }, + 'deposit': (_, myGame) { + return DepositOverlay(game: myGame); + }, + 'signin': (_, myGame) { + return SignInOverlay(game: myGame); + }, + 'mainMenu': (_, myGame) { + return MainMenuOverlay(game: myGame); + }, + 'gameOver': (_, myGame) { + return LoseMenuOverlay(game: myGame); + }, + }, + ))); +} + +// Grab the nearest platform. +int getNearestPlatform(int level) { + return level <= 0 + ? 0 + : level <= 3 + ? 2 + : level <= 6 + ? 5 + : 8; +} + +class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents { + TextPaint fireworksPaint = TextPaint( + config: const TextPaintConfig( + fontSize: 48.0, fontFamily: 'Codystar', color: FIREWORK_COLOR), + ); + + TextPaint scoresPaint = TextPaint( + config: const TextPaintConfig(fontSize: 16.0, color: FIREWORK_COLOR), + ); + + String leaderboard = ""; + String address = ""; + String username = ""; + int tries = 0; + bool competitive = false; + + late CircuitBackground circuitBackground; + late PlatformHolder platformHolder; + late CoinHolder coinHolder; + late WireHolder wireHolder; + late BugHolder bugHolder; + late Firework fireworks; + late DebrisHolder debrisHolder; + late WallHolder wallHolder; + Random random = Random(); + bool playingMusic = false; + + late Runner runner; + late GameState gameState; + late double blockSize; + + bool loaded = false; + bool firstDeath = true; + late Wire wire; + late TextComponent _distance; + late TextComponent _coins; + int startLoading = 0; + + MyGame() : super() { + viewport.resize(Vector2(1920, 1080)); + } + + // Load the game and all of its assets, may take a couple of seconds. + @override + Future onLoad() async { + // If playing in tournament mode, load all information from server. + if (!NO_TOURNAMENT) { + final prefs = await SharedPreferences.getInstance(); + username = prefs.getString('username') ?? ""; + tries = prefs.getInt('tries') ?? 0; + String result = await connectServer("gettries", "user=$username"); + try { + tries = int.parse(result); + prefs.setInt('tries', tries); + } catch (e) { + print(e); + } + } + FlameAudio.bgm.initialize(); + + // preload all audio assets. + await FlameAudio.audioCache.loadAll([ + 'sfx/coin_catch.mp3', + 'sfx/glitch_death.mp3', + 'sfx/jet_boost.mp3', + 'sfx/menu_button.mp3', + 'sfx/obstacle_death.mp3', + 'sfx/robot_friend_beep.mp3', + 'sfx/button_click.mp3', + 'sfx/land.mp3', + 'sfx/laser.mp3', + 'sfx/shield.mp3', + 'sfx/bug_death1.mp3', + 'sfx/fireworks.mp3', + 'sfx/fall_death_speed.mp3', + 'Infinite_Menu.mp3', + 'Infinite_Spankage_M.mp3', + ]); + + // Load each object. + circuitBackground = CircuitBackground(this); + await circuitBackground.load(); + platformHolder = PlatformHolder(); + await platformHolder.load(); + coinHolder = CoinHolder(); + coinHolder.setPersonalGameRef(this); + await coinHolder.load(); + wireHolder = WireHolder(); + await wireHolder.load(); + bugHolder = BugHolder(); + await bugHolder.load(); + debrisHolder = DebrisHolder(); + await debrisHolder.load(); + wallHolder = WallHolder(); + await wallHolder.load(); + fireworks = Firework(this); + await fireworks.load(); + + gameState = GameState(); + + runner = Runner(); + await runner.load(); + + // Set up game UI + loaded = true; + _distance = TextComponent("Time: 0", + position: Vector2(size.x - 100, 10), textRenderer: scoresPaint) + ..anchor = Anchor.topRight; + _distance.changePriorityWithoutResorting(OVERLAY_PRIORITY); + _coins = TextComponent(": 0", + position: Vector2(size.x - 20, 10), textRenderer: scoresPaint) + ..anchor = Anchor.topRight; + _coins.changePriorityWithoutResorting(OVERLAY_PRIORITY); + + // add all overlays first since the first time they are added there is a + // delay, so calling it earlier makes a smoother experience. + overlays.add("leaderboard"); + overlays.remove('leaderboard'); + overlays.add("deposit"); + overlays.remove('deposit'); + overlays.add("signin"); + overlays.remove('signin'); + overlays.add("gameOver"); + overlays.remove('gameOver'); + overlays.add("mainMenu"); + overlays.add('loading'); + + // set up the game and pause it. + setUp(); + gameState.setPaused(); + startLoading = DateTime.now().microsecondsSinceEpoch; + } + + // Choose which music to play. Useful since web browser does not let you play + // music until the user interacts with the website. + void playMusic() { + if (overlays.isActive('mainMenu')) { + FlameAudio.bgm.play('Infinite_Menu.mp3'); + } else { + FlameAudio.bgm.play('Infinite_Spankage_M.mp3'); + } + playingMusic = true; + } + + // Fill the screen with platforms and all of the obstacles. + void fillScreen() { + if (shouldReset) { + return; + } + int dangerLevel = gameState.getDangerLevel(); + + platformHolder.generatePlatforms(this); + + if (dangerLevel > 2) { + int wireChosenRegion = random.nextInt(9); + if (wireChosenRegion % 3 != 2 && + wireChosenRegion != 6 && + wireChosenRegion != 7) { + wireHolder.generateWire(this, wireChosenRegion); + } + } + + if (dangerLevel > 0) { + int bugChosenRegion = random.nextInt(9); + if (bugChosenRegion % 3 != 2 && bugChosenRegion % 3 != 0) { + bugHolder.generateBug(this, bugChosenRegion); + } + } + + if (dangerLevel > 1) { + int debrisChosenRegion = random.nextInt(9); + if (debrisChosenRegion % 3 == 0 && debrisChosenRegion != 6) { + debrisHolder.generateDebris(this, debrisChosenRegion); + } + } + + int choseCoinLevel = random.nextInt(9); + if (choseCoinLevel % 3 != 2 && choseCoinLevel != 6) { + coinHolder.generateCoin(this, choseCoinLevel); + } + + if (dangerLevel > 4) { + int wallChosenRegion = random.nextInt(9); + if (wallChosenRegion % 3 == 1 && wallChosenRegion != 7) { + wallHolder.generateWall(this, wallChosenRegion); + } + } + } + + // Check if an obstacle is being placed too near another obstacle, + // to ensure fairness for the player. + bool isTooNearOtherObstacles(Rect rect) { + Rect obstacleBounds = Rect.fromLTRB( + 3 * rect.left - 2 * (rect.left + blockSize) - 1, + 3 * rect.top - 2 * (rect.top + blockSize) - 1, + 3 * (rect.left + blockSize) - 2 * rect.left + 1, + 3 * (rect.top + blockSize) - 2 * rect.top + 1); + for (List wireLevel in wireHolder.objects) { + for (MovingObject wire in wireLevel) { + if (wire.intersect(obstacleBounds) != "none") { + return true; + } + } + } + + for (List coinLevel in coinHolder.objects) { + for (MovingObject coin in coinLevel) { + if (coin.intersect(obstacleBounds) != "none") { + return true; + } + } + } + + for (List bugLevel in bugHolder.objects) { + for (MovingObject bug in bugLevel) { + if (bug.intersect(obstacleBounds) != "none") { + return true; + } + } + } + + for (List debrisLevel in debrisHolder.objects) { + for (MovingObject debris in debrisLevel) { + if (debris.intersect(obstacleBounds) != "none") { + return true; + } + } + } + + for (List wallLevel in wallHolder.objects) { + for (MovingObject wall in wallLevel) { + if (wall.intersect(obstacleBounds) != "none") { + return true; + } + } + } + + return false; + } + + bool shouldReset = false; + + // Connect to the server in online mode to get information and to participate + // in the weekly tournament. + Future connectServer(String command, String arguments) async { + try { + final response = await http.post( + Uri.parse("$SERVER:$PORT/$command?$arguments"), + headers: { + 'Content-Type': 'application/json; charset=UTF-8', + }, + ); + if (response.statusCode == 200) { + // If the server did return a 200, + // then parse the JSON. + return response.body; + } else { + // If the server did not return a 201 CREATED response, + // then throw an exception. + throw Exception('Failed to connect to Firo Runner server.'); + } + // var value = await channel.stream.first; + // print(value); + } catch (e) { + print(e); + return ""; + } + } + + // Put the loss screen up. + Future displayLoss() async { + if (!(runner.sprite.animation?.done() ?? false) && + runner.sprite.animation!.loop == false && + firstDeath) { + return; + } + firstDeath = false; + overlays.add('gameOver'); + } + + // Put the main menu screen up. + void mainMenu() { + overlays.remove('gameOver'); + overlays.add('mainMenu'); + FlameAudio.bgm.stop(); + FlameAudio.bgm.play('Infinite_Menu.mp3'); + } + + // reset the game. + void reset() { + runner.sprite.animation!.reset(); + overlays.remove('gameOver'); + overlays.remove('mainMenu'); + shouldReset = false; + components.clear(); + setUp(); + } + + // process after a death. + Future die() async { + gameState.setPaused(); + // if in a tournament mode update information. + if (!NO_TOURNAMENT) { + final prefs = await SharedPreferences.getInstance(); + if (username != "" && competitive) { + await connectServer( + "newscore", "user=$username&score=${gameState.getPlayerScore()}"); + } + tries = prefs.getInt('tries') ?? 0; + String result = await connectServer("gettries", "user=$username"); + try { + tries = int.parse(result); + prefs.setInt('tries', tries); + } catch (e) { + print(e); + } + } + shouldReset = true; + } + + // set up the game for another run. + void setUp() { + add(runner); + fireworks.setUp(); + runner.sprite.clearEffects(); + runner.sprite.current = RunnerState.run; + circuitBackground.setUp(); + platformHolder.setUp(); + coinHolder.setUp(); + wireHolder.setUp(); + bugHolder.setUp(); + debrisHolder.setUp(); + wallHolder.setUp(); + + gameState.setUp(this); + + runner.setUp(); + add(_coins); + add(_distance); + + fillScreen(); + platformHolder.objects[2][0].sprite.current = PlatformState.left; + platformHolder.objects[5][0].sprite.current = PlatformState.left; + } + + @override + void render(Canvas canvas) { + if (!overlays.isActive('mainMenu')) { + circuitBackground.render(canvas); + fireworks.renderText(canvas); + super.render(canvas); + coinHolder.renderCoinScore(canvas); + } + } + + @override + void update(double dt) { + if (overlays.isActive('loading') && + (DateTime.now().microsecondsSinceEpoch - startLoading) > LOADING_TIME) { + overlays.remove('loading'); + if (!kIsWeb) { + playMusic(); + } + } + fireworks.update(dt); + platformHolder.removePast(this); + coinHolder.removePast(this); + wireHolder.removePast(this); + bugHolder.removePast(this); + debrisHolder.removePast(this); + wallHolder.removePast(this); + fillScreen(); + super.update(dt); + circuitBackground.update(dt); + gameState.update(dt); + platformHolder.update(dt); + coinHolder.update(dt); + wireHolder.update(dt); + bugHolder.update(dt); + debrisHolder.update(dt); + wallHolder.update(dt); + + _distance.text = "Time: ${gameState.getPlayerTime()}"; + _coins.text = " ${gameState.numCoins}"; + if (shouldReset && + !overlays.isActive('gameOver') && + !overlays.isActive('mainMenu')) { + displayLoss(); + } + } + + @override + void onResize(Vector2 canvasSize) { + Vector2 oldSize = viewport.canvasSize; + super.onResize(canvasSize); + blockSize = canvasSize.y / 9; + if (loaded) { + double xRatio = canvasSize.x / oldSize.x; + double yRatio = canvasSize.y / oldSize.y; + circuitBackground.resize(canvasSize, xRatio, yRatio); + runner.resize(canvasSize, xRatio, yRatio); + platformHolder.resize(canvasSize, xRatio, yRatio); + coinHolder.resize(canvasSize, xRatio, yRatio); + wireHolder.resize(canvasSize, xRatio, yRatio); + bugHolder.resize(canvasSize, xRatio, yRatio); + debrisHolder.resize(canvasSize, xRatio, yRatio); + wallHolder.resize(canvasSize, xRatio, yRatio); + fireworks.resize(canvasSize, xRatio, yRatio); + } + } + + // Mobile controls + late List xDeltas; + late List yDeltas; + @override + void onPanStart(DragStartInfo info) { + xDeltas = List.empty(growable: true); + yDeltas = List.empty(growable: true); + } + + bool action = false; + + @override + void onPanUpdate(DragUpdateInfo info) { + xDeltas.add(info.delta.game.x); + yDeltas.add(info.delta.game.y); + if (xDeltas.length > 2 && !action) { + action = true; + if (!playingMusic && kIsWeb) { + playMusic(); + } + double xDelta = xDeltas.isEmpty + ? 0 + : xDeltas.reduce((value, element) => value + element); + double yDelta = yDeltas.isEmpty + ? 0 + : yDeltas.reduce((value, element) => value + element); + if (xDelta.abs() > yDelta.abs()) { + if (xDelta > 0) { + runner.control("right"); + } else { + runner.control("left"); + } + } else if (xDelta.abs() < yDelta.abs()) { + if (yDelta > 0) { + runner.control("down"); + } else { + runner.control("up"); + } + } + xDeltas = List.empty(growable: true); + yDeltas = List.empty(growable: true); + } + } + + @override + void onPanEnd(DragEndInfo info) { + action = false; + xDeltas = List.empty(growable: true); + yDeltas = List.empty(growable: true); + } + + @override + void onTap() { + if (!playingMusic && kIsWeb) { + playMusic(); + } + runner.control("center"); + } + + // Keyboard controls. + var keyboardKey; + @override + void onKeyEvent(RawKeyEvent event) { + if (!playingMusic && kIsWeb) { + playMusic(); + } + if (event is RawKeyDownEvent) { + action = true; + keyboardKey = null; + switch (event.data.logicalKey.keyId) { + case 4294968068: + case 119: + case 87: + // case "w": + runner.control("up"); + break; + case 4294968066: + case 97: + case 65: + // case "a": + runner.control("left"); + break; + case 4294968065: + case 115: + case 83: + // case "s": + runner.control("down"); + break; + case 4294968067: + case 100: + case 68: + // case "d": + runner.control("right"); + break; + default: + break; + } + } + + if (event is RawKeyUpEvent) { + action = false; + } + } +} diff --git a/lib/moving_objects/bug.dart b/lib/moving_objects/bug.dart new file mode 100644 index 0000000..45a9eb2 --- /dev/null +++ b/lib/moving_objects/bug.dart @@ -0,0 +1,31 @@ +import 'package:firo_runner/moving_objects/moving_object.dart'; +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; + +enum BugState { normal, breaking } + +class Bug extends MovingObject { + Bug(MyGame gameRef) : super(gameRef) { + List bug = gameRef.bugHolder.getBug("normal"); + List breakingImage = gameRef.bugHolder.getBug("breaking"); + SpriteAnimation normal = SpriteAnimation.spriteList(bug, stepTime: 0.1); + + SpriteAnimation breaking = + SpriteAnimation.spriteList(breakingImage, stepTime: 0.01, loop: false); + + sprite = SpriteAnimationGroupComponent( + animations: { + BugState.normal: normal, + BugState.breaking: breaking, + }, + current: BugState.normal, + ); + + sprite.changePriorityWithoutResorting(BUG_PRIORITY); + + setSize( + gameRef.blockSize, + gameRef.blockSize, + ); + } +} diff --git a/lib/moving_objects/circuit_background.dart b/lib/moving_objects/circuit_background.dart new file mode 100644 index 0000000..3da1a8d --- /dev/null +++ b/lib/moving_objects/circuit_background.dart @@ -0,0 +1,398 @@ +import 'package:firo_runner/moving_objects/moving_object.dart'; +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; +import 'package:flame/flame.dart'; +import 'package:flame/extensions.dart'; + +enum WindowState { + first, + second, + third, + fourth, + fifth, + sixth, + seventh, +} + +enum OverlayState { + first, + second, + third, + fourth, + fifth, + sixth, + seventh, +} + +// Class for the moving background. +class CircuitBackground extends MovingObject { + late Image background; + + late Image overlay0; + late Image overlay1; + late Image overlay2; + late Image overlay3; + late Image overlay4; + late Image overlay5; + late Image overlay6; + + late Image windows0; + late Image windows1; + late Image windows2; + late Image windows3; + late Image windows4; + late Image windows5; + late Image windows6; + + late Sprite background1; + late Sprite background2; + late SpriteAnimationGroupComponent windowA; + late SpriteAnimationGroupComponent windowB; + late SpriteAnimationGroupComponent overlayA; + late SpriteAnimationGroupComponent overlayB; + Vector2 background1Size = Vector2(0, 0); + Vector2 background2Size = Vector2(0, 0); + Vector2 background1Position = Vector2(0, 0); + Vector2 background2Position = Vector2(0, 0); + + CircuitBackground(MyGame gameRef) : super(gameRef); + + Future load() async { + background = await Flame.images.load("bg.png"); + background1 = Sprite(background); + background2 = Sprite(background); + + overlay0 = await Flame.images.load("overlay100.png"); + overlay1 = await Flame.images.load("overlay90.png"); + overlay2 = await Flame.images.load("overlay80.png"); + overlay3 = await Flame.images.load("overlay70.png"); + overlay4 = await Flame.images.load("overlay60.png"); + overlay5 = await Flame.images.load("overlay50.png"); + overlay6 = await Flame.images.load("overlay40.png"); + + SpriteAnimation firstOverlay = SpriteAnimation.fromFrameData( + overlay0, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation secondOverlay = SpriteAnimation.fromFrameData( + overlay1, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation thirdOverlay = SpriteAnimation.fromFrameData( + overlay2, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation fourthOverlay = SpriteAnimation.fromFrameData( + overlay3, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation fifthOverlay = SpriteAnimation.fromFrameData( + overlay4, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation sixthOverlay = SpriteAnimation.fromFrameData( + overlay5, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation seventhOverlay = SpriteAnimation.fromFrameData( + overlay6, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + overlayA = SpriteAnimationGroupComponent( + animations: { + OverlayState.first: firstOverlay, + OverlayState.second: secondOverlay, + OverlayState.third: thirdOverlay, + OverlayState.fourth: fourthOverlay, + OverlayState.fifth: fifthOverlay, + OverlayState.sixth: sixthOverlay, + OverlayState.seventh: seventhOverlay, + }, + current: OverlayState.first, + ); + + overlayB = SpriteAnimationGroupComponent( + animations: { + OverlayState.first: firstOverlay, + OverlayState.second: secondOverlay, + OverlayState.third: thirdOverlay, + OverlayState.fourth: fourthOverlay, + OverlayState.fifth: fifthOverlay, + OverlayState.sixth: sixthOverlay, + OverlayState.seventh: seventhOverlay, + }, + current: OverlayState.first, + ); + + overlayA.changePriorityWithoutResorting(WINDOW_PRIORITY - 1); + + overlayA.changePriorityWithoutResorting(WINDOW_PRIORITY - 1); + + windows0 = await Flame.images.load("windows-0.png"); + windows1 = await Flame.images.load("windows-1.png"); + windows2 = await Flame.images.load("windows-2.png"); + windows3 = await Flame.images.load("windows-3.png"); + windows4 = await Flame.images.load("windows-4.png"); + windows5 = await Flame.images.load("windows-5.png"); + windows6 = await Flame.images.load("windows-6.png"); + + SpriteAnimation firstWindow = SpriteAnimation.fromFrameData( + windows0, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation secondWindow = SpriteAnimation.fromFrameData( + windows1, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation thirdWindow = SpriteAnimation.fromFrameData( + windows2, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation fourthWindow = SpriteAnimation.fromFrameData( + windows3, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation fifthWindow = SpriteAnimation.fromFrameData( + windows4, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation sixthWindow = SpriteAnimation.fromFrameData( + windows5, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation seventhWindow = SpriteAnimation.fromFrameData( + windows6, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + windowA = SpriteAnimationGroupComponent( + animations: { + WindowState.first: firstWindow, + WindowState.second: secondWindow, + WindowState.third: thirdWindow, + WindowState.fourth: fourthWindow, + WindowState.fifth: fifthWindow, + WindowState.sixth: sixthWindow, + WindowState.seventh: seventhWindow, + }, + current: WindowState.first, + ); + + windowB = SpriteAnimationGroupComponent( + animations: { + WindowState.first: firstWindow, + WindowState.second: secondWindow, + WindowState.third: thirdWindow, + WindowState.fourth: fourthWindow, + WindowState.fifth: fifthWindow, + WindowState.sixth: sixthWindow, + WindowState.seventh: seventhWindow, + }, + current: WindowState.first, + ); + + windowA.changePriorityWithoutResorting(WINDOW_PRIORITY); + + windowA.changePriorityWithoutResorting(WINDOW_PRIORITY); + + setUp(); + } + + void setUp() { + windowA.current = WindowState.first; + windowB.current = WindowState.first; + overlayA.current = OverlayState.first; + overlayB.current = OverlayState.first; + background1Position = Vector2(0, 0); + background1Size = Vector2( + gameRef.viewport.canvasSize.y * (background.width / background.height), + gameRef.viewport.canvasSize.y); + windowA.position = background1Position; + windowA.size = background1Size; + overlayA.position = background1Position; + overlayA.size = background1Size; + + background2Position = + Vector2(background1Position.x + background1Size.x - 1, 0); + background2Size = Vector2( + gameRef.viewport.canvasSize.y * (background.width / background.height), + gameRef.viewport.canvasSize.y); + windowB.position = background2Position; + windowB.size = background2Size; + overlayB.position = background2Position; + overlayB.size = background2Size; + } + + @override + void update(double dt) { + switch (gameRef.gameState.getScoreLevel()) { + case 12: + windowA.current = WindowState.seventh; + windowB.current = WindowState.seventh; + break; + case 11: + overlayA.current = OverlayState.seventh; + overlayB.current = OverlayState.seventh; + break; + case 10: + windowA.current = WindowState.sixth; + windowB.current = WindowState.sixth; + break; + case 9: + overlayA.current = OverlayState.sixth; + overlayB.current = OverlayState.sixth; + break; + case 8: + windowA.current = WindowState.fifth; + windowB.current = WindowState.fifth; + break; + case 7: + overlayA.current = OverlayState.fifth; + overlayB.current = OverlayState.fifth; + break; + case 6: + windowA.current = WindowState.fourth; + windowB.current = WindowState.fourth; + break; + case 5: + overlayA.current = OverlayState.fourth; + overlayB.current = OverlayState.fourth; + break; + case 4: + windowA.current = WindowState.third; + windowB.current = WindowState.third; + break; + case 3: + overlayA.current = OverlayState.third; + overlayB.current = OverlayState.third; + break; + case 2: + windowA.current = WindowState.second; + windowB.current = WindowState.second; + break; + case 1: + overlayA.current = OverlayState.second; + overlayB.current = OverlayState.second; + break; + default: + windowA.current = WindowState.first; + windowB.current = WindowState.first; + overlayA.current = OverlayState.first; + overlayB.current = OverlayState.first; + break; + } + windowA.update(dt); + windowB.update(dt); + overlayA.update(dt); + overlayB.update(dt); + if (background1Position.x + background1Size.x < 0) { + double newPosition = background2Position.x + background2Size.x; + background1Position = Vector2(newPosition - 1, 0); + } else if (background2Position.x + background2Size.x < 0) { + double newPosition = background1Position.x + background1Size.x; + background2Position = Vector2(newPosition - 1, 0); + } + + double velocity = gameRef.gameState.getVelocity() / 10.0; + background1Position = background1Position - Vector2(velocity * dt, 0); + windowA.position = background1Position; + overlayA.position = background1Position; + background2Position = background2Position - Vector2(velocity * dt, 0); + windowB.position = background2Position; + overlayB.position = background2Position; + } + + void render(Canvas canvas) { + background1.render(canvas, + size: background1Size, position: background1Position); + canvas.save(); + overlayA.render(canvas); + canvas.restore(); + canvas.save(); + windowA.render(canvas); + canvas.restore(); + background2.render(canvas, + size: background2Size, position: background2Position); + canvas.save(); + overlayB.render(canvas); + canvas.restore(); + canvas.save(); + windowB.render(canvas); + canvas.restore(); + } + + @override + void resize(Vector2 newSize, double xRatio, double yRatio) { + background1Position.x *= xRatio; + background1Position.y *= yRatio; + background1Size.x *= xRatio; + background1Size.y *= yRatio; + background2Position.x *= xRatio; + background2Position.y *= yRatio; + background2Size.x *= xRatio; + background2Size.y *= yRatio; + windowA.position = background1Position; + windowA.size = background1Size; + overlayA.position = background1Position; + overlayA.size = background1Size; + windowB.position = background2Position; + windowB.size = background2Size; + overlayB.position = background2Position; + overlayB.size = background2Size; + } +} diff --git a/lib/moving_objects/coin.dart b/lib/moving_objects/coin.dart new file mode 100644 index 0000000..d6e2f25 --- /dev/null +++ b/lib/moving_objects/coin.dart @@ -0,0 +1,28 @@ +import 'package:firo_runner/moving_objects/moving_object.dart'; +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; + +enum CoinState { normal } + +class Coin extends MovingObject { + Coin(MyGame gameRef) : super(gameRef) { + List coin = gameRef.coinHolder.getCoin(); + SpriteAnimation normal = SpriteAnimation.spriteList(coin, stepTime: 0.1); + + sprite = SpriteAnimationGroupComponent( + animations: { + CoinState.normal: normal, + }, + current: CoinState.normal, + ); + + sprite.changePriorityWithoutResorting(COIN_PRIORITY); + + var platform = gameRef.platformHolder.l1[0].image; + + setSize( + gameRef.blockSize * (platform.width / platform.height / 2.8), + gameRef.blockSize * (platform.width / platform.height / 2.8), + ); + } +} diff --git a/lib/moving_objects/debris.dart b/lib/moving_objects/debris.dart new file mode 100644 index 0000000..f9568d9 --- /dev/null +++ b/lib/moving_objects/debris.dart @@ -0,0 +1,29 @@ +import 'package:firo_runner/moving_objects/moving_object.dart'; +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; + +enum DebrisState { normal } + +class Debris extends MovingObject { + Debris(MyGame gameRef) : super(gameRef) { + List debris = gameRef.debrisHolder.getDebris(); + SpriteAnimation normal = SpriteAnimation.spriteList(debris, stepTime: 0.1); + + sprite = SpriteAnimationGroupComponent( + animations: { + DebrisState.normal: normal, + }, + current: DebrisState.normal, + ); + + sprite.changePriorityWithoutResorting(DEBRIS_PRIORITY); + + setSize( + gameRef.blockSize * + (gameRef.debrisHolder.debris[0].image.width / + gameRef.debrisHolder.debris[0].image.height) * + 1.5, + gameRef.blockSize * 1.5, + ); + } +} diff --git a/lib/moving_objects/moving_object.dart b/lib/moving_objects/moving_object.dart new file mode 100644 index 0000000..f914d1a --- /dev/null +++ b/lib/moving_objects/moving_object.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; + +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; + +// Class meant to be extended by any object that will move left on the screen. +// Ensures a relatively constant moving velocity, and takes care of sprite +// animations and positioning. +class MovingObject { + late SpriteAnimationGroupComponent sprite; + MyGame gameRef; + + MovingObject(this.gameRef); + + void setPosition(double x, double y) { + sprite.position = Vector2(x, y); + } + + void setSize(double x, double y) { + sprite.size = Vector2(x, y); + } + + Sprite getSprite() { + return sprite.animation!.getSprite(); + } + + void update(double dt) { + double velocity = gameRef.gameState.getVelocity(); + sprite.position = sprite.position - Vector2(velocity * dt, 0); + } + + // Get the rightmost pixel position of this sprite. + double getRightEnd() { + return sprite.position.x + sprite.width; + } + + void remove() { + sprite.remove(); + } + + // See where this object intersects another object if at all. + String intersect(Rect other) { + final collision = sprite.toRect().intersect(other); + if (!collision.isEmpty) { + double yDistance = other.top - sprite.toRect().top; + double xDistance = other.left - sprite.toRect().left; + if (yDistance.abs() > xDistance.abs()) { + if (yDistance > 0) { + return "bottom"; + } else { + return "top"; + } + } else { + if (xDistance > 0) { + return "right"; + } else { + return "left"; + } + } + } + return "none"; + } + + // Resize the object for chaning screen sizes. + void resize(Vector2 newSize, double xRatio, double yRatio) { + sprite.x *= xRatio; + sprite.y *= yRatio; + sprite.width *= xRatio; + sprite.height *= yRatio; + } +} diff --git a/lib/moving_objects/platform.dart b/lib/moving_objects/platform.dart new file mode 100644 index 0000000..03383ab --- /dev/null +++ b/lib/moving_objects/platform.dart @@ -0,0 +1,109 @@ +import 'dart:math'; + +import 'package:firo_runner/moving_objects/moving_object.dart'; +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; + +enum PlatformState { + left, + mid, + right, + single, +} + +class Platform extends MovingObject { + int row = 0; + bool prohibitObstacles = false; + List removeChildren = []; + + Platform(MyGame gameRef) : super(gameRef) { + var random = Random(); + + int version = random.nextInt(2); + + SpriteAnimation left = SpriteAnimation.spriteList( + version == 0 ? gameRef.platformHolder.l1 : gameRef.platformHolder.l2, + stepTime: 0.12); + + SpriteAnimation mid = SpriteAnimation.spriteList( + version == 0 ? gameRef.platformHolder.m1 : gameRef.platformHolder.m2, + stepTime: 0.12); + + SpriteAnimation right = SpriteAnimation.spriteList( + version == 0 ? gameRef.platformHolder.r1 : gameRef.platformHolder.r2, + stepTime: 0.12); + + SpriteAnimation single = SpriteAnimation.spriteList( + version == 0 ? gameRef.platformHolder.o1 : gameRef.platformHolder.o2, + stepTime: 0.12); + + sprite = SpriteAnimationGroupComponent( + animations: { + PlatformState.left: left, + PlatformState.mid: mid, + PlatformState.right: right, + PlatformState.single: single, + }, + current: PlatformState.mid, + ); + + sprite.changePriorityWithoutResorting(PLATFORM_PRIORITY); + + setSize( + gameRef.blockSize * + (gameRef.platformHolder.l1[0].image.width / + gameRef.platformHolder.l1[0].image.height), + gameRef.blockSize, + ); + } + + @override + void remove() { + removeChildrenObjects(); + super.remove(); + } + + void removeChildrenObjects() { + if (removeChildren.isNotEmpty) { + for (Function removeChild in removeChildren) { + removeChild(); + } + } + } + + @override + void update(double dt) { + List platformLevel = gameRef.platformHolder.objects[row]; + int index = platformLevel.indexOf(this); + Vector2 right = Vector2(-200, -200); + if (index + 1 < platformLevel.length) { + right = platformLevel.elementAt(index + 1).sprite.position; + } + super.update(dt); + if (index == -1 || (index < 1 && sprite.x <= sprite.width)) { + return; + } + Vector2 left = Vector2(-200, -200); + if (index - 1 >= 0) { + left = platformLevel.elementAt(index - 1).sprite.position; + } + + bool hasLeft = (left.x - sprite.position.x).abs() < 2.5 * sprite.size.x; + bool hasRight = (sprite.position.x - right.x).abs() < 2.5 * sprite.size.x; + + // If the platform cannot be seen by the player. + if (!((sprite.x >= 0 && sprite.x <= gameRef.size.x) || + (sprite.x + sprite.width >= 0 && + sprite.x + sprite.width <= gameRef.size.x))) { + if (hasLeft && hasRight) { + sprite.current = PlatformState.mid; + } else if (hasLeft && !hasRight) { + sprite.current = PlatformState.right; + } else if (!hasLeft && hasRight) { + sprite.current = PlatformState.left; + } else { + sprite.current = PlatformState.single; + } + } + } +} diff --git a/lib/moving_objects/wall.dart b/lib/moving_objects/wall.dart new file mode 100644 index 0000000..3f00d58 --- /dev/null +++ b/lib/moving_objects/wall.dart @@ -0,0 +1,50 @@ +import 'package:firo_runner/moving_objects/moving_object.dart'; +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; + +enum WallState { normal } + +class Wall extends MovingObject { + int direction = -1; + late int bottomPlatformLevel; + Wall(MyGame gameRef) : super(gameRef) { + List wall = gameRef.wallHolder.getWall(); + SpriteAnimation normal = SpriteAnimation.spriteList(wall, stepTime: 0.1); + + sprite = SpriteAnimationGroupComponent( + animations: { + WallState.normal: normal, + }, + current: WallState.normal, + ); + + sprite.changePriorityWithoutResorting(WALL_PRIORITY); + + setSize( + gameRef.blockSize * + (gameRef.wallHolder.wall[0].image.width / + gameRef.wallHolder.wall[0].image.height) * + 2.0, + gameRef.blockSize * 0.35, + ); + } + + // Override the update method so that this object can also move vertically + // as an obstacle. + @override + void update(double dt) { + super.update(dt); + int nearestPlatform = + getNearestPlatform((sprite.x / gameRef.blockSize).round()); + nearestPlatform = nearestPlatform == 0 ? -1 : nearestPlatform; + if (sprite.y + sprite.height > bottomPlatformLevel * gameRef.blockSize) { + direction = -1; + } else if ((bottomPlatformLevel - 2) * gameRef.blockSize - + 2 * gameRef.blockSize / 7 > + sprite.y) { + direction = 1; + } + double velocity = gameRef.gameState.getVelocity() / 10.0; + sprite.position = sprite.position + Vector2(0, direction * velocity * dt); + } +} diff --git a/lib/moving_objects/wire.dart b/lib/moving_objects/wire.dart new file mode 100644 index 0000000..c4f4a53 --- /dev/null +++ b/lib/moving_objects/wire.dart @@ -0,0 +1,59 @@ +import 'package:firo_runner/moving_objects/moving_object.dart'; +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; +import 'package:flutter/material.dart'; + +enum WireState { normal } + +class Wire extends MovingObject { + Wire(MyGame gameRef) : super(gameRef) { + List wire = gameRef.wireHolder.getWire(); + SpriteAnimation normal = SpriteAnimation.spriteList(wire, stepTime: 0.05); + + sprite = SpriteAnimationGroupComponent( + animations: { + WireState.normal: normal, + }, + current: WireState.normal, + ); + + sprite.changePriorityWithoutResorting(WIRE_PRIORITY); + + setSize( + gameRef.blockSize, + gameRef.blockSize, + ); + } + + // Override the intersect method so that the hitbox is smaller for the wires, + // this will be more fair to the player. + @override + String intersect(Rect other) { + Rect currentRect = sprite.toRect(); + Rect wireRect = Rect.fromLTWH( + currentRect.left + 2 * currentRect.width / 5, + currentRect.top + 2 * currentRect.height / 7, + currentRect.width / 5, + currentRect.height / 5, + ); + final collision = wireRect.intersect(other); + if (!collision.isEmpty) { + double yDistance = other.top - wireRect.top; + double xDistance = other.left - wireRect.left; + if (yDistance.abs() > xDistance.abs()) { + if (yDistance > 0) { + return "bottom"; + } else { + return "top"; + } + } else { + if (xDistance > 0) { + return "right"; + } else { + return "left"; + } + } + } + return "none"; + } +} diff --git a/lib/overlays/deposit_overlay.dart b/lib/overlays/deposit_overlay.dart new file mode 100644 index 0000000..2dd753d --- /dev/null +++ b/lib/overlays/deposit_overlay.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; + +import '../main.dart'; +import 'package:qr_flutter/qr_flutter.dart'; + +class DepositOverlay extends StatelessWidget { + const DepositOverlay({ + Key? key, + required this.game, + }) : super(key: key); + + final MyGame game; + + List getDepositAddress(double width) { + List list = []; + if (game.address.length != 34) {} + list.add(QrImage( + data: game.address, + version: QrVersions.auto, + size: width / 5, + backgroundColor: Colors.white, + )); + list.add(Padding( + padding: EdgeInsets.all(width * 0.01), + child: Card( + color: cardColor, + shape: RoundedRectangleBorder( + side: const BorderSide(color: titleColor, width: 3), + borderRadius: BorderRadius.circular(10.0)), + child: Padding( + padding: EdgeInsets.all(width * 0.01), + child: SelectableText( + game.address, + style: TextStyle( + color: textColor, + fontSize: width * 0.03, + ), + ), + ), + ), + )); + return list; + } + + @override + Widget build(BuildContext context) { + double width = MediaQuery.of(context).size.width; + return Material( + color: Colors.transparent, + child: InkWell( + child: Center( + child: Container( + height: game.viewport.canvasSize.y, + width: game.viewport.canvasSize.x, + decoration: const BoxDecoration( + image: DecorationImage( + image: lossImage, + fit: BoxFit.fill, + ), + ), + child: SizedBox( + width: width / 3, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: getDepositAddress(width), + ), + ), + ), + ), + onTap: () { + game.overlays.remove('deposit'); + }, + ), + ); + } +} diff --git a/lib/overlays/leader_board_overlay.dart b/lib/overlays/leader_board_overlay.dart new file mode 100644 index 0000000..b8b42e1 --- /dev/null +++ b/lib/overlays/leader_board_overlay.dart @@ -0,0 +1,166 @@ +import 'package:flutter/material.dart'; + +import '../main.dart'; + +class LeaderBoardOverlay extends StatelessWidget { + const LeaderBoardOverlay({ + Key? key, + required this.game, + }) : super(key: key); + + final MyGame game; + + List getLeaderboard(double width) { + List leaders = []; + List list = game.leaderboard.split("\n"); + + if (list.isEmpty || list.length % 2 != 1 || list.length == 1) { + leaders.add( + Card( + color: cardColor, + shape: RoundedRectangleBorder( + side: BorderSide(color: titleColor, width: 3), + borderRadius: BorderRadius.circular(10.0)), + child: FractionallySizedBox( + widthFactor: 0.5, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: EdgeInsets.all(width * 0.01), + child: Text( + "No Internet Connection.", + style: TextStyle( + color: textColor, + fontSize: width * 0.03, + ), + ), + ) + ], + ), + ), + ), + ); + return leaders; + } + + leaders.add( + Card( + color: cardColor, + shape: RoundedRectangleBorder( + side: BorderSide(color: titleColor, width: 3), + borderRadius: BorderRadius.circular(10.0)), + child: FractionallySizedBox( + widthFactor: 0.4, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: EdgeInsets.all(width * 0.01), + child: Text( + "Username", + style: TextStyle( + color: textColor, + fontSize: width * 0.03, + ), + ), + ), + SizedBox( + width: width / 11, + ), + Padding( + padding: EdgeInsets.all(width * 0.01), + child: Text( + "Score", + style: TextStyle( + color: textColor, + fontSize: width * 0.03, + ), + ), + ), + ], + ), + ), + ), + ); + for (int i = 0; i < list.length - 2; i = i + 2) { + String name = list.elementAt(i); + String score = list.elementAt(i + 1); + leaders.add( + Card( + color: cardColor, + shape: RoundedRectangleBorder( + side: BorderSide(color: borderColor, width: 3), + borderRadius: BorderRadius.circular(10.0)), + child: FractionallySizedBox( + widthFactor: 0.4, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: EdgeInsets.all(width * 0.01), + child: Text( + name.substring(0, name.length < 10 ? name.length : 10), + style: TextStyle( + color: textColor, + fontSize: width * 0.03, + ), + ), + ), + SizedBox( + width: width / 11, + ), + Padding( + padding: EdgeInsets.all(width * 0.01), + child: Text( + score, + style: TextStyle( + color: textColor, + fontSize: width * 0.03, + ), + ), + ), + ], + ), + ), + ), + ); + } + return leaders; + } + + @override + Widget build(BuildContext context) { + double width = MediaQuery.of(context).size.width; + return Material( + color: Colors.transparent, + child: InkWell( + child: Center( + child: Container( + height: game.viewport.canvasSize.y, + width: game.viewport.canvasSize.x, + decoration: const BoxDecoration( + image: DecorationImage( + image: lossImage, + fit: BoxFit.fill, + ), + ), + child: SizedBox( + width: width / 3, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: getLeaderboard(width), + ), + ), + ), + ), + onTap: () { + game.overlays.remove('leaderboard'); + }, + ), + ); + } +} diff --git a/lib/overlays/lose_menu_overlay.dart b/lib/overlays/lose_menu_overlay.dart new file mode 100644 index 0000000..a298ca7 --- /dev/null +++ b/lib/overlays/lose_menu_overlay.dart @@ -0,0 +1,116 @@ +import 'package:flame_audio/flame_audio.dart'; +import 'package:flutter/material.dart'; + +import '../main.dart'; + +import 'package:audioplayers/src/api/player_mode.dart'; + +class LoseMenuOverlay extends StatelessWidget { + const LoseMenuOverlay({ + Key? key, + required this.game, + }) : super(key: key); + + final MyGame game; + + @override + Widget build(BuildContext context) { + double width = MediaQuery.of(context).size.width; + return Center( + child: Container( + height: game.viewport.canvasSize.y, + width: game.viewport.canvasSize.x, + decoration: const BoxDecoration( + image: DecorationImage( + image: lossImage, + fit: BoxFit.fill, + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Material( + type: MaterialType.transparency, + child: Text( + 'Score: ${game.gameState.getPlayerScore()}', + style: TextStyle( + color: textColor, + fontSize: width * 0.05, + ), + ), + ), + const SizedBox(height: 32.0), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MaterialButton( + padding: const EdgeInsets.all(8.0), + elevation: 8.0, + child: Container( + decoration: const BoxDecoration( + image: + DecorationImage(image: buttonImage, fit: BoxFit.fill), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + " MAIN MENU ", + style: TextStyle( + color: textColor, + fontSize: width * 0.03, + ), + ), + ), + ), + // ), + onPressed: () async { + // Go to the Main Menu + await FlameAudio.audioCache.play('sfx/button_click.mp3', + mode: PlayerMode.LOW_LATENCY); + game.mainMenu(); + }, + ), + const SizedBox( + width: 32.0, + ), + MaterialButton( + padding: const EdgeInsets.all(8.0), + elevation: 8.0, + child: Container( + decoration: const BoxDecoration( + image: + DecorationImage(image: buttonImage, fit: BoxFit.fill), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + " REPLAY${game.competitive ? " ${game.tries}" : ""} ", + style: TextStyle( + color: game.competitive && game.tries <= 0 + ? inactiveColor + : textColor, + fontSize: width * 0.03, + ), + ), + ), + ), + // ), + onPressed: game.competitive && game.tries <= 0 + ? null + : () async { + await FlameAudio.audioCache.play( + 'sfx/button_click.mp3', + mode: PlayerMode.LOW_LATENCY); + game.runner.friend = await FlameAudio.audioCache + .loop('sfx/robot_friend_beep.mp3'); + game.reset(); + }, + ), + ], + ), + ], + ), + ), + ); + } +} diff --git a/lib/overlays/main_menu_overlay.dart b/lib/overlays/main_menu_overlay.dart new file mode 100644 index 0000000..0176d32 --- /dev/null +++ b/lib/overlays/main_menu_overlay.dart @@ -0,0 +1,253 @@ +import 'package:flame_audio/flame_audio.dart'; +import 'package:flutter/material.dart'; + +import 'package:audioplayers/src/api/player_mode.dart'; +import '../main.dart'; + +class MainMenuOverlay extends StatelessWidget { + const MainMenuOverlay({ + Key? key, + required this.game, + }) : super(key: key); + + final MyGame game; + + @override + Widget build(BuildContext context) { + double width = MediaQuery.of(context).size.width; + return Center( + child: Container( + height: game.viewport.canvasSize.y, + width: game.viewport.canvasSize.x, + decoration: const BoxDecoration( + image: DecorationImage( + image: mainMenuImage, + fit: BoxFit.fitWidth, + ), + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: NO_TOURNAMENT + ? MainAxisAlignment.spaceEvenly + : MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + const SizedBox( + height: 16.0, + ), + const SizedBox( + height: 16.0, + ), + const SizedBox( + height: 16.0, + ), + Row( + children: [ + MaterialButton( + padding: const EdgeInsets.fromLTRB(8, 8, 8, 8), + elevation: 8.0, + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: buttonImage, fit: BoxFit.fill), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + " START ", + style: TextStyle( + color: textColor, + fontSize: width * 0.025, + ), + ), + ), + ), + onPressed: () async { + // Go to the Main Menu + FlameAudio.audioCache.play('sfx/menu_button.mp3', + mode: PlayerMode.LOW_LATENCY); + game.competitive = false; + game.reset(); + game.runner.boost = FlameAudio.audioCache.play( + 'sfx/laser.mp3', + volume: 0.0, + mode: PlayerMode.LOW_LATENCY); + FlameAudio.bgm.stop(); + FlameAudio.bgm.play('Infinite_Spankage_M.mp3'); + game.runner.friend = await FlameAudio.audioCache.loop( + 'sfx/robot_friend_beep.mp3', + volume: 0.25, + mode: PlayerMode.LOW_LATENCY); + }, + ), + ], + ), + NO_TOURNAMENT + ? const SizedBox( + height: 16.0, + ) + : Row( + children: [ + MaterialButton( + padding: const EdgeInsets.fromLTRB(8, 8, 8, 8), + elevation: 8.0, + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: buttonImage, fit: BoxFit.fill), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + " DEPOSIT ", + style: TextStyle( + color: game.username == "" + ? inactiveColor + : textColor, + fontSize: width * 0.025, + ), + ), + ), + ), + onPressed: game.username == "" + ? null + : () async { + game.address = await game.connectServer( + "deposit", "user=${game.username}"); + FlameAudio.audioCache.play( + 'sfx/button_click.mp3', + mode: PlayerMode.LOW_LATENCY); + game.overlays.add("deposit"); + }, + ), + MaterialButton( + padding: const EdgeInsets.fromLTRB(8, 8, 8, 8), + elevation: 8.0, + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: buttonImage, fit: BoxFit.fill), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + " TOURNAMENT ${game.tries} ", + style: TextStyle( + color: + game.username == "" || game.tries == 0 + ? inactiveColor + : textColor, + fontSize: width * 0.025, + ), + ), + ), + ), + onPressed: game.username == "" || game.tries == 0 + ? null + : () async { + // Go to the Main Menu + FlameAudio.audioCache.play( + 'sfx/menu_button.mp3', + mode: PlayerMode.LOW_LATENCY); + game.runner.boost = FlameAudio.audioCache + .play('sfx/laser.mp3', + volume: 0.0, + mode: PlayerMode.LOW_LATENCY); + game.competitive = true; + game.reset(); + FlameAudio.bgm.stop(); + FlameAudio.bgm + .play('Infinite_Spankage_M.mp3'); + game.runner.friend = await FlameAudio + .audioCache + .loop('sfx/robot_friend_beep.mp3', + volume: 0.25, + mode: PlayerMode.LOW_LATENCY); + }, + ), + ], + ), + NO_TOURNAMENT + ? const SizedBox( + height: 16.0, + ) + : Row( + children: [ + MaterialButton( + padding: const EdgeInsets.fromLTRB(8, 8, 8, 8), + elevation: 8.0, + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: buttonImage, fit: BoxFit.fill), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + " ${game.username == "" ? "SIGN IN" : game.username} ", + style: TextStyle( + color: textColor, + fontSize: width * 0.025, + ), + ), + ), + ), + onPressed: () async { + FlameAudio.audioCache.play('sfx/button_click.mp3', + mode: PlayerMode.LOW_LATENCY); + game.overlays.add("signin"); + }, + ), + MaterialButton( + padding: const EdgeInsets.fromLTRB(8, 8, 8, 8), + elevation: 8.0, + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: buttonImage, fit: BoxFit.fill), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + " LEADER BOARD ", + style: TextStyle( + color: textColor, + fontSize: width * 0.025, + ), + ), + ), + ), + onPressed: () async { + game.leaderboard = await game.connectServer( + "leaderboard", "user=value"); + FlameAudio.audioCache.play('sfx/button_click.mp3', + mode: PlayerMode.LOW_LATENCY); + game.overlays.add("leaderboard"); + }, + ), + ], + ), + ], + ), + const SizedBox( + width: 32.0, + ), + const SizedBox( + width: 32.0, + ), + const SizedBox( + width: 32.0, + ), + const SizedBox( + width: 32.0, + ), + ], + ), + ), + ); + } +} diff --git a/lib/overlays/sign_in_overlay.dart b/lib/overlays/sign_in_overlay.dart new file mode 100644 index 0000000..92680d5 --- /dev/null +++ b/lib/overlays/sign_in_overlay.dart @@ -0,0 +1,145 @@ +import 'package:flame_audio/flame_audio.dart'; +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../main.dart'; +import 'package:audioplayers/src/api/player_mode.dart'; + +/// This is the stateful widget that the main application instantiates. +class SignInOverlay extends StatefulWidget { + const SignInOverlay({ + Key? key, + required this.game, + }) : super(key: key); + + final MyGame game; + + @override + State createState() => _MyStatefulWidgetState(); +} + +/// This is the private State class that goes with MyStatefulWidget. +class _MyStatefulWidgetState extends State { + final GlobalKey _formKey = GlobalKey(); + final accountController = TextEditingController(); + final keyController = TextEditingController(); + + @override + Widget build(BuildContext context) { + double width = MediaQuery.of(context).size.width; + return Material( + color: Colors.transparent, + child: InkWell( + child: Center( + child: Container( + height: widget.game.viewport.canvasSize.y, + width: widget.game.viewport.canvasSize.x, + decoration: const BoxDecoration( + image: DecorationImage( + image: lossImage, + fit: BoxFit.fill, + ), + ), + child: SingleChildScrollView( + child: Center( + child: SizedBox( + width: 2 * width / 3, + child: Container( + padding: const EdgeInsets.all(30), + color: Colors.white, + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + TextFormField( + decoration: const InputDecoration( + hintText: 'Enter your account name', + ), + validator: (String? value) { + if (value == null || value.isEmpty) { + return 'Please enter your account name'; + } else if (value.contains(' ')) { + return 'Please input a valid account name without any spaces'; + } + return null; + }, + controller: accountController, + ), + TextFormField( + decoration: const InputDecoration( + hintText: 'Enter your receiving Firo address.', + ), + validator: (String? value) { + if (value == null || value.isEmpty) { + print("logging in instead of signing up."); + return null; + } else if (value.length != 34) { + return 'Not a valid receiving Firo address.'; + } + return null; + }, + controller: keyController, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: ElevatedButton( + onPressed: () async { + // // Validate will return true if the form is valid, or false if + // // the form is invalid. + FlameAudio.audioCache.play( + 'sfx/button_click.mp3', + mode: PlayerMode.LOW_LATENCY); + if (!_formKey.currentState!.validate()) { + return; + } + + // Process data. + String account = accountController.text; + String key = keyController.text; + + String username = await widget.game.connectServer( + "newuser", + "user=$account&receive=${key == "" ? "dud" : key}"); + + if (username.toLowerCase().contains("error")) { + print("There was an error"); + } else { + final prefs = + await SharedPreferences.getInstance(); + prefs.setString('username', username); + widget.game.username = + prefs.getString('username') ?? ""; + try { + String result = await widget.game + .connectServer( + "gettries", "user=$username"); + widget.game.tries = int.parse(result); + prefs.setInt('tries', widget.game.tries); + } catch (e) { + print(e); + } + } + + widget.game.overlays.remove('signin'); + }, + child: const Text('Sign In'), + ), + ), + ], + ), + ), + ), + ), + ), + ), + ), + ), + onTap: () { + widget.game.overlays.remove('signin'); + }, + ), + ); + } +} diff --git a/lib/runner.dart b/lib/runner.dart new file mode 100644 index 0000000..aaa4bda --- /dev/null +++ b/lib/runner.dart @@ -0,0 +1,675 @@ +import 'package:flame/extensions.dart'; +import 'package:firo_runner/moving_objects/bug.dart'; +import 'package:firo_runner/moving_objects/moving_object.dart'; +import 'package:firo_runner/main.dart'; +import 'package:flame/effects.dart'; +import 'package:flame/flame.dart'; +import 'dart:math'; + +import 'package:flame/components.dart'; +import 'package:flame/image_composition.dart'; +import 'package:flame_audio/flame_audio.dart'; +import 'package:flutter/animation.dart'; +import 'package:audioplayers/src/api/player_mode.dart'; + +enum RunnerState { + run, + jump, + duck, + duck2, + duck3, + kick, + kick2, + kick3, + float, + float2, + float3, + fall, + die, + electrocute, + glitch, +} + +class Runner extends Component with HasGameRef { + late SpriteAnimationGroupComponent sprite; + String runnerState = "run"; + int level = 4; + String previousState = "run"; + var runnerPosition = Vector2(0, 0); + late Vector2 runnerSize; + bool dead = false; + late Future boost; + late var friend = null; + + void setUp() { + dead = false; + runnerState = "run"; + previousState = "run"; + level = 4; + + runnerSize = Vector2( + gameRef.size.y / 9, + gameRef.size.y / 9, + ); + + setSize(runnerSize, gameRef.blockSize); + runnerPosition = Vector2(gameRef.blockSize * 2, gameRef.blockSize * 4); + setPosition(runnerPosition); + } + + void setPosition(Vector2 position) { + sprite.position = position; + } + + void setSize(Vector2 size, double ySize) { + sprite.size = size; + } + + Sprite getSprite() { + return sprite.animation!.getSprite(); + } + + @override + void render(Canvas c) { + super.render(c); + getSprite().render(c, + position: Vector2(sprite.position.x - sprite.size.x / 3, + sprite.position.y - sprite.size.y / 3), + size: sprite.size * 1.6); + } + + // update which level the runner should be at. + void updateLevel() { + level = (sprite.position.y / gameRef.blockSize).round(); + } + + // process the event that the runner is in. + void event(String event) { + if (gameRef.gameState.isPaused) { + return; + } + sprite.animation!.reset(); + switch (event) { + case "jump": + previousState = runnerState; + runnerState = event; + sprite.current = RunnerState.jump; + sprite.addEffect(MoveEffect( + path: [ + // sprite.position, + Vector2(sprite.x, (level - 1) * gameRef.blockSize), + ], + duration: 0.15, + curve: Curves.bounceIn, + onComplete: () { + updateLevel(); + this.event("float"); + }, + )); + break; + case "double_jump": + if (belowPlatform()) { + break; + } + previousState = runnerState; + clearEffects(keepSounds: true); + if (level - 1 < 0) { + break; + } + runnerState = event; + switch (gameRef.gameState.getRobotLevel()) { + case 3: + sprite.current = RunnerState.float3; + break; + case 2: + sprite.current = RunnerState.float2; + break; + default: + sprite.current = RunnerState.float; + break; + } + sprite.addEffect(MoveEffect( + path: [ + Vector2(sprite.x, (level - 2) * gameRef.blockSize), + ], + duration: 0.20, + curve: Curves.ease, + onComplete: () { + updateLevel(); + clearEffects(); + if (onTopOfPlatform()) { + this.event("run"); + } else { + this.event("float"); + } + }, + )); + break; + case "fall": + previousState = runnerState; + clearEffects(); + runnerState = event; + sprite.current = RunnerState.fall; + sprite.addEffect(getFallingEffect()); + break; + case "kick": + previousState = runnerState; + runnerState = event; + boost = FlameAudio.audioCache + .play('sfx/laser.mp3', volume: 1.0, mode: PlayerMode.LOW_LATENCY); + switch (gameRef.gameState.getRobotLevel()) { + case 3: + sprite.current = RunnerState.kick3; + break; + case 2: + sprite.current = RunnerState.kick2; + break; + default: + sprite.current = RunnerState.kick; + break; + } + break; + case "run": + previousState = runnerState; + runnerState = event; + sprite.current = RunnerState.run; + break; + case "float": + previousState = runnerState; + runnerState = event; + boost = FlameAudio.audioCache.play('sfx/jet_boost.mp3', + volume: 0.25, mode: PlayerMode.LOW_LATENCY); + switch (gameRef.gameState.getRobotLevel()) { + case 3: + sprite.current = RunnerState.float3; + break; + case 2: + sprite.current = RunnerState.float2; + break; + default: + sprite.current = RunnerState.float; + break; + } + sprite.addEffect(MoveEffect( + path: [sprite.position], + duration: 1.5, + curve: Curves.ease, + onComplete: () { + updateLevel(); + if (onTopOfPlatform()) { + this.event("run"); + } else { + this.event("fall"); + } + }, + )); + break; + case "duck": + previousState = runnerState; + runnerState = event; + boost = FlameAudio.audioCache + .play('sfx/shield.mp3', volume: 0.25, mode: PlayerMode.LOW_LATENCY); + switch (gameRef.gameState.getRobotLevel()) { + case 3: + sprite.current = RunnerState.duck3; + break; + case 2: + sprite.current = RunnerState.duck2; + break; + default: + sprite.current = RunnerState.duck; + break; + } + sprite.addEffect(MoveEffect( + path: [sprite.position], + duration: 1.5, + curve: Curves.linear, + onComplete: () { + if (boost != null) { + boost.then((value) => value.stop()); + } + this.event("run"); + }, + )); + break; + case "die": + if (dead) { + return; + } + FlameAudio.audioCache.play('sfx/fall_death_speed.mp3', + volume: 0.5, mode: PlayerMode.LOW_LATENCY); + previousState = runnerState; + clearEffects(); + runnerState = event; + sprite.current = RunnerState.die; + dead = true; + friend.stop(); + gameRef.die(); + sprite.addEffect(getFallingEffect()); + break; + case "electrocute": + if (dead) { + return; + } + FlameAudio.audioCache.play('sfx/fall_death_speed.mp3', + volume: 0.5, mode: PlayerMode.LOW_LATENCY); + previousState = runnerState; + clearEffects(); + runnerState = event; + sprite.current = RunnerState.electrocute; + dead = true; + friend.stop(); + gameRef.die(); + sprite.addEffect(getFallingEffect()); + break; + case "glitch": + if (dead) { + return; + } + FlameAudio.audioCache.play('sfx/glitch_death.mp3', + volume: 0.5, mode: PlayerMode.LOW_LATENCY); + previousState = runnerState; + clearEffects(); + runnerState = event; + sprite.current = RunnerState.glitch; + dead = true; + friend.stop(); + gameRef.die(); + break; + default: + break; + } + } + + // Get the falling effect for falling and deaths. + MoveEffect getFallingEffect() { + for (int i = level; i < 9; i++) { + if (i % 3 != 2) { + continue; + } + int distance = (i - 1 - level); + double time = 0.2; + for (int x = 2; x < distance; x++) { + time += time * pow(0.5, x - 1); + } + double estimatedXCoordinate = + time * gameRef.gameState.getVelocity() + sprite.x; + for (MovingObject p in gameRef.platformHolder.objects[i]) { + if (estimatedXCoordinate >= p.sprite.x - p.sprite.width / 2 && + estimatedXCoordinate <= p.sprite.x + p.sprite.width) { + return MoveEffect( + path: [ + Vector2(sprite.x, (i - 1) * gameRef.blockSize), + ], + duration: time, + curve: Curves.ease, + onComplete: () { + updateLevel(); + if (onTopOfPlatform()) { + FlameAudio.audioCache + .play('sfx/land.mp3', mode: PlayerMode.LOW_LATENCY); + event("run"); + } else { + event("fall"); + } + }, + ); + } + } + } + return MoveEffect( + path: [ + Vector2(sprite.x, 8 * gameRef.blockSize), + ], + duration: 0.2 * (8 - level), + curve: Curves.ease, + onComplete: () { + updateLevel(); + FlameAudio.audioCache + .play('sfx/land.mp3', mode: PlayerMode.LOW_LATENCY); + if (onTopOfPlatform()) { + event("run"); + } else { + event("fall"); + } + }, + ); + } + + // Platform agnostic control input to determine the runners actions. + void control(String input) { + if (gameRef.gameState.isPaused) { + return; + } + switch (input) { + case "up": + if (runnerState == "run" || runnerState == "kick") { + event("jump"); + } else if (runnerState == "float" && previousState == "jump") { + event("double_jump"); + } else if (runnerState == "duck") { + clearEffects(); + event("run"); + } + break; + case "down": + if (runnerState == "run" || runnerState == "kick") { + event("duck"); + } else if (runnerState == "float" && onTopOfPlatform()) { + clearEffects(); + event("run"); + } else if (runnerState == "float") { + clearEffects(); + event("fall"); + } + break; + case "right": + if (runnerState == "run" || runnerState == "kick") { + event("kick"); + } + break; + case "left": + if (runnerState == "kick") { + sprite.animation!.reset(); + clearEffects(); + event("run"); + } + break; + } + } + + @override + void update(double dt) { + super.update(dt); + if (sprite.position.y + sprite.size.y >= gameRef.size.y) { + event("die"); + } + // If the animation is finished + if (sprite.animation?.done() ?? false) { + if (!dead) { + sprite.animation!.reset(); + if (runnerState == "kick") { + event("run"); + } + sprite.current = RunnerState.run; + } + } + + if (runnerState == "float" || runnerState == "double_jump") { + if (onTopOfPlatform()) { + updateLevel(); + clearEffects(); + FlameAudio.audioCache + .play('sfx/land.mp3', mode: PlayerMode.LOW_LATENCY); + event("run"); + } + } + + intersecting(); + sprite.update(dt); + } + + // Check whether or not the runner is on top of a platform. + bool onTopOfPlatform() { + Rect runnerRect = sprite.toRect(); + bool onTopOfPlatform = false; + for (List platformLevel in gameRef.platformHolder.objects) { + for (MovingObject p in platformLevel) { + String side = p.intersect(runnerRect); + if (side == "none") { + Rect belowRunner = Rect.fromLTRB(runnerRect.left, runnerRect.top, + runnerRect.right, runnerRect.bottom + 1); + if (p.intersect(belowRunner) != "none") { + onTopOfPlatform = true; + } + } + } + } + return onTopOfPlatform; + } + + // Check if the runner is directly below a platform. + bool belowPlatform() { + Rect runnerRect = Rect.fromLTRB( + sprite.toRect().left, + sprite.toRect().top, + sprite.toRect().right - sprite.toRect().width / 2, + sprite.toRect().bottom); + bool belowPlatform = false; + for (List platformLevel in gameRef.platformHolder.objects) { + for (MovingObject p in platformLevel) { + String side = p.intersect(runnerRect); + if (side == "none") { + Rect belowRunner = Rect.fromLTRB(runnerRect.left, runnerRect.top - 1, + runnerRect.right, runnerRect.bottom); + if (p.intersect(belowRunner) == "bottom") { + belowPlatform = true; + } + } + } + } + return belowPlatform; + } + + // Check to see if the runner is intersecting any of the game objects, and + // trigger the appropriate events. + void intersecting() { + if (gameRef.gameState.isPaused) { + return; + } + Rect runnerRect = sprite.toRect(); + bool onTopOfPlatform = this.onTopOfPlatform(); + + for (List coinLevel in gameRef.coinHolder.objects) { + for (int i = 0; i < coinLevel.length;) { + if (coinLevel[i].intersect(runnerRect) != "none") { + gameRef.gameState.numCoins++; + FlameAudio.audioCache.play('sfx/coin_catch.mp3', + volume: 0.25, mode: PlayerMode.LOW_LATENCY); + gameRef.coinHolder.remove(coinLevel, i); + continue; + } + i++; + } + } + + for (List wireLevel in gameRef.wireHolder.objects) { + for (int i = 0; i < wireLevel.length; i++) { + if (wireLevel[i].intersect(runnerRect) != "none") { + event("electrocute"); + return; + } + } + } + + for (List bugLevel in gameRef.bugHolder.objects) { + for (int i = 0; i < bugLevel.length; i++) { + String intersectState = bugLevel[i].intersect(runnerRect); + if (bugLevel[i].sprite.current == BugState.breaking) { + continue; + } + if (intersectState == "none") { + Rect above = Rect.fromLTRB( + runnerRect.left + sprite.width / 3, + runnerRect.top - 1, + runnerRect.right - sprite.width / 3, + runnerRect.bottom); + String aboveIntersect = bugLevel[i].intersect(above); + if (aboveIntersect != "none" && + (runnerState == "duck" || runnerState == "float")) { + continue; + } else if (aboveIntersect != "none") { + event("glitch"); + return; + } + } else if (intersectState == "left" && runnerState == "kick") { + FlameAudio.audioCache + .play('sfx/bug_death1.mp3', mode: PlayerMode.LOW_LATENCY); + bugLevel[i].sprite.current = BugState.breaking; + gameRef.coinHolder.generateCoin(gameRef, level, + force: true, xPosition: bugLevel[i].sprite.x + gameRef.blockSize); + } else { + event("glitch"); + return; + } + } + } + + for (List debrisLevel in gameRef.debrisHolder.objects) { + for (int i = 0; i < debrisLevel.length; i++) { + Rect slim = Rect.fromLTRB( + runnerRect.left + sprite.width / 3, + runnerRect.top, + runnerRect.right - sprite.width / 3, + runnerRect.bottom); + String intersectState = debrisLevel[i].intersect(slim); + if (intersectState == "none") { + continue; + } else if (runnerState == "duck" && intersectState != "above") { + continue; + } else { + FlameAudio.audioCache + .play('sfx/obstacle_death.mp3', mode: PlayerMode.LOW_LATENCY); + event("die"); + } + } + } + + for (List wallLevel in gameRef.wallHolder.objects) { + for (int i = 0; i < wallLevel.length; i++) { + Rect slim = Rect.fromLTRB( + runnerRect.left + sprite.width / 3, + runnerRect.top + sprite.height / (runnerState == "duck" ? 3 : 6), + runnerRect.right - sprite.width / 3, + runnerRect.bottom - sprite.height / 3); + String intersectState = wallLevel[i].intersect(slim); + if (intersectState == "none") { + continue; + } else { + FlameAudio.audioCache + .play('sfx/obstacle_death.mp3', mode: PlayerMode.LOW_LATENCY); + event("die"); + } + } + } + + if (!onTopOfPlatform && + (runnerState == "run" || + runnerState == "kick" || + runnerState == "duck")) { + clearEffects(); + event("fall"); + } + } + + // Load all of the runners animations. + Future load() async { + List satellites = []; + for (int i = 1; i <= 38; i++) { + satellites.add(await Flame.images.load( + 'runner/satellite/satellite00${i < 10 ? "0" + i.toString() : i.toString()}.png')); + } + + SpriteAnimation running = + await loadSpriteAnimation("run", 38, satellites: satellites); + + SpriteAnimation jumping = await loadSpriteAnimation("jump", 6, + satellites: satellites, loop: false); + + SpriteAnimation ducking = + await loadSpriteAnimation("duck1", 38, satellites: satellites); + + SpriteAnimation ducking2 = + await loadSpriteAnimation("duck2", 38, satellites: satellites); + + SpriteAnimation ducking3 = + await loadSpriteAnimation("duck3", 38, satellites: satellites); + + SpriteAnimation kicking = await loadSpriteAnimation("attack1", 38, + satellites: satellites, loop: false); + + SpriteAnimation kicking2 = await loadSpriteAnimation("attack2", 38, + satellites: satellites, loop: false); + + SpriteAnimation kicking3 = await loadSpriteAnimation("attack3", 38, + satellites: satellites, loop: false); + + SpriteAnimation floating = + await loadSpriteAnimation("hover1", 44, satellites: satellites); + + SpriteAnimation floating2 = + await loadSpriteAnimation("hover2", 44, satellites: satellites); + + SpriteAnimation floating3 = + await loadSpriteAnimation("hover3", 44, satellites: satellites); + + SpriteAnimation falling = await loadSpriteAnimation("fall", 20, + satellites: satellites, loop: false); + + SpriteAnimation dying = + await loadSpriteAnimation("death2", 57, loop: false); + + SpriteAnimation dyingGlitch = + await loadSpriteAnimation("death1", 82, loop: false); + + sprite = SpriteAnimationGroupComponent( + animations: { + RunnerState.run: running, + RunnerState.jump: jumping, + RunnerState.duck: ducking, + RunnerState.duck2: ducking2, + RunnerState.duck3: ducking3, + RunnerState.kick: kicking, + RunnerState.kick2: kicking2, + RunnerState.kick3: kicking3, + RunnerState.float: floating, + RunnerState.float2: floating2, + RunnerState.float3: floating3, + RunnerState.fall: falling, + RunnerState.die: dying, + RunnerState.electrocute: dying, + RunnerState.glitch: dyingGlitch, + }, + current: RunnerState.run, + ); + + changePriorityWithoutResorting(RUNNER_PRIORITY); + } + + Future loadSpriteAnimation(String name, int howManyFrames, + {List? satellites, bool loop = true}) async { + List sprites = []; + for (int i = 1; i <= howManyFrames; i++) { + final composition = ImageComposition(); + if (satellites != null) { + composition.add( + satellites.elementAt(((i - 1) % satellites.length)), Vector2(0, 0)); + } + composition.add( + await Flame.images.load( + 'runner/$name/${name}00${i < 10 ? "0" + i.toString() : i.toString()}.png'), + Vector2(0, 0)); + + sprites.add(Sprite(await composition.compose())); + } + + return SpriteAnimation.spriteList(sprites, stepTime: 0.02, loop: loop); + } + + void resize(Vector2 newSize, double xRatio, double yRatio) { + sprite.x = gameRef.blockSize * 2; + sprite.y = gameRef.blockSize * level; + sprite.size.x = gameRef.blockSize; + sprite.size.y = gameRef.blockSize; + if (sprite.effects.isNotEmpty) { + sprite.effects.first.onComplete!(); + } + } + + void clearEffects({bool keepSounds = false}) { + sprite.clearEffects(); + if (!keepSounds && boost != null) { + boost.then((value) => value.stop()); + } + } +} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index d38195a..e71a16d 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" diff --git a/linux/flutter/generated_plugin_registrant.h b/linux/flutter/generated_plugin_registrant.h index 9bf7478..e0f0a47 100644 --- a/linux/flutter/generated_plugin_registrant.h +++ b/linux/flutter/generated_plugin_registrant.h @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_ diff --git a/pubspec.lock b/pubspec.lock index 1757435..6b852ae 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,320 +1,439 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.6.1" - audioplayers: - dependency: transitive - description: - name: audioplayers - url: "https://pub.dartlang.org" - source: hosted - version: "0.18.3" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - box2d_flame: - dependency: transitive - description: - name: box2d_flame - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.6" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.15.0" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - ffi: - dependency: transitive - description: - name: ffi - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "6.1.2" - flame: - dependency: "direct main" - description: - name: flame - url: "https://pub.dartlang.org" - source: hosted - version: "0.29.4" - flare_dart: - dependency: transitive - description: - name: flare_dart - url: "https://pub.dartlang.org" - source: hosted - version: "2.3.4" - flare_flutter: - dependency: transitive - description: - name: flare_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.6" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.3" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.10" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" - ordered_set: - dependency: transitive - description: - name: ordered_set - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.3" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.1" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - synchronized: - dependency: transitive - description: - name: synchronized - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.0+2" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.0" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" - uuid: - dependency: transitive - description: - name: uuid - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.4" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - win32: - dependency: transitive - description: - name: win32 - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.8" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" -sdks: - dart: ">=2.13.0 <3.0.0" - flutter: ">=2.0.0" +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.5" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.8.1" + audioplayers: + dependency: transitive + description: + name: audioplayers + url: "https://pub.dartlang.org" + source: hosted + version: "0.19.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.15.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + flame: + dependency: "direct main" + description: + name: flame + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0-releasecandidate.13" + flame_audio: + dependency: "direct main" + description: + name: flame_audio + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0-rc.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_launcher_icons: + dependency: "direct dev" + description: + name: flutter_launcher_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.2" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.3" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.7" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.3" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.10" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + ordered_set: + dependency: transitive + description: + name: ordered_set + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.1" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.3" + qr: + dependency: transitive + description: + name: qr + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + synchronized: + dependency: transitive + description: + name: synchronized + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.2" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.4" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.9" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "5.3.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" +sdks: + dart: ">=2.14.0 <3.0.0" + flutter: ">=2.5.0" diff --git a/pubspec.yaml b/pubspec.yaml index 6ce7a4a..f7c74e0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,82 +1,90 @@ -name: firo_runner -description: An infitite runner game powered by Firo. - -# The following line prevents the package from being accidentally published to -# pub.dev using `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 used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.12.0 <3.0.0" - -dependencies: - flutter: - sdk: flutter - flame: ^0.29.4 - - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.2 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - - # 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 - - assets: - - assets/images/ - - assets/audio/ - - assets/audio/sfx/ - - # 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/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # 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/custom-fonts/#from-packages +name: firo_runner +description: An infitite runner game powered by Firo. + +# The following line prevents the package from being accidentally published to +# pub.dev using `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 used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.12.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + flame: "^1.0.0-releasecandidate.11" + flame_audio: "^1.0.0-rc.1" + http: ^0.13.3 + qr_flutter: ^4.0.0 + shared_preferences: ^2.0.8 + + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + +flutter_icons: + android: "launcher_icon" + ios: true + image_path: "assets/icon/head-logo.png" + +dev_dependencies: + flutter_lints: ^1.0.4 + flutter_test: + sdk: flutter + flutter_launcher_icons: "^0.9.2" + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # 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 + + assets: + - assets/images/ + - assets/audio/ + - assets/audio/sfx/ + - assets/images/runner/run/ + - assets/images/runner/fall/ + - assets/images/runner/satellite/ + - assets/images/runner/death2/ + - assets/images/runner/death1/ + - assets/images/runner/jump/ + - assets/images/runner/attack1/ + - assets/images/runner/attack2/ + - assets/images/runner/attack3/ + - assets/images/runner/duck1/ + - assets/images/runner/duck2/ + - assets/images/runner/duck3/ + - assets/images/runner/hover1/ + - assets/images/runner/hover2/ + - assets/images/runner/hover3/ + - assets/images/bug/ + - assets/images/coin/ + - assets/images/debris/ + - assets/images/firework/ + - assets/images/platform/ + - assets/images/wall/ + - assets/images/wire/ + + fonts: + - family: Codystar + fonts: + - asset: assets/fonts/Codystar-Regular.ttf + diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png index b749bfe..132d230 100644 Binary files a/web/icons/Icon-192.png and b/web/icons/Icon-192.png differ diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png index 88cfd48..7919024 100644 Binary files a/web/icons/Icon-512.png and b/web/icons/Icon-512.png differ diff --git a/windows/.gitignore b/windows/.gitignore new file mode 100644 index 0000000..ec4098a --- /dev/null +++ b/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt new file mode 100644 index 0000000..713eedb --- /dev/null +++ b/windows/CMakeLists.txt @@ -0,0 +1,95 @@ +cmake_minimum_required(VERSION 3.15) +project(firo_runner LANGUAGES CXX) + +set(BINARY_NAME "firo_runner") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Configure build options. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() + +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build +add_subdirectory("runner") + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/windows/flutter/CMakeLists.txt b/windows/flutter/CMakeLists.txt new file mode 100644 index 0000000..c10f4f6 --- /dev/null +++ b/windows/flutter/CMakeLists.txt @@ -0,0 +1,103 @@ +cmake_minimum_required(VERSION 3.15) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..8b6d468 --- /dev/null +++ b/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,11 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + + +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/windows/flutter/generated_plugin_registrant.h b/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..dc139d8 --- /dev/null +++ b/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake new file mode 100644 index 0000000..4d10c25 --- /dev/null +++ b/windows/flutter/generated_plugins.cmake @@ -0,0 +1,15 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) diff --git a/windows/runner/CMakeLists.txt b/windows/runner/CMakeLists.txt new file mode 100644 index 0000000..7560ea7 --- /dev/null +++ b/windows/runner/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.15) +project(runner LANGUAGES CXX) + +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) +apply_standard_settings(${BINARY_NAME}) +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc new file mode 100644 index 0000000..1107551 --- /dev/null +++ b/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#ifdef FLUTTER_BUILD_NUMBER +#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER +#else +#define VERSION_AS_NUMBER 1,0,0 +#endif + +#ifdef FLUTTER_BUILD_NAME +#define VERSION_AS_STRING #FLUTTER_BUILD_NAME +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.firogames" "\0" + VALUE "FileDescription", "A new Flutter project." "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "firo_runner" "\0" + VALUE "LegalCopyright", "Copyright (C) 2021 com.firogames. All rights reserved." "\0" + VALUE "OriginalFilename", "firo_runner.exe" "\0" + VALUE "ProductName", "firo_runner" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/windows/runner/flutter_window.cpp b/windows/runner/flutter_window.cpp new file mode 100644 index 0000000..3a11b51 --- /dev/null +++ b/windows/runner/flutter_window.cpp @@ -0,0 +1,61 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/windows/runner/flutter_window.h b/windows/runner/flutter_window.h new file mode 100644 index 0000000..28c2383 --- /dev/null +++ b/windows/runner/flutter_window.h @@ -0,0 +1,33 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp new file mode 100644 index 0000000..89da126 --- /dev/null +++ b/windows/runner/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.CreateAndShow(L"firo_runner", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/windows/runner/resource.h b/windows/runner/resource.h new file mode 100644 index 0000000..ddc7f3e --- /dev/null +++ b/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/windows/runner/resources/app_icon.ico b/windows/runner/resources/app_icon.ico new file mode 100644 index 0000000..c04e20c Binary files /dev/null and b/windows/runner/resources/app_icon.ico differ diff --git a/windows/runner/runner.exe.manifest b/windows/runner/runner.exe.manifest new file mode 100644 index 0000000..2c680b8 --- /dev/null +++ b/windows/runner/runner.exe.manifest @@ -0,0 +1,20 @@ + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/windows/runner/utils.cpp b/windows/runner/utils.cpp new file mode 100644 index 0000000..05b53c0 --- /dev/null +++ b/windows/runner/utils.cpp @@ -0,0 +1,64 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr); + if (target_length == 0) { + return std::string(); + } + std::string utf8_string; + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, utf8_string.data(), + target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/windows/runner/utils.h b/windows/runner/utils.h new file mode 100644 index 0000000..3f0e05c --- /dev/null +++ b/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/windows/runner/win32_window.cpp b/windows/runner/win32_window.cpp new file mode 100644 index 0000000..97f4439 --- /dev/null +++ b/windows/runner/win32_window.cpp @@ -0,0 +1,245 @@ +#include "win32_window.h" + +#include + +#include "resource.h" + +namespace { + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + FreeLibrary(user32_module); + } +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + return OnCreate(); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} diff --git a/windows/runner/win32_window.h b/windows/runner/win32_window.h new file mode 100644 index 0000000..d9bcac1 --- /dev/null +++ b/windows/runner/win32_window.h @@ -0,0 +1,98 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates and shows a win32 window with |title| and position and size using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size to will treat the width height passed in to this function + // as logical pixels and scale to appropriate for the default monitor. Returns + // true if the window was created successfully. + bool CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responsponds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_