├── log └── .keep ├── app ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── concerns │ │ └── .keep │ └── challenge.rb ├── assets │ ├── images │ │ └── .keep │ ├── stylesheets │ │ ├── index.css │ │ ├── show.css │ │ └── application.css │ └── javascripts │ │ ├── application.js │ │ └── prepare-query-text-box.js ├── controllers │ ├── concerns │ │ ├── .keep │ │ └── challenge_concern.rb │ ├── application_controller.rb │ ├── challenges_controller.rb │ └── attempts_controller.rb ├── views │ ├── challenges │ │ ├── _challenge.html.slim │ │ ├── _schema.html.slim │ │ ├── _editor.slim │ │ ├── index.html.slim │ │ └── show.html.slim │ ├── shared │ │ └── _query_results.html.slim │ └── layouts │ │ └── application.html.erb └── helpers │ └── application_helper.rb ├── lib ├── assets │ └── .keep ├── tasks │ ├── .keep │ └── seed_sample_db.rake ├── table_info.rb └── attempt.rb ├── public ├── favicon.ico ├── robots.txt ├── 500.html ├── 422.html └── 404.html ├── .ruby-version ├── .powder ├── vendor └── assets │ ├── javascripts │ └── .keep │ ├── stylesheets │ ├── .keep │ ├── basscss-progress.css │ ├── basscss.min.css │ ├── basscss.css │ ├── font-awesome.min.css │ └── font-awesome.css │ └── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 ├── .powrc ├── .rspec ├── bin ├── bundle ├── rake ├── rails ├── spring └── setup ├── config ├── boot.rb ├── initializers │ ├── cookies_serializer.rb │ ├── session_store.rb │ ├── mime_types.rb │ ├── filter_parameter_logging.rb │ ├── backtrace_silencers.rb │ ├── assets.rb │ ├── wrap_parameters.rb │ └── inflections.rb ├── environment.rb ├── routes.rb ├── database.yml ├── locales │ └── en.yml ├── secrets.yml ├── application.rb └── environments │ ├── development.rb │ ├── test.rb │ └── production.rb ├── config.ru ├── db ├── migrate │ ├── 20150701181238_add_order_to_challenges.rb │ ├── 20150706195903_add_metadata_to_challenges.rb │ ├── 20150629192408_create_challenges.rb │ └── 20150625192829_create_sample_data.rb ├── seeds.rb ├── schema.rb └── challenge_seeds.json ├── spec ├── helpers │ └── challenge_helper.rb ├── factories │ └── challenge.rb ├── lib │ ├── table_info_spec.rb │ └── attempt_spec.rb ├── models │ └── challenge_spec.rb ├── controllers │ ├── attempts_controller_spec.rb │ └── challenges_controller_spec.rb ├── rails_helper.rb └── spec_helper.rb ├── Rakefile ├── dotenv ├── Gemfile ├── .gitignore ├── README.md └── Gemfile.lock /log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.2.0 2 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.powder: -------------------------------------------------------------------------------- 1 | sqltutor.devbootcamp 2 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.powrc: -------------------------------------------------------------------------------- 1 | source .env.development 2 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require spec_helper 3 | -------------------------------------------------------------------------------- /vendor/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/audibleblink/sql-trainer/HEAD/vendor/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /app/views/challenges/_challenge.html.slim: -------------------------------------------------------------------------------- 1 | .challenge-item.truncate 2 | = link_to challenge.instructions, challenge_path(challenge) 3 | -------------------------------------------------------------------------------- /vendor/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/audibleblink/sql-trainer/HEAD/vendor/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /vendor/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/audibleblink/sql-trainer/HEAD/vendor/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /vendor/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/audibleblink/sql-trainer/HEAD/vendor/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /vendor/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/audibleblink/sql-trainer/HEAD/vendor/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/index.css: -------------------------------------------------------------------------------- 1 | progress.progress { 2 | color: teal 3 | } 4 | 5 | .topic { 6 | font-family: 'Source Code Pro', Consolas, monospace; 7 | } 8 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json 4 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_sql-tutor_session' 4 | -------------------------------------------------------------------------------- /db/migrate/20150701181238_add_order_to_challenges.rb: -------------------------------------------------------------------------------- 1 | class AddOrderToChallenges < ActiveRecord::Migration 2 | def change 3 | add_column :challenges, :order, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/concerns/challenge_concern.rb: -------------------------------------------------------------------------------- 1 | module ChallengeConcern 2 | extend ActiveSupport::Concerns 3 | 4 | def previous_query? 5 | flash[:query].present? 6 | end 7 | 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20150706195903_add_metadata_to_challenges.rb: -------------------------------------------------------------------------------- 1 | class AddMetadataToChallenges < ActiveRecord::Migration 2 | def change 3 | add_column :challenges, :metadata, :json 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | require_relative '../config/boot' 7 | require 'rake' 8 | Rake.application.run 9 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /spec/helpers/challenge_helper.rb: -------------------------------------------------------------------------------- 1 | module ChallengeHelper 2 | def stub_next_challenge challenge 3 | allow_any_instance_of(ApplicationController).to receive(:next_challenge) { challenge } 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | resources :challenges, only:[:index, :show] 3 | resources :attempts, only:[:create] 4 | 5 | get "/reset", to: "attempts#reset" 6 | 7 | root to: "challenges#index" 8 | end 9 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | //= require jquery 2 | //= require jquery_ujs 3 | //= require codemirror 4 | //= require codemirror/modes/sql 5 | //= require codemirror/keymaps/sublime 6 | //= require_self 7 | //= require_tree . 8 | var ST = ST || {} 9 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | APP_PATH = File.expand_path('../../config/application', __FILE__) 7 | require_relative '../config/boot' 8 | require 'rails/commands' 9 | -------------------------------------------------------------------------------- /app/views/challenges/_schema.html.slim: -------------------------------------------------------------------------------- 1 | - tables.each do |table| 2 | table.border.rounded.mb2.h5 3 | th.blue.border-bottom.bg-silver 4 | = table[:table_name] 5 | - table[:fields].each do |field| 6 | tr 7 | td.border-bottom 8 | =field 9 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/views/shared/_query_results.html.slim: -------------------------------------------------------------------------------- 1 | table 2 | tr.headers 3 | - results[:fields].each do |field_name| 4 | th.blue.border-top.bg-silver =field_name 5 | - results[:rows].each do |row_data| 6 | tr 7 | - row_data.each do |k, v| 8 | td.border-top =v 9 | -------------------------------------------------------------------------------- /dotenv: -------------------------------------------------------------------------------- 1 | # database.yml 2 | export DATABASE= 3 | export DATABASE_USERNAME= 4 | export DATABASE_PASSWORD= 5 | 6 | # SSO 7 | export DBC_SHARED_SECRET= 8 | export DEVBOOTCAMP_SSO_URL= 9 | 10 | # Backoffice 11 | export BO_KEY= 12 | export BO_SECRET= 13 | export BACKOFFICE_API_URL= 14 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | include ChallengeConcern 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20150629192408_create_challenges.rb: -------------------------------------------------------------------------------- 1 | class CreateChallenges < ActiveRecord::Migration 2 | def change 3 | create_table :challenges do |t| 4 | t.string :instructions 5 | t.string :query 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/factories/challenge.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | 3 | sequence :order_number do |n| 4 | "#{n}" 5 | end 6 | 7 | factory :challenge do 8 | instructions "select a thing" 9 | query "select * from things limit 1" 10 | order { generate(:order_number) } 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SqlTutor 5 | <%= stylesheet_link_tag 'application', media: 'all' %> 6 | <%= javascript_include_tag 'application' %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /spec/lib/table_info_spec.rb: -------------------------------------------------------------------------------- 1 | describe "TableInfo" do 2 | 3 | context "#schema_for" do 4 | 5 | let(:schema) { TableInfo.schema_for("tracks") } 6 | 7 | it "returns the schema for a given table" do 8 | expect(schema).to have_key :table_name 9 | expect(schema).to have_key :fields 10 | end 11 | 12 | end 13 | 14 | end 15 | -------------------------------------------------------------------------------- /lib/table_info.rb: -------------------------------------------------------------------------------- 1 | module TableInfo 2 | extend self 3 | 4 | DB = ActiveRecord::Base.connection 5 | 6 | def schema_for(table_name) 7 | metadata = {table_name: table_name} 8 | 9 | DB.transaction do 10 | metadata[:fields] = DB.execute("SELECT * FROM #{table_name} WHERE false").fields 11 | raise ActiveRecord::Rollback 12 | end 13 | 14 | metadata 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/views/challenges/_editor.slim: -------------------------------------------------------------------------------- 1 | = form_tag("/attempts", class: "md-col md-col-12") do |t| 2 | = hidden_field_tag("attempt[challenge_id]", @challenge.id) 3 | = text_area_tag("attempt[query]", flash[:query], class: "sql-textarea md-col md-col-12 border-none") 4 | .btn.block.clear.p0.mt1 5 | = submit_tag("Run", class: "btn btn-primary md-col-12 mt2") 6 | 7 | script 8 | | ST.autoHighlightQueryText.init() 9 | -------------------------------------------------------------------------------- /spec/models/challenge_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Challenge, type: :model do 4 | context "#next" do 5 | 6 | let!(:first_challenge) {create(:challenge)} 7 | let!(:second_challenge) {create(:challenge)} 8 | 9 | it "returns the next challenge in the database" do 10 | expect(first_challenge.next.order).to eq second_challenge.order 11 | end 12 | 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/tasks/seed_sample_db.rake: -------------------------------------------------------------------------------- 1 | namespace :db do 2 | namespace :sample do 3 | desc "Populates the sample database" 4 | task :seed => :environment do 5 | puts "Populating the sample database" 6 | 7 | db_path = File.expand_path('../../../db/seeds.sql', __FILE__) 8 | statements = File.read(db_path) 9 | ActiveRecord::Base.connection.execute(statements) 10 | 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | 4 | gem 'rails', '4.2.1' 5 | gem 'sass-rails', '~> 5.0' 6 | gem 'jquery-rails' 7 | gem 'pg' 8 | gem 'slim-rails' 9 | gem 'codemirror-rails' 10 | 11 | group :development, :test do 12 | gem 'dotenv-rails' 13 | gem 'factory_girl' 14 | gem 'database_cleaner' 15 | gem 'byebug' 16 | gem 'powder' 17 | gem 'pry-byebug' 18 | gem 'rspec-rails' 19 | gem 'web-console', '~> 2.0' 20 | gem 'spring' 21 | end 22 | -------------------------------------------------------------------------------- /app/models/challenge.rb: -------------------------------------------------------------------------------- 1 | class Challenge < ActiveRecord::Base 2 | default_scope { order(:order) } 3 | store_accessor :metadata, :tables, :topic 4 | 5 | def next 6 | self.class.find_by(order: order + 1) 7 | end 8 | 9 | def previous 10 | self.class.find_by(order: order - 1) || Challenge.first 11 | end 12 | 13 | def schema 14 | tables.map do |table_name| 15 | TableInfo.schema_for(table_name) 16 | end 17 | end 18 | 19 | end 20 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | path = File.expand_path("../challenge_seeds.json", __FILE__) 4 | data = JSON.parse(File.read(path)) 5 | 6 | def create_challenges(data) 7 | data["values"].each do |values| 8 | params = Hash[data["fields"].zip(values)] 9 | Challenge.create!(params) 10 | end 11 | end 12 | 13 | 14 | # seed the challenge questions 15 | create_challenges(data) 16 | 17 | # seed tables that students run queries on 18 | Rake::Task['db:sample:seed'].invoke 19 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | defaults: &defaults 2 | adapter: postgresql 3 | encoding: utf8 4 | pool: 5 5 | template: template0 6 | collation: en_US.UTF-8 7 | ctype: en_US.UTF-8 8 | host: <%= ENV['DATABASE_HOST'] || 'localhost' %> 9 | port: <%= ENV['DATABASE_PORT'] || 5432 %> 10 | database: <%= ENV['DATABASE'] %> 11 | username: <%= ENV['DATABASE_USERNAME'] %> 12 | password: <%= ENV['DATABASE_PASSWORD'] %> 13 | 14 | development: 15 | <<: *defaults 16 | 17 | test: 18 | <<: *defaults 19 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require "rubygems" 8 | require "bundler" 9 | 10 | if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m) 11 | Gem.paths = { "GEM_PATH" => [Bundler.bundle_path.to_s, *Gem.path].uniq } 12 | gem "spring", match[1] 13 | require "spring/binstub" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | !/log/.keep 17 | /tmp 18 | 19 | .env.development 20 | .env.test 21 | auto-highlight-query-text.js 22 | 23 | -------------------------------------------------------------------------------- /app/assets/stylesheets/show.css: -------------------------------------------------------------------------------- 1 | #attempt_query { 2 | max-height: 8em; 3 | min-height: 8em; 4 | } 5 | 6 | .sql-textarea { 7 | resize: none; 8 | font-family: 'Source Code Pro', Consolas, monospace; 9 | } 10 | 11 | .query-results-table { 12 | max-height: 18em; 13 | min-height: 18em; 14 | } 15 | 16 | .metadata { 17 | overflow: scroll; 18 | max-height: 24em; 19 | min-height: 24em; 20 | /*font-family: 'Source Code Pro', Consolas, monospace;*/ 21 | } 22 | 23 | form > .CodeMirror { 24 | font-family: 'Source Code Pro', Consolas, monospace; 25 | max-height: 9em; 26 | min-height: 9em; 27 | line-height: 1.5em; 28 | font-size: 120%; 29 | border-radius: 3px; 30 | } 31 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/basscss-progress.css: -------------------------------------------------------------------------------- 1 | progress { 2 | display: block; 3 | width: 100%; 4 | height: calc( var(--form-field-height) / 4 ); 5 | margin: var(--form-field-padding-y) 0; 6 | overflow: hidden; 7 | -webkit-appearance: none; 8 | } 9 | 10 | .progress { 11 | background-color: var(--darken-2); 12 | border: 0; 13 | border-radius: 3px; 14 | } 15 | 16 | .progress::-webkit-progress-bar { 17 | -webkit-appearance: none; 18 | background-color: var(--darken-2) 19 | } 20 | 21 | .progress::-webkit-progress-value { 22 | -webkit-appearance: none; 23 | background-color: currentColor; 24 | } 25 | 26 | .progress::-moz-progress-bar { 27 | background-color: currentColor; 28 | } 29 | -------------------------------------------------------------------------------- /app/assets/javascripts/prepare-query-text-box.js: -------------------------------------------------------------------------------- 1 | ST.autoHighlightQueryText = { 2 | init: function(){ 3 | var textarea = document.getElementById("attempt_query") 4 | , options = { 5 | lineNumbers: true, 6 | mode: "text/x-sql", 7 | theme: "monokai", 8 | keyMap: "sublime", 9 | autofocus: true, 10 | extraKeys: { 11 | Tab: false, 12 | "Cmd-D": function(){ 13 | var word = editor.findWordAt(editor.getCursor()); 14 | editor.setSelection(word.anchor, word.head); 15 | } 16 | }, 17 | cursorHeight: 0.8, 18 | } 19 | 20 | var editor = CodeMirror.fromTextArea(textarea, options); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/attempt.rb: -------------------------------------------------------------------------------- 1 | module Attempt 2 | 3 | def self.is_correct?(query_attempt, challenge_query) 4 | results_for(query_attempt) == results_for(challenge_query) 5 | end 6 | 7 | def self.results_for(query) 8 | results = "" 9 | ActiveRecord::Base.connection.transaction do 10 | begin 11 | dataset = ActiveRecord::Base.connection.execute(query) 12 | results = { :fields => dataset.fields, :rows => dataset.entries } 13 | rescue Exception => ex 14 | message = ex.message.gsub("PG::Error: ERROR: ", "").split("\n").first 15 | results = { :error => message } 16 | end 17 | 18 | raise ActiveRecord::Rollback 19 | end 20 | 21 | results 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | 3 | def challenges_by_topic(challenges) 4 | challenges.group_by(&:topic) 5 | end 6 | 7 | def progress_value 8 | @progress.to_f / @challenges.count.to_f 9 | end 10 | 11 | def start_button_text 12 | is_new_user ? "Start" : "Continue" 13 | end 14 | 15 | def is_new_user 16 | @progress == 0 17 | end 18 | 19 | def last_challenge 20 | Challenge.find_by(order: session[:challenge_id]) 21 | end 22 | 23 | def next_challenge 24 | session[:challenge_id] ? last_challenge.next : Challenge.first 25 | end 26 | 27 | def display_last_query 28 | if @last_query 29 | "Last Query: #{flash[:query]}" 30 | end 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /app/controllers/challenges_controller.rb: -------------------------------------------------------------------------------- 1 | class ChallengesController < ApplicationController 2 | 3 | before_action :load_challenge, :set_previous_results, only: [:show] 4 | 5 | def index 6 | @challenges = Challenge.all 7 | @progress = session.fetch(:challenge_id) {0} 8 | end 9 | 10 | def show 11 | @metadata = @challenge.schema 12 | end 13 | 14 | private 15 | 16 | def load_challenge 17 | @challenge = Challenge.find_by(id: params[:id]) 18 | end 19 | 20 | def set_previous_results 21 | return unless previous_query? 22 | last_guess_correct = flash[:notice].present? 23 | expected = last_guess_correct ? @challenge.previous.query : @challenge.query 24 | @last_query = Attempt.results_for(flash[:query]) 25 | @expected = Attempt.results_for(expected) 26 | end 27 | 28 | end 29 | -------------------------------------------------------------------------------- /app/controllers/attempts_controller.rb: -------------------------------------------------------------------------------- 1 | class AttemptsController < ApplicationController 2 | 3 | def create 4 | challenge = Challenge.find_by(id: attempt_params[:challenge_id]) 5 | valid_attempt = Attempt.is_correct?(attempt_params[:query], challenge.query) 6 | 7 | flash[:query] = attempt_params[:query] 8 | 9 | if valid_attempt 10 | flash[:notice] = "Correct!" 11 | session[:challenge_id] = challenge.id 12 | redirect_to challenge.next ? challenge.next : root_path 13 | else 14 | flash[:alert] = "Incorrect" 15 | redirect_to challenge 16 | end 17 | 18 | end 19 | 20 | def reset 21 | session.clear 22 | redirect_to root_path 23 | end 24 | 25 | private 26 | 27 | def attempt_params 28 | params.require(:attempt).permit(:query, :challenge_id) 29 | end 30 | 31 | end 32 | -------------------------------------------------------------------------------- /spec/controllers/attempts_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe AttemptsController do 4 | 5 | let(:challenge) {create(:challenge)} 6 | 7 | describe "#create" do 8 | 9 | before do 10 | allow(Challenge).to receive(:find_by) {challenge} 11 | end 12 | 13 | it "sets correct flash message when user is correct" do 14 | allow(Attempt).to receive(:is_correct?) {true} 15 | post :create, {attempt: {query: "select * from invoices", challenge_id: 1}} 16 | expect(flash[:notice]).to eq "Correct!" 17 | end 18 | 19 | it "sets correct flash message when user is incorrect" do 20 | allow(Attempt).to receive(:is_correct?) {false} 21 | post :create, attempt: {query: "bad query", challenge_id: 1} 22 | expect(flash[:alert]).to eq "Incorrect" 23 | end 24 | 25 | end 26 | 27 | 28 | end 29 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | 4 | # path to your application root. 5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 6 | 7 | Dir.chdir APP_ROOT do 8 | # This script is a starting point to setup your application. 9 | # Add necessary setup steps to this file: 10 | 11 | puts "== Installing dependencies ==" 12 | system "gem install bundler --conservative" 13 | system "bundle check || bundle install" 14 | 15 | # puts "\n== Copying sample files ==" 16 | # unless File.exist?("config/database.yml") 17 | # system "cp config/database.yml.sample config/database.yml" 18 | # end 19 | 20 | puts "\n== Preparing database ==" 21 | system "bin/rake db:setup" 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system "rm -f log/*" 25 | system "rm -rf tmp/cache" 26 | 27 | puts "\n== Restarting application server ==" 28 | system "touch tmp/restart.txt" 29 | end 30 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any styles 10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new 11 | * file per style scope. 12 | * 13 | *= require basscss.min 14 | *= require font-awesome.min 15 | *= require basscss-progress 16 | *= require codemirror 17 | *= require codemirror/themes/monokai 18 | *= require_tree . 19 | *= require_tree . 20 | *= require_self 21 | */ 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Sql Tutor 3 | 4 | An app designed to allow students to practice and level up their SQL queries. 5 | 6 | ![Imgur](http://i.imgur.com/xLP2omw.png) 7 | 8 | ### Setup 9 | 10 | Install gems: 11 | ``` 12 | $ bundle install 13 | ``` 14 | 15 | Default environment variables are stored in the `dotenv` file. You should create both `.env.development` and `.env.test` files with your local configuration details. 16 | 17 | ``` 18 | $ cp dotenv .env.development 19 | $ cp dotenv .env.test 20 | ``` 21 | 22 | Create and seed the database: 23 | ``` 24 | $ rake db:setup 25 | ``` 26 | 27 | Setup pow using powder 28 | ``` 29 | $ powder install 30 | $ powder link 31 | ``` 32 | 33 | Your app should start and be accessible at `http://launchpad.devbootcamp.dev`. You can restart the server with the command `$ powder restart`. 34 | 35 | ### Development 36 | 37 | See a list of powder commands: 38 | ``` 39 | $ powder -h 40 | ``` 41 | 42 | Run tests: 43 | ``` 44 | $ RAILS_ENV=test rake spec 45 | ``` 46 | -------------------------------------------------------------------------------- /spec/lib/attempt_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe Attempt do 4 | 5 | let(:good_query) {"select * from artists;"} 6 | let(:bad_query) {"bad query is bad"} 7 | 8 | context "#is_correct?" do 9 | 10 | let(:challenge) {Struct.new("Question", :query).new("select * from artists;") } 11 | 12 | it "returns true when resulting QueryResults objects match" do 13 | expect(Attempt.is_correct?(challenge.query, good_query)).to be true 14 | end 15 | 16 | it "returns false when resulting QueryResults objects do not match" do 17 | expect(Attempt.is_correct?(challenge.query, bad_query)).to be false 18 | end 19 | 20 | end 21 | 22 | context "#results_for" do 23 | 24 | it "returns a valid response for a valid query" do 25 | expect(Attempt.results_for(good_query)).to have_key :fields 26 | end 27 | 28 | it "returns an for an invalid query" do 29 | expect(Attempt.results_for(bad_query)).to have_key :error 30 | end 31 | 32 | end 33 | 34 | end 35 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: f08b0b32087e38a99adfd1bc24622963c989fcdbfd5330b2e545d3777355ed500d9c00107941ae9a09d6955fc96c9135025d6f5490dd735e557020ec38be15a7 15 | 16 | test: 17 | secret_key_base: 8bc4c1c8d4167ba8b406601794b1b5806685dba64e2cd3642e382a8714d3f81c01f1fe42a1529f51bc7536a497b6738db395c98d5375618195a847293427defa 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /app/views/challenges/index.html.slim: -------------------------------------------------------------------------------- 1 | 2 | .container 3 | .header.h1.mt2 4 | | SQL Tutor 5 | hr.mb3 6 | 7 | ul.challenges.md-col.md-col-7 8 | - challenges_by_topic(@challenges).each_pair do |topic, challenges| 9 | .panel.border-top.border-left.rounded.mb3.md-col.md-col-11 10 | .topic.bg-silver.px1.h3 11 | = topic 12 | .sub-challenges.p2.bg-white 13 | = render challenges 14 | 15 | .progress.md-col.md-col-3 16 | .progress-indicator.mb2 17 | progress.progress.muted value="#{progress_value}" = progress_value 18 | .progress-text.right-align 19 | = "#{@progress} of #{@challenges.count} challenges completed" 20 | 21 | .progress-functions.md-col.md-col-12 22 | .continue.md-col.md-col-12.right-align 23 | = link_to "#{start_button_text}", next_challenge, class: "btn btn-primary mb2 .md-col md-col-8 center" 24 | 25 | - if is_new_user 26 | .reset.md-col.md-col-12.right-align.hide 27 | - else 28 | .reset.md-col.md-col-12.right-align 29 | = link_to "Reset Progress", reset_path, class: "btn btn-primary bg-red mb2 .md-col md-col-8 center" 30 | -------------------------------------------------------------------------------- /app/views/challenges/show.html.slim: -------------------------------------------------------------------------------- 1 | .messages.center.white 2 | .notice.bg-green 3 | = flash[:notice] 4 | .alert.bg-red.white 5 | = flash[:alert] 6 | 7 | .container 8 | .header.h1.mt2 9 | = link_to "SQL Tutor", root_path 10 | hr 11 | .challenge 12 | .challenge-left.md-col.md-col-9 13 | .instructions.py2.h2.md-col.md-col-10 14 | = @challenge.instructions 15 | 16 | .attempt.md-col.md-col-10.bg-silver.rounded.p2 17 | .attempt-form.md-col.md-col-12 18 | = render "editor" 19 | 20 | .clear 21 | .query.md-col.md-col-12 22 | .h5.mt2 23 | = display_last_query 24 | 25 | .challenge-right.md-col.md-col-3 26 | .h2.mt1 Table Info 27 | .metadata.p2.mt1 28 | = render "schema", tables: @metadata 29 | 30 | .hr 31 | .results.md-col.md-col-12.mb3 32 | .actual.md-col.md-col-6 33 | - if @last_query && @last_query.key?(:fields) 34 | h4 Your Results 35 | .query-results-table.overflow-scroll.mr2.border.rounded 36 | = render "shared/query_results", results: @last_query 37 | - elsif @last_query && @last_query.key?(:error) 38 | h4 Your Results 39 | .query-results-table.overflow-scroll.mr1 40 | = @last_query[:error] 41 | .expected.md-col.md-col-6 42 | - if @expected 43 | h4 Expected Results 44 | .query-results-table.overflow-scroll.mr2.border.rounded 45 | = render "shared/query_results", results: @expected 46 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require "rails" 4 | # Pick the frameworks you want: 5 | require "active_model/railtie" 6 | require "active_job/railtie" 7 | require "active_record/railtie" 8 | require "action_controller/railtie" 9 | require "action_mailer/railtie" 10 | require "action_view/railtie" 11 | require "sprockets/railtie" 12 | # require "rails/test_unit/railtie" 13 | 14 | # Require the gems listed in Gemfile, including any gems 15 | # you've limited to :test, :development, or :production. 16 | Bundler.require(*Rails.groups) 17 | 18 | module SqlTutor 19 | class Application < Rails::Application 20 | config.autoload_paths += Dir["#{config.root}/lib/**/"] 21 | # Settings in config/environments/* take precedence over those specified here. 22 | # Application configuration should go into files in config/initializers 23 | # -- all .rb files in that directory are automatically loaded. 24 | 25 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 26 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 27 | # config.time_zone = 'Central Time (US & Canada)' 28 | 29 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 30 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 31 | # config.i18n.default_locale = :de 32 | 33 | # Do not swallow errors in after_commit/after_rollback callbacks. 34 | config.active_record.raise_in_transactional_callbacks = true 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /spec/controllers/challenges_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe ChallengesController do 4 | let!(:challenge) { build(:challenge) } 5 | 6 | describe "#index" do 7 | let(:challenges) { [challenge] } 8 | let(:progress) { 0 } 9 | 10 | it "displays the challenges in order" do 11 | expect(Challenge).to receive(:all) { challenges } 12 | expect(session).to receive(:fetch).with(:challenge_id) { progress } 13 | get :index 14 | expect(assigns(:challenges)).to eq challenges 15 | expect(assigns(:progress)).to eq progress 16 | end 17 | end 18 | 19 | describe "#show" do 20 | let(:metadata) { 'metadata' } 21 | 22 | before(:each) do 23 | allow(Challenge).to receive(:find_by) { challenge } 24 | allow(challenge).to receive(:schema) { metadata } 25 | end 26 | 27 | it "displays the challenges index page" do 28 | allow_any_instance_of(ApplicationController).to receive(:previous_query?) { false } 29 | get :show, id: 1 30 | expect(assigns(:challenge)).to eq challenge 31 | expect(assigns(:metadata)).to eq metadata 32 | expect(assigns(:last_query)).to be_nil 33 | expect(assigns(:expected)).to be_nil 34 | end 35 | 36 | it "sets the previous results" do 37 | results = 'query results' 38 | allow_any_instance_of(ApplicationController).to receive(:previous_query?) { true } 39 | allow(Attempt).to receive(:results_for) { results } 40 | get :show, id: 1 41 | expect(assigns(:last_query)).to eq results 42 | expect(assigns(:expected)).to eq results 43 | end 44 | end 45 | 46 | 47 | end 48 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations. 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | 30 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 31 | # yet still be able to expire them through the digest params. 32 | config.assets.digest = true 33 | 34 | # Adds additional error checking when serving assets at runtime. 35 | # Checks for improperly declared sprockets dependencies. 36 | # Raises helpful error messages. 37 | config.assets.raise_runtime_errors = true 38 | 39 | # Raises error for missing translations 40 | # config.action_view.raise_on_missing_translations = true 41 | end 42 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static file server for tests with Cache-Control for performance. 16 | config.serve_static_files = true 17 | config.static_cache_control = 'public, max-age=3600' 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Randomize the order test cases are executed. 35 | config.active_support.test_order = :random 36 | 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /spec/rails_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | ENV['RAILS_ENV'] ||= 'test' 3 | require 'dotenv' ; Dotenv.overload ".env.test" 4 | require File.expand_path('../../config/environment', __FILE__) 5 | # Prevent database truncation if the environment is production 6 | abort("The Rails environment is running in production mode!") if Rails.env.production? 7 | require 'spec_helper' 8 | require 'rspec/rails' 9 | require 'helpers/challenge_helper' 10 | # Add additional requires below this line. Rails is not loaded until this point! 11 | 12 | # Requires supporting ruby files with custom matchers and macros, etc, in 13 | # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are 14 | # run as spec files by default. This means that files in spec/support that end 15 | # in _spec.rb will both be required and run as specs, causing the specs to be 16 | # run twice. It is recommended that you do not name files matching this glob to 17 | # end with _spec.rb. You can configure this pattern with the --pattern 18 | # option on the command line or in ~/.rspec, .rspec or `.rspec-local`. 19 | # 20 | # The following line is provided for convenience purposes. It has the downside 21 | # of increasing the boot-up time by auto-requiring all files in the support 22 | # directory. Alternatively, in the individual `*_spec.rb` files, manually 23 | # require only the support files necessary. 24 | # 25 | # Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } 26 | 27 | # Checks for pending migrations before tests are run. 28 | # If you are not using ActiveRecord, you can remove this line. 29 | ActiveRecord::Migration.maintain_test_schema! 30 | 31 | FactoryGirl.definition_file_paths = [File.expand_path('../factories', __FILE__)] 32 | FactoryGirl.find_definitions 33 | 34 | RSpec.configure do |config| 35 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 36 | config.include FactoryGirl::Syntax::Methods 37 | config.fixture_path = "#{::Rails.root}/spec/fixtures" 38 | config.include ChallengeHelper 39 | 40 | # If you're not using ActiveRecord, or you'd prefer not to run each of your 41 | # examples within a transaction, remove the following line or assign false 42 | # instead of true. 43 | config.use_transactional_fixtures = true 44 | 45 | # RSpec Rails can automatically mix in different behaviours to your tests 46 | # based on their file location, for example enabling you to call `get` and 47 | # `post` in specs under `spec/controllers`. 48 | # 49 | # You can disable this behaviour by removing the line below, and instead 50 | # explicitly tag your specs with their type, e.g.: 51 | # 52 | # RSpec.describe UsersController, :type => :controller do 53 | # # ... 54 | # end 55 | # 56 | # The different available types are documented in the features, such as in 57 | # https://relishapp.com/rspec/rspec-rails/docs 58 | config.infer_spec_type_from_file_location! 59 | end 60 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like 20 | # NGINX, varnish or squid. 21 | # config.action_dispatch.rack_cache = true 22 | 23 | # Disable serving static files from the `/public` folder by default since 24 | # Apache or NGINX already handles this. 25 | config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? 26 | 27 | # Compress JavaScripts and CSS. 28 | # config.assets.css_compressor = :sass 29 | 30 | # Do not fallback to assets pipeline if a precompiled asset is missed. 31 | config.assets.compile = false 32 | 33 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 34 | # yet still be able to expire them through the digest params. 35 | config.assets.digest = true 36 | 37 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 38 | 39 | # Specifies the header that your server uses for sending files. 40 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 41 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 42 | 43 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 44 | # config.force_ssl = true 45 | 46 | # Use the lowest log level to ensure availability of diagnostic information 47 | # when problems arise. 48 | config.log_level = :debug 49 | 50 | # Prepend all log lines with the following tags. 51 | # config.log_tags = [ :subdomain, :uuid ] 52 | 53 | # Use a different logger for distributed setups. 54 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 55 | 56 | # Use a different cache store in production. 57 | # config.cache_store = :mem_cache_store 58 | 59 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 60 | # config.action_controller.asset_host = 'http://assets.example.com' 61 | 62 | # Ignore bad email addresses and do not raise email delivery errors. 63 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 64 | # config.action_mailer.raise_delivery_errors = false 65 | 66 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 67 | # the I18n.default_locale when a translation cannot be found). 68 | config.i18n.fallbacks = true 69 | 70 | # Send deprecation notices to registered listeners. 71 | config.active_support.deprecation = :notify 72 | 73 | # Use default logging formatter so that PID and timestamp are not suppressed. 74 | config.log_formatter = ::Logger::Formatter.new 75 | 76 | # Do not dump schema after migrations. 77 | config.active_record.dump_schema_after_migration = false 78 | end 79 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file was generated by the `rails generate rspec:install` command. Conventionally, all 2 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. 3 | # The generated `.rspec` file contains `--require spec_helper` which will cause 4 | # this file to always be loaded, without a need to explicitly require it in any 5 | # files. 6 | # 7 | # Given that it is always loaded, you are encouraged to keep this file as 8 | # light-weight as possible. Requiring heavyweight dependencies from this file 9 | # will add to the boot time of your test suite on EVERY test run, even for an 10 | # individual file that may not need all of that loaded. Instead, consider making 11 | # a separate helper file that requires the additional dependencies and performs 12 | # the additional setup, and require it from the spec files that actually need 13 | # it. 14 | # 15 | # The `.rspec` file also contains a few flags that are not defaults but that 16 | # users commonly want. 17 | # 18 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration 19 | RSpec.configure do |config| 20 | # rspec-expectations config goes here. You can use an alternate 21 | # assertion/expectation library such as wrong or the stdlib/minitest 22 | # assertions if you prefer. 23 | config.expect_with :rspec do |expectations| 24 | # This option will default to `true` in RSpec 4. It makes the `description` 25 | # and `failure_message` of custom matchers include text for helper methods 26 | # defined using `chain`, e.g.: 27 | # be_bigger_than(2).and_smaller_than(4).description 28 | # # => "be bigger than 2 and smaller than 4" 29 | # ...rather than: 30 | # # => "be bigger than 2" 31 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 32 | end 33 | 34 | # rspec-mocks config goes here. You can use an alternate test double 35 | # library (such as bogus or mocha) by changing the `mock_with` option here. 36 | config.mock_with :rspec do |mocks| 37 | # Prevents you from mocking or stubbing a method that does not exist on 38 | # a real object. This is generally recommended, and will default to 39 | # `true` in RSpec 4. 40 | mocks.verify_partial_doubles = true 41 | end 42 | 43 | # The settings below are suggested to provide a good initial experience 44 | # with RSpec, but feel free to customize to your heart's content. 45 | =begin 46 | # These two settings work together to allow you to limit a spec run 47 | # to individual examples or groups you care about by tagging them with 48 | # `:focus` metadata. When nothing is tagged with `:focus`, all examples 49 | # get run. 50 | config.filter_run :focus 51 | config.run_all_when_everything_filtered = true 52 | 53 | # Allows RSpec to persist some state between runs in order to support 54 | # the `--only-failures` and `--next-failure` CLI options. We recommend 55 | # you configure your source control system to ignore this file. 56 | config.example_status_persistence_file_path = "spec/examples.txt" 57 | 58 | # Limits the available syntax to the non-monkey patched syntax that is 59 | # recommended. For more details, see: 60 | # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax 61 | # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ 62 | # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching 63 | config.disable_monkey_patching! 64 | 65 | # Many RSpec users commonly either run the entire suite or an individual 66 | # file, and it's useful to allow more verbose output when running an 67 | # individual spec file. 68 | if config.files_to_run.one? 69 | # Use the documentation formatter for detailed output, 70 | # unless a formatter has already been configured 71 | # (e.g. via a command-line flag). 72 | config.default_formatter = 'doc' 73 | end 74 | 75 | # Print the 10 slowest examples and example groups at the 76 | # end of the spec run, to help surface which specs are running 77 | # particularly slow. 78 | config.profile_examples = 10 79 | 80 | # Run specs in random order to surface order dependencies. If you find an 81 | # order dependency and want to debug it, you can fix the order by providing 82 | # the seed, which is printed after each run. 83 | # --seed 1234 84 | config.order = :random 85 | 86 | # Seed global randomization in this process using the `--seed` CLI option. 87 | # Setting this allows you to use `--seed` to deterministically reproduce 88 | # test failures related to randomization by passing the same `--seed` value 89 | # as the one that triggered the failure. 90 | Kernel.srand config.seed 91 | =end 92 | end 93 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (4.2.1) 5 | actionpack (= 4.2.1) 6 | actionview (= 4.2.1) 7 | activejob (= 4.2.1) 8 | mail (~> 2.5, >= 2.5.4) 9 | rails-dom-testing (~> 1.0, >= 1.0.5) 10 | actionpack (4.2.1) 11 | actionview (= 4.2.1) 12 | activesupport (= 4.2.1) 13 | rack (~> 1.6) 14 | rack-test (~> 0.6.2) 15 | rails-dom-testing (~> 1.0, >= 1.0.5) 16 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 17 | actionview (4.2.1) 18 | activesupport (= 4.2.1) 19 | builder (~> 3.1) 20 | erubis (~> 2.7.0) 21 | rails-dom-testing (~> 1.0, >= 1.0.5) 22 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 23 | activejob (4.2.1) 24 | activesupport (= 4.2.1) 25 | globalid (>= 0.3.0) 26 | activemodel (4.2.1) 27 | activesupport (= 4.2.1) 28 | builder (~> 3.1) 29 | activerecord (4.2.1) 30 | activemodel (= 4.2.1) 31 | activesupport (= 4.2.1) 32 | arel (~> 6.0) 33 | activesupport (4.2.1) 34 | i18n (~> 0.7) 35 | json (~> 1.7, >= 1.7.7) 36 | minitest (~> 5.1) 37 | thread_safe (~> 0.3, >= 0.3.4) 38 | tzinfo (~> 1.1) 39 | arel (6.0.0) 40 | binding_of_caller (0.7.2) 41 | debug_inspector (>= 0.0.1) 42 | builder (3.2.2) 43 | byebug (4.0.5) 44 | columnize (= 0.9.0) 45 | codemirror-rails (5.3) 46 | railties (>= 3.0, < 5) 47 | coderay (1.1.0) 48 | columnize (0.9.0) 49 | database_cleaner (1.4.1) 50 | debug_inspector (0.0.2) 51 | diff-lcs (1.2.5) 52 | dotenv (2.0.1) 53 | dotenv-rails (2.0.1) 54 | dotenv (= 2.0.1) 55 | erubis (2.7.0) 56 | factory_girl (4.5.0) 57 | activesupport (>= 3.0.0) 58 | globalid (0.3.5) 59 | activesupport (>= 4.1.0) 60 | i18n (0.7.0) 61 | jquery-rails (4.0.4) 62 | rails-dom-testing (~> 1.0) 63 | railties (>= 4.2.0) 64 | thor (>= 0.14, < 2.0) 65 | json (1.8.3) 66 | loofah (2.0.2) 67 | nokogiri (>= 1.5.9) 68 | mail (2.6.3) 69 | mime-types (>= 1.16, < 3) 70 | method_source (0.8.2) 71 | mime-types (2.6.1) 72 | mini_portile (0.6.2) 73 | minitest (5.7.0) 74 | nokogiri (1.6.6.2) 75 | mini_portile (~> 0.6.0) 76 | pg (0.18.2) 77 | powder (0.3.0) 78 | thor (>= 0.11.5) 79 | pry (0.10.1) 80 | coderay (~> 1.1.0) 81 | method_source (~> 0.8.1) 82 | slop (~> 3.4) 83 | pry-byebug (3.1.0) 84 | byebug (~> 4.0) 85 | pry (~> 0.10) 86 | rack (1.6.4) 87 | rack-test (0.6.3) 88 | rack (>= 1.0) 89 | rails (4.2.1) 90 | actionmailer (= 4.2.1) 91 | actionpack (= 4.2.1) 92 | actionview (= 4.2.1) 93 | activejob (= 4.2.1) 94 | activemodel (= 4.2.1) 95 | activerecord (= 4.2.1) 96 | activesupport (= 4.2.1) 97 | bundler (>= 1.3.0, < 2.0) 98 | railties (= 4.2.1) 99 | sprockets-rails 100 | rails-deprecated_sanitizer (1.0.3) 101 | activesupport (>= 4.2.0.alpha) 102 | rails-dom-testing (1.0.6) 103 | activesupport (>= 4.2.0.beta, < 5.0) 104 | nokogiri (~> 1.6.0) 105 | rails-deprecated_sanitizer (>= 1.0.1) 106 | rails-html-sanitizer (1.0.2) 107 | loofah (~> 2.0) 108 | railties (4.2.1) 109 | actionpack (= 4.2.1) 110 | activesupport (= 4.2.1) 111 | rake (>= 0.8.7) 112 | thor (>= 0.18.1, < 2.0) 113 | rake (10.4.2) 114 | rspec-core (3.3.1) 115 | rspec-support (~> 3.3.0) 116 | rspec-expectations (3.3.0) 117 | diff-lcs (>= 1.2.0, < 2.0) 118 | rspec-support (~> 3.3.0) 119 | rspec-mocks (3.3.1) 120 | diff-lcs (>= 1.2.0, < 2.0) 121 | rspec-support (~> 3.3.0) 122 | rspec-rails (3.3.2) 123 | actionpack (>= 3.0, < 4.3) 124 | activesupport (>= 3.0, < 4.3) 125 | railties (>= 3.0, < 4.3) 126 | rspec-core (~> 3.3.0) 127 | rspec-expectations (~> 3.3.0) 128 | rspec-mocks (~> 3.3.0) 129 | rspec-support (~> 3.3.0) 130 | rspec-support (3.3.0) 131 | sass (3.4.15) 132 | sass-rails (5.0.3) 133 | railties (>= 4.0.0, < 5.0) 134 | sass (~> 3.1) 135 | sprockets (>= 2.8, < 4.0) 136 | sprockets-rails (>= 2.0, < 4.0) 137 | tilt (~> 1.1) 138 | slim (3.0.3) 139 | temple (~> 0.7.3) 140 | tilt (>= 1.3.3, < 2.1) 141 | slim-rails (3.0.1) 142 | actionmailer (>= 3.1, < 5.0) 143 | actionpack (>= 3.1, < 5.0) 144 | activesupport (>= 3.1, < 5.0) 145 | railties (>= 3.1, < 5.0) 146 | slim (~> 3.0) 147 | slop (3.6.0) 148 | spring (1.3.6) 149 | sprockets (3.2.0) 150 | rack (~> 1.0) 151 | sprockets-rails (2.3.2) 152 | actionpack (>= 3.0) 153 | activesupport (>= 3.0) 154 | sprockets (>= 2.8, < 4.0) 155 | temple (0.7.5) 156 | thor (0.19.1) 157 | thread_safe (0.3.5) 158 | tilt (1.4.1) 159 | tzinfo (1.2.2) 160 | thread_safe (~> 0.1) 161 | web-console (2.1.3) 162 | activemodel (>= 4.0) 163 | binding_of_caller (>= 0.7.2) 164 | railties (>= 4.0) 165 | sprockets-rails (>= 2.0, < 4.0) 166 | 167 | PLATFORMS 168 | ruby 169 | 170 | DEPENDENCIES 171 | byebug 172 | codemirror-rails 173 | database_cleaner 174 | dotenv-rails 175 | factory_girl 176 | jquery-rails 177 | pg 178 | powder 179 | pry-byebug 180 | rails (= 4.2.1) 181 | rspec-rails 182 | sass-rails (~> 5.0) 183 | slim-rails 184 | spring 185 | web-console (~> 2.0) 186 | -------------------------------------------------------------------------------- /db/migrate/20150625192829_create_sample_data.rb: -------------------------------------------------------------------------------- 1 | class CreateSampleData < ActiveRecord::Migration 2 | def change 3 | 4 | sql = <<-SQL 5 | -- Create Tables 6 | CREATE TABLE artists 7 | ( 8 | id SERIAL PRIMARY KEY, 9 | name VARCHAR(120) 10 | ); 11 | 12 | CREATE TABLE albums 13 | ( 14 | id SERIAL PRIMARY KEY, 15 | title VARCHAR(160) NOT NULL, 16 | artist_id INTEGER NOT NULL, 17 | FOREIGN KEY (artist_id) REFERENCES artists (id) 18 | ON DELETE NO ACTION ON UPDATE NO ACTION 19 | ); 20 | 21 | CREATE TABLE employees 22 | ( 23 | id SERIAL PRIMARY KEY, 24 | last_name VARCHAR(20) NOT NULL, 25 | first_name VARCHAR(20) NOT NULL, 26 | title VARCHAR(30), 27 | reports_to INTEGER, 28 | birth_date TIMESTAMP, 29 | hire_date TIMESTAMP, 30 | address VARCHAR(70), 31 | city VARCHAR(40), 32 | state VARCHAR(40), 33 | country VARCHAR(40), 34 | postal_code VARCHAR(10), 35 | phone VARCHAR(24), 36 | fax VARCHAR(24), 37 | email VARCHAR(60), 38 | FOREIGN KEY (reports_to) REFERENCES employees (id) 39 | ON DELETE NO ACTION ON UPDATE NO ACTION 40 | ); 41 | 42 | CREATE TABLE customers 43 | ( 44 | id SERIAL PRIMARY KEY, 45 | first_name VARCHAR(40) NOT NULL, 46 | last_name VARCHAR(20) NOT NULL, 47 | company VARCHAR(80), 48 | address VARCHAR(70), 49 | city VARCHAR(40), 50 | state VARCHAR(40), 51 | country VARCHAR(40), 52 | postal_code VARCHAR(10), 53 | phone VARCHAR(24), 54 | fax VARCHAR(24), 55 | email VARCHAR(60) NOT NULL, 56 | support_rep_id INTEGER, 57 | FOREIGN KEY (support_rep_id) REFERENCES employees (id) 58 | ON DELETE NO ACTION ON UPDATE NO ACTION 59 | ); 60 | 61 | CREATE TABLE genres 62 | ( 63 | id SERIAL PRIMARY KEY, 64 | name VARCHAR(120) 65 | ); 66 | 67 | CREATE TABLE invoices 68 | ( 69 | id SERIAL PRIMARY KEY, 70 | customer_id INTEGER NOT NULL, 71 | invoice_date TIMESTAMP NOT NULL, 72 | billing_address VARCHAR(70), 73 | billing_city VARCHAR(40), 74 | billing_state VARCHAR(40), 75 | billing_country VARCHAR(40), 76 | billing_postal_code VARCHAR(10), 77 | total NUMERIC(10,2) NOT NULL, 78 | FOREIGN KEY (customer_id) REFERENCES customers (id) 79 | ON DELETE NO ACTION ON UPDATE NO ACTION 80 | ); 81 | 82 | CREATE TABLE media_types 83 | ( 84 | id SERIAL PRIMARY KEY, 85 | name VARCHAR(120) 86 | ); 87 | 88 | CREATE TABLE tracks 89 | ( 90 | id SERIAL PRIMARY KEY, 91 | name VARCHAR(200) NOT NULL, 92 | album_id INTEGER, 93 | media_type_id INTEGER NOT NULL, 94 | genre_id INTEGER, 95 | composer VARCHAR(220), 96 | milliseconds INTEGER NOT NULL, 97 | bytes INTEGER, 98 | unit_price NUMERIC(10,2) NOT NULL, 99 | FOREIGN KEY (album_id) REFERENCES albums (id) 100 | ON DELETE NO ACTION ON UPDATE NO ACTION, 101 | FOREIGN KEY (genre_id) REFERENCES genres (id) 102 | ON DELETE NO ACTION ON UPDATE NO ACTION, 103 | FOREIGN KEY (media_type_id) REFERENCES media_types (id) 104 | ON DELETE NO ACTION ON UPDATE NO ACTION 105 | ); 106 | 107 | CREATE TABLE invoice_lines 108 | ( 109 | id SERIAL PRIMARY KEY, 110 | invoice_id INTEGER NOT NULL, 111 | track_id INTEGER NOT NULL, 112 | unit_price NUMERIC(10,2) NOT NULL, 113 | quantity INTEGER NOT NULL, 114 | FOREIGN KEY (invoice_id) REFERENCES invoices (id) 115 | ON DELETE NO ACTION ON UPDATE NO ACTION, 116 | FOREIGN KEY (track_id) REFERENCES tracks (id) 117 | ON DELETE NO ACTION ON UPDATE NO ACTION 118 | ); 119 | 120 | CREATE TABLE playlists 121 | ( 122 | id SERIAL PRIMARY KEY, 123 | name VARCHAR(120) 124 | ); 125 | 126 | CREATE TABLE playlist_tracks 127 | ( 128 | playlist_id INTEGER NOT NULL, 129 | track_id INTEGER NOT NULL, 130 | CONSTRAINT PK_PlaylistTrack PRIMARY KEY (playlist_id, track_id), 131 | FOREIGN KEY (playlist_id) REFERENCES playlists (id) 132 | ON DELETE NO ACTION ON UPDATE NO ACTION, 133 | FOREIGN KEY (track_id) REFERENCES tracks (id) 134 | ON DELETE NO ACTION ON UPDATE NO ACTION 135 | ); 136 | 137 | 138 | -- Create Primary Key Unique Indexes 139 | 140 | CREATE UNIQUE INDEX index_album_on_id ON albums(id); 141 | 142 | CREATE UNIQUE INDEX index_artist_on_id ON artists(id); 143 | 144 | CREATE UNIQUE INDEX index_customer_on_id ON customers(id); 145 | 146 | CREATE UNIQUE INDEX index_employee_on_id ON employees(id); 147 | 148 | CREATE UNIQUE INDEX index_genre_on_id ON genres(id); 149 | 150 | CREATE UNIQUE INDEX index_invoice_on_id ON invoices(id); 151 | 152 | CREATE UNIQUE INDEX index_invoice_line_on_id ON invoice_lines(id); 153 | 154 | CREATE UNIQUE INDEX index_media_type_on_id ON media_types(id); 155 | 156 | CREATE UNIQUE INDEX index_playlist_on_id ON playlists(id); 157 | 158 | CREATE UNIQUE INDEX index_playlist_track_on_id ON playlist_tracks(playlist_id, track_id); 159 | 160 | CREATE UNIQUE INDEX index_track_on_id ON tracks(id); 161 | 162 | 163 | -- Create Foreign Keys 164 | 165 | CREATE INDEX index_album_on_artist_id ON albums (artist_id); 166 | 167 | CREATE INDEX index_customers_on_support_rep_id ON customers (support_rep_id); 168 | 169 | CREATE INDEX index_employees_on_reports_to ON employees (reports_to); 170 | 171 | CREATE INDEX index_invoices_on_customer_id ON invoices (customer_id); 172 | 173 | CREATE INDEX index_invoice_lines_on_invoice_id ON invoice_lines (invoice_id); 174 | 175 | CREATE INDEX index_invoice_lines_on_track_id ON invoice_lines (track_id); 176 | 177 | CREATE INDEX index_playlist_tracks_on_track_id ON playlist_tracks (track_id); 178 | 179 | CREATE INDEX index_tracks_on_album_id ON tracks (album_id); 180 | 181 | CREATE INDEX index_track_on_genre_id ON tracks (genre_id); 182 | 183 | CREATE INDEX index_track_on_media_type_id ON tracks (media_type_id); 184 | SQL 185 | 186 | execute(sql) 187 | end 188 | end 189 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 20150706195903) do 15 | 16 | # These are extensions that must be enabled in order to support this database 17 | enable_extension "plpgsql" 18 | 19 | create_table "albums", force: :cascade do |t| 20 | t.string "title", limit: 160, null: false 21 | t.integer "artist_id", null: false 22 | end 23 | 24 | add_index "albums", ["artist_id"], name: "index_album_on_artist_id", using: :btree 25 | add_index "albums", ["id"], name: "index_album_on_id", unique: true, using: :btree 26 | 27 | create_table "artists", force: :cascade do |t| 28 | t.string "name", limit: 120 29 | end 30 | 31 | add_index "artists", ["id"], name: "index_artist_on_id", unique: true, using: :btree 32 | 33 | create_table "challenges", force: :cascade do |t| 34 | t.string "instructions" 35 | t.string "query" 36 | t.datetime "created_at", null: false 37 | t.datetime "updated_at", null: false 38 | t.integer "order" 39 | t.json "metadata" 40 | end 41 | 42 | create_table "customers", force: :cascade do |t| 43 | t.string "first_name", limit: 40, null: false 44 | t.string "last_name", limit: 20, null: false 45 | t.string "company", limit: 80 46 | t.string "address", limit: 70 47 | t.string "city", limit: 40 48 | t.string "state", limit: 40 49 | t.string "country", limit: 40 50 | t.string "postal_code", limit: 10 51 | t.string "phone", limit: 24 52 | t.string "fax", limit: 24 53 | t.string "email", limit: 60, null: false 54 | t.integer "support_rep_id" 55 | end 56 | 57 | add_index "customers", ["id"], name: "index_customer_on_id", unique: true, using: :btree 58 | add_index "customers", ["support_rep_id"], name: "index_customers_on_support_rep_id", using: :btree 59 | 60 | create_table "employees", force: :cascade do |t| 61 | t.string "last_name", limit: 20, null: false 62 | t.string "first_name", limit: 20, null: false 63 | t.string "title", limit: 30 64 | t.integer "reports_to" 65 | t.datetime "birth_date" 66 | t.datetime "hire_date" 67 | t.string "address", limit: 70 68 | t.string "city", limit: 40 69 | t.string "state", limit: 40 70 | t.string "country", limit: 40 71 | t.string "postal_code", limit: 10 72 | t.string "phone", limit: 24 73 | t.string "fax", limit: 24 74 | t.string "email", limit: 60 75 | end 76 | 77 | add_index "employees", ["id"], name: "index_employee_on_id", unique: true, using: :btree 78 | add_index "employees", ["reports_to"], name: "index_employees_on_reports_to", using: :btree 79 | 80 | create_table "genres", force: :cascade do |t| 81 | t.string "name", limit: 120 82 | end 83 | 84 | add_index "genres", ["id"], name: "index_genre_on_id", unique: true, using: :btree 85 | 86 | create_table "invoice_lines", force: :cascade do |t| 87 | t.integer "invoice_id", null: false 88 | t.integer "track_id", null: false 89 | t.decimal "unit_price", precision: 10, scale: 2, null: false 90 | t.integer "quantity", null: false 91 | end 92 | 93 | add_index "invoice_lines", ["id"], name: "index_invoice_line_on_id", unique: true, using: :btree 94 | add_index "invoice_lines", ["invoice_id"], name: "index_invoice_lines_on_invoice_id", using: :btree 95 | add_index "invoice_lines", ["track_id"], name: "index_invoice_lines_on_track_id", using: :btree 96 | 97 | create_table "invoices", force: :cascade do |t| 98 | t.integer "customer_id", null: false 99 | t.datetime "invoice_date", null: false 100 | t.string "billing_address", limit: 70 101 | t.string "billing_city", limit: 40 102 | t.string "billing_state", limit: 40 103 | t.string "billing_country", limit: 40 104 | t.string "billing_postal_code", limit: 10 105 | t.decimal "total", precision: 10, scale: 2, null: false 106 | end 107 | 108 | add_index "invoices", ["customer_id"], name: "index_invoices_on_customer_id", using: :btree 109 | add_index "invoices", ["id"], name: "index_invoice_on_id", unique: true, using: :btree 110 | 111 | create_table "media_types", force: :cascade do |t| 112 | t.string "name", limit: 120 113 | end 114 | 115 | add_index "media_types", ["id"], name: "index_media_type_on_id", unique: true, using: :btree 116 | 117 | create_table "playlist_tracks", id: false, force: :cascade do |t| 118 | t.integer "playlist_id", null: false 119 | t.integer "track_id", null: false 120 | end 121 | 122 | add_index "playlist_tracks", ["playlist_id", "track_id"], name: "index_playlist_track_on_id", unique: true, using: :btree 123 | add_index "playlist_tracks", ["track_id"], name: "index_playlist_tracks_on_track_id", using: :btree 124 | 125 | create_table "playlists", force: :cascade do |t| 126 | t.string "name", limit: 120 127 | end 128 | 129 | add_index "playlists", ["id"], name: "index_playlist_on_id", unique: true, using: :btree 130 | 131 | create_table "tracks", force: :cascade do |t| 132 | t.string "name", limit: 200, null: false 133 | t.integer "album_id" 134 | t.integer "media_type_id", null: false 135 | t.integer "genre_id" 136 | t.string "composer", limit: 220 137 | t.integer "milliseconds", null: false 138 | t.integer "bytes" 139 | t.decimal "unit_price", precision: 10, scale: 2, null: false 140 | end 141 | 142 | add_index "tracks", ["album_id"], name: "index_tracks_on_album_id", using: :btree 143 | add_index "tracks", ["genre_id"], name: "index_track_on_genre_id", using: :btree 144 | add_index "tracks", ["id"], name: "index_track_on_id", unique: true, using: :btree 145 | add_index "tracks", ["media_type_id"], name: "index_track_on_media_type_id", using: :btree 146 | 147 | add_foreign_key "albums", "artists", name: "albums_artist_id_fkey" 148 | add_foreign_key "customers", "employees", column: "support_rep_id", name: "customers_support_rep_id_fkey" 149 | add_foreign_key "employees", "employees", column: "reports_to", name: "employees_reports_to_fkey" 150 | add_foreign_key "invoice_lines", "invoices", name: "invoice_lines_invoice_id_fkey" 151 | add_foreign_key "invoice_lines", "tracks", name: "invoice_lines_track_id_fkey" 152 | add_foreign_key "invoices", "customers", name: "invoices_customer_id_fkey" 153 | add_foreign_key "playlist_tracks", "playlists", name: "playlist_tracks_playlist_id_fkey" 154 | add_foreign_key "playlist_tracks", "tracks", name: "playlist_tracks_track_id_fkey" 155 | add_foreign_key "tracks", "albums", name: "tracks_album_id_fkey" 156 | add_foreign_key "tracks", "genres", name: "tracks_genre_id_fkey" 157 | add_foreign_key "tracks", "media_types", name: "tracks_media_type_id_fkey" 158 | end 159 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/basscss.min.css: -------------------------------------------------------------------------------- 1 | body{margin:0}img{max-width:100%}svg{max-height:100%}fieldset,input,select,textarea{font-family:inherit;font-size:1rem;box-sizing:border-box;margin-top:0;margin-bottom:0}label{vertical-align:middle}input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{height:2.25rem;padding:.5rem .5rem;vertical-align:middle;-webkit-appearance:none}select{line-height:1.75;padding:.5rem .5rem}select:not([multiple]){height:2.25rem;vertical-align:middle}textarea{line-height:1.75;padding:.5rem .5rem}table{border-collapse:separate;border-spacing:0;max-width:100%;width:100%}th{text-align:left;font-weight:700}td,th{padding:.25rem 1rem;line-height:inherit}th{vertical-align:bottom}td{vertical-align:top}body{font-family:'Helvetica Neue',Helvetica,sans-serif;line-height:1.5;font-size:100%}h1,h2,h3,h4,h5,h6{font-family:'Helvetica Neue',Helvetica,sans-serif;font-weight:700;line-height:1.25;margin-top:1em;margin-bottom:.5em}p{margin-top:0;margin-bottom:1rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}code,pre,samp{font-family:'Source Code Pro',Consolas,monospace;font-size:inherit}pre{margin-top:0;margin-bottom:1rem;overflow-x:scroll}h1{font-size:2rem}h2{font-size:1.5rem}h3{font-size:1.25rem}h4{font-size:1rem}h5{font-size:.875rem}h6{font-size:.75rem}body{color:#111;background-color:#fff}a{color:#0074d9;text-decoration:none}a:hover{text-decoration:underline}code,pre{background-color:transparent;border-radius:3px}hr{border:0;border-bottom-style:solid;border-bottom-width:1px;border-bottom-color:rgba(0,0,0,.125)}.field{border-style:solid;border-width:1px;border-color:rgba(0,0,0,.125);border-radius:3px}.field.is-focused,.field:focus{outline:0;border-color:#0074d9;box-shadow:0 0 0 2px rgba(0,116,217,.5)}.field.is-disabled,.field:disabled{background-color:rgba(0,0,0,.125);opacity:.5}.field.is-read-only,.field:read-only:not(select){background-color:rgba(0,0,0,.125)}.field.is-success{border-color:#2ecc40}.field.is-success.is-focused,.field.is-success:focus{box-shadow:0 0 0 2px rgba(46,204,64,.5)}.field.is-warning{border-color:#ffdc00}.field.is-warning.is-focused,.field.is-warning:focus{box-shadow:0 0 0 2px rgba(255,220,0,.5)}.field.is-error,.field:invalid{border-color:#ff4136}.field.is-error.is-focused,.field.is-error:focus,.field:invalid.is-focused,.field:invalid:focus{box-shadow:0 0 0 2px rgba(255,65,54,.5)}.table-light td,.table-light th{border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgba(0,0,0,.125)}.table-light tr:last-child td{border-bottom:0}.btn{font-family:inherit;font-size:inherit;font-weight:700;text-decoration:none;cursor:pointer;display:inline-block;line-height:1.125rem;padding:.5rem 1rem;margin:0;height:auto;border:1px solid transparent;vertical-align:middle;-webkit-appearance:none;color:inherit;background-color:transparent}.btn:hover{text-decoration:none}.btn:focus{outline:0;border-color:rgba(0,0,0,.125);box-shadow:0 0 0 3px rgba(0,0,0,.25)}::-moz-focus-inner{border:0;padding:0}.btn-primary{color:#fff;background-color:#0074d9;border-radius:3px}.btn-primary:hover{box-shadow:inset 0 0 0 20rem rgba(0,0,0,.0625)}.btn-primary:active{box-shadow:inset 0 0 0 20rem rgba(0,0,0,.125),inset 0 3px 4px 0 rgba(0,0,0,.25),0 0 1px rgba(0,0,0,.125)}.btn-primary.is-disabled,.btn-primary:disabled{opacity:.5}.btn-outline,.btn-outline:hover{border-color:currentcolor}.btn-outline{border-radius:3px}.btn-outline:hover{box-shadow:inset 0 0 0 20rem rgba(0,0,0,.0625)}.btn-outline:active{box-shadow:inset 0 0 0 20rem rgba(0,0,0,.125),inset 0 3px 4px 0 rgba(0,0,0,.25),0 0 1px rgba(0,0,0,.125)}.btn-outline.is-disabled,.btn-outline:disabled{opacity:.5}.h1{font-size:2rem}.h2{font-size:1.5rem}.h3{font-size:1.25rem}.h4{font-size:1rem}.h5{font-size:.875rem}.h6{font-size:.75rem}.bold{font-weight:700}.regular{font-weight:400}.italic{font-style:italic}.caps{text-transform:uppercase;letter-spacing:.2em}.left-align{text-align:left}.center{text-align:center}.right-align{text-align:right}.justify{text-align:justify}.nowrap{white-space:nowrap}.break-word{word-wrap:break-word}.truncate{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.list-reset{list-style:none;padding-left:0}.inline{display:inline}.block{display:block}.inline-block{display:inline-block}.table{display:table}.table-cell{display:table-cell}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-auto{overflow:auto}.clearfix:after,.clearfix:before{content:" ";display:table}.clearfix:after{clear:both}.left{float:left}.right{float:right}.fit{max-width:100%}.border-box{box-sizing:border-box}.align-baseline{vertical-align:baseline}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.align-bottom{vertical-align:bottom}.m0{margin:0}.mt0{margin-top:0}.mr0{margin-right:0}.mb0{margin-bottom:0}.ml0{margin-left:0}.m1{margin:.5rem}.mt1{margin-top:.5rem}.mr1{margin-right:.5rem}.mb1{margin-bottom:.5rem}.ml1{margin-left:.5rem}.m2{margin:1rem}.mt2{margin-top:1rem}.mr2{margin-right:1rem}.mb2{margin-bottom:1rem}.ml2{margin-left:1rem}.m3{margin:2rem}.mt3{margin-top:2rem}.mr3{margin-right:2rem}.mb3{margin-bottom:2rem}.ml3{margin-left:2rem}.m4{margin:4rem}.mt4{margin-top:4rem}.mr4{margin-right:4rem}.mb4{margin-bottom:4rem}.ml4{margin-left:4rem}.mxn1{margin-left:-.5rem;margin-right:-.5rem}.mxn2{margin-left:-1rem;margin-right:-1rem}.mxn3{margin-left:-2rem;margin-right:-2rem}.mxn4{margin-left:-4rem;margin-right:-4rem}.mx-auto{margin-left:auto;margin-right:auto}.p0{padding:0}.p1{padding:.5rem}.py1{padding-top:.5rem;padding-bottom:.5rem}.px1{padding-left:.5rem;padding-right:.5rem}.p2{padding:1rem}.py2{padding-top:1rem;padding-bottom:1rem}.px2{padding-left:1rem;padding-right:1rem}.p3{padding:2rem}.py3{padding-top:2rem;padding-bottom:2rem}.px3{padding-left:2rem;padding-right:2rem}.p4{padding:4rem}.py4{padding-top:4rem;padding-bottom:4rem}.px4{padding-left:4rem;padding-right:4rem}.relative{position:relative}.absolute{position:absolute}.fixed{position:fixed}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.z1{z-index:1}.z2{z-index:2}.z3{z-index:3}.z4{z-index:4}.lg-show,.md-show,.sm-show{display:none!important}@media (min-width:40em){.sm-show{display:block!important}}@media (min-width:52em){.md-show{display:block!important}}@media (min-width:64em){.lg-show{display:block!important}}@media (min-width:40em){.sm-hide{display:none!important}}@media (min-width:52em){.md-hide{display:none!important}}@media (min-width:64em){.lg-hide{display:none!important}}.display-none{display:none!important}.hide{position:absolute!important;height:1px;width:1px;overflow:hidden;clip:rect(1px,1px,1px,1px)}.container{max-width:64em;margin-left:auto;margin-right:auto}.col{float:left;box-sizing:border-box}.col-right{float:right;box-sizing:border-box}.col-1{width:8.33333%}.col-2{width:16.66667%}.col-3{width:25%}.col-4{width:33.33333%}.col-5{width:41.66667%}.col-6{width:50%}.col-7{width:58.33333%}.col-8{width:66.66667%}.col-9{width:75%}.col-10{width:83.33333%}.col-11{width:91.66667%}.col-12{width:100%}@media (min-width:40em){.sm-col{float:left;box-sizing:border-box}.sm-col-right{float:right;box-sizing:border-box}.sm-col-1{width:8.33333%}.sm-col-2{width:16.66667%}.sm-col-3{width:25%}.sm-col-4{width:33.33333%}.sm-col-5{width:41.66667%}.sm-col-6{width:50%}.sm-col-7{width:58.33333%}.sm-col-8{width:66.66667%}.sm-col-9{width:75%}.sm-col-10{width:83.33333%}.sm-col-11{width:91.66667%}.sm-col-12{width:100%}}@media (min-width:52em){.md-col{float:left;box-sizing:border-box}.md-col-right{float:right;box-sizing:border-box}.md-col-1{width:8.33333%}.md-col-2{width:16.66667%}.md-col-3{width:25%}.md-col-4{width:33.33333%}.md-col-5{width:41.66667%}.md-col-6{width:50%}.md-col-7{width:58.33333%}.md-col-8{width:66.66667%}.md-col-9{width:75%}.md-col-10{width:83.33333%}.md-col-11{width:91.66667%}.md-col-12{width:100%}}@media (min-width:64em){.lg-col{float:left;box-sizing:border-box}.lg-col-right{float:right;box-sizing:border-box}.lg-col-1{width:8.33333%}.lg-col-2{width:16.66667%}.lg-col-3{width:25%}.lg-col-4{width:33.33333%}.lg-col-5{width:41.66667%}.lg-col-6{width:50%}.lg-col-7{width:58.33333%}.lg-col-8{width:66.66667%}.lg-col-9{width:75%}.lg-col-10{width:83.33333%}.lg-col-11{width:91.66667%}.lg-col-12{width:100%}}.flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.flex-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.flex-wrap{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-center{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.flex-baseline{-webkit-box-align:baseline;-webkit-align-items:baseline;-ms-flex-align:baseline;align-items:baseline}.flex-stretch{-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch}.flex-start{-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start}.flex-end{-webkit-box-align:end;-webkit-align-items:flex-end;-ms-flex-align:end;align-items:flex-end}.flex-justify{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.flex-auto{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}.flex-grow{-webkit-box-flex:1;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto}.flex-none{-webkit-box-flex:0;-webkit-flex:none;-ms-flex:none;flex:none}.flex-first{-webkit-box-ordinal-group:0;-webkit-order:-1;-ms-flex-order:-1;order:-1}.flex-last{-webkit-box-ordinal-group:100000;-webkit-order:99999;-ms-flex-order:99999;order:99999}@media (min-width:40em){.sm-flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}}@media (min-width:52em){.md-flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}}@media (min-width:64em){.lg-flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}}.border{border-style:solid;border-width:1px;border-color:rgba(0,0,0,.125)}.border-top{border-top-style:solid;border-top-width:1px;border-top-color:rgba(0,0,0,.125)}.border-right{border-right-style:solid;border-right-width:1px;border-right-color:rgba(0,0,0,.125)}.border-bottom{border-bottom-style:solid;border-bottom-width:1px;border-bottom-color:rgba(0,0,0,.125)}.border-left{border-left-style:solid;border-left-width:1px;border-left-color:rgba(0,0,0,.125)}.border-none{border:0}.rounded{border-radius:3px}.circle{border-radius:50%}.rounded-top{border-radius:3px 3px 0 0}.rounded-right{border-radius:0 3px 3px 0}.rounded-bottom{border-radius:0 0 3px 3px}.rounded-left{border-radius:3px 0 0 3px}.not-rounded{border-radius:0}.black{color:#111}.gray{color:#aaa}.silver{color:#ddd}.white{color:#fff}.aqua{color:#7fdbff}.blue{color:#0074d9}.navy{color:#001f3f}.teal{color:#39cccc}.green{color:#2ecc40}.olive{color:#3d9970}.lime{color:#01ff70}.yellow{color:#ffdc00}.orange{color:#ff851b}.red{color:#ff4136}.fuchsia{color:#f012be}.purple{color:#b10dc9}.maroon{color:#85144b}.color-inherit{color:inherit}.muted{opacity:.5}.bg-black{background-color:#111}.bg-gray{background-color:#aaa}.bg-silver{background-color:#ddd}.bg-white{background-color:#fff}.bg-aqua{background-color:#7fdbff}.bg-blue{background-color:#0074d9}.bg-navy{background-color:#001f3f}.bg-teal{background-color:#39cccc}.bg-green{background-color:#2ecc40}.bg-olive{background-color:#3d9970}.bg-lime{background-color:#01ff70}.bg-yellow{background-color:#ffdc00}.bg-orange{background-color:#ff851b}.bg-red{background-color:#ff4136}.bg-fuchsia{background-color:#f012be}.bg-purple{background-color:#b10dc9}.bg-maroon{background-color:#85144b}.bg-darken-1{background-color:rgba(0,0,0,.0625)}.bg-darken-2{background-color:rgba(0,0,0,.125)}.bg-darken-3{background-color:rgba(0,0,0,.25)}.bg-darken-4{background-color:rgba(0,0,0,.5)} -------------------------------------------------------------------------------- /db/challenge_seeds.json: -------------------------------------------------------------------------------- 1 | { 2 | "fields": [ 3 | "query", 4 | "instructions", 5 | "order", 6 | "metadata" 7 | ], 8 | "values": [ 9 | [ 10 | "SELECT * FROM invoices;", 11 | "Give me a list of all invoices", 12 | 1, 13 | {"tables": ["invoices"], "topic": "select"} 14 | ], 15 | [ 16 | "SELECT * FROM artists;", 17 | "Give me a list of all artists", 18 | 2, 19 | {"tables": ["artists"], "topic": "select"} 20 | ], 21 | [ 22 | "SELECT name FROM artists;", 23 | "Give me the name of every artist", 24 | 3, 25 | {"tables": ["artists"], "topic": "select"} 26 | ], 27 | [ 28 | "SELECT first_name, last_name FROM employees;", 29 | "Give me the first and last names of every employee", 30 | 4, 31 | {"tables": ["employees"], "topic": "select"} 32 | ], 33 | [ 34 | "SELECT name FROM media_types;", 35 | "Give me the names of every media type", 36 | 5, 37 | {"tables": ["media_types"], "topic": "select"} 38 | ], 39 | [ 40 | "SELECT * FROM employees ORDER BY hire_date DESC;", 41 | "Give me a list of every employee by hire date in descending order", 42 | 6, 43 | {"tables": ["employees"], "topic": "order by"} 44 | ], 45 | [ 46 | "SELECT hire_date, first_name, last_name FROM employees WHERE hire_date \u003c '2011-02-15';", 47 | "Give me the hire date, first name, and last name of all employees hired before February 15, 2011", 48 | 7, 49 | {"tables": ["employees"], "topic": "where"} 50 | ], 51 | [ 52 | "SELECT * FROM employees WHERE last_name LIKE 'A%';", 53 | "Give me a list of all employees whose name begins with \"A\"", 54 | 8, 55 | {"tables": ["employees"], "topic": "where"} 56 | ], 57 | [ 58 | "SELECT * FROM invoices WHERE billing_state = 'WA' AND billing_city = 'Redmond';", 59 | "Give me a list of all invoices from Redmond, WA", 60 | 9, 61 | {"tables": ["invoices"], "topic": "where"} 62 | ], 63 | [ 64 | "SELECT * FROM invoices WHERE billing_country = 'Germany' AND billing_city = 'Berlin';", 65 | "Give me a list of all invoices from Berlin, Germany", 66 | 10, 67 | {"tables": ["invoices"], "topic": "where"} 68 | ], 69 | [ 70 | "SELECT * FROM invoices WHERE billing_country = 'Canada';", 71 | "Give me a list of all invoices from Canada", 72 | 11, 73 | {"tables": ["invoices"], "topic": "where"} 74 | ], 75 | [ 76 | "SELECT * FROM invoices WHERE billing_country = 'Canada' AND billing_state = 'AB';", 77 | "Give me a list of all invoices from Alberta (AB), Canada", 78 | 12, 79 | {"tables": ["invoices"], "topic": "where"} 80 | ], 81 | [ 82 | "SELECT * FROM invoices WHERE billing_country = 'Canada' AND billing_state = 'AB' AND billing_city = 'Edmonton';", 83 | "Give me a list of all invoices from Edmonton, Alberta (AB), Canada", 84 | 13, 85 | {"tables": ["invoices"], "topic": "where"} 86 | ], 87 | [ 88 | "SELECT billing_address FROM invoices WHERE billing_state = 'WA' AND billing_city = 'Redmond';", 89 | "Give me the billing addresses from every invoice from Redmond, WA", 90 | 14, 91 | {"tables": ["invoices"], "topic": "where"} 92 | ], 93 | [ 94 | "SELECT * FROM invoices WHERE billing_state = 'NV' AND billing_city = 'Reno' AND total \u003e 5;", 95 | "Give me a list of all invoices for more than $5.00 from Reno, NV", 96 | 15, 97 | {"tables": ["invoices"], "topic": "where"} 98 | ], 99 | [ 100 | "SELECT * FROM tracks WHERE composer IS NULL;", 101 | "Give me a list of every track without a composer", 102 | 16, 103 | {"tables": ["tracks"], "topic": "where"} 104 | ], 105 | [ 106 | "SELECT * FROM customers WHERE company IS NULL;", 107 | "Give me a list of every customer not associated with a company", 108 | 17, 109 | {"tables": ["customers"], "topic": "where"} 110 | ], 111 | [ 112 | "SELECT * FROM invoices WHERE billing_state = 'WA' AND billing_city = 'Redmond' ORDER BY total ASC;", 113 | "Give me a list of all invoices from Redmond, WA sorted from low-to-high by total", 114 | 18, 115 | {"tables": ["invoices"], "topic": "where"} 116 | ], 117 | [ 118 | "SELECT * FROM invoices WHERE billing_state = 'WA' AND billing_city = 'Redmond' ORDER BY total DESC;", 119 | "Give me a list of all invoices from Redmond, WA sorted from high-to-low by total", 120 | 19, 121 | {"tables": ["invoices"], "topic": "where"} 122 | ], 123 | [ 124 | "SELECT * FROM invoices WHERE billing_country = 'Germany' ORDER BY total DESC;", 125 | "Give me a list of all invoices from Germany sorted from high-to-low by total", 126 | 20, 127 | {"tables": ["invoices"], "topic": "where"} 128 | ], 129 | [ 130 | "SELECT * FROM invoices WHERE billing_country = 'Germany' ORDER BY total DESC LIMIT 10;", 131 | "Give me a list of the 10 most expensive invoices from Germany", 132 | 21, 133 | {"tables": ["invoices"], "topic": "where"} 134 | ], 135 | [ 136 | "SELECT * FROM invoices WHERE billing_state = 'MA' AND billing_city = 'Boston' ORDER BY total DESC LIMIT 10;", 137 | "Give me a list of the 10 most expensive invoices from Boston, MA", 138 | 22, 139 | {"tables": ["invoices"], "topic": "where"} 140 | ], 141 | [ 142 | "SELECT * FROM invoices WHERE billing_state = 'MA' AND billing_city = 'Boston' ORDER BY total ASC LIMIT 10;", 143 | "Give me a list of the 10 least expensive invoices from Boston, MA", 144 | 23, 145 | {"tables": ["invoices"], "topic": "where"} 146 | ], 147 | [ 148 | "SELECT billing_address FROM invoices WHERE billing_state = 'CA' AND billing_city = 'Cupertino' ORDER BY total DESC LIMIT 3;", 149 | "Give me the street addresses of the 3 most expensive invoices from Cupertino, CA", 150 | 24, 151 | {"tables": ["invoices"], "topic": "where"} 152 | ], 153 | [ 154 | "SELECT * FROM invoices WHERE billing_state = 'CA' AND (billing_city = 'Mountain View' OR billing_city = 'Cupertino');", 155 | "Give me a list of all invoices from either Cupertino, CA or Mountain View, CA", 156 | 25, 157 | {"tables": ["invoices"], "topic": "where"} 158 | ], 159 | [ 160 | "SELECT count(*) FROM invoices WHERE billing_city = 'Santiago';", 161 | "Find the number of invoices sent to the city of \"Santiago\"", 162 | 26, 163 | {"tables": ["invoices"], "topic": "where"} 164 | ], 165 | [ 166 | "SELECT country, COUNT(*) FROM customers GROUP BY country;", 167 | "Give me a count of the number of customers by country", 168 | 27, 169 | {"tables": ["customers"], "topic": "group by"} 170 | ], 171 | [ 172 | "SELECT unit_price, COUNT(*) FROM tracks GROUP BY unit_price;", 173 | "Give me a count of the number of tracks by unit price", 174 | 28, 175 | {"tables": ["tracks"], "topic": "group by"} 176 | ], 177 | [ 178 | "SELECT name FROM artists WHERE name LIKE '%smith%';", 179 | "Give me a list of all names of artists whose name contains \"smith\".", 180 | 29, 181 | {"tables": ["artists"], "topic": "where"} 182 | ], 183 | [ 184 | "SELECT name FROM artists WHERE name LIKE '%smith';", 185 | "Give me a list of names of artists whose name ends with \"smith\".", 186 | 30, 187 | {"tables": ["artists"], "topic": "where"} 188 | ], 189 | [ 190 | "SELECT city, COUNT(*) FROM employees GROUP BY city;", 191 | "Give me a count of the number of employees by city", 192 | 31, 193 | {"tables": ["employees"], "topic": "group by"} 194 | ], 195 | [ 196 | "SELECT country, COUNT(*) FROM customers GROUP BY country ORDER BY COUNT(*) DESC LIMIT 3", 197 | "Give me a list of the top 3 countries by number of customers in descending order", 198 | 32, 199 | {"tables": ["customers"], "topic": "group by"} 200 | ], 201 | [ 202 | "SELECT billing_city, COUNT(*) FROM invoices GROUP BY billing_city ORDER BY COUNT(*) DESC LIMIT 5", 203 | "Give me a list of the top 5 cities by number of invoices in descending order", 204 | 33, 205 | {"tables": ["invoices"], "topic": "group by"} 206 | ], 207 | [ 208 | "SELECT ar.name, al.title FROM artists AS ar JOIN albums AS al ON al.artist_id = ar.id;", 209 | "List all artist names alongside the titles of their albums", 210 | 34, 211 | {"tables": ["artists", "albums"], "topic": "join"} 212 | ], 213 | [ 214 | "SELECT tr.name, al.title FROM albums AS al JOIN tracks AS tr ON tr.album_id = al.id;", 215 | "List all album names along with their track titles", 216 | 35, 217 | {"tables": ["albums", "tracks"], "topic": "join"} 218 | ], 219 | [ 220 | "SELECT ar.name, al.title FROM artists AS ar JOIN albums AS al ON al.artist_id = ar.id ORDER BY ar.name;", 221 | "List all artist names alongside the titles of their albums, in alphabetical order by artist name", 222 | 36, 223 | {"tables": ["albums", "artists"], "topic": "join"} 224 | ], 225 | [ 226 | "SELECT cs.first_name, cs.last_name, inv.total FROM customers AS cs JOIN invoices AS inv ON cs.id = inv.customer_id ORDER BY inv.total DESC;", 227 | "List all customers' first and last names next to the totals on their invoices, ordered by total, high to low", 228 | 37, 229 | {"tables": ["customers", "invoices"], "topic": "join"} 230 | ], 231 | [ 232 | "SELECT * FROM customers AS cs JOIN invoices AS inv ON cs.id = inv.customer_id ORDER BY inv.total DESC LIMIT 1;", 233 | "Give me the customer (and their invoice) with the highest invoice total", 234 | 38, 235 | {"tables": ["customers", "invoices"], "topic": "join"} 236 | ], 237 | [ 238 | "SELECT * FROM albums AS al JOIN artists AS ar ON ar.id = al.artist_id WHERE ar.name = 'Aerosmith';", 239 | "Give me a list of every Aerosmith album", 240 | 39, 241 | {"tables": ["albums", "artists"], "topic": "join"} 242 | ], 243 | [ 244 | "SELECT * FROM albums AS al JOIN artists AS ar ON ar.id = al.artist_id WHERE ar.name = 'Iron Maiden';", 245 | "Give me a list of every Iron Maiden album", 246 | 40, 247 | {"tables": ["albums", "artists"], "topic": "join"} 248 | ], 249 | [ 250 | "SELECT * FROM albums AS al JOIN tracks AS tr ON tr.album_id = al.id WHERE tr.name = 'Midnight';", 251 | "Give me a list of albums that contains a song called \"Midnight\"", 252 | 41, 253 | {"tables": ["albums", "tracks"], "topic": "join"} 254 | ], 255 | [ 256 | "SELECT * FROM artists AS ar JOIN albums AS al ON ar.id = al.artist_id JOIN tracks AS tr ON tr.album_id = al.id WHERE tr.name = 'Midnight';", 257 | "Give me a list of every artist who has performed the song \"Midnight\"", 258 | 42, 259 | {"tables": ["albums", "artists", "tracks"], "topic": "join"} 260 | ], 261 | [ 262 | "SELECT COUNT(*) FROM albums AS al JOIN artists AS ar ON ar.id = al.artist_id WHERE ar.name = 'Iron Maiden';", 263 | "Give me a count of the number of albums by Iron Maiden", 264 | 43, 265 | {"tables": ["albums", "artists"], "topic": "join"} 266 | ], 267 | [ 268 | "SELECT ar.name, COUNT(*) FROM artists AS ar JOIN albums AS al ON ar.id = al.artist_id GROUP BY ar.id ORDER BY ar.name", 269 | "List all artists and the number of albums they each have", 270 | 44, 271 | {"tables": ["artists", "albums"], "topic": "join"} 272 | ], 273 | [ 274 | "SELECT a.title, COUNT(*) FROM albums AS a JOIN tracks AS t ON (t.album_id = a.id) GROUP BY a.id ORDER BY a.title", 275 | "List all albums next to the number of tracks they each have", 276 | 45, 277 | {"tables": ["albums", "tracks"], "topic": "join"} 278 | ], 279 | [ 280 | "SELECT ar.*, COUNT(*) AS count FROM artists AS ar JOIN albums AS al ON ar.id = al.artist_id GROUP BY ar.id ORDER BY count DESC LIMIT 1;", 281 | "Find the artist with the most albums", 282 | 46, 283 | {"tables": ["artists", "albums"], "topic": "join"} 284 | ], 285 | [ 286 | "SELECT al.*, COUNT(*) AS count FROM tracks AS tr JOIN albums AS al ON tr.album_id = al.id GROUP BY al.id ORDER BY count DESC LIMIT 1;", 287 | "Find the album with the most tracks", 288 | 47, 289 | {"tables": ["tracks", "albums"], "topic": "join"} 290 | ], 291 | [ 292 | "SELECT cs.first_name, cs.last_name, SUM(inv.total) AS sum FROM customers AS cs JOIN invoices AS inv ON cs.id = inv.customer_id GROUP BY cs.id ORDER BY sum DESC LIMIT 5;", 293 | "List the names of the top five customers based on the sums of their invoice totals", 294 | 48, 295 | {"tables": ["customers", "invoices"], "topic": "join"} 296 | ], 297 | [ 298 | "SELECT * FROM artists ORDER BY name ASC;", 299 | "Give me a list of all artists sorted alphabetically by first name", 300 | 49, 301 | {"tables": ["artists"], "topic": "order by"} 302 | ], 303 | [ 304 | "SELECT al.*, COUNT(*) count FROM albums al JOIN tracks t ON (t.album_id = al.id) GROUP BY al.id ORDER BY count DESC", 305 | "List all albums next to the number of tracks they each have in descending order", 306 | 50, 307 | {"tables": ["albums", "tracks"], "topic": "join"} 308 | ], 309 | [ 310 | "SELECT ar.*, COUNT(*) AS count FROM artists AS ar JOIN albums AS al ON ar.id = al.artist_id GROUP BY ar.id ORDER BY count DESC, ar.name;", 311 | "List all artists and the number of albums they each have in descending order and then by artist name in ascending order", 312 | 51, 313 | {"tables": ["artists", "albums"], "topic": "join"} 314 | ] 315 | ] 316 | } 317 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/basscss.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Basscss v7.0.0 4 | Low-level CSS toolkit 5 | http://basscss.com 6 | 7 | 14.59 kB 8 | 3.32 kB Gzipped 9 | 282 Rules 10 | 324 Selectors 11 | 435 Declarations 12 | 93 Properties 13 | 14 | */ 15 | 16 | 17 | 18 | body { margin: 0 } 19 | img { max-width: 100% } 20 | svg { max-height: 100% } 21 | 22 | input, 23 | select, 24 | textarea, 25 | fieldset { 26 | font-family: inherit; 27 | font-size: 1rem; 28 | box-sizing: border-box; 29 | margin-top: 0; 30 | margin-bottom: 0; 31 | } 32 | 33 | label { 34 | vertical-align: middle; 35 | } 36 | 37 | input[type=text], 38 | input[type=date], 39 | input[type=datetime], 40 | input[type=datetime-local], 41 | input[type=email], 42 | input[type=month], 43 | input[type=number], 44 | input[type=password], 45 | input[type=search], 46 | input[type=tel], 47 | input[type=time], 48 | input[type=url], 49 | input[type=week] { 50 | height: 2.25rem; 51 | padding: .5rem .5rem; 52 | vertical-align: middle; 53 | -webkit-appearance: none; 54 | } 55 | 56 | select { 57 | line-height: 1.75; 58 | padding: .5rem .5rem; 59 | } 60 | 61 | select:not([multiple]) { 62 | height: 2.25rem; 63 | vertical-align: middle; 64 | } 65 | 66 | textarea { 67 | line-height: 1.75; 68 | padding: .5rem .5rem; 69 | } 70 | 71 | table { 72 | border-collapse: separate; 73 | border-spacing: 0; 74 | max-width: 100%; 75 | width: 100%; 76 | } 77 | 78 | th { 79 | text-align: left; 80 | font-weight: bold; 81 | } 82 | 83 | th, 84 | td { 85 | padding: .25rem 1rem; 86 | line-height: inherit; 87 | } 88 | 89 | th { vertical-align: bottom } 90 | td { vertical-align: top } 91 | 92 | body { 93 | font-family: 'Helvetica Neue', Helvetica, sans-serif; 94 | line-height: 1.5; 95 | font-size: 100%; 96 | } 97 | 98 | h1, h2, h3, h4, h5, h6 { 99 | font-family: 'Helvetica Neue', Helvetica, sans-serif; 100 | font-weight: bold; 101 | line-height: 1.25; 102 | margin-top: 1em; 103 | margin-bottom: .5em; 104 | } 105 | 106 | p { 107 | margin-top: 0; 108 | margin-bottom: 1rem; 109 | } 110 | 111 | dl, ol, ul { 112 | margin-top: 0; 113 | margin-bottom: 1rem; 114 | } 115 | 116 | pre, code, samp { 117 | font-family: 'Source Code Pro', Consolas, monospace; 118 | font-size: inherit; 119 | } 120 | 121 | pre { 122 | margin-top: 0; 123 | margin-bottom: 1rem; 124 | overflow-x: scroll; 125 | } 126 | 127 | h1 { font-size: 2rem } 128 | h2 { font-size: 1.5rem } 129 | h3 { font-size: 1.25rem } 130 | h4 { font-size: 1rem } 131 | h5 { font-size: .875rem } 132 | h6 { font-size: .75rem } 133 | 134 | body { 135 | color: #111; 136 | background-color: #fff; 137 | } 138 | 139 | a { 140 | color: #0074d9; 141 | text-decoration: none; 142 | } 143 | 144 | a:hover { 145 | text-decoration: underline; 146 | } 147 | 148 | pre, code { 149 | background-color: transparent; 150 | border-radius: 3px; 151 | } 152 | 153 | hr { 154 | border: 0; 155 | border-bottom-style: solid; 156 | border-bottom-width: 1px; 157 | border-bottom-color: rgba(0,0,0,.125); 158 | } 159 | 160 | .field { 161 | border-style: solid; 162 | border-width: 1px; 163 | border-color: rgba(0,0,0,.125); 164 | border-radius: 3px; 165 | } 166 | 167 | .field:focus, 168 | .field.is-focused { 169 | outline: none; 170 | border-color: #0074d9; 171 | box-shadow: 0 0 0 2px rgba(0, 116, 217, 0.5); 172 | } 173 | 174 | .field:disabled, 175 | .field.is-disabled { 176 | background-color: rgba(0,0,0,.125); 177 | opacity: .5; 178 | } 179 | 180 | .field:read-only:not(select), 181 | .field.is-read-only { 182 | background-color: rgba(0,0,0,.125); 183 | } 184 | 185 | 186 | .field.is-success { 187 | border-color: #2ecc40; 188 | } 189 | 190 | .field.is-success:focus, 191 | .field.is-success.is-focused { 192 | box-shadow: 0 0 0 2px rgba(46, 204, 64, 0.5); 193 | } 194 | 195 | .field.is-warning { 196 | border-color: #ffdc00; 197 | } 198 | 199 | .field.is-warning:focus, 200 | .field.is-warning.is-focused { 201 | box-shadow: 0 0 0 2px rgba(255, 220, 0, 0.5); 202 | } 203 | 204 | .field:invalid, 205 | .field.is-error { 206 | border-color: #ff4136; 207 | } 208 | 209 | .field:invalid:focus, 210 | .field:invalid.is-focused, 211 | .field.is-error:focus, 212 | .field.is-error.is-focused { 213 | box-shadow: 0 0 0 2px rgba(255, 65, 54, 0.5); 214 | } 215 | 216 | .table-light th, 217 | .table-light td { 218 | border-bottom-width: 1px; 219 | border-bottom-style: solid; 220 | border-bottom-color: rgba(0,0,0,.125); 221 | } 222 | 223 | .table-light tr:last-child td { 224 | border-bottom: 0; 225 | } 226 | 227 | .btn { 228 | font-family: inherit; 229 | font-size: inherit; 230 | font-weight: bold; 231 | text-decoration: none; 232 | cursor: pointer; 233 | display: inline-block; 234 | line-height: 1.125rem; 235 | padding: .5rem 1rem; 236 | margin: 0; 237 | height: auto; 238 | border: 1px solid transparent; 239 | vertical-align: middle; 240 | -webkit-appearance: none; 241 | color: inherit; 242 | background-color: transparent; 243 | } 244 | 245 | .btn:hover { 246 | text-decoration: none; 247 | } 248 | 249 | .btn:focus { 250 | outline: none; 251 | border-color: rgba(0,0,0,.125); 252 | box-shadow: 0 0 0 3px rgba(0,0,0,.25); 253 | } 254 | 255 | ::-moz-focus-inner { 256 | border: 0; 257 | padding: 0; 258 | } 259 | 260 | .btn-primary { 261 | color: #fff; 262 | background-color: #0074d9; 263 | border-radius: 3px; 264 | } 265 | 266 | .btn-primary:hover { 267 | box-shadow: inset 0 0 0 20rem rgba(0,0,0,.0625); 268 | } 269 | 270 | .btn-primary:active { 271 | box-shadow: inset 0 0 0 20rem rgba(0,0,0,.125), 272 | inset 0 3px 4px 0 rgba(0,0,0,.25), 273 | 0 0 1px rgba(0,0,0,.125); 274 | } 275 | 276 | .btn-primary:disabled, 277 | .btn-primary.is-disabled { 278 | opacity: .5; 279 | } 280 | 281 | .btn-outline, 282 | .btn-outline:hover { 283 | border-color: currentcolor; 284 | } 285 | 286 | .btn-outline { 287 | border-radius: 3px; 288 | } 289 | 290 | .btn-outline:hover { 291 | box-shadow: inset 0 0 0 20rem rgba(0,0,0,.0625); 292 | } 293 | 294 | .btn-outline:active { 295 | box-shadow: inset 0 0 0 20rem rgba(0,0,0,.125), 296 | inset 0 3px 4px 0 rgba(0,0,0,.25), 297 | 0 0 1px rgba(0,0,0,.125); 298 | } 299 | 300 | .btn-outline:disabled, 301 | .btn-outline.is-disabled { 302 | opacity: .5; 303 | } 304 | 305 | .h1 { font-size: 2rem } 306 | .h2 { font-size: 1.5rem } 307 | .h3 { font-size: 1.25rem } 308 | .h4 { font-size: 1rem } 309 | .h5 { font-size: .875rem } 310 | .h6 { font-size: .75rem } 311 | 312 | .bold { font-weight: bold } 313 | .regular { font-weight: normal } 314 | .italic { font-style: italic } 315 | .caps { text-transform: uppercase; letter-spacing: .2em; } 316 | 317 | .left-align { text-align: left } 318 | .center { text-align: center } 319 | .right-align { text-align: right } 320 | .justify { text-align: justify } 321 | 322 | .nowrap { white-space: nowrap } 323 | .break-word { word-wrap: break-word } 324 | 325 | .truncate { 326 | max-width: 100%; 327 | overflow: hidden; 328 | text-overflow: ellipsis; 329 | white-space: nowrap; 330 | } 331 | 332 | .list-reset { 333 | list-style: none; 334 | padding-left: 0; 335 | } 336 | 337 | .inline { display: inline } 338 | .block { display: block } 339 | .inline-block { display: inline-block } 340 | .table { display: table } 341 | .table-cell { display: table-cell } 342 | 343 | .overflow-hidden { overflow: hidden } 344 | .overflow-scroll { overflow: scroll } 345 | .overflow-auto { overflow: auto } 346 | 347 | .clearfix:before, 348 | .clearfix:after { 349 | content: " "; 350 | display: table 351 | } 352 | .clearfix:after { clear: both } 353 | 354 | .left { float: left } 355 | .right { float: right } 356 | 357 | .fit { max-width: 100% } 358 | 359 | .border-box { box-sizing: border-box } 360 | 361 | .align-baseline { vertical-align: baseline } 362 | .align-top { vertical-align: top } 363 | .align-middle { vertical-align: middle } 364 | .align-bottom { vertical-align: bottom } 365 | 366 | .m0 { margin: 0 } 367 | .mt0 { margin-top: 0 } 368 | .mr0 { margin-right: 0 } 369 | .mb0 { margin-bottom: 0 } 370 | .ml0 { margin-left: 0 } 371 | 372 | .m1 { margin: .5rem } 373 | .mt1 { margin-top: .5rem } 374 | .mr1 { margin-right: .5rem } 375 | .mb1 { margin-bottom: .5rem } 376 | .ml1 { margin-left: .5rem } 377 | 378 | .m2 { margin: 1rem } 379 | .mt2 { margin-top: 1rem } 380 | .mr2 { margin-right: 1rem } 381 | .mb2 { margin-bottom: 1rem } 382 | .ml2 { margin-left: 1rem } 383 | 384 | .m3 { margin: 2rem } 385 | .mt3 { margin-top: 2rem } 386 | .mr3 { margin-right: 2rem } 387 | .mb3 { margin-bottom: 2rem } 388 | .ml3 { margin-left: 2rem } 389 | 390 | .m4 { margin: 4rem } 391 | .mt4 { margin-top: 4rem } 392 | .mr4 { margin-right: 4rem } 393 | .mb4 { margin-bottom: 4rem } 394 | .ml4 { margin-left: 4rem } 395 | 396 | .mxn1 { margin-left: -.5rem; margin-right: -.5rem; } 397 | .mxn2 { margin-left: -1rem; margin-right: -1rem; } 398 | .mxn3 { margin-left: -2rem; margin-right: -2rem; } 399 | .mxn4 { margin-left: -4rem; margin-right: -4rem; } 400 | 401 | .mx-auto { margin-left: auto; margin-right: auto; } 402 | .p0 { padding: 0 } 403 | 404 | .p1 { padding: .5rem } 405 | .py1 { padding-top: .5rem; padding-bottom: .5rem } 406 | .px1 { padding-left: .5rem; padding-right: .5rem } 407 | 408 | .p2 { padding: 1rem } 409 | .py2 { padding-top: 1rem; padding-bottom: 1rem } 410 | .px2 { padding-left: 1rem; padding-right: 1rem } 411 | 412 | .p3 { padding: 2rem } 413 | .py3 { padding-top: 2rem; padding-bottom: 2rem } 414 | .px3 { padding-left: 2rem; padding-right: 2rem } 415 | 416 | .p4 { padding: 4rem } 417 | .py4 { padding-top: 4rem; padding-bottom: 4rem } 418 | .px4 { padding-left: 4rem; padding-right: 4rem } 419 | 420 | .relative { position: relative } 421 | .absolute { position: absolute } 422 | .fixed { position: fixed } 423 | 424 | .top-0 { top: 0 } 425 | .right-0 { right: 0 } 426 | .bottom-0 { bottom: 0 } 427 | .left-0 { left: 0 } 428 | 429 | .z1 { z-index: 1 } 430 | .z2 { z-index: 2 } 431 | .z3 { z-index: 3 } 432 | .z4 { z-index: 4 } 433 | 434 | .sm-show, .md-show, .lg-show { 435 | display: none !important 436 | } 437 | 438 | @media (min-width: 40em) { 439 | .sm-show { display: block !important } 440 | } 441 | 442 | @media (min-width: 52em) { 443 | .md-show { display: block !important } 444 | } 445 | 446 | @media (min-width: 64em) { 447 | .lg-show { display: block !important } 448 | } 449 | 450 | 451 | @media (min-width: 40em) { 452 | .sm-hide { display: none !important } 453 | } 454 | 455 | @media (min-width: 52em) { 456 | .md-hide { display: none !important } 457 | } 458 | 459 | @media (min-width: 64em) { 460 | .lg-hide { display: none !important } 461 | } 462 | 463 | .display-none { display: none !important } 464 | 465 | .hide { 466 | position: absolute !important; 467 | height: 1px; 468 | width: 1px; 469 | overflow: hidden; 470 | clip: rect(1px, 1px, 1px, 1px); 471 | } 472 | 473 | .container { 474 | max-width: 64em; 475 | margin-left: auto; 476 | margin-right: auto; 477 | } 478 | .col { 479 | float: left; 480 | box-sizing: border-box; 481 | } 482 | 483 | .col-right { 484 | float: right; 485 | box-sizing: border-box; 486 | } 487 | 488 | .col-1 { 489 | width: 8.33333%; 490 | } 491 | 492 | .col-2 { 493 | width: 16.66667%; 494 | } 495 | 496 | .col-3 { 497 | width: 25%; 498 | } 499 | 500 | .col-4 { 501 | width: 33.33333%; 502 | } 503 | 504 | .col-5 { 505 | width: 41.66667%; 506 | } 507 | 508 | .col-6 { 509 | width: 50%; 510 | } 511 | 512 | .col-7 { 513 | width: 58.33333%; 514 | } 515 | 516 | .col-8 { 517 | width: 66.66667%; 518 | } 519 | 520 | .col-9 { 521 | width: 75%; 522 | } 523 | 524 | .col-10 { 525 | width: 83.33333%; 526 | } 527 | 528 | .col-11 { 529 | width: 91.66667%; 530 | } 531 | 532 | .col-12 { 533 | width: 100%; 534 | } 535 | @media (min-width: 40em) { 536 | 537 | .sm-col { 538 | float: left; 539 | box-sizing: border-box; 540 | } 541 | 542 | .sm-col-right { 543 | float: right; 544 | box-sizing: border-box; 545 | } 546 | 547 | .sm-col-1 { 548 | width: 8.33333%; 549 | } 550 | 551 | .sm-col-2 { 552 | width: 16.66667%; 553 | } 554 | 555 | .sm-col-3 { 556 | width: 25%; 557 | } 558 | 559 | .sm-col-4 { 560 | width: 33.33333%; 561 | } 562 | 563 | .sm-col-5 { 564 | width: 41.66667%; 565 | } 566 | 567 | .sm-col-6 { 568 | width: 50%; 569 | } 570 | 571 | .sm-col-7 { 572 | width: 58.33333%; 573 | } 574 | 575 | .sm-col-8 { 576 | width: 66.66667%; 577 | } 578 | 579 | .sm-col-9 { 580 | width: 75%; 581 | } 582 | 583 | .sm-col-10 { 584 | width: 83.33333%; 585 | } 586 | 587 | .sm-col-11 { 588 | width: 91.66667%; 589 | } 590 | 591 | .sm-col-12 { 592 | width: 100%; 593 | } 594 | 595 | } 596 | @media (min-width: 52em) { 597 | 598 | .md-col { 599 | float: left; 600 | box-sizing: border-box; 601 | } 602 | 603 | .md-col-right { 604 | float: right; 605 | box-sizing: border-box; 606 | } 607 | 608 | .md-col-1 { 609 | width: 8.33333%; 610 | } 611 | 612 | .md-col-2 { 613 | width: 16.66667%; 614 | } 615 | 616 | .md-col-3 { 617 | width: 25%; 618 | } 619 | 620 | .md-col-4 { 621 | width: 33.33333%; 622 | } 623 | 624 | .md-col-5 { 625 | width: 41.66667%; 626 | } 627 | 628 | .md-col-6 { 629 | width: 50%; 630 | } 631 | 632 | .md-col-7 { 633 | width: 58.33333%; 634 | } 635 | 636 | .md-col-8 { 637 | width: 66.66667%; 638 | } 639 | 640 | .md-col-9 { 641 | width: 75%; 642 | } 643 | 644 | .md-col-10 { 645 | width: 83.33333%; 646 | } 647 | 648 | .md-col-11 { 649 | width: 91.66667%; 650 | } 651 | 652 | .md-col-12 { 653 | width: 100%; 654 | } 655 | 656 | } 657 | @media (min-width: 64em) { 658 | 659 | .lg-col { 660 | float: left; 661 | box-sizing: border-box; 662 | } 663 | 664 | .lg-col-right { 665 | float: right; 666 | box-sizing: border-box; 667 | } 668 | 669 | .lg-col-1 { 670 | width: 8.33333%; 671 | } 672 | 673 | .lg-col-2 { 674 | width: 16.66667%; 675 | } 676 | 677 | .lg-col-3 { 678 | width: 25%; 679 | } 680 | 681 | .lg-col-4 { 682 | width: 33.33333%; 683 | } 684 | 685 | .lg-col-5 { 686 | width: 41.66667%; 687 | } 688 | 689 | .lg-col-6 { 690 | width: 50%; 691 | } 692 | 693 | .lg-col-7 { 694 | width: 58.33333%; 695 | } 696 | 697 | .lg-col-8 { 698 | width: 66.66667%; 699 | } 700 | 701 | .lg-col-9 { 702 | width: 75%; 703 | } 704 | 705 | .lg-col-10 { 706 | width: 83.33333%; 707 | } 708 | 709 | .lg-col-11 { 710 | width: 91.66667%; 711 | } 712 | 713 | .lg-col-12 { 714 | width: 100%; 715 | } 716 | 717 | } 718 | 719 | .flex { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex } 720 | 721 | .flex-column { -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column } 722 | .flex-wrap { -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap } 723 | 724 | .flex-center { -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center } 725 | .flex-baseline { -webkit-box-align: baseline; -webkit-align-items: baseline; -ms-flex-align: baseline; align-items: baseline } 726 | .flex-stretch { -webkit-box-align: stretch; -webkit-align-items: stretch; -ms-flex-align: stretch; align-items: stretch } 727 | .flex-start { -webkit-box-align: start; -webkit-align-items: flex-start; -ms-flex-align: start; align-items: flex-start } 728 | .flex-end { -webkit-box-align: end; -webkit-align-items: flex-end; -ms-flex-align: end; align-items: flex-end } 729 | 730 | .flex-justify { -webkit-box-pack: justify; -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between } 731 | 732 | .flex-auto { -webkit-box-flex: 1; -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto } 733 | .flex-grow { -webkit-box-flex: 1; -webkit-flex: 1 0 auto; -ms-flex: 1 0 auto; flex: 1 0 auto } 734 | .flex-none { -webkit-box-flex: 0; -webkit-flex: none; -ms-flex: none; flex: none } 735 | 736 | .flex-first { -webkit-box-ordinal-group: 0; -webkit-order: -1; -ms-flex-order: -1; order: -1 } 737 | .flex-last { -webkit-box-ordinal-group: 100000; -webkit-order: 99999; -ms-flex-order: 99999; order: 99999 } 738 | @media (min-width: 40em) { 739 | .sm-flex { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex } 740 | } 741 | @media (min-width: 52em) { 742 | .md-flex { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex } 743 | } 744 | @media (min-width: 64em) { 745 | .lg-flex { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex } 746 | } 747 | 748 | .border { 749 | border-style: solid; 750 | border-width: 1px; 751 | border-color: rgba(0,0,0,.125); 752 | } 753 | 754 | .border-top { 755 | border-top-style: solid; 756 | border-top-width: 1px; 757 | border-top-color: rgba(0,0,0,.125); 758 | } 759 | 760 | .border-right { 761 | border-right-style: solid; 762 | border-right-width: 1px; 763 | border-right-color: rgba(0,0,0,.125); 764 | } 765 | 766 | .border-bottom { 767 | border-bottom-style: solid; 768 | border-bottom-width: 1px; 769 | border-bottom-color: rgba(0,0,0,.125); 770 | } 771 | 772 | .border-left { 773 | border-left-style: solid; 774 | border-left-width: 1px; 775 | border-left-color: rgba(0,0,0,.125); 776 | } 777 | 778 | .border-none { border: 0 } 779 | 780 | .rounded { border-radius: 3px } 781 | .circle { border-radius: 50% } 782 | 783 | .rounded-top { border-radius: 3px 3px 0 0 } 784 | .rounded-right { border-radius: 0 3px 3px 0 } 785 | .rounded-bottom { border-radius: 0 0 3px 3px } 786 | .rounded-left { border-radius: 3px 0 0 3px } 787 | 788 | .not-rounded { border-radius: 0 } 789 | 790 | .black { color: #111 } 791 | .gray { color: #aaa } 792 | .silver { color: #ddd } 793 | .white { color: #fff } 794 | 795 | .aqua { color: #7fdbff } 796 | .blue { color: #0074d9 } 797 | .navy { color: #001f3f } 798 | .teal { color: #39cccc } 799 | .green { color: #2ecc40 } 800 | .olive { color: #3d9970 } 801 | .lime { color: #01ff70 } 802 | 803 | .yellow { color: #ffdc00 } 804 | .orange { color: #ff851b } 805 | .red { color: #ff4136 } 806 | .fuchsia { color: #f012be } 807 | .purple { color: #b10dc9 } 808 | .maroon { color: #85144b } 809 | 810 | .color-inherit { color: inherit } 811 | .muted { opacity: .5 } 812 | 813 | .bg-black { background-color: #111 } 814 | .bg-gray { background-color: #aaa } 815 | .bg-silver { background-color: #ddd } 816 | .bg-white { background-color: #fff } 817 | 818 | .bg-aqua { background-color: #7fdbff } 819 | .bg-blue { background-color: #0074d9 } 820 | .bg-navy { background-color: #001f3f } 821 | .bg-teal { background-color: #39cccc } 822 | .bg-green { background-color: #2ecc40 } 823 | .bg-olive { background-color: #3d9970 } 824 | .bg-lime { background-color: #01ff70 } 825 | 826 | .bg-yellow { background-color: #ffdc00 } 827 | .bg-orange { background-color: #ff851b } 828 | .bg-red { background-color: #ff4136 } 829 | .bg-fuchsia { background-color: #f012be } 830 | .bg-purple { background-color: #b10dc9 } 831 | .bg-maroon { background-color: #85144b } 832 | 833 | .bg-darken-1 { background-color: rgba(0,0,0,.0625) } 834 | .bg-darken-2 { background-color: rgba(0,0,0,.125) } 835 | .bg-darken-3 { background-color: rgba(0,0,0,.25) } 836 | .bg-darken-4 { background-color: rgba(0,0,0,.5) } 837 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.3.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0, 0)}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-genderless:before,.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"} -------------------------------------------------------------------------------- /vendor/assets/stylesheets/font-awesome.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | /* FONT PATH 6 | * -------------------------- */ 7 | @font-face { 8 | font-family: 'FontAwesome'; 9 | src: url('../fonts/fontawesome-webfont.eot?v=4.3.0'); 10 | src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg'); 11 | font-weight: normal; 12 | font-style: normal; 13 | } 14 | .fa { 15 | display: inline-block; 16 | font: normal normal normal 14px/1 FontAwesome; 17 | font-size: inherit; 18 | text-rendering: auto; 19 | -webkit-font-smoothing: antialiased; 20 | -moz-osx-font-smoothing: grayscale; 21 | transform: translate(0, 0); 22 | } 23 | /* makes the font 33% larger relative to the icon container */ 24 | .fa-lg { 25 | font-size: 1.33333333em; 26 | line-height: 0.75em; 27 | vertical-align: -15%; 28 | } 29 | .fa-2x { 30 | font-size: 2em; 31 | } 32 | .fa-3x { 33 | font-size: 3em; 34 | } 35 | .fa-4x { 36 | font-size: 4em; 37 | } 38 | .fa-5x { 39 | font-size: 5em; 40 | } 41 | .fa-fw { 42 | width: 1.28571429em; 43 | text-align: center; 44 | } 45 | .fa-ul { 46 | padding-left: 0; 47 | margin-left: 2.14285714em; 48 | list-style-type: none; 49 | } 50 | .fa-ul > li { 51 | position: relative; 52 | } 53 | .fa-li { 54 | position: absolute; 55 | left: -2.14285714em; 56 | width: 2.14285714em; 57 | top: 0.14285714em; 58 | text-align: center; 59 | } 60 | .fa-li.fa-lg { 61 | left: -1.85714286em; 62 | } 63 | .fa-border { 64 | padding: .2em .25em .15em; 65 | border: solid 0.08em #eeeeee; 66 | border-radius: .1em; 67 | } 68 | .pull-right { 69 | float: right; 70 | } 71 | .pull-left { 72 | float: left; 73 | } 74 | .fa.pull-left { 75 | margin-right: .3em; 76 | } 77 | .fa.pull-right { 78 | margin-left: .3em; 79 | } 80 | .fa-spin { 81 | -webkit-animation: fa-spin 2s infinite linear; 82 | animation: fa-spin 2s infinite linear; 83 | } 84 | .fa-pulse { 85 | -webkit-animation: fa-spin 1s infinite steps(8); 86 | animation: fa-spin 1s infinite steps(8); 87 | } 88 | @-webkit-keyframes fa-spin { 89 | 0% { 90 | -webkit-transform: rotate(0deg); 91 | transform: rotate(0deg); 92 | } 93 | 100% { 94 | -webkit-transform: rotate(359deg); 95 | transform: rotate(359deg); 96 | } 97 | } 98 | @keyframes fa-spin { 99 | 0% { 100 | -webkit-transform: rotate(0deg); 101 | transform: rotate(0deg); 102 | } 103 | 100% { 104 | -webkit-transform: rotate(359deg); 105 | transform: rotate(359deg); 106 | } 107 | } 108 | .fa-rotate-90 { 109 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); 110 | -webkit-transform: rotate(90deg); 111 | -ms-transform: rotate(90deg); 112 | transform: rotate(90deg); 113 | } 114 | .fa-rotate-180 { 115 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); 116 | -webkit-transform: rotate(180deg); 117 | -ms-transform: rotate(180deg); 118 | transform: rotate(180deg); 119 | } 120 | .fa-rotate-270 { 121 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); 122 | -webkit-transform: rotate(270deg); 123 | -ms-transform: rotate(270deg); 124 | transform: rotate(270deg); 125 | } 126 | .fa-flip-horizontal { 127 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); 128 | -webkit-transform: scale(-1, 1); 129 | -ms-transform: scale(-1, 1); 130 | transform: scale(-1, 1); 131 | } 132 | .fa-flip-vertical { 133 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); 134 | -webkit-transform: scale(1, -1); 135 | -ms-transform: scale(1, -1); 136 | transform: scale(1, -1); 137 | } 138 | :root .fa-rotate-90, 139 | :root .fa-rotate-180, 140 | :root .fa-rotate-270, 141 | :root .fa-flip-horizontal, 142 | :root .fa-flip-vertical { 143 | filter: none; 144 | } 145 | .fa-stack { 146 | position: relative; 147 | display: inline-block; 148 | width: 2em; 149 | height: 2em; 150 | line-height: 2em; 151 | vertical-align: middle; 152 | } 153 | .fa-stack-1x, 154 | .fa-stack-2x { 155 | position: absolute; 156 | left: 0; 157 | width: 100%; 158 | text-align: center; 159 | } 160 | .fa-stack-1x { 161 | line-height: inherit; 162 | } 163 | .fa-stack-2x { 164 | font-size: 2em; 165 | } 166 | .fa-inverse { 167 | color: #ffffff; 168 | } 169 | /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen 170 | readers do not read off random characters that represent icons */ 171 | .fa-glass:before { 172 | content: "\f000"; 173 | } 174 | .fa-music:before { 175 | content: "\f001"; 176 | } 177 | .fa-search:before { 178 | content: "\f002"; 179 | } 180 | .fa-envelope-o:before { 181 | content: "\f003"; 182 | } 183 | .fa-heart:before { 184 | content: "\f004"; 185 | } 186 | .fa-star:before { 187 | content: "\f005"; 188 | } 189 | .fa-star-o:before { 190 | content: "\f006"; 191 | } 192 | .fa-user:before { 193 | content: "\f007"; 194 | } 195 | .fa-film:before { 196 | content: "\f008"; 197 | } 198 | .fa-th-large:before { 199 | content: "\f009"; 200 | } 201 | .fa-th:before { 202 | content: "\f00a"; 203 | } 204 | .fa-th-list:before { 205 | content: "\f00b"; 206 | } 207 | .fa-check:before { 208 | content: "\f00c"; 209 | } 210 | .fa-remove:before, 211 | .fa-close:before, 212 | .fa-times:before { 213 | content: "\f00d"; 214 | } 215 | .fa-search-plus:before { 216 | content: "\f00e"; 217 | } 218 | .fa-search-minus:before { 219 | content: "\f010"; 220 | } 221 | .fa-power-off:before { 222 | content: "\f011"; 223 | } 224 | .fa-signal:before { 225 | content: "\f012"; 226 | } 227 | .fa-gear:before, 228 | .fa-cog:before { 229 | content: "\f013"; 230 | } 231 | .fa-trash-o:before { 232 | content: "\f014"; 233 | } 234 | .fa-home:before { 235 | content: "\f015"; 236 | } 237 | .fa-file-o:before { 238 | content: "\f016"; 239 | } 240 | .fa-clock-o:before { 241 | content: "\f017"; 242 | } 243 | .fa-road:before { 244 | content: "\f018"; 245 | } 246 | .fa-download:before { 247 | content: "\f019"; 248 | } 249 | .fa-arrow-circle-o-down:before { 250 | content: "\f01a"; 251 | } 252 | .fa-arrow-circle-o-up:before { 253 | content: "\f01b"; 254 | } 255 | .fa-inbox:before { 256 | content: "\f01c"; 257 | } 258 | .fa-play-circle-o:before { 259 | content: "\f01d"; 260 | } 261 | .fa-rotate-right:before, 262 | .fa-repeat:before { 263 | content: "\f01e"; 264 | } 265 | .fa-refresh:before { 266 | content: "\f021"; 267 | } 268 | .fa-list-alt:before { 269 | content: "\f022"; 270 | } 271 | .fa-lock:before { 272 | content: "\f023"; 273 | } 274 | .fa-flag:before { 275 | content: "\f024"; 276 | } 277 | .fa-headphones:before { 278 | content: "\f025"; 279 | } 280 | .fa-volume-off:before { 281 | content: "\f026"; 282 | } 283 | .fa-volume-down:before { 284 | content: "\f027"; 285 | } 286 | .fa-volume-up:before { 287 | content: "\f028"; 288 | } 289 | .fa-qrcode:before { 290 | content: "\f029"; 291 | } 292 | .fa-barcode:before { 293 | content: "\f02a"; 294 | } 295 | .fa-tag:before { 296 | content: "\f02b"; 297 | } 298 | .fa-tags:before { 299 | content: "\f02c"; 300 | } 301 | .fa-book:before { 302 | content: "\f02d"; 303 | } 304 | .fa-bookmark:before { 305 | content: "\f02e"; 306 | } 307 | .fa-print:before { 308 | content: "\f02f"; 309 | } 310 | .fa-camera:before { 311 | content: "\f030"; 312 | } 313 | .fa-font:before { 314 | content: "\f031"; 315 | } 316 | .fa-bold:before { 317 | content: "\f032"; 318 | } 319 | .fa-italic:before { 320 | content: "\f033"; 321 | } 322 | .fa-text-height:before { 323 | content: "\f034"; 324 | } 325 | .fa-text-width:before { 326 | content: "\f035"; 327 | } 328 | .fa-align-left:before { 329 | content: "\f036"; 330 | } 331 | .fa-align-center:before { 332 | content: "\f037"; 333 | } 334 | .fa-align-right:before { 335 | content: "\f038"; 336 | } 337 | .fa-align-justify:before { 338 | content: "\f039"; 339 | } 340 | .fa-list:before { 341 | content: "\f03a"; 342 | } 343 | .fa-dedent:before, 344 | .fa-outdent:before { 345 | content: "\f03b"; 346 | } 347 | .fa-indent:before { 348 | content: "\f03c"; 349 | } 350 | .fa-video-camera:before { 351 | content: "\f03d"; 352 | } 353 | .fa-photo:before, 354 | .fa-image:before, 355 | .fa-picture-o:before { 356 | content: "\f03e"; 357 | } 358 | .fa-pencil:before { 359 | content: "\f040"; 360 | } 361 | .fa-map-marker:before { 362 | content: "\f041"; 363 | } 364 | .fa-adjust:before { 365 | content: "\f042"; 366 | } 367 | .fa-tint:before { 368 | content: "\f043"; 369 | } 370 | .fa-edit:before, 371 | .fa-pencil-square-o:before { 372 | content: "\f044"; 373 | } 374 | .fa-share-square-o:before { 375 | content: "\f045"; 376 | } 377 | .fa-check-square-o:before { 378 | content: "\f046"; 379 | } 380 | .fa-arrows:before { 381 | content: "\f047"; 382 | } 383 | .fa-step-backward:before { 384 | content: "\f048"; 385 | } 386 | .fa-fast-backward:before { 387 | content: "\f049"; 388 | } 389 | .fa-backward:before { 390 | content: "\f04a"; 391 | } 392 | .fa-play:before { 393 | content: "\f04b"; 394 | } 395 | .fa-pause:before { 396 | content: "\f04c"; 397 | } 398 | .fa-stop:before { 399 | content: "\f04d"; 400 | } 401 | .fa-forward:before { 402 | content: "\f04e"; 403 | } 404 | .fa-fast-forward:before { 405 | content: "\f050"; 406 | } 407 | .fa-step-forward:before { 408 | content: "\f051"; 409 | } 410 | .fa-eject:before { 411 | content: "\f052"; 412 | } 413 | .fa-chevron-left:before { 414 | content: "\f053"; 415 | } 416 | .fa-chevron-right:before { 417 | content: "\f054"; 418 | } 419 | .fa-plus-circle:before { 420 | content: "\f055"; 421 | } 422 | .fa-minus-circle:before { 423 | content: "\f056"; 424 | } 425 | .fa-times-circle:before { 426 | content: "\f057"; 427 | } 428 | .fa-check-circle:before { 429 | content: "\f058"; 430 | } 431 | .fa-question-circle:before { 432 | content: "\f059"; 433 | } 434 | .fa-info-circle:before { 435 | content: "\f05a"; 436 | } 437 | .fa-crosshairs:before { 438 | content: "\f05b"; 439 | } 440 | .fa-times-circle-o:before { 441 | content: "\f05c"; 442 | } 443 | .fa-check-circle-o:before { 444 | content: "\f05d"; 445 | } 446 | .fa-ban:before { 447 | content: "\f05e"; 448 | } 449 | .fa-arrow-left:before { 450 | content: "\f060"; 451 | } 452 | .fa-arrow-right:before { 453 | content: "\f061"; 454 | } 455 | .fa-arrow-up:before { 456 | content: "\f062"; 457 | } 458 | .fa-arrow-down:before { 459 | content: "\f063"; 460 | } 461 | .fa-mail-forward:before, 462 | .fa-share:before { 463 | content: "\f064"; 464 | } 465 | .fa-expand:before { 466 | content: "\f065"; 467 | } 468 | .fa-compress:before { 469 | content: "\f066"; 470 | } 471 | .fa-plus:before { 472 | content: "\f067"; 473 | } 474 | .fa-minus:before { 475 | content: "\f068"; 476 | } 477 | .fa-asterisk:before { 478 | content: "\f069"; 479 | } 480 | .fa-exclamation-circle:before { 481 | content: "\f06a"; 482 | } 483 | .fa-gift:before { 484 | content: "\f06b"; 485 | } 486 | .fa-leaf:before { 487 | content: "\f06c"; 488 | } 489 | .fa-fire:before { 490 | content: "\f06d"; 491 | } 492 | .fa-eye:before { 493 | content: "\f06e"; 494 | } 495 | .fa-eye-slash:before { 496 | content: "\f070"; 497 | } 498 | .fa-warning:before, 499 | .fa-exclamation-triangle:before { 500 | content: "\f071"; 501 | } 502 | .fa-plane:before { 503 | content: "\f072"; 504 | } 505 | .fa-calendar:before { 506 | content: "\f073"; 507 | } 508 | .fa-random:before { 509 | content: "\f074"; 510 | } 511 | .fa-comment:before { 512 | content: "\f075"; 513 | } 514 | .fa-magnet:before { 515 | content: "\f076"; 516 | } 517 | .fa-chevron-up:before { 518 | content: "\f077"; 519 | } 520 | .fa-chevron-down:before { 521 | content: "\f078"; 522 | } 523 | .fa-retweet:before { 524 | content: "\f079"; 525 | } 526 | .fa-shopping-cart:before { 527 | content: "\f07a"; 528 | } 529 | .fa-folder:before { 530 | content: "\f07b"; 531 | } 532 | .fa-folder-open:before { 533 | content: "\f07c"; 534 | } 535 | .fa-arrows-v:before { 536 | content: "\f07d"; 537 | } 538 | .fa-arrows-h:before { 539 | content: "\f07e"; 540 | } 541 | .fa-bar-chart-o:before, 542 | .fa-bar-chart:before { 543 | content: "\f080"; 544 | } 545 | .fa-twitter-square:before { 546 | content: "\f081"; 547 | } 548 | .fa-facebook-square:before { 549 | content: "\f082"; 550 | } 551 | .fa-camera-retro:before { 552 | content: "\f083"; 553 | } 554 | .fa-key:before { 555 | content: "\f084"; 556 | } 557 | .fa-gears:before, 558 | .fa-cogs:before { 559 | content: "\f085"; 560 | } 561 | .fa-comments:before { 562 | content: "\f086"; 563 | } 564 | .fa-thumbs-o-up:before { 565 | content: "\f087"; 566 | } 567 | .fa-thumbs-o-down:before { 568 | content: "\f088"; 569 | } 570 | .fa-star-half:before { 571 | content: "\f089"; 572 | } 573 | .fa-heart-o:before { 574 | content: "\f08a"; 575 | } 576 | .fa-sign-out:before { 577 | content: "\f08b"; 578 | } 579 | .fa-linkedin-square:before { 580 | content: "\f08c"; 581 | } 582 | .fa-thumb-tack:before { 583 | content: "\f08d"; 584 | } 585 | .fa-external-link:before { 586 | content: "\f08e"; 587 | } 588 | .fa-sign-in:before { 589 | content: "\f090"; 590 | } 591 | .fa-trophy:before { 592 | content: "\f091"; 593 | } 594 | .fa-github-square:before { 595 | content: "\f092"; 596 | } 597 | .fa-upload:before { 598 | content: "\f093"; 599 | } 600 | .fa-lemon-o:before { 601 | content: "\f094"; 602 | } 603 | .fa-phone:before { 604 | content: "\f095"; 605 | } 606 | .fa-square-o:before { 607 | content: "\f096"; 608 | } 609 | .fa-bookmark-o:before { 610 | content: "\f097"; 611 | } 612 | .fa-phone-square:before { 613 | content: "\f098"; 614 | } 615 | .fa-twitter:before { 616 | content: "\f099"; 617 | } 618 | .fa-facebook-f:before, 619 | .fa-facebook:before { 620 | content: "\f09a"; 621 | } 622 | .fa-github:before { 623 | content: "\f09b"; 624 | } 625 | .fa-unlock:before { 626 | content: "\f09c"; 627 | } 628 | .fa-credit-card:before { 629 | content: "\f09d"; 630 | } 631 | .fa-rss:before { 632 | content: "\f09e"; 633 | } 634 | .fa-hdd-o:before { 635 | content: "\f0a0"; 636 | } 637 | .fa-bullhorn:before { 638 | content: "\f0a1"; 639 | } 640 | .fa-bell:before { 641 | content: "\f0f3"; 642 | } 643 | .fa-certificate:before { 644 | content: "\f0a3"; 645 | } 646 | .fa-hand-o-right:before { 647 | content: "\f0a4"; 648 | } 649 | .fa-hand-o-left:before { 650 | content: "\f0a5"; 651 | } 652 | .fa-hand-o-up:before { 653 | content: "\f0a6"; 654 | } 655 | .fa-hand-o-down:before { 656 | content: "\f0a7"; 657 | } 658 | .fa-arrow-circle-left:before { 659 | content: "\f0a8"; 660 | } 661 | .fa-arrow-circle-right:before { 662 | content: "\f0a9"; 663 | } 664 | .fa-arrow-circle-up:before { 665 | content: "\f0aa"; 666 | } 667 | .fa-arrow-circle-down:before { 668 | content: "\f0ab"; 669 | } 670 | .fa-globe:before { 671 | content: "\f0ac"; 672 | } 673 | .fa-wrench:before { 674 | content: "\f0ad"; 675 | } 676 | .fa-tasks:before { 677 | content: "\f0ae"; 678 | } 679 | .fa-filter:before { 680 | content: "\f0b0"; 681 | } 682 | .fa-briefcase:before { 683 | content: "\f0b1"; 684 | } 685 | .fa-arrows-alt:before { 686 | content: "\f0b2"; 687 | } 688 | .fa-group:before, 689 | .fa-users:before { 690 | content: "\f0c0"; 691 | } 692 | .fa-chain:before, 693 | .fa-link:before { 694 | content: "\f0c1"; 695 | } 696 | .fa-cloud:before { 697 | content: "\f0c2"; 698 | } 699 | .fa-flask:before { 700 | content: "\f0c3"; 701 | } 702 | .fa-cut:before, 703 | .fa-scissors:before { 704 | content: "\f0c4"; 705 | } 706 | .fa-copy:before, 707 | .fa-files-o:before { 708 | content: "\f0c5"; 709 | } 710 | .fa-paperclip:before { 711 | content: "\f0c6"; 712 | } 713 | .fa-save:before, 714 | .fa-floppy-o:before { 715 | content: "\f0c7"; 716 | } 717 | .fa-square:before { 718 | content: "\f0c8"; 719 | } 720 | .fa-navicon:before, 721 | .fa-reorder:before, 722 | .fa-bars:before { 723 | content: "\f0c9"; 724 | } 725 | .fa-list-ul:before { 726 | content: "\f0ca"; 727 | } 728 | .fa-list-ol:before { 729 | content: "\f0cb"; 730 | } 731 | .fa-strikethrough:before { 732 | content: "\f0cc"; 733 | } 734 | .fa-underline:before { 735 | content: "\f0cd"; 736 | } 737 | .fa-table:before { 738 | content: "\f0ce"; 739 | } 740 | .fa-magic:before { 741 | content: "\f0d0"; 742 | } 743 | .fa-truck:before { 744 | content: "\f0d1"; 745 | } 746 | .fa-pinterest:before { 747 | content: "\f0d2"; 748 | } 749 | .fa-pinterest-square:before { 750 | content: "\f0d3"; 751 | } 752 | .fa-google-plus-square:before { 753 | content: "\f0d4"; 754 | } 755 | .fa-google-plus:before { 756 | content: "\f0d5"; 757 | } 758 | .fa-money:before { 759 | content: "\f0d6"; 760 | } 761 | .fa-caret-down:before { 762 | content: "\f0d7"; 763 | } 764 | .fa-caret-up:before { 765 | content: "\f0d8"; 766 | } 767 | .fa-caret-left:before { 768 | content: "\f0d9"; 769 | } 770 | .fa-caret-right:before { 771 | content: "\f0da"; 772 | } 773 | .fa-columns:before { 774 | content: "\f0db"; 775 | } 776 | .fa-unsorted:before, 777 | .fa-sort:before { 778 | content: "\f0dc"; 779 | } 780 | .fa-sort-down:before, 781 | .fa-sort-desc:before { 782 | content: "\f0dd"; 783 | } 784 | .fa-sort-up:before, 785 | .fa-sort-asc:before { 786 | content: "\f0de"; 787 | } 788 | .fa-envelope:before { 789 | content: "\f0e0"; 790 | } 791 | .fa-linkedin:before { 792 | content: "\f0e1"; 793 | } 794 | .fa-rotate-left:before, 795 | .fa-undo:before { 796 | content: "\f0e2"; 797 | } 798 | .fa-legal:before, 799 | .fa-gavel:before { 800 | content: "\f0e3"; 801 | } 802 | .fa-dashboard:before, 803 | .fa-tachometer:before { 804 | content: "\f0e4"; 805 | } 806 | .fa-comment-o:before { 807 | content: "\f0e5"; 808 | } 809 | .fa-comments-o:before { 810 | content: "\f0e6"; 811 | } 812 | .fa-flash:before, 813 | .fa-bolt:before { 814 | content: "\f0e7"; 815 | } 816 | .fa-sitemap:before { 817 | content: "\f0e8"; 818 | } 819 | .fa-umbrella:before { 820 | content: "\f0e9"; 821 | } 822 | .fa-paste:before, 823 | .fa-clipboard:before { 824 | content: "\f0ea"; 825 | } 826 | .fa-lightbulb-o:before { 827 | content: "\f0eb"; 828 | } 829 | .fa-exchange:before { 830 | content: "\f0ec"; 831 | } 832 | .fa-cloud-download:before { 833 | content: "\f0ed"; 834 | } 835 | .fa-cloud-upload:before { 836 | content: "\f0ee"; 837 | } 838 | .fa-user-md:before { 839 | content: "\f0f0"; 840 | } 841 | .fa-stethoscope:before { 842 | content: "\f0f1"; 843 | } 844 | .fa-suitcase:before { 845 | content: "\f0f2"; 846 | } 847 | .fa-bell-o:before { 848 | content: "\f0a2"; 849 | } 850 | .fa-coffee:before { 851 | content: "\f0f4"; 852 | } 853 | .fa-cutlery:before { 854 | content: "\f0f5"; 855 | } 856 | .fa-file-text-o:before { 857 | content: "\f0f6"; 858 | } 859 | .fa-building-o:before { 860 | content: "\f0f7"; 861 | } 862 | .fa-hospital-o:before { 863 | content: "\f0f8"; 864 | } 865 | .fa-ambulance:before { 866 | content: "\f0f9"; 867 | } 868 | .fa-medkit:before { 869 | content: "\f0fa"; 870 | } 871 | .fa-fighter-jet:before { 872 | content: "\f0fb"; 873 | } 874 | .fa-beer:before { 875 | content: "\f0fc"; 876 | } 877 | .fa-h-square:before { 878 | content: "\f0fd"; 879 | } 880 | .fa-plus-square:before { 881 | content: "\f0fe"; 882 | } 883 | .fa-angle-double-left:before { 884 | content: "\f100"; 885 | } 886 | .fa-angle-double-right:before { 887 | content: "\f101"; 888 | } 889 | .fa-angle-double-up:before { 890 | content: "\f102"; 891 | } 892 | .fa-angle-double-down:before { 893 | content: "\f103"; 894 | } 895 | .fa-angle-left:before { 896 | content: "\f104"; 897 | } 898 | .fa-angle-right:before { 899 | content: "\f105"; 900 | } 901 | .fa-angle-up:before { 902 | content: "\f106"; 903 | } 904 | .fa-angle-down:before { 905 | content: "\f107"; 906 | } 907 | .fa-desktop:before { 908 | content: "\f108"; 909 | } 910 | .fa-laptop:before { 911 | content: "\f109"; 912 | } 913 | .fa-tablet:before { 914 | content: "\f10a"; 915 | } 916 | .fa-mobile-phone:before, 917 | .fa-mobile:before { 918 | content: "\f10b"; 919 | } 920 | .fa-circle-o:before { 921 | content: "\f10c"; 922 | } 923 | .fa-quote-left:before { 924 | content: "\f10d"; 925 | } 926 | .fa-quote-right:before { 927 | content: "\f10e"; 928 | } 929 | .fa-spinner:before { 930 | content: "\f110"; 931 | } 932 | .fa-circle:before { 933 | content: "\f111"; 934 | } 935 | .fa-mail-reply:before, 936 | .fa-reply:before { 937 | content: "\f112"; 938 | } 939 | .fa-github-alt:before { 940 | content: "\f113"; 941 | } 942 | .fa-folder-o:before { 943 | content: "\f114"; 944 | } 945 | .fa-folder-open-o:before { 946 | content: "\f115"; 947 | } 948 | .fa-smile-o:before { 949 | content: "\f118"; 950 | } 951 | .fa-frown-o:before { 952 | content: "\f119"; 953 | } 954 | .fa-meh-o:before { 955 | content: "\f11a"; 956 | } 957 | .fa-gamepad:before { 958 | content: "\f11b"; 959 | } 960 | .fa-keyboard-o:before { 961 | content: "\f11c"; 962 | } 963 | .fa-flag-o:before { 964 | content: "\f11d"; 965 | } 966 | .fa-flag-checkered:before { 967 | content: "\f11e"; 968 | } 969 | .fa-terminal:before { 970 | content: "\f120"; 971 | } 972 | .fa-code:before { 973 | content: "\f121"; 974 | } 975 | .fa-mail-reply-all:before, 976 | .fa-reply-all:before { 977 | content: "\f122"; 978 | } 979 | .fa-star-half-empty:before, 980 | .fa-star-half-full:before, 981 | .fa-star-half-o:before { 982 | content: "\f123"; 983 | } 984 | .fa-location-arrow:before { 985 | content: "\f124"; 986 | } 987 | .fa-crop:before { 988 | content: "\f125"; 989 | } 990 | .fa-code-fork:before { 991 | content: "\f126"; 992 | } 993 | .fa-unlink:before, 994 | .fa-chain-broken:before { 995 | content: "\f127"; 996 | } 997 | .fa-question:before { 998 | content: "\f128"; 999 | } 1000 | .fa-info:before { 1001 | content: "\f129"; 1002 | } 1003 | .fa-exclamation:before { 1004 | content: "\f12a"; 1005 | } 1006 | .fa-superscript:before { 1007 | content: "\f12b"; 1008 | } 1009 | .fa-subscript:before { 1010 | content: "\f12c"; 1011 | } 1012 | .fa-eraser:before { 1013 | content: "\f12d"; 1014 | } 1015 | .fa-puzzle-piece:before { 1016 | content: "\f12e"; 1017 | } 1018 | .fa-microphone:before { 1019 | content: "\f130"; 1020 | } 1021 | .fa-microphone-slash:before { 1022 | content: "\f131"; 1023 | } 1024 | .fa-shield:before { 1025 | content: "\f132"; 1026 | } 1027 | .fa-calendar-o:before { 1028 | content: "\f133"; 1029 | } 1030 | .fa-fire-extinguisher:before { 1031 | content: "\f134"; 1032 | } 1033 | .fa-rocket:before { 1034 | content: "\f135"; 1035 | } 1036 | .fa-maxcdn:before { 1037 | content: "\f136"; 1038 | } 1039 | .fa-chevron-circle-left:before { 1040 | content: "\f137"; 1041 | } 1042 | .fa-chevron-circle-right:before { 1043 | content: "\f138"; 1044 | } 1045 | .fa-chevron-circle-up:before { 1046 | content: "\f139"; 1047 | } 1048 | .fa-chevron-circle-down:before { 1049 | content: "\f13a"; 1050 | } 1051 | .fa-html5:before { 1052 | content: "\f13b"; 1053 | } 1054 | .fa-css3:before { 1055 | content: "\f13c"; 1056 | } 1057 | .fa-anchor:before { 1058 | content: "\f13d"; 1059 | } 1060 | .fa-unlock-alt:before { 1061 | content: "\f13e"; 1062 | } 1063 | .fa-bullseye:before { 1064 | content: "\f140"; 1065 | } 1066 | .fa-ellipsis-h:before { 1067 | content: "\f141"; 1068 | } 1069 | .fa-ellipsis-v:before { 1070 | content: "\f142"; 1071 | } 1072 | .fa-rss-square:before { 1073 | content: "\f143"; 1074 | } 1075 | .fa-play-circle:before { 1076 | content: "\f144"; 1077 | } 1078 | .fa-ticket:before { 1079 | content: "\f145"; 1080 | } 1081 | .fa-minus-square:before { 1082 | content: "\f146"; 1083 | } 1084 | .fa-minus-square-o:before { 1085 | content: "\f147"; 1086 | } 1087 | .fa-level-up:before { 1088 | content: "\f148"; 1089 | } 1090 | .fa-level-down:before { 1091 | content: "\f149"; 1092 | } 1093 | .fa-check-square:before { 1094 | content: "\f14a"; 1095 | } 1096 | .fa-pencil-square:before { 1097 | content: "\f14b"; 1098 | } 1099 | .fa-external-link-square:before { 1100 | content: "\f14c"; 1101 | } 1102 | .fa-share-square:before { 1103 | content: "\f14d"; 1104 | } 1105 | .fa-compass:before { 1106 | content: "\f14e"; 1107 | } 1108 | .fa-toggle-down:before, 1109 | .fa-caret-square-o-down:before { 1110 | content: "\f150"; 1111 | } 1112 | .fa-toggle-up:before, 1113 | .fa-caret-square-o-up:before { 1114 | content: "\f151"; 1115 | } 1116 | .fa-toggle-right:before, 1117 | .fa-caret-square-o-right:before { 1118 | content: "\f152"; 1119 | } 1120 | .fa-euro:before, 1121 | .fa-eur:before { 1122 | content: "\f153"; 1123 | } 1124 | .fa-gbp:before { 1125 | content: "\f154"; 1126 | } 1127 | .fa-dollar:before, 1128 | .fa-usd:before { 1129 | content: "\f155"; 1130 | } 1131 | .fa-rupee:before, 1132 | .fa-inr:before { 1133 | content: "\f156"; 1134 | } 1135 | .fa-cny:before, 1136 | .fa-rmb:before, 1137 | .fa-yen:before, 1138 | .fa-jpy:before { 1139 | content: "\f157"; 1140 | } 1141 | .fa-ruble:before, 1142 | .fa-rouble:before, 1143 | .fa-rub:before { 1144 | content: "\f158"; 1145 | } 1146 | .fa-won:before, 1147 | .fa-krw:before { 1148 | content: "\f159"; 1149 | } 1150 | .fa-bitcoin:before, 1151 | .fa-btc:before { 1152 | content: "\f15a"; 1153 | } 1154 | .fa-file:before { 1155 | content: "\f15b"; 1156 | } 1157 | .fa-file-text:before { 1158 | content: "\f15c"; 1159 | } 1160 | .fa-sort-alpha-asc:before { 1161 | content: "\f15d"; 1162 | } 1163 | .fa-sort-alpha-desc:before { 1164 | content: "\f15e"; 1165 | } 1166 | .fa-sort-amount-asc:before { 1167 | content: "\f160"; 1168 | } 1169 | .fa-sort-amount-desc:before { 1170 | content: "\f161"; 1171 | } 1172 | .fa-sort-numeric-asc:before { 1173 | content: "\f162"; 1174 | } 1175 | .fa-sort-numeric-desc:before { 1176 | content: "\f163"; 1177 | } 1178 | .fa-thumbs-up:before { 1179 | content: "\f164"; 1180 | } 1181 | .fa-thumbs-down:before { 1182 | content: "\f165"; 1183 | } 1184 | .fa-youtube-square:before { 1185 | content: "\f166"; 1186 | } 1187 | .fa-youtube:before { 1188 | content: "\f167"; 1189 | } 1190 | .fa-xing:before { 1191 | content: "\f168"; 1192 | } 1193 | .fa-xing-square:before { 1194 | content: "\f169"; 1195 | } 1196 | .fa-youtube-play:before { 1197 | content: "\f16a"; 1198 | } 1199 | .fa-dropbox:before { 1200 | content: "\f16b"; 1201 | } 1202 | .fa-stack-overflow:before { 1203 | content: "\f16c"; 1204 | } 1205 | .fa-instagram:before { 1206 | content: "\f16d"; 1207 | } 1208 | .fa-flickr:before { 1209 | content: "\f16e"; 1210 | } 1211 | .fa-adn:before { 1212 | content: "\f170"; 1213 | } 1214 | .fa-bitbucket:before { 1215 | content: "\f171"; 1216 | } 1217 | .fa-bitbucket-square:before { 1218 | content: "\f172"; 1219 | } 1220 | .fa-tumblr:before { 1221 | content: "\f173"; 1222 | } 1223 | .fa-tumblr-square:before { 1224 | content: "\f174"; 1225 | } 1226 | .fa-long-arrow-down:before { 1227 | content: "\f175"; 1228 | } 1229 | .fa-long-arrow-up:before { 1230 | content: "\f176"; 1231 | } 1232 | .fa-long-arrow-left:before { 1233 | content: "\f177"; 1234 | } 1235 | .fa-long-arrow-right:before { 1236 | content: "\f178"; 1237 | } 1238 | .fa-apple:before { 1239 | content: "\f179"; 1240 | } 1241 | .fa-windows:before { 1242 | content: "\f17a"; 1243 | } 1244 | .fa-android:before { 1245 | content: "\f17b"; 1246 | } 1247 | .fa-linux:before { 1248 | content: "\f17c"; 1249 | } 1250 | .fa-dribbble:before { 1251 | content: "\f17d"; 1252 | } 1253 | .fa-skype:before { 1254 | content: "\f17e"; 1255 | } 1256 | .fa-foursquare:before { 1257 | content: "\f180"; 1258 | } 1259 | .fa-trello:before { 1260 | content: "\f181"; 1261 | } 1262 | .fa-female:before { 1263 | content: "\f182"; 1264 | } 1265 | .fa-male:before { 1266 | content: "\f183"; 1267 | } 1268 | .fa-gittip:before, 1269 | .fa-gratipay:before { 1270 | content: "\f184"; 1271 | } 1272 | .fa-sun-o:before { 1273 | content: "\f185"; 1274 | } 1275 | .fa-moon-o:before { 1276 | content: "\f186"; 1277 | } 1278 | .fa-archive:before { 1279 | content: "\f187"; 1280 | } 1281 | .fa-bug:before { 1282 | content: "\f188"; 1283 | } 1284 | .fa-vk:before { 1285 | content: "\f189"; 1286 | } 1287 | .fa-weibo:before { 1288 | content: "\f18a"; 1289 | } 1290 | .fa-renren:before { 1291 | content: "\f18b"; 1292 | } 1293 | .fa-pagelines:before { 1294 | content: "\f18c"; 1295 | } 1296 | .fa-stack-exchange:before { 1297 | content: "\f18d"; 1298 | } 1299 | .fa-arrow-circle-o-right:before { 1300 | content: "\f18e"; 1301 | } 1302 | .fa-arrow-circle-o-left:before { 1303 | content: "\f190"; 1304 | } 1305 | .fa-toggle-left:before, 1306 | .fa-caret-square-o-left:before { 1307 | content: "\f191"; 1308 | } 1309 | .fa-dot-circle-o:before { 1310 | content: "\f192"; 1311 | } 1312 | .fa-wheelchair:before { 1313 | content: "\f193"; 1314 | } 1315 | .fa-vimeo-square:before { 1316 | content: "\f194"; 1317 | } 1318 | .fa-turkish-lira:before, 1319 | .fa-try:before { 1320 | content: "\f195"; 1321 | } 1322 | .fa-plus-square-o:before { 1323 | content: "\f196"; 1324 | } 1325 | .fa-space-shuttle:before { 1326 | content: "\f197"; 1327 | } 1328 | .fa-slack:before { 1329 | content: "\f198"; 1330 | } 1331 | .fa-envelope-square:before { 1332 | content: "\f199"; 1333 | } 1334 | .fa-wordpress:before { 1335 | content: "\f19a"; 1336 | } 1337 | .fa-openid:before { 1338 | content: "\f19b"; 1339 | } 1340 | .fa-institution:before, 1341 | .fa-bank:before, 1342 | .fa-university:before { 1343 | content: "\f19c"; 1344 | } 1345 | .fa-mortar-board:before, 1346 | .fa-graduation-cap:before { 1347 | content: "\f19d"; 1348 | } 1349 | .fa-yahoo:before { 1350 | content: "\f19e"; 1351 | } 1352 | .fa-google:before { 1353 | content: "\f1a0"; 1354 | } 1355 | .fa-reddit:before { 1356 | content: "\f1a1"; 1357 | } 1358 | .fa-reddit-square:before { 1359 | content: "\f1a2"; 1360 | } 1361 | .fa-stumbleupon-circle:before { 1362 | content: "\f1a3"; 1363 | } 1364 | .fa-stumbleupon:before { 1365 | content: "\f1a4"; 1366 | } 1367 | .fa-delicious:before { 1368 | content: "\f1a5"; 1369 | } 1370 | .fa-digg:before { 1371 | content: "\f1a6"; 1372 | } 1373 | .fa-pied-piper:before { 1374 | content: "\f1a7"; 1375 | } 1376 | .fa-pied-piper-alt:before { 1377 | content: "\f1a8"; 1378 | } 1379 | .fa-drupal:before { 1380 | content: "\f1a9"; 1381 | } 1382 | .fa-joomla:before { 1383 | content: "\f1aa"; 1384 | } 1385 | .fa-language:before { 1386 | content: "\f1ab"; 1387 | } 1388 | .fa-fax:before { 1389 | content: "\f1ac"; 1390 | } 1391 | .fa-building:before { 1392 | content: "\f1ad"; 1393 | } 1394 | .fa-child:before { 1395 | content: "\f1ae"; 1396 | } 1397 | .fa-paw:before { 1398 | content: "\f1b0"; 1399 | } 1400 | .fa-spoon:before { 1401 | content: "\f1b1"; 1402 | } 1403 | .fa-cube:before { 1404 | content: "\f1b2"; 1405 | } 1406 | .fa-cubes:before { 1407 | content: "\f1b3"; 1408 | } 1409 | .fa-behance:before { 1410 | content: "\f1b4"; 1411 | } 1412 | .fa-behance-square:before { 1413 | content: "\f1b5"; 1414 | } 1415 | .fa-steam:before { 1416 | content: "\f1b6"; 1417 | } 1418 | .fa-steam-square:before { 1419 | content: "\f1b7"; 1420 | } 1421 | .fa-recycle:before { 1422 | content: "\f1b8"; 1423 | } 1424 | .fa-automobile:before, 1425 | .fa-car:before { 1426 | content: "\f1b9"; 1427 | } 1428 | .fa-cab:before, 1429 | .fa-taxi:before { 1430 | content: "\f1ba"; 1431 | } 1432 | .fa-tree:before { 1433 | content: "\f1bb"; 1434 | } 1435 | .fa-spotify:before { 1436 | content: "\f1bc"; 1437 | } 1438 | .fa-deviantart:before { 1439 | content: "\f1bd"; 1440 | } 1441 | .fa-soundcloud:before { 1442 | content: "\f1be"; 1443 | } 1444 | .fa-database:before { 1445 | content: "\f1c0"; 1446 | } 1447 | .fa-file-pdf-o:before { 1448 | content: "\f1c1"; 1449 | } 1450 | .fa-file-word-o:before { 1451 | content: "\f1c2"; 1452 | } 1453 | .fa-file-excel-o:before { 1454 | content: "\f1c3"; 1455 | } 1456 | .fa-file-powerpoint-o:before { 1457 | content: "\f1c4"; 1458 | } 1459 | .fa-file-photo-o:before, 1460 | .fa-file-picture-o:before, 1461 | .fa-file-image-o:before { 1462 | content: "\f1c5"; 1463 | } 1464 | .fa-file-zip-o:before, 1465 | .fa-file-archive-o:before { 1466 | content: "\f1c6"; 1467 | } 1468 | .fa-file-sound-o:before, 1469 | .fa-file-audio-o:before { 1470 | content: "\f1c7"; 1471 | } 1472 | .fa-file-movie-o:before, 1473 | .fa-file-video-o:before { 1474 | content: "\f1c8"; 1475 | } 1476 | .fa-file-code-o:before { 1477 | content: "\f1c9"; 1478 | } 1479 | .fa-vine:before { 1480 | content: "\f1ca"; 1481 | } 1482 | .fa-codepen:before { 1483 | content: "\f1cb"; 1484 | } 1485 | .fa-jsfiddle:before { 1486 | content: "\f1cc"; 1487 | } 1488 | .fa-life-bouy:before, 1489 | .fa-life-buoy:before, 1490 | .fa-life-saver:before, 1491 | .fa-support:before, 1492 | .fa-life-ring:before { 1493 | content: "\f1cd"; 1494 | } 1495 | .fa-circle-o-notch:before { 1496 | content: "\f1ce"; 1497 | } 1498 | .fa-ra:before, 1499 | .fa-rebel:before { 1500 | content: "\f1d0"; 1501 | } 1502 | .fa-ge:before, 1503 | .fa-empire:before { 1504 | content: "\f1d1"; 1505 | } 1506 | .fa-git-square:before { 1507 | content: "\f1d2"; 1508 | } 1509 | .fa-git:before { 1510 | content: "\f1d3"; 1511 | } 1512 | .fa-hacker-news:before { 1513 | content: "\f1d4"; 1514 | } 1515 | .fa-tencent-weibo:before { 1516 | content: "\f1d5"; 1517 | } 1518 | .fa-qq:before { 1519 | content: "\f1d6"; 1520 | } 1521 | .fa-wechat:before, 1522 | .fa-weixin:before { 1523 | content: "\f1d7"; 1524 | } 1525 | .fa-send:before, 1526 | .fa-paper-plane:before { 1527 | content: "\f1d8"; 1528 | } 1529 | .fa-send-o:before, 1530 | .fa-paper-plane-o:before { 1531 | content: "\f1d9"; 1532 | } 1533 | .fa-history:before { 1534 | content: "\f1da"; 1535 | } 1536 | .fa-genderless:before, 1537 | .fa-circle-thin:before { 1538 | content: "\f1db"; 1539 | } 1540 | .fa-header:before { 1541 | content: "\f1dc"; 1542 | } 1543 | .fa-paragraph:before { 1544 | content: "\f1dd"; 1545 | } 1546 | .fa-sliders:before { 1547 | content: "\f1de"; 1548 | } 1549 | .fa-share-alt:before { 1550 | content: "\f1e0"; 1551 | } 1552 | .fa-share-alt-square:before { 1553 | content: "\f1e1"; 1554 | } 1555 | .fa-bomb:before { 1556 | content: "\f1e2"; 1557 | } 1558 | .fa-soccer-ball-o:before, 1559 | .fa-futbol-o:before { 1560 | content: "\f1e3"; 1561 | } 1562 | .fa-tty:before { 1563 | content: "\f1e4"; 1564 | } 1565 | .fa-binoculars:before { 1566 | content: "\f1e5"; 1567 | } 1568 | .fa-plug:before { 1569 | content: "\f1e6"; 1570 | } 1571 | .fa-slideshare:before { 1572 | content: "\f1e7"; 1573 | } 1574 | .fa-twitch:before { 1575 | content: "\f1e8"; 1576 | } 1577 | .fa-yelp:before { 1578 | content: "\f1e9"; 1579 | } 1580 | .fa-newspaper-o:before { 1581 | content: "\f1ea"; 1582 | } 1583 | .fa-wifi:before { 1584 | content: "\f1eb"; 1585 | } 1586 | .fa-calculator:before { 1587 | content: "\f1ec"; 1588 | } 1589 | .fa-paypal:before { 1590 | content: "\f1ed"; 1591 | } 1592 | .fa-google-wallet:before { 1593 | content: "\f1ee"; 1594 | } 1595 | .fa-cc-visa:before { 1596 | content: "\f1f0"; 1597 | } 1598 | .fa-cc-mastercard:before { 1599 | content: "\f1f1"; 1600 | } 1601 | .fa-cc-discover:before { 1602 | content: "\f1f2"; 1603 | } 1604 | .fa-cc-amex:before { 1605 | content: "\f1f3"; 1606 | } 1607 | .fa-cc-paypal:before { 1608 | content: "\f1f4"; 1609 | } 1610 | .fa-cc-stripe:before { 1611 | content: "\f1f5"; 1612 | } 1613 | .fa-bell-slash:before { 1614 | content: "\f1f6"; 1615 | } 1616 | .fa-bell-slash-o:before { 1617 | content: "\f1f7"; 1618 | } 1619 | .fa-trash:before { 1620 | content: "\f1f8"; 1621 | } 1622 | .fa-copyright:before { 1623 | content: "\f1f9"; 1624 | } 1625 | .fa-at:before { 1626 | content: "\f1fa"; 1627 | } 1628 | .fa-eyedropper:before { 1629 | content: "\f1fb"; 1630 | } 1631 | .fa-paint-brush:before { 1632 | content: "\f1fc"; 1633 | } 1634 | .fa-birthday-cake:before { 1635 | content: "\f1fd"; 1636 | } 1637 | .fa-area-chart:before { 1638 | content: "\f1fe"; 1639 | } 1640 | .fa-pie-chart:before { 1641 | content: "\f200"; 1642 | } 1643 | .fa-line-chart:before { 1644 | content: "\f201"; 1645 | } 1646 | .fa-lastfm:before { 1647 | content: "\f202"; 1648 | } 1649 | .fa-lastfm-square:before { 1650 | content: "\f203"; 1651 | } 1652 | .fa-toggle-off:before { 1653 | content: "\f204"; 1654 | } 1655 | .fa-toggle-on:before { 1656 | content: "\f205"; 1657 | } 1658 | .fa-bicycle:before { 1659 | content: "\f206"; 1660 | } 1661 | .fa-bus:before { 1662 | content: "\f207"; 1663 | } 1664 | .fa-ioxhost:before { 1665 | content: "\f208"; 1666 | } 1667 | .fa-angellist:before { 1668 | content: "\f209"; 1669 | } 1670 | .fa-cc:before { 1671 | content: "\f20a"; 1672 | } 1673 | .fa-shekel:before, 1674 | .fa-sheqel:before, 1675 | .fa-ils:before { 1676 | content: "\f20b"; 1677 | } 1678 | .fa-meanpath:before { 1679 | content: "\f20c"; 1680 | } 1681 | .fa-buysellads:before { 1682 | content: "\f20d"; 1683 | } 1684 | .fa-connectdevelop:before { 1685 | content: "\f20e"; 1686 | } 1687 | .fa-dashcube:before { 1688 | content: "\f210"; 1689 | } 1690 | .fa-forumbee:before { 1691 | content: "\f211"; 1692 | } 1693 | .fa-leanpub:before { 1694 | content: "\f212"; 1695 | } 1696 | .fa-sellsy:before { 1697 | content: "\f213"; 1698 | } 1699 | .fa-shirtsinbulk:before { 1700 | content: "\f214"; 1701 | } 1702 | .fa-simplybuilt:before { 1703 | content: "\f215"; 1704 | } 1705 | .fa-skyatlas:before { 1706 | content: "\f216"; 1707 | } 1708 | .fa-cart-plus:before { 1709 | content: "\f217"; 1710 | } 1711 | .fa-cart-arrow-down:before { 1712 | content: "\f218"; 1713 | } 1714 | .fa-diamond:before { 1715 | content: "\f219"; 1716 | } 1717 | .fa-ship:before { 1718 | content: "\f21a"; 1719 | } 1720 | .fa-user-secret:before { 1721 | content: "\f21b"; 1722 | } 1723 | .fa-motorcycle:before { 1724 | content: "\f21c"; 1725 | } 1726 | .fa-street-view:before { 1727 | content: "\f21d"; 1728 | } 1729 | .fa-heartbeat:before { 1730 | content: "\f21e"; 1731 | } 1732 | .fa-venus:before { 1733 | content: "\f221"; 1734 | } 1735 | .fa-mars:before { 1736 | content: "\f222"; 1737 | } 1738 | .fa-mercury:before { 1739 | content: "\f223"; 1740 | } 1741 | .fa-transgender:before { 1742 | content: "\f224"; 1743 | } 1744 | .fa-transgender-alt:before { 1745 | content: "\f225"; 1746 | } 1747 | .fa-venus-double:before { 1748 | content: "\f226"; 1749 | } 1750 | .fa-mars-double:before { 1751 | content: "\f227"; 1752 | } 1753 | .fa-venus-mars:before { 1754 | content: "\f228"; 1755 | } 1756 | .fa-mars-stroke:before { 1757 | content: "\f229"; 1758 | } 1759 | .fa-mars-stroke-v:before { 1760 | content: "\f22a"; 1761 | } 1762 | .fa-mars-stroke-h:before { 1763 | content: "\f22b"; 1764 | } 1765 | .fa-neuter:before { 1766 | content: "\f22c"; 1767 | } 1768 | .fa-facebook-official:before { 1769 | content: "\f230"; 1770 | } 1771 | .fa-pinterest-p:before { 1772 | content: "\f231"; 1773 | } 1774 | .fa-whatsapp:before { 1775 | content: "\f232"; 1776 | } 1777 | .fa-server:before { 1778 | content: "\f233"; 1779 | } 1780 | .fa-user-plus:before { 1781 | content: "\f234"; 1782 | } 1783 | .fa-user-times:before { 1784 | content: "\f235"; 1785 | } 1786 | .fa-hotel:before, 1787 | .fa-bed:before { 1788 | content: "\f236"; 1789 | } 1790 | .fa-viacoin:before { 1791 | content: "\f237"; 1792 | } 1793 | .fa-train:before { 1794 | content: "\f238"; 1795 | } 1796 | .fa-subway:before { 1797 | content: "\f239"; 1798 | } 1799 | .fa-medium:before { 1800 | content: "\f23a"; 1801 | } 1802 | --------------------------------------------------------------------------------