diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..87fcc07
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+.DS_Store
+.dart_tool/
+.packages
+.pub/
+.idea
+.atom
+.vscode
+.flutter-plugins
+build/
+*.iml
diff --git a/.metadata b/.metadata
new file mode 100644
index 0000000..01c6bb4
--- /dev/null
+++ b/.metadata
@@ -0,0 +1,8 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 7ffcd3d22d7bc1222d53d6d3bb83f59891aac2c2
+ channel: dev
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..e980ec2
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,7 @@
+# This is the list of Material Components for Flutter Codelabs authors for
+# copyright purposes.
+#
+# This does not necessarily list everyone who has contributed code, since in
+# some cases, their employer may be the copyright holder. To see the full list
+# of contributors, see the revision history in source control.
+Google Inc.
\ No newline at end of file
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..a426e05
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1 @@
+Please see the [Material Components code of conduct](https://github.com/material-components/material-components/blob/develop/CODE_OF_CONDUCT.md).
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7a4a3ea
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b660a9a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+# MDC-100 Series of Codelabs
+
+## Getting Started
+
+For help getting started with Flutter, view our online
+[documentation](https://flutter.io/).
diff --git a/android/.gitignore b/android/.gitignore
new file mode 100644
index 0000000..65b7315
--- /dev/null
+++ b/android/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+*.class
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+GeneratedPluginRegistrant.java
diff --git a/android/app/build.gradle b/android/app/build.gradle
new file mode 100644
index 0000000..b1b0947
--- /dev/null
+++ b/android/app/build.gradle
@@ -0,0 +1,51 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+apply plugin: 'com.android.application'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion 27
+
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId "com.example.mdc100series"
+ minSdkVersion 16
+ targetSdkVersion 27
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ // TODO: Add your own signing config for the release build.
+ // Signing with the debug keys for now, so `flutter run --release` works.
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.1'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
+}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..794047c
--- /dev/null
+++ b/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/java/com/example/mdc100series/MainActivity.java b/android/app/src/main/java/com/example/mdc100series/MainActivity.java
new file mode 100644
index 0000000..e0edeac
--- /dev/null
+++ b/android/app/src/main/java/com/example/mdc100series/MainActivity.java
@@ -0,0 +1,14 @@
+package com.example.mdc100series;
+
+import android.os.Bundle;
+
+import io.flutter.app.FlutterActivity;
+import io.flutter.plugins.GeneratedPluginRegistrant;
+
+public class MainActivity extends FlutterActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ GeneratedPluginRegistrant.registerWith(this);
+ }
+}
diff --git a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100755
index 0000000..24d8606
--- /dev/null
+++ b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/drawable/ic_launcher_background.xml b/android/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100755
index 0000000..71c9a19
--- /dev/null
+++ b/android/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,12 @@
+
+
+
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100755
index 0000000..bbd3e02
--- /dev/null
+++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100755
index 0000000..bbd3e02
--- /dev/null
+++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100755
index 0000000..a32fa66
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100755
index 0000000..e7d24e5
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100755
index 0000000..2c16c25
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100755
index 0000000..d4fe0b4
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..ef13423
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100755
index 0000000..aaa7607
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..9d4bec2
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100755
index 0000000..5be5eef
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100755
index 0000000..4285ee3
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100755
index 0000000..691ff57
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
new file mode 100755
index 0000000..7737817
--- /dev/null
+++ b/android/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Shrine
+
diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..4df3624
--- /dev/null
+++ b/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/android/build.gradle b/android/build.gradle
new file mode 100644
index 0000000..bb8a303
--- /dev/null
+++ b/android/build.gradle
@@ -0,0 +1,29 @@
+buildscript {
+ repositories {
+ google()
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.2.1'
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/android/gradle.properties b/android/gradle.properties
new file mode 100644
index 0000000..8bd86f6
--- /dev/null
+++ b/android/gradle.properties
@@ -0,0 +1 @@
+org.gradle.jvmargs=-Xmx1536M
diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..2819f02
--- /dev/null
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jun 23 08:50:38 CEST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
diff --git a/android/gradlew b/android/gradlew
new file mode 100755
index 0000000..9d82f78
--- /dev/null
+++ b/android/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/android/gradlew.bat b/android/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/android/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/android/settings.gradle b/android/settings.gradle
new file mode 100644
index 0000000..5a2f14f
--- /dev/null
+++ b/android/settings.gradle
@@ -0,0 +1,15 @@
+include ':app'
+
+def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+
+def plugins = new Properties()
+def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
+if (pluginsFile.exists()) {
+ pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
+}
+
+plugins.each { name, path ->
+ def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
+ include ":$name"
+ project(":$name").projectDir = pluginDirectory
+}
diff --git a/assets/2.0x/diamond.png b/assets/2.0x/diamond.png
new file mode 100644
index 0000000..602e2ea
Binary files /dev/null and b/assets/2.0x/diamond.png differ
diff --git a/assets/2.0x/slanted_menu.png b/assets/2.0x/slanted_menu.png
new file mode 100755
index 0000000..5958055
Binary files /dev/null and b/assets/2.0x/slanted_menu.png differ
diff --git a/assets/3.0x/diamond.png b/assets/3.0x/diamond.png
new file mode 100644
index 0000000..78af7cd
Binary files /dev/null and b/assets/3.0x/diamond.png differ
diff --git a/assets/3.0x/slanted_menu.png b/assets/3.0x/slanted_menu.png
new file mode 100755
index 0000000..9b4920d
Binary files /dev/null and b/assets/3.0x/slanted_menu.png differ
diff --git a/assets/diamond.png b/assets/diamond.png
new file mode 100644
index 0000000..1978a0a
Binary files /dev/null and b/assets/diamond.png differ
diff --git a/assets/slanted_menu.png b/assets/slanted_menu.png
new file mode 100755
index 0000000..c80d2d4
Binary files /dev/null and b/assets/slanted_menu.png differ
diff --git a/fonts/Rubik-Medium.ttf b/fonts/Rubik-Medium.ttf
new file mode 100755
index 0000000..c0b7965
Binary files /dev/null and b/fonts/Rubik-Medium.ttf differ
diff --git a/fonts/Rubik-Regular.ttf b/fonts/Rubik-Regular.ttf
new file mode 100755
index 0000000..fb52c8e
Binary files /dev/null and b/fonts/Rubik-Regular.ttf differ
diff --git a/ios/.gitignore b/ios/.gitignore
new file mode 100644
index 0000000..79cc4da
--- /dev/null
+++ b/ios/.gitignore
@@ -0,0 +1,45 @@
+.idea/
+.vagrant/
+.sconsign.dblite
+.svn/
+
+.DS_Store
+*.swp
+profile
+
+DerivedData/
+build/
+GeneratedPluginRegistrant.h
+GeneratedPluginRegistrant.m
+
+.generated/
+
+*.pbxuser
+*.mode1v3
+*.mode2v3
+*.perspectivev3
+
+!default.pbxuser
+!default.mode1v3
+!default.mode2v3
+!default.perspectivev3
+
+xcuserdata
+
+*.moved-aside
+
+*.pyc
+*sync/
+Icon?
+.tags*
+
+/Flutter/app.flx
+/Flutter/app.zip
+/Flutter/flutter_assets/
+/Flutter/App.framework
+/Flutter/Flutter.framework
+/Flutter/Generated.xcconfig
+/ServiceDefinitions.json
+
+Pods/
+.symlinks/
diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 0000000..6c2de80
--- /dev/null
+++ b/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+ MinimumOSVersion
+ 8.0
+
+
diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig
new file mode 100644
index 0000000..592ceee
--- /dev/null
+++ b/ios/Flutter/Debug.xcconfig
@@ -0,0 +1 @@
+#include "Generated.xcconfig"
diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig
new file mode 100644
index 0000000..592ceee
--- /dev/null
+++ b/ios/Flutter/Release.xcconfig
@@ -0,0 +1 @@
+#include "Generated.xcconfig"
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..5d3c321
--- /dev/null
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,440 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
+ 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
+ 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
+ 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; };
+ 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
+ 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
+ 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 = (
+ 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
+ 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
+ );
+ 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 = ""; };
+ 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
+ 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
+ 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; 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 = ""; };
+ 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
+ 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
+ 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 = (
+ 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
+ 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 9740EEB11CF90186004384FC /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
+ 3B80C3931E831B6300D905FE /* App.framework */,
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+ 9740EEBA1CF902C7004384FC /* Flutter.framework */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */,
+ );
+ name = Flutter;
+ sourceTree = "";
+ };
+ 97C146E51CF9000F007C117D = {
+ isa = PBXGroup;
+ children = (
+ 9740EEB11CF90186004384FC /* Flutter */,
+ 97C146F01CF9000F007C117D /* Runner */,
+ 97C146EF1CF9000F007C117D /* Products */,
+ CF3B75C9A7D2FA2A4C99F110 /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ 97C146EF1CF9000F007C117D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146EE1CF9000F007C117D /* Runner.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 97C146F01CF9000F007C117D /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
+ 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
+ 97C146FA1CF9000F007C117D /* Main.storyboard */,
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */,
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+ 97C147021CF9000F007C117D /* Info.plist */,
+ 97C146F11CF9000F007C117D /* Supporting Files */,
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+ );
+ path = Runner;
+ sourceTree = "";
+ };
+ 97C146F11CF9000F007C117D /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146F21CF9000F007C117D /* main.m */,
+ );
+ name = "Supporting Files";
+ 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 = 0910;
+ ORGANIZATIONNAME = "The Chromium Authors";
+ TargetAttributes = {
+ 97C146ED1CF9000F007C117D = {
+ CreatedOnToolsVersion = 7.3.1;
+ };
+ };
+ };
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ 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 */,
+ 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */,
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+ 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+ 2D5378261FAA1A9400D5DBA9 /* flutter_assets 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\" 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 = (
+ 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
+ 97C146F31CF9000F007C117D /* main.m 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 */
+ 97C147031CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ 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_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_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 = 8.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 97C147041CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ 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_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_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 = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 97C147061CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ARCHS = arm64;
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CURRENT_PROJECT_VERSION = 1;
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.mdc100Series;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ 97C147071CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ARCHS = arm64;
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CURRENT_PROJECT_VERSION = 1;
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.mdc100Series;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ 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 */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147061CF9000F007C117D /* Debug */,
+ 97C147071CF9000F007C117D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1d526a1
--- /dev/null
+++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 0000000..1263ac8
--- /dev/null
+++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1d526a1
--- /dev/null
+++ b/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/ios/Runner/AppDelegate.h b/ios/Runner/AppDelegate.h
new file mode 100644
index 0000000..cf210d2
--- /dev/null
+++ b/ios/Runner/AppDelegate.h
@@ -0,0 +1,6 @@
+#import
+#import
+
+@interface AppDelegate : FlutterAppDelegate
+
+@end
diff --git a/ios/Runner/AppDelegate.m b/ios/Runner/AppDelegate.m
new file mode 100644
index 0000000..112becd
--- /dev/null
+++ b/ios/Runner/AppDelegate.m
@@ -0,0 +1,12 @@
+#include "AppDelegate.h"
+#include "GeneratedPluginRegistrant.h"
+
+@implementation AppDelegate
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ [GeneratedPluginRegistrant registerWithRegistry:self];
+ // Override point for customization after application launch.
+ return [super application:application didFinishLaunchingWithOptions:launchOptions];
+}
+
+@end
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..d36b1fa
--- /dev/null
+++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,122 @@
+{
+ "images" : [
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-83.5x83.5@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "1024x1024",
+ "idiom" : "ios-marketing",
+ "filename" : "Icon-App-1024x1024@1x.png",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
new file mode 100644
index 0000000..de2a979
Binary files /dev/null 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
new file mode 100644
index 0000000..2eef297
Binary files /dev/null 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
new file mode 100644
index 0000000..c55fee9
Binary files /dev/null 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
new file mode 100644
index 0000000..fdff7f5
Binary files /dev/null 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
new file mode 100644
index 0000000..9922de2
Binary files /dev/null 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
new file mode 100644
index 0000000..d3ffe68
Binary files /dev/null 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
new file mode 100644
index 0000000..9714fd9
Binary files /dev/null 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
new file mode 100644
index 0000000..c55fee9
Binary files /dev/null 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
new file mode 100644
index 0000000..b879953
Binary files /dev/null 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
new file mode 100644
index 0000000..4b3366f
Binary files /dev/null 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
new file mode 100644
index 0000000..4b3366f
Binary files /dev/null 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
new file mode 100644
index 0000000..336e718
Binary files /dev/null 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
new file mode 100644
index 0000000..d686e82
Binary files /dev/null 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
new file mode 100644
index 0000000..b0edf43
Binary files /dev/null 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
new file mode 100644
index 0000000..ff6ca32
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App.appiconset/Contents.json
new file mode 100644
index 0000000..b871839
--- /dev/null
+++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App.appiconset/Contents.json
@@ -0,0 +1 @@
+{
"images": [
{
"idiom": "iphone",
"size": "20x20",
"filename": "Icon-App-20@2x.png",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "20x20",
"filename": "Icon-App-20@3x.png",
"scale": "3x"
},
{
"idiom": "iphone",
"size": "29x29",
"filename": "Icon-App-29@2x.png",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "29x29",
"filename": "Icon-App-29@3x.png",
"scale": "3x"
},
{
"idiom": "iphone",
"size": "60x60",
"filename": "Icon-App-60@2x.png",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "60x60",
"filename": "Icon-App-60@3x.png",
"scale": "3x"
},
{
"idiom": "ipad",
"size": "29x29",
"filename": "Icon-App-iPad-29.png",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "29x29",
"filename": "Icon-App-iPad-29@2x.png",
"scale": "2x"
},
{
"idiom": "ipad",
"size": "76x76",
"filename": "Icon-App-76.png",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "76x76",
"filename": "Icon-App-76@2x.png",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "40x40",
"filename": "Icon-App-Small-40@2x.png",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "40x40",
"filename": "Icon-App-Small-40@3x.png",
"scale": "3x"
},
{
"idiom": "ipad",
"size": "40x40",
"filename": "Icon-App-40.png",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "40x40",
"filename": "Icon-App-40@2x.png",
"scale": "2x"
},
{
"idiom": "ipad",
"size": "20x20",
"filename": "Icon-App-20.png",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "20x20",
"filename": "Icon-App-iPad-20@2x.png",
"scale": "2x"
},
{
"idiom": "ipad",
"size": "83.5x83.5",
"filename": "Icon-App-iPad-835@2x.png",
"scale": "2x"
},
{
"idiom": "ios-marketing",
"size": "1024x1024",
"filename": "Icon-App-Artwork.png",
"scale": "1x"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
\ No newline at end of file
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
new file mode 100644
index 0000000..0bedcf2
--- /dev/null
+++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
new file mode 100644
index 0000000..89c2725
--- /dev/null
+++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
@@ -0,0 +1,5 @@
+# Launch Screen Assets
+
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
+
+You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000..f2e259c
--- /dev/null
+++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..f3c2851
--- /dev/null
+++ b/ios/Runner/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
new file mode 100644
index 0000000..c24a3c7
--- /dev/null
+++ b/ios/Runner/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ mdc_100_series
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UIViewControllerBasedStatusBarAppearance
+
+
+
diff --git a/ios/Runner/main.m b/ios/Runner/main.m
new file mode 100644
index 0000000..0ccc450
--- /dev/null
+++ b/ios/Runner/main.m
@@ -0,0 +1,9 @@
+#import
+#import
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/lib/app.dart b/lib/app.dart
new file mode 100644
index 0000000..e464483
--- /dev/null
+++ b/lib/app.dart
@@ -0,0 +1,52 @@
+// Copyright 2018-present the Flutter authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import 'package:flutter/material.dart';
+
+import 'home.dart';
+import 'login.dart';
+
+// TODO: Convert ShrineApp to stateful widget (104)
+class ShrineApp extends StatelessWidget {
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ title: 'Shrine',
+ // TODO: Change home: to a Backdrop with a HomePage frontLayer (104)
+ home: HomePage(),
+ // TODO: Make currentCategory field take _currentCategory (104)
+ // TODO: Pass _currentCategory for frontLayer (104)
+ // TODO: Change backLayer field value to CategoryMenuPage (104)
+ initialRoute: '/login',
+ onGenerateRoute: _getRoute,
+ // TODO: Add a theme (103)
+ );
+ }
+
+ Route _getRoute(RouteSettings settings) {
+ if (settings.name != '/login') {
+ return null;
+ }
+
+ return MaterialPageRoute(
+ settings: settings,
+ builder: (BuildContext context) => LoginPage(),
+ fullscreenDialog: true,
+ );
+ }
+}
+
+// TODO: Build a Shrine Theme (103)
+// TODO: Build a Shrine Text Theme (103)
diff --git a/lib/home.dart b/lib/home.dart
new file mode 100644
index 0000000..e5b3637
--- /dev/null
+++ b/lib/home.dart
@@ -0,0 +1,32 @@
+// Copyright 2018-present the Flutter authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import 'package:flutter/material.dart';
+
+class HomePage extends StatelessWidget {
+ // TODO: Make a collection of cards (102)
+ // TODO: Add a variable for Category (104)
+ @override
+ Widget build(BuildContext context) {
+ // TODO: Return an AsymmetricView (104)
+ // TODO: Pass Category variable to AsymmetricView (104)
+ return Scaffold(
+ // TODO: Add app bar (102)
+ // TODO: Add a grid view (102)
+ body: Center(
+ child: Text('You did it!'),
+ ),
+ );
+ }
+}
diff --git a/lib/login.dart b/lib/login.dart
new file mode 100644
index 0000000..b1153df
--- /dev/null
+++ b/lib/login.dart
@@ -0,0 +1,80 @@
+// Copyright 2018-present the Flutter authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import 'package:flutter/material.dart';
+
+class LoginPage extends StatefulWidget {
+ @override
+ _LoginPageState createState() => _LoginPageState();
+}
+
+class _LoginPageState extends State {
+ // TODO: Add text editing controllers (101)
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: SafeArea(
+ child: ListView(
+ padding: EdgeInsets.symmetric(horizontal: 24.0),
+ children: [
+ SizedBox(height: 80.0),
+ Column(
+ children: [
+ Image.asset('assets/diamond.png'),
+ SizedBox(height: 16.0),
+ Text('SHRINE'),
+ ],
+ ),
+ SizedBox(height: 120.0),
+ // TODO: Wrap Username with AccentColorOverride (103)
+ // TODO: Remove filled: true values (103)
+ // TODO: Wrap Password with AccentColorOverride (103)
+ TextField(
+ decoration: InputDecoration(
+ filled: true,
+ labelText: 'Username'
+ ),
+ ),
+ SizedBox(height: 12.0),
+ TextField(
+ decoration: InputDecoration(
+ filled: true,
+ labelText: 'Password',
+ ),
+ obscureText: true,
+ ),
+ ButtonBar(
+ children: [
+ FlatButton(
+ child: Text('CANCEL'),
+ onPressed: () {
+
+ },
+ ),
+ RaisedButton(
+ child: Text('NEXT'),
+ onPressed: () {
+
+ },
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+// TODO: Add AccentColorOverride (103)
diff --git a/lib/main.dart b/lib/main.dart
new file mode 100644
index 0000000..f79ef41
--- /dev/null
+++ b/lib/main.dart
@@ -0,0 +1,19 @@
+// Copyright 2018-present the Flutter authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import 'package:flutter/material.dart';
+
+import 'package:Shrine/app.dart';
+
+void main() => runApp(ShrineApp());
diff --git a/lib/model/product.dart b/lib/model/product.dart
new file mode 100755
index 0000000..5df0ad1
--- /dev/null
+++ b/lib/model/product.dart
@@ -0,0 +1,43 @@
+// Copyright 2018-present the Flutter authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import 'package:flutter/foundation.dart';
+
+enum Category { all, accessories, clothing, home, }
+
+class Product {
+ const Product({
+ @required this.category,
+ @required this.id,
+ @required this.isFeatured,
+ @required this.name,
+ @required this.price,
+ }) : assert(category != null),
+ assert(id != null),
+ assert(isFeatured != null),
+ assert(name != null),
+ assert(price != null);
+
+ final Category category;
+ final int id;
+ final bool isFeatured;
+ final String name;
+ final int price;
+
+ String get assetName => '$id-0.jpg';
+ String get assetPackage => 'shrine_images';
+
+ @override
+ String toString() => "$name (id=$id)";
+}
diff --git a/lib/model/products_repository.dart b/lib/model/products_repository.dart
new file mode 100755
index 0000000..a1824e8
--- /dev/null
+++ b/lib/model/products_repository.dart
@@ -0,0 +1,295 @@
+// Copyright 2018-present the Flutter authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import 'product.dart';
+
+class ProductsRepository {
+ static List loadProducts(Category category) {
+ const allProducts = [
+ Product(
+ category: Category.accessories,
+ id: 0,
+ isFeatured: true,
+ name: 'Vagabond sack',
+ price: 120,
+ ),
+ Product(
+ category: Category.accessories,
+ id: 1,
+ isFeatured: true,
+ name: 'Stella sunglasses',
+ price: 58,
+ ),
+ Product(
+ category: Category.accessories,
+ id: 2,
+ isFeatured: false,
+ name: 'Whitney belt',
+ price: 35,
+ ),
+ Product(
+ category: Category.accessories,
+ id: 3,
+ isFeatured: true,
+ name: 'Garden strand',
+ price: 98,
+ ),
+ Product(
+ category: Category.accessories,
+ id: 4,
+ isFeatured: false,
+ name: 'Strut earrings',
+ price: 34,
+ ),
+ Product(
+ category: Category.accessories,
+ id: 5,
+ isFeatured: false,
+ name: 'Varsity socks',
+ price: 12,
+ ),
+ Product(
+ category: Category.accessories,
+ id: 6,
+ isFeatured: false,
+ name: 'Weave keyring',
+ price: 16,
+ ),
+ Product(
+ category: Category.accessories,
+ id: 7,
+ isFeatured: true,
+ name: 'Gatsby hat',
+ price: 40,
+ ),
+ Product(
+ category: Category.accessories,
+ id: 8,
+ isFeatured: true,
+ name: 'Shrug bag',
+ price: 198,
+ ),
+ Product(
+ category: Category.home,
+ id: 9,
+ isFeatured: true,
+ name: 'Gilt desk trio',
+ price: 58,
+ ),
+ Product(
+ category: Category.home,
+ id: 10,
+ isFeatured: false,
+ name: 'Copper wire rack',
+ price: 18,
+ ),
+ Product(
+ category: Category.home,
+ id: 11,
+ isFeatured: false,
+ name: 'Soothe ceramic set',
+ price: 28,
+ ),
+ Product(
+ category: Category.home,
+ id: 12,
+ isFeatured: false,
+ name: 'Hurrahs tea set',
+ price: 34,
+ ),
+ Product(
+ category: Category.home,
+ id: 13,
+ isFeatured: true,
+ name: 'Blue stone mug',
+ price: 18,
+ ),
+ Product(
+ category: Category.home,
+ id: 14,
+ isFeatured: true,
+ name: 'Rainwater tray',
+ price: 27,
+ ),
+ Product(
+ category: Category.home,
+ id: 15,
+ isFeatured: true,
+ name: 'Chambray napkins',
+ price: 16,
+ ),
+ Product(
+ category: Category.home,
+ id: 16,
+ isFeatured: true,
+ name: 'Succulent planters',
+ price: 16,
+ ),
+ Product(
+ category: Category.home,
+ id: 17,
+ isFeatured: false,
+ name: 'Quartet table',
+ price: 175,
+ ),
+ Product(
+ category: Category.home,
+ id: 18,
+ isFeatured: true,
+ name: 'Kitchen quattro',
+ price: 129,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 19,
+ isFeatured: false,
+ name: 'Clay sweater',
+ price: 48,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 20,
+ isFeatured: false,
+ name: 'Sea tunic',
+ price: 45,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 21,
+ isFeatured: false,
+ name: 'Plaster tunic',
+ price: 38,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 22,
+ isFeatured: false,
+ name: 'White pinstripe shirt',
+ price: 70,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 23,
+ isFeatured: false,
+ name: 'Chambray shirt',
+ price: 70,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 24,
+ isFeatured: true,
+ name: 'Seabreeze sweater',
+ price: 60,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 25,
+ isFeatured: false,
+ name: 'Gentry jacket',
+ price: 178,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 26,
+ isFeatured: false,
+ name: 'Navy trousers',
+ price: 74,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 27,
+ isFeatured: true,
+ name: 'Walter henley (white)',
+ price: 38,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 28,
+ isFeatured: true,
+ name: 'Surf and perf shirt',
+ price: 48,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 29,
+ isFeatured: true,
+ name: 'Ginger scarf',
+ price: 98,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 30,
+ isFeatured: true,
+ name: 'Ramona crossover',
+ price: 68,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 31,
+ isFeatured: false,
+ name: 'Chambray shirt',
+ price: 38,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 32,
+ isFeatured: false,
+ name: 'Classic white collar',
+ price: 58,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 33,
+ isFeatured: true,
+ name: 'Cerise scallop tee',
+ price: 42,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 34,
+ isFeatured: false,
+ name: 'Shoulder rolls tee',
+ price: 27,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 35,
+ isFeatured: false,
+ name: 'Grey slouch tank',
+ price: 24,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 36,
+ isFeatured: false,
+ name: 'Sunshirt dress',
+ price: 58,
+ ),
+ Product(
+ category: Category.clothing,
+ id: 37,
+ isFeatured: true,
+ name: 'Fine lines tee',
+ price: 58,
+ ),
+ ];
+ if (category == Category.all) {
+ return allProducts;
+ } else {
+ return allProducts.where((Product p) {
+ return p.category == category;
+ }).toList();
+ }
+ }
+}
diff --git a/lib/supplemental/asymmetric_view.dart b/lib/supplemental/asymmetric_view.dart
new file mode 100644
index 0000000..6b5be2b
--- /dev/null
+++ b/lib/supplemental/asymmetric_view.dart
@@ -0,0 +1,95 @@
+// Copyright 2018-present the Flutter authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import 'package:flutter/material.dart';
+
+import '../model/product.dart';
+import 'product_columns.dart';
+
+class AsymmetricView extends StatelessWidget {
+ final List products;
+
+ AsymmetricView({Key key, this.products});
+
+ List _buildColumns(BuildContext context) {
+ if (products == null || products.isEmpty) {
+ return [];
+ }
+
+ /// This will return a list of columns. It will oscillate between the two
+ /// kinds of columns. Even cases of the index (0, 2, 4, etc) will be
+ /// TwoProductCardColumn and the odd cases will be OneProductCardColumn.
+ ///
+ /// Each pair of columns will advance us 3 products forward (2 + 1). That's
+ /// some kinda awkward math so we use _evenCasesIndex and _oddCasesIndex as
+ /// helpers for creating the index of the product list that will correspond
+ /// to the index of the list of columns.
+ return List.generate(_listItemCount(products.length), (int index) {
+ double width = .59 * MediaQuery.of(context).size.width;
+ Widget column;
+ if (index % 2 == 0) {
+ /// Even cases
+ int bottom = _evenCasesIndex(index);
+ column = TwoProductCardColumn(
+ bottom: products[bottom],
+ top: products.length - 1 >= bottom + 1
+ ? products[bottom + 1]
+ : null);
+ width += 32.0;
+ } else {
+ /// Odd cases
+ column = OneProductCardColumn(
+ product: products[_oddCasesIndex(index)],
+ );
+ }
+ return Container(
+ width: width,
+ child: Padding(
+ padding: EdgeInsets.symmetric(horizontal: 16.0),
+ child: column,
+ ),
+ );
+ }).toList();
+ }
+
+ int _evenCasesIndex(int input) {
+ /// The operator ~/ is a cool one. It's the truncating division operator. It
+ /// divides the number and if there's a remainder / decimal, it cuts it off.
+ /// This is like dividing and then casting the result to int. Also, it's
+ /// functionally equivalent to floor() in this case.
+ return input ~/ 2 * 3;
+ }
+
+ int _oddCasesIndex(int input) {
+ assert(input > 0);
+ return (input / 2).ceil() * 3 - 1;
+ }
+
+ int _listItemCount(int totalItems) {
+ if (totalItems % 3 == 0) {
+ return totalItems ~/ 3 * 2;
+ } else {
+ return (totalItems / 3).ceil() * 2 - 1;
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return ListView(
+ scrollDirection: Axis.horizontal,
+ padding: EdgeInsets.fromLTRB(0.0, 34.0, 16.0, 44.0),
+ children: _buildColumns(context),
+ );
+ }
+}
diff --git a/lib/supplemental/cut_corners_border.dart b/lib/supplemental/cut_corners_border.dart
new file mode 100644
index 0000000..6837a09
--- /dev/null
+++ b/lib/supplemental/cut_corners_border.dart
@@ -0,0 +1,139 @@
+// Copyright 2018-present the Flutter authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import 'dart:ui' show lerpDouble;
+
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+
+class CutCornersBorder extends OutlineInputBorder {
+ const CutCornersBorder({
+ BorderSide borderSide: const BorderSide(),
+ BorderRadius borderRadius: const BorderRadius.all(Radius.circular(2.0)),
+ this.cut: 7.0,
+ double gapPadding: 2.0,
+ }) : super(
+ borderSide: borderSide,
+ borderRadius: borderRadius,
+ gapPadding: gapPadding);
+
+ @override
+ CutCornersBorder copyWith({
+ BorderSide borderSide,
+ BorderRadius borderRadius,
+ double gapPadding,
+ double cut,
+ }) {
+ return CutCornersBorder(
+ borderRadius: borderRadius ?? this.borderRadius,
+ borderSide: borderSide ?? this.borderSide,
+ cut: cut ?? this.cut,
+ gapPadding: gapPadding ?? this.gapPadding,
+ );
+ }
+
+ final double cut;
+
+ @override
+ ShapeBorder lerpFrom(ShapeBorder a, double t) {
+ if (a is CutCornersBorder) {
+ final CutCornersBorder outline = a;
+ return CutCornersBorder(
+ borderRadius: BorderRadius.lerp(outline.borderRadius, borderRadius, t),
+ borderSide: BorderSide.lerp(outline.borderSide, borderSide, t),
+ cut: cut,
+ gapPadding: outline.gapPadding,
+ );
+ }
+ return super.lerpFrom(a, t);
+ }
+
+ @override
+ ShapeBorder lerpTo(ShapeBorder b, double t) {
+ if (b is CutCornersBorder) {
+ final CutCornersBorder outline = b;
+ return CutCornersBorder(
+ borderRadius: BorderRadius.lerp(borderRadius, outline.borderRadius, t),
+ borderSide: BorderSide.lerp(borderSide, outline.borderSide, t),
+ cut: cut,
+ gapPadding: outline.gapPadding,
+ );
+ }
+ return super.lerpTo(b, t);
+ }
+
+ Path _notchedCornerPath(Rect center,
+ [double start = 0.0, double extent = 0.0]) {
+ final Path path = Path();
+ if (start > 0.0 || extent > 0.0) {
+ path.relativeMoveTo(extent + start, center.top);
+ _notchedSidesAndBottom(center, path);
+ path..lineTo(center.left + cut, center.top)..lineTo(start, center.top);
+ } else {
+ path.moveTo(center.left + cut, center.top);
+ _notchedSidesAndBottom(center, path);
+ path.lineTo(center.left + cut, center.top);
+ }
+ return path;
+ }
+
+ Path _notchedSidesAndBottom(Rect center, Path path) {
+ return path
+ ..lineTo(center.right - cut, center.top)
+ ..lineTo(center.right, center.top + cut)
+ ..lineTo(center.right, center.top + center.height - cut)
+ ..lineTo(center.right - cut, center.top + center.height)
+ ..lineTo(center.left + cut, center.top + center.height)
+ ..lineTo(center.left, center.top + center.height - cut)
+ ..lineTo(center.left, center.top + cut);
+ }
+
+ @override
+ void paint(
+ Canvas canvas,
+ Rect rect, {
+ double gapStart,
+ double gapExtent: 0.0,
+ double gapPercentage: 0.0,
+ TextDirection textDirection,
+ }) {
+ assert(gapExtent != null);
+ assert(gapPercentage >= 0.0 && gapPercentage <= 1.0);
+
+ final Paint paint = borderSide.toPaint();
+ final RRect outer = borderRadius.toRRect(rect);
+ if (gapStart == null || gapExtent <= 0.0 || gapPercentage == 0.0) {
+ canvas.drawPath(_notchedCornerPath(outer.middleRect), paint);
+ } else {
+ final double extent =
+ lerpDouble(0.0, gapExtent + gapPadding * 2.0, gapPercentage);
+ switch (textDirection) {
+ case TextDirection.rtl:
+ {
+ final Path path = _notchedCornerPath(
+ outer.middleRect, gapStart + gapPadding - extent, extent);
+ canvas.drawPath(path, paint);
+ break;
+ }
+ case TextDirection.ltr:
+ {
+ final Path path = _notchedCornerPath(
+ outer.middleRect, gapStart - gapPadding, extent);
+ canvas.drawPath(path, paint);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/lib/supplemental/product_card.dart b/lib/supplemental/product_card.dart
new file mode 100644
index 0000000..31ff717
--- /dev/null
+++ b/lib/supplemental/product_card.dart
@@ -0,0 +1,76 @@
+// Copyright 2018-present the Flutter authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import 'package:flutter/material.dart';
+import 'package:intl/intl.dart';
+
+import '../model/product.dart';
+
+class ProductCard extends StatelessWidget {
+ ProductCard({this.imageAspectRatio: 33 / 49, this.product})
+ : assert(imageAspectRatio == null || imageAspectRatio > 0);
+
+ final double imageAspectRatio;
+ final Product product;
+
+ static final kTextBoxHeight = 65.0;
+
+ @override
+ Widget build(BuildContext context) {
+ final NumberFormat formatter = NumberFormat.simpleCurrency(
+ decimalDigits: 0, locale: Localizations.localeOf(context).toString());
+ final ThemeData theme = Theme.of(context);
+
+ final imageWidget = Image.asset(
+ product.assetName,
+ package: product.assetPackage,
+ fit: BoxFit.cover,
+ );
+
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ AspectRatio(
+ aspectRatio: imageAspectRatio,
+ child: imageWidget,
+ ),
+ SizedBox(
+ height: kTextBoxHeight * MediaQuery.of(context).textScaleFactor,
+ width: 121.0,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.end,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ // TODO(larche): Make headline6 when available
+ Text(
+ product == null ? '' : product.name,
+ style: theme.textTheme.button,
+ softWrap: false,
+ overflow: TextOverflow.ellipsis,
+ maxLines: 1,
+ ),
+ SizedBox(height: 4.0),
+ // TODO(larche): Make subtitle2 when available
+ Text(
+ product == null ? '' : formatter.format(product.price),
+ style: theme.textTheme.caption,
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/supplemental/product_columns.dart b/lib/supplemental/product_columns.dart
new file mode 100644
index 0000000..ad6be75
--- /dev/null
+++ b/lib/supplemental/product_columns.dart
@@ -0,0 +1,89 @@
+// Copyright 2018-present the Flutter authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import 'package:flutter/material.dart';
+
+import '../model/product.dart';
+import 'product_card.dart';
+
+class TwoProductCardColumn extends StatelessWidget {
+ TwoProductCardColumn({
+ this.bottom,
+ this.top,
+ }) : assert(bottom != null);
+
+ final Product bottom, top;
+
+ @override
+ Widget build(BuildContext context) {
+ return LayoutBuilder(
+ builder: (BuildContext context, BoxConstraints constraints) {
+ const spacerHeight = 44.0;
+
+ double heightOfCards = (constraints.biggest.height - spacerHeight) / 2.0;
+ double heightOfImages = heightOfCards - ProductCard.kTextBoxHeight;
+ // TODO: Change imageAspectRatio calculation (104)
+ double imageAspectRatio = constraints.biggest.width / heightOfImages;
+
+ // TODO: Replace Column with a ListView (104)
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Padding(
+ padding: EdgeInsetsDirectional.only(start: 28.0),
+ child: top != null
+ ? ProductCard(
+ imageAspectRatio: imageAspectRatio,
+ product: top,
+ )
+ : SizedBox(
+ height: heightOfCards,
+ ),
+ ),
+ SizedBox(height: spacerHeight),
+ Padding(
+ padding: EdgeInsetsDirectional.only(end: 28.0),
+ child: ProductCard(
+ imageAspectRatio: imageAspectRatio,
+ product: bottom,
+ ),
+ ),
+ ],
+ );
+ });
+ }
+}
+
+class OneProductCardColumn extends StatelessWidget {
+ OneProductCardColumn({this.product});
+
+ final Product product;
+
+ @override
+ Widget build(BuildContext context) {
+ // TODO: Replace Column with a ListView (104)
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ ProductCard(
+ product: product,
+ ),
+ SizedBox(
+ height: 40.0,
+ ),
+ ],
+ );
+ }
+}
diff --git a/pubspec.lock b/pubspec.lock
new file mode 100644
index 0000000..cd4d4bb
--- /dev/null
+++ b/pubspec.lock
@@ -0,0 +1,160 @@
+# Generated by pub
+# See https://www.dartlang.org/tools/pub/glossary#lockfile
+packages:
+ async:
+ dependency: transitive
+ description:
+ name: async
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.8"
+ boolean_selector:
+ dependency: transitive
+ description:
+ name: boolean_selector
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.4"
+ charcode:
+ dependency: transitive
+ description:
+ name: charcode
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.2"
+ collection:
+ dependency: transitive
+ description:
+ name: collection
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.14.11"
+ cupertino_icons:
+ dependency: "direct main"
+ description:
+ name: cupertino_icons
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.1.2"
+ 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"
+ intl:
+ dependency: "direct main"
+ description:
+ name: intl
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.15.7"
+ matcher:
+ dependency: transitive
+ description:
+ name: matcher
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.12.3+1"
+ meta:
+ dependency: transitive
+ description:
+ name: meta
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.6"
+ path:
+ dependency: transitive
+ description:
+ name: path
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.6.2"
+ pedantic:
+ dependency: transitive
+ description:
+ name: pedantic
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.5.0"
+ quiver:
+ dependency: transitive
+ description:
+ name: quiver
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.1"
+ shrine_images:
+ dependency: "direct main"
+ description:
+ name: shrine_images
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.1"
+ 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.5.5"
+ stack_trace:
+ dependency: transitive
+ description:
+ name: stack_trace
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.9.3"
+ stream_channel:
+ dependency: transitive
+ description:
+ name: stream_channel
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.6.8"
+ string_scanner:
+ dependency: transitive
+ description:
+ name: string_scanner
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.4"
+ term_glyph:
+ dependency: transitive
+ description:
+ name: term_glyph
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.0"
+ test_api:
+ dependency: transitive
+ description:
+ name: test_api
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.2.2"
+ typed_data:
+ dependency: transitive
+ description:
+ name: typed_data
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.6"
+ vector_math:
+ dependency: transitive
+ description:
+ name: vector_math
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.8"
+sdks:
+ dart: ">=2.1.1-dev.0.0 <3.0.0"
diff --git a/pubspec.yaml b/pubspec.yaml
new file mode 100644
index 0000000..350ae24
--- /dev/null
+++ b/pubspec.yaml
@@ -0,0 +1,57 @@
+name: Shrine
+description: Learn the basics of using Material Components by building a simple app with core components.
+
+dependencies:
+ flutter:
+ sdk: flutter
+ intl: ^0.15.6
+
+ cupertino_icons: ^0.1.0
+ shrine_images: 1.1.1
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+
+flutter:
+ uses-material-design: true
+ assets:
+ - assets/diamond.png
+ - packages/shrine_images/0-0.jpg
+ - packages/shrine_images/1-0.jpg
+ - packages/shrine_images/2-0.jpg
+ - packages/shrine_images/3-0.jpg
+ - packages/shrine_images/4-0.jpg
+ - packages/shrine_images/5-0.jpg
+ - packages/shrine_images/6-0.jpg
+ - packages/shrine_images/7-0.jpg
+ - packages/shrine_images/8-0.jpg
+ - packages/shrine_images/9-0.jpg
+ - packages/shrine_images/10-0.jpg
+ - packages/shrine_images/11-0.jpg
+ - packages/shrine_images/12-0.jpg
+ - packages/shrine_images/13-0.jpg
+ - packages/shrine_images/14-0.jpg
+ - packages/shrine_images/15-0.jpg
+ - packages/shrine_images/16-0.jpg
+ - packages/shrine_images/17-0.jpg
+ - packages/shrine_images/18-0.jpg
+ - packages/shrine_images/19-0.jpg
+ - packages/shrine_images/20-0.jpg
+ - packages/shrine_images/21-0.jpg
+ - packages/shrine_images/22-0.jpg
+ - packages/shrine_images/23-0.jpg
+ - packages/shrine_images/24-0.jpg
+ - packages/shrine_images/25-0.jpg
+ - packages/shrine_images/26-0.jpg
+ - packages/shrine_images/27-0.jpg
+ - packages/shrine_images/28-0.jpg
+ - packages/shrine_images/29-0.jpg
+ - packages/shrine_images/30-0.jpg
+ - packages/shrine_images/31-0.jpg
+ - packages/shrine_images/32-0.jpg
+ - packages/shrine_images/33-0.jpg
+ - packages/shrine_images/34-0.jpg
+ - packages/shrine_images/35-0.jpg
+ - packages/shrine_images/36-0.jpg
+ - packages/shrine_images/37-0.jpg