diff --git a/.gitignore b/.gitignore index 6db3c9a5bc..c17ee441a6 100644 --- a/.gitignore +++ b/.gitignore @@ -7,9 +7,18 @@ # Ignore bundler config. /.bundle +# Ignore the default SQLite database. +/db/*.sqlite3 +/db/*.sqlite3-journal + # Ignore all logfiles and tempfiles. /log/* !/log/.keep /tmp .DS_Store + +/coverage + +# Ignore the .env file (it's full of secrets!) +.env diff --git a/Gemfile b/Gemfile index c69f4ddde9..9e544a5bf1 100644 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,10 @@ source 'https://rubygems.org' -ruby '2.3.1' +# graphing for erd +gem 'graphviz' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.2.6' -# Use postgresql as the database for Active Record -# gem 'pg', '~> 0.15' + # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' # Use Uglifier as compressor for JavaScript assets @@ -23,6 +23,15 @@ gem 'jbuilder', '~> 2.0' # bundle exec rake doc:rails generates the API under doc/api. gem 'sdoc', '~> 0.4.0', group: :doc + +# For authentication +gem 'omniauth' + +#google as our authentication instead +gem "omniauth-google-oauth2", "~> 0.2.1" + +#for 5 star reviews +gem 'ratyrate' # Use ActiveModel has_secure_password # gem 'bcrypt', '~> 3.1.7' @@ -32,15 +41,41 @@ gem 'sdoc', '~> 0.4.0', group: :doc # Use Capistrano for deployment # gem 'capistrano-rails', group: :development +group :test do + gem 'minitest-reporters' + gem 'simplecov' +end + group :development, :test do + # Use sqlite3 as the database for Active Record + gem 'sqlite3' + # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug' + # for tests + gem 'dotenv-rails' + + #for testing + gem 'better_errors' + gem 'binding_of_caller' + + end group :development do # Access an IRB console on exception pages or by using <%= console %> in views gem 'web-console', '~> 2.0' + #for erd diagram + gem 'rails-erd' + # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' end + +group :production do + # to use postgres in production + gem 'pg' + + gem 'rails_12factor' +end diff --git a/Gemfile.lock b/Gemfile.lock index 20975578b8..2405ad8627 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,11 +36,19 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) + addressable (2.4.0) + ansi (1.5.0) arel (6.0.3) + better_errors (2.1.1) + coderay (>= 1.0.0) + erubis (>= 2.6.6) + rack (>= 0.9.0) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) builder (3.2.2) - byebug (8.2.5) + byebug (9.0.6) + choice (0.2.0) + coderay (1.1.1) coffee-rails (4.1.1) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.1.x) @@ -48,33 +56,69 @@ GEM coffee-script-source execjs coffee-script-source (1.10.0) - concurrent-ruby (1.0.1) + concurrent-ruby (1.0.2) debug_inspector (0.0.2) + docile (1.1.5) + dotenv (2.1.1) + dotenv-rails (2.1.1) + dotenv (= 2.1.1) + railties (>= 4.0, < 5.1) erubis (2.7.0) - execjs (2.6.0) - globalid (0.3.6) + execjs (2.7.0) + faraday (0.9.2) + multipart-post (>= 1.2, < 3) + globalid (0.3.7) activesupport (>= 4.1.0) + graphviz (0.3.0) + hashie (3.4.6) i18n (0.7.0) - jbuilder (2.4.1) + jbuilder (2.6.0) activesupport (>= 3.0.0, < 5.1) multi_json (~> 1.2) - jquery-rails (4.1.1) + jquery-rails (4.2.1) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (1.8.3) + jwt (1.5.6) loofah (2.0.3) nokogiri (>= 1.5.9) mail (2.6.4) mime-types (>= 1.16, < 4) - mime-types (3.0) + mime-types (3.1) mime-types-data (~> 3.2015) - mime-types-data (3.2016.0221) - mini_portile2 (2.0.0) - minitest (5.8.4) - multi_json (1.11.3) - nokogiri (1.6.7.2) - mini_portile2 (~> 2.0.0.rc2) + mime-types-data (3.2016.0521) + mini_portile2 (2.1.0) + minitest (5.9.1) + minitest-reporters (1.1.11) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + multi_json (1.12.1) + multi_xml (0.5.5) + multipart-post (2.0.0) + nokogiri (1.6.8.1) + mini_portile2 (~> 2.1.0) + oauth2 (1.2.0) + faraday (>= 0.8, < 0.10) + jwt (~> 1.0) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (>= 1.2, < 3) + omniauth (1.3.1) + hashie (>= 1.2, < 4) + rack (>= 1.0, < 3) + omniauth-google-oauth2 (0.2.10) + addressable (~> 2.3) + jwt (~> 1.0) + multi_json (~> 1.3) + omniauth (>= 1.1.1) + omniauth-oauth2 (~> 1.3.1) + omniauth-oauth2 (1.3.1) + oauth2 (~> 1.0) + omniauth (~> 1.2) + pg (0.19.0) rack (1.6.4) rack-test (0.6.3) rack (>= 1.0) @@ -95,42 +139,63 @@ GEM activesupport (>= 4.2.0.beta, < 5.0) nokogiri (~> 1.6.0) rails-deprecated_sanitizer (>= 1.0.1) + rails-erd (1.5.0) + activerecord (>= 3.2) + activesupport (>= 3.2) + choice (~> 0.2.0) + ruby-graphviz (~> 1.2) rails-html-sanitizer (1.0.3) loofah (~> 2.0) + rails_12factor (0.0.3) + rails_serve_static_assets + rails_stdout_logging + rails_serve_static_assets (0.0.5) + rails_stdout_logging (0.0.5) railties (4.2.6) actionpack (= 4.2.6) activesupport (= 4.2.6) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rake (11.1.2) + rake (11.3.0) + ratyrate (1.2.2.alpha) rdoc (4.2.2) json (~> 1.4) + ruby-graphviz (1.2.2) + ruby-progressbar (1.8.1) sass (3.4.22) - sass-rails (5.0.4) - railties (>= 4.0.0, < 5.0) + sass-rails (5.0.6) + railties (>= 4.0.0, < 6) sass (~> 3.1) sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - sdoc (0.4.1) + sdoc (0.4.2) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) - spring (1.7.1) - sprockets (3.6.0) + simplecov (0.12.0) + docile (~> 1.1.0) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) + spring (2.0.0) + activesupport (>= 4.2) + sprockets (3.7.0) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.0.4) + sprockets-rails (3.2.0) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) + sqlite3 (1.3.12) thor (0.19.1) thread_safe (0.3.5) - tilt (2.0.2) - turbolinks (2.5.3) - coffee-rails + tilt (2.0.5) + turbolinks (5.0.1) + turbolinks-source (~> 5) + turbolinks-source (5.0.0) tzinfo (1.2.2) thread_safe (~> 0.1) - uglifier (3.0.0) + uglifier (3.0.2) execjs (>= 0.3.0, < 3) web-console (2.3.0) activemodel (>= 4.0) @@ -142,20 +207,30 @@ PLATFORMS ruby DEPENDENCIES + better_errors + binding_of_caller byebug coffee-rails (~> 4.1.0) + dotenv-rails + graphviz jbuilder (~> 2.0) jquery-rails + minitest-reporters + omniauth + omniauth-google-oauth2 (~> 0.2.1) + pg rails (= 4.2.6) + rails-erd + rails_12factor + ratyrate sass-rails (~> 5.0) sdoc (~> 0.4.0) + simplecov spring + sqlite3 turbolinks uglifier (>= 1.3.0) web-console (~> 2.0) -RUBY VERSION - ruby 2.3.1p112 - BUNDLED WITH 1.13.5 diff --git a/README.rdoc b/README.rdoc new file mode 100644 index 0000000000..dd4e97e22e --- /dev/null +++ b/README.rdoc @@ -0,0 +1,28 @@ +== README + +This README would normally document whatever steps are necessary to get the +application up and running. + +Things you may want to cover: + +* Ruby version + +* System dependencies + +* Configuration + +* Database creation + +* Database initialization + +* How to run the test suite + +* Services (job queues, cache servers, search engines, etc.) + +* Deployment instructions + +* ... + + +Please feel free to use a different markup language if you do not plan to run +rake doc:app. diff --git a/app/assets/.DS_Store b/app/assets/.DS_Store new file mode 100644 index 0000000000..fd1427cb55 Binary files /dev/null and b/app/assets/.DS_Store differ diff --git a/app/assets/images/almonds.jpg b/app/assets/images/almonds.jpg new file mode 100644 index 0000000000..dc978d5ed6 Binary files /dev/null and b/app/assets/images/almonds.jpg differ diff --git a/app/assets/images/basket.jpg b/app/assets/images/basket.jpg new file mode 100644 index 0000000000..100ba418b3 Binary files /dev/null and b/app/assets/images/basket.jpg differ diff --git a/app/assets/images/basketcart.png b/app/assets/images/basketcart.png new file mode 100644 index 0000000000..750814c824 Binary files /dev/null and b/app/assets/images/basketcart.png differ diff --git a/app/assets/images/blanket.jpg b/app/assets/images/blanket.jpg new file mode 100644 index 0000000000..b1f085e603 Binary files /dev/null and b/app/assets/images/blanket.jpg differ diff --git a/app/assets/images/brie.jpg b/app/assets/images/brie.jpg new file mode 100644 index 0000000000..6d006b22fe Binary files /dev/null and b/app/assets/images/brie.jpg differ diff --git a/app/assets/images/categories/almonds.jpg b/app/assets/images/categories/almonds.jpg new file mode 100644 index 0000000000..cc708317a0 Binary files /dev/null and b/app/assets/images/categories/almonds.jpg differ diff --git a/app/assets/images/categories/charcuterie.jpg b/app/assets/images/categories/charcuterie.jpg new file mode 100644 index 0000000000..f5cd5bd87b Binary files /dev/null and b/app/assets/images/categories/charcuterie.jpg differ diff --git a/app/assets/images/categories/cheese.jpg b/app/assets/images/categories/cheese.jpg new file mode 100644 index 0000000000..ad9cacb577 Binary files /dev/null and b/app/assets/images/categories/cheese.jpg differ diff --git a/app/assets/images/categories/essentials.jpg b/app/assets/images/categories/essentials.jpg new file mode 100644 index 0000000000..6ebcf1e436 Binary files /dev/null and b/app/assets/images/categories/essentials.jpg differ diff --git a/app/assets/images/categories/peaches.jpg b/app/assets/images/categories/peaches.jpg new file mode 100644 index 0000000000..aadd4e3b07 Binary files /dev/null and b/app/assets/images/categories/peaches.jpg differ diff --git a/app/assets/images/categories/wines.jpg b/app/assets/images/categories/wines.jpg new file mode 100644 index 0000000000..c43cdd8600 Binary files /dev/null and b/app/assets/images/categories/wines.jpg differ diff --git a/app/assets/images/chicken.jpeg b/app/assets/images/chicken.jpeg new file mode 100644 index 0000000000..8243a4c4cf Binary files /dev/null and b/app/assets/images/chicken.jpeg differ diff --git a/app/assets/images/favicon.ico b/app/assets/images/favicon.ico new file mode 100644 index 0000000000..012f3b8e7e Binary files /dev/null and b/app/assets/images/favicon.ico differ diff --git a/app/assets/images/goat_cheese.jpeg b/app/assets/images/goat_cheese.jpeg new file mode 100644 index 0000000000..609a0cf941 Binary files /dev/null and b/app/assets/images/goat_cheese.jpeg differ diff --git a/app/assets/images/grapes.jpg b/app/assets/images/grapes.jpg new file mode 100644 index 0000000000..d193e8bd74 Binary files /dev/null and b/app/assets/images/grapes.jpg differ diff --git a/app/assets/images/gruyere.jpg b/app/assets/images/gruyere.jpg new file mode 100644 index 0000000000..eef074ffab Binary files /dev/null and b/app/assets/images/gruyere.jpg differ diff --git a/app/assets/images/merchant-strawberries.jpg b/app/assets/images/merchant-strawberries.jpg new file mode 100644 index 0000000000..d0881b703c Binary files /dev/null and b/app/assets/images/merchant-strawberries.jpg differ diff --git a/app/assets/images/salami.jpg b/app/assets/images/salami.jpg new file mode 100644 index 0000000000..6cae79c294 Binary files /dev/null and b/app/assets/images/salami.jpg differ diff --git a/app/assets/images/sampler.jpg b/app/assets/images/sampler.jpg new file mode 100644 index 0000000000..dd8663a631 Binary files /dev/null and b/app/assets/images/sampler.jpg differ diff --git a/app/assets/images/sauternes.jpg b/app/assets/images/sauternes.jpg new file mode 100644 index 0000000000..a8944e4255 Binary files /dev/null and b/app/assets/images/sauternes.jpg differ diff --git a/app/assets/images/slicer.jpeg b/app/assets/images/slicer.jpeg new file mode 100644 index 0000000000..b837cae512 Binary files /dev/null and b/app/assets/images/slicer.jpeg differ diff --git a/app/assets/javascripts/categories.coffee b/app/assets/javascripts/categories.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/categories.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/main.coffee b/app/assets/javascripts/main.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/main.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/merchants.coffee b/app/assets/javascripts/merchants.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/merchants.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/order_items.coffee b/app/assets/javascripts/order_items.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/order_items.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/orders.coffee b/app/assets/javascripts/orders.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/orders.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/product_categories.coffee b/app/assets/javascripts/product_categories.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/product_categories.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/products.coffee b/app/assets/javascripts/products.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/products.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/reviews.coffee b/app/assets/javascripts/reviews.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/reviews.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/sessions.coffee b/app/assets/javascripts/sessions.coffee new file mode 100644 index 0000000000..24f83d18bb --- /dev/null +++ b/app/assets/javascripts/sessions.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index f9cd5b3483..6dd163fe90 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -1,15 +1,221 @@ -/* - * This is a manifest file that'll be compiled into application.css, which will include all the files - * listed below. - * - * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, - * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. - * - * You're free to add application-wide styles to this file and they'll appear at the bottom of the - * compiled file so the styles you add here take precedence over styles defined in any styles - * defined in the other CSS/SCSS files in this directory. It is generally better to create a new - * file per style scope. - * - *= require_tree . - *= require_self - */ +@import url('foundation.css'); +@import url('https://fonts.googleapis.com/css?family=Josefin+Slab'); + + +/*HEADER*/ +header section.top-bar { + background-color: #5A6070; + margin-bottom: 2%; +} + +.basketcart-img { + height: 30%; +} + +section.top-bar nav.top-bar-section { + font-family: 'Josefin Slab', serif; +} + +ul.menu.top-bar-left, ul.menu.top-bar-right { + background-color: transparent; + font-family: 'Josefin Slab', serif; + color: #ECEBE4; + padding: 0 1% 0 1%; +} + +ul.menu.top-bar-right li a{ + display: inline; + text-align: right; +} + +.increase-font2 { + font-size: 150% +} + +header article h1#header-title a { + font-family: 'Josefin Slab', serif; + color: #483C46; + background-color: transparent; +} + +header article h4#header-subtitle { + font-family: 'Josefin Slab', serif; + color: #483C46; + background-color: transparent; +} + +header article h1#header-title a:hover { + color: #595959; +} + +header section#category-list article.top-bar-section ul { + border-top: #5A6070 solid 1px; + border-bottom: #5A6070 solid 1px; +} + +.increase-space { + padding-bottom: 2%; +} + +.center { + text-align: center; +} + +/*FOOTER*/ +footer div { + width: 100%; + background-color: #5A6070; + color: #ECEBE4; +} + +footer div p { + padding: .3%; +} + +/*ALL PAGES*/ +.page-title { + padding-top: 2%; + padding-bottom: 1%; + text-align: center; + font-family: 'Josefin Slab', serif; + color: #5E4E5B; +} + +ul.bullet-none { + list-style: none; +} + + +table, th, td { + border: 1px solid darkgrey; + font-family: 'Josefin Slab', serif; +} + +.indent { + margin-left: 10%; +} + +.add-space { + padding-right: 2%; +} + +.change-font { + font-family: 'Josefin Slab', serif; +} + +.add-padding-top { + padding-top: 1%; +} + +.underline { + border-bottom: dotted black 1px; +} + +/*PRODUCT PAGES*/ +.product-img { + /*display: block;*/ + width: 100%; + /*margin: auto;*/ + padding: auto; +} + +.product-link { + text-align: center; + font-family: 'Josefin Slab', serif; + color: #5E4E5B; +} + +.product-image-thumbnail { + width: 70%; + padding: 2%; +} + +.product-button { + text-align: center; + font-family: 'Josefin Slab', serif; + padding: 3px; + margin-top: 5px; + border: solid 1px #5A6070; + border-radius: 25%; + color: #ECEBE4; + background-color: #5E4E5B; + display: inline-block; + } + + .category-link { + font-family: 'Josefin Slab', serif; +} + +/*CATEGORY PAGES*/ +.category-img { + display: block; + width: 50%; + margin: auto; + padding-bottom: 2% +} +.category-img-thumbnail { + display: block; + padding: 2% +} + +.underline-category { + border-bottom: solid 1px #110D0F; + margin-bottom: 2%; +} + +.product-categories-link { + text-align: center; + font-family: 'Josefin Slab', serif; + color: #5E4E5B; +} + +.merchant-img-thumbnail { + width: 30%; +} + +/*TABLES*/ +.new-table { + padding: 2% 15% 0% 15%; +} + +.product-new-table { + padding: 2% 15% 0% 15%; + background-color: #ECEBE4; +} + +.form-text { + font-family: 'Josefin Slab', serif; + padding-left: 15%; + padding-top: 2%; +} + +#category-options { + font-family: 'Josefin Slab', serif; + padding-left: 10%; +} + +.cream-background { + background-color: #ECEBE4; + margin: 0 2% 0 2%; +} + +.top-add-space { + padding-top: 2%; +} + +.increase-font { + font-size: 110% +} + +.padding-lf-rt { + padding: 0 4% 0 4%; +} + +.padding-bot { + padding-bottom: 3%; +} + +/*MERCHANT*/ +.merchant-img { +padding-top: 3%; +} diff --git a/app/assets/stylesheets/categories.scss b/app/assets/stylesheets/categories.scss new file mode 100644 index 0000000000..42976cbc11 --- /dev/null +++ b/app/assets/stylesheets/categories.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Categories controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/foundation.css b/app/assets/stylesheets/foundation.css new file mode 100644 index 0000000000..66aca962de --- /dev/null +++ b/app/assets/stylesheets/foundation.css @@ -0,0 +1,4194 @@ +@charset "UTF-8"; +/** + * Foundation for Sites by ZURB + * Version 6.2.3 + * foundation.zurb.com + * Licensed under MIT Open Source + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS and IE text size adjust after device orientation change, + * without disabling user zoom. + */ +html { + font-family: sans-serif; + /* 1 */ + -ms-text-size-adjust: 100%; + /* 2 */ + -webkit-text-size-adjust: 100%; + /* 2 */ } + +/** + * Remove default margin. + */ +body { + margin: 0; } + +/* HTML5 display definitions + ========================================================================== */ +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; } + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ +audio, +canvas, +progress, +video { + display: inline-block; + /* 1 */ + vertical-align: baseline; + /* 2 */ } + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ +audio:not([controls]) { + display: none; + height: 0; } + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. + */ +[hidden], +template { + display: none; } + +/* Links + ========================================================================== */ +/** + * Remove the gray background color from active links in IE 10. + */ +a { + background-color: transparent; } + +/** + * Improve readability of focused elements when they are also in an + * active/hover state. + */ +a:active, +a:hover { + outline: 0; } + +/* Text-level semantics + ========================================================================== */ +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ +abbr[title] { + border-bottom: 1px dotted; } + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ +b, +strong { + font-weight: bold; } + +/** + * Address styling not present in Safari and Chrome. + */ +dfn { + font-style: italic; } + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ +h1 { + font-size: 2em; + margin: 0.67em 0; } + +/** + * Address styling not present in IE 8/9. + */ +mark { + background: #ff0; + color: #000; } + +/** + * Address inconsistent and variable font size in all browsers. + */ +small { + font-size: 80%; } + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +/* Embedded content + ========================================================================== */ +/** + * Remove border when inside `a` element in IE 8/9/10. + */ +img { + border: 0; } + +/** + * Correct overflow not hidden in IE 9/10/11. + */ +svg:not(:root) { + overflow: hidden; } + +/* Grouping content + ========================================================================== */ +/** + * Address margin not present in IE 8/9 and Safari. + */ +figure { + margin: 1em 40px; } + +/** + * Address differences between Firefox and other browsers. + */ +hr { + box-sizing: content-box; + height: 0; } + +/** + * Contain overflow in all browsers. + */ +pre { + overflow: auto; } + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; } + +/* Forms + ========================================================================== */ +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ +button, +input, +optgroup, +select, +textarea { + color: inherit; + /* 1 */ + font: inherit; + /* 2 */ + margin: 0; + /* 3 */ } + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ +button { + overflow: visible; } + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ +button, +select { + text-transform: none; } + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + /* 2 */ + cursor: pointer; + /* 3 */ } + +/** + * Re-set default cursor for disabled elements. + */ +button[disabled], +html input[disabled] { + cursor: not-allowed; } + +/** + * Remove inner padding and border in Firefox 4+. + */ +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; } + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ +input { + line-height: normal; } + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ } + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; } + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome. + */ +input[type="search"] { + -webkit-appearance: textfield; + /* 1 */ + box-sizing: content-box; + /* 2 */ } + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +/** + * Define consistent border, margin, and padding. + * [NOTE] We don't enable this ruleset in Foundation, because we want the
element to have plain styling. + */ +/* fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; + } */ +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ +legend { + border: 0; + /* 1 */ + padding: 0; + /* 2 */ } + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ +textarea { + overflow: auto; } + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ +optgroup { + font-weight: bold; } + +/* Tables + ========================================================================== */ +/** + * Remove most spacing between table cells. + */ +table { + border-collapse: collapse; + border-spacing: 0; } + +td, +th { + padding: 0; } + +.foundation-mq { + font-family: "small=0em&medium=40em&large=64em&xlarge=75em&xxlarge=90em"; } + +html { + font-size: 100%; + box-sizing: border-box; } + +*, +*::before, +*::after { + box-sizing: inherit; } + +body { + padding: 0; + margin: 0; + font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; + font-weight: normal; + line-height: 1.5; + color: #0a0a0a; + background: #fefefe; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } + +img { + max-width: 100%; + height: auto; + -ms-interpolation-mode: bicubic; + display: inline-block; + vertical-align: middle; } + +textarea { + height: auto; + min-height: 50px; + border-radius: 0; } + +select { + width: 100%; + border-radius: 0; } + +#map_canvas img, +#map_canvas embed, +#map_canvas object, +.map_canvas img, +.map_canvas embed, +.map_canvas object, +.mqa-display img, +.mqa-display embed, +.mqa-display object { + max-width: none !important; } + +button { + -webkit-appearance: none; + -moz-appearance: none; + background: transparent; + padding: 0; + border: 0; + border-radius: 0; + line-height: 1; } + [data-whatinput='mouse'] button { + outline: 0; } + +.is-visible { + display: block !important; } + +.is-hidden { + display: none !important; } + +.row { + max-width: 75rem; + margin-left: auto; + margin-right: auto; } + .row::before, .row::after { + content: ' '; + display: table; } + .row::after { + clear: both; } + .row.collapse > .column, .row.collapse > .columns { + padding-left: 0; + padding-right: 0; } + .row .row { + max-width: none; + margin-left: -0.625rem; + margin-right: -0.625rem; } + @media screen and (min-width: 40em) { + .row .row { + margin-left: -0.9375rem; + margin-right: -0.9375rem; } } + .row .row.collapse { + margin-left: 0; + margin-right: 0; } + .row.expanded { + max-width: none; } + .row.expanded .row { + margin-left: auto; + margin-right: auto; } + +.column, .columns { + width: 100%; + float: left; + padding-left: 0.625rem; + padding-right: 0.625rem; } + @media screen and (min-width: 40em) { + .column, .columns { + padding-left: 0.9375rem; + padding-right: 0.9375rem; } } + .column:last-child:not(:first-child), .columns:last-child:not(:first-child) { + float: right; } + .column.end:last-child:last-child, .end.columns:last-child:last-child { + float: left; } + +.column.row.row, .row.row.columns { + float: none; } + .row .column.row.row, .row .row.row.columns { + padding-left: 0; + padding-right: 0; + margin-left: 0; + margin-right: 0; } + +.small-1 { + width: 8.33333%; } + +.small-push-1 { + position: relative; + left: 8.33333%; } + +.small-pull-1 { + position: relative; + left: -8.33333%; } + +.small-offset-0 { + margin-left: 0%; } + +.small-2 { + width: 16.66667%; } + +.small-push-2 { + position: relative; + left: 16.66667%; } + +.small-pull-2 { + position: relative; + left: -16.66667%; } + +.small-offset-1 { + margin-left: 8.33333%; } + +.small-3 { + width: 25%; } + +.small-push-3 { + position: relative; + left: 25%; } + +.small-pull-3 { + position: relative; + left: -25%; } + +.small-offset-2 { + margin-left: 16.66667%; } + +.small-4 { + width: 33.33333%; } + +.small-push-4 { + position: relative; + left: 33.33333%; } + +.small-pull-4 { + position: relative; + left: -33.33333%; } + +.small-offset-3 { + margin-left: 25%; } + +.small-5 { + width: 41.66667%; } + +.small-push-5 { + position: relative; + left: 41.66667%; } + +.small-pull-5 { + position: relative; + left: -41.66667%; } + +.small-offset-4 { + margin-left: 33.33333%; } + +.small-6 { + width: 50%; } + +.small-push-6 { + position: relative; + left: 50%; } + +.small-pull-6 { + position: relative; + left: -50%; } + +.small-offset-5 { + margin-left: 41.66667%; } + +.small-7 { + width: 58.33333%; } + +.small-push-7 { + position: relative; + left: 58.33333%; } + +.small-pull-7 { + position: relative; + left: -58.33333%; } + +.small-offset-6 { + margin-left: 50%; } + +.small-8 { + width: 66.66667%; } + +.small-push-8 { + position: relative; + left: 66.66667%; } + +.small-pull-8 { + position: relative; + left: -66.66667%; } + +.small-offset-7 { + margin-left: 58.33333%; } + +.small-9 { + width: 75%; } + +.small-push-9 { + position: relative; + left: 75%; } + +.small-pull-9 { + position: relative; + left: -75%; } + +.small-offset-8 { + margin-left: 66.66667%; } + +.small-10 { + width: 83.33333%; } + +.small-push-10 { + position: relative; + left: 83.33333%; } + +.small-pull-10 { + position: relative; + left: -83.33333%; } + +.small-offset-9 { + margin-left: 75%; } + +.small-11 { + width: 91.66667%; } + +.small-push-11 { + position: relative; + left: 91.66667%; } + +.small-pull-11 { + position: relative; + left: -91.66667%; } + +.small-offset-10 { + margin-left: 83.33333%; } + +.small-12 { + width: 100%; } + +.small-offset-11 { + margin-left: 91.66667%; } + +.small-up-1 > .column, .small-up-1 > .columns { + width: 100%; + float: left; } + .small-up-1 > .column:nth-of-type(1n), .small-up-1 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-1 > .column:nth-of-type(1n+1), .small-up-1 > .columns:nth-of-type(1n+1) { + clear: both; } + .small-up-1 > .column:last-child, .small-up-1 > .columns:last-child { + float: left; } + +.small-up-2 > .column, .small-up-2 > .columns { + width: 50%; + float: left; } + .small-up-2 > .column:nth-of-type(1n), .small-up-2 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-2 > .column:nth-of-type(2n+1), .small-up-2 > .columns:nth-of-type(2n+1) { + clear: both; } + .small-up-2 > .column:last-child, .small-up-2 > .columns:last-child { + float: left; } + +.small-up-3 > .column, .small-up-3 > .columns { + width: 33.33333%; + float: left; } + .small-up-3 > .column:nth-of-type(1n), .small-up-3 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-3 > .column:nth-of-type(3n+1), .small-up-3 > .columns:nth-of-type(3n+1) { + clear: both; } + .small-up-3 > .column:last-child, .small-up-3 > .columns:last-child { + float: left; } + +.small-up-4 > .column, .small-up-4 > .columns { + width: 25%; + float: left; } + .small-up-4 > .column:nth-of-type(1n), .small-up-4 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-4 > .column:nth-of-type(4n+1), .small-up-4 > .columns:nth-of-type(4n+1) { + clear: both; } + .small-up-4 > .column:last-child, .small-up-4 > .columns:last-child { + float: left; } + +.small-up-5 > .column, .small-up-5 > .columns { + width: 20%; + float: left; } + .small-up-5 > .column:nth-of-type(1n), .small-up-5 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-5 > .column:nth-of-type(5n+1), .small-up-5 > .columns:nth-of-type(5n+1) { + clear: both; } + .small-up-5 > .column:last-child, .small-up-5 > .columns:last-child { + float: left; } + +.small-up-6 > .column, .small-up-6 > .columns { + width: 16.66667%; + float: left; } + .small-up-6 > .column:nth-of-type(1n), .small-up-6 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-6 > .column:nth-of-type(6n+1), .small-up-6 > .columns:nth-of-type(6n+1) { + clear: both; } + .small-up-6 > .column:last-child, .small-up-6 > .columns:last-child { + float: left; } + +.small-up-7 > .column, .small-up-7 > .columns { + width: 14.28571%; + float: left; } + .small-up-7 > .column:nth-of-type(1n), .small-up-7 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-7 > .column:nth-of-type(7n+1), .small-up-7 > .columns:nth-of-type(7n+1) { + clear: both; } + .small-up-7 > .column:last-child, .small-up-7 > .columns:last-child { + float: left; } + +.small-up-8 > .column, .small-up-8 > .columns { + width: 12.5%; + float: left; } + .small-up-8 > .column:nth-of-type(1n), .small-up-8 > .columns:nth-of-type(1n) { + clear: none; } + .small-up-8 > .column:nth-of-type(8n+1), .small-up-8 > .columns:nth-of-type(8n+1) { + clear: both; } + .small-up-8 > .column:last-child, .small-up-8 > .columns:last-child { + float: left; } + +.small-collapse > .column, .small-collapse > .columns { + padding-left: 0; + padding-right: 0; } + +.small-collapse .row, +.expanded.row .small-collapse.row { + margin-left: 0; + margin-right: 0; } + +.small-uncollapse > .column, .small-uncollapse > .columns { + padding-left: 0.625rem; + padding-right: 0.625rem; } + +.small-centered { + float: none; + margin-left: auto; + margin-right: auto; } + +.small-uncentered, +.small-push-0, +.small-pull-0 { + position: static; + margin-left: 0; + margin-right: 0; + float: left; } + +@media screen and (min-width: 40em) { + .medium-1 { + width: 8.33333%; } + .medium-push-1 { + position: relative; + left: 8.33333%; } + .medium-pull-1 { + position: relative; + left: -8.33333%; } + .medium-offset-0 { + margin-left: 0%; } + .medium-2 { + width: 16.66667%; } + .medium-push-2 { + position: relative; + left: 16.66667%; } + .medium-pull-2 { + position: relative; + left: -16.66667%; } + .medium-offset-1 { + margin-left: 8.33333%; } + .medium-3 { + width: 25%; } + .medium-push-3 { + position: relative; + left: 25%; } + .medium-pull-3 { + position: relative; + left: -25%; } + .medium-offset-2 { + margin-left: 16.66667%; } + .medium-4 { + width: 33.33333%; } + .medium-push-4 { + position: relative; + left: 33.33333%; } + .medium-pull-4 { + position: relative; + left: -33.33333%; } + .medium-offset-3 { + margin-left: 25%; } + .medium-5 { + width: 41.66667%; } + .medium-push-5 { + position: relative; + left: 41.66667%; } + .medium-pull-5 { + position: relative; + left: -41.66667%; } + .medium-offset-4 { + margin-left: 33.33333%; } + .medium-6 { + width: 50%; } + .medium-push-6 { + position: relative; + left: 50%; } + .medium-pull-6 { + position: relative; + left: -50%; } + .medium-offset-5 { + margin-left: 41.66667%; } + .medium-7 { + width: 58.33333%; } + .medium-push-7 { + position: relative; + left: 58.33333%; } + .medium-pull-7 { + position: relative; + left: -58.33333%; } + .medium-offset-6 { + margin-left: 50%; } + .medium-8 { + width: 66.66667%; } + .medium-push-8 { + position: relative; + left: 66.66667%; } + .medium-pull-8 { + position: relative; + left: -66.66667%; } + .medium-offset-7 { + margin-left: 58.33333%; } + .medium-9 { + width: 75%; } + .medium-push-9 { + position: relative; + left: 75%; } + .medium-pull-9 { + position: relative; + left: -75%; } + .medium-offset-8 { + margin-left: 66.66667%; } + .medium-10 { + width: 83.33333%; } + .medium-push-10 { + position: relative; + left: 83.33333%; } + .medium-pull-10 { + position: relative; + left: -83.33333%; } + .medium-offset-9 { + margin-left: 75%; } + .medium-11 { + width: 91.66667%; } + .medium-push-11 { + position: relative; + left: 91.66667%; } + .medium-pull-11 { + position: relative; + left: -91.66667%; } + .medium-offset-10 { + margin-left: 83.33333%; } + .medium-12 { + width: 100%; } + .medium-offset-11 { + margin-left: 91.66667%; } + .medium-up-1 > .column, .medium-up-1 > .columns { + width: 100%; + float: left; } + .medium-up-1 > .column:nth-of-type(1n), .medium-up-1 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-1 > .column:nth-of-type(1n+1), .medium-up-1 > .columns:nth-of-type(1n+1) { + clear: both; } + .medium-up-1 > .column:last-child, .medium-up-1 > .columns:last-child { + float: left; } + .medium-up-2 > .column, .medium-up-2 > .columns { + width: 50%; + float: left; } + .medium-up-2 > .column:nth-of-type(1n), .medium-up-2 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-2 > .column:nth-of-type(2n+1), .medium-up-2 > .columns:nth-of-type(2n+1) { + clear: both; } + .medium-up-2 > .column:last-child, .medium-up-2 > .columns:last-child { + float: left; } + .medium-up-3 > .column, .medium-up-3 > .columns { + width: 33.33333%; + float: left; } + .medium-up-3 > .column:nth-of-type(1n), .medium-up-3 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-3 > .column:nth-of-type(3n+1), .medium-up-3 > .columns:nth-of-type(3n+1) { + clear: both; } + .medium-up-3 > .column:last-child, .medium-up-3 > .columns:last-child { + float: left; } + .medium-up-4 > .column, .medium-up-4 > .columns { + width: 25%; + float: left; } + .medium-up-4 > .column:nth-of-type(1n), .medium-up-4 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-4 > .column:nth-of-type(4n+1), .medium-up-4 > .columns:nth-of-type(4n+1) { + clear: both; } + .medium-up-4 > .column:last-child, .medium-up-4 > .columns:last-child { + float: left; } + .medium-up-5 > .column, .medium-up-5 > .columns { + width: 20%; + float: left; } + .medium-up-5 > .column:nth-of-type(1n), .medium-up-5 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-5 > .column:nth-of-type(5n+1), .medium-up-5 > .columns:nth-of-type(5n+1) { + clear: both; } + .medium-up-5 > .column:last-child, .medium-up-5 > .columns:last-child { + float: left; } + .medium-up-6 > .column, .medium-up-6 > .columns { + width: 16.66667%; + float: left; } + .medium-up-6 > .column:nth-of-type(1n), .medium-up-6 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-6 > .column:nth-of-type(6n+1), .medium-up-6 > .columns:nth-of-type(6n+1) { + clear: both; } + .medium-up-6 > .column:last-child, .medium-up-6 > .columns:last-child { + float: left; } + .medium-up-7 > .column, .medium-up-7 > .columns { + width: 14.28571%; + float: left; } + .medium-up-7 > .column:nth-of-type(1n), .medium-up-7 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-7 > .column:nth-of-type(7n+1), .medium-up-7 > .columns:nth-of-type(7n+1) { + clear: both; } + .medium-up-7 > .column:last-child, .medium-up-7 > .columns:last-child { + float: left; } + .medium-up-8 > .column, .medium-up-8 > .columns { + width: 12.5%; + float: left; } + .medium-up-8 > .column:nth-of-type(1n), .medium-up-8 > .columns:nth-of-type(1n) { + clear: none; } + .medium-up-8 > .column:nth-of-type(8n+1), .medium-up-8 > .columns:nth-of-type(8n+1) { + clear: both; } + .medium-up-8 > .column:last-child, .medium-up-8 > .columns:last-child { + float: left; } + .medium-collapse > .column, .medium-collapse > .columns { + padding-left: 0; + padding-right: 0; } + .medium-collapse .row, + .expanded.row .medium-collapse.row { + margin-left: 0; + margin-right: 0; } + .medium-uncollapse > .column, .medium-uncollapse > .columns { + padding-left: 0.9375rem; + padding-right: 0.9375rem; } + .medium-centered { + float: none; + margin-left: auto; + margin-right: auto; } + .medium-uncentered, + .medium-push-0, + .medium-pull-0 { + position: static; + margin-left: 0; + margin-right: 0; + float: left; } } + +@media screen and (min-width: 64em) { + .large-1 { + width: 8.33333%; } + .large-push-1 { + position: relative; + left: 8.33333%; } + .large-pull-1 { + position: relative; + left: -8.33333%; } + .large-offset-0 { + margin-left: 0%; } + .large-2 { + width: 16.66667%; } + .large-push-2 { + position: relative; + left: 16.66667%; } + .large-pull-2 { + position: relative; + left: -16.66667%; } + .large-offset-1 { + margin-left: 8.33333%; } + .large-3 { + width: 25%; } + .large-push-3 { + position: relative; + left: 25%; } + .large-pull-3 { + position: relative; + left: -25%; } + .large-offset-2 { + margin-left: 16.66667%; } + .large-4 { + width: 33.33333%; } + .large-push-4 { + position: relative; + left: 33.33333%; } + .large-pull-4 { + position: relative; + left: -33.33333%; } + .large-offset-3 { + margin-left: 25%; } + .large-5 { + width: 41.66667%; } + .large-push-5 { + position: relative; + left: 41.66667%; } + .large-pull-5 { + position: relative; + left: -41.66667%; } + .large-offset-4 { + margin-left: 33.33333%; } + .large-6 { + width: 50%; } + .large-push-6 { + position: relative; + left: 50%; } + .large-pull-6 { + position: relative; + left: -50%; } + .large-offset-5 { + margin-left: 41.66667%; } + .large-7 { + width: 58.33333%; } + .large-push-7 { + position: relative; + left: 58.33333%; } + .large-pull-7 { + position: relative; + left: -58.33333%; } + .large-offset-6 { + margin-left: 50%; } + .large-8 { + width: 66.66667%; } + .large-push-8 { + position: relative; + left: 66.66667%; } + .large-pull-8 { + position: relative; + left: -66.66667%; } + .large-offset-7 { + margin-left: 58.33333%; } + .large-9 { + width: 75%; } + .large-push-9 { + position: relative; + left: 75%; } + .large-pull-9 { + position: relative; + left: -75%; } + .large-offset-8 { + margin-left: 66.66667%; } + .large-10 { + width: 83.33333%; } + .large-push-10 { + position: relative; + left: 83.33333%; } + .large-pull-10 { + position: relative; + left: -83.33333%; } + .large-offset-9 { + margin-left: 75%; } + .large-11 { + width: 91.66667%; } + .large-push-11 { + position: relative; + left: 91.66667%; } + .large-pull-11 { + position: relative; + left: -91.66667%; } + .large-offset-10 { + margin-left: 83.33333%; } + .large-12 { + width: 100%; } + .large-offset-11 { + margin-left: 91.66667%; } + .large-up-1 > .column, .large-up-1 > .columns { + width: 100%; + float: left; } + .large-up-1 > .column:nth-of-type(1n), .large-up-1 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-1 > .column:nth-of-type(1n+1), .large-up-1 > .columns:nth-of-type(1n+1) { + clear: both; } + .large-up-1 > .column:last-child, .large-up-1 > .columns:last-child { + float: left; } + .large-up-2 > .column, .large-up-2 > .columns { + width: 50%; + float: left; } + .large-up-2 > .column:nth-of-type(1n), .large-up-2 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-2 > .column:nth-of-type(2n+1), .large-up-2 > .columns:nth-of-type(2n+1) { + clear: both; } + .large-up-2 > .column:last-child, .large-up-2 > .columns:last-child { + float: left; } + .large-up-3 > .column, .large-up-3 > .columns { + width: 33.33333%; + float: left; } + .large-up-3 > .column:nth-of-type(1n), .large-up-3 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-3 > .column:nth-of-type(3n+1), .large-up-3 > .columns:nth-of-type(3n+1) { + clear: both; } + .large-up-3 > .column:last-child, .large-up-3 > .columns:last-child { + float: left; } + .large-up-4 > .column, .large-up-4 > .columns { + width: 25%; + float: left; } + .large-up-4 > .column:nth-of-type(1n), .large-up-4 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-4 > .column:nth-of-type(4n+1), .large-up-4 > .columns:nth-of-type(4n+1) { + clear: both; } + .large-up-4 > .column:last-child, .large-up-4 > .columns:last-child { + float: left; } + .large-up-5 > .column, .large-up-5 > .columns { + width: 20%; + float: left; } + .large-up-5 > .column:nth-of-type(1n), .large-up-5 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-5 > .column:nth-of-type(5n+1), .large-up-5 > .columns:nth-of-type(5n+1) { + clear: both; } + .large-up-5 > .column:last-child, .large-up-5 > .columns:last-child { + float: left; } + .large-up-6 > .column, .large-up-6 > .columns { + width: 16.66667%; + float: left; } + .large-up-6 > .column:nth-of-type(1n), .large-up-6 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-6 > .column:nth-of-type(6n+1), .large-up-6 > .columns:nth-of-type(6n+1) { + clear: both; } + .large-up-6 > .column:last-child, .large-up-6 > .columns:last-child { + float: left; } + .large-up-7 > .column, .large-up-7 > .columns { + width: 14.28571%; + float: left; } + .large-up-7 > .column:nth-of-type(1n), .large-up-7 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-7 > .column:nth-of-type(7n+1), .large-up-7 > .columns:nth-of-type(7n+1) { + clear: both; } + .large-up-7 > .column:last-child, .large-up-7 > .columns:last-child { + float: left; } + .large-up-8 > .column, .large-up-8 > .columns { + width: 12.5%; + float: left; } + .large-up-8 > .column:nth-of-type(1n), .large-up-8 > .columns:nth-of-type(1n) { + clear: none; } + .large-up-8 > .column:nth-of-type(8n+1), .large-up-8 > .columns:nth-of-type(8n+1) { + clear: both; } + .large-up-8 > .column:last-child, .large-up-8 > .columns:last-child { + float: left; } + .large-collapse > .column, .large-collapse > .columns { + padding-left: 0; + padding-right: 0; } + .large-collapse .row, + .expanded.row .large-collapse.row { + margin-left: 0; + margin-right: 0; } + .large-uncollapse > .column, .large-uncollapse > .columns { + padding-left: 0.9375rem; + padding-right: 0.9375rem; } + .large-centered { + float: none; + margin-left: auto; + margin-right: auto; } + .large-uncentered, + .large-push-0, + .large-pull-0 { + position: static; + margin-left: 0; + margin-right: 0; + float: left; } } + +div, +dl, +dt, +dd, +ul, +ol, +li, +h1, +h2, +h3, +h4, +h5, +h6, +pre, +form, +p, +blockquote, +th, +td { + margin: 0; + padding: 0; } + +p { + font-size: inherit; + line-height: 1.6; + margin-bottom: 1rem; + text-rendering: optimizeLegibility; } + +em, +i { + font-style: italic; + line-height: inherit; } + +strong, +b { + font-weight: bold; + line-height: inherit; } + +small { + font-size: 80%; + line-height: inherit; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; + font-weight: normal; + font-style: normal; + color: inherit; + text-rendering: optimizeLegibility; + margin-top: 0; + margin-bottom: 0.5rem; + line-height: 1.4; } + h1 small, + h2 small, + h3 small, + h4 small, + h5 small, + h6 small { + color: #cacaca; + line-height: 0; } + +h1 { + font-size: 1.5rem; } + +h2 { + font-size: 1.25rem; } + +h3 { + font-size: 1.1875rem; } + +h4 { + font-size: 1.125rem; } + +h5 { + font-size: 1.0625rem; } + +h6 { + font-size: 1rem; } + +@media screen and (min-width: 40em) { + h1 { + font-size: 3rem; } + h2 { + font-size: 2.5rem; } + h3 { + font-size: 1.9375rem; } + h4 { + font-size: 1.5625rem; } + h5 { + font-size: 1.25rem; } + h6 { + font-size: 1rem; } } + +a { + color: #2199e8; + text-decoration: none; + line-height: inherit; + cursor: pointer; } + a:hover, a:focus { + color: #1585cf; } + a img { + border: 0; } + +hr { + max-width: 75rem; + height: 0; + border-right: 0; + border-top: 0; + border-bottom: 1px solid #cacaca; + border-left: 0; + margin: 1.25rem auto; + clear: both; } + +ul, +ol, +dl { + line-height: 1.6; + margin-bottom: 1rem; + list-style-position: outside; } + +li { + font-size: inherit; } + +ul { + list-style-type: disc; + margin-left: 1.25rem; } + +ol { + margin-left: 1.25rem; } + +ul ul, ol ul, ul ol, ol ol { + margin-left: 1.25rem; + margin-bottom: 0; } + +dl { + margin-bottom: 1rem; } + dl dt { + margin-bottom: 0.3rem; + font-weight: bold; } + +blockquote { + margin: 0 0 1rem; + padding: 0.5625rem 1.25rem 0 1.1875rem; + border-left: 1px solid #cacaca; } + blockquote, blockquote p { + line-height: 1.6; + color: #8a8a8a; } + +cite { + display: block; + font-size: 0.8125rem; + color: #8a8a8a; } + cite:before { + content: '\2014 \0020'; } + +abbr { + color: #0a0a0a; + cursor: help; + border-bottom: 1px dotted #0a0a0a; } + +code { + font-family: Consolas, "Liberation Mono", Courier, monospace; + font-weight: normal; + color: #0a0a0a; + background-color: #e6e6e6; + border: 1px solid #cacaca; + padding: 0.125rem 0.3125rem 0.0625rem; } + +kbd { + padding: 0.125rem 0.25rem 0; + margin: 0; + background-color: #e6e6e6; + color: #0a0a0a; + font-family: Consolas, "Liberation Mono", Courier, monospace; } + +.subheader { + margin-top: 0.2rem; + margin-bottom: 0.5rem; + font-weight: normal; + line-height: 1.4; + color: #8a8a8a; } + +.lead { + font-size: 125%; + line-height: 1.6; } + +.stat { + font-size: 2.5rem; + line-height: 1; } + p + .stat { + margin-top: -1rem; } + +.no-bullet { + margin-left: 0; + list-style: none; } + +.text-left { + text-align: left; } + +.text-right { + text-align: right; } + +.text-center { + text-align: center; } + +.text-justify { + text-align: justify; } + +@media screen and (min-width: 40em) { + .medium-text-left { + text-align: left; } + .medium-text-right { + text-align: right; } + .medium-text-center { + text-align: center; } + .medium-text-justify { + text-align: justify; } } + +@media screen and (min-width: 64em) { + .large-text-left { + text-align: left; } + .large-text-right { + text-align: right; } + .large-text-center { + text-align: center; } + .large-text-justify { + text-align: justify; } } + +.show-for-print { + display: none !important; } + +@media print { + * { + background: transparent !important; + color: black !important; + box-shadow: none !important; + text-shadow: none !important; } + .show-for-print { + display: block !important; } + .hide-for-print { + display: none !important; } + table.show-for-print { + display: table !important; } + thead.show-for-print { + display: table-header-group !important; } + tbody.show-for-print { + display: table-row-group !important; } + tr.show-for-print { + display: table-row !important; } + td.show-for-print { + display: table-cell !important; } + th.show-for-print { + display: table-cell !important; } + a, + a:visited { + text-decoration: underline; } + a[href]:after { + content: " (" attr(href) ")"; } + .ir a:after, + a[href^='javascript:']:after, + a[href^='#']:after { + content: ''; } + abbr[title]:after { + content: " (" attr(title) ")"; } + pre, + blockquote { + border: 1px solid #8a8a8a; + page-break-inside: avoid; } + thead { + display: table-header-group; } + tr, + img { + page-break-inside: avoid; } + img { + max-width: 100% !important; } + @page { + margin: 0.5cm; } + p, + h2, + h3 { + orphans: 3; + widows: 3; } + h2, + h3 { + page-break-after: avoid; } } + +.button { + display: inline-block; + text-align: center; + line-height: 1; + cursor: pointer; + -webkit-appearance: none; + transition: background-color 0.25s ease-out, color 0.25s ease-out; + vertical-align: middle; + border: 1px solid transparent; + border-radius: 0; + padding: 0.85em 1em; + margin: 0 0 1rem 0; + font-size: 0.9rem; + background-color: #2199e8; + color: #fefefe; } + [data-whatinput='mouse'] .button { + outline: 0; } + .button:hover, .button:focus { + background-color: #1583cc; + color: #fefefe; } + .button.tiny { + font-size: 0.6rem; } + .button.small { + font-size: 0.75rem; } + .button.large { + font-size: 1.25rem; } + .button.expanded { + display: block; + width: 100%; + margin-left: 0; + margin-right: 0; } + .button.primary { + background-color: #2199e8; + color: #fefefe; } + .button.primary:hover, .button.primary:focus { + background-color: #147cc0; + color: #fefefe; } + .button.secondary { + background-color: #777; + color: #fefefe; } + .button.secondary:hover, .button.secondary:focus { + background-color: #5f5f5f; + color: #fefefe; } + .button.success { + background-color: #3adb76; + color: #fefefe; } + .button.success:hover, .button.success:focus { + background-color: #22bb5b; + color: #fefefe; } + .button.warning { + background-color: #ffae00; + color: #fefefe; } + .button.warning:hover, .button.warning:focus { + background-color: #cc8b00; + color: #fefefe; } + .button.alert { + background-color: #ec5840; + color: #fefefe; } + .button.alert:hover, .button.alert:focus { + background-color: #da3116; + color: #fefefe; } + .button.hollow { + border: 1px solid #2199e8; + color: #2199e8; } + .button.hollow, .button.hollow:hover, .button.hollow:focus { + background-color: transparent; } + .button.hollow:hover, .button.hollow:focus { + border-color: #0c4d78; + color: #0c4d78; } + .button.hollow.primary { + border: 1px solid #2199e8; + color: #2199e8; } + .button.hollow.primary:hover, .button.hollow.primary:focus { + border-color: #0c4d78; + color: #0c4d78; } + .button.hollow.secondary { + border: 1px solid #777; + color: #777; } + .button.hollow.secondary:hover, .button.hollow.secondary:focus { + border-color: #3c3c3c; + color: #3c3c3c; } + .button.hollow.success { + border: 1px solid #3adb76; + color: #3adb76; } + .button.hollow.success:hover, .button.hollow.success:focus { + border-color: #157539; + color: #157539; } + .button.hollow.warning { + border: 1px solid #ffae00; + color: #ffae00; } + .button.hollow.warning:hover, .button.hollow.warning:focus { + border-color: #805700; + color: #805700; } + .button.hollow.alert { + border: 1px solid #ec5840; + color: #ec5840; } + .button.hollow.alert:hover, .button.hollow.alert:focus { + border-color: #881f0e; + color: #881f0e; } + .button.disabled, .button[disabled] { + opacity: 0.25; + cursor: not-allowed; } + .button.disabled:hover, .button.disabled:focus, .button[disabled]:hover, .button[disabled]:focus { + background-color: #2199e8; + color: #fefefe; } + .button.dropdown::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 0.4em; + border-color: #fefefe transparent transparent; + border-top-style: solid; + border-bottom-width: 0; + position: relative; + top: 0.4em; + float: right; + margin-left: 1em; + display: inline-block; } + .button.arrow-only::after { + margin-left: 0; + float: none; + top: -0.1em; } + +[type='text'], [type='password'], [type='date'], [type='datetime'], [type='datetime-local'], [type='month'], [type='week'], [type='email'], [type='number'], [type='search'], [type='tel'], [type='time'], [type='url'], [type='color'], +textarea { + display: block; + box-sizing: border-box; + width: 100%; + height: 2.4375rem; + padding: 0.5rem; + border: 1px solid #cacaca; + margin: 0 0 1rem; + font-family: inherit; + font-size: 1rem; + color: #0a0a0a; + background-color: #fefefe; + box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.1); + border-radius: 0; + transition: box-shadow 0.5s, border-color 0.25s ease-in-out; + -webkit-appearance: none; + -moz-appearance: none; } + [type='text']:focus, [type='password']:focus, [type='date']:focus, [type='datetime']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='week']:focus, [type='email']:focus, [type='number']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='url']:focus, [type='color']:focus, + textarea:focus { + border: 1px solid #8a8a8a; + background-color: #fefefe; + outline: none; + box-shadow: 0 0 5px #cacaca; + transition: box-shadow 0.5s, border-color 0.25s ease-in-out; } + +textarea { + max-width: 100%; } + textarea[rows] { + height: auto; } + +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #cacaca; } + +input::-moz-placeholder, +textarea::-moz-placeholder { + color: #cacaca; } + +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #cacaca; } + +input::placeholder, +textarea::placeholder { + color: #cacaca; } + +input:disabled, input[readonly], +textarea:disabled, +textarea[readonly] { + background-color: #e6e6e6; + cursor: not-allowed; } + +[type='submit'], +[type='button'] { + border-radius: 0; + -webkit-appearance: none; + -moz-appearance: none; } + +input[type='search'] { + box-sizing: border-box; } + +[type='file'], +[type='checkbox'], +[type='radio'] { + margin: 0 0 1rem; } + +[type='checkbox'] + label, +[type='radio'] + label { + display: inline-block; + margin-left: 0.5rem; + margin-right: 1rem; + margin-bottom: 0; + vertical-align: baseline; } + [type='checkbox'] + label[for], + [type='radio'] + label[for] { + cursor: pointer; } + +label > [type='checkbox'], +label > [type='radio'] { + margin-right: 0.5rem; } + +[type='file'] { + width: 100%; } + +label { + display: block; + margin: 0; + font-size: 0.875rem; + font-weight: normal; + line-height: 1.8; + color: #0a0a0a; } + label.middle { + margin: 0 0 1rem; + padding: 0.5625rem 0; } + +.help-text { + margin-top: -0.5rem; + font-size: 0.8125rem; + font-style: italic; + color: #0a0a0a; } + +.input-group { + display: table; + width: 100%; + margin-bottom: 1rem; } + .input-group > :first-child { + border-radius: 0 0 0 0; } + .input-group > :last-child > * { + border-radius: 0 0 0 0; } + +.input-group-label, .input-group-field, .input-group-button { + margin: 0; + white-space: nowrap; + display: table-cell; + vertical-align: middle; } + +.input-group-label { + text-align: center; + padding: 0 1rem; + background: #e6e6e6; + color: #0a0a0a; + border: 1px solid #cacaca; + white-space: nowrap; + width: 1%; + height: 100%; } + .input-group-label:first-child { + border-right: 0; } + .input-group-label:last-child { + border-left: 0; } + +.input-group-field { + border-radius: 0; + height: 2.5rem; } + +.input-group-button { + padding-top: 0; + padding-bottom: 0; + text-align: center; + height: 100%; + width: 1%; } + .input-group-button a, + .input-group-button input, + .input-group-button button { + margin: 0; } + +.input-group .input-group-button { + display: table-cell; } + +fieldset { + border: 0; + padding: 0; + margin: 0; } + +legend { + margin-bottom: 0.5rem; + max-width: 100%; } + +.fieldset { + border: 1px solid #cacaca; + padding: 1.25rem; + margin: 1.125rem 0; } + .fieldset legend { + background: #fefefe; + padding: 0 0.1875rem; + margin: 0; + margin-left: -0.1875rem; } + +select { + height: 2.4375rem; + padding: 0.5rem; + border: 1px solid #cacaca; + margin: 0 0 1rem; + font-size: 1rem; + font-family: inherit; + line-height: normal; + color: #0a0a0a; + background-color: #fefefe; + border-radius: 0; + -webkit-appearance: none; + -moz-appearance: none; + background-image: url("data:image/svg+xml;utf8,"); + background-size: 9px 6px; + background-position: right -1rem center; + background-origin: content-box; + background-repeat: no-repeat; + padding-right: 1.5rem; } + @media screen and (min-width: 0\0) { + select { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg=="); } } + select:disabled { + background-color: #e6e6e6; + cursor: not-allowed; } + select::-ms-expand { + display: none; } + select[multiple] { + height: auto; + background-image: none; } + +.is-invalid-input:not(:focus) { + background-color: rgba(236, 88, 64, 0.1); + border-color: #ec5840; } + +.is-invalid-label { + color: #ec5840; } + +.form-error { + display: none; + margin-top: -0.5rem; + margin-bottom: 1rem; + font-size: 0.75rem; + font-weight: bold; + color: #ec5840; } + .form-error.is-visible { + display: block; } + +.accordion { + list-style-type: none; + background: #fefefe; + margin-left: 0; } + +.accordion-item:first-child > :first-child { + border-radius: 0 0 0 0; } + +.accordion-item:last-child > :last-child { + border-radius: 0 0 0 0; } + +.accordion-title { + display: block; + padding: 1.25rem 1rem; + line-height: 1; + font-size: 0.75rem; + color: #2199e8; + position: relative; + border: 1px solid #e6e6e6; + border-bottom: 0; } + :last-child:not(.is-active) > .accordion-title { + border-radius: 0 0 0 0; + border-bottom: 1px solid #e6e6e6; } + .accordion-title:hover, .accordion-title:focus { + background-color: #e6e6e6; } + .accordion-title::before { + content: '+'; + position: absolute; + right: 1rem; + top: 50%; + margin-top: -0.5rem; } + .is-active > .accordion-title::before { + content: '–'; } + +.accordion-content { + padding: 1rem; + display: none; + border: 1px solid #e6e6e6; + border-bottom: 0; + background-color: #fefefe; + color: #0a0a0a; } + :last-child > .accordion-content:last-child { + border-bottom: 1px solid #e6e6e6; } + +.is-accordion-submenu-parent > a { + position: relative; } + .is-accordion-submenu-parent > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 6px; + border-color: #2199e8 transparent transparent; + border-top-style: solid; + border-bottom-width: 0; + position: absolute; + top: 50%; + margin-top: -4px; + right: 1rem; } + +.is-accordion-submenu-parent[aria-expanded='true'] > a::after { + -webkit-transform-origin: 50% 50%; + -ms-transform-origin: 50% 50%; + transform-origin: 50% 50%; + -webkit-transform: scaleY(-1); + -ms-transform: scaleY(-1); + transform: scaleY(-1); } + +.badge { + display: inline-block; + padding: 0.3em; + min-width: 2.1em; + font-size: 0.6rem; + text-align: center; + border-radius: 50%; + background: #2199e8; + color: #fefefe; } + .badge.secondary { + background: #777; + color: #fefefe; } + .badge.success { + background: #3adb76; + color: #fefefe; } + .badge.warning { + background: #ffae00; + color: #fefefe; } + .badge.alert { + background: #ec5840; + color: #fefefe; } + +.breadcrumbs { + list-style: none; + margin: 0 0 1rem 0; } + .breadcrumbs::before, .breadcrumbs::after { + content: ' '; + display: table; } + .breadcrumbs::after { + clear: both; } + .breadcrumbs li { + float: left; + color: #0a0a0a; + font-size: 0.6875rem; + cursor: default; + text-transform: uppercase; } + .breadcrumbs li:not(:last-child)::after { + color: #cacaca; + content: "/"; + margin: 0 0.75rem; + position: relative; + top: 1px; + opacity: 1; } + .breadcrumbs a { + color: #2199e8; } + .breadcrumbs a:hover { + text-decoration: underline; } + .breadcrumbs .disabled { + color: #cacaca; + cursor: not-allowed; } + +.button-group { + margin-bottom: 1rem; + font-size: 0; } + .button-group::before, .button-group::after { + content: ' '; + display: table; } + .button-group::after { + clear: both; } + .button-group .button { + margin: 0; + margin-right: 1px; + margin-bottom: 1px; + font-size: 0.9rem; } + .button-group .button:last-child { + margin-right: 0; } + .button-group.tiny .button { + font-size: 0.6rem; } + .button-group.small .button { + font-size: 0.75rem; } + .button-group.large .button { + font-size: 1.25rem; } + .button-group.expanded { + margin-right: -1px; } + .button-group.expanded::before, .button-group.expanded::after { + display: none; } + .button-group.expanded .button:first-child:nth-last-child(2), .button-group.expanded .button:first-child:nth-last-child(2):first-child:nth-last-child(2) ~ .button { + display: inline-block; + width: calc(50% - 1px); + margin-right: 1px; } + .button-group.expanded .button:first-child:nth-last-child(2):last-child, .button-group.expanded .button:first-child:nth-last-child(2):first-child:nth-last-child(2) ~ .button:last-child { + margin-right: -6px; } + .button-group.expanded .button:first-child:nth-last-child(3), .button-group.expanded .button:first-child:nth-last-child(3):first-child:nth-last-child(3) ~ .button { + display: inline-block; + width: calc(33.33333% - 1px); + margin-right: 1px; } + .button-group.expanded .button:first-child:nth-last-child(3):last-child, .button-group.expanded .button:first-child:nth-last-child(3):first-child:nth-last-child(3) ~ .button:last-child { + margin-right: -6px; } + .button-group.expanded .button:first-child:nth-last-child(4), .button-group.expanded .button:first-child:nth-last-child(4):first-child:nth-last-child(4) ~ .button { + display: inline-block; + width: calc(25% - 1px); + margin-right: 1px; } + .button-group.expanded .button:first-child:nth-last-child(4):last-child, .button-group.expanded .button:first-child:nth-last-child(4):first-child:nth-last-child(4) ~ .button:last-child { + margin-right: -6px; } + .button-group.expanded .button:first-child:nth-last-child(5), .button-group.expanded .button:first-child:nth-last-child(5):first-child:nth-last-child(5) ~ .button { + display: inline-block; + width: calc(20% - 1px); + margin-right: 1px; } + .button-group.expanded .button:first-child:nth-last-child(5):last-child, .button-group.expanded .button:first-child:nth-last-child(5):first-child:nth-last-child(5) ~ .button:last-child { + margin-right: -6px; } + .button-group.expanded .button:first-child:nth-last-child(6), .button-group.expanded .button:first-child:nth-last-child(6):first-child:nth-last-child(6) ~ .button { + display: inline-block; + width: calc(16.66667% - 1px); + margin-right: 1px; } + .button-group.expanded .button:first-child:nth-last-child(6):last-child, .button-group.expanded .button:first-child:nth-last-child(6):first-child:nth-last-child(6) ~ .button:last-child { + margin-right: -6px; } + .button-group.primary .button { + background-color: #2199e8; + color: #fefefe; } + .button-group.primary .button:hover, .button-group.primary .button:focus { + background-color: #147cc0; + color: #fefefe; } + .button-group.secondary .button { + background-color: #777; + color: #fefefe; } + .button-group.secondary .button:hover, .button-group.secondary .button:focus { + background-color: #5f5f5f; + color: #fefefe; } + .button-group.success .button { + background-color: #3adb76; + color: #fefefe; } + .button-group.success .button:hover, .button-group.success .button:focus { + background-color: #22bb5b; + color: #fefefe; } + .button-group.warning .button { + background-color: #ffae00; + color: #fefefe; } + .button-group.warning .button:hover, .button-group.warning .button:focus { + background-color: #cc8b00; + color: #fefefe; } + .button-group.alert .button { + background-color: #ec5840; + color: #fefefe; } + .button-group.alert .button:hover, .button-group.alert .button:focus { + background-color: #da3116; + color: #fefefe; } + .button-group.stacked .button, .button-group.stacked-for-small .button, .button-group.stacked-for-medium .button { + width: 100%; } + .button-group.stacked .button:last-child, .button-group.stacked-for-small .button:last-child, .button-group.stacked-for-medium .button:last-child { + margin-bottom: 0; } + @media screen and (min-width: 40em) { + .button-group.stacked-for-small .button { + width: auto; + margin-bottom: 0; } } + @media screen and (min-width: 64em) { + .button-group.stacked-for-medium .button { + width: auto; + margin-bottom: 0; } } + @media screen and (max-width: 39.9375em) { + .button-group.stacked-for-small.expanded { + display: block; } + .button-group.stacked-for-small.expanded .button { + display: block; + margin-right: 0; } } + +.callout { + margin: 0 0 1rem 0; + padding: 1rem; + border: 1px solid rgba(10, 10, 10, 0.25); + border-radius: 0; + position: relative; + color: #0a0a0a; + background-color: white; } + .callout > :first-child { + margin-top: 0; } + .callout > :last-child { + margin-bottom: 0; } + .callout.primary { + background-color: #def0fc; } + .callout.secondary { + background-color: #ebebeb; } + .callout.success { + background-color: #e1faea; } + .callout.warning { + background-color: #fff3d9; } + .callout.alert { + background-color: #fce6e2; } + .callout.small { + padding-top: 0.5rem; + padding-right: 0.5rem; + padding-bottom: 0.5rem; + padding-left: 0.5rem; } + .callout.large { + padding-top: 3rem; + padding-right: 3rem; + padding-bottom: 3rem; + padding-left: 3rem; } + +.close-button { + position: absolute; + color: #8a8a8a; + right: 1rem; + top: 0.5rem; + font-size: 2em; + line-height: 1; + cursor: pointer; } + [data-whatinput='mouse'] .close-button { + outline: 0; } + .close-button:hover, .close-button:focus { + color: #0a0a0a; } + +.menu { + margin: 0; + list-style-type: none; } + .menu > li { + display: table-cell; + vertical-align: middle; } + [data-whatinput='mouse'] .menu > li { + outline: 0; } + .menu > li > a { + display: block; + padding: 0.7rem 1rem; + line-height: 1; } + .menu input, + .menu a, + .menu button { + margin-bottom: 0; } + .menu > li > a img, + .menu > li > a i, + .menu > li > a svg { + vertical-align: middle; } + .menu > li > a img + span, + .menu > li > a i + span, + .menu > li > a svg + span { + vertical-align: middle; } + .menu > li > a img, + .menu > li > a i, + .menu > li > a svg { + margin-right: 0.25rem; + display: inline-block; } + .menu > li { + display: table-cell; } + .menu.vertical > li { + display: block; } + @media screen and (min-width: 40em) { + .menu.medium-horizontal > li { + display: table-cell; } + .menu.medium-vertical > li { + display: block; } } + @media screen and (min-width: 64em) { + .menu.large-horizontal > li { + display: table-cell; } + .menu.large-vertical > li { + display: block; } } + .menu.simple li { + line-height: 1; + display: inline-block; + margin-right: 1rem; } + .menu.simple a { + padding: 0; } + .menu.align-right::before, .menu.align-right::after { + content: ' '; + display: table; } + .menu.align-right::after { + clear: both; } + .menu.align-right > li { + float: right; } + .menu.expanded { + width: 100%; + display: table; + table-layout: fixed; } + .menu.expanded > li:first-child:last-child { + width: 100%; } + .menu.icon-top > li > a { + text-align: center; } + .menu.icon-top > li > a img, + .menu.icon-top > li > a i, + .menu.icon-top > li > a svg { + display: block; + margin: 0 auto 0.25rem; } + .menu.nested { + margin-left: 1rem; } + .menu .active > a { + color: #fefefe; + background: #2199e8; } + +.menu-text { + font-weight: bold; + color: inherit; + line-height: 1; + padding-top: 0; + padding-bottom: 0; + padding: 0.7rem 1rem; } + +.menu-centered { + text-align: center; } + .menu-centered > .menu { + display: inline-block; } + +.no-js [data-responsive-menu] ul { + display: none; } + +.menu-icon { + position: relative; + display: inline-block; + vertical-align: middle; + cursor: pointer; + width: 20px; + height: 16px; } + .menu-icon::after { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 2px; + background: #fefefe; + top: 0; + left: 0; + box-shadow: 0 7px 0 #fefefe, 0 14px 0 #fefefe; } + .menu-icon:hover::after { + background: #cacaca; + box-shadow: 0 7px 0 #cacaca, 0 14px 0 #cacaca; } + +.menu-icon.dark { + position: relative; + display: inline-block; + vertical-align: middle; + cursor: pointer; + width: 20px; + height: 16px; } + .menu-icon.dark::after { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 2px; + background: #0a0a0a; + top: 0; + left: 0; + box-shadow: 0 7px 0 #0a0a0a, 0 14px 0 #0a0a0a; } + .menu-icon.dark:hover::after { + background: #8a8a8a; + box-shadow: 0 7px 0 #8a8a8a, 0 14px 0 #8a8a8a; } + +.is-drilldown { + position: relative; + overflow: hidden; } + .is-drilldown li { + display: block !important; } + +.is-drilldown-submenu { + position: absolute; + top: 0; + left: 100%; + z-index: -1; + height: 100%; + width: 100%; + background: #fefefe; + transition: -webkit-transform 0.15s linear; + transition: transform 0.15s linear; } + .is-drilldown-submenu.is-active { + z-index: 1; + display: block; + -webkit-transform: translateX(-100%); + -ms-transform: translateX(-100%); + transform: translateX(-100%); } + .is-drilldown-submenu.is-closing { + -webkit-transform: translateX(100%); + -ms-transform: translateX(100%); + transform: translateX(100%); } + +.is-drilldown-submenu-parent > a { + position: relative; } + .is-drilldown-submenu-parent > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 6px; + border-color: transparent transparent transparent #2199e8; + border-left-style: solid; + border-right-width: 0; + position: absolute; + top: 50%; + margin-top: -6px; + right: 1rem; } + +.js-drilldown-back > a::before { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 6px; + border-color: transparent #2199e8 transparent transparent; + border-right-style: solid; + border-left-width: 0; + border-left-width: 0; + display: inline-block; + vertical-align: middle; + margin-right: 0.75rem; } + +.dropdown-pane { + background-color: #fefefe; + border: 1px solid #cacaca; + border-radius: 0; + display: block; + font-size: 1rem; + padding: 1rem; + position: absolute; + visibility: hidden; + width: 300px; + z-index: 10; } + .dropdown-pane.is-open { + visibility: visible; } + +.dropdown-pane.tiny { + width: 100px; } + +.dropdown-pane.small { + width: 200px; } + +.dropdown-pane.large { + width: 400px; } + +.dropdown.menu > li.opens-left > .is-dropdown-submenu { + left: auto; + right: 0; + top: 100%; } + +.dropdown.menu > li.opens-right > .is-dropdown-submenu { + right: auto; + left: 0; + top: 100%; } + +.dropdown.menu > li.is-dropdown-submenu-parent > a { + padding-right: 1.5rem; + position: relative; } + +.dropdown.menu > li.is-dropdown-submenu-parent > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: #2199e8 transparent transparent; + border-top-style: solid; + border-bottom-width: 0; + right: 5px; + margin-top: -2px; } + +[data-whatinput='mouse'] .dropdown.menu a { + outline: 0; } + +.no-js .dropdown.menu ul { + display: none; } + +.dropdown.menu.vertical > li .is-dropdown-submenu { + top: 0; } + +.dropdown.menu.vertical > li.opens-left > .is-dropdown-submenu { + left: auto; + right: 100%; } + +.dropdown.menu.vertical > li.opens-right > .is-dropdown-submenu { + right: auto; + left: 100%; } + +.dropdown.menu.vertical > li > a::after { + right: 14px; + margin-top: -3px; } + +.dropdown.menu.vertical > li.opens-left > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: transparent #2199e8 transparent transparent; + border-right-style: solid; + border-left-width: 0; } + +.dropdown.menu.vertical > li.opens-right > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: transparent transparent transparent #2199e8; + border-left-style: solid; + border-right-width: 0; } + +@media screen and (min-width: 40em) { + .dropdown.menu.medium-horizontal > li.opens-left > .is-dropdown-submenu { + left: auto; + right: 0; + top: 100%; } + .dropdown.menu.medium-horizontal > li.opens-right > .is-dropdown-submenu { + right: auto; + left: 0; + top: 100%; } + .dropdown.menu.medium-horizontal > li.is-dropdown-submenu-parent > a { + padding-right: 1.5rem; + position: relative; } + .dropdown.menu.medium-horizontal > li.is-dropdown-submenu-parent > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: #2199e8 transparent transparent; + border-top-style: solid; + border-bottom-width: 0; + right: 5px; + margin-top: -2px; } + .dropdown.menu.medium-vertical > li .is-dropdown-submenu { + top: 0; } + .dropdown.menu.medium-vertical > li.opens-left > .is-dropdown-submenu { + left: auto; + right: 100%; } + .dropdown.menu.medium-vertical > li.opens-right > .is-dropdown-submenu { + right: auto; + left: 100%; } + .dropdown.menu.medium-vertical > li > a::after { + right: 14px; + margin-top: -3px; } + .dropdown.menu.medium-vertical > li.opens-left > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: transparent #2199e8 transparent transparent; + border-right-style: solid; + border-left-width: 0; } + .dropdown.menu.medium-vertical > li.opens-right > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: transparent transparent transparent #2199e8; + border-left-style: solid; + border-right-width: 0; } } + +@media screen and (min-width: 64em) { + .dropdown.menu.large-horizontal > li.opens-left > .is-dropdown-submenu { + left: auto; + right: 0; + top: 100%; } + .dropdown.menu.large-horizontal > li.opens-right > .is-dropdown-submenu { + right: auto; + left: 0; + top: 100%; } + .dropdown.menu.large-horizontal > li.is-dropdown-submenu-parent > a { + padding-right: 1.5rem; + position: relative; } + .dropdown.menu.large-horizontal > li.is-dropdown-submenu-parent > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: #2199e8 transparent transparent; + border-top-style: solid; + border-bottom-width: 0; + right: 5px; + margin-top: -2px; } + .dropdown.menu.large-vertical > li .is-dropdown-submenu { + top: 0; } + .dropdown.menu.large-vertical > li.opens-left > .is-dropdown-submenu { + left: auto; + right: 100%; } + .dropdown.menu.large-vertical > li.opens-right > .is-dropdown-submenu { + right: auto; + left: 100%; } + .dropdown.menu.large-vertical > li > a::after { + right: 14px; + margin-top: -3px; } + .dropdown.menu.large-vertical > li.opens-left > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: transparent #2199e8 transparent transparent; + border-right-style: solid; + border-left-width: 0; } + .dropdown.menu.large-vertical > li.opens-right > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: transparent transparent transparent #2199e8; + border-left-style: solid; + border-right-width: 0; } } + +.dropdown.menu.align-right .is-dropdown-submenu.first-sub { + top: 100%; + left: auto; + right: 0; } + +.is-dropdown-menu.vertical { + width: 100px; } + .is-dropdown-menu.vertical.align-right { + float: right; } + +.is-dropdown-submenu-parent { + position: relative; } + .is-dropdown-submenu-parent a::after { + position: absolute; + top: 50%; + right: 5px; + margin-top: -2px; } + .is-dropdown-submenu-parent.opens-inner > .is-dropdown-submenu { + top: 100%; + left: auto; } + .is-dropdown-submenu-parent.opens-left > .is-dropdown-submenu { + left: auto; + right: 100%; } + .is-dropdown-submenu-parent.opens-right > .is-dropdown-submenu { + right: auto; + left: 100%; } + +.is-dropdown-submenu { + display: none; + position: absolute; + top: 0; + left: 100%; + min-width: 200px; + z-index: 1; + background: #fefefe; + border: 1px solid #cacaca; } + .is-dropdown-submenu .is-dropdown-submenu-parent > a::after { + right: 14px; + margin-top: -3px; } + .is-dropdown-submenu .is-dropdown-submenu-parent.opens-left > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: transparent #2199e8 transparent transparent; + border-right-style: solid; + border-left-width: 0; } + .is-dropdown-submenu .is-dropdown-submenu-parent.opens-right > a::after { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 5px; + border-color: transparent transparent transparent #2199e8; + border-left-style: solid; + border-right-width: 0; } + .is-dropdown-submenu .is-dropdown-submenu { + margin-top: -1px; } + .is-dropdown-submenu > li { + width: 100%; } + .is-dropdown-submenu.js-dropdown-active { + display: block; } + +.flex-video { + position: relative; + height: 0; + padding-bottom: 75%; + margin-bottom: 1rem; + overflow: hidden; } + .flex-video iframe, + .flex-video object, + .flex-video embed, + .flex-video video { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; } + .flex-video.widescreen { + padding-bottom: 56.25%; } + .flex-video.vimeo { + padding-top: 0; } + +.label { + display: inline-block; + padding: 0.33333rem 0.5rem; + font-size: 0.8rem; + line-height: 1; + white-space: nowrap; + cursor: default; + border-radius: 0; + background: #2199e8; + color: #fefefe; } + .label.secondary { + background: #777; + color: #fefefe; } + .label.success { + background: #3adb76; + color: #fefefe; } + .label.warning { + background: #ffae00; + color: #fefefe; } + .label.alert { + background: #ec5840; + color: #fefefe; } + +.media-object { + margin-bottom: 1rem; + display: block; } + .media-object img { + max-width: none; } + @media screen and (max-width: 39.9375em) { + .media-object.stack-for-small .media-object-section { + padding: 0; + padding-bottom: 1rem; + display: block; } + .media-object.stack-for-small .media-object-section img { + width: 100%; } } + +.media-object-section { + display: table-cell; + vertical-align: top; } + .media-object-section:first-child { + padding-right: 1rem; } + .media-object-section:last-child:not(:nth-child(2)) { + padding-left: 1rem; } + .media-object-section > :last-child { + margin-bottom: 0; } + .media-object-section.middle { + vertical-align: middle; } + .media-object-section.bottom { + vertical-align: bottom; } + +html, +body { + height: 100%; } + +.off-canvas-wrapper { + width: 100%; + overflow-x: hidden; + position: relative; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-overflow-scrolling: auto; } + +.off-canvas-wrapper-inner { + position: relative; + width: 100%; + transition: -webkit-transform 0.5s ease; + transition: transform 0.5s ease; } + .off-canvas-wrapper-inner::before, .off-canvas-wrapper-inner::after { + content: ' '; + display: table; } + .off-canvas-wrapper-inner::after { + clear: both; } + +.off-canvas-content, +.off-canvas-content { + min-height: 100%; + background: #fefefe; + transition: -webkit-transform 0.5s ease; + transition: transform 0.5s ease; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + z-index: 1; + padding-bottom: 0.1px; + box-shadow: 0 0 10px rgba(10, 10, 10, 0.5); } + +.js-off-canvas-exit { + display: none; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(254, 254, 254, 0.25); + cursor: pointer; + transition: background 0.5s ease; } + +.off-canvas { + position: absolute; + background: #e6e6e6; + z-index: -1; + max-height: 100%; + overflow-y: auto; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); } + [data-whatinput='mouse'] .off-canvas { + outline: 0; } + .off-canvas.position-left { + left: -250px; + top: 0; + width: 250px; } + .is-open-left { + -webkit-transform: translateX(250px); + -ms-transform: translateX(250px); + transform: translateX(250px); } + .off-canvas.position-right { + right: -250px; + top: 0; + width: 250px; } + .is-open-right { + -webkit-transform: translateX(-250px); + -ms-transform: translateX(-250px); + transform: translateX(-250px); } + +@media screen and (min-width: 40em) { + .position-left.reveal-for-medium { + left: 0; + z-index: auto; + position: fixed; } + .position-left.reveal-for-medium ~ .off-canvas-content { + margin-left: 250px; } + .position-right.reveal-for-medium { + right: 0; + z-index: auto; + position: fixed; } + .position-right.reveal-for-medium ~ .off-canvas-content { + margin-right: 250px; } } + +@media screen and (min-width: 64em) { + .position-left.reveal-for-large { + left: 0; + z-index: auto; + position: fixed; } + .position-left.reveal-for-large ~ .off-canvas-content { + margin-left: 250px; } + .position-right.reveal-for-large { + right: 0; + z-index: auto; + position: fixed; } + .position-right.reveal-for-large ~ .off-canvas-content { + margin-right: 250px; } } + +.orbit { + position: relative; } + +.orbit-container { + position: relative; + margin: 0; + overflow: hidden; + list-style: none; } + +.orbit-slide { + width: 100%; + max-height: 100%; } + .orbit-slide.no-motionui.is-active { + top: 0; + left: 0; } + +.orbit-figure { + margin: 0; } + +.orbit-image { + margin: 0; + width: 100%; + max-width: 100%; } + +.orbit-caption { + position: absolute; + bottom: 0; + width: 100%; + padding: 1rem; + margin-bottom: 0; + color: #fefefe; + background-color: rgba(10, 10, 10, 0.5); } + +.orbit-previous, .orbit-next { + position: absolute; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); + z-index: 10; + padding: 1rem; + color: #fefefe; } + [data-whatinput='mouse'] .orbit-previous, [data-whatinput='mouse'] .orbit-next { + outline: 0; } + .orbit-previous:hover, .orbit-next:hover, .orbit-previous:active, .orbit-next:active, .orbit-previous:focus, .orbit-next:focus { + background-color: rgba(10, 10, 10, 0.5); } + +.orbit-previous { + left: 0; } + +.orbit-next { + left: auto; + right: 0; } + +.orbit-bullets { + position: relative; + margin-top: 0.8rem; + margin-bottom: 0.8rem; + text-align: center; } + [data-whatinput='mouse'] .orbit-bullets { + outline: 0; } + .orbit-bullets button { + width: 1.2rem; + height: 1.2rem; + margin: 0.1rem; + background-color: #cacaca; + border-radius: 50%; } + .orbit-bullets button:hover { + background-color: #8a8a8a; } + .orbit-bullets button.is-active { + background-color: #8a8a8a; } + +.pagination { + margin-left: 0; + margin-bottom: 1rem; } + .pagination::before, .pagination::after { + content: ' '; + display: table; } + .pagination::after { + clear: both; } + .pagination li { + font-size: 0.875rem; + margin-right: 0.0625rem; + border-radius: 0; + display: none; } + .pagination li:last-child, .pagination li:first-child { + display: inline-block; } + @media screen and (min-width: 40em) { + .pagination li { + display: inline-block; } } + .pagination a, + .pagination button { + color: #0a0a0a; + display: block; + padding: 0.1875rem 0.625rem; + border-radius: 0; } + .pagination a:hover, + .pagination button:hover { + background: #e6e6e6; } + .pagination .current { + padding: 0.1875rem 0.625rem; + background: #2199e8; + color: #fefefe; + cursor: default; } + .pagination .disabled { + padding: 0.1875rem 0.625rem; + color: #cacaca; + cursor: not-allowed; } + .pagination .disabled:hover { + background: transparent; } + .pagination .ellipsis::after { + content: '\2026'; + padding: 0.1875rem 0.625rem; + color: #0a0a0a; } + +.pagination-previous a::before, +.pagination-previous.disabled::before { + content: '\00ab'; + display: inline-block; + margin-right: 0.5rem; } + +.pagination-next a::after, +.pagination-next.disabled::after { + content: '\00bb'; + display: inline-block; + margin-left: 0.5rem; } + +.progress { + background-color: #cacaca; + height: 1rem; + margin-bottom: 1rem; + border-radius: 0; } + .progress.primary .progress-meter { + background-color: #2199e8; } + .progress.secondary .progress-meter { + background-color: #777; } + .progress.success .progress-meter { + background-color: #3adb76; } + .progress.warning .progress-meter { + background-color: #ffae00; } + .progress.alert .progress-meter { + background-color: #ec5840; } + +.progress-meter { + position: relative; + display: block; + width: 0%; + height: 100%; + background-color: #2199e8; } + +.progress-meter-text { + position: absolute; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + position: absolute; + margin: 0; + font-size: 0.75rem; + font-weight: bold; + color: #fefefe; + white-space: nowrap; } + +body.is-reveal-open { + overflow: hidden; } + +html.is-reveal-open, +html.is-reveal-open body { + height: 100%; + overflow: hidden; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + +.reveal-overlay { + display: none; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 1005; + background-color: rgba(10, 10, 10, 0.45); + overflow-y: scroll; } + +.reveal { + display: none; + z-index: 1006; + padding: 1rem; + border: 1px solid #cacaca; + background-color: #fefefe; + border-radius: 0; + position: relative; + top: 100px; + margin-left: auto; + margin-right: auto; + overflow-y: auto; } + [data-whatinput='mouse'] .reveal { + outline: 0; } + @media screen and (min-width: 40em) { + .reveal { + min-height: 0; } } + .reveal .column, .reveal .columns, + .reveal .columns { + min-width: 0; } + .reveal > :last-child { + margin-bottom: 0; } + @media screen and (min-width: 40em) { + .reveal { + width: 600px; + max-width: 75rem; } } + @media screen and (min-width: 40em) { + .reveal .reveal { + left: auto; + right: auto; + margin: 0 auto; } } + .reveal.collapse { + padding: 0; } + @media screen and (min-width: 40em) { + .reveal.tiny { + width: 30%; + max-width: 75rem; } } + @media screen and (min-width: 40em) { + .reveal.small { + width: 50%; + max-width: 75rem; } } + @media screen and (min-width: 40em) { + .reveal.large { + width: 90%; + max-width: 75rem; } } + .reveal.full { + top: 0; + left: 0; + width: 100%; + height: 100%; + height: 100vh; + min-height: 100vh; + max-width: none; + margin-left: 0; + border: 0; + border-radius: 0; } + @media screen and (max-width: 39.9375em) { + .reveal { + top: 0; + left: 0; + width: 100%; + height: 100%; + height: 100vh; + min-height: 100vh; + max-width: none; + margin-left: 0; + border: 0; + border-radius: 0; } } + .reveal.without-overlay { + position: fixed; } + +.slider { + position: relative; + height: 0.5rem; + margin-top: 1.25rem; + margin-bottom: 2.25rem; + background-color: #e6e6e6; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -ms-touch-action: none; + touch-action: none; } + +.slider-fill { + position: absolute; + top: 0; + left: 0; + display: inline-block; + max-width: 100%; + height: 0.5rem; + background-color: #cacaca; + transition: all 0.2s ease-in-out; } + .slider-fill.is-dragging { + transition: all 0s linear; } + +.slider-handle { + position: absolute; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); + position: absolute; + left: 0; + z-index: 1; + display: inline-block; + width: 1.4rem; + height: 1.4rem; + background-color: #2199e8; + transition: all 0.2s ease-in-out; + -ms-touch-action: manipulation; + touch-action: manipulation; + border-radius: 0; } + [data-whatinput='mouse'] .slider-handle { + outline: 0; } + .slider-handle:hover { + background-color: #1583cc; } + .slider-handle.is-dragging { + transition: all 0s linear; } + +.slider.disabled, +.slider[disabled] { + opacity: 0.25; + cursor: not-allowed; } + +.slider.vertical { + display: inline-block; + width: 0.5rem; + height: 12.5rem; + margin: 0 1.25rem; + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); } + .slider.vertical .slider-fill { + top: 0; + width: 0.5rem; + max-height: 100%; } + .slider.vertical .slider-handle { + position: absolute; + top: 0; + left: 50%; + width: 1.4rem; + height: 1.4rem; + -webkit-transform: translateX(-50%); + -ms-transform: translateX(-50%); + transform: translateX(-50%); } + +.sticky-container { + position: relative; } + +.sticky { + position: absolute; + z-index: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); } + +.sticky.is-stuck { + position: fixed; + z-index: 5; } + .sticky.is-stuck.is-at-top { + top: 0; } + .sticky.is-stuck.is-at-bottom { + bottom: 0; } + +.sticky.is-anchored { + position: absolute; + left: auto; + right: auto; } + .sticky.is-anchored.is-at-bottom { + bottom: 0; } + +.switch { + margin-bottom: 1rem; + outline: 0; + position: relative; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + color: #fefefe; + font-weight: bold; + font-size: 0.875rem; } + +.switch-input { + opacity: 0; + position: absolute; } + +.switch-paddle { + background: #cacaca; + cursor: pointer; + display: block; + position: relative; + width: 4rem; + height: 2rem; + transition: all 0.25s ease-out; + border-radius: 0; + color: inherit; + font-weight: inherit; } + input + .switch-paddle { + margin: 0; } + .switch-paddle::after { + background: #fefefe; + content: ''; + display: block; + position: absolute; + height: 1.5rem; + left: 0.25rem; + top: 0.25rem; + width: 1.5rem; + transition: all 0.25s ease-out; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + border-radius: 0; } + input:checked ~ .switch-paddle { + background: #2199e8; } + input:checked ~ .switch-paddle::after { + left: 2.25rem; } + [data-whatinput='mouse'] input:focus ~ .switch-paddle { + outline: 0; } + +.switch-active, .switch-inactive { + position: absolute; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); } + +.switch-active { + left: 8%; + display: none; } + input:checked + label > .switch-active { + display: block; } + +.switch-inactive { + right: 15%; } + input:checked + label > .switch-inactive { + display: none; } + +.switch.tiny .switch-paddle { + width: 3rem; + height: 1.5rem; + font-size: 0.625rem; } + +.switch.tiny .switch-paddle::after { + width: 1rem; + height: 1rem; } + +.switch.tiny input:checked ~ .switch-paddle::after { + left: 1.75rem; } + +.switch.small .switch-paddle { + width: 3.5rem; + height: 1.75rem; + font-size: 0.75rem; } + +.switch.small .switch-paddle::after { + width: 1.25rem; + height: 1.25rem; } + +.switch.small input:checked ~ .switch-paddle::after { + left: 2rem; } + +.switch.large .switch-paddle { + width: 5rem; + height: 2.5rem; + font-size: 1rem; } + +.switch.large .switch-paddle::after { + width: 2rem; + height: 2rem; } + +.switch.large input:checked ~ .switch-paddle::after { + left: 2.75rem; } + +table { + width: 100%; + margin-bottom: 1rem; + border-radius: 0; } + table thead, + table tbody, + table tfoot { + border: 1px solid #f1f1f1; + background-color: #fefefe; } + table caption { + font-weight: bold; + padding: 0.5rem 0.625rem 0.625rem; } + table thead, + table tfoot { + background: #f8f8f8; + color: #0a0a0a; } + table thead tr, + table tfoot tr { + background: transparent; } + table thead th, + table thead td, + table tfoot th, + table tfoot td { + padding: 0.5rem 0.625rem 0.625rem; + font-weight: bold; + text-align: left; } + table tbody tr:nth-child(even) { + background-color: #f1f1f1; } + table tbody th, + table tbody td { + padding: 0.5rem 0.625rem 0.625rem; } + +@media screen and (max-width: 63.9375em) { + table.stack thead { + display: none; } + table.stack tfoot { + display: none; } + table.stack tr, + table.stack th, + table.stack td { + display: block; } + table.stack td { + border-top: 0; } } + +table.scroll { + display: block; + width: 100%; + overflow-x: auto; } + +table.hover tr:hover { + background-color: #f9f9f9; } + +table.hover tr:nth-of-type(even):hover { + background-color: #ececec; } + +.table-scroll { + overflow-x: auto; } + .table-scroll table { + width: auto; } + +.tabs { + margin: 0; + list-style-type: none; + background: #fefefe; + border: 1px solid #e6e6e6; } + .tabs::before, .tabs::after { + content: ' '; + display: table; } + .tabs::after { + clear: both; } + +.tabs.vertical > li { + width: auto; + float: none; + display: block; } + +.tabs.simple > li > a { + padding: 0; } + .tabs.simple > li > a:hover { + background: transparent; } + +.tabs.primary { + background: #2199e8; } + .tabs.primary > li > a { + color: #fefefe; } + .tabs.primary > li > a:hover, .tabs.primary > li > a:focus { + background: #1893e4; } + +.tabs-title { + float: left; } + .tabs-title > a { + display: block; + padding: 1.25rem 1.5rem; + line-height: 1; + font-size: 0.75rem; } + .tabs-title > a:hover { + background: #fefefe; } + .tabs-title > a:focus, .tabs-title > a[aria-selected='true'] { + background: #e6e6e6; } + +.tabs-content { + background: #fefefe; + transition: all 0.5s ease; + border: 1px solid #e6e6e6; + border-top: 0; } + +.tabs-content.vertical { + border: 1px solid #e6e6e6; + border-left: 0; } + +.tabs-panel { + display: none; + padding: 1rem; } + .tabs-panel.is-active { + display: block; } + +.thumbnail { + border: solid 4px #fefefe; + box-shadow: 0 0 0 1px rgba(10, 10, 10, 0.2); + display: inline-block; + line-height: 0; + max-width: 100%; + transition: box-shadow 200ms ease-out; + border-radius: 0; + margin-bottom: 1rem; } + .thumbnail:hover, .thumbnail:focus { + box-shadow: 0 0 6px 1px rgba(33, 153, 232, 0.5); } + +.title-bar { + background: #0a0a0a; + color: #fefefe; + padding: 0.5rem; } + .title-bar::before, .title-bar::after { + content: ' '; + display: table; } + .title-bar::after { + clear: both; } + .title-bar .menu-icon { + margin-left: 0.25rem; + margin-right: 0.25rem; } + +.title-bar-left { + float: left; } + +.title-bar-right { + float: right; + text-align: right; } + +.title-bar-title { + font-weight: bold; + vertical-align: middle; + display: inline-block; } + +.menu-icon.dark { + position: relative; + display: inline-block; + vertical-align: middle; + cursor: pointer; + width: 20px; + height: 16px; } + .menu-icon.dark::after { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 2px; + background: #0a0a0a; + top: 0; + left: 0; + box-shadow: 0 7px 0 #0a0a0a, 0 14px 0 #0a0a0a; } + .menu-icon.dark:hover::after { + background: #8a8a8a; + box-shadow: 0 7px 0 #8a8a8a, 0 14px 0 #8a8a8a; } + +.has-tip { + border-bottom: dotted 1px #8a8a8a; + font-weight: bold; + position: relative; + display: inline-block; + cursor: help; } + +.tooltip { + background-color: #0a0a0a; + color: #fefefe; + font-size: 80%; + padding: 0.75rem; + position: absolute; + z-index: 10; + top: calc(100% + 0.6495rem); + max-width: 10rem !important; + border-radius: 0; } + .tooltip::before { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 0.75rem; + border-color: transparent transparent #0a0a0a; + border-bottom-style: solid; + border-top-width: 0; + bottom: 100%; + position: absolute; + left: 50%; + -webkit-transform: translateX(-50%); + -ms-transform: translateX(-50%); + transform: translateX(-50%); } + .tooltip.top::before { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 0.75rem; + border-color: #0a0a0a transparent transparent; + border-top-style: solid; + border-bottom-width: 0; + top: 100%; + bottom: auto; } + .tooltip.left::before { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 0.75rem; + border-color: transparent transparent transparent #0a0a0a; + border-left-style: solid; + border-right-width: 0; + bottom: auto; + left: 100%; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); } + .tooltip.right::before { + content: ''; + display: block; + width: 0; + height: 0; + border: inset 0.75rem; + border-color: transparent #0a0a0a transparent transparent; + border-right-style: solid; + border-left-width: 0; + bottom: auto; + left: auto; + right: 100%; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); } + +.top-bar { + padding: 0.5rem; } + .top-bar::before, .top-bar::after { + content: ' '; + display: table; } + .top-bar::after { + clear: both; } + .top-bar, + .top-bar ul { + background-color: #e6e6e6; } + .top-bar input { + max-width: 200px; + margin-right: 1rem; } + .top-bar .input-group-field { + width: 100%; + margin-right: 0; } + .top-bar input.button { + width: auto; } + .top-bar .top-bar-left, + .top-bar .top-bar-right { + width: 100%; } + @media screen and (min-width: 40em) { + .top-bar .top-bar-left, + .top-bar .top-bar-right { + width: auto; } } + @media screen and (max-width: 63.9375em) { + .top-bar.stacked-for-medium .top-bar-left, + .top-bar.stacked-for-medium .top-bar-right { + width: 100%; } } + @media screen and (max-width: 74.9375em) { + .top-bar.stacked-for-large .top-bar-left, + .top-bar.stacked-for-large .top-bar-right { + width: 100%; } } + +.top-bar-title { + float: left; + margin-right: 1rem; } + +.top-bar-left { + float: left; } + +.top-bar-right { + float: right; } + +.hide { + display: none !important; } + +.invisible { + visibility: hidden; } + +@media screen and (max-width: 39.9375em) { + .hide-for-small-only { + display: none !important; } } + +@media screen and (max-width: 0em), screen and (min-width: 40em) { + .show-for-small-only { + display: none !important; } } + +@media screen and (min-width: 40em) { + .hide-for-medium { + display: none !important; } } + +@media screen and (max-width: 39.9375em) { + .show-for-medium { + display: none !important; } } + +@media screen and (min-width: 40em) and (max-width: 63.9375em) { + .hide-for-medium-only { + display: none !important; } } + +@media screen and (max-width: 39.9375em), screen and (min-width: 64em) { + .show-for-medium-only { + display: none !important; } } + +@media screen and (min-width: 64em) { + .hide-for-large { + display: none !important; } } + +@media screen and (max-width: 63.9375em) { + .show-for-large { + display: none !important; } } + +@media screen and (min-width: 64em) and (max-width: 74.9375em) { + .hide-for-large-only { + display: none !important; } } + +@media screen and (max-width: 63.9375em), screen and (min-width: 75em) { + .show-for-large-only { + display: none !important; } } + +.show-for-sr, +.show-on-focus { + position: absolute !important; + width: 1px; + height: 1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); } + +.show-on-focus:active, .show-on-focus:focus { + position: static !important; + height: auto; + width: auto; + overflow: visible; + clip: auto; } + +.show-for-landscape, +.hide-for-portrait { + display: block !important; } + @media screen and (orientation: landscape) { + .show-for-landscape, + .hide-for-portrait { + display: block !important; } } + @media screen and (orientation: portrait) { + .show-for-landscape, + .hide-for-portrait { + display: none !important; } } + +.hide-for-landscape, +.show-for-portrait { + display: none !important; } + @media screen and (orientation: landscape) { + .hide-for-landscape, + .show-for-portrait { + display: none !important; } } + @media screen and (orientation: portrait) { + .hide-for-landscape, + .show-for-portrait { + display: block !important; } } + +.float-left { + float: left !important; } + +.float-right { + float: right !important; } + +.float-center { + display: block; + margin-left: auto; + margin-right: auto; } + +.clearfix::before, .clearfix::after { + content: ' '; + display: table; } + +.clearfix::after { + clear: both; } + +.slide-in-down.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: translateY(-100%); + -ms-transform: translateY(-100%); + transform: translateY(-100%); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.slide-in-down.mui-enter.mui-enter-active { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); } + +.slide-in-left.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: translateX(-100%); + -ms-transform: translateX(-100%); + transform: translateX(-100%); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.slide-in-left.mui-enter.mui-enter-active { + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); } + +.slide-in-up.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: translateY(100%); + -ms-transform: translateY(100%); + transform: translateY(100%); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.slide-in-up.mui-enter.mui-enter-active { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); } + +.slide-in-right.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: translateX(100%); + -ms-transform: translateX(100%); + transform: translateX(100%); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.slide-in-right.mui-enter.mui-enter-active { + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); } + +.slide-out-down.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.slide-out-down.mui-leave.mui-leave-active { + -webkit-transform: translateY(100%); + -ms-transform: translateY(100%); + transform: translateY(100%); } + +.slide-out-right.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.slide-out-right.mui-leave.mui-leave-active { + -webkit-transform: translateX(100%); + -ms-transform: translateX(100%); + transform: translateX(100%); } + +.slide-out-up.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.slide-out-up.mui-leave.mui-leave-active { + -webkit-transform: translateY(-100%); + -ms-transform: translateY(-100%); + transform: translateY(-100%); } + +.slide-out-left.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.slide-out-left.mui-leave.mui-leave-active { + -webkit-transform: translateX(-100%); + -ms-transform: translateX(-100%); + transform: translateX(-100%); } + +.fade-in.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + opacity: 0; + transition-property: opacity; } + +.fade-in.mui-enter.mui-enter-active { + opacity: 1; } + +.fade-out.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + opacity: 1; + transition-property: opacity; } + +.fade-out.mui-leave.mui-leave-active { + opacity: 0; } + +.hinge-in-from-top.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotateX(-90deg); + transform: perspective(2000px) rotateX(-90deg); + -webkit-transform-origin: top; + -ms-transform-origin: top; + transform-origin: top; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 0; } + +.hinge-in-from-top.mui-enter.mui-enter-active { + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + opacity: 1; } + +.hinge-in-from-right.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotateY(-90deg); + transform: perspective(2000px) rotateY(-90deg); + -webkit-transform-origin: right; + -ms-transform-origin: right; + transform-origin: right; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 0; } + +.hinge-in-from-right.mui-enter.mui-enter-active { + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + opacity: 1; } + +.hinge-in-from-bottom.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotateX(90deg); + transform: perspective(2000px) rotateX(90deg); + -webkit-transform-origin: bottom; + -ms-transform-origin: bottom; + transform-origin: bottom; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 0; } + +.hinge-in-from-bottom.mui-enter.mui-enter-active { + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + opacity: 1; } + +.hinge-in-from-left.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotateY(90deg); + transform: perspective(2000px) rotateY(90deg); + -webkit-transform-origin: left; + -ms-transform-origin: left; + transform-origin: left; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 0; } + +.hinge-in-from-left.mui-enter.mui-enter-active { + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + opacity: 1; } + +.hinge-in-from-middle-x.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotateX(-90deg); + transform: perspective(2000px) rotateX(-90deg); + -webkit-transform-origin: center; + -ms-transform-origin: center; + transform-origin: center; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 0; } + +.hinge-in-from-middle-x.mui-enter.mui-enter-active { + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + opacity: 1; } + +.hinge-in-from-middle-y.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotateY(-90deg); + transform: perspective(2000px) rotateY(-90deg); + -webkit-transform-origin: center; + -ms-transform-origin: center; + transform-origin: center; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 0; } + +.hinge-in-from-middle-y.mui-enter.mui-enter-active { + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + opacity: 1; } + +.hinge-out-from-top.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + -webkit-transform-origin: top; + -ms-transform-origin: top; + transform-origin: top; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 1; } + +.hinge-out-from-top.mui-leave.mui-leave-active { + -webkit-transform: perspective(2000px) rotateX(-90deg); + transform: perspective(2000px) rotateX(-90deg); + opacity: 0; } + +.hinge-out-from-right.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + -webkit-transform-origin: right; + -ms-transform-origin: right; + transform-origin: right; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 1; } + +.hinge-out-from-right.mui-leave.mui-leave-active { + -webkit-transform: perspective(2000px) rotateY(-90deg); + transform: perspective(2000px) rotateY(-90deg); + opacity: 0; } + +.hinge-out-from-bottom.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + -webkit-transform-origin: bottom; + -ms-transform-origin: bottom; + transform-origin: bottom; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 1; } + +.hinge-out-from-bottom.mui-leave.mui-leave-active { + -webkit-transform: perspective(2000px) rotateX(90deg); + transform: perspective(2000px) rotateX(90deg); + opacity: 0; } + +.hinge-out-from-left.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + -webkit-transform-origin: left; + -ms-transform-origin: left; + transform-origin: left; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 1; } + +.hinge-out-from-left.mui-leave.mui-leave-active { + -webkit-transform: perspective(2000px) rotateY(90deg); + transform: perspective(2000px) rotateY(90deg); + opacity: 0; } + +.hinge-out-from-middle-x.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + -webkit-transform-origin: center; + -ms-transform-origin: center; + transform-origin: center; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 1; } + +.hinge-out-from-middle-x.mui-leave.mui-leave-active { + -webkit-transform: perspective(2000px) rotateX(-90deg); + transform: perspective(2000px) rotateX(-90deg); + opacity: 0; } + +.hinge-out-from-middle-y.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: perspective(2000px) rotate(0deg); + transform: perspective(2000px) rotate(0deg); + -webkit-transform-origin: center; + -ms-transform-origin: center; + transform-origin: center; + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 1; } + +.hinge-out-from-middle-y.mui-leave.mui-leave-active { + -webkit-transform: perspective(2000px) rotateY(-90deg); + transform: perspective(2000px) rotateY(-90deg); + opacity: 0; } + +.scale-in-up.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: scale(0.5); + -ms-transform: scale(0.5); + transform: scale(0.5); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 0; } + +.scale-in-up.mui-enter.mui-enter-active { + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + opacity: 1; } + +.scale-in-down.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: scale(1.5); + -ms-transform: scale(1.5); + transform: scale(1.5); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 0; } + +.scale-in-down.mui-enter.mui-enter-active { + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + opacity: 1; } + +.scale-out-up.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 1; } + +.scale-out-up.mui-leave.mui-leave-active { + -webkit-transform: scale(1.5); + -ms-transform: scale(1.5); + transform: scale(1.5); + opacity: 0; } + +.scale-out-down.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 1; } + +.scale-out-down.mui-leave.mui-leave-active { + -webkit-transform: scale(0.5); + -ms-transform: scale(0.5); + transform: scale(0.5); + opacity: 0; } + +.spin-in.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: rotate(-0.75turn); + -ms-transform: rotate(-0.75turn); + transform: rotate(-0.75turn); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 0; } + +.spin-in.mui-enter.mui-enter-active { + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; } + +.spin-out.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 1; } + +.spin-out.mui-leave.mui-leave-active { + -webkit-transform: rotate(0.75turn); + -ms-transform: rotate(0.75turn); + transform: rotate(0.75turn); + opacity: 0; } + +.spin-in-ccw.mui-enter { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: rotate(0.75turn); + -ms-transform: rotate(0.75turn); + transform: rotate(0.75turn); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 0; } + +.spin-in-ccw.mui-enter.mui-enter-active { + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; } + +.spin-out-ccw.mui-leave { + transition-duration: 500ms; + transition-timing-function: linear; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + transition-property: -webkit-transform, opacity; + transition-property: transform, opacity; + opacity: 1; } + +.spin-out-ccw.mui-leave.mui-leave-active { + -webkit-transform: rotate(-0.75turn); + -ms-transform: rotate(-0.75turn); + transform: rotate(-0.75turn); + opacity: 0; } + +.slow { + transition-duration: 750ms !important; } + +.fast { + transition-duration: 250ms !important; } + +.linear { + transition-timing-function: linear !important; } + +.ease { + transition-timing-function: ease !important; } + +.ease-in { + transition-timing-function: ease-in !important; } + +.ease-out { + transition-timing-function: ease-out !important; } + +.ease-in-out { + transition-timing-function: ease-in-out !important; } + +.bounce-in { + transition-timing-function: cubic-bezier(0.485, 0.155, 0.24, 1.245) !important; } + +.bounce-out { + transition-timing-function: cubic-bezier(0.485, 0.155, 0.515, 0.845) !important; } + +.bounce-in-out { + transition-timing-function: cubic-bezier(0.76, -0.245, 0.24, 1.245) !important; } + +.short-delay { + transition-delay: 300ms !important; } + +.long-delay { + transition-delay: 700ms !important; } + +.shake { + -webkit-animation-name: shake-7; + animation-name: shake-7; } + +@-webkit-keyframes shake-7 { + 0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90% { + -webkit-transform: translateX(7%); + transform: translateX(7%); } + 5%, 15%, 25%, 35%, 45%, 55%, 65%, 75%, 85%, 95% { + -webkit-transform: translateX(-7%); + transform: translateX(-7%); } } + +@keyframes shake-7 { + 0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90% { + -webkit-transform: translateX(7%); + transform: translateX(7%); } + 5%, 15%, 25%, 35%, 45%, 55%, 65%, 75%, 85%, 95% { + -webkit-transform: translateX(-7%); + transform: translateX(-7%); } } + +.spin-cw { + -webkit-animation-name: spin-cw-1turn; + animation-name: spin-cw-1turn; } + +@-webkit-keyframes spin-cw-1turn { + 0% { + -webkit-transform: rotate(-1turn); + transform: rotate(-1turn); } + 100% { + -webkit-transform: rotate(0); + transform: rotate(0); } } + +@keyframes spin-cw-1turn { + 0% { + -webkit-transform: rotate(-1turn); + transform: rotate(-1turn); } + 100% { + -webkit-transform: rotate(0); + transform: rotate(0); } } + +.spin-ccw { + -webkit-animation-name: spin-cw-1turn; + animation-name: spin-cw-1turn; } + +@keyframes spin-cw-1turn { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); } + 100% { + -webkit-transform: rotate(1turn); + transform: rotate(1turn); } } + +.wiggle { + -webkit-animation-name: wiggle-7deg; + animation-name: wiggle-7deg; } + +@-webkit-keyframes wiggle-7deg { + 40%, 50%, 60% { + -webkit-transform: rotate(7deg); + transform: rotate(7deg); } + 35%, 45%, 55%, 65% { + -webkit-transform: rotate(-7deg); + transform: rotate(-7deg); } + 0%, 30%, 70%, 100% { + -webkit-transform: rotate(0); + transform: rotate(0); } } + +@keyframes wiggle-7deg { + 40%, 50%, 60% { + -webkit-transform: rotate(7deg); + transform: rotate(7deg); } + 35%, 45%, 55%, 65% { + -webkit-transform: rotate(-7deg); + transform: rotate(-7deg); } + 0%, 30%, 70%, 100% { + -webkit-transform: rotate(0); + transform: rotate(0); } } + +.shake, +.spin-cw, +.spin-ccw, +.wiggle { + -webkit-animation-duration: 500ms; + animation-duration: 500ms; } + +.infinite { + -webkit-animation-iteration-count: infinite; + animation-iteration-count: infinite; } + +.slow { + -webkit-animation-duration: 750ms !important; + animation-duration: 750ms !important; } + +.fast { + -webkit-animation-duration: 250ms !important; + animation-duration: 250ms !important; } + +.linear { + -webkit-animation-timing-function: linear !important; + animation-timing-function: linear !important; } + +.ease { + -webkit-animation-timing-function: ease !important; + animation-timing-function: ease !important; } + +.ease-in { + -webkit-animation-timing-function: ease-in !important; + animation-timing-function: ease-in !important; } + +.ease-out { + -webkit-animation-timing-function: ease-out !important; + animation-timing-function: ease-out !important; } + +.ease-in-out { + -webkit-animation-timing-function: ease-in-out !important; + animation-timing-function: ease-in-out !important; } + +.bounce-in { + -webkit-animation-timing-function: cubic-bezier(0.485, 0.155, 0.24, 1.245) !important; + animation-timing-function: cubic-bezier(0.485, 0.155, 0.24, 1.245) !important; } + +.bounce-out { + -webkit-animation-timing-function: cubic-bezier(0.485, 0.155, 0.515, 0.845) !important; + animation-timing-function: cubic-bezier(0.485, 0.155, 0.515, 0.845) !important; } + +.bounce-in-out { + -webkit-animation-timing-function: cubic-bezier(0.76, -0.245, 0.24, 1.245) !important; + animation-timing-function: cubic-bezier(0.76, -0.245, 0.24, 1.245) !important; } + +.short-delay { + -webkit-animation-delay: 300ms !important; + animation-delay: 300ms !important; } + +.long-delay { + -webkit-animation-delay: 700ms !important; + animation-delay: 700ms !important; } diff --git a/app/assets/stylesheets/foundation.min.css b/app/assets/stylesheets/foundation.min.css new file mode 100644 index 0000000000..fe291e8027 --- /dev/null +++ b/app/assets/stylesheets/foundation.min.css @@ -0,0 +1,2 @@ +@charset "UTF-8"; +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:not-allowed}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.foundation-mq{font-family:"small=0em&medium=40em&large=64em&xlarge=75em&xxlarge=90em"}html{font-size:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}body{padding:0;margin:0;font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-weight:400;line-height:1.5;color:#0a0a0a;background:#fefefe;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img{max-width:100%;height:auto;-ms-interpolation-mode:bicubic;display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px;border-radius:0}select{width:100%;border-radius:0}#map_canvas embed,#map_canvas img,#map_canvas object,.map_canvas embed,.map_canvas img,.map_canvas object,.mqa-display embed,.mqa-display img,.mqa-display object{max-width:none!important}button{-webkit-appearance:none;-moz-appearance:none;background:transparent;padding:0;border:0;border-radius:0;line-height:1}[data-whatinput=mouse] button{outline:0}.is-visible{display:block!important}.is-hidden{display:none!important}.row{max-width:75rem;margin-left:auto;margin-right:auto}.row:after,.row:before{content:' ';display:table}.row:after{clear:both}.row.collapse>.column,.row.collapse>.columns{padding-left:0;padding-right:0}.row .row{max-width:none;margin-left:-.625rem;margin-right:-.625rem}@media screen and (min-width:40em){.row .row{margin-left:-.9375rem;margin-right:-.9375rem}}.row .row.collapse{margin-left:0;margin-right:0}.row.expanded{max-width:none}.row.expanded .row{margin-left:auto;margin-right:auto}.column,.columns{width:100%;float:left;padding-left:.625rem;padding-right:.625rem}@media screen and (min-width:40em){.column,.columns{padding-left:.9375rem;padding-right:.9375rem}}.column:last-child:not(:first-child),.columns:last-child:not(:first-child){float:right}.column.end:last-child:last-child,.end.columns:last-child:last-child{float:left}.column.row.row,.row.row.columns{float:none}.row .column.row.row,.row .row.row.columns{padding-left:0;padding-right:0;margin-left:0;margin-right:0}.small-1{width:8.33333%}.small-push-1{position:relative;left:8.33333%}.small-pull-1{position:relative;left:-8.33333%}.small-offset-0{margin-left:0}.small-2{width:16.66667%}.small-push-2{position:relative;left:16.66667%}.small-pull-2{position:relative;left:-16.66667%}.small-offset-1{margin-left:8.33333%}.small-3{width:25%}.small-push-3{position:relative;left:25%}.small-pull-3{position:relative;left:-25%}.small-offset-2{margin-left:16.66667%}.small-4{width:33.33333%}.small-push-4{position:relative;left:33.33333%}.small-pull-4{position:relative;left:-33.33333%}.small-offset-3{margin-left:25%}.small-5{width:41.66667%}.small-push-5{position:relative;left:41.66667%}.small-pull-5{position:relative;left:-41.66667%}.small-offset-4{margin-left:33.33333%}.small-6{width:50%}.small-push-6{position:relative;left:50%}.small-pull-6{position:relative;left:-50%}.small-offset-5{margin-left:41.66667%}.small-7{width:58.33333%}.small-push-7{position:relative;left:58.33333%}.small-pull-7{position:relative;left:-58.33333%}.small-offset-6{margin-left:50%}.small-8{width:66.66667%}.small-push-8{position:relative;left:66.66667%}.small-pull-8{position:relative;left:-66.66667%}.small-offset-7{margin-left:58.33333%}.small-9{width:75%}.small-push-9{position:relative;left:75%}.small-pull-9{position:relative;left:-75%}.small-offset-8{margin-left:66.66667%}.small-10{width:83.33333%}.small-push-10{position:relative;left:83.33333%}.small-pull-10{position:relative;left:-83.33333%}.small-offset-9{margin-left:75%}.small-11{width:91.66667%}.small-push-11{position:relative;left:91.66667%}.small-pull-11{position:relative;left:-91.66667%}.small-offset-10{margin-left:83.33333%}.small-12{width:100%}.small-offset-11{margin-left:91.66667%}.small-up-1>.column,.small-up-1>.columns{width:100%;float:left}.small-up-1>.column:nth-of-type(1n),.small-up-1>.columns:nth-of-type(1n){clear:none}.small-up-1>.column:nth-of-type(1n+1),.small-up-1>.columns:nth-of-type(1n+1){clear:both}.small-up-1>.column:last-child,.small-up-1>.columns:last-child{float:left}.small-up-2>.column,.small-up-2>.columns{width:50%;float:left}.small-up-2>.column:nth-of-type(1n),.small-up-2>.columns:nth-of-type(1n){clear:none}.small-up-2>.column:nth-of-type(2n+1),.small-up-2>.columns:nth-of-type(2n+1){clear:both}.small-up-2>.column:last-child,.small-up-2>.columns:last-child{float:left}.small-up-3>.column,.small-up-3>.columns{width:33.33333%;float:left}.small-up-3>.column:nth-of-type(1n),.small-up-3>.columns:nth-of-type(1n){clear:none}.small-up-3>.column:nth-of-type(3n+1),.small-up-3>.columns:nth-of-type(3n+1){clear:both}.small-up-3>.column:last-child,.small-up-3>.columns:last-child{float:left}.small-up-4>.column,.small-up-4>.columns{width:25%;float:left}.small-up-4>.column:nth-of-type(1n),.small-up-4>.columns:nth-of-type(1n){clear:none}.small-up-4>.column:nth-of-type(4n+1),.small-up-4>.columns:nth-of-type(4n+1){clear:both}.small-up-4>.column:last-child,.small-up-4>.columns:last-child{float:left}.small-up-5>.column,.small-up-5>.columns{width:20%;float:left}.small-up-5>.column:nth-of-type(1n),.small-up-5>.columns:nth-of-type(1n){clear:none}.small-up-5>.column:nth-of-type(5n+1),.small-up-5>.columns:nth-of-type(5n+1){clear:both}.small-up-5>.column:last-child,.small-up-5>.columns:last-child{float:left}.small-up-6>.column,.small-up-6>.columns{width:16.66667%;float:left}.small-up-6>.column:nth-of-type(1n),.small-up-6>.columns:nth-of-type(1n){clear:none}.small-up-6>.column:nth-of-type(6n+1),.small-up-6>.columns:nth-of-type(6n+1){clear:both}.small-up-6>.column:last-child,.small-up-6>.columns:last-child{float:left}.small-up-7>.column,.small-up-7>.columns{width:14.28571%;float:left}.small-up-7>.column:nth-of-type(1n),.small-up-7>.columns:nth-of-type(1n){clear:none}.small-up-7>.column:nth-of-type(7n+1),.small-up-7>.columns:nth-of-type(7n+1){clear:both}.small-up-7>.column:last-child,.small-up-7>.columns:last-child{float:left}.small-up-8>.column,.small-up-8>.columns{width:12.5%;float:left}.small-up-8>.column:nth-of-type(1n),.small-up-8>.columns:nth-of-type(1n){clear:none}.small-up-8>.column:nth-of-type(8n+1),.small-up-8>.columns:nth-of-type(8n+1){clear:both}.small-up-8>.column:last-child,.small-up-8>.columns:last-child{float:left}.small-collapse>.column,.small-collapse>.columns{padding-left:0;padding-right:0}.expanded.row .small-collapse.row,.small-collapse .row{margin-left:0;margin-right:0}.small-uncollapse>.column,.small-uncollapse>.columns{padding-left:.625rem;padding-right:.625rem}.small-centered{float:none;margin-left:auto;margin-right:auto}.small-pull-0,.small-push-0,.small-uncentered{position:static;margin-left:0;margin-right:0;float:left}@media screen and (min-width:40em){.medium-1{width:8.33333%}.medium-push-1{position:relative;left:8.33333%}.medium-pull-1{position:relative;left:-8.33333%}.medium-offset-0{margin-left:0}.medium-2{width:16.66667%}.medium-push-2{position:relative;left:16.66667%}.medium-pull-2{position:relative;left:-16.66667%}.medium-offset-1{margin-left:8.33333%}.medium-3{width:25%}.medium-push-3{position:relative;left:25%}.medium-pull-3{position:relative;left:-25%}.medium-offset-2{margin-left:16.66667%}.medium-4{width:33.33333%}.medium-push-4{position:relative;left:33.33333%}.medium-pull-4{position:relative;left:-33.33333%}.medium-offset-3{margin-left:25%}.medium-5{width:41.66667%}.medium-push-5{position:relative;left:41.66667%}.medium-pull-5{position:relative;left:-41.66667%}.medium-offset-4{margin-left:33.33333%}.medium-6{width:50%}.medium-push-6{position:relative;left:50%}.medium-pull-6{position:relative;left:-50%}.medium-offset-5{margin-left:41.66667%}.medium-7{width:58.33333%}.medium-push-7{position:relative;left:58.33333%}.medium-pull-7{position:relative;left:-58.33333%}.medium-offset-6{margin-left:50%}.medium-8{width:66.66667%}.medium-push-8{position:relative;left:66.66667%}.medium-pull-8{position:relative;left:-66.66667%}.medium-offset-7{margin-left:58.33333%}.medium-9{width:75%}.medium-push-9{position:relative;left:75%}.medium-pull-9{position:relative;left:-75%}.medium-offset-8{margin-left:66.66667%}.medium-10{width:83.33333%}.medium-push-10{position:relative;left:83.33333%}.medium-pull-10{position:relative;left:-83.33333%}.medium-offset-9{margin-left:75%}.medium-11{width:91.66667%}.medium-push-11{position:relative;left:91.66667%}.medium-pull-11{position:relative;left:-91.66667%}.medium-offset-10{margin-left:83.33333%}.medium-12{width:100%}.medium-offset-11{margin-left:91.66667%}.medium-up-1>.column,.medium-up-1>.columns{width:100%;float:left}.medium-up-1>.column:nth-of-type(1n),.medium-up-1>.columns:nth-of-type(1n){clear:none}.medium-up-1>.column:nth-of-type(1n+1),.medium-up-1>.columns:nth-of-type(1n+1){clear:both}.medium-up-1>.column:last-child,.medium-up-1>.columns:last-child{float:left}.medium-up-2>.column,.medium-up-2>.columns{width:50%;float:left}.medium-up-2>.column:nth-of-type(1n),.medium-up-2>.columns:nth-of-type(1n){clear:none}.medium-up-2>.column:nth-of-type(2n+1),.medium-up-2>.columns:nth-of-type(2n+1){clear:both}.medium-up-2>.column:last-child,.medium-up-2>.columns:last-child{float:left}.medium-up-3>.column,.medium-up-3>.columns{width:33.33333%;float:left}.medium-up-3>.column:nth-of-type(1n),.medium-up-3>.columns:nth-of-type(1n){clear:none}.medium-up-3>.column:nth-of-type(3n+1),.medium-up-3>.columns:nth-of-type(3n+1){clear:both}.medium-up-3>.column:last-child,.medium-up-3>.columns:last-child{float:left}.medium-up-4>.column,.medium-up-4>.columns{width:25%;float:left}.medium-up-4>.column:nth-of-type(1n),.medium-up-4>.columns:nth-of-type(1n){clear:none}.medium-up-4>.column:nth-of-type(4n+1),.medium-up-4>.columns:nth-of-type(4n+1){clear:both}.medium-up-4>.column:last-child,.medium-up-4>.columns:last-child{float:left}.medium-up-5>.column,.medium-up-5>.columns{width:20%;float:left}.medium-up-5>.column:nth-of-type(1n),.medium-up-5>.columns:nth-of-type(1n){clear:none}.medium-up-5>.column:nth-of-type(5n+1),.medium-up-5>.columns:nth-of-type(5n+1){clear:both}.medium-up-5>.column:last-child,.medium-up-5>.columns:last-child{float:left}.medium-up-6>.column,.medium-up-6>.columns{width:16.66667%;float:left}.medium-up-6>.column:nth-of-type(1n),.medium-up-6>.columns:nth-of-type(1n){clear:none}.medium-up-6>.column:nth-of-type(6n+1),.medium-up-6>.columns:nth-of-type(6n+1){clear:both}.medium-up-6>.column:last-child,.medium-up-6>.columns:last-child{float:left}.medium-up-7>.column,.medium-up-7>.columns{width:14.28571%;float:left}.medium-up-7>.column:nth-of-type(1n),.medium-up-7>.columns:nth-of-type(1n){clear:none}.medium-up-7>.column:nth-of-type(7n+1),.medium-up-7>.columns:nth-of-type(7n+1){clear:both}.medium-up-7>.column:last-child,.medium-up-7>.columns:last-child{float:left}.medium-up-8>.column,.medium-up-8>.columns{width:12.5%;float:left}.medium-up-8>.column:nth-of-type(1n),.medium-up-8>.columns:nth-of-type(1n){clear:none}.medium-up-8>.column:nth-of-type(8n+1),.medium-up-8>.columns:nth-of-type(8n+1){clear:both}.medium-up-8>.column:last-child,.medium-up-8>.columns:last-child{float:left}.medium-collapse>.column,.medium-collapse>.columns{padding-left:0;padding-right:0}.expanded.row .medium-collapse.row,.medium-collapse .row{margin-left:0;margin-right:0}.medium-uncollapse>.column,.medium-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem}.medium-centered{float:none;margin-left:auto;margin-right:auto}.medium-pull-0,.medium-push-0,.medium-uncentered{position:static;margin-left:0;margin-right:0;float:left}}@media screen and (min-width:64em){.large-1{width:8.33333%}.large-push-1{position:relative;left:8.33333%}.large-pull-1{position:relative;left:-8.33333%}.large-offset-0{margin-left:0}.large-2{width:16.66667%}.large-push-2{position:relative;left:16.66667%}.large-pull-2{position:relative;left:-16.66667%}.large-offset-1{margin-left:8.33333%}.large-3{width:25%}.large-push-3{position:relative;left:25%}.large-pull-3{position:relative;left:-25%}.large-offset-2{margin-left:16.66667%}.large-4{width:33.33333%}.large-push-4{position:relative;left:33.33333%}.large-pull-4{position:relative;left:-33.33333%}.large-offset-3{margin-left:25%}.large-5{width:41.66667%}.large-push-5{position:relative;left:41.66667%}.large-pull-5{position:relative;left:-41.66667%}.large-offset-4{margin-left:33.33333%}.large-6{width:50%}.large-push-6{position:relative;left:50%}.large-pull-6{position:relative;left:-50%}.large-offset-5{margin-left:41.66667%}.large-7{width:58.33333%}.large-push-7{position:relative;left:58.33333%}.large-pull-7{position:relative;left:-58.33333%}.large-offset-6{margin-left:50%}.large-8{width:66.66667%}.large-push-8{position:relative;left:66.66667%}.large-pull-8{position:relative;left:-66.66667%}.large-offset-7{margin-left:58.33333%}.large-9{width:75%}.large-push-9{position:relative;left:75%}.large-pull-9{position:relative;left:-75%}.large-offset-8{margin-left:66.66667%}.large-10{width:83.33333%}.large-push-10{position:relative;left:83.33333%}.large-pull-10{position:relative;left:-83.33333%}.large-offset-9{margin-left:75%}.large-11{width:91.66667%}.large-push-11{position:relative;left:91.66667%}.large-pull-11{position:relative;left:-91.66667%}.large-offset-10{margin-left:83.33333%}.large-12{width:100%}.large-offset-11{margin-left:91.66667%}.large-up-1>.column,.large-up-1>.columns{width:100%;float:left}.large-up-1>.column:nth-of-type(1n),.large-up-1>.columns:nth-of-type(1n){clear:none}.large-up-1>.column:nth-of-type(1n+1),.large-up-1>.columns:nth-of-type(1n+1){clear:both}.large-up-1>.column:last-child,.large-up-1>.columns:last-child{float:left}.large-up-2>.column,.large-up-2>.columns{width:50%;float:left}.large-up-2>.column:nth-of-type(1n),.large-up-2>.columns:nth-of-type(1n){clear:none}.large-up-2>.column:nth-of-type(2n+1),.large-up-2>.columns:nth-of-type(2n+1){clear:both}.large-up-2>.column:last-child,.large-up-2>.columns:last-child{float:left}.large-up-3>.column,.large-up-3>.columns{width:33.33333%;float:left}.large-up-3>.column:nth-of-type(1n),.large-up-3>.columns:nth-of-type(1n){clear:none}.large-up-3>.column:nth-of-type(3n+1),.large-up-3>.columns:nth-of-type(3n+1){clear:both}.large-up-3>.column:last-child,.large-up-3>.columns:last-child{float:left}.large-up-4>.column,.large-up-4>.columns{width:25%;float:left}.large-up-4>.column:nth-of-type(1n),.large-up-4>.columns:nth-of-type(1n){clear:none}.large-up-4>.column:nth-of-type(4n+1),.large-up-4>.columns:nth-of-type(4n+1){clear:both}.large-up-4>.column:last-child,.large-up-4>.columns:last-child{float:left}.large-up-5>.column,.large-up-5>.columns{width:20%;float:left}.large-up-5>.column:nth-of-type(1n),.large-up-5>.columns:nth-of-type(1n){clear:none}.large-up-5>.column:nth-of-type(5n+1),.large-up-5>.columns:nth-of-type(5n+1){clear:both}.large-up-5>.column:last-child,.large-up-5>.columns:last-child{float:left}.large-up-6>.column,.large-up-6>.columns{width:16.66667%;float:left}.large-up-6>.column:nth-of-type(1n),.large-up-6>.columns:nth-of-type(1n){clear:none}.large-up-6>.column:nth-of-type(6n+1),.large-up-6>.columns:nth-of-type(6n+1){clear:both}.large-up-6>.column:last-child,.large-up-6>.columns:last-child{float:left}.large-up-7>.column,.large-up-7>.columns{width:14.28571%;float:left}.large-up-7>.column:nth-of-type(1n),.large-up-7>.columns:nth-of-type(1n){clear:none}.large-up-7>.column:nth-of-type(7n+1),.large-up-7>.columns:nth-of-type(7n+1){clear:both}.large-up-7>.column:last-child,.large-up-7>.columns:last-child{float:left}.large-up-8>.column,.large-up-8>.columns{width:12.5%;float:left}.large-up-8>.column:nth-of-type(1n),.large-up-8>.columns:nth-of-type(1n){clear:none}.large-up-8>.column:nth-of-type(8n+1),.large-up-8>.columns:nth-of-type(8n+1){clear:both}.large-up-8>.column:last-child,.large-up-8>.columns:last-child{float:left}.large-collapse>.column,.large-collapse>.columns{padding-left:0;padding-right:0}.expanded.row .large-collapse.row,.large-collapse .row{margin-left:0;margin-right:0}.large-uncollapse>.column,.large-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem}.large-centered{float:none;margin-left:auto;margin-right:auto}.large-pull-0,.large-push-0,.large-uncentered{position:static;margin-left:0;margin-right:0;float:left}}blockquote,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,li,ol,p,pre,td,th,ul{margin:0;padding:0}p{font-size:inherit;line-height:1.6;margin-bottom:1rem;text-rendering:optimizeLegibility}em,i{font-style:italic}b,em,i,strong{line-height:inherit}b,strong{font-weight:700}small{font-size:80%;line-height:inherit}h1,h2,h3,h4,h5,h6{font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-weight:400;font-style:normal;color:inherit;text-rendering:optimizeLegibility;margin-top:0;margin-bottom:.5rem;line-height:1.4}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:#cacaca;line-height:0}h1{font-size:1.5rem}h2{font-size:1.25rem}h3{font-size:1.1875rem}h4{font-size:1.125rem}h5{font-size:1.0625rem}h6{font-size:1rem}@media screen and (min-width:40em){h1{font-size:3rem}h2{font-size:2.5rem}h3{font-size:1.9375rem}h4{font-size:1.5625rem}h5{font-size:1.25rem}h6{font-size:1rem}}a{color:#2199e8;text-decoration:none;line-height:inherit;cursor:pointer}a:focus,a:hover{color:#1585cf}a img{border:0}hr{max-width:75rem;height:0;border-right:0;border-top:0;border-bottom:1px solid #cacaca;border-left:0;margin:1.25rem auto;clear:both}dl,ol,ul{line-height:1.6;margin-bottom:1rem;list-style-position:outside}li{font-size:inherit}ul{list-style-type:disc}ol,ul{margin-left:1.25rem}ol ol,ol ul,ul ol,ul ul{margin-left:1.25rem;margin-bottom:0}dl{margin-bottom:1rem}dl dt{margin-bottom:.3rem;font-weight:700}blockquote{margin:0 0 1rem;padding:.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #cacaca}blockquote,blockquote p{line-height:1.6;color:#8a8a8a}cite{display:block;font-size:.8125rem;color:#8a8a8a}cite:before{content:'\2014 \0020'}abbr{color:#0a0a0a;cursor:help;border-bottom:1px dotted #0a0a0a}code{font-weight:400;border:1px solid #cacaca;padding:.125rem .3125rem .0625rem}code,kbd{font-family:Consolas,Liberation Mono,Courier,monospace;color:#0a0a0a;background-color:#e6e6e6}kbd{padding:.125rem .25rem 0;margin:0}.subheader{margin-top:.2rem;margin-bottom:.5rem;font-weight:400;line-height:1.4;color:#8a8a8a}.lead{font-size:125%;line-height:1.6}.stat{font-size:2.5rem;line-height:1}p+.stat{margin-top:-1rem}.no-bullet{margin-left:0;list-style:none}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}@media screen and (min-width:40em){.medium-text-left{text-align:left}.medium-text-right{text-align:right}.medium-text-center{text-align:center}.medium-text-justify{text-align:justify}}@media screen and (min-width:64em){.large-text-left{text-align:left}.large-text-right{text-align:right}.large-text-center{text-align:center}.large-text-justify{text-align:justify}}.show-for-print{display:none!important}@media print{*{background:transparent!important;color:#000!important;box-shadow:none!important;text-shadow:none!important}.show-for-print{display:block!important}.hide-for-print{display:none!important}table.show-for-print{display:table!important}thead.show-for-print{display:table-header-group!important}tbody.show-for-print{display:table-row-group!important}tr.show-for-print{display:table-row!important}td.show-for-print,th.show-for-print{display:table-cell!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}.ir a:after,a[href^='#']:after,a[href^='javascript:']:after{content:''}abbr[title]:after{content:" (" attr(title) ")"}blockquote,pre{border:1px solid #8a8a8a;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.button{display:inline-block;text-align:center;line-height:1;cursor:pointer;-webkit-appearance:none;transition:background-color .25s ease-out,color .25s ease-out;vertical-align:middle;border:1px solid transparent;border-radius:0;padding:.85em 1em;margin:0 0 1rem;font-size:.9rem;background-color:#2199e8;color:#fefefe}[data-whatinput=mouse] .button{outline:0}.button:focus,.button:hover{background-color:#1583cc;color:#fefefe}.button.tiny{font-size:.6rem}.button.small{font-size:.75rem}.button.large{font-size:1.25rem}.button.expanded{display:block;width:100%;margin-left:0;margin-right:0}.button.primary{background-color:#2199e8;color:#fefefe}.button.primary:focus,.button.primary:hover{background-color:#147cc0;color:#fefefe}.button.secondary{background-color:#777;color:#fefefe}.button.secondary:focus,.button.secondary:hover{background-color:#5f5f5f;color:#fefefe}.button.success{background-color:#3adb76;color:#fefefe}.button.success:focus,.button.success:hover{background-color:#22bb5b;color:#fefefe}.button.warning{background-color:#ffae00;color:#fefefe}.button.warning:focus,.button.warning:hover{background-color:#cc8b00;color:#fefefe}.button.alert{background-color:#ec5840;color:#fefefe}.button.alert:focus,.button.alert:hover{background-color:#da3116;color:#fefefe}.button.hollow{border:1px solid #2199e8;color:#2199e8}.button.hollow,.button.hollow:focus,.button.hollow:hover{background-color:transparent}.button.hollow:focus,.button.hollow:hover{border-color:#0c4d78;color:#0c4d78}.button.hollow.primary{border:1px solid #2199e8;color:#2199e8}.button.hollow.primary:focus,.button.hollow.primary:hover{border-color:#0c4d78;color:#0c4d78}.button.hollow.secondary{border:1px solid #777;color:#777}.button.hollow.secondary:focus,.button.hollow.secondary:hover{border-color:#3c3c3c;color:#3c3c3c}.button.hollow.success{border:1px solid #3adb76;color:#3adb76}.button.hollow.success:focus,.button.hollow.success:hover{border-color:#157539;color:#157539}.button.hollow.warning{border:1px solid #ffae00;color:#ffae00}.button.hollow.warning:focus,.button.hollow.warning:hover{border-color:#805700;color:#805700}.button.hollow.alert{border:1px solid #ec5840;color:#ec5840}.button.hollow.alert:focus,.button.hollow.alert:hover{border-color:#881f0e;color:#881f0e}.button.disabled,.button[disabled]{opacity:.25;cursor:not-allowed}.button.disabled:focus,.button.disabled:hover,.button[disabled]:focus,.button[disabled]:hover{background-color:#2199e8;color:#fefefe}.button.dropdown:after{content:'';display:block;width:0;height:0;border:.4em inset;border-color:#fefefe transparent transparent;border-top-style:solid;border-bottom-width:0;position:relative;top:.4em;float:right;margin-left:1em;display:inline-block}.button.arrow-only:after{margin-left:0;float:none;top:-.1em}[type=color],[type=date],[type=datetime-local],[type=datetime],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],textarea{display:block;box-sizing:border-box;width:100%;height:2.4375rem;padding:.5rem;border:1px solid #cacaca;margin:0 0 1rem;font-family:inherit;font-size:1rem;color:#0a0a0a;background-color:#fefefe;box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);border-radius:0;transition:box-shadow .5s,border-color .25s ease-in-out;-webkit-appearance:none;-moz-appearance:none}[type=color]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=datetime]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,textarea:focus{border:1px solid #8a8a8a;background-color:#fefefe;outline:none;box-shadow:0 0 5px #cacaca;transition:box-shadow .5s,border-color .25s ease-in-out}textarea{max-width:100%}textarea[rows]{height:auto}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#cacaca}input::-moz-placeholder,textarea::-moz-placeholder{color:#cacaca}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#cacaca}input::placeholder,textarea::placeholder{color:#cacaca}input:disabled,input[readonly],textarea:disabled,textarea[readonly]{background-color:#e6e6e6;cursor:not-allowed}[type=button],[type=submit]{border-radius:0;-webkit-appearance:none;-moz-appearance:none}input[type=search]{box-sizing:border-box}[type=checkbox],[type=file],[type=radio]{margin:0 0 1rem}[type=checkbox]+label,[type=radio]+label{display:inline-block;margin-left:.5rem;margin-right:1rem;margin-bottom:0;vertical-align:baseline}[type=checkbox]+label[for],[type=radio]+label[for]{cursor:pointer}label>[type=checkbox],label>[type=radio]{margin-right:.5rem}[type=file]{width:100%}label{display:block;margin:0;font-size:.875rem;font-weight:400;line-height:1.8;color:#0a0a0a}label.middle{margin:0 0 1rem;padding:.5625rem 0}.help-text{margin-top:-.5rem;font-size:.8125rem;font-style:italic;color:#0a0a0a}.input-group{display:table;width:100%;margin-bottom:1rem}.input-group>:first-child,.input-group>:last-child>*{border-radius:0 0 0 0}.input-group-button,.input-group-field,.input-group-label{margin:0;white-space:nowrap;display:table-cell;vertical-align:middle}.input-group-label{text-align:center;padding:0 1rem;background:#e6e6e6;color:#0a0a0a;border:1px solid #cacaca;white-space:nowrap;width:1%;height:100%}.input-group-label:first-child{border-right:0}.input-group-label:last-child{border-left:0}.input-group-field{border-radius:0;height:2.5rem}.input-group-button{padding-top:0;padding-bottom:0;text-align:center;height:100%;width:1%}.input-group-button a,.input-group-button button,.input-group-button input{margin:0}.input-group .input-group-button{display:table-cell}fieldset{border:0;padding:0;margin:0}legend{margin-bottom:.5rem;max-width:100%}.fieldset{border:1px solid #cacaca;padding:1.25rem;margin:1.125rem 0}.fieldset legend{background:#fefefe;padding:0 .1875rem;margin:0;margin-left:-.1875rem}select{height:2.4375rem;padding:.5rem;border:1px solid #cacaca;margin:0 0 1rem;font-size:1rem;font-family:inherit;line-height:normal;color:#0a0a0a;background-color:#fefefe;border-radius:0;-webkit-appearance:none;-moz-appearance:none;background-image:url("data:image/svg+xml;utf8,");background-size:9px 6px;background-position:right -1rem center;background-origin:content-box;background-repeat:no-repeat;padding-right:1.5rem}@media screen and (min-width:0\0){select{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg==")}}select:disabled{background-color:#e6e6e6;cursor:not-allowed}select::-ms-expand{display:none}select[multiple]{height:auto;background-image:none}.is-invalid-input:not(:focus){background-color:rgba(236,88,64,.1);border-color:#ec5840}.form-error,.is-invalid-label{color:#ec5840}.form-error{display:none;margin-top:-.5rem;margin-bottom:1rem;font-size:.75rem;font-weight:700}.form-error.is-visible{display:block}.accordion{list-style-type:none;background:#fefefe;margin-left:0}.accordion-item:first-child>:first-child,.accordion-item:last-child>:last-child{border-radius:0 0 0 0}.accordion-title{display:block;padding:1.25rem 1rem;line-height:1;font-size:.75rem;color:#2199e8;position:relative;border:1px solid #e6e6e6;border-bottom:0}:last-child:not(.is-active)>.accordion-title{border-radius:0 0 0 0;border-bottom:1px solid #e6e6e6}.accordion-title:focus,.accordion-title:hover{background-color:#e6e6e6}.accordion-title:before{content:'+';position:absolute;right:1rem;top:50%;margin-top:-.5rem}.is-active>.accordion-title:before{content:'–'}.accordion-content{padding:1rem;display:none;border:1px solid #e6e6e6;border-bottom:0;background-color:#fefefe;color:#0a0a0a}:last-child>.accordion-content:last-child{border-bottom:1px solid #e6e6e6}.is-accordion-submenu-parent>a{position:relative}.is-accordion-submenu-parent>a:after{content:'';display:block;width:0;height:0;border:6px inset;border-color:#2199e8 transparent transparent;border-top-style:solid;border-bottom-width:0;position:absolute;top:50%;margin-top:-4px;right:1rem}.is-accordion-submenu-parent[aria-expanded=true]>a:after{-webkit-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transform:scaleY(-1);transform:scaleY(-1)}.badge{display:inline-block;padding:.3em;min-width:2.1em;font-size:.6rem;text-align:center;border-radius:50%;background:#2199e8;color:#fefefe}.badge.secondary{background:#777;color:#fefefe}.badge.success{background:#3adb76;color:#fefefe}.badge.warning{background:#ffae00;color:#fefefe}.badge.alert{background:#ec5840;color:#fefefe}.breadcrumbs{list-style:none;margin:0 0 1rem}.breadcrumbs:after,.breadcrumbs:before{content:' ';display:table}.breadcrumbs:after{clear:both}.breadcrumbs li{float:left;color:#0a0a0a;font-size:.6875rem;cursor:default;text-transform:uppercase}.breadcrumbs li:not(:last-child):after{color:#cacaca;content:"/";margin:0 .75rem;position:relative;top:1px;opacity:1}.breadcrumbs a{color:#2199e8}.breadcrumbs a:hover{text-decoration:underline}.breadcrumbs .disabled{color:#cacaca;cursor:not-allowed}.button-group{margin-bottom:1rem;font-size:0}.button-group:after,.button-group:before{content:' ';display:table}.button-group:after{clear:both}.button-group .button{margin:0;margin-right:1px;margin-bottom:1px;font-size:.9rem}.button-group .button:last-child{margin-right:0}.button-group.tiny .button{font-size:.6rem}.button-group.small .button{font-size:.75rem}.button-group.large .button{font-size:1.25rem}.button-group.expanded{margin-right:-1px}.button-group.expanded:after,.button-group.expanded:before{display:none}.button-group.expanded .button:first-child:nth-last-child(2),.button-group.expanded .button:first-child:nth-last-child(2):first-child:nth-last-child(2)~.button{display:inline-block;width:calc(50% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(2):first-child:nth-last-child(2)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(2):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(3),.button-group.expanded .button:first-child:nth-last-child(3):first-child:nth-last-child(3)~.button{display:inline-block;width:calc(33.33333% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(3):first-child:nth-last-child(3)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(3):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(4),.button-group.expanded .button:first-child:nth-last-child(4):first-child:nth-last-child(4)~.button{display:inline-block;width:calc(25% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(4):first-child:nth-last-child(4)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(4):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(5),.button-group.expanded .button:first-child:nth-last-child(5):first-child:nth-last-child(5)~.button{display:inline-block;width:calc(20% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(5):first-child:nth-last-child(5)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(5):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(6),.button-group.expanded .button:first-child:nth-last-child(6):first-child:nth-last-child(6)~.button{display:inline-block;width:calc(16.66667% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(6):first-child:nth-last-child(6)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(6):last-child{margin-right:-6px}.button-group.primary .button{background-color:#2199e8;color:#fefefe}.button-group.primary .button:focus,.button-group.primary .button:hover{background-color:#147cc0;color:#fefefe}.button-group.secondary .button{background-color:#777;color:#fefefe}.button-group.secondary .button:focus,.button-group.secondary .button:hover{background-color:#5f5f5f;color:#fefefe}.button-group.success .button{background-color:#3adb76;color:#fefefe}.button-group.success .button:focus,.button-group.success .button:hover{background-color:#22bb5b;color:#fefefe}.button-group.warning .button{background-color:#ffae00;color:#fefefe}.button-group.warning .button:focus,.button-group.warning .button:hover{background-color:#cc8b00;color:#fefefe}.button-group.alert .button{background-color:#ec5840;color:#fefefe}.button-group.alert .button:focus,.button-group.alert .button:hover{background-color:#da3116;color:#fefefe}.button-group.stacked-for-medium .button,.button-group.stacked-for-small .button,.button-group.stacked .button{width:100%}.button-group.stacked-for-medium .button:last-child,.button-group.stacked-for-small .button:last-child,.button-group.stacked .button:last-child{margin-bottom:0}@media screen and (min-width:40em){.button-group.stacked-for-small .button{width:auto;margin-bottom:0}}@media screen and (min-width:64em){.button-group.stacked-for-medium .button{width:auto;margin-bottom:0}}@media screen and (max-width:39.9375em){.button-group.stacked-for-small.expanded{display:block}.button-group.stacked-for-small.expanded .button{display:block;margin-right:0}}.callout{margin:0 0 1rem;padding:1rem;border:1px solid hsla(0,0%,4%,.25);border-radius:0;position:relative;color:#0a0a0a;background-color:#fff}.callout>:first-child{margin-top:0}.callout>:last-child{margin-bottom:0}.callout.primary{background-color:#def0fc}.callout.secondary{background-color:#ebebeb}.callout.success{background-color:#e1faea}.callout.warning{background-color:#fff3d9}.callout.alert{background-color:#fce6e2}.callout.small{padding:.5rem}.callout.large{padding:3rem}.close-button{position:absolute;color:#8a8a8a;right:1rem;top:.5rem;font-size:2em;line-height:1;cursor:pointer}[data-whatinput=mouse] .close-button{outline:0}.close-button:focus,.close-button:hover{color:#0a0a0a}.menu{margin:0;list-style-type:none}.menu>li{display:table-cell;vertical-align:middle}[data-whatinput=mouse] .menu>li{outline:0}.menu>li>a{display:block;padding:.7rem 1rem;line-height:1}.menu a,.menu button,.menu input{margin-bottom:0}.menu>li>a i,.menu>li>a i+span,.menu>li>a img,.menu>li>a img+span,.menu>li>a svg,.menu>li>a svg+span{vertical-align:middle}.menu>li>a i,.menu>li>a img,.menu>li>a svg{margin-right:.25rem;display:inline-block}.menu>li{display:table-cell}.menu.vertical>li{display:block}@media screen and (min-width:40em){.menu.medium-horizontal>li{display:table-cell}.menu.medium-vertical>li{display:block}}@media screen and (min-width:64em){.menu.large-horizontal>li{display:table-cell}.menu.large-vertical>li{display:block}}.menu.simple li{line-height:1;display:inline-block;margin-right:1rem}.menu.simple a{padding:0}.menu.align-right:after,.menu.align-right:before{content:' ';display:table}.menu.align-right:after{clear:both}.menu.align-right>li{float:right}.menu.expanded{width:100%;display:table;table-layout:fixed}.menu.expanded>li:first-child:last-child{width:100%}.menu.icon-top>li>a{text-align:center}.menu.icon-top>li>a i,.menu.icon-top>li>a img,.menu.icon-top>li>a svg{display:block;margin:0 auto .25rem}.menu.nested{margin-left:1rem}.menu .active>a{color:#fefefe;background:#2199e8}.menu-text{font-weight:700;color:inherit;line-height:1;padding-top:0;padding-bottom:0;padding:.7rem 1rem}.menu-centered{text-align:center}.menu-centered>.menu{display:inline-block}.no-js [data-responsive-menu] ul{display:none}.menu-icon{position:relative;display:inline-block;vertical-align:middle;cursor:pointer;width:20px;height:16px}.menu-icon:after{content:'';position:absolute;display:block;width:100%;height:2px;background:#fefefe;top:0;left:0;box-shadow:0 7px 0 #fefefe,0 14px 0 #fefefe}.menu-icon:hover:after{background:#cacaca;box-shadow:0 7px 0 #cacaca,0 14px 0 #cacaca}.is-drilldown{position:relative;overflow:hidden}.is-drilldown li{display:block!important}.is-drilldown-submenu{position:absolute;top:0;left:100%;z-index:-1;height:100%;width:100%;background:#fefefe;transition:-webkit-transform .15s linear;transition:transform .15s linear}.is-drilldown-submenu.is-active{z-index:1;display:block;-webkit-transform:translateX(-100%);transform:translateX(-100%)}.is-drilldown-submenu.is-closing{-webkit-transform:translateX(100%);transform:translateX(100%)}.is-drilldown-submenu-parent>a{position:relative}.is-drilldown-submenu-parent>a:after{content:'';display:block;width:0;height:0;border:6px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid;border-right-width:0;position:absolute;top:50%;margin-top:-6px;right:1rem}.js-drilldown-back>a:before{content:'';display:block;width:0;height:0;border:6px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;border-left-width:0;display:inline-block;vertical-align:middle;margin-right:.75rem}.dropdown-pane{background-color:#fefefe;border:1px solid #cacaca;border-radius:0;display:block;font-size:1rem;padding:1rem;position:absolute;visibility:hidden;width:300px;z-index:3}.dropdown-pane.is-open{visibility:visible}.dropdown-pane.tiny{width:100px}.dropdown-pane.small{width:200px}.dropdown-pane.large{width:400px}.dropdown.menu>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu>li.opens-right>.is-dropdown-submenu{right:auto;left:0;top:100%}.dropdown.menu>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu>li.is-dropdown-submenu-parent>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:#2199e8 transparent transparent;border-top-style:solid;border-bottom-width:0;right:5px;margin-top:-2px}[data-whatinput=mouse] .dropdown.menu a{outline:0}.no-js .dropdown.menu ul{display:none}.dropdown.menu.vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%}.dropdown.menu.vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.vertical>li>a:after{right:14px;margin-top:-3px}.dropdown.menu.vertical>li.opens-left>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;border-left-width:0}.dropdown.menu.vertical>li.opens-right>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid;border-right-width:0}@media screen and (min-width:40em){.dropdown.menu.medium-horizontal>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu.medium-horizontal>li.opens-right>.is-dropdown-submenu{right:auto;left:0;top:100%}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:#2199e8 transparent transparent;border-top-style:solid;border-bottom-width:0;right:5px;margin-top:-2px}.dropdown.menu.medium-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.medium-vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%}.dropdown.menu.medium-vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.medium-vertical>li>a:after{right:14px;margin-top:-3px}.dropdown.menu.medium-vertical>li.opens-left>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;border-left-width:0}.dropdown.menu.medium-vertical>li.opens-right>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid;border-right-width:0}}@media screen and (min-width:64em){.dropdown.menu.large-horizontal>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu.large-horizontal>li.opens-right>.is-dropdown-submenu{right:auto;left:0;top:100%}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:#2199e8 transparent transparent;border-top-style:solid;border-bottom-width:0;right:5px;margin-top:-2px}.dropdown.menu.large-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.large-vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%}.dropdown.menu.large-vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.large-vertical>li>a:after{right:14px;margin-top:-3px}.dropdown.menu.large-vertical>li.opens-left>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;border-left-width:0}.dropdown.menu.large-vertical>li.opens-right>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid;border-right-width:0}}.dropdown.menu.align-right .is-dropdown-submenu.first-sub{top:100%;left:auto;right:0}.is-dropdown-menu.vertical{width:100px}.is-dropdown-menu.vertical.align-right{float:right}.is-dropdown-submenu-parent{position:relative}.is-dropdown-submenu-parent a:after{position:absolute;top:50%;right:5px;margin-top:-2px}.is-dropdown-submenu-parent.opens-inner>.is-dropdown-submenu{top:100%;left:auto}.is-dropdown-submenu-parent.opens-left>.is-dropdown-submenu{left:auto;right:100%}.is-dropdown-submenu-parent.opens-right>.is-dropdown-submenu{right:auto;left:100%}.is-dropdown-submenu{display:none;position:absolute;top:0;left:100%;min-width:200px;z-index:1;background:#fefefe;border:1px solid #cacaca}.is-dropdown-submenu .is-dropdown-submenu-parent>a:after{right:14px;margin-top:-3px}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-left>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent #2199e8 transparent transparent;border-right-style:solid;border-left-width:0}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-right>a:after{content:'';display:block;width:0;height:0;border:5px inset;border-color:transparent transparent transparent #2199e8;border-left-style:solid;border-right-width:0}.is-dropdown-submenu .is-dropdown-submenu{margin-top:-1px}.is-dropdown-submenu>li{width:100%}.is-dropdown-submenu.js-dropdown-active{display:block}.flex-video{position:relative;height:0;padding-bottom:75%;margin-bottom:1rem;overflow:hidden}.flex-video embed,.flex-video iframe,.flex-video object,.flex-video video{position:absolute;top:0;left:0;width:100%;height:100%}.flex-video.widescreen{padding-bottom:56.25%}.flex-video.vimeo{padding-top:0}.label{display:inline-block;padding:.33333rem .5rem;font-size:.8rem;line-height:1;white-space:nowrap;cursor:default;border-radius:0;background:#2199e8;color:#fefefe}.label.secondary{background:#777;color:#fefefe}.label.success{background:#3adb76;color:#fefefe}.label.warning{background:#ffae00;color:#fefefe}.label.alert{background:#ec5840;color:#fefefe}.media-object{margin-bottom:1rem;display:block}.media-object img{max-width:none}@media screen and (max-width:39.9375em){.media-object.stack-for-small .media-object-section{padding:0;padding-bottom:1rem;display:block}.media-object.stack-for-small .media-object-section img{width:100%}}.media-object-section{display:table-cell;vertical-align:top}.media-object-section:first-child{padding-right:1rem}.media-object-section:last-child:not(:nth-child(2)){padding-left:1rem}.media-object-section>:last-child{margin-bottom:0}.media-object-section.middle{vertical-align:middle}.media-object-section.bottom{vertical-align:bottom}body,html{height:100%}.off-canvas-wrapper{width:100%;overflow-x:hidden;position:relative;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-overflow-scrolling:auto}.off-canvas-wrapper-inner{position:relative;width:100%;transition:-webkit-transform .5s ease;transition:transform .5s ease}.off-canvas-wrapper-inner:after,.off-canvas-wrapper-inner:before{content:' ';display:table}.off-canvas-wrapper-inner:after{clear:both}.off-canvas-content{min-height:100%;background:#fefefe;transition:-webkit-transform .5s ease;transition:transform .5s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1;padding-bottom:.1px;box-shadow:0 0 10px hsla(0,0%,4%,.5)}.js-off-canvas-exit{display:none;position:absolute;top:0;left:0;width:100%;height:100%;background:hsla(0,0%,100%,.25);cursor:pointer;transition:background .5s ease}.off-canvas{position:absolute;background:#e6e6e6;z-index:-1;max-height:100%;overflow-y:auto;-webkit-transform:translateX(0);transform:translateX(0)}[data-whatinput=mouse] .off-canvas{outline:0}.off-canvas.position-left{left:-250px;top:0;width:250px}.is-open-left{-webkit-transform:translateX(250px);transform:translateX(250px)}.off-canvas.position-right{right:-250px;top:0;width:250px}.is-open-right{-webkit-transform:translateX(-250px);transform:translateX(-250px)}@media screen and (min-width:40em){.position-left.reveal-for-medium{left:0;z-index:auto;position:fixed}.position-left.reveal-for-medium~.off-canvas-content{margin-left:250px}.position-right.reveal-for-medium{right:0;z-index:auto;position:fixed}.position-right.reveal-for-medium~.off-canvas-content{margin-right:250px}}@media screen and (min-width:64em){.position-left.reveal-for-large{left:0;z-index:auto;position:fixed}.position-left.reveal-for-large~.off-canvas-content{margin-left:250px}.position-right.reveal-for-large{right:0;z-index:auto;position:fixed}.position-right.reveal-for-large~.off-canvas-content{margin-right:250px}}.orbit,.orbit-container{position:relative}.orbit-container{margin:0;overflow:hidden;list-style:none}.orbit-slide{width:100%;max-height:100%}.orbit-slide.no-motionui.is-active{top:0;left:0}.orbit-figure{margin:0}.orbit-image{margin:0;width:100%;max-width:100%}.orbit-caption{bottom:0;width:100%;margin-bottom:0;background-color:hsla(0,0%,4%,.5)}.orbit-caption,.orbit-next,.orbit-previous{position:absolute;padding:1rem;color:#fefefe}.orbit-next,.orbit-previous{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);z-index:3}[data-whatinput=mouse] .orbit-next,[data-whatinput=mouse] .orbit-previous{outline:0}.orbit-next:active,.orbit-next:focus,.orbit-next:hover,.orbit-previous:active,.orbit-previous:focus,.orbit-previous:hover{background-color:hsla(0,0%,4%,.5)}.orbit-previous{left:0}.orbit-next{left:auto;right:0}.orbit-bullets{position:relative;margin-top:.8rem;margin-bottom:.8rem;text-align:center}[data-whatinput=mouse] .orbit-bullets{outline:0}.orbit-bullets button{width:1.2rem;height:1.2rem;margin:.1rem;background-color:#cacaca;border-radius:50%}.orbit-bullets button.is-active,.orbit-bullets button:hover{background-color:#8a8a8a}.pagination{margin-left:0;margin-bottom:1rem}.pagination:after,.pagination:before{content:' ';display:table}.pagination:after{clear:both}.pagination li{font-size:.875rem;margin-right:.0625rem;border-radius:0;display:none}.pagination li:first-child,.pagination li:last-child{display:inline-block}@media screen and (min-width:40em){.pagination li{display:inline-block}}.pagination a,.pagination button{color:#0a0a0a;display:block;padding:.1875rem .625rem;border-radius:0}.pagination a:hover,.pagination button:hover{background:#e6e6e6}.pagination .current{padding:.1875rem .625rem;background:#2199e8;color:#fefefe;cursor:default}.pagination .disabled{padding:.1875rem .625rem;color:#cacaca;cursor:not-allowed}.pagination .disabled:hover{background:transparent}.pagination .ellipsis:after{content:'\2026';padding:.1875rem .625rem;color:#0a0a0a}.pagination-previous.disabled:before,.pagination-previous a:before{content:'\00ab';display:inline-block;margin-right:.5rem}.pagination-next.disabled:after,.pagination-next a:after{content:'\00bb';display:inline-block;margin-left:.5rem}.progress{background-color:#cacaca;height:1rem;margin-bottom:1rem;border-radius:0}.progress.primary .progress-meter{background-color:#2199e8}.progress.secondary .progress-meter{background-color:#777}.progress.success .progress-meter{background-color:#3adb76}.progress.warning .progress-meter{background-color:#ffae00}.progress.alert .progress-meter{background-color:#ec5840}.progress-meter{position:relative;display:block;width:0;height:100%;background-color:#2199e8}.progress-meter-text{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;margin:0;font-size:.75rem;font-weight:700;color:#fefefe;white-space:nowrap}body.is-reveal-open{overflow:hidden}html.is-reveal-open,html.is-reveal-open body{height:100%;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.reveal-overlay{display:none;position:fixed;top:0;bottom:0;left:0;right:0;z-index:4;background-color:hsla(0,0%,4%,.45);overflow-y:scroll}.reveal{display:none;z-index:5;padding:1rem;border:1px solid #cacaca;background-color:#fefefe;border-radius:0;position:relative;top:100px;margin-left:auto;margin-right:auto;overflow-y:auto}[data-whatinput=mouse] .reveal{outline:0}@media screen and (min-width:40em){.reveal{min-height:0}}.reveal .column,.reveal .columns{min-width:0}.reveal>:last-child{margin-bottom:0}@media screen and (min-width:40em){.reveal{width:600px;max-width:75rem}}@media screen and (min-width:40em){.reveal .reveal{left:auto;right:auto;margin:0 auto}}.reveal.collapse{padding:0}@media screen and (min-width:40em){.reveal.tiny{width:30%;max-width:75rem}}@media screen and (min-width:40em){.reveal.small{width:50%;max-width:75rem}}@media screen and (min-width:40em){.reveal.large{width:90%;max-width:75rem}}.reveal.full{top:0;left:0;width:100%;height:100%;height:100vh;min-height:100vh;max-width:none;margin-left:0;border:0;border-radius:0}@media screen and (max-width:39.9375em){.reveal{top:0;left:0;width:100%;height:100%;height:100vh;min-height:100vh;max-width:none;margin-left:0;border:0;border-radius:0}}.reveal.without-overlay{position:fixed}.slider{position:relative;height:.5rem;margin-top:1.25rem;margin-bottom:2.25rem;background-color:#e6e6e6;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-touch-action:none;touch-action:none}.slider-fill{position:absolute;top:0;left:0;display:inline-block;max-width:100%;height:.5rem;background-color:#cacaca;transition:all .2s ease-in-out}.slider-fill.is-dragging{transition:all 0s linear}.slider-handle{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);position:absolute;left:0;z-index:1;display:inline-block;width:1.4rem;height:1.4rem;background-color:#2199e8;transition:all .2s ease-in-out;-ms-touch-action:manipulation;touch-action:manipulation;border-radius:0}[data-whatinput=mouse] .slider-handle{outline:0}.slider-handle:hover{background-color:#1583cc}.slider-handle.is-dragging{transition:all 0s linear}.slider.disabled,.slider[disabled]{opacity:.25;cursor:not-allowed}.slider.vertical{display:inline-block;width:.5rem;height:12.5rem;margin:0 1.25rem;-webkit-transform:scaleY(-1);transform:scaleY(-1)}.slider.vertical .slider-fill{top:0;width:.5rem;max-height:100%}.slider.vertical .slider-handle{position:absolute;top:0;left:50%;width:1.4rem;height:1.4rem;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.sticky-container{position:relative}.sticky{position:absolute;z-index:0;-webkit-transform:translateZ(0);transform:translateZ(0)}.sticky.is-stuck{position:fixed;z-index:2}.sticky.is-stuck.is-at-top{top:0}.sticky.is-stuck.is-at-bottom{bottom:0}.sticky.is-anchored{position:absolute;left:auto;right:auto}.sticky.is-anchored.is-at-bottom{bottom:0}.switch{margin-bottom:1rem;outline:0;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#fefefe;font-weight:700;font-size:.875rem}.switch-input{opacity:0;position:absolute}.switch-paddle{background:#cacaca;cursor:pointer;display:block;position:relative;width:4rem;height:2rem;transition:all .25s ease-out;border-radius:0;color:inherit;font-weight:inherit}input+.switch-paddle{margin:0}.switch-paddle:after{background:#fefefe;content:'';display:block;position:absolute;height:1.5rem;left:.25rem;top:.25rem;width:1.5rem;transition:all .25s ease-out;-webkit-transform:translateZ(0);transform:translateZ(0);border-radius:0}input:checked~.switch-paddle{background:#2199e8}input:checked~.switch-paddle:after{left:2.25rem}[data-whatinput=mouse] input:focus~.switch-paddle{outline:0}.switch-active,.switch-inactive{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.switch-active{left:8%;display:none}input:checked+label>.switch-active{display:block}.switch-inactive{right:15%}input:checked+label>.switch-inactive{display:none}.switch.tiny .switch-paddle{width:3rem;height:1.5rem;font-size:.625rem}.switch.tiny .switch-paddle:after{width:1rem;height:1rem}.switch.tiny input:checked~.switch-paddle:after{left:1.75rem}.switch.small .switch-paddle{width:3.5rem;height:1.75rem;font-size:.75rem}.switch.small .switch-paddle:after{width:1.25rem;height:1.25rem}.switch.small input:checked~.switch-paddle:after{left:2rem}.switch.large .switch-paddle{width:5rem;height:2.5rem;font-size:1rem}.switch.large .switch-paddle:after{width:2rem;height:2rem}.switch.large input:checked~.switch-paddle:after{left:2.75rem}table{width:100%;margin-bottom:1rem;border-radius:0}table tbody,table tfoot,table thead{border:1px solid #f1f1f1;background-color:#fefefe}table caption{font-weight:700;padding:.5rem .625rem .625rem}table tfoot,table thead{background:#f8f8f8;color:#0a0a0a}table tfoot tr,table thead tr{background:transparent}table tfoot td,table tfoot th,table thead td,table thead th{padding:.5rem .625rem .625rem;font-weight:700;text-align:left}table tbody tr:nth-child(even){background-color:#f1f1f1}table tbody td,table tbody th{padding:.5rem .625rem .625rem}@media screen and (max-width:63.9375em){table.stack tfoot,table.stack thead{display:none}table.stack td,table.stack th,table.stack tr{display:block}table.stack td{border-top:0}}table.scroll{display:block;width:100%;overflow-x:auto}table.hover tr:hover{background-color:#f9f9f9}table.hover tr:nth-of-type(even):hover{background-color:#ececec}.table-scroll{overflow-x:auto}.table-scroll table{width:auto}.tabs{margin:0;list-style-type:none;background:#fefefe;border:1px solid #e6e6e6}.tabs:after,.tabs:before{content:' ';display:table}.tabs:after{clear:both}.tabs.vertical>li{width:auto;float:none;display:block}.tabs.simple>li>a{padding:0}.tabs.simple>li>a:hover{background:transparent}.tabs.primary{background:#2199e8}.tabs.primary>li>a{color:#fefefe}.tabs.primary>li>a:focus,.tabs.primary>li>a:hover{background:#1893e4}.tabs-title{float:left}.tabs-title>a{display:block;padding:1.25rem 1.5rem;line-height:1;font-size:.75rem}.tabs-title>a:hover{background:#fefefe}.tabs-title>a:focus,.tabs-title>a[aria-selected=true]{background:#e6e6e6}.tabs-content{background:#fefefe;transition:all .5s ease;border:1px solid #e6e6e6;border-top:0}.tabs-content.vertical{border:1px solid #e6e6e6;border-left:0}.tabs-panel{display:none;padding:1rem}.tabs-panel.is-active{display:block}.thumbnail{border:4px solid #fefefe;box-shadow:0 0 0 1px hsla(0,0%,4%,.2);display:inline-block;line-height:0;max-width:100%;transition:box-shadow .2s ease-out;border-radius:0;margin-bottom:1rem}.thumbnail:focus,.thumbnail:hover{box-shadow:0 0 6px 1px rgba(33,153,232,.5)}.title-bar{background:#0a0a0a;color:#fefefe;padding:.5rem}.title-bar:after,.title-bar:before{content:' ';display:table}.title-bar:after{clear:both}.title-bar .menu-icon{margin-left:.25rem;margin-right:.25rem}.title-bar-left{float:left}.title-bar-right{float:right;text-align:right}.title-bar-title{font-weight:700}.menu-icon.dark,.title-bar-title{vertical-align:middle;display:inline-block}.menu-icon.dark{position:relative;cursor:pointer;width:20px;height:16px}.menu-icon.dark:after{content:'';position:absolute;display:block;width:100%;height:2px;background:#0a0a0a;top:0;left:0;box-shadow:0 7px 0 #0a0a0a,0 14px 0 #0a0a0a}.menu-icon.dark:hover:after{background:#8a8a8a;box-shadow:0 7px 0 #8a8a8a,0 14px 0 #8a8a8a}.has-tip{border-bottom:1px dotted #8a8a8a;font-weight:700;position:relative;display:inline-block;cursor:help}.tooltip{background-color:#0a0a0a;color:#fefefe;font-size:80%;padding:.75rem;position:absolute;z-index:3;top:calc(100% + .6495rem);max-width:10rem!important;border-radius:0}.tooltip:before{border-color:transparent transparent #0a0a0a;border-bottom-style:solid;border-top-width:0;bottom:100%;position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.tooltip.top:before,.tooltip:before{content:'';display:block;width:0;height:0;border:.75rem inset}.tooltip.top:before{border-color:#0a0a0a transparent transparent;border-top-style:solid;border-bottom-width:0;top:100%;bottom:auto}.tooltip.left:before{border-color:transparent transparent transparent #0a0a0a;border-left-style:solid;border-right-width:0;left:100%}.tooltip.left:before,.tooltip.right:before{content:'';display:block;width:0;height:0;border:.75rem inset;bottom:auto;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.tooltip.right:before{border-color:transparent #0a0a0a transparent transparent;border-right-style:solid;border-left-width:0;left:auto;right:100%}.top-bar{padding:.5rem}.top-bar:after,.top-bar:before{content:' ';display:table}.top-bar:after{clear:both}.top-bar,.top-bar ul{background-color:#e6e6e6}.top-bar input{max-width:200px;margin-right:1rem}.top-bar .input-group-field{width:100%;margin-right:0}.top-bar input.button{width:auto}.top-bar .top-bar-left,.top-bar .top-bar-right{width:100%}@media screen and (min-width:40em){.top-bar .top-bar-left,.top-bar .top-bar-right{width:auto}}@media screen and (max-width:63.9375em){.top-bar.stacked-for-medium .top-bar-left,.top-bar.stacked-for-medium .top-bar-right{width:100%}}@media screen and (max-width:74.9375em){.top-bar.stacked-for-large .top-bar-left,.top-bar.stacked-for-large .top-bar-right{width:100%}}.top-bar-title{float:left;margin-right:1rem}.top-bar-left{float:left}.top-bar-right{float:right}.hide{display:none!important}.invisible{visibility:hidden}@media screen and (max-width:39.9375em){.hide-for-small-only{display:none!important}}@media screen and (max-width:0em),screen and (min-width:40em){.show-for-small-only{display:none!important}}@media screen and (min-width:40em){.hide-for-medium{display:none!important}}@media screen and (max-width:39.9375em){.show-for-medium{display:none!important}}@media screen and (min-width:40em) and (max-width:63.9375em){.hide-for-medium-only{display:none!important}}@media screen and (max-width:39.9375em),screen and (min-width:64em){.show-for-medium-only{display:none!important}}@media screen and (min-width:64em){.hide-for-large{display:none!important}}@media screen and (max-width:63.9375em){.show-for-large{display:none!important}}@media screen and (min-width:64em) and (max-width:74.9375em){.hide-for-large-only{display:none!important}}@media screen and (max-width:63.9375em),screen and (min-width:75em){.show-for-large-only{display:none!important}}.show-for-sr,.show-on-focus{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}.show-on-focus:active,.show-on-focus:focus{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hide-for-portrait,.show-for-landscape{display:block!important}@media screen and (orientation:landscape){.hide-for-portrait,.show-for-landscape{display:block!important}}@media screen and (orientation:portrait){.hide-for-portrait,.show-for-landscape{display:none!important}}.hide-for-landscape,.show-for-portrait{display:none!important}@media screen and (orientation:landscape){.hide-for-landscape,.show-for-portrait{display:none!important}}@media screen and (orientation:portrait){.hide-for-landscape,.show-for-portrait{display:block!important}}.float-left{float:left!important}.float-right{float:right!important}.float-center{display:block;margin-left:auto;margin-right:auto}.clearfix:after,.clearfix:before{content:' ';display:table}.clearfix:after{clear:both}.slide-in-down.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:translateY(-100%);transform:translateY(-100%);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-in-down.mui-enter.mui-enter-active{-webkit-transform:translateY(0);transform:translateY(0)}.slide-in-left.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:translateX(-100%);transform:translateX(-100%);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-in-left.mui-enter.mui-enter-active{-webkit-transform:translateX(0);transform:translateX(0)}.slide-in-up.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:translateY(100%);transform:translateY(100%);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-in-up.mui-enter.mui-enter-active{-webkit-transform:translateY(0);transform:translateY(0)}.slide-in-right.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:translateX(100%);transform:translateX(100%);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-in-right.mui-enter.mui-enter-active{-webkit-transform:translateX(0);transform:translateX(0)}.slide-out-down.mui-leave{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:translateY(0);transform:translateY(0);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-out-down.mui-leave.mui-leave-active{-webkit-transform:translateY(100%);transform:translateY(100%)}.slide-out-right.mui-leave{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:translateX(0);transform:translateX(0);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-out-right.mui-leave.mui-leave-active{-webkit-transform:translateX(100%);transform:translateX(100%)}.slide-out-up.mui-leave{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:translateY(0);transform:translateY(0);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-out-up.mui-leave.mui-leave-active{-webkit-transform:translateY(-100%);transform:translateY(-100%)}.slide-out-left.mui-leave{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:translateX(0);transform:translateX(0);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-out-left.mui-leave.mui-leave-active{-webkit-transform:translateX(-100%);transform:translateX(-100%)}.fade-in.mui-enter{transition-duration:.5s;transition-timing-function:linear;opacity:0;transition-property:opacity}.fade-in.mui-enter.mui-enter-active{opacity:1}.fade-out.mui-leave{transition-duration:.5s;transition-timing-function:linear;opacity:1;transition-property:opacity}.fade-out.mui-leave.mui-leave-active{opacity:0}.hinge-in-from-top.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);-webkit-transform-origin:top;transform-origin:top;transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:0}.hinge-in-from-top.mui-enter.mui-enter-active{-webkit-transform:perspective(2000px) rotate(0deg);transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-in-from-right.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:perspective(2000px) rotateY(-90deg);transform:perspective(2000px) rotateY(-90deg);-webkit-transform-origin:right;transform-origin:right;transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:0}.hinge-in-from-right.mui-enter.mui-enter-active{-webkit-transform:perspective(2000px) rotate(0deg);transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-in-from-bottom.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:perspective(2000px) rotateX(90deg);transform:perspective(2000px) rotateX(90deg);-webkit-transform-origin:bottom;transform-origin:bottom;transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:0}.hinge-in-from-bottom.mui-enter.mui-enter-active{-webkit-transform:perspective(2000px) rotate(0deg);transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-in-from-left.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:perspective(2000px) rotateY(90deg);transform:perspective(2000px) rotateY(90deg);-webkit-transform-origin:left;transform-origin:left;transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:0}.hinge-in-from-left.mui-enter.mui-enter-active{-webkit-transform:perspective(2000px) rotate(0deg);transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-in-from-middle-x.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);-webkit-transform-origin:center;transform-origin:center;transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:0}.hinge-in-from-middle-x.mui-enter.mui-enter-active{-webkit-transform:perspective(2000px) rotate(0deg);transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-in-from-middle-y.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:perspective(2000px) rotateY(-90deg);transform:perspective(2000px) rotateY(-90deg);-webkit-transform-origin:center;transform-origin:center;transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:0}.hinge-in-from-middle-y.mui-enter.mui-enter-active,.hinge-out-from-top.mui-leave{-webkit-transform:perspective(2000px) rotate(0deg);transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-out-from-top.mui-leave{transition-duration:.5s;transition-timing-function:linear;-webkit-transform-origin:top;transform-origin:top;transition-property:-webkit-transform,opacity;transition-property:transform,opacity}.hinge-out-from-top.mui-leave.mui-leave-active{-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);opacity:0}.hinge-out-from-right.mui-leave{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:perspective(2000px) rotate(0deg);transform:perspective(2000px) rotate(0deg);-webkit-transform-origin:right;transform-origin:right;transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:1}.hinge-out-from-right.mui-leave.mui-leave-active{-webkit-transform:perspective(2000px) rotateY(-90deg);transform:perspective(2000px) rotateY(-90deg);opacity:0}.hinge-out-from-bottom.mui-leave{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:perspective(2000px) rotate(0deg);transform:perspective(2000px) rotate(0deg);-webkit-transform-origin:bottom;transform-origin:bottom;transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:1}.hinge-out-from-bottom.mui-leave.mui-leave-active{-webkit-transform:perspective(2000px) rotateX(90deg);transform:perspective(2000px) rotateX(90deg);opacity:0}.hinge-out-from-left.mui-leave{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:perspective(2000px) rotate(0deg);transform:perspective(2000px) rotate(0deg);-webkit-transform-origin:left;transform-origin:left;transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:1}.hinge-out-from-left.mui-leave.mui-leave-active{-webkit-transform:perspective(2000px) rotateY(90deg);transform:perspective(2000px) rotateY(90deg);opacity:0}.hinge-out-from-middle-x.mui-leave{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:perspective(2000px) rotate(0deg);transform:perspective(2000px) rotate(0deg);-webkit-transform-origin:center;transform-origin:center;transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:1}.hinge-out-from-middle-x.mui-leave.mui-leave-active{-webkit-transform:perspective(2000px) rotateX(-90deg);transform:perspective(2000px) rotateX(-90deg);opacity:0}.hinge-out-from-middle-y.mui-leave{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:perspective(2000px) rotate(0deg);transform:perspective(2000px) rotate(0deg);-webkit-transform-origin:center;transform-origin:center;transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:1}.hinge-out-from-middle-y.mui-leave.mui-leave-active{-webkit-transform:perspective(2000px) rotateY(-90deg);transform:perspective(2000px) rotateY(-90deg);opacity:0}.scale-in-up.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:scale(.5);transform:scale(.5);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:0}.scale-in-up.mui-enter.mui-enter-active{-webkit-transform:scale(1);transform:scale(1);opacity:1}.scale-in-down.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:scale(1.5);transform:scale(1.5);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:0}.scale-in-down.mui-enter.mui-enter-active,.scale-out-up.mui-leave{-webkit-transform:scale(1);transform:scale(1);opacity:1}.scale-out-up.mui-leave{transition-duration:.5s;transition-timing-function:linear;transition-property:-webkit-transform,opacity;transition-property:transform,opacity}.scale-out-up.mui-leave.mui-leave-active{-webkit-transform:scale(1.5);transform:scale(1.5);opacity:0}.scale-out-down.mui-leave{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:scale(1);transform:scale(1);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:1}.scale-out-down.mui-leave.mui-leave-active{-webkit-transform:scale(.5);transform:scale(.5);opacity:0}.spin-in.mui-enter{transition-duration:.5s;transition-timing-function:linear;-webkit-transform:rotate(-270deg);transform:rotate(-270deg);transition-property:-webkit-transform,opacity;transition-property:transform,opacity;opacity:0}.spin-in.mui-enter.mui-enter-active,.spin-out.mui-leave{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}.spin-out.mui-leave{transition-duration:.5s;transition-timing-function:linear;transition-property:-webkit-transform,opacity;transition-property:transform,opacity}.spin-in-ccw.mui-enter,.spin-out.mui-leave.mui-leave-active{-webkit-transform:rotate(270deg);transform:rotate(270deg);opacity:0}.spin-in-ccw.mui-enter{transition-duration:.5s;transition-timing-function:linear;transition-property:-webkit-transform,opacity;transition-property:transform,opacity}.spin-in-ccw.mui-enter.mui-enter-active,.spin-out-ccw.mui-leave{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}.spin-out-ccw.mui-leave{transition-duration:.5s;transition-timing-function:linear;transition-property:-webkit-transform,opacity;transition-property:transform,opacity}.spin-out-ccw.mui-leave.mui-leave-active{-webkit-transform:rotate(-270deg);transform:rotate(-270deg);opacity:0}.slow{transition-duration:.75s!important}.fast{transition-duration:.25s!important}.linear{transition-timing-function:linear!important}.ease{transition-timing-function:ease!important}.ease-in{transition-timing-function:ease-in!important}.ease-out{transition-timing-function:ease-out!important}.ease-in-out{transition-timing-function:ease-in-out!important}.bounce-in{transition-timing-function:cubic-bezier(.485,.155,.24,1.245)!important}.bounce-out{transition-timing-function:cubic-bezier(.485,.155,.515,.845)!important}.bounce-in-out{transition-timing-function:cubic-bezier(.76,-.245,.24,1.245)!important}.short-delay{transition-delay:.3s!important}.long-delay{transition-delay:.7s!important}.shake{-webkit-animation-name:a;animation-name:a}@-webkit-keyframes a{0%,10%,20%,30%,40%,50%,60%,70%,80%,90%{-webkit-transform:translateX(7%);transform:translateX(7%)}5%,15%,25%,35%,45%,55%,65%,75%,85%,95%{-webkit-transform:translateX(-7%);transform:translateX(-7%)}}@keyframes a{0%,10%,20%,30%,40%,50%,60%,70%,80%,90%{-webkit-transform:translateX(7%);transform:translateX(7%)}5%,15%,25%,35%,45%,55%,65%,75%,85%,95%{-webkit-transform:translateX(-7%);transform:translateX(-7%)}}.spin-cw{-webkit-animation-name:b;animation-name:b}@-webkit-keyframes b{0%{-webkit-transform:rotate(-1turn);transform:rotate(-1turn)}to{-webkit-transform:rotate(0);transform:rotate(0)}}@keyframes b{0%{-webkit-transform:rotate(-1turn);transform:rotate(-1turn)}to{-webkit-transform:rotate(0);transform:rotate(0)}}.spin-ccw{-webkit-animation-name:b;animation-name:b}@keyframes b{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.wiggle{-webkit-animation-name:c;animation-name:c}@-webkit-keyframes c{40%,50%,60%{-webkit-transform:rotate(7deg);transform:rotate(7deg)}35%,45%,55%,65%{-webkit-transform:rotate(-7deg);transform:rotate(-7deg)}0%,30%,70%,to{-webkit-transform:rotate(0);transform:rotate(0)}}@keyframes c{40%,50%,60%{-webkit-transform:rotate(7deg);transform:rotate(7deg)}35%,45%,55%,65%{-webkit-transform:rotate(-7deg);transform:rotate(-7deg)}0%,30%,70%,to{-webkit-transform:rotate(0);transform:rotate(0)}}.shake,.spin-ccw,.spin-cw,.wiggle{-webkit-animation-duration:.5s;animation-duration:.5s}.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.slow{-webkit-animation-duration:.75s!important;animation-duration:.75s!important}.fast{-webkit-animation-duration:.25s!important;animation-duration:.25s!important}.linear{-webkit-animation-timing-function:linear!important;animation-timing-function:linear!important}.ease{-webkit-animation-timing-function:ease!important;animation-timing-function:ease!important}.ease-in{-webkit-animation-timing-function:ease-in!important;animation-timing-function:ease-in!important}.ease-out{-webkit-animation-timing-function:ease-out!important;animation-timing-function:ease-out!important}.ease-in-out{-webkit-animation-timing-function:ease-in-out!important;animation-timing-function:ease-in-out!important}.bounce-in{-webkit-animation-timing-function:cubic-bezier(.485,.155,.24,1.245)!important;animation-timing-function:cubic-bezier(.485,.155,.24,1.245)!important}.bounce-out{-webkit-animation-timing-function:cubic-bezier(.485,.155,.515,.845)!important;animation-timing-function:cubic-bezier(.485,.155,.515,.845)!important}.bounce-in-out{-webkit-animation-timing-function:cubic-bezier(.76,-.245,.24,1.245)!important;animation-timing-function:cubic-bezier(.76,-.245,.24,1.245)!important}.short-delay{-webkit-animation-delay:.3s!important;animation-delay:.3s!important}.long-delay{-webkit-animation-delay:.7s!important;animation-delay:.7s!important} \ No newline at end of file diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss new file mode 100644 index 0000000000..a0d94c17c1 --- /dev/null +++ b/app/assets/stylesheets/main.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the main controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/merchants.scss b/app/assets/stylesheets/merchants.scss new file mode 100644 index 0000000000..f4c164d600 --- /dev/null +++ b/app/assets/stylesheets/merchants.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Merchants controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/order_items.scss b/app/assets/stylesheets/order_items.scss new file mode 100644 index 0000000000..584862de9b --- /dev/null +++ b/app/assets/stylesheets/order_items.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the OrderItems controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/orders.scss b/app/assets/stylesheets/orders.scss new file mode 100644 index 0000000000..7bbeaca8dc --- /dev/null +++ b/app/assets/stylesheets/orders.scss @@ -0,0 +1,7 @@ +// Place all the styles related to the Orders controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ + +

{ + font-family: 'Josefin Slab', serif; +} diff --git a/app/assets/stylesheets/product_categories.scss b/app/assets/stylesheets/product_categories.scss new file mode 100644 index 0000000000..6e23ff2c67 --- /dev/null +++ b/app/assets/stylesheets/product_categories.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the ProductCategories controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/products.scss b/app/assets/stylesheets/products.scss new file mode 100644 index 0000000000..bff386e55a --- /dev/null +++ b/app/assets/stylesheets/products.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Products controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/reviews.scss b/app/assets/stylesheets/reviews.scss new file mode 100644 index 0000000000..11bbb12cd5 --- /dev/null +++ b/app/assets/stylesheets/reviews.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Reviews controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/sessions.scss b/app/assets/stylesheets/sessions.scss new file mode 100644 index 0000000000..7bef9cf826 --- /dev/null +++ b/app/assets/stylesheets/sessions.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the sessions controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d83690e1b9..76a5e80674 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,4 +2,31 @@ class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception + +private + def current_user + begin + @current_user ||= Merchant.find(session[:user_id]) if session[:user_id] + rescue ActiveRecord::RecordNotFound + @current_user = nil + end + end + + def require_login + if current_user.nil? + flash[:error] = "Please log in to continue." + redirect_to root_path + end + end + + # faking an order! + def current_order + begin + @current_order_id = session[:order_id] + #we can fake this by setting it to 6 + # @current_order_id = 6 + rescue ActiveRecord::RecordNotFound + @current_order_id = nil + end + end end diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb new file mode 100644 index 0000000000..692f229e53 --- /dev/null +++ b/app/controllers/categories_controller.rb @@ -0,0 +1,44 @@ +class CategoriesController < ApplicationController + before_action :category_exist?, only: [:show] + before_action :current_order + + def index + @all_categories = Category.all + end + + def show + @products_by_category = @category.products + end + + #TODO NEW AND CREATE SHOULD BE ONLY AUTHOURIZED FOR VIEW BY MERCHANTS + def new #route here from creating a new product + @category = Category.new + end + + def create + @category = Category.new(category_params) + + if @category.save + redirect_to new_merchant_product_path(session[:user_id]) + else + render :new + end + end + + + private + + def category_params + params.require(:category).permit(:name, :description, :photo_url) + end + + def category_exist? + #exception handeling: + begin + @category = Category.find(params[:id]) + rescue ActiveRecord::RecordNotFound + redirect_to "/errors/category_not_found" + return + end + end +end diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb new file mode 100644 index 0000000000..3e249ac3d0 --- /dev/null +++ b/app/controllers/main_controller.rb @@ -0,0 +1,5 @@ +class MainController < ApplicationController + before_action :current_order + def index; end + +end diff --git a/app/controllers/merchants_controller.rb b/app/controllers/merchants_controller.rb new file mode 100644 index 0000000000..95bc69ff7e --- /dev/null +++ b/app/controllers/merchants_controller.rb @@ -0,0 +1,42 @@ +class MerchantsController < ApplicationController + before_action :current_order + + def index + @merchants = Merchant.all + end + + def show + current_user + @merchant = Merchant.find(params[:id]) + + @cumulative_revenue = 0 + @merchant.products.each do |product| + @total_revenue = 0 + @item = OrderItem.where(product_id: product.id) + @price = product.price + @item.each do |i| + @revenue = i.quantity * @price + @total_revenue += @revenue + end + @cumulative_revenue += @total_revenue + end + # + # @revenue = {} + # @order_items.each do |item| + # @prdct = Product.find(item.product_id) + # merchant = @prdct.merchant_id + # price = @prdct.price + # quantity = item.quantity + # @item_revenue = price * quantity + # @revenue[merchant] = @item_revenue + # end + + if @current_user == nil || @current_user != @merchant + @user_page = false + else + @user_page = true + end + + end + +end diff --git a/app/controllers/order_items_controller.rb b/app/controllers/order_items_controller.rb new file mode 100644 index 0000000000..f694ca85dd --- /dev/null +++ b/app/controllers/order_items_controller.rb @@ -0,0 +1,73 @@ +class OrderItemsController < ApplicationController + + before_action :current_order + # def create + # + # end +# method creates one order item (adds one of product item to order) + def create + + # # @order = Order.find_by(id: params[:order_id].to_i) + # @order_id = params[:order_id] + # @product_id = params[:product_id] + # # @product = params[:product] + # params = {order_id: @order_id product_id: @product_id, quantity: 1} + # raise + # @order_item = @product.order_items.new(order_item_params(params)) + # if @order_item.save + # # SUCCESS remove item from product stock + # redirect_to product_path(@product) + # else + # # render # same but with flash message? + # # if we removed item from product stock then replace it + # # NO SUCCESS + # end + # + # + # # if Order.where(id: params[:id]).length == 0 + # # new_order = Order.new # with those params + # # new_order.save + # # end + # + # # @todo RETURN WITH PARAMS + # + # # raise + # # redirect_to product_path(params[:id]) + end +# # +# # # Talk about the routes +# # def update +# # @order_item = OrderItem.find(params[:id].to_i) +# # @quantity_available = Product.find(@order_item.product_id).stock_quantity +# # if @order_item.quantity > @quantity_available +# # raise "You may not add a quantity to the order that is greater than the stock quantity." +# # elsif @order_item.save +# # redirect_to order_path +# # # I think there needs to be a parameter here, but what is it? It is not the one displayed because that is associated with the OrderItem. +# # else +# # redirect_to order_item_path(params[:id].to_i) +# # end +# # end +# # +# # def destroy +# # order_status = Order.find(OrderItem.find(params[:id].to_i).product_id).status +# # order_count = OrderItem.where(params[:id].to_i).product_id).length +# # if order_status == "paid" || order_status == "completed" || order_status == "cancelled" +# # raise "You can't delete an item that has already been paid for" +# # elsif order_count = 1 +# # Order.find(OrderItem.find(params[:id].to_i).product_id).cancelled +# # +# # else +# # redirect_to :action=> :index +# # end +# # end +# # +# # +# # +# # + private + def order_item_params(params) + params.permit! + # params.require(:order_item).permit(:quantity) + end +end diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb new file mode 100644 index 0000000000..881c6e5595 --- /dev/null +++ b/app/controllers/orders_controller.rb @@ -0,0 +1,84 @@ +class OrdersController < ApplicationController + before_action :current_order + + + def create + # if session[:order_id] != nil + # render :update + # return + # else + @product = Product.find_by(id: params[:product_id].to_i) + @order = Order.new + @order.status = "pending" + if @order.save + OrderItem.create_order_item(@product, @order) + session[:order_id] = @order.id + redirect_to product_path(@product) # might redirect to cart + else + flash[:notice] = "Sorry, something that wasn't supposed to happen, happened." + redirect_to product_path(@product.id) + end + # end #session + end + + def show + current_user + @order = Order.find(params[:id]) + @order_items = OrderItem.where(order_id: @order.id) + @revenue = {} + @total_revenue = 0 + @order_items.each do |item| + @prdct = Product.find(item.product_id) + @price = @prdct.price + @quantity = item.quantity + @item_revenue = (@price * @quantity) + @total_revenue = @item_revenue + @total_revenue + end + end + + + def checkout + # Edit order, is more like, edit the contact information of the user in the cart. This will be called when they go to checkout their order. + @order = Order.find(params[:id]) + end + + def update + order_id = @current_order_id + @order = Order.find(order_id) + if @order.status == "pending" + #SUCCESS + @product = Product.find(params[:product_id]) + if OrderItem.update_order_item(@product, @order) != false + @order.save ? flash[:notice] = "Your order is saved" : flash[:notice] = "Your order did not save" + else + flash[:notice] = "Sorry, this order is not valid" + redirect_to products_path + return + end + redirect_to order_path(@order) + else #(not pending) + flash[:notice] = "Sorry, this order is not valid" + redirect_to products_path + end #pending + end + + def pay + @order = Order.find(params[:id]) + if @order.update(order_params) + # delete your order_id out of session so that you can make another order! + @order.purchase_time = DateTime.now + @order.save + session.delete(:order_id) + + flash[:notice] = "Thank you for placing your order with BasketCase. Please come again soon!" + redirect_to order_path(params[:id]) + else + redirect_to root_path + end + end + + private + def order_params + params.require(:order).permit(:name, :email, :mailing_address, :cc_last_4, :cc_expire, :status, ) + end +end diff --git a/app/controllers/product_categories_controller.rb b/app/controllers/product_categories_controller.rb new file mode 100644 index 0000000000..db060d6370 --- /dev/null +++ b/app/controllers/product_categories_controller.rb @@ -0,0 +1,33 @@ +class ProductCategoriesController < ApplicationController + before_action :current_order + + def new + @all_categories = Category.all + @product_category = ProductCategory.new + end + + def create + category_ids = product_category_params[:category_ids] + product_id = product_category_params[:product_id] + + unless category_ids.nil? + category_ids.each do | category_id | + product_category = ProductCategory.new(product_id: product_id) + product_category.category_id = category_id + product_category.save + end + end + + redirect_to products_path + end + + private + + def product_category_params + # XXX SKY: This is a nasty hack :( fix it some day + # Pretty sure we should be able to get the generated form to organize + # the data this way, but not sure how + params[:product_category] = {product_id: params[:product_id], category_ids: params[:category_ids]} + params.require(:product_category).permit(:product_id, category_ids: []) + end +end diff --git a/app/controllers/products_controller.rb b/app/controllers/products_controller.rb new file mode 100644 index 0000000000..b38cc6086e --- /dev/null +++ b/app/controllers/products_controller.rb @@ -0,0 +1,115 @@ +class ProductsController < ApplicationController + before_action :current_order + # before_action :check_user, only: [:edit, :update, :retired] + + def index + if params[:merchant_id] == nil + #shows all the products in the site + @products = Product.all + elsif params[:merchant_id] + # a view of products for a merchant + merchant_id = params[:merchant_id] + @merchant = Merchant.find(merchant_id) + @products = Product.where(merchant_id: merchant_id) + end + end + + def show + current_user + # This is the individual product page + @product = Product.find(params[:id]) + @categories = @product.categories + + # If user is not logged in OR user is not the owner of the product, show them the add review/add to cart button. If they are the owner, show them the edit link. + if @current_user == nil || @current_user.id != @product.merchant_id + @user_page = false + else + @user_page = true + end + end + + def new + # This should only be visible to logged in users. + # Within the context of a merchant, a form to create a new product. + # If you're not logged in (e.g. @current_user = nil, display a login prompt) + current_user + # TODO: Need to add in checking if @current_user is nil (not logged in) + if @current_user == nil + redirect_to login_failure_path + else + @merchant = @current_user + @product = @merchant.products.new + end + @all_categories = Category.all + end + + def create + current_user + # Within the context of a merchant, post the form from new. + @all_categories = Category.all + + if @current_user == nil + redirect_to login_failure_path + else + @merchant = Merchant.find(@current_user.id) + + @product = @merchant.products.new(product_params) + + if @product.save(product_params) + redirect_to new_product_product_category_path(@product.id) + return + else + render :new + end + end + end + + def edit + current_user + check_user + @product = Product.find(params[:id]) + + end + + + def update + current_user + # This is the PATCH call when a merchant updates their product + @product = Product.find(params[:id]) + + @merchant = Merchant.find(@product.merchant_id) + + # if @merchant != @current_user + # # display some message and re-route to @current_user's page? + # elsif @current_user == nil + # # redirect to login page. + # end + + if @product.update(product_params) + redirect_to merchant_path(@merchant.id) + else + render :edit + end + + end + + def retired + # TODO: This is the PATCH call when a merchant retires a product + end + + private + def product_params + params.require(:product).permit(:name, :price, :stock_quantity, :description, :photo_url) + end + private + + def check_user + if @current_user == nil + flash[:notice] = "You need to log in to edit this." + redirect_to product_path(Product.find(params[:id])) + elsif !@current_user.products.include? Product.find(params[:id]) + flash[:notice] = "You cannot edit this product; it doesn't belong to you." + redirect_to product_path(Product.find(params[:id])) + end + end +end diff --git a/app/controllers/reviews_controller.rb b/app/controllers/reviews_controller.rb new file mode 100644 index 0000000000..cb7f1d3c45 --- /dev/null +++ b/app/controllers/reviews_controller.rb @@ -0,0 +1,53 @@ +class ReviewsController < ApplicationController + before_action :current_order + def index + @reviews_by_product = Review.where(product_id: params[:product_id]) + product_id = params[:product_id] + if @reviews_by_product.first == nil + redirect_to product_path(product_id) + else + @product = @reviews_by_product.first.product + end + end + + def show + #TODO REMOVE IF WE AREN'T GOING TO USE THIS!!!!! + end + + def new + current_user + product = Product.find(params[:product_id]) + + if @current_user.nil? || @current_user.id != product.merchant_id + @review = Review.new + else + flash[:notice] = "You cannot write a review for your own product." + redirect_to product_path(product.id) + end + end + + def create + #exception handeling: + begin + @product = Product.find(params[:product_id]) + rescue ActiveRecord::RecordNotFound + render "/errors/product_not_found" + return + end + + @review = Review.new(review_params) + @product.reviews << @review + if @review.save + redirect_to product_reviews_path + else + render :new + end + end + + + private + + def review_params + params.require(:review).permit(:rating, :title, :body) + end +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000000..e41dad3108 --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,32 @@ +class SessionsController < ApplicationController + before_action :current_order + def index + @user = Merchant.find(session[:user_id]) # < recalls the value set in a previous request + end + + def create + auth_hash = request.env['omniauth.auth'] + redirect_to login_failure_path if auth_hash['uid'].nil? + + @user = Merchant.find_by(uid: auth_hash[:uid], provider: 'google') + if @user.nil? + # User doesn't match anything in the DB. + # Attempt to create a new user. + @user = Merchant.build_from_google(auth_hash) + unless @user.save + render :login_failure + return + end + end + + # Save the user ID in the session + session[:user_id] = @user.id + redirect_to merchant_path(session[:user_id]) + end + + def destroy + session.delete(:user_id) + redirect_to root_path + end + +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6be7945c..37e51538dd 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,2 +1,6 @@ module ApplicationHelper + + def money_format(cents) + sprintf("$%0.02f", cents/100.to_f) + end end diff --git a/app/helpers/categories_helper.rb b/app/helpers/categories_helper.rb new file mode 100644 index 0000000000..e06f31554c --- /dev/null +++ b/app/helpers/categories_helper.rb @@ -0,0 +1,2 @@ +module CategoriesHelper +end diff --git a/app/helpers/main_helper.rb b/app/helpers/main_helper.rb new file mode 100644 index 0000000000..826effed96 --- /dev/null +++ b/app/helpers/main_helper.rb @@ -0,0 +1,2 @@ +module MainHelper +end diff --git a/app/helpers/merchants_helper.rb b/app/helpers/merchants_helper.rb new file mode 100644 index 0000000000..5337747b0f --- /dev/null +++ b/app/helpers/merchants_helper.rb @@ -0,0 +1,2 @@ +module MerchantsHelper +end diff --git a/app/helpers/order_items_helper.rb b/app/helpers/order_items_helper.rb new file mode 100644 index 0000000000..e197528ae1 --- /dev/null +++ b/app/helpers/order_items_helper.rb @@ -0,0 +1,2 @@ +module OrderItemsHelper +end diff --git a/app/helpers/orders_helper.rb b/app/helpers/orders_helper.rb new file mode 100644 index 0000000000..443227fd48 --- /dev/null +++ b/app/helpers/orders_helper.rb @@ -0,0 +1,2 @@ +module OrdersHelper +end diff --git a/app/helpers/product_categories_helper.rb b/app/helpers/product_categories_helper.rb new file mode 100644 index 0000000000..99470b5068 --- /dev/null +++ b/app/helpers/product_categories_helper.rb @@ -0,0 +1,2 @@ +module ProductCategoriesHelper +end diff --git a/app/helpers/products_helper.rb b/app/helpers/products_helper.rb new file mode 100644 index 0000000000..ab5c42b325 --- /dev/null +++ b/app/helpers/products_helper.rb @@ -0,0 +1,2 @@ +module ProductsHelper +end diff --git a/app/helpers/reviews_helper.rb b/app/helpers/reviews_helper.rb new file mode 100644 index 0000000000..682b7b1abc --- /dev/null +++ b/app/helpers/reviews_helper.rb @@ -0,0 +1,2 @@ +module ReviewsHelper +end diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb new file mode 100644 index 0000000000..309f8b2eb3 --- /dev/null +++ b/app/helpers/sessions_helper.rb @@ -0,0 +1,2 @@ +module SessionsHelper +end diff --git a/app/models/category.rb b/app/models/category.rb new file mode 100644 index 0000000000..c99fcbc6a8 --- /dev/null +++ b/app/models/category.rb @@ -0,0 +1,7 @@ +class Category < ActiveRecord::Base + has_many :product_categories + has_many :products, :through => :product_categories + + validates :name, presence: true, uniqueness: true + validates :photo_url, presence: true +end diff --git a/app/models/merchant.rb b/app/models/merchant.rb new file mode 100644 index 0000000000..6943292974 --- /dev/null +++ b/app/models/merchant.rb @@ -0,0 +1,19 @@ +class Merchant < ActiveRecord::Base + has_many :products + + validates :name, presence: true, uniqueness: true + validates :email, presence: true, uniqueness: true + + validates :uid, :provider, presence: true + + def self.build_from_google(auth_hash) + user = Merchant.new + user.uid = auth_hash[:uid] + user.provider = 'google' + user.name = auth_hash['info']['name'] + user.email = auth_hash['info']['email'] + + return user + end + +end diff --git a/app/models/order.rb b/app/models/order.rb new file mode 100644 index 0000000000..b98cd63252 --- /dev/null +++ b/app/models/order.rb @@ -0,0 +1,20 @@ +class Order < ActiveRecord::Base + has_many :order_items + has_many :products, :through => :order_items + + # validates :order_items, presence: true + # REMOVING ORDER_ITEMS validates or else we have a chicken and egg scenario. + # validates :order_items, :length => { :minimum => 1 } + + + validates :status, :presence => true, inclusion: { in: %w(pending paid completed cancelled) } + +private + def card_adjust(cc_last_4) + + end + # validates :name + # validates :email + # validates_length_of :cc_last_4, :is => 4, #should this be an integer + # validates :cc_expire +end diff --git a/app/models/order_item.rb b/app/models/order_item.rb new file mode 100644 index 0000000000..112153be95 --- /dev/null +++ b/app/models/order_item.rb @@ -0,0 +1,40 @@ +class OrderItem < ActiveRecord::Base + belongs_to :product + belongs_to :order + validates :quantity, presence: true, numericality: { only_integer: true, greater_than: 0 } + validates :product, presence: true + # validates_inclusion_of :product_id, :in => Product.all.pluck(:id) + validates :order, presence: true + + def self.create_order_item(product, order) + order_item = product.order_items.new(quantity: 1) + order_item.order_id = order.id + if order_item.save + return order_item + else + return false + end + end + + def self.update_order_item(product, order) + if order == nil || product == nil + return false + end + + if order.products.length >= 1 + #UPDATE PATH + OrderItem.where(order_id: order.id).each do |item| + if product.id == item[:product_id] + item[:quantity] += 1 + if item.save + return item + end + end + end + end #order.count + # SUCCESS, but we need to add a new order_item + # CREATE PATH + return OrderItem.create_order_item(product,order) # returns the new order item + end + +end diff --git a/app/models/product.rb b/app/models/product.rb new file mode 100644 index 0000000000..f101c52e79 --- /dev/null +++ b/app/models/product.rb @@ -0,0 +1,28 @@ +class Product < ActiveRecord::Base + has_many :reviews + belongs_to :merchant + + has_many :order_items + has_many :orders, :through => :order_items + + has_many :product_categories + + # The way to do a nested form (this might just not be working because there's no create product_categories action) + accepts_nested_attributes_for :product_categories + + has_many :categories, :through => :product_categories + + validates :name, presence: true, uniqueness: true + + validates :price, presence: true, numericality: { only_integer: true, greater_than: 0 } + + # Having product require at least one category before being saved to the database is making it impossible to create new products (chicken/egg problem), so I'm commenting it out for now. + # + # validates :categories, :length => { :minimum => 1 } + + validates :merchant, :presence => true + + # Same here - I think this is important to have validated (cannot have negative stock.) + validates :stock_quantity, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 } + +end diff --git a/app/models/product_category.rb b/app/models/product_category.rb new file mode 100644 index 0000000000..9f66674499 --- /dev/null +++ b/app/models/product_category.rb @@ -0,0 +1,4 @@ +class ProductCategory < ActiveRecord::Base + belongs_to :product + belongs_to :category +end diff --git a/app/models/review.rb b/app/models/review.rb new file mode 100644 index 0000000000..87c4e258a0 --- /dev/null +++ b/app/models/review.rb @@ -0,0 +1,6 @@ +class Review < ActiveRecord::Base + belongs_to :product + + validates :product, :presence => true + validates :rating, presence: true, :numericality => {only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: 5} +end diff --git a/app/views/categories/_form.html.erb b/app/views/categories/_form.html.erb new file mode 100644 index 0000000000..c836f7e7b9 --- /dev/null +++ b/app/views/categories/_form.html.erb @@ -0,0 +1,31 @@ +<% if @category.errors.any? %> +

+<% end %> + +<%= form_for @category, class: 'add-form', html: {class: 'form'}, url: submit_url, method:http_method do |f| %> +
+ <%= f.label :name, "Category Name(required)" %> + <%= f.text_field :name %> +
+ +
+ <%= f.label :description, "Description:" %> + <%= f.text_field :description %> +
+ +
+ <%= f.label :photo_url, "Image URL(required):" %> + <%= f.text_field :photo_url %> +
+ +
+ <%= f.submit "Create a Category", :class => 'button' %> +
+ +<% end %> diff --git a/app/views/categories/index.html.erb b/app/views/categories/index.html.erb new file mode 100644 index 0000000000..53c4e22e94 --- /dev/null +++ b/app/views/categories/index.html.erb @@ -0,0 +1,14 @@ +
+
+

Product Categories

+
+ + +
diff --git a/app/views/categories/new.html.erb b/app/views/categories/new.html.erb new file mode 100644 index 0000000000..0ed7063d93 --- /dev/null +++ b/app/views/categories/new.html.erb @@ -0,0 +1,11 @@ +
+
+

Add a New Category

+
+ +
+ <%= render partial: "form", locals: { submit_url: categories_path, http_method: :post } %> +
+ +
Don't want to add a category, <%= link_to "Go to All Categories", categories_path %>
+
diff --git a/app/views/categories/show.html.erb b/app/views/categories/show.html.erb new file mode 100644 index 0000000000..c5d5e3a3a2 --- /dev/null +++ b/app/views/categories/show.html.erb @@ -0,0 +1,18 @@ +
+
+

<%= @category.name %>

+
+ +
+ <%= link_to "#{image_tag(@category.photo_url)}".html_safe, category_path, class: "category-img" %> +
+ + +
diff --git a/app/views/errors/category_not_found.html.erb b/app/views/errors/category_not_found.html.erb new file mode 100644 index 0000000000..c89b9da327 --- /dev/null +++ b/app/views/errors/category_not_found.html.erb @@ -0,0 +1,7 @@ +
+
+

This category doesn't exist.

+ + <%= link_to "Go Back to all Categories", categories_path %> +
+
diff --git a/app/views/errors/product_not_found.html.erb b/app/views/errors/product_not_found.html.erb new file mode 100644 index 0000000000..e4682cba07 --- /dev/null +++ b/app/views/errors/product_not_found.html.erb @@ -0,0 +1,7 @@ +
+
+

This product doesn't exist.

+
+ + <%= link_to "Go Back to all Products", products_path %> +
diff --git a/app/views/errors/wrong_user.html.erb b/app/views/errors/wrong_user.html.erb new file mode 100644 index 0000000000..ccfae01947 --- /dev/null +++ b/app/views/errors/wrong_user.html.erb @@ -0,0 +1,7 @@ +
+
+

This page doesn't belong to you.

+ + <%= link_to "Go Back to Your Merchant Portal", merchant_path(@current_user.id) %> +
+
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 9b70e01c2e..b78f1ec70d 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -1,14 +1,60 @@ - Betsy + BasketCase <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> <%= csrf_meta_tags %> + + +
+
+ +
-<%= yield %> +
+

<%= link_to "BasketCase", root_path%>

+

- - the go-to site for all things picnic! - -

+
+
+
+ +
+
+
+ + <%= yield %> diff --git a/app/views/main/index.html.erb b/app/views/main/index.html.erb new file mode 100644 index 0000000000..f6020b568c --- /dev/null +++ b/app/views/main/index.html.erb @@ -0,0 +1,5 @@ +
+
+ <%= image_tag 'basket.jpg' %> +
+
diff --git a/app/views/merchants/index.html.erb b/app/views/merchants/index.html.erb new file mode 100644 index 0000000000..8f60a93b56 --- /dev/null +++ b/app/views/merchants/index.html.erb @@ -0,0 +1,23 @@ +
+
+
+

All Mechants

+
+
+ +
+
    + <% @merchants.each do |merchant| %> +
  • + <%= link_to "#{merchant.name}", merchant_path(merchant) %> +
  • + <% end %> +
+ +
    +
  • + <%= image_tag "merchant-strawberries.jpg", class: "merchant-img" %> +
  • +
+
+
diff --git a/app/views/merchants/show.html.erb b/app/views/merchants/show.html.erb new file mode 100644 index 0000000000..f3b926484a --- /dev/null +++ b/app/views/merchants/show.html.erb @@ -0,0 +1,75 @@ +
+

+ <%= @merchant.name %> +

+ + <% if @user_page == true %> +

+ <%= "Welcome to your Merchant Page, #{@merchant.name}." %> +

+ +
+
Total Revenue: (<%= money_format(@cumulative_revenue) %>)
+ <%= link_to "Add a new product", new_merchant_product_path(@merchant), class: "button" %> +
+ <% end %> + +
+ <% @merchant.products.each do |product| %> + <% if product.orders.length > 0 %> +
    +
  • +

    <%= link_to "#{product.name} (qty: #{product.stock_quantity})", product_path(product), class: "increase-font" %>

    +

    <%= link_to(image_tag("#{product.photo_url}", class: "merchant-img-thumbnail"), product_path(product)) %>

    +
  • +
+ + <% if @user_page == true %> + <%= link_to "Edit", edit_product_path(product), class: "button" %> + <%= link_to "Retire Product", product_retired_path(product), class: "alert button" %> + <% end %> + + <% if @user_page == true %> + + + + + + + + + <% product.orders.reverse.each do |order| %> +
+
+ <% if order.status != 'pending' %> + + <% else %> + + <% end %> + + + + + + + + <% end %> + <% end %> +
Order DateOrder NumberCustomerOrder StatusOrder Details
<%=order.purchase_time.strftime("%Y-%m-%d")%>N/A<%=order.id%><%=order.name%><%=order.status%><%= link_to "View", order_path(order) %>
+ + <% else %> +
    +
  • +

    <%= link_to "#{product.name} (qty: #{product.stock_quantity})", product_path(product), class: "increase-font" %>

    +

    <%= link_to(image_tag("#{product.photo_url}", class: "merchant-img-thumbnail"), product_path(product)) %>

    +
  • +
+ + <% if @user_page == true %> + <%= link_to "Edit", edit_product_path(product), class: "button"%> + <%= link_to "Retire Product", product_retired_path(product), class: "alert button" %> + <% end %> + + <% end %> + <% end %> +
diff --git a/app/views/orders/_order_info.html.erb b/app/views/orders/_order_info.html.erb new file mode 100644 index 0000000000..d0495456e6 --- /dev/null +++ b/app/views/orders/_order_info.html.erb @@ -0,0 +1,30 @@ +<% if @order.status != "pending" %> +
+

+ +

Customer Information:

+ + + + + + + + + + + + + + + + + + + + + + +
Email:<%= @order.email %>
Mailing Address:<%= @order.mailing_address %>
Name on Credit Card:<%= @order.name %>
Last four digits of Credit Card:<%= sprintf '%04d' % @order.cc_last_4 %>
Credit Card Expiration Date:<%= @order.cc_expire %>
+
+<% end %> diff --git a/app/views/orders/checkout.html.erb b/app/views/orders/checkout.html.erb new file mode 100644 index 0000000000..1a24fd693e --- /dev/null +++ b/app/views/orders/checkout.html.erb @@ -0,0 +1,28 @@ +
+
+

Checkout

+
+

<%= @order.name%>, please complete the following information to complete your checkout.

+ +<%= form_for(@order, url: pay_for_order_path) do |f| %> + +<%= f.label :name %> +<%= f.text_field :name %> + +<%= f.label :email %> +<%= f.text_field :email %> + +<%= f.label :mailing_address %> +<%= f.text_field :mailing_address %> + +<%= f.label :cc_last_4%> +<%= f.text_field :cc_last_4 %> + +<%= f.label :cc_expire %> +<%= f.text_field :cc_expire %> + +<%= f.hidden_field :status, :value => "paid" %> + + <%= f.submit "Complete Order" %> +<% end %> +
diff --git a/app/views/orders/show.html.erb b/app/views/orders/show.html.erb new file mode 100644 index 0000000000..a1a72a6655 --- /dev/null +++ b/app/views/orders/show.html.erb @@ -0,0 +1,60 @@ +
+
+

Order Page for <%= @order.name%>

+
+ + <%if flash[:notice]%> +

<%= flash[:notice] %>

+ <%end%> + + +<% if @order.status == "pending" %> +

+ + <%= button_to "Checkout", checkout_path(@order.id), method: :get %> +

+<% end %> + +<%= render partial: "order_info" %> + + +
+ +

Order Information:

+ + + + + + + + + <% @order_items.each do |item| %> + + + + + + + + + + <% end %> +
Product ItemQuantityPrice per ItemTotalAssociated MerchantShipped?
<%= Product.find(item.product_id).name%><%= item.quantity%><%= money_format(Product.find(item.product_id).price)%><%= money_format(Product.find(item.product_id).price * item.quantity)%><%= Product.find(item.product_id).merchant_id%> + <%= item.shipping_status%> + <% if @current_user == Product.find(item.product_id).merchant_id %> + <%= button_to "ship this product", some_path %> + <% end %> +
+ +

Grand Total:<%= money_format(@total_revenue) %>

+
+ +<% @order_items.each do |item| %> + <% if @order.id == item.order_id %> +

Merchant_id: <%=(item.product.merchant_id) %>Product_id: <%= item.product_id %> Order_id <%= item.order_id %>

+ <% end %> +<% end %> + + +
diff --git a/app/views/product_categories/_form.html.erb b/app/views/product_categories/_form.html.erb new file mode 100644 index 0000000000..2cd2296074 --- /dev/null +++ b/app/views/product_categories/_form.html.erb @@ -0,0 +1,23 @@ +<% if @product_category.errors.any? %> + +<% end %> + +<%= form_for @product_category, class: 'add-form', html: {class: 'form'}, url: submit_url,method: http_method do |f| %> +
+ <% @all_categories.each do | category | %> + <%= check_box_tag 'category_ids[]', category.id %> + <%= category.name %> + <% end %> +
+ +
+ <%= f.submit "Create", class: "button"%> +
+ +<% end %> diff --git a/app/views/product_categories/new.html.erb b/app/views/product_categories/new.html.erb new file mode 100644 index 0000000000..7ee8713ca6 --- /dev/null +++ b/app/views/product_categories/new.html.erb @@ -0,0 +1,9 @@ +
+
+

Select all of the Categories that your Product belongs to:

+
+ +
+ <%= render partial: "form", locals: { submit_url: product_product_categories_path, http_method: :post } %> +
+
diff --git a/app/views/products/_form.html.erb b/app/views/products/_form.html.erb new file mode 100644 index 0000000000..3fbaf0962a --- /dev/null +++ b/app/views/products/_form.html.erb @@ -0,0 +1,41 @@ +<% if @product.errors.any? %> + +<% end %> + +<%= form_for [@merchant, @product], method: http_method do |f| %> +
+ <%= f.label "Product Name" %> + <%= f.text_field :name %> +
+ +
+ <%= f.label "Product Description" %> + <%= f.text_field :description %> +
+ +
+ <%= f.label "Photo (URL)" %> + <%= f.text_field :photo_url %> +
+ +
+ <%= f.label :price %> + <%= f.text_field :price %> +
+ +
+ <%= f.label "Quantity Available" %> + <%= f.text_field :stock_quantity %> +
+ +
+ <%= f.submit "Submit", class: "button" %> +
+ +<% end %> diff --git a/app/views/products/edit.html.erb b/app/views/products/edit.html.erb new file mode 100644 index 0000000000..af1cdb5763 --- /dev/null +++ b/app/views/products/edit.html.erb @@ -0,0 +1,7 @@ + +
+
+

Hi, <%= @current_user.name %>! You're editing <%= @product.name %> !

+
+ <%= render partial: "form", locals: { http_method: :patch } %> +
diff --git a/app/views/products/index.html.erb b/app/views/products/index.html.erb new file mode 100644 index 0000000000..ea163834e1 --- /dev/null +++ b/app/views/products/index.html.erb @@ -0,0 +1,21 @@ +
+
+

+ All the Products + <% if @merchant %> + for <%= @merchant.name %> + <% end %> +

+
+ +
+
    + <% @products.each do |product| %> +
  • +

    <%= link_to(image_tag(product.photo_url, class:"product-img-thumbnail"), product_path(product)) %>

    +

    <%= link_to "#{product.name}", product_path(product), class: "product-link increase-font2" %>

    +
  • + <% end %> +
+
+
diff --git a/app/views/products/new.html.erb b/app/views/products/new.html.erb new file mode 100644 index 0000000000..76a819cff9 --- /dev/null +++ b/app/views/products/new.html.erb @@ -0,0 +1,27 @@ + +
+
+

Hi, <%= @current_user.name %>! You're making a new product!

+
+ +
+
+
Please add a category if you do not see an appropriate one for your product below:
+ <%= link_to "Add a Category", new_category_path, class: "button small-2 columns" %>

+
+ +
+
    + <% @all_categories.each do | category | %> +
  1. <%= category.name %>
  2. + <% end %> +
+
+
+
+
+ +
+ <%= render partial: "form", locals: { http_method: :post } %> +
+
diff --git a/app/views/products/show.html.erb b/app/views/products/show.html.erb new file mode 100644 index 0000000000..7714d2c4f3 --- /dev/null +++ b/app/views/products/show.html.erb @@ -0,0 +1,64 @@ + +
+
+
+ <% if flash[:notice] %> +

<%= flash[:notice] %>

+ <% end %> +
+ +

+ <%= @product.name %> +

+
+ + + +
diff --git a/app/views/reviews/_form_stars.html.erb b/app/views/reviews/_form_stars.html.erb new file mode 100644 index 0000000000..1f06bcf1d0 --- /dev/null +++ b/app/views/reviews/_form_stars.html.erb @@ -0,0 +1,14 @@ +
+
+ + + + + + + + + + +
+
diff --git a/app/views/reviews/index.html.erb b/app/views/reviews/index.html.erb new file mode 100644 index 0000000000..8d673fb684 --- /dev/null +++ b/app/views/reviews/index.html.erb @@ -0,0 +1,21 @@ +
+
+

<%= "Reviews for #{@product.name}" %>

+
+ +
+ + + <% @reviews_by_product.each do | review | %> + + + <% end %> +
+
<%= "#{review.title} (Rating: #{review.rating}):" %>
+

<%= "#{review.body}" %>

+
+
+
+ <%= link_to "Add a Review", new_product_review_path(params[:product_id]), class: "product-button" %> +
+
diff --git a/app/views/reviews/new.html.erb b/app/views/reviews/new.html.erb new file mode 100644 index 0000000000..687133f412 --- /dev/null +++ b/app/views/reviews/new.html.erb @@ -0,0 +1,31 @@ +
+
+

Add a Review

+
+ + <% if @review.errors.any? %> +
    + <% @review.errors.each do |column, message| %> +
  • + <%= column.capitalize %> <%= message %> +
  • + <% end %> +
+ <% end %> + + <%= form_for @review, class: "", html: {class: 'form'}, url: product_reviews_path, http_method: :post do |f| %> +
+
+ <%= f.label :title, 'Title:' %> + <%= f.text_field :title %> + + <%= f.label :rating, 'Rating:(1-5)' %> + <%= f.text_field :rating %> + + <%= f.label :body %> + <%= f.text_field :body %> +
+ <%= f.submit :class => 'button' %> +
+ <% end %> +
diff --git a/app/views/sessions/index.html.erb b/app/views/sessions/index.html.erb new file mode 100644 index 0000000000..bb45850f2b --- /dev/null +++ b/app/views/sessions/index.html.erb @@ -0,0 +1 @@ +

sessions index

diff --git a/app/views/sessions/login_failure.html.erb b/app/views/sessions/login_failure.html.erb new file mode 100644 index 0000000000..e9a9c14d80 --- /dev/null +++ b/app/views/sessions/login_failure.html.erb @@ -0,0 +1,7 @@ +
+
+

Sorry, something went wrong with your login. Please click below to try again.

+
+ + <%= link_to "Log In", "/auth/google" %> +
diff --git a/bin/spring b/bin/spring index 7fe232c3aa..9bc076b9ea 100755 --- a/bin/spring +++ b/bin/spring @@ -7,9 +7,10 @@ unless defined?(Spring) require 'rubygems' require 'bundler' - if (match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m)) - Gem.paths = { 'GEM_PATH' => [Bundler.bundle_path.to_s, *Gem.path].uniq.join(Gem.path_separator) } - gem 'spring', match[1] + lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) + if spring = lockfile.specs.detect { |spec| spec.name == "spring" } + Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path + gem 'spring', spring.version require 'spring/binstub' end end diff --git a/config/database.yml b/config/database.yml index 04f24be2ba..1c1a37ca8d 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,85 +1,25 @@ -# PostgreSQL. Versions 8.2 and up are supported. +# SQLite version 3.x +# gem install sqlite3 # -# Install the pg driver: -# gem install pg -# On OS X with Homebrew: -# gem install pg -- --with-pg-config=/usr/local/bin/pg_config -# On OS X with MacPorts: -# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config -# On Windows: -# gem install pg -# Choose the win32 build. -# Install PostgreSQL and put its /bin directory on your path. -# -# Configure Using Gemfile -# gem 'pg' +# Ensure the SQLite 3 gem is defined in your Gemfile +# gem 'sqlite3' # default: &default - adapter: postgresql - encoding: unicode - # For details on connection pooling, see rails configuration guide - # http://guides.rubyonrails.org/configuring.html#database-pooling + adapter: sqlite3 pool: 5 + timeout: 5000 development: <<: *default - database: betsy_development - - # The specified database role being used to connect to postgres. - # To create additional roles in postgres see `$ createuser --help`. - # When left blank, postgres will use the default role. This is - # the same name as the operating system user that initialized the database. - #username: betsy - - # The password associated with the postgres role (username). - #password: - - # Connect on a TCP socket. Omitted by default since the client uses a - # domain socket that doesn't need configuration. Windows does not have - # domain sockets, so uncomment these lines. - #host: localhost - - # The TCP port the server listens on. Defaults to 5432. - # If your server runs on a different port number, change accordingly. - #port: 5432 - - # Schema search path. The server defaults to $user,public - #schema_search_path: myapp,sharedapp,public - - # Minimum log levels, in increasing order: - # debug5, debug4, debug3, debug2, debug1, - # log, notice, warning, error, fatal, and panic - # Defaults to warning. - #min_messages: notice + database: db/development.sqlite3 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: <<: *default - database: betsy_test + database: db/test.sqlite3 -# As with config/secrets.yml, you never want to store sensitive information, -# like your database password, in your source code. If your source code is -# ever seen by anyone, they now have access to your database. -# -# Instead, provide the password as a unix environment variable when you boot -# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database -# for a full rundown on how to provide these environment variables in a -# production deployment. -# -# On Heroku and other platform providers, you may have a full connection URL -# available as an environment variable. For example: -# -# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" -# -# You can use this database configuration with: -# -# production: -# url: <%= ENV['DATABASE_URL'] %> -# production: <<: *default - database: betsy_production - username: betsy - password: <%= ENV['BETSY_DATABASE_PASSWORD'] %> + database: db/production.sqlite3 diff --git a/config/environments/production.rb b/config/environments/production.rb index 5c1b32e486..01c624345f 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -3,6 +3,10 @@ # Code is not reloaded between requests. config.cache_classes = true + config.serve_static_assets = true + config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' + + # Eager load code on boot. This eager loads most of Rails and # your application in memory, allowing both threaded web servers @@ -29,7 +33,7 @@ # config.assets.css_compressor = :sass # Do not fallback to assets pipeline if a precompiled asset is missed. - config.assets.compile = false + config.assets.compile = true # Asset digests allow you to set far-future HTTP expiration dates on all assets, # yet still be able to expire them through the digest params. diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb new file mode 100644 index 0000000000..4dac3bf16c --- /dev/null +++ b/config/initializers/omniauth.rb @@ -0,0 +1,14 @@ + # provider :github, ENV["GITHUB_CLIENT_ID"], ENV["GITHUB_CLIENT_SECRET"], scope: "user:email" + # provider :google, ENV["GITHUB_CLIENT_ID"], ENV["GITHUB_CLIENT_SECRET"], scope: "user:email" + + Rails.application.config.middleware.use OmniAuth::Builder do + provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"], + { + :name => "google", + :scope => "email, profile", + # :prompt => "select_account", + :image_aspect_ratio => "square", + :image_size => 50, + :skip_jwt => true + } +end diff --git a/config/routes.rb b/config/routes.rb index 3f66539d54..33af1e8ac7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,56 +1,47 @@ Rails.application.routes.draw do - # The priority is based upon order of creation: first created -> highest priority. - # See how all your routes lay out with "rake routes". - - # You can have the root of your site routed with "root" - # root 'welcome#index' - - # Example of regular route: - # get 'products/:id' => 'catalog#view' - - # Example of named route that can be invoked with purchase_url(id: product.id) - # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase - - # Example resource route (maps HTTP verbs to controller actions automatically): - # resources :products - - # Example resource route with options: - # resources :products do - # member do - # get 'short' - # post 'toggle' - # end - # - # collection do - # get 'sold' - # end - # end - - # Example resource route with sub-resources: - # resources :products do - # resources :comments, :sales - # resource :seller - # end - - # Example resource route with more complex sub-resources: - # resources :products do - # resources :comments - # resources :sales do - # get 'recent', on: :collection - # end - # end - - # Example resource route with concerns: - # concern :toggleable do - # post 'toggle' - # end - # resources :posts, concerns: :toggleable - # resources :photos, concerns: :toggleable - - # Example resource route within a namespace: - # namespace :admin do - # # Directs /admin/products/* to Admin::ProductsController - # # (app/controllers/admin/products_controller.rb) - # resources :products - # end + + root 'main#index' + + get "/auth/:provider/callback" => "sessions#create" + + get "/sessions/login_failure", to: "sessions#login_failure", as: "login_failure" + get "/sessions", to: "sessions#index", as: "sessions" + delete "/sessions", to: "sessions#destroy" + + resources :merchants, except: [:destroy] do + resources :products, only: [:new, :create, :index] + end + #add non-restful route orders where merchant id + + resources :products, except: [:new, :create, :destroy] do + resources :reviews, except: [:update, :destroy, :edit] + resources :product_categories, only: [:new, :create] + resources :orders, only: [:create, :update] + resources :order_items, only: [:create] + end + patch 'products/:id/retired', to: 'products#retired', as: 'product_retired' + + + resources :categories, except: [:destroy, :edit, :update] + + # resources :orders, except: [:destroy, :index, :new, :create, :update] + resources :orders, only: [:show, :edit] + + get 'orders/:id/checkout', to: 'orders#checkout', as: 'checkout' + patch 'orders/:id/pay', to: 'orders#pay', as: 'pay_for_order' + + # post 'products/:id/orders', to: 'orders#create' + + patch 'orders/:id/completed', to: 'orders#completed', as: 'order_completed' + patch 'orders/:id/cancelled', to: 'orders#cancelled', as: 'order_cancelled' + patch 'orders/:id/paid', to: 'orders#paid', as: 'order_paid' + + + # RELATIONSHIP TABLE ROUTES + resources :order_items, only: [:destroy, :update] + patch 'order_items/:id/shipped', to: 'order_items#shipped', as: 'order_items_shipped' + + + + end diff --git a/config/secrets.yml b/config/secrets.yml index 6442868fc1..b5398f4c2d 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -11,10 +11,10 @@ # if you're sharing your code publicly. development: - secret_key_base: eaebee6b0ce07b1e5b22743dacf6e6aaec01bf01c88370f9f86c3ae0d8592b4313c5e9da09754cd613eda8d206168bd74d5ed9910230b3957725352c70e2cf80 + secret_key_base: 797788a7d548970228544355b6b2bca444c1090f0e4b790e2b042a29f14aa19e09fe16fe70ab4f8a195fb3f32d073a92c7e084363e024d69b7304337af3d0524 test: - secret_key_base: f9c5bd6c383573755e5f8cf214402a51eb5ce8c7d0df9860dbf980f03fbd6c508e97412644b6a80d7034774602b05e05988bf7ab8ff594912950fdb590589a4d + secret_key_base: 05b285fa9c7a5144eab32f559f51e8f861a351626add1f4050ac8be190ea5c700d7b4316bbc390f20ca5901d6ce6867894e99eb12260da2b27d9150cb26dee26 # Do not keep production secrets in the repository, # instead read values from the environment. diff --git a/db/migrate/20161019210038_create_categories.rb b/db/migrate/20161019210038_create_categories.rb new file mode 100644 index 0000000000..9ac8ca0166 --- /dev/null +++ b/db/migrate/20161019210038_create_categories.rb @@ -0,0 +1,11 @@ +class CreateCategories < ActiveRecord::Migration + def change + create_table :categories do |t| + t.string :name + t.string :description + t.string :photo_url + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20161019210201_create_merchants.rb b/db/migrate/20161019210201_create_merchants.rb new file mode 100644 index 0000000000..5acaaec25f --- /dev/null +++ b/db/migrate/20161019210201_create_merchants.rb @@ -0,0 +1,10 @@ +class CreateMerchants < ActiveRecord::Migration + def change + create_table :merchants do |t| + t.string :name + t.string :email + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20161019210300_create_order_items.rb b/db/migrate/20161019210300_create_order_items.rb new file mode 100644 index 0000000000..fd43d27aab --- /dev/null +++ b/db/migrate/20161019210300_create_order_items.rb @@ -0,0 +1,12 @@ +class CreateOrderItems < ActiveRecord::Migration + def change + create_table :order_items do |t| + t.belongs_to :order, index: true + t.belongs_to :product, index: true + t.integer :quantity + t.boolean :shipping_status, :default => false + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20161019210413_create_orders.rb b/db/migrate/20161019210413_create_orders.rb new file mode 100644 index 0000000000..17c53537fc --- /dev/null +++ b/db/migrate/20161019210413_create_orders.rb @@ -0,0 +1,15 @@ +class CreateOrders < ActiveRecord::Migration + def change + create_table :orders do |t| + t.string :name + t.string :email + t.string :mailing_address + t.string :cc_last_4 #We can validate this as four number digits + t.date :cc_expire + t.datetime :purchase_time + t.string :status + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20161019210530_create_product_categories.rb b/db/migrate/20161019210530_create_product_categories.rb new file mode 100644 index 0000000000..18a63580fa --- /dev/null +++ b/db/migrate/20161019210530_create_product_categories.rb @@ -0,0 +1,10 @@ +class CreateProductCategories < ActiveRecord::Migration + def change + create_table :product_categories do |t| + t.belongs_to :product, index: true + t.belongs_to :category, index: true + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20161019210628_create_products.rb b/db/migrate/20161019210628_create_products.rb new file mode 100644 index 0000000000..fb64387ce8 --- /dev/null +++ b/db/migrate/20161019210628_create_products.rb @@ -0,0 +1,15 @@ +class CreateProducts < ActiveRecord::Migration + def change + create_table :products do |t| + t.string :name + t.integer :price + t.integer :stock_quantity + t.string :description + t.string :photo_url + + t.belongs_to :merchant, index: true + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20161019210922_create_reviews.rb b/db/migrate/20161019210922_create_reviews.rb new file mode 100644 index 0000000000..404a90f513 --- /dev/null +++ b/db/migrate/20161019210922_create_reviews.rb @@ -0,0 +1,13 @@ +class CreateReviews < ActiveRecord::Migration + def change + create_table :reviews do |t| + t.integer :rating + t.string :title + t.string :body + + t.belongs_to :product, index: true + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20161022022550_add_uid_and_provider_column_to_merchant_table.rb b/db/migrate/20161022022550_add_uid_and_provider_column_to_merchant_table.rb new file mode 100644 index 0000000000..88ea700d28 --- /dev/null +++ b/db/migrate/20161022022550_add_uid_and_provider_column_to_merchant_table.rb @@ -0,0 +1,6 @@ +class AddUidAndProviderColumnToMerchantTable < ActiveRecord::Migration + def change + add_column :merchants, :uid, :string #null: false # this is the identifier provided by Github + add_column :merchants, :provider, :string #null: false # this tells us who provided the identifier + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000000..6704a100b4 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,91 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20161022022550) do + + create_table "categories", force: :cascade do |t| + t.string "name" + t.string "description" + t.string "photo_url" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "merchants", force: :cascade do |t| + t.string "name" + t.string "email" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "uid" + t.string "provider" + end + + create_table "order_items", force: :cascade do |t| + t.integer "order_id" + t.integer "product_id" + t.integer "quantity" + t.boolean "shipping_status", default: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "order_items", ["order_id"], name: "index_order_items_on_order_id" + add_index "order_items", ["product_id"], name: "index_order_items_on_product_id" + + create_table "orders", force: :cascade do |t| + t.string "name" + t.string "email" + t.string "mailing_address" + t.string "cc_last_4" + t.date "cc_expire" + t.datetime "purchase_time" + t.string "status" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "product_categories", force: :cascade do |t| + t.integer "product_id" + t.integer "category_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "product_categories", ["category_id"], name: "index_product_categories_on_category_id" + add_index "product_categories", ["product_id"], name: "index_product_categories_on_product_id" + + create_table "products", force: :cascade do |t| + t.string "name" + t.integer "price" + t.integer "stock_quantity" + t.string "description" + t.string "photo_url" + t.integer "merchant_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "products", ["merchant_id"], name: "index_products_on_merchant_id" + + create_table "reviews", force: :cascade do |t| + t.integer "rating" + t.string "title" + t.string "body" + t.integer "product_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "reviews", ["product_id"], name: "index_reviews_on_product_id" + +end diff --git a/db/seeds.rb b/db/seeds.rb index 4edb1e857e..7a83b000ed 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,7 +1,44 @@ -# This file should contain all the record creation needed to seed the database with its default values. -# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). -# -# Examples: -# -# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) -# Mayor.create(name: 'Emanuel', city: cities.first) +# We have validations for order requires that at least one order_item exists (and we do have the csv's set up correctly, but the order matters and fails to seed if we do them separately). +# We have validations on product that requires product_categories to exist (which also means that the csv's which are set up correctly, but can't be seeded independently.) Right now we're removing the validations so that the database seeds. If we have time we're going to consolidate them. +# Possibly use create! if we want to get an error on validations for our seed data, or we could turn off validations if we know that our seed data is valid. + +require 'csv' +# Merchant seed +CSV.read("seed_csvs/merchant.csv").each do |line| + id, name, email = line # parallel assignment! + id = id.to_i # need id to be a fixnum + merchant = Merchant.new(id: id.to_i, name: name, email: email) + +# This is how you would save without using validations + merchant.save(validate: false) +# Should maybe check here that all of our records got added. +end + +CSV.foreach('./seed_csvs/categories.csv', :headers => true) do |row| + Category.create(row.to_hash) +end + +CSV.read("seed_csvs/products.csv").each do |t| + product = Product.new(name: t[0], price: t[1], stock_quantity: t[2], description: t[3], photo_url: t[4], merchant_id: t[5]) + product.save(validate:false) +end + +CSV.foreach('./seed_csvs/orders.csv', :headers => true) do |row| + order = Order.create(row.to_hash) + order.save(validate:false) +end + +CSV.foreach('./seed_csvs/reviews.csv', :headers => true) do |row| + Review.create(row.to_hash) +end + + +# Order_Item +CSV.read("seed_csvs/order_items.csv").each do |t| + OrderItem.create(order_id: t[0], product_id: t[1], quantity: t[2]) +end + +#Product_Category +CSV.read("seed_csvs/product_categories.csv").each do |t| + ProductCategory.create(product_id: t[0], category_id: t[1]) +end diff --git a/seed_csvs/categories.csv b/seed_csvs/categories.csv new file mode 100644 index 0000000000..fd1277aa6f --- /dev/null +++ b/seed_csvs/categories.csv @@ -0,0 +1,6 @@ +name,description,photo_url +Wines,"From smooth light chardonnay to bold bodied cabernet's, our wine selection is top quality!","categories/wines.jpg" +Cheeses,"Smelly, soft, creamy, hard, flavored, etc. Looking for a type of Cheese, we've got you covered.","categories/cheese.jpg" +Stone Fruits and Nuts,Lovely seasoned nut varieties and stone fruits.,"categories/peaches.jpg" +Basket Essentials,Every essential picnic item you'll need for an amazing food experience outside of your home.,"categories/essentials.jpg" +Charcuterie,A cultured variety of cured meats from around the world.,"categories/charcuterie.jpg" diff --git a/seed_csvs/merchant.csv b/seed_csvs/merchant.csv new file mode 100644 index 0000000000..54b89f49ab --- /dev/null +++ b/seed_csvs/merchant.csv @@ -0,0 +1,10 @@ +1,"Karin's Cheese",karin@karinscheese.com +2,"Alma's Baked Goods",alma@mybakery.com +3,"Parker-Thiel",ptt@parkerthiel.com +4,"Baskets and More",mail@basketsandmore.com +5,"Sky's the Limit",skysales@gmail.com +6,"Maddie's Veggies",maddie@veggies.com +7,"Fancy Flatware",sales@fancyflatware.com +8,"Pickled Fancy",sales@pickles.com +9,"Best Blankets",kari@bestblankets.com +10,"Wine World",sales@wineworldandspirits.com diff --git a/seed_csvs/order_items.csv b/seed_csvs/order_items.csv new file mode 100644 index 0000000000..c6e6c97d52 --- /dev/null +++ b/seed_csvs/order_items.csv @@ -0,0 +1,12 @@ +1,4,2 +1,7,1 +1,19,2 +2,1,1 +3,7,3 +3,8,1 +4,16,1 +5,8,2 +6,15,1 +6,17,1 +6,18,1 +7,20,1 diff --git a/seed_csvs/orders.csv b/seed_csvs/orders.csv new file mode 100644 index 0000000000..6b4a6f79d8 --- /dev/null +++ b/seed_csvs/orders.csv @@ -0,0 +1,8 @@ +name,email,mailing_address,cc_last_4,cc_expire,purchase_time,status,cc_expire +Amber,ladida@adadev.com,"333 Skyhigh blvd, San Francisco, CA 93104",789,18-Feb,12:45 PM,paid,9-2020 +Anna,madie@adadev.com,"1234 Lily lane, Seattle, WA 90923",896,20-Mar,1:33 AM,paid,9-2020 +Shari,binks@adadev.com,"679 Sharari Dr, Skokie, New York 87654",984,22-Sep,3:10 PM,completed,9-2020 +Paul,pderryl@gmail.com,"333 duck pond lane, Seattle, WA 98105",234,16-Jul,7:45 PM,paid,9-2020 +Richard,rfiller@gmail.com,"234 dill drive, Pittsburg, Pa 87621",635,22-Nov,8:06 AM,completed,9-2020 +Tom,tomriddle@hogwarts.com,"1 darkarts dr., Burrow 12438",276,18-Mar,1:06 PM,pending,9-2020 +Ian,Ian@gmail.com,"5 Picnic Park Rd., Sunnyville, CA 94532",987,1/23/22,5:33 PM,cancelled,9-2020 diff --git a/seed_csvs/product_categories.csv b/seed_csvs/product_categories.csv new file mode 100644 index 0000000000..2cc8a7aaff --- /dev/null +++ b/seed_csvs/product_categories.csv @@ -0,0 +1,22 @@ +1,2 +2,2 +3,2 +4,5 +5,4 +6,4 +7,3 +8,4 +9,4 +10,3 +11,5 +12,5 +13,5 +14,4 +15,5 +16,3 +17,3 +17,4 +18,1 +19,1 +20,1 +20,4 diff --git a/seed_csvs/products.csv b/seed_csvs/products.csv new file mode 100644 index 0000000000..fbdb0d0231 --- /dev/null +++ b/seed_csvs/products.csv @@ -0,0 +1,20 @@ +"Groovy Gruyere",499,10,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent in enim dapibus, volutpat ex tempus, gravida lacus. Vivamus mattis sagittis odio, eu ornare lorem posuere in. Vivamus viverra odio ex, vel laoreet mi facilisis ut.","gruyere.jpg",1 +"Good-looking Goat",299,20,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent in enim dapibus, volutpat ex tempus, gravida lacus. Vivamus mattis sagittis odio, eu ornare lorem posuere in. Vivamus viverra odio ex, vel laoreet mi facilisis ut.","goat_cheese.jpeg",1 +"Breezy Brie",499,15,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent in enim dapibus, volutpat ex tempus, gravida lacus. Vivamus mattis sagittis odio, eu ornare lorem posuere in. Vivamus viverra odio ex, vel laoreet mi facilisis ut.","brie.jpg",2 +"Sagging Salami",699,15,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent in enim dapibus, volutpat ex tempus, gravida lacus. Vivamus mattis sagittis odio, eu ornare lorem posuere in. Vivamus viverra odio ex, vel laoreet mi facilisis ut.","salami.jpg",4 +"Bacciferous Basket",7500,7,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent in enim dapibus, volutpat ex tempus, gravida lacus. Vivamus mattis sagittis odio, eu ornare lorem posuere in. Vivamus viverra odio ex, vel laoreet mi facilisis ut.","basket.jpg",4 +"Blase Blanket",2000,20,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent in enim dapibus, volutpat ex tempus, gravida lacus. Vivamus mattis sagittis odio, eu ornare lorem posuere in. Vivamus viverra odio ex, vel laoreet mi facilisis ut.","blanket.jpg",4 +"Grecian Grapes",700,13,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent in enim dapibus, volutpat ex tempus, gravida lacus. Vivamus mattis sagittis odio, eu ornare lorem posuere in. Vivamus viverra odio ex, vel laoreet mi facilisis ut.","grapes.jpg",5 +"Cheap Cheese Slicer",800,15,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent in enim dapibus, volutpat ex tempus, gravida lacus. Vivamus mattis sagittis odio, eu ornare lorem posuere in. Vivamus viverra odio ex, vel laoreet mi facilisis ut.","slicer.jpeg",7 +"Saggy Sampler",2000,6,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent in enim dapibus, volutpat ex tempus, gravida lacus. Vivamus mattis sagittis odio, eu ornare lorem posuere in. Vivamus viverra odio ex, vel laoreet mi facilisis ut.","sampler.jpg",8 +"Almost Almonds",900,25,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent in enim dapibus, volutpat ex tempus, gravida lacus. Vivamus mattis sagittis odio, eu ornare lorem posuere in. Vivamus viverra odio ex, vel laoreet mi facilisis ut.","almonds.jpg",8 +Prociutto,1600,35,"The quality of prosciutto is entirely in how it's cured. The outside of the ham is usually rubbed with just salt and sometimes a mix of spices. This draws out moisture and concentrates the flavor while the ham slowly air-dries (very much like dry-aged beef). This process can take anywhere from a few months to a several years depending on the desired result.","http://f.tqn.com/y/foodreference/1/W/y/3/-/-/182025119.jpg",1 +Chorizo,1500,25,"Garlic, salt, herbs and other seasonings are then added, perhaps with a little white wine to speed the natural fermentation process. It then rests for two days. This curing gives chorizo its typical slightly acidic taste. Finally, they are then tied and hung up to dry.","http://assets.epicurious.com/photos/57aa23ebde966cd27ad74903/2:1/w_1260,h_630/chorizo.jpg",2 +Rosemary Pork And Chicken Terrine,1800,20,"And to think that the general public thinks that liver pâté is to be enjoyed in moderation! Our little secret is that we perfectly know that those pâtés are full of healthy saturated animal fats. A classic recipe, this pâté is distinctive for the pastis used in the recipe, and the generous blanket of whole fennel seeds on the top. ","https://s-media-cache-ak0.pinimg.com/originals/34/3a/8d/343a8d090f962842487d1811aedecdb0.jpg",3 +Siberian Sturgeon Caviar,8000,10,"We offer the finest caviar raised through sustainable means, comparable to the wild stocks of the Caspian Sea.","http://caviar.com/wp-content/uploads/caviar-siberian-sturgeon-1.jpg",4 +Picnic Meatballs,1000,100,"Deliciously perfect meatballs, drilled round and bite size for your picnic basket.","http://maximizedliving.com/wp-content/uploads/2011/09/swedish-meatballs.jpg",5 +Moroccan Olives,800,50,"The color of an olive indicates the stage of ripeness at which it was picked. Green olives are olives picked before they are ripe, usually in September or October. They should have a firm texture and nutty flavor. What we refer to as 'black' olives actually run the gamut from light brown, to beautiful shades of red and purple, all to way to deepest black. Moroccan olives are a deep dark red, almost sweet in flavor.","http://epicureandculture.com/wp-content/uploads/2015/12/olives.jpg",6 +Popcorn,300,50,"Corn. Yellow and tall. Harvested at its prime and prepared for popping. Stored in bags of latest quality to ensure maximum freshness for your picnic eats.","http://www.whatwillyoustore.com/wp-content/uploads/2016/01/Popcorn-Bucket.jpg",7 +Sauternes,7000,20,"Sauternes is a French sweet wine from the Sauternais region of the Graves section in Bordeaux.","sauternes.jpg",8 +Madeira,4000,20,"Madeira is a fortified Portuguese wine made in the Madeira Islands. Madeira is produced in a variety of styles ranging from dry wines which can be consumed on their own as an aperitif, to sweet wines more usually consumed with dessert.","http://catavino.net/wp-content/uploads/2015/06/6755024641_847daf3b3e_b.jpg",9 +"Tovaritch! Premium Vodka",3000,20,"Gold rated. Incredibly pure and neutral on the nose with perfect refinement and subtlety. Soft and laser-precise on the palate with a seamless balance and great length of flavor. Velvety and mouth-filling in style.","https://s.thestreet.com/files/tsc/v2008/photos/all-pics/food/Tovaritch_inside-large.jpg",10 diff --git a/seed_csvs/reviews.csv b/seed_csvs/reviews.csv new file mode 100644 index 0000000000..aa45ee063b --- /dev/null +++ b/seed_csvs/reviews.csv @@ -0,0 +1,11 @@ +rating,title,body,product_id +4,Best Picnic Food EVER!!!,Souffl� topping toffee I love. Toffee I love pie marshmallow candy canes candy canes pastry jujubes topping. Cake halvah chocolate cake bonbon pastry cheesecake jujubes.,1 +2,cheese wasn't smelly enough,Candy gummi bears croissant fruitcake. Souffl� cake chocolate wafer souffl� oat cake. Toffee jelly beans gummi bears bonbon. Bear claw carrot cake oat cake.,3 +3,Perfect Travel Size!!!,I love pastry dessert lemon drops gummi bears sesame snaps. I love macaroon liquorice tootsie roll chupa chups lemon drops I love. Muffin wafer cake pastry fruitcake bonbon I love chocolate cake.,5 +2,Wouldn't buy again :(,carrot cake tootsie roll. Gummies apple pie tootsie roll lemon drops liquorice dessert pudding. Sweet caramels souffl� I love chocolate. Liquorice drag�e dessert.,10 +5,Highly Recommend,Candy gummi bears croissant fruitcake. Souffl� cake chocolate wafer souffl� oat cake. Toffee jelly beans gummi bears bonbon. Bear claw carrot cake oat cake.,9 +5,I love this Wine!!!,Oat cake marzipan gummi bears sugar plum I love I love sweet roll I love caramels. Gummi bears donut macaroon jelly beans jelly beans caramels I love I love. Cake I love tart chocolate cake I love gummies toffee gingerbread sesame snaps.,1 +4,Cheese Please!!!,lemon drops gummi bears sesame snaps. I love macaroon liquorice tootsie roll chupa chups lemon drops I love. Muffin wafer cake pastry fruitcake bonbon I love chocolate cake.,9 +5,Perfect Pairing,bears croissant fruitcake. Souffl� cake chocolate wafer souffl� oat cake. Toffee jelly beans gummi bears bonbon. Bear claw carrot cake oat cake.,11 +1,Broke after two uses,Oat cake chocolate cake carrot cake tootsie roll. Gummies apple pie tootsie roll lemon drops liquorice dessert pudding. Sweet caramels souffl� I love chocolate. Liquorice drag�e dessert.,15 +3,Not enough Flavor,gummi bears croissant fruitcake. Souffl� cake chocolate wafer souffl� oat cake. Toffee jelly beans gummi bears bonbon. Bear claw carrot cake oat cake.,3 diff --git a/test/controllers/categories_controller_test.rb b/test/controllers/categories_controller_test.rb new file mode 100644 index 0000000000..d89ba3559c --- /dev/null +++ b/test/controllers/categories_controller_test.rb @@ -0,0 +1,57 @@ +require 'test_helper' + +class CategoriesControllerTest < ActionController::TestCase + setup do + @category = categories(:one) + end + + test "should get index" do + get :index + assert_response :success + # assert_not_nil assigns(:categories) + end + + test "should get new" do + get :new + assert_response :success + end + + test "should create category" do + session[:user_id] = merchants(:one).id + + post_params = { + name: "unique test", + photo_url: "www.test.org" + } + assert_difference('Category.count', 1) do + post :create, category: post_params + end + assert_redirected_to new_merchant_product_path(session[:user_id]) + end + + test "should show category" do + category = categories(:one) + get :show, { id: category.id } + assert_response :success + end + + test "should rescue error and redirect_to /errors/category_not_found" do + category = categories(:one) + category.id = 980 + + get :show, { id: category.id } + assert_redirected_to "/errors/category_not_found" + end + + test "should render :new if category isn't saved" do + post_params = { + name: "unique test", + } + assert_no_difference('Category.count') do + post :create, category: post_params + end + + assert_template :new + end + +end diff --git a/test/controllers/main_controller_test.rb b/test/controllers/main_controller_test.rb new file mode 100644 index 0000000000..f42e54a3d5 --- /dev/null +++ b/test/controllers/main_controller_test.rb @@ -0,0 +1,9 @@ +require 'test_helper' + +class MainControllerTest < ActionController::TestCase + test "should get the main page" do + get :index + assert_response :success + assert_template :index + end +end diff --git a/test/controllers/merchants_controller_test.rb b/test/controllers/merchants_controller_test.rb new file mode 100644 index 0000000000..ad5c60192d --- /dev/null +++ b/test/controllers/merchants_controller_test.rb @@ -0,0 +1,17 @@ +require 'test_helper' + +class MerchantsControllerTest < ActionController::TestCase + +test "should get index" do + get :index + assert_response :success +end + +test "should get show" do + get :show, id: merchants(:one).id + assert_response :success +end + +# positive/negative create tests + +end diff --git a/test/controllers/order_items_controller_test.rb b/test/controllers/order_items_controller_test.rb new file mode 100644 index 0000000000..fb158170fe --- /dev/null +++ b/test/controllers/order_items_controller_test.rb @@ -0,0 +1,98 @@ +require 'test_helper' + +class OrderItemsControllerTest < ActionController::TestCase +# CREATE!!! + # test "should create a new OrderItem" do + # post_params = {product: products(:three), order: orders(:three_pending)} + # puts "#{post_params} >>>>>>>>>" + # post :create, post_params + # assert_response :redirect + # end + + # test "creating a new order_item should change the total number" do + # assert_difference 'OrderItem.count', 1 do + # post_params = {order_item: {product_id: products(:three).id, order_id: orders(:three_pending).id, quantity: 1 }} + # post :create, post_params + # end + # end + + +# +# test "should create a new order when one doesn't already exist" do +# # Create a new order with a new order_item +# order_count = Order.all.count.to_i +# +# needs_order = OrderItem.new(order_id:1, product_id:products(:two).id, quantity:1) +# needs_order.save +# new_order_count = Order.all.count +# assert_equal order_count + 1, new_order_count +# end +# # +# # # TO FIX ERROR - end of input error +# # test "should not create a new order if one already exists" do +# # # Order_Item with existing Order id should NOT create a new order. +# # new_order_count = Order.all.count +# # # Not sure why there is an error appearing on the next line, all parts are closed. +# # next_order = OrderItem.new(order_id:orders(one:).id, product_id:products(:two).id, quantity:1) +# # next_order.save +# # new_two = Order.all.count +# # assert_equal new_order_count, new_two +# # end +# # +# # #UPDATE - NOTE - A person should only be able to update the quatity because they shouldn't be able to change the order_id which is unqiue to them and if they want to change the product, they have to go to that product and put it in the order. +# +# # WHY IS THIS PASSING?!?! +# test "a person should be able to update the quantity" do +# order_item = OrderItem.find(order_items(:four).id) +# order_item.quantity = 3 +# assert order_item.valid? +# end +# # WHY IS THIS PASSING?!?! +# test "a person should not add more items to their cart than are available" do +# order_item = OrderItem.find(order_items(:four).id) +# order_item.quantity = 7 +# assert_raise "You may not add a quantity to the order that is greater than the stock quantity." +# end +# # +# # MAYBE THIS IS BETTER FOR ORDER? WHY ARE THEY PAYING FOR THE ITEM, NOT THE ORDER? +# # test "an order_item can't be updated once the order is paid for" do +# # order_item = OrderItem.find(order_items(:five).id) +# # order_item.quantity = 2 +# # #Did we want to flash this? +# # assert_not order_item.valid? +# # assert_raise "You can't update an item that has already been paid for" +# # end +# # +# # #DESTROY +# # test "should be able to call destroy" do +# # delete :destroy, {id: items(:four).id} +# # assert_response :redirect +# # end +# # +# # test "Deleting the order_item should remove it from the order" do +# # assert_difference 'OrderItem.count', -1 do +# # delete :destroy, {id: order_items(:four).id } +# # end +# # end +# # +# # test "An order_item may not be deleted if the order has been paid for already " do +# # order_item = OrderItem.find(order_items(:five).id) +# # order_item.destroy +# # #Did we want to flash this? +# # assert_raise "You can't delete an item that has already been paid for" +# # end +# # +# # test "Deleteing the last order_item from the order will cancel the order" do +# # assert_difference 'Order.count', -1 do +# # delete :destroy, {id: order_items(:one).id } +# # end +# # end +# # +# # #SHIPPED - Still need to think through the tests here. Right now, I see how this would change the order status but not sure all the implications of being shipped. +# # +# # test "Shipping an item will update the shippment status" do +# # +# # end +end +# # +# # # create update destroy shipped diff --git a/test/controllers/orders_controller_test.rb b/test/controllers/orders_controller_test.rb new file mode 100644 index 0000000000..df6e31be0d --- /dev/null +++ b/test/controllers/orders_controller_test.rb @@ -0,0 +1,132 @@ +require 'test_helper' + +class OrdersControllerTest < ActionController::TestCase + + test "should be able to create a new order" do + post_params = {product_id: products(:three).id} + post :create, post_params + assert_response :redirect + end + + test "creating a new order should increase the number of orders by 1" do + assert_difference 'Order.count', 1 do + post_params = {product_id: products(:three).id} + post :create, post_params + end + end + + test "A new order will have status 'pending'" do + # Fake a user + # session[:user_id] = merchants(:one).id + post_params = {product_id: products(:one).id} + post :create, post_params + order = Order.last + + assert_equal order.status, "pending" + end + + test "A new order will not be created if product is nil or has no stock" do + product = products(:one) + product[:stock_quantity] = 0 + order_count = Order.count + assert_equal order_count, Order.count do + post_params = {product_id: product.id} + post :create, post_params + end + end + + test "A new order will be created if a other current order is not an open (not yet cancelled or paid) order" do + # # @todo discuss how to test/implement this + # # The first order + # post_params = {product_id: products(:one).id} + # post :create, post_params + # # Closing the first order + # order_cancel = Order.all.last + # order_cancel[:status] = "cancelled" + # + # assert_not order_cancel.status? + # + # # The second order + # post_params = {product_id: products(:one).id} + # post :create, post_params + # + # order_paid = Order.all.last + # order_paid[:status] = "paid" + # + # assert_not order_paid.status? + end + +# UPDATE _____________________ # + + test "updating an order should redirect to the order page" do + session[:order_id] = orders(:one).id + order = orders(:one) + product_id = products(:one).id + post_params = {id: order.id, product_id: product_id} + post :update, post_params + + assert_response :redirect + end + + test "updating an order with a new product should add it to the existing order" do + session[:order_id] = orders(:one).id + order = orders(:one) + # contains product(:one) + + prod_id = products(:three).id + update_post_params = {id: order.id, product_id: prod_id} + post :update, update_post_params + + assert_equal OrderItem.last.product_id, prod_id + end + +# test "updating an order with a new product should only be possible when the order is 'pending'" do +# +# end + +# # WIP @todo This one seems to geniunly pick up a bug, added to TRELLO +# test "it will not create a new order while staying in the same session" do +# assert_difference('Order.count', 1) do +# post_params = {product_id: products(:three).id} +# post :create, post_params +# end +# puts "before #{Order.count} <<<<<<<" +# assert_no_difference('Order.count') do +# post_params = {product_id: products(:three).id} +# post :create, post_params +# puts "#{Order.count} <<<<<<<" +# +# assert_response :redirect +# # assert_not_nil session[:order_id] +# end +# end + +# test "should update the order when the order_item changes" do +# end +# + +test "should get show" do + get :show, id: orders(:one).id + assert_response :success +end + +test "should get checkout" do + get :checkout, id: orders(:one).id + assert_response :success +end +# +# # Return to non-restful routes. +# test "an order is marked completed when all items in the order have been shipped" do +# +# end +# +# test "an order is cancelled when the session ends before being paid for" do +# +# end +# +# test "an order is paid for when the CC info is provided" do +# +# end +end +# +# # create edit show update completed cancelled paid diff --git a/test/controllers/product_categories_controller_test.rb b/test/controllers/product_categories_controller_test.rb new file mode 100644 index 0000000000..d3f2327e3b --- /dev/null +++ b/test/controllers/product_categories_controller_test.rb @@ -0,0 +1,54 @@ +require 'test_helper' + +class ProductCategoriesControllerTest < ActionController::TestCase + setup do + @product_category = product_categories(:one) + end + + test "should get new" do + params = products(:one) + get :new, { product_id: params.id } + assert_response :success + end + + test "should create product_category" do + product = products(:one) + category = categories(:one) + + assert_difference('ProductCategory.count', 1) do + post :create, { product_id: product.id, category_ids: [category.id] } + end + + assert_redirected_to products_path + end + + test "should not create product_category if no category selected" do + product = products(:one) + + assert_no_difference('ProductCategory.count') do + post :create, { product_id: product.id } + end + + assert_redirected_to products_path + end + + test "should add the correct number of product_category items for the number of categories added to the product" do + product = products(:three) + category1 = categories(:one) + category2 = categories(:two) + + category_ids = [category1.id, category2.id] + num_of_categories = category_ids.length + prev_num_of_prod_cat = ProductCategory.where(product_id: product.id).length + + + assert_difference('ProductCategory.count', 2) do + post :create, { product_id: product.id, category_ids: category_ids } + end + + current_num_of_prod_cat = ProductCategory.where(product_id: product.id).length + + + assert_equal current_num_of_prod_cat, (prev_num_of_prod_cat + num_of_categories) + end +end diff --git a/test/controllers/products_controller_test.rb b/test/controllers/products_controller_test.rb new file mode 100644 index 0000000000..d1e2ab509d --- /dev/null +++ b/test/controllers/products_controller_test.rb @@ -0,0 +1,179 @@ +require 'test_helper' + +class ProductsControllerTest < ActionController::TestCase + test "index displays all the products if no merchant_id or category_id is given" do + get :index + assert_response :success + assert_template :index + + products_from_controller = assigns(:products) + assert_equal Product.count, products_from_controller.length + end + + test "index displays all the products for a merchant (when called in the context of a merchant)" do + # fake a merchant ID in the request + get :index, merchant_id: merchants(:one).id + assert_response :success + assert_template :index + + # Same merchant returned from the index method + assert_equal assigns(:merchant), merchants(:one) + + products_from_controller = assigns(:products) + + assert_equal products_from_controller.count, merchants(:one).products.count + # Each product returned belongs to that merchant. + products_from_controller.each do |product| + assert_includes merchants(:one).products, product + end + end + test "products#show displays a product if it exists!" do + product_id = products(:one).id + get :show, { id: product_id } + + assert_response :success + product = assigns(:product) + assert_not_nil product + assert_equal product.id, product_id + + #this controller doesn't make a new artist + assert_no_difference ('Product.count') do + get :show, { id: product_id } + end + end + + test "if a product belongs to a user, @user_page should be true so that we show the right things on the show page" do + #fake a user logged in + session[:user_id] = merchants(:one).id + + product_id = products(:one).id + + get :show, {id: product_id} + assert_equal assigns(:user_page), true + + end + + # test "products#show displays an error page if product does not exist" do + # skip + # # TODO + # end + + test "products#new displays the new form for logged in merchant" do + #fake a user is logged in. + session[:user_id] = merchants(:one).id + + get :new, {merchant_id: session[:user_id]} + + assert_response :success + assert_template :new + end + + test "products#new is only visible to logged in users" do + # Ensure there is no logged in user. + session.delete(:user_id) + + get :new, {merchant_id: merchants(:one).id} + assert_response :redirect + assert_redirected_to login_failure_path + end + + test "can create a valid product (if logged in)" do + #faking logged in + session[:user_id] = merchants(:one).id + + product_params = + { name: "Jammy Jams", + description: "They make the best jam.", + price: 349, + stock_quantity: 1, + photo_url: 'grapes.jpg', + } + + # make a new product actually adds a product to the database. + assert_difference('Product.count', 1) do + post :create, merchant_id: session[:user_id], product: product_params + end + + post :create, merchant_id: session[:user_id], product: product_params + + + # TODO: write a test that redirects to product_categories#new path where a customer should add their new product to some categories after they make the product. + end + + test "cannot create a new product if not logged in" do + # Ensure there is no logged in user. + session.delete(:user_id) + + post :create, {merchant_id: merchants(:one).id} + assert_response :redirect + assert_redirected_to login_failure_path + end + + test "can get the edit page for their own product" do + #faking logged in + session[:user_id] = merchants(:one).id + product_id = merchants(:one).products.first.id + + get :edit, {id: product_id} + #user is owner of product + assert_equal products(:one).merchant_id, session[:user_id] + + assert_response :success + end + + test "user cannot edit product if they're not the owner." do + #ensure a user not logged in + session.delete(:user_id) + product = merchants(:one).products.first + + get :edit, {id: product.id} + + #user cannot see edit page. + assert_redirected_to product_path(product.id) + + #fake a user logged in + session[:user_id] = merchants(:two).id + + #this product belongs to merchant one. + get :edit, {id: product.id} + + #user cannot see edit page. + assert_redirected_to product_path(product.id) + end + + test "user can successfully update a product they own" do + #fake a user logged in + session[:user_id] = merchants(:one).id + product = merchants(:one).products.first + + product.name = "Jammy Jams" + + patch :update, { id: product.id, product: product.attributes } + + assert_redirected_to merchant_path(session[:user_id]) + + #updating a product should not add a new product to the database. + + product.description = "The best product ever. Believe me." + + assert_difference('Product.count', 0) do + patch :update, { id: product.id, product: product.attributes } + end + # We should add a test for the redirect in here, but Sky updated the redirect. + end + + # I can't get this test to work. + # test "if I don't supply a required field get redirected to edit" do + # #fake a user logged in. + # session[:user_id] = merchants(:one).id + # product = merchants(:one).products.first + # + # product.name = products(:two).name + # + # #this should fail + # patch :update, { id: product.id, product: product.attributes, merchant: merchants(:one) } + # #this should render + # assert_template :edit + # + # end +end diff --git a/test/controllers/reviews_controller_test.rb b/test/controllers/reviews_controller_test.rb new file mode 100644 index 0000000000..ec4290bb19 --- /dev/null +++ b/test/controllers/reviews_controller_test.rb @@ -0,0 +1,59 @@ +require 'test_helper' + +class ReviewsControllerTest < ActionController::TestCase + + test "Should render reviews index page for a specific product" do + product = products(:one) + + get :index, product_id: product.id + assert_response :success + end + + test "If there are no reviews for a product, will redirect you to the product show page" do + product = products(:one) + product.reviews = [] + + get :index, product_id: product.id + assert_redirected_to product_path(product.id) + end + + test "Should render reviews new page for a specific product" do + product = products(:two) + + get :new, product_id: product.id + assert_response :success + end + + test "Should return the correct number of reviews for a specific product" do + product = products(:one) + + assert_equal(product.reviews.count, 2) + end + + test "Can create a review with a product id and rating" do + test_product = products(:one) + + assert_difference('Review.count', 1) do + post :create, product_id: test_product.id, review: { rating: 5, title: "test" } + end + + assert_redirected_to product_reviews_path + end + + test "Cannot create a review with an product id and no rating" do + test_product = products(:one) + + assert_no_difference('Review.count') do + post :create, product_id: test_product.id, review: { title: "test" } + end + end + + test "Cannot create a review with an invalid product id and a valid rating" do + test_product = products(:one) + test_product.id = 90008 + + assert_no_difference('Review.count') do + post :create, product_id: test_product.id, review: { rating: 5, title: "test" } + end + end +end diff --git a/test/controllers/sessions_controller_test.rb b/test/controllers/sessions_controller_test.rb new file mode 100644 index 0000000000..4412118c95 --- /dev/null +++ b/test/controllers/sessions_controller_test.rb @@ -0,0 +1,60 @@ +require 'test_helper' + +class SessionsControllerTest < ActionController::TestCase + def login_a_user + request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:google] + get :create, {provider: "google"} + end + + test "should get index" do + session[:user_id] = merchants(:one).id + + get :index + assert_response :success + assert_equal assigns(:user).id, session[:user_id] + end + + test "Attempting to log in without email should send you to login failure page" do + # login_a_user + request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:google] + user = request.env['omniauth.auth'][:info] + user.email = nil + + assert_no_difference('Merchant.count') do + get :create, {provider: "google"} + end + assert_template :login_failure + end + + test "Can Create a user" do + assert_difference('Merchant.count', 1) do + login_a_user + + assert_response :redirect + assert_redirected_to merchant_path(session[:user_id]) + assert_not_nil session[:user_id] + end + end + + test "If a user logs in twice it doesn't create a 2nd user" do + assert_difference('Merchant.count', 1) do + login_a_user + end + + assert_no_difference('Merchant.count') do + login_a_user + assert_response :redirect + assert_redirected_to merchant_path(session[:user_id]) + assert_not_nil session[:user_id] + end + end + + test "If a user logs out user_id should be nil and should be redirected to the right place" do + login_a_user + get :destroy + + assert_response :redirect + assert_redirected_to root_path + assert_nil session[:user_id] + end +end diff --git a/test/fixtures/categories.yml b/test/fixtures/categories.yml new file mode 100644 index 0000000000..75457a873a --- /dev/null +++ b/test/fixtures/categories.yml @@ -0,0 +1,14 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: + name: textiles + description: All the napkins in the world. + photo_url: https://instagram.fsnc1-1.fna.fbcdn.net/t51.2885-15/e35/12816929_202522856792499_1943289082_n.jpg +two: + name: cookies + description: Seriously, cookies. + photo_url: https://instagram.fsnc1-1.fna.fbcdn.net/t51.2885-15/e35/12547505_182223832136468_536848961_n.jpg diff --git a/test/fixtures/merchants.yml b/test/fixtures/merchants.yml new file mode 100644 index 0000000000..8dcb52b11f --- /dev/null +++ b/test/fixtures/merchants.yml @@ -0,0 +1,29 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: + name: Heart Shaped Everything + email: sales@hse.org + uid: 1234567890qwerty + provider: betsoogle + +two: + name: Picnic Ant + email: sales@picnicant.com + uid: qwerty1234567890 + provider: betsoogle + +three: + name: Gingham Suppliers + email: gingham@suppliers.ya + uid: qwerty123456789 + provider: betsoogle + +four: + name: Gingham Suppliers + email: gingham@suppliers.ya + uid: qwerty123456789 + provider: betsoogle diff --git a/test/fixtures/order_items.yml b/test/fixtures/order_items.yml new file mode 100644 index 0000000000..519098eca6 --- /dev/null +++ b/test/fixtures/order_items.yml @@ -0,0 +1,37 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: + order: one + product: one + quantity: 1 + shipping_status: false +# +two_true: + order: one + product: two + quantity: 2 + shipping_status: true + +three_true: + order: two + product: one + quantity: 1 + shipping_status: true + +# To show that you can not add more quantity than in the stock +four: + order: three_pending + product: three + quantity: 1 + shipping_status: false + +# To show that you can not update the quantity if the order status is anything but pending. Can't use ones above because quantity would not be enough to add anything to the cart. +five: + order: two #paid + product: three + quantity: 1 + shipping_status: false diff --git a/test/fixtures/orders.yml b/test/fixtures/orders.yml new file mode 100644 index 0000000000..261a928119 --- /dev/null +++ b/test/fixtures/orders.yml @@ -0,0 +1,41 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: + name: A. Customer + email: person@email.com + mailing_address: 1234 NW 56th Street, Seattle, WA 98107 + cc_last_4: 1234 + cc_expire: <%= Date.new(2017, 12, 31) %> + purchase_time: <%= DateTime.now %> + status: paid + +two: + name: B. Customer + email: person_two@email.com + mailing_address: 98765 NW 56th Street, Seattle, WA 98107 + cc_last_4: 1234 + cc_expire: <%= Date.new(2017, 12, 31) %> + purchase_time: <%= DateTime.now %> + status: paid + +three_pending: + name: C. Customer + email: person_three@email.com + mailing_address: 98765 NW 56th Street, Seattle, WA 98107 + cc_last_4: 1234 + cc_expire: <%= Date.new(2017, 12, 31) %> + purchase_time: <%= DateTime.now %> + status: pending + +four_shipped: + name: D. Customer + email: person_four@email.com + mailing_address: 4567 NW 56th Street, Seattle, WA 98107 + cc_last_4: 4567 + cc_expire: <%= Date.new(2017, 12, 31) %> + purchase_time: <%= DateTime.now %> + status: completed diff --git a/test/fixtures/product_categories.yml b/test/fixtures/product_categories.yml new file mode 100644 index 0000000000..c77291f6fa --- /dev/null +++ b/test/fixtures/product_categories.yml @@ -0,0 +1,15 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: + product: one + category: one +two: + product: two + category: two +three: + product: one + category: two diff --git a/test/fixtures/products.yml b/test/fixtures/products.yml new file mode 100644 index 0000000000..54c4c3f4cf --- /dev/null +++ b/test/fixtures/products.yml @@ -0,0 +1,29 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: + name: Hot Toddy + price: 1200 + stock_quantity: 1 + description: Who doesn't like a nice hot toddy on a cold day? + photo_url: http://assets.epicurious.com/photos/5761c7f08accf290434553a2/master/pass/hot-toddy.jpg + merchant: one + # apparently, I can associate them by name with the active record model name. +two: + name: Chocolate Covered Strawberries + price: 849 + stock_quantity: 2 + description: Best picnic snack ever! Get them today! + photo_url: https://c3.staticflickr.com/5/4100/4873551178_cb27bf93f6_b.jpg + merchant: two + +three: + name: Chocolate Bar + price: 400 + stock_quantity: 6 + description: How could you say no? + photo_url: https://c3.staticflickr.com/5/4100/4873551178_cb27bf93f6_b.jpg + merchant: two diff --git a/test/fixtures/reviews.yml b/test/fixtures/reviews.yml new file mode 100644 index 0000000000..49521a609b --- /dev/null +++ b/test/fixtures/reviews.yml @@ -0,0 +1,21 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: + rating: 1 + title: Not for picnics. + body: Because apparently in parks you're not supposed to be openly drinking alcohol. Who knew. + product: one +two: + rating: 2 + title: I've seen worse. + body: Strawberries get kind of soggy when you coat them in chocolate and then put them in a picnic basket. Better to eat them right out of the fridge. + product: two +three: + rating: 4 + title: Nom Nom Nom + body: Thinky Drinky every day! + product: one diff --git a/test/models/category_test.rb b/test/models/category_test.rb new file mode 100644 index 0000000000..c71359be5c --- /dev/null +++ b/test/models/category_test.rb @@ -0,0 +1,45 @@ +require 'test_helper' + +class CategoryTest < ActiveSupport::TestCase + def login_a_user + request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:google] + get :create, {provider: "google"} + end + + test "A merchant can create a category with a name and image" do + + end + + test "A merchant cannot create a category without a name" do + + end + + test "A merchant cannot create a category without an image" do + + end + + test "A user cannot create a category with a name and image" do + + end + + test "redirects you to the category_not_found page if category doesn't exist" do + + end + + # test "A user and merchant is able to get the correct number of categories on the index page" do + # assert_equal(Category.length, 2) + # end + + # test "A user and merchant is able to get index page" do + # get :index + # assert_response :success + # end + # + # test "A merchant and user is able to get show page" do + # category = categories(:two) + # + # get :show, category_id: category.id + # assert_response :success + # end + +end diff --git a/test/models/merchant_test.rb b/test/models/merchant_test.rb new file mode 100644 index 0000000000..47f6570180 --- /dev/null +++ b/test/models/merchant_test.rb @@ -0,0 +1,69 @@ +require 'test_helper' + +class MerchantTest < ActiveSupport::TestCase + + test "Created merchant must take name, email, uid, and provider" do + merchant = Merchant.create!(name: "Aunt Betsy's", email: "auntie@betsy.to", uid: "qwert133557", provider: "betsoogle") + assert merchant.valid? + end + + test "Merchant is not valid when empty" do + invalid_merchant = Merchant.new + assert_not invalid_merchant.valid? + end + + test "Merchant must have a name" do + merchant = merchants(:one) + merchant.name = nil + assert_not merchant.valid? + end + + test "Merchant must have an email" do + merchant = merchants(:two) + merchant.email = nil + assert_not merchant.valid? + end + + test "Merchant must have a uid" do + merchant = merchants(:three) + merchant.uid = nil + assert_not merchant.valid? + end + + test "Merchant must have a provider" do + merchant = merchants(:four) + merchant.provider = nil + assert_not merchant.valid? + end + + test "Merchants must be created with unique name and email, duplicates are not allowed" do + valid_merchant = merchants(:three) # Might not need this, as :three should already be in database + duplicate_merchant = Merchant.new(name: "Gingham Suppliers", email: "gingham@suppliers.ya", uid: "qwerty123456789", provider: "betsoogle") + assert_not duplicate_merchant.save + end + + test "Merchant cannot be saved if name is same as a different merchant" do + # valid_merchant = merchants(:three) + merchant = merchants(:three) + merchant.name = "Ant's Blankets" + assert_not merchant.save + end + + test "Merchant cannot be saved if email is same as a different merchant" do + # valid_merchant = merchants(:four) + merchant = merchants(:four) + merchant.email = "do@re.mi" + assert_not merchant.save + end + + test "Many merchants can be saved on the database, and be individually retrieved" do + merchant = Merchant.new(name: "Aunt Betsy's", email: "auntie@betsy.to", uid: "qwert133557", provider: "betsoogle") + merchant2 = Merchant.new(name: "Strawberries and Champagne", email: "little.shop@strawberries.fr", uid: "asdf12345", provider: "betsoogle") + + assert merchant.save + assert merchant2.save + assert_includes Merchant.all, merchant + assert_includes Merchant.all, merchant2 + end + +end diff --git a/test/models/order_item_test.rb b/test/models/order_item_test.rb new file mode 100644 index 0000000000..f5f11461cc --- /dev/null +++ b/test/models/order_item_test.rb @@ -0,0 +1,77 @@ +require 'test_helper' + +class OrderItemTest < ActiveSupport::TestCase + test "create a new order item with valid data" do + assert order_items(:one).valid? + assert order_items(:two_true).valid? + end + + test "Should reject an OrderItem with no quantity" do + item = OrderItem.new(product_id: products(:one).id, order_id: orders(:two).id) + assert_not item.valid? + end + + test "Should reject an OrderItem with a quantity other than an integer" do + order_item = OrderItem.new(product_id: products(:two).id, order_id: orders(:two).id, quantity: "a") + order_item2 = OrderItem.new(product_id: products(:one).id, order_id: orders(:two).id, quantity: false) + assert_not order_item.valid? + assert_not order_item2.valid? + end + + test "Must belong to a product AND order" do + item = OrderItem.new(product_id: products(:one).id, order_id: orders(:two).id, quantity: 1) + assert item.valid? + item_two = OrderItem.new(product_id: 1, order_id: orders(:two), quantity: 1) + item_three = OrderItem.new(product_id: products(:one).id, order_id: 1, quantity: 1) + assert_not item_two.valid? + assert_not item_three.valid? + end + + test "Should reject an OrderItem with a quantity less than or equal to 0" do + order_item = OrderItem.new(product_id: products(:two), order_id: orders(:two), quantity: -1) + order_item2 = OrderItem.new(product_id: products(:one), order_id: orders(:two), quantity: 0) + assert_not order_item.valid? + assert_not order_item2.valid? + end + + test "the method create_order_item should create a new OrderItem instance" do + product = products(:one) + order = orders(:one) + assert_difference('OrderItem.count', 1) do + OrderItem.create_order_item(product, order) + end + end + + #_____________________________________________________# + # @todo write the code to pass these tests + #_____________________________________________________# + # these tests need access to order items that are pending and access to orders and products that are not connected!!!! + + test "the method create_order_item should not create a new order item if there is already one with current order and product" do + # These fixtures are connected in the fixtures + product = products(:one) + order = orders(:one) + + assert_difference('OrderItem.count', 1) do + OrderItem.create_order_item(product, order) + end + end + + test "the method update_order_item should update the quantity of an order item by one when the product is added to the order a second time" do + # These fixtures are connected in the fixtures + product = products(:one) + order = orders(:one) + order_item = order_items(:one) + + assert_equal(product.id, order_item.product_id) + assert_equal(order.id, order_item.order_id) + + order_item[:quantity] = 20 + order_item.save + model_oi = OrderItem.update_order_item(product, order) + + assert_equal(model_oi, order_item) + assert_equal(model_oi.quantity, 21) + end + +end diff --git a/test/models/order_test.rb b/test/models/order_test.rb new file mode 100644 index 0000000000..07344b7ad6 --- /dev/null +++ b/test/models/order_test.rb @@ -0,0 +1,47 @@ +require 'test_helper' + +class OrderTest < ActiveSupport::TestCase + test "create a new order with valid input values" do + assert products(:one).valid? + end + + test "cannot create a order without a status" do + order = Order.new(name: "Penny") + assert_not order.valid? + end + + test "cannot create a order without an incorrect status" do + order = Order.new(status: "Penny") + assert_not order.valid? + end + + test "cannot change an order's status to an incorrect value" do + order = orders(:one) + order.status = "Penny" + assert_not order.valid? + end + + test "order should return correct number of products" do + order = orders(:one) + assert_respond_to(order, :products) + + assert_equal(order.products.length, 2) + end + + # test "The open? method will return true if an order is 'pending' and 'false' if it is 'paid', 'cancelled', or 'complete'" do + # end + + + # REMOVED BECAUSE NO LONGER VALIDATING ORDER_ITEM + # test "order cannot be created without an order item" do + # test_order = orders(:one) + # assert_respond_to(test_order, :order_items) + # test_order.order_items.each do | order | + # OrderItem.destroy(order.id) + # end + # + # test_order.reload + # assert_not test_order.valid? + # end + +end diff --git a/test/models/product_category_test.rb b/test/models/product_category_test.rb new file mode 100644 index 0000000000..6f788ebac5 --- /dev/null +++ b/test/models/product_category_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class ProductCategoryTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/product_test.rb b/test/models/product_test.rb new file mode 100644 index 0000000000..48a08123f9 --- /dev/null +++ b/test/models/product_test.rb @@ -0,0 +1,90 @@ +require 'test_helper' + +class ProductTest < ActiveSupport::TestCase + test "create a new product with valid data" do + assert products(:one).valid? + assert products(:two).valid? + end + + test "new product without name is not valid" do + no_name = products(:one) + no_name.name = nil + + assert_not no_name.valid? + end + + test "new product with same name as another product is not valid" do + not_new = products(:one) + not_new.name = products(:two).name + + assert_not not_new.valid? + end + + test "new product without price is not valid" do + no_price = products(:one) + no_price.price = nil + + assert_not no_price.valid? + end + + test "price cannot be negative" do + we_pay_you = products(:one) + we_pay_you.price = -1234 + + assert_not we_pay_you.valid? + end + + test "price has to be an integer" do + how_much = products(:one) + how_much.price = "$12" + + assert_not how_much.valid? + + how_much.price = 12.34 + + assert_not how_much.valid? + end + + test "price of 0 is not valid" do + free = products(:one) + free.price = 0 + + assert_not free.valid? + end + + test "product with no merchant is not valid" do + whose = products(:one) + whose.merchant_id = nil + + assert_not whose.valid? + end + + test "product should have categories" do + prod = products(:one) + assert_respond_to(prod, :categories) + end + + # This test is commented out because we've removed the validation for at least one category. + # test "product should have at least one category" do + # #This product doesn't have any categories through product_categories, because I've just created it here. It's not valid because validations says we should have at least one product_category. + # prod = Product.new(name:"a valid name", merchant_id: merchants(:one), price: 1200, stock_quantity: 1) + # + # assert_not prod.valid? + # end + + test "product cannot have invalid stock_quantity" do + product = products(:one) + product.stock_quantity = -1 + + assert_not product.valid? + + product.stock_quantity = "none" + + assert_not product.valid? + + product.stock_quantity = nil + + assert_not product.valid? + end + +end diff --git a/test/models/review_test.rb b/test/models/review_test.rb new file mode 100644 index 0000000000..f4615d3e24 --- /dev/null +++ b/test/models/review_test.rb @@ -0,0 +1,45 @@ +require 'test_helper' + +class ReviewTest < ActiveSupport::TestCase + # Rating must be present + # Rating must be between 1 and 5 + test "Creates a review with a rating that is an integer and a product_id" do + review = Review.new(rating: 4, product: products(:one)) + assert review.valid? + end + + test "Cannot create a review without a rating" do + review = Review.new(title: "Awesome Product", product: products(:one)) + assert_not review.valid? + end + + # Rating must be an integer + test "Cannot create a review with a rating that is not and integer" do + review = Review.new(rating: "five stars", product: products(:one)) + assert_not review.valid? + end + + # Rating must be between 1 and 5 + test "Cannot create a review with a rating that is > 5" do + review = Review.new(rating: 6, product: products(:one)) + assert_not review.valid? + end + + test "Cannot create a review with a rating that is < 1" do + review = Review.new(rating: 0, product: products(:one)) + assert_not review.valid? + end + + # belongs_to: Product + test "Cannot create review without a product_id" do + review = Review.new(rating: 5) + assert_not review.valid? + end + + test "Review belongs to a specific product" do + review = reviews(:one) + assert_equal(review.product_id, products(:one).id) + end + + +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 92e39b2d78..8572524ec4 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,10 +1,25 @@ ENV['RAILS_ENV'] ||= 'test' require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' +require 'minitest/reporters' +require 'simplecov' +SimpleCov.start + class ActiveSupport::TestCase # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. fixtures :all # Add more helper methods to be used by all tests here... + Minitest::Reporters.use! + + def setup + # Turn on test mode - auth requests will be short-circuited + # OmniAuth.config.test_mode = true + # What data should we get back from auth requests? + + OmniAuth.config.mock_auth[:google] = OmniAuth::AuthHash.new({ + provider: 'google', uid: '88888', info: { email: "a@b.com", name: "Ada" } + }) + end end