Full Code of MattMcFarland/reactathon for AI

master c35837d58488 cached
178 files
2.3 MB
611.1k tokens
120 symbols
1 requests
Download .txt
Showing preview only (2,569K chars total). Download the full file or copy to clipboard to get everything.
Repository: MattMcFarland/reactathon
Branch: master
Commit: c35837d58488
Files: 178
Total size: 2.3 MB

Directory structure:
gitextract_uwmvxg_y/

├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .flowconfig
├── .gitignore
├── LICENSE
├── README.md
├── client/
│   ├── client-manifest.json
│   ├── gulpCompressionOptions.js
│   └── src/
│       ├── Layout.js
│       ├── __tests__/
│       │   └── ok.js
│       ├── actions/
│       │   └── AppActions.js
│       ├── alt.js
│       ├── components/
│       │   ├── AddNewArticleForm.js
│       │   ├── LoginForm.js
│       │   ├── ResetPasswordForm.js
│       │   ├── ResetRequestForm.js
│       │   ├── SignupForm.js
│       │   ├── index.js
│       │   └── partials/
│       │       ├── Elements.js
│       │       ├── FormErrors.js
│       │       └── index.js
│       ├── containers/
│       │   ├── AddNewArticle.js
│       │   ├── Article.js
│       │   ├── ArticleList.js
│       │   ├── Dashboard.js
│       │   ├── Home.js
│       │   ├── Login.js
│       │   ├── NoMatch.js
│       │   ├── Page.js
│       │   ├── ResetPassword.js
│       │   ├── ResetRequest.js
│       │   ├── SignUp.js
│       │   ├── Tag.js
│       │   ├── TagList.js
│       │   ├── User.js
│       │   └── index.js
│       ├── main.js
│       ├── queries/
│       │   ├── ViewerQueries.js
│       │   └── index.js
│       ├── stores/
│       │   └── AppStore.js
│       └── style/
│           ├── base/
│           │   ├── _transitions.scss
│           │   └── _variables.scss
│           ├── main.scss
│           ├── objects/
│           │   └── _buttons.scss
│           └── vendor/
│               ├── _bootstrap.scss
│               └── bootstrap/
│                   ├── _alerts.scss
│                   ├── _badges.scss
│                   ├── _breadcrumbs.scss
│                   ├── _button-groups.scss
│                   ├── _buttons.scss
│                   ├── _carousel.scss
│                   ├── _close.scss
│                   ├── _code.scss
│                   ├── _component-animations.scss
│                   ├── _dropdowns.scss
│                   ├── _forms.scss
│                   ├── _glyphicons.scss
│                   ├── _grid.scss
│                   ├── _input-groups.scss
│                   ├── _jumbotron.scss
│                   ├── _labels.scss
│                   ├── _list-group.scss
│                   ├── _media.scss
│                   ├── _mixins.scss
│                   ├── _modals.scss
│                   ├── _navbar.scss
│                   ├── _navs.scss
│                   ├── _normalize.scss
│                   ├── _pager.scss
│                   ├── _pagination.scss
│                   ├── _panels.scss
│                   ├── _popovers.scss
│                   ├── _print.scss
│                   ├── _progress-bars.scss
│                   ├── _responsive-embed.scss
│                   ├── _responsive-utilities.scss
│                   ├── _scaffolding.scss
│                   ├── _tables.scss
│                   ├── _theme.scss
│                   ├── _thumbnails.scss
│                   ├── _tooltip.scss
│                   ├── _type.scss
│                   ├── _utilities.scss
│                   ├── _variables.scss
│                   ├── _wells.scss
│                   └── mixins/
│                       ├── _alerts.scss
│                       ├── _background-variant.scss
│                       ├── _border-radius.scss
│                       ├── _buttons.scss
│                       ├── _center-block.scss
│                       ├── _clearfix.scss
│                       ├── _forms.scss
│                       ├── _gradients.scss
│                       ├── _grid-framework.scss
│                       ├── _grid.scss
│                       ├── _hide-text.scss
│                       ├── _image.scss
│                       ├── _labels.scss
│                       ├── _list-group.scss
│                       ├── _nav-divider.scss
│                       ├── _nav-vertical-align.scss
│                       ├── _opacity.scss
│                       ├── _pagination.scss
│                       ├── _panels.scss
│                       ├── _progress-bar.scss
│                       ├── _reset-filter.scss
│                       ├── _reset-text.scss
│                       ├── _resize.scss
│                       ├── _responsive-visibility.scss
│                       ├── _size.scss
│                       ├── _tab-focus.scss
│                       ├── _table-row.scss
│                       ├── _text-emphasis.scss
│                       ├── _text-overflow.scss
│                       └── _vendor-prefixes.scss
├── data/
│   ├── schema.graphql
│   └── schema.json
├── ecosystem.json
├── gulpfile.js
├── mediakit/
│   └── reactathon.ai
├── package.json
├── scripts/
│   ├── babelRelayPlugin.js
│   ├── mocha-bootload.js
│   ├── seed.js
│   ├── server.js
│   └── updateSchema.js
├── server/
│   └── src/
│       ├── __tests__/
│       │   └── testModules.js
│       ├── app.config.js
│       ├── app.js
│       ├── auth/
│       │   ├── index.js
│       │   ├── modules.js
│       │   └── passport.js
│       ├── database/
│       │   ├── index.js
│       │   ├── migrations/
│       │   │   └── .gitkeep
│       │   ├── models/
│       │   │   ├── Article.js
│       │   │   ├── Comment.js
│       │   │   ├── Flag.js
│       │   │   ├── Tag.js
│       │   │   ├── TagItem.js
│       │   │   ├── Token.js
│       │   │   ├── User.js
│       │   │   ├── Vote.js
│       │   │   ├── customTypes/
│       │   │   │   ├── URL.js
│       │   │   │   ├── email.js
│       │   │   │   └── index.js
│       │   │   └── index.js
│       │   ├── modules.js
│       │   └── seeders/
│       │       └── .gitkeep
│       ├── modules.js
│       ├── pages/
│       │   └── about.md
│       ├── public/
│       │   ├── browserconfig.xml
│       │   ├── img/
│       │   │   └── .gitkeep
│       │   └── manifest.json
│       ├── routes/
│       │   ├── api.js
│       │   ├── auth.js
│       │   ├── index.js
│       │   ├── modules.js
│       │   └── root.js
│       ├── schema/
│       │   └── index.js
│       ├── utils/
│       │   ├── fromGravatar.js
│       │   ├── getGravatar.js
│       │   ├── index.js
│       │   ├── logger.js
│       │   └── modules.js
│       └── views/
│           ├── error.hbs
│           ├── index.hbs
│           ├── layout.hbs
│           └── root.hbs
├── ssl/
│   ├── localhost.cert
│   └── localhost.key
└── tasks/
    ├── bundle.js
    ├── bundledebugdeps.js
    ├── bundledeps.js
    ├── bundlemin.js
    ├── helpers.js
    └── sass.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .babelrc
================================================
{
  "presets": ["es2015", "stage-0", "react"],
  "plugins": ["transform-flow-strip-types", "babel-relay-plugin-loader"]
}

================================================
FILE: .editorconfig
================================================
; http://editorconfig.org

root = true

[*.js]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
indent_size = 2

[*.html]
indent_size = 2

[*.hbs]
indent_size = 2


================================================
FILE: .eslintignore
================================================
./flow/**/*
./tasks/**/*
./scripts/**/*

================================================
FILE: .eslintrc
================================================
{
  "parser": "babel-eslint",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "plugins": [
    "react"
  ],
  "arrowFunctions": true,
  "blockBindings": true,
  "classes": true,
  "defaultParams": true,
  "destructuring": true,
  "forOf": true,
  "generators": true,
  "modules": true,
  "objectLiteralComputedProperties": true,
  "objectLiteralShorthandMethods": true,
  "objectLiteralShorthandProperties": true,
  "spread": true,
  "templateStrings": true,
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  "rules": {
    "react/display-name": [2, { "acceptTranspilerName": true }],
    "react/forbid-prop-types": [2, { "forbid": [] }],
    "react/jsx-boolean-value": [2, "never"],
    "react/jsx-closing-bracket-location": [2, "after-props"],
    "react/jsx-curly-spacing": [2, "never"],
    "react/jsx-handler-names": [0, {
      "eventHandlerPrefix": "handle",
      "eventHandlerPropPrefix": "on"
    }],
    "react/jsx-indent-props": [0, "1"],
    "react/jsx-key": 2,
    "react/jsx-max-props-per-line": [2, { "maximum": 4 }],
    "react/jsx-no-bind": 2,
    "react/jsx-no-duplicate-props": 2,
    "react/jsx-no-literals": 0,
    "react/jsx-no-undef": 2,
    "react/jsx-pascal-case": 2,
    "react/jsx-sort-prop-types": 0,
    "react/jsx-sort-props": 0,
    "react/jsx-uses-react": 2,
    "react/jsx-uses-vars": 2,
    "react/no-danger": 0,
    "react/no-did-mount-set-state": 2,
    "react/no-did-update-set-state": 2,
    "react/no-direct-mutation-state": 2,
    "react/no-multi-comp": 0,
    "react/no-set-state": 0,
    "react/no-unknown-property": 2,
    "react/prefer-es6-class": 2,
    "react/prop-types": 0,
    "react/react-in-jsx-scope": 2,
    "react/require-extension": 2,
    "react/self-closing-comp": 2,
    "react/sort-comp": 0,
    "react/wrap-multilines": 2,
    "comma-dangle": 0,
    "no-cond-assign": 2,
    "no-console": 0,
    "no-constant-condition": 2,
    "no-control-regex": 0,
    "no-debugger": 0,
    "no-dupe-args": 2,
    "no-dupe-keys": 2,
    "no-duplicate-case": 2,
    "no-empty": 2,
    "no-empty-character-class": 2,
    "no-ex-assign": 2,
    "no-extra-boolean-cast": 2,
    "no-extra-semi": 2,
    "no-func-assign": 2,
    "no-inner-declarations": [
      2,
      "functions"
    ],
    "no-invalid-regexp": 2,
    "no-irregular-whitespace": 2,
    "no-negated-in-lhs": 2,
    "no-obj-calls": 2,
    "no-regex-spaces": 2,
    "no-reserved-keys": 0,
    "no-sparse-arrays": 2,
    "no-unreachable": 2,
    "use-isnan": 2,
    "valid-jsdoc": 0,
    "valid-typeof": 2,
    "block-scoped-var": 0,
    "complexity": 0,
    "consistent-return": 0,
    "curly": [
      2,
      "all"
    ],
    "default-case": 0,
    "dot-notation": 0,
    "eqeqeq": 2,
    "guard-for-in": 2,
    "no-alert": 2,
    "no-caller": 2,
    "no-div-regex": 2,
    "no-empty-label": 2,
    "no-eq-null": 0,
    "no-eval": 2,
    "no-extend-native": 2,
    "no-extra-bind": 2,
    "no-fallthrough": 2,
    "no-floating-decimal": 2,
    "no-implied-eval": 2,
    "no-iterator": 2,
    "no-labels": 0,
    "no-lone-blocks": 0,
    "no-loop-func": 0,
    "no-multi-spaces": 2,
    "no-multi-str": 2,
    "no-native-reassign": 0,
    "no-new": 2,
    "no-new-func": 0,
    "no-new-wrappers": 2,
    "no-octal": 2,
    "no-octal-escape": 2,
    "no-param-reassign": 2,
    "no-process-env": 0,
    "no-proto": 2,
    "no-redeclare": 2,
    "no-return-assign": 2,
    "no-script-url": 2,
    "no-self-compare": 0,
    "no-sequences": 2,
    "no-throw-literal": 2,
    "no-unused-expressions": 2,
    "no-void": 2,
    "no-warning-comments": 0,
    "no-with": 2,
    "radix": [2, "as-needed"],
    "vars-on-top": 0,
    "wrap-iife": 2,
    "yoda": [
      2,
      "never",
      {
        "exceptRange": true
      }
    ],
    "strict": 0,
    "no-catch-shadow": 2,
    "no-delete-var": 2,
    "no-label-var": 2,
    "no-shadow": 2,
    "no-shadow-restricted-names": 2,
    "no-undef": 2,
    "no-undef-init": 2,
    "no-undefined": 0,
    "no-unused-vars": [
      2,
      {
        "vars": "all",
        "args": "after-used",
        "varsIgnorePattern": "React|Relay"
      }
    ],
    "no-use-before-define": 0,
    "handle-callback-err": [
      2,
      "error"
    ],
    "no-mixed-requires": [
      2,
      true
    ],
    "no-new-require": 2,
    "no-path-concat": 2,
    "no-process-exit": 0,
    "no-restricted-modules": 0,
    "no-sync": 0,
    "brace-style": [
      2,
      "1tbs",
      {
        "allowSingleLine": true
      }
    ],
    "comma-spacing": 0,
    "comma-style": [
      2,
      "last"
    ],
    "consistent-this": 0,
    "eol-last": 2,
    "func-names": 0,
    "func-style": 0,
    "key-spacing": [
      2,
      {
        "beforeColon": false,
        "afterColon": true
      }
    ],
    "max-nested-callbacks": 0,
    "new-cap": 0,
    "new-parens": 2,
    "newline-after-var": 0,
    "no-array-constructor": 2,
    "no-inline-comments": 0,
    "no-lonely-if": 2,
    "no-mixed-spaces-and-tabs": 2,
    "no-multiple-empty-lines": 0,
    "no-nested-ternary": 0,
    "no-new-object": 2,
    "no-spaced-func": 2,
    "no-ternary": 0,
    "no-trailing-spaces": 0,
    "no-underscore-dangle": 0,
    "one-var": [
      2,
      "never"
    ],
    "operator-assignment": [
      2,
      "always"
    ],
    "padded-blocks": 0,
    "quote-props": [
      2,
      "as-needed"
    ],
    "quotes": [
      2,
      "single"
    ],
    "semi": [
      2,
      "always"
    ],
    "semi-spacing": [
      2,
      {
        "before": false,
        "after": true
      }
    ],
    "sort-vars": 0,
    "space-after-keywords": [
      2,
      "always"
    ],
    "space-before-blocks": [
      2,
      "always"
    ],
    "space-before-function-paren": [
      2,
      {
        "anonymous": "always",
        "named": "never"
      }
    ],
    "space-in-brackets": 0,
    "space-in-parens": 0,
    "space-infix-ops": [
      2,
      {
        "int32Hint": false
      }
    ],
    "space-return-throw-case": 2,
    "space-unary-ops": [
      2,
      {
        "words": true,
        "nonwords": false
      }
    ],
    "spaced-comment": [
      2,
      "always"
    ],
    "wrap-regex": 0,
    "no-var": 0,
    "max-len": [2, 80, 4]
  }
}

================================================
FILE: .flowconfig
================================================
[ignore]
.*/coverage/.*
.*/scripts/.*
.*/node_modules/.*
.*/public/.*
.*/dist/.*

[include]

[libs]
flow

[options]


================================================
FILE: .gitignore
================================================
# Created by .ignore support plugin (hsz.mobi)
### Emacs template
# -*- mode: gitignore; -*-

\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*

# Org-mode
.org-id-locations
*_archive

# flymake-mode
*_flymake.*

# eshell files
/eshell/history
/eshell/lastdir

# elpa packages
/elpa/

# reftex files
*.rel

# AUCTeX auto folder
/auto/

# cask packages
.cask/
### VisualStudio template
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/

# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# DNX
project.lock.json
artifacts/

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile

# Visual Studio profiler
*.psess
*.vsp
*.vspx

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding add-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config

# Windows Azure Build Output
csx/
*.build.csdef

# Windows Store app package directory
AppPackages/

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/

# Others

*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
*.mdf
*.ldf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings

# Microsoft Fakes
FakesAssemblies/

# Node.js Tools for Visual Studio
.ntvs_analysis.dat

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
### Windows template
# Windows image file caches
Thumbs.db
ehthumbs.db

# Folder config file
Desktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msm
*.msp

# Windows shortcuts
*.lnk
### Vim template
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist

### Xcode template
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## Build generated
DerivedData

## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata

## Other
*.xccheckout
*.moved-aside
*.xcuserstate
### Node template
# Logs
logs

npm-debug.log*

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git


### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio

## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:

# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries

# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml

# Gradle:
# .idea/gradle.xml
# .idea/libraries

# Mongo Explorer plugin:
# .idea/mongoSettings.xml

## File-based project format:
*.ipr
*.iws

## Plugin-specific files:

# IntelliJ
/out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Cloud9 template
# Cloud9 IDE - http://c9.io
.c9revisions
.c9
### Linux template

# KDE directory preferences
.directory

# Linux trash folder which might appear on any partition or disk
.Trash-*
### Eclipse template
*.pydevproject
.metadata
.gradlex
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath

# Eclipse Core
.project

# External tool builders
.externalToolBuilders/

# Locally stored "Eclipse launch configurations"
*.launch

# CDT-specific
.cproject

# JDT-specific (Eclipse Java Development Tools)
.classpath

# Java annotation processor (APT)
.factorypath

# PDT-specific
.buildpath

# sbteclipse plugin
.target

# TeXlipse plugin
.texlipse
### OSX template
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

db.development.sqlite
db.test.sqlite

raw*.json

# bower
bower_components

# distribution
lib
bundles

# sessions
sessions

# logs
*.log

================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Reactathon
Copyright (c) 2016 Matt McFarland

Some code heavily borrowed from hackathon-started by Sahat Yalkabov.
https://github.com/sahat/hackathon-starter

Hackathon Starter
Copyright (c) 2014-2016 Sahat Yalkabov
MIT Licensed

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.

================================================
FILE: README.md
================================================
# DEPRECATED
This project has been superceded by the much more up-to-date, user-friendly, [react-create-app](https://github.com/facebookincubator/create-react-app) - which is perfect for hackathons or kickstarting your next react app!

---

### Getting started

**1. Clone the Repo:**

```sh
git clone https://github.com/MattMcFarland/reactathon.git 
```

**2. Install Dependencies:**

```sh
cd reactathon
npm install
```

**3. Edit App config:**

Edit `server/src/app.config.js` to setup everything.

**4. Seed database:**

Optionally run the seeder to create dummy data.

```sh
npm run seed
```

**5. Run the dev server:**

```sh
npm run dev
```

**6. Deploy when ready:**

Deploy options are further down the guide :)

### FAQs

- **What bells and whistles does Reactathon include?**

	- React.js
	- Node.js
	- Express.js
	- Babel.js 6.3.x ES7 Stage 0
	- GraphQL
	- Relay ready
	- Sequelize SQL ORM
	- sqlite3 database
	- PhantomJS SEO
  	- Winston logging
	- Passport.js with oAuth2 support
		- SQL User database
		- Github
  		- Facebook
  		- Twitter
  		- Google Plus
	- Deployment with the following suites:
  		- PM2
  		- Microsoft Azure
  		- Heroku

- **What are the System Requirements?** Reactathon has been tested with:
	- Mac OSX or Linux
	- Node.js v5.3.0
	- Further testing needed to source our requirements

- **Are the warnings a concern?** During `npm install` you may see warnings about deprecated or global packages. These are expected, and will not cause a problem. Should they become a problem, the project will be updated as needed.

- **Are any of the bundled packages experimental?**

Reactathon currently uses babel stage zero, which is considered experimental.
As such, it is recommended to sustain upgrading babel until reactathon is
more stable.

### Changelog

- 0.10.2
  - Update readme
  - Update package.json

- 0.10.1
  - Add resolve dependency
  
- 0.10.0
  - Add nav items for articles
  
- 0.9.0
  - Add database seeder (Issue: #6)
  - Add article list view (Issue: #3)
  - Add article detail view (Issue #20)
  
- 0.8.1
  - Update readme

- 0.8.0
  
  - Add Password reset views
  - Add Password reset endpoint
  - Add mailgun emailer
  - Add server endpoint for reset/forgot
  
- 0.7.0

  - Add winston logger

- 0.6.x
  - 0.6.2 - Fix issue #16 (Slow dev startup)
  - 0.6.1 - update ecosystem.json to have correct value for development env
  - 0.6.0 - add link/unlink social provider functionality to the dashboard view

- 0.5.0
  - add start of user dashboard
  - add edge cases for signup and logout
  - add oauth for github, google, twitter, and facebook.
  - fix critical issue with missing files causing npm install to fail.

- 0.4.x
  - 0.4.1 - Fix relayJS
  - 0.4.0 - Add Github oauth2 flow

- 0.3.0
  - Added social media button styling
  - Added client auth login logic

- 0.2.0
  - added adobe illustrator file

- 0.1.0

  - Fixed critical issue with example env vars not loading
  - Improved watch script speed
  - Add Token to model

- 0.0.0 -- start

### License

The MIT License

### Acknowledgements

The idea of this hackathon starter project is heavily inspired from [Hackathon Starter](https://github.com/sahat/hackathon-starter) that was created by Sahat Yalkabov in 2014 and is still very much in active development.




================================================
FILE: client/client-manifest.json
================================================
{
  "dependencies": {
    "alt": "0.17.9",
    "classnames": "^2.2.1",
    "highlight.js": "^9.0.0",
    "history": "^1.17.0",
    "moment": "^2.11.0",
    "react": "^0.14.3",
    "react-bootstrap": "^0.28.1",
    "react-dom": "^0.14.3",
    "react-input-autosize": "^0.6.6",
    "react-notification-system": "^0.2.6",
    "react-relay": "^0.6.1",
    "react-router": "^2.0.0-rc4",
    "react-router-relay": "^0.9.0",
    "react-select": "^0.9.1",
    "superagent": "^1.6.1",
    "validator": "^4.5.0"
  }
}

================================================
FILE: client/gulpCompressionOptions.js
================================================
module.exports = {
  sequences: true,      // join consecutive statemets with the “comma operator”
  properties: true,     // optimize property access: a["foo"] → a.foo
  dead_code: true,      // discard unreachable code
  drop_debugger: true,  // discard “debugger” statements
  unsafe: true,         // some unsafe optimizations (see below)
  conditionals: true,   // optimize if-s and conditional expressions
  comparisons: true,    // optimize comparisons
  evaluate: true,       // evaluate constant expressions
  booleans: true,       // optimize boolean expressions
  loops: true,          // optimize loops
  unused: true,         // drop unused variables/functions
  hoist_funs: true,     // hoist function declarations
  hoist_vars: true,     // hoist variable declarations
  if_return: true,      // optimize if-s followed by return/continue
  join_vars: true,      // join var declarations
  cascade: true,        // try to cascade `right` into `left` in sequences
  side_effects: true,   // drop side-effect-free statements
  warnings: true,       // warn about potentially dangerous optimizations/code
  global_defs: {}       // global definitions
};


================================================
FILE: client/src/Layout.js
================================================
import React from 'react';
import { Link } from 'react-router';
import {
  Navbar,
  Nav,
  MenuItem,
  Modal,
  Button,
  NavDropdown
} from 'react-bootstrap';
import { SignupForm, LoginForm } from './components';
import { Logo } from './components/partials/Elements';
import { AppActions } from './actions/AppActions';
import { AppStore } from './stores/AppStore';
import NotificationSystem from 'react-notification-system';

const Content = ({children}) => (
  <div>{children}</div>
);

export class Layout extends React.Component {

  constructor() {
    super();
    this.state = {
      ...AppStore.getState()
    };
    this._notificationSystem = null;
    this.onChange = this.onChange.bind(this);
  }
  componentDidMount() {
    AppStore.listen(this.onChange);
    this._notificationSystem = this.refs.notificationSystem;
  }
  componentWillUnmount() {
    AppStore.unlisten(this.onChange);
  }
  addNotification = (queue) => {
    let message = queue.slice(0, 1);
    this._notificationSystem.addNotification(message[0]);
  };
  onChange(state) {
    if (state.queue && state.queue.length) {
      setTimeout(this.addNotification(state.queue), 100);
    }
    this.setState(state);
  }

  render() {

    var Menu;

    var name = this.props.location.pathname;
    let { showSignupModal, showLoginModal } = this.state;


    let onShowSignupForm = () => (AppActions.showSignupModal());
    let onShowLoginForm = () => (AppActions.showLoginModal());
    let onHideSignupForm = () => (AppActions.hideSignupModal());
    let onHideLoginForm = () => (AppActions.hideLoginModal());
    let logout = (e) => {
      e.preventDefault();
      AppActions.logout();
    };
    let gotoDashboard = (e) => {
      e.preventDefault();
      this.props.history.push('/dashboard');
    };
    let gotoAddNewArticle = (e) => {
      e.preventDefault();
      this.props.history.push('/add-article');
    };
    if (this.state.user) {
      Menu = ({}) => (
        <Nav pullRight style={{marginTop: '5px'}}>
          <NavDropdown eventKey={2} title='Create' id='create-dropdown'>
            <MenuItem onClick={gotoAddNewArticle} eventKey={2.1}>
              Add New Article
            </MenuItem>
          </NavDropdown>
          <NavDropdown eventKey={3} title='Account' id='user-dropdown'>
            <MenuItem onClick={gotoDashboard} eventKey={3.1}>
              Dashboard
            </MenuItem>
            <MenuItem divider />
            <MenuItem onClick={logout} eventKey={3.2}>Logout</MenuItem>
          </NavDropdown>


        </Nav>
      );

    } else {

      Menu = ({}) => (
        <Nav pullRight style={{marginTop: '5px'}}>
          <Button bsStyle='link' onClick={onShowSignupForm}>
            Create Account
          </Button>
          <Button bsStyle='link' onClick={onShowLoginForm}>
            Login
          </Button>
        </Nav>
      );
    }




    return (
      <section>
        <Navbar inverse>
          <Navbar.Header>
            <Navbar.Brand>
              <Link
                style={{paddingTop: '21px'}}
                to='/'>
                <Logo />
              </Link>
            </Navbar.Brand>
            <Navbar.Toggle />
          </Navbar.Header>
          <Navbar.Collapse>
            <Nav>
              <Navbar.Text>
                <Link
                  activeClassName='active'
                  className='nav-item nav-link btn btn-link'
                  to='/page/about'>About</Link>
              </Navbar.Text>
              <Navbar.Text>
                <Link
                  activeClassName='active'
                  className='nav-item nav-link btn btn-link'
                  to='/articles'>Articles</Link>
              </Navbar.Text>
            </Nav>
            <Menu/>
          </Navbar.Collapse>
        </Navbar>
        <section className='container'>
          <Content key={name}>
            {this.props.children}
          </Content>
        </section>
        {showSignupModal ?
          <Modal
            show={showSignupModal}
            onHide={onHideSignupForm}>
            <Modal.Header closeButton>
              <Modal.Title>Signup</Modal.Title>
            </Modal.Header>
            <Modal.Body>
              <SignupForm />
            </Modal.Body>
            <Modal.Footer>
              <Button onClick={onHideSignupForm}>
                Cancel
              </Button>
            </Modal.Footer>
          </Modal>
          : ''}

        {showLoginModal ?
          <Modal
            show={showLoginModal}
            onHide={onHideLoginForm}>
            <Modal.Header closeButton>
              <Modal.Title>Login</Modal.Title>
            </Modal.Header>
            <Modal.Body>
              <LoginForm />
            </Modal.Body>
            <Modal.Footer>
              <Button onClick={onHideLoginForm}>
                Cancel
              </Button>
            </Modal.Footer>
          </Modal>
          : ''}

        <NotificationSystem ref='notificationSystem' />
      </section>
    );
  }
}

Layout.contextTypes = {
  router: React.PropTypes.object.isRequired
};


================================================
FILE: client/src/__tests__/ok.js
================================================


================================================
FILE: client/src/actions/AppActions.js
================================================
import alt from '../alt';
import ajax from 'superagent';

class AppActionsSpec {
  constructor() {
    this.generateActions(
      'signupPending',
      'signupSuccess',
      'signupFail',

      'loginPending',
      'loginSuccess',
      'loginFail',

      'logoutPending',
      'logoutSuccess',
      'logoutFail',

      'addArticlePending',
      'addArticleSuccess',
      'addArticleFail',


      'requestNewPassword',

      'showSignupModal',
      'hideSignupModal',
      'showLoginModal',
      'hideLoginModal',

      'pushQueue',
      'shiftQueue'

    );
  }

  logout() {
    ajax.post('/api/logout')
      .end((err, res) => {
        if (!err) {
          if (res && res.body) {
            this.actions.pushQueue({
              level: 'success',
              title: 'Goodbye!',
              message: 'You are now logged out!'
            });
            this.actions.shiftQueue();
            this.actions.logoutFail();
            this.actions.logoutSuccess(res.body.user);
          } else {
            this.actions.pushQueue({
              level: 'error',
              title: 'Oh snap!',
              message: 'Something bad happened!'
            });
            this.actions.shiftQueue();
            this.actions.logoutFail();
          }
        } else {
          this.actions.logoutFail(err);
        }
      });
    this.actions.logoutPending();
  }
  login({username, password}) {
      ajax.post('/api/login')
        .send({
          username,
          password
        })
        .set('Content-Type', 'application/json')
        .set('Accept', 'application/json')
        .end((err, res) => {
          if (!err) {
            if (res && res.body && res.body.user) {
              this.actions.pushQueue({
                level: 'success',
                title: 'Success!',
                message: 'You are now logged in!'
              });
              this.actions.shiftQueue();
              this.actions.loginFail();
              this.actions.loginSuccess(res.body.user);
            } else {
              this.actions.pushQueue({
                level: 'error',
                title: 'Oh snap!',
                message: 'Something bad happened!'
              });
              this.actions.shiftQueue();
              this.actions.loginFail();
            }
          } else {
            this.actions.loginFail(err);
          }
        });
    this.actions.loginPending();
  }

  addArticle({title, content}) {
    ajax.post('/api/add-article')
      .send({
        title,
        content
      })
      .set('Content-Type', 'application/json')
      .set('Accept', 'application/json')
      .end((err, res) => {
        if (!err) {
          if (res && res.body && res.body.user) {
            this.actions.pushQueue({
              level: 'success',
              title: 'Success!',
              message: 'Your article has been created!'
            });
            this.actions.shiftQueue();
            this.actions.addArticleFail();
            this.actions.addArticleSuccess(res.body.user);
          } else {
            this.actions.pushQueue({
              level: 'error',
              title: 'Oh snap!',
              message: 'Something bad happened!'
            });
            this.actions.shiftQueue();
            this.actions.addArticleFail();
          }
        } else {
          this.actions.addArticleFail(err);
        }
      });
    this.actions.addArticlePending();
  }

  signup({username, password, email}) {
    ajax.post('/api/signup')
      .send({
        username,
        password,
        email
      })
      .set('Content-Type', 'application/json')
      .set('Accept', 'application/json')
      .end((err, res) => {
        if (!err) {
          if (res && res.body && res.body.user) {
            this.actions.pushQueue({
              level: 'success',
              title: 'Success!',
              message: 'You are now logged in!'
            });
            this.actions.shiftQueue();
            this.actions.signupFail();
            this.actions.signupSuccess(res.body.user);
          } else {
            this.actions.pushQueue({
              level: 'error',
              title: 'Oh snap!',
              message: 'Something bad happened!'
            });
            this.actions.shiftQueue();
            this.actions.signupFail();
          }
        } else {
          this.actions.signupFail(err);
        }
      });
    this.actions.signupPending();
  }

  toast(options) {
    this.actions.pushQueue(options);
    this.actions.shiftQueue();
  }
}

export const AppActions = alt.createActions(AppActionsSpec);


================================================
FILE: client/src/alt.js
================================================
import Alt from 'alt';

var alt = new Alt();


export default alt;


================================================
FILE: client/src/components/AddNewArticleForm.js
================================================
import React from 'react';
import { FormErrors } from './partials';
import {
  Button,
  Input,
  ButtonInput
} from 'react-bootstrap';

import { AppActions } from '../actions/AppActions';
import { AppStore } from '../stores/AppStore';

export class AddNewArticleForm extends React.Component {

  constructor() {
    super();
    this.state = {
      ...AppStore.getState(),
      title: '',
      content: ''
    };
    this.onChange = this.onChange.bind(this);
  }
  componentDidMount() {
    AppStore.listen(this.onChange);
  }
  componentWillUnmount() {
    AppStore.unlisten(this.onChange);
  }
  onChange(state) {
    this.setState(state);
  }



  handleTitleChange = (e => this.onChange(
      {title: e.target.value})
  );
  handleContentChange = (e => this.onChange(
      {content: e.target.value})
  );


  validate = () => {
    var errors = [];
    var { title,
      content
      } = this.state;
    const rules = [
      {
        failOn: title.trim().length < 10,
        error: 'Title must be at least 10 characters'
      },
      {
        failOn: content.trim().length < 30,
        error: 'Content must be at least 30 characters'
      }
    ];

    rules.forEach((rule) => {

      if (rule.failOn) {
        errors.push(rule);
      }
    });

    if (errors.length) {
      return {
        errors: errors,
        valid: false
      };
    } else {
      return {
        errors: null,
        valid: true
      };
    }
  };

  handleSubmit = (e) => {
    e.preventDefault();


    var valid = this.validate();
    if (valid.errors) {

      let article = valid.errors.length > 1 ? 'are' : 'is';
      let noun = valid.errors.length > 1 ? 'errors' : 'error';
      let count = valid.errors.length > 1 ? valid.errors.length : 'one';

      this.setState({
        error: {
          message: `There ${article} ${count} ${noun},  please try again.`,
          data: valid.errors
        }
      });
      return;
    }

    AppActions.addArticle({
      title: this.state.title,
      content: this.state.content
    });

  };

  render() {
    // handlers
    let {
      handleSubmit,
      handleTitleChange,
      handleContentChange
      } = this;
    // state
    let {
      error,
      title,
      content
      } = this.state;

    return (
      <section>
        {error ? <FormErrors {...error} /> : ''}
        <form onSubmit={handleSubmit}>
          <h4>Create new Article</h4>
          <hr/>
          <Input disabled={this.state.addArticlePending}
                 type="text"
                 label="Title"
                 value={title}
                 onChange={handleTitleChange}
                 placeholder="Enter a title" />
          <Input disabled={this.state.addArticlePending}
                 type="textarea"
                 value={content}
                 onChange={handleContentChange}
                 label="Content" />
          {this.state.addArticlePending ?
            <Button disabled>Saving...</Button> :
            <ButtonInput bsStyle="success"
                         type="submit"
                         value="Save" />

          }

        </form>
      </section>
    );
  }
}


================================================
FILE: client/src/components/LoginForm.js
================================================
import React from 'react';
import { Link } from 'react-router';
import { FormErrors } from './partials';
import { Center, LoginWith } from './partials/Elements';
import {
  Button,
  Input,
  ButtonInput
} from 'react-bootstrap';

import { AppActions } from '../actions/AppActions';
import { AppStore } from '../stores/AppStore';

export class LoginForm extends React.Component {

  constructor() {
    super();
    this.state = {
      ...AppStore.getState(),
      username: '',
      password: ''
    };
    this.onChange = this.onChange.bind(this);
  }
  componentDidMount() {
    AppStore.listen(this.onChange);
  }
  componentWillUnmount() {
    AppStore.unlisten(this.onChange);
  }
  onChange(state) {
    this.setState(state);
  }

  clearState = () => {
    this.setState({
      username: '',
      password: ''
    });
  };

  handleForgotPasswordClick = () => {
    AppActions.hideLoginModal();
  };

  handleUsernameChange = (e => this.onChange(
      {username: e.target.value})
  );
  handlePasswordChange = (e => this.onChange(
      {password: e.target.value})
  );


  validate = () => {
    var errors = [];
    var { username,
      password
      } = this.state;
    const rules = [
      {
        failOn: username.trim().length < 4,
        error: 'Username must be at least 4 characters'
      },
      {
        failOn: password.trim().length < 5,
        error: 'Password must be at least 5 characters'
      }
    ];

    rules.forEach((rule) => {

      if (rule.failOn) {
        errors.push(rule);
      }
    });

    if (errors.length) {
      return {
        errors: errors,
        valid: false
      };
    } else {
      return {
        errors: null,
        valid: true
      };
    }
  };

  handleSubmit = (e) => {
    e.preventDefault();


    var valid = this.validate();
    if (valid.errors) {

      let article = valid.errors.length > 1 ? 'are' : 'is';
      let noun = valid.errors.length > 1 ? 'errors' : 'error';
      let count = valid.errors.length > 1 ? valid.errors.length : 'one';

      this.setState({
        error: {
          message: `There ${article} ${count} ${noun},  please try again.`,
          data: valid.errors
        }
      });
      return;
    }

    AppActions.login({
      username: this.state.username,
      password: this.state.password
    });

  };

  render() {
    // handlers
    let {
      handleSubmit,
      handleUsernameChange,
      handlePasswordChange,
      handleForgotPasswordClick
      } = this;
    // state
    let {
      error,
      username,
      password
      } = this.state;

    return (
      <section>
        {error ? <FormErrors {...error} /> : ''}
        <form onSubmit={handleSubmit}>
          <Center><h4>Login with social account</h4></Center>
          <hr/>
          <LoginWith github/>
          <LoginWith reddit/>
          <LoginWith google/>
          <LoginWith twitter/>
          <LoginWith facebook/>
          <Center><h4>Sign in with local account</h4></Center>
          <hr/>
          <Input disabled={this.state.loginPending}
                 type="text"
                 label="Username"
                 value={username}
                 onChange={handleUsernameChange}
                 placeholder="Enter a username" />
          <Input disabled={this.state.loginPending}
                 type="password"
                 value={password}
                 onChange={handlePasswordChange}
                 label="Password" />
          {this.state.signupPending ?
            <Button disabled>Signing up...</Button> :
            <ButtonInput bsStyle="success"
                         type="submit"
                         value="Login" />

        }
          <Link
            onClick={handleForgotPasswordClick}
            to={{
            pathname: '/reset'
          }}>
            Forgot your password?
          </Link>
        </form>
      </section>
    );
  }
}


================================================
FILE: client/src/components/ResetPasswordForm.js
================================================
import React from 'react';
import ajax from 'superagent';
import { Link } from 'react-router';
import { FormErrors } from './partials';
import { AppActions } from '../actions/AppActions';
import {
  Input,
  ButtonInput
} from 'react-bootstrap';

export class ResetPasswordForm extends React.Component {

  constructor() {
    super();
    this.state = {
      newPassword: '',
      processing: false,
      passwordReset: false,
      errors: []
    };
  }

  handleInputChange = (e => this.setState(
      {newPassword: e.target.value})
  );

  validate = () => {
    var errors = [];
    var { newPassword } = this.state;
    const rules = [
      {
        failOn: newPassword.trim().length < 5,
        error: 'Password must be at least 5 characters'
      }
    ];

    rules.forEach((rule) => {

      if (rule.failOn) {
        errors.push(rule);
      }
    });

    if (errors.length) {
      return {
        errors: errors,
        valid: false
      };
    } else {
      return {
        errors: null,
        valid: true
      };
    }
  };


  handleSubmit = (e) => {
    let newPassword = this.state.newPassword;
    e.preventDefault();

    var valid = this.validate();
    if (valid.errors) {

      let article = valid.errors.length > 1 ? 'are' : 'is';
      let noun = valid.errors.length > 1 ? 'errors' : 'error';
      let count = valid.errors.length > 1 ? valid.errors.length : 'one';

      this.setState({
        error: {
          processing: false,
          message: `There ${article} ${count} ${noun},  please try again.`,
          data: valid.errors
        }
      });
      return;
    }
    this.setState({
      processing: true
    });
    ajax.post('/api/reset')
      .send({password: newPassword})
      .end((err, res) => {
        if (err || res.text !== 'ok') {
          AppActions.toast({
            level: 'error',
            title: 'Server Error',
            message: 'Password reset token is invalid or has expired.'
          });
          this.context.router.push('/reset');
        }
        AppActions.toast({
          level: 'success',
          title: 'Success',
          message: 'Your password has been changed.'
        });
        this.setState({
          passwordReset: true
        });
      });
  };

  render() {

    let {
      processing,
      passwordReset,
      error,
      newPassword } = this.state;


    if (passwordReset) {
      return (
        <div style={{padding: '2em'}}>
          <p>
            Password successfully reset.
          </p>

          <p><Link
            to="/login">Go Login</Link></p>
        </div>
      );
    } else {
      return (
        <form onSubmit={this.handleSubmit}>
          {error ? <FormErrors {...error} /> : ''}
          <fieldset>
            <legend>
              Reset Password
            </legend>
            <p>
              <span>Enter a new password:</span>
            </p>
            <Input
              required
              type="password"
              onChange={this.handleInputChange}
              value={newPassword}
              placeholder="New Password"/>
            <ButtonInput
              disabled={processing}
              bsStyle="primary"
              type="submit">
              Change Password
            </ButtonInput>
          </fieldset>
        </form>
      );
    }
  }
}

ResetPasswordForm.contextTypes = {
  router: React.PropTypes.object.isRequired
};



================================================
FILE: client/src/components/ResetRequestForm.js
================================================
import React from 'react';
import ajax from 'superagent';
import { Link } from 'react-router';

import {
  Input,
  ButtonInput
} from 'react-bootstrap';

export class ResetRequestForm extends React.Component {

  constructor() {
    super();
    this.state = {
      pending: false,
      email: '',
      emailSent: false,
    };
  }

  handleInputChange = (e => this.setState(
      {email: e.target.value})
  );

  handleSubmit = (e) => {
    let email = this.state.email;
    e.preventDefault();
    this.setState({
      pending: true
    });
    if (this.state.emailSent) {
      return;
    }
    ajax.post('/api/forgot')
        .send({email})
        .end((err, res) => {
          this.setState({
            emailSent: true
          });
          console.info(err, res);
        });

  };

  render() {

    let { emailSent, email, pending } = this.state;

    if (emailSent) {
      return (
        <div style={{padding: '2em'}}>
          <p>
            A link to reset your password has been sent to&nbsp;
            <strong>{email}</strong>.
            Make sure to check your spam folder in case you do not see it.
          </p>

          <p><Link
            ref="homeLink"
            to="/">Back to home</Link></p>
        </div>
      );
    } else {
      return (
        <form onSubmit={this.handleSubmit}>
          <fieldset>
            <legend>
              Reset Password
            </legend>
            <p>
              <span>Enter your email address below and</span>
              <span>&nbsp;we will send you a link to reset your password</span>
            </p>
            <Input
              required
              type="email"
              onChange={this.handleInputChange}
              value={email}
              placeholder="Email address"/>
            <ButtonInput
              disabled={pending}
              bsStyle="primary"
              type="submit">
              Send reset link
            </ButtonInput>
          </fieldset>
        </form>
      );
    }
  }

}




================================================
FILE: client/src/components/SignupForm.js
================================================
import React from 'react';
import validator from 'validator';
import { FormErrors } from './partials';

import {
  Button,
  Input,
  ButtonInput
} from 'react-bootstrap';

import { AppActions } from '../actions/AppActions';
import { AppStore } from '../stores/AppStore';

export class SignupForm extends React.Component {

  constructor() {
    super();
    this.state = {
      ...AppStore.getState(),
      username: '',
      password: '',
      email: ''
    };
    this.onChange = this.onChange.bind(this);
  }
  componentDidMount() {
    AppStore.listen(this.onChange);
  }
  componentWillUnmount() {
    AppStore.unlisten(this.onChange);
  }
  onChange(state) {
    this.setState(state);
  }
  clearState = () => {
    this.setState({
      username: '',
      password: '',
      email: ''
    });
  };

  handleUsernameChange = (e => this.onChange(
      {username: e.target.value})
  );
  handlePasswordChange = (e => this.onChange(
      {password: e.target.value})
  );
  handleEmailChange = (e => this.onChange(
      {email: e.target.value})
  );



  validate = () => {
    var errors = [];
    var { username,
          password,
          email
          } = this.state;
    const rules = [
      {
        failOn: !validator.isEmail(email),
        error: 'Please use a valid email address'
      },
      {
        failOn: username.trim().length < 4,
        error: 'Username must be at least 4 characters'
      },
      {
        failOn: password.trim().length < 5,
        error: 'Password must be at least 5 characters'
      }
    ];

    rules.forEach((rule) => {

      if (rule.failOn) {
        errors.push(rule);
      }
    });

    if (errors.length) {
      return {
        errors: errors,
        valid: false
      };
    } else {
      return {
        errors: null,
        valid: true
      };
    }
  };

  handleSubmit = (e) => {
    e.preventDefault();


    var valid = this.validate();
    if (valid.errors) {

      let article = valid.errors.length > 1 ? 'are' : 'is';
      let noun = valid.errors.length > 1 ? 'errors' : 'error';
      let count = valid.errors.length > 1 ? valid.errors.length : 'one';

      this.setState({
        error: {
          message: `There ${article} ${count} ${noun},  please try again.`,
          data: valid.errors
        }
      });
      return;
    }

    AppActions.signup({
      username: this.state.username,
      password: this.state.password,
      email: this.state.email
    });

  };

  render() {
    // handlers
    let {
          handleSubmit,
          handleUsernameChange,
          handlePasswordChange,
          handleEmailChange
          } = this;
    // state
    let {
          error,
          username,
          password,
          email
          } = this.state;

    return (
      <section>
        {error ? <FormErrors {...error} /> : ''}
        <form onSubmit={handleSubmit}>
          <h4>Create an Account</h4>
          <hr/>
          <Input disabled={this.state.signupPending}
                 type="text"
                 label="Username"
                 value={username}
                 onChange={handleUsernameChange}
                 placeholder="Enter a username" />
          <Input disabled={this.state.signupPending}
                 type="email"
                 label="Email Address"
                 value={email}
                 onChange={handleEmailChange}
                 placeholder="Enter email" />
          <Input disabled={this.state.signupPending}
                 type="password"
                 value={password}
                 onChange={handlePasswordChange}
                 label="Password" />
          {this.state.signupPending ?
            <Button disabled>Signing up...</Button> :
            <ButtonInput bsStyle="primary"
                         type="submit"
                         value="Signup" />
          }
        </form>
      </section>
    );
  }
}


================================================
FILE: client/src/components/index.js
================================================
export { LoginForm } from './LoginForm';
export { SignupForm } from './SignupForm';
export { ResetRequestForm } from './ResetRequestForm';
export { ResetPasswordForm } from './ResetPasswordForm';
export { AddNewArticleForm } from './AddNewArticleForm';


================================================
FILE: client/src/components/partials/Elements.js
================================================
import React from 'react';
import { Collapse, Button } from 'react-bootstrap';

const performRedirect = (path) => (
  window.location.href = path
);

const val = (prop) => (
  Object.keys(prop).join(' ')
);

const redirect = {
  github: () => performRedirect('/auth/github'),
  reddit: () => performRedirect('/auth/reddit'),
  twitter: () => performRedirect('/auth/twitter'),
  facebook: () => performRedirect('/auth/facebook'),
  google: () => performRedirect('/auth/google')
};


export const LeftIconButton = (props) => (
  <button
    type="button"
    {...props}>
    {props.children}
  </button>
);


export const LoginWith = (account) => (
  <div style={{maxWidth: '350px', margin: '8px auto'}}>
  <LeftIconButton
    block
    className={'btn btn-block social-btn social-btn-' + val(account)}
    onClick={redirect[val(account)]}>
    <LeftFa {...account} />
    &nbsp;Sign in with {val(account)}
  </LeftIconButton>
  </div>
);


export const LeftFa = (icon) => (
  <span
    style={{float: 'left'}}
    className={'fa fa-' + val(icon) + ' fix-left'}/>
);

export const Fa = (icon) => (
  <span className={'fa fa-' + val(icon)}/>
);


export const Logo = ({
  size = 'auto'
  }) => (
  <span style={{fontWeight: 'bold', fontSize: size, fontFamily: 'Hack'}}>
    <span style={{color: '#E26262'}}>
      React
    </span>
    <span style={{color: 'grey'}}>
      athon
    </span>
  </span>
);
export const Center = ({
  children
}) => (
  <section style={{textAlign: 'center'}}>
    {children}
  </section>
);

export const Icon = ({
  name
  }) => (
  <span className={'icon icon-' + name}/>
);

export const Alert = ({
  children,
  kind = 'info'
  }) => (
  <div className={'alert alert-' + kind}>
    {children}
  </div>
);

const selectAll = (e) => {
  let target = e.target;
  target.setSelectionRange(0, target.value.length);
};

export const PastaLink = ({
  label,
  value
}) => (
  <div className='form-group'>
    <label>{label}</label>
    <input
      className='form-control'
      readOnly
      type='text' value={value} onClick={selectAll} />
  </div>
);

const Title = ({
  children
}) => (
  <strong>
    {children}
  </strong>
);


export const Radio = ({
  name,
  value,
  children,
  onChange,
  set
}) => (
  <label className="radio-inline">
  <input
    onChange = {onChange}
    checked = {set === value}
    type = 'radio'
    name = {name}
    id = {name}
    value = {value} />
    {children}
  </label>
);

export const Expander = ({
  isExpanded = false,
  title,
  children,
  onToggle
}) => (
  <span>
    <Title>
      <Button kind="link btn-sm" onClick={onToggle}>
        {title}
        &nbsp;
        <Icon name={isExpanded ? 'caret-down' : 'caret-right'}/>
      </Button>
    </Title>
    <Collapse in={isExpanded}>
      <div>
        {children}
      </div>
    </Collapse>
  </span>
);


================================================
FILE: client/src/components/partials/FormErrors.js
================================================
import React from 'react';
import { Alert } from './Elements';

const ErrorItem = ({msg}) => (
  <div>{msg}</div>
);


export const FormErrors = ({
  message,
  data
  }) => (
  <Alert kind="danger">
    {message}
    {data.map((item, i) =>
      <ErrorItem key={i} msg={item.error}/>)}
  </Alert>
);


================================================
FILE: client/src/components/partials/index.js
================================================
export { FormErrors } from './FormErrors';
export { Elements } from './Elements';


================================================
FILE: client/src/containers/AddNewArticle.js
================================================
import React from 'react';
import { AddNewArticleForm } from '../components';
export const AddNewArticle = () => (
  <section>
    <div
      style={{
        maxWidth: '788px',
        padding: '8px',
        background: 'white',
        margin: '1em auto 2em auto',
        borderRadius: '2px',
        boxShadow: '0 3px 10px rgba(0, 0, 0, 0.16), ' +
         '0 3px 10px rgba(0, 0, 0, 0.23)'
        }}>
      <AddNewArticleForm />
    </div>
  </section>
);



================================================
FILE: client/src/containers/Article.js
================================================
import React from 'react';
import Relay from 'react-relay';
import moment from 'moment';


class ArticleComponent extends React.Component {

  render() {

    var {
      author,
      title,
      content,
      dateCreated } = this.props.article;

    console.log(this.props);

    return (
      <article>
        <header>
          <h2>{title}</h2>
          <em>by {author.username} - {moment(dateCreated).fromNow()}.</em>
        </header>
        <p>
          {content}
        </p>
      </article>
    );
  }
}


export const Article = Relay.createContainer(ArticleComponent, {
  fragments: {
    article: () => Relay.QL`
      fragment on Article {
        author {
          username
        }
        title
        content
        dateCreated
      }
    `
  }
});


================================================
FILE: client/src/containers/ArticleList.js
================================================
import React from 'react';
import Relay from 'react-relay';
import { Link } from 'react-router';
import moment from 'moment';


const ArticleListItem = ({
  author,
  dateCreated,
  title,
  content,
  url
}) => (
  <section>
    <header>
      {author.username} posted an article
      <Link to={url}>{moment(dateCreated).fromNow()}.</Link>
    </header>
    <h5>{title}</h5>
    <p>{content}</p>
  </section>
);

class ArticleListComponent extends React.Component {

  renderList = () => {
    return this.props.viewer.articles.edges.map(edge =>
      <ArticleListItem key={edge.node.id} {...edge.node} />
    );
  };
  loadNextPage = () => {
    // Increments the number of articles being rendered by 5.
    this.props.relay.setVariables({
      count: this.props.relay.variables.count + 5
    });
  };
  render() {
    var hasNextPage = this.props.viewer.articles.pageInfo.hasNextPage;
    return (
      <section>
        <div>{this.renderList()}</div>
        {hasNextPage ?
          <button onClick={this.loadNextPage}>Load More</button> : ''}
      </section>

    );
  }

}



export const ArticleList = Relay.createContainer(ArticleListComponent, {
  initialVariables: {
    count: 5
  },
  fragments: {
    viewer: () => Relay.QL`
      fragment on GraphAPI {
        articles(first: $count) {
          pageInfo {
            hasNextPage
          }
          edges {
            node {
              id
              url
              author {
                username
              }
              dateCreated
              content
              title
            }
          }
        }
      }
    `
  }
});


================================================
FILE: client/src/containers/Dashboard.js
================================================
import React from 'react';
import Relay from 'react-relay';
import moment from 'moment';

import {
  Col,
  Row,
  // Panel,
  Button,
  Input,
  Thumbnail,
  ButtonInput
} from 'react-bootstrap';


const UserCard = ({
  displayName,
  location,
  pictureUrl,
  username,
  website,
  dateCreated
}) => (
  <div>
    <h3>Hello, {displayName}!</h3>
    <Thumbnail style={{backgroundColor: 'white' }}src={pictureUrl}>
      <p>Joined {moment(dateCreated).fromNow()}</p>
      <p>{username ? username : ''}</p>
      <p>
      {location}
      </p>
      <p>
        <a href={website}>{website}</a>
      </p>
    </Thumbnail>
  </div>
);


class DashboardComponent extends React.Component {
  constructor(props) {
    console.log(props);

    super(props);
  }


  onLinkFacebook = () => (window.location.href = '/auth/facebook');

  onLinkGithub = () => (window.location.href = '/auth/github');

  onLinkReddit = () => (window.location.href = '/auth/reddit');

  onLinkGoogle = () => (window.location.href = '/auth/google');

  onLinkTwitter = () => (window.location.href = '/auth/twitter');

  onUnlinkFacebook = () => (window.location.href = '/auth/unlink/facebook');

  onUnlinkGithub = () => (window.location.href = '/auth/unlink/github');

  onUnlinkReddit = () => (window.location.href = '/auth/unlink/reddit');

  onUnlinkGoogle = () => (window.location.href = '/auth/unlink/google');

  onUnlinkTwitter = () => (window.location.href = '/auth/unlink/twitter');

  render() {

    // Store
    let {
      website,
      email,
      username,
      github,
      google,
      twitter,
      facebook,
      reddit
      } = this.props.viewer.user;

    return (
      <section>

        <Row>
          <Col xs={12} sm={6} md={5} lg={4}>

            <UserCard {...this.props.viewer.user} />

          </Col>

          <Col xs={12} sm={6} md={7} lg={8}>
            <form style={{marginTop: '54px'}}>
              <label>Username</label>
              <Input type="text" readOnly value={username}/>
              <label>Email</label>
              <Input type="email" readOnly value={email}/>
              <label>Website</label>
              <Input type="url" readOnly value={website}/>
              <fieldset>
                <legend>Providers</legend>
                <label>Facebook</label>
                <ButtonInput
                  onClick={facebook ?
                  this.onUnlinkFacebook :
                  this.onLinkFacebook}>
                  {facebook ? 'Unlink' : 'link'}
                </ButtonInput>
                <label>Reddit</label>
                <ButtonInput
                  onClick={reddit ?
                  this.onUnlinkReddit :
                  this.onLinkReddit}>
                  {reddit ? 'Unlink' : 'link'}
                </ButtonInput>
                <label>Github</label>
                <ButtonInput
                  onClick={github ?
                  this.onUnlinkGithub :
                  this.onLinkGithub}>
                  {github ? 'Unlink' : 'link'}
                </ButtonInput>
                <label>Google</label>
                <ButtonInput
                  onClick={google ?
                  this.onUnlinkGoogle :
                  this.onLinkGoogle}>
                  {google ? 'Unlink' : 'link'}
                </ButtonInput>
                <label>Twitter</label>
                <ButtonInput
                  onClick={twitter ?
                  this.onUnlinkTwitter :
                  this.onLinkTwitter}>
                  {twitter ? 'Unlink' : 'link'}
                </ButtonInput>
              </fieldset>
              <Button bsStyle="success">Edit Profile</Button>
            </form>
          </Col>
        </Row>

      </section>
    );
  }
}

export const Dashboard = Relay.createContainer(DashboardComponent, {
  initialVariables: {
    id: localStorage.getItem('user')
  },
  fragments: {
    viewer: () => Relay.QL`
      fragment on GraphAPI {
        user(id: $id) {
          displayName,
          dateCreated,
          username,
          email,
          location,
          website,
          pictureUrl,
          github
          google
          twitter
          facebook
          reddit
        }
      }
    `
  }
});


================================================
FILE: client/src/containers/Home.js
================================================
import React from 'react';
import { Logo, Center } from '../components/partials/Elements';
export const Home = () => (
  <section>
    <h1>
    <Center>
      <Logo size='40pt'/>
    </Center>
    </h1>
    <hr/>
  </section>
);



================================================
FILE: client/src/containers/Login.js
================================================
import React from 'react';
import { LoginForm } from '../components';
export const Login = () => (
  <section>
    <div
      style={{
        maxWidth: '440px',
        padding: '8px',
        background: 'white',
        margin: '1em auto 2em auto',
        borderRadius: '2px',
        boxShadow: '0 3px 10px rgba(0, 0, 0, 0.16), ' +
         '0 3px 10px rgba(0, 0, 0, 0.23)'
        }}>
      <LoginForm />
    </div>
  </section>
);



================================================
FILE: client/src/containers/NoMatch.js
================================================
import React from 'react';

export const NoMatch = () => (
  <article>
    <h3>Not Found</h3>
    <p>Sorry, the page requested was not found</p>
  </article>
);




================================================
FILE: client/src/containers/Page.js
================================================
import React from 'react';
import ajax from 'superagent';
import marked from 'marked';

export class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    ajax.get('/api/page/' + props.params.id, (err, res) => {
      if (err || !res) {
        this.setState({errorPage: true});
      } else {
        try {
          let data = marked(res.text.toString(), {sanitize: true});
          this.setState({ data });
        } catch (e) {
          this.setState({errorPage: true});
        }
      }
    });
  }

  render() {
    if (this.state.errorPage) {
      return (
        <article>
        <h3>Not Found</h3>
        <p>Sorry, the page requested was not found</p>
        </article>
      );
    } else {
      return (
        <article dangerouslySetInnerHTML = {{ __html: this.state.data }}>
        </article>
      );
    }
  }
}


================================================
FILE: client/src/containers/ResetPassword.js
================================================
import React from 'react';
import { ResetPasswordForm } from '../components';
export const ResetPassword = () => (
  <section>
    <div
      style={{
        maxWidth: '440px',
        padding: '8px',
        background: 'white',
        margin: '1em auto 2em auto',
        borderRadius: '2px',
        boxShadow: '0 3px 10px rgba(0, 0, 0, 0.16), ' +
         '0 3px 10px rgba(0, 0, 0, 0.23)'
        }}>
      <ResetPasswordForm />
    </div>
  </section>
);



================================================
FILE: client/src/containers/ResetRequest.js
================================================
import React from 'react';
import { ResetRequestForm } from '../components';
export const ResetRequest = () => (
  <section>
    <div
      style={{
        maxWidth: '440px',
        padding: '8px',
        background: 'white',
        margin: '1em auto 2em auto',
        borderRadius: '2px',
        boxShadow: '0 3px 10px rgba(0, 0, 0, 0.16), ' +
         '0 3px 10px rgba(0, 0, 0, 0.23)'
        }}>
      <ResetRequestForm />
    </div>
  </section>
);



================================================
FILE: client/src/containers/SignUp.js
================================================
import React from 'react';
import { SignupForm } from '../components';
export const SignUp = () => (
  <section>
    <div
      style={{
        maxWidth: '440px',
        padding: '8px',
        background: 'white',
        margin: '1em auto 2em auto',
        borderRadius: '2px',
        boxShadow: '0 3px 10px rgba(0, 0, 0, 0.16), ' +
         '0 3px 10px rgba(0, 0, 0, 0.23)'
        }}>
      <SignupForm />
    </div>
  </section>
);



================================================
FILE: client/src/containers/Tag.js
================================================
import React from 'react';

export const Tag = () => (
  <section>
    <h1>TODO: Update me</h1>
  </section>
);



================================================
FILE: client/src/containers/TagList.js
================================================
import React from 'react';

export const TagList = () => (
  <section>
    <h1>TODO: Update me</h1>
  </section>
);



================================================
FILE: client/src/containers/User.js
================================================
import React from 'react';
import Relay from 'react-relay';
import { Col, Row } from 'react-bootstrap';

const ProfilePicture = () => (
  <div>ProfilePicture Here</div>
);
const UserLocation = () => (
  <div>UserLocation Here</div>
);
const UserWebsite = () => (
  <div>UserWebsite Here</div>
);


class UserComponent extends React.Component {
  constructor(props) {
    console.log(props);

    super(props);
  }

  render() {
    return (
      <section>
        <Row>

          <Col xs={12} sm={6} md={5} lg={4}>
            <ProfilePicture/>
            <UserLocation/>
            <UserWebsite/>
          </Col>

          <Col xs={12} sm={6} md={7} lg={8}>
            <form>

            </form>
          </Col>

        </Row>
      </section>
    );
  }
}

export const User = Relay.createContainer(UserComponent, {
  fragments: {
    user: () => Relay.QL`
      fragment on User {
        username,
        displayName
      }
    `
  }
});


================================================
FILE: client/src/containers/index.js
================================================
export { Home } from './Home';
export { Article } from './Article';
export { ArticleList } from './ArticleList';
export { Page } from './Page';
export { TagList } from './TagList';
export { NoMatch } from './NoMatch';
export { Tag } from './Tag';
export { Login } from './Login';
export { SignUp } from './SignUp';
export { Dashboard } from './Dashboard';
export { User } from './User';
export { ResetRequest } from './ResetRequest';
export { ResetPassword } from './ResetPassword';
export { AddNewArticle } from './AddNewArticle';



================================================
FILE: client/src/main.js
================================================
/*
 *  React
 */
import React from 'react';
import { render } from 'react-dom';

/*
 *  React-Router
 */
import {
  browserHistory,
  IndexRoute,
  Route
} from 'react-router';

/*
 * Relay
 */
import Relay from 'react-relay';
import { RelayRouter } from 'react-router-relay';



/*
 * Layout
 */
import { Layout } from './Layout';


/*
 * Containers
 */

import {
  Article,
  ArticleList,
  Home,
  NoMatch,
  Page,
  Login,
  SignUp,
  Tag,
  TagList,
  Dashboard,
  User,
  ResetRequest,
  ResetPassword,
  AddNewArticle
} from './containers';

const viewerQuery = {
  viewer: () => Relay.QL`query { viewer }`
};

const articleQuery = {
  article: () => Relay.QL`
    query {
      article(id: $articleId)
    }
  `
};

class Master extends React.Component {

  render() {

    return (
      <RelayRouter history={browserHistory}>

        <Route
          path="/"
          component={Layout}>
          <IndexRoute component={Home} />
          <Route path="/" component={Home}/>
          <Route
            path="/users/:id"
            component={User}
            queries={{
          user: () => Relay.QL`query { user(id: $id) }`
        }} />
          <Route
            path="/dashboard"
            queries={{
          viewer: () => Relay.QL`query { viewer }`
        }}
            component={Dashboard}/>
          <Route path="/login" component={Login}/>
          <Route path="/signup" component={SignUp}/>
          <Route path="/page/:id" component={Page}/>
          <Route path="/add-article" component={AddNewArticle}/>
          <Route path="articles"
            queries={viewerQuery}
            component={ArticleList}/>
          <Route path="/articles/:articleId"
            queries={articleQuery}
            component={Article}/>
          <Route path="tags" component={TagList}/>
          <Route path="/tags/:id" component={Tag}/>
          <Route path="/reset" component={ResetRequest}/>
          <Route path="/reset/:token" component={ResetPassword}/>
          <Route path="*" component={NoMatch}/>
        </Route >
      </RelayRouter>
    );
  }
}
Master.contextTypes = {
  router: React.PropTypes.string
};

render(( <Master/> ), document.getElementById('main'));


================================================
FILE: client/src/queries/ViewerQueries.js
================================================
import Relay from 'react-relay';

export default {
  viewer: () => Relay.QL`query { viewer }`
};


================================================
FILE: client/src/queries/index.js
================================================
export { ViewerQueries } from './ViewerQueries';


================================================
FILE: client/src/stores/AppStore.js
================================================
import alt from '../alt';
import { AppActions } from '../actions/AppActions';


class AppStoreSpec {
  constructor() {
    this.bindActions(AppActions);
    var userEl = document.getElementById('user');
    this.user = userEl ? JSON.parse(userEl.innerHTML) : null;
    localStorage.setItem('user', this.user);
    this.showSignupModal = false;
    this.showLoginModal = false;
    this.signupPending = false;
    this.queue = [];
  }

  onShowSignupModal() {
    this.setState({showSignupModal: true});
  }

  onHideSignupModal() {
    this.setState({showSignupModal: false});
  }

  onShowLoginModal() {
    this.setState({showLoginModal: true});
  }

  onHideLoginModal() {
    this.setState({showLoginModal: false});
  }

  onSignupPending = () => {
    localStorage.removeItem('user');
    this.signupPending = true;
  };

  onSignupSuccess(user) {
    this.user = user.id.toString();
    localStorage.setItem('user', this.user);
    this.signupPending = false;
    this.showSignupModal = false;
    window.location.href = '/dashboard';
  }
  onSignupFail() {
    this.signupPending = false;
    localStorage.removeItem('user');
  }


  onLoginPending = () => {
    localStorage.removeItem('user');
    this.loginPending = true;
  };

  onLoginSuccess(user) {
    this.user = user.id.toString();
    localStorage.setItem('user', this.user);
    this.loginPending = false;
    this.showLoginModal = false;
  }
  onLoginFail() {
    this.loginPending = false;
    localStorage.removeItem('user');
  }

  onAddArticleSuccess() {
    this.addArticlePending = false;
  }
  onAddArticleFail() {
    this.addArticlePending = false;
  }



  onLogoutPending = () => (this.logoutPending = true);

  onLogoutSuccess() {
    this.user = null;
    localStorage.removeItem('user');
    this.logoutPending = false;
    window.location.href = '/';
  }
  onLogoutFail() {
    this.logoutPending = false;
  }

  onPushQueue(options) {
    this.queue.push(options);
  }

  onShiftQueue() {
    this.queue.shift();
  }

}

export const AppStore =
               alt.createStore(AppStoreSpec, 'AppStore');


================================================
FILE: client/src/style/base/_transitions.scss
================================================
$page-trans-time: 0.3s;
$page-trans-easing: ease-in-out;

.page-transition {
  &-enter, &-leave {
    transition: opacity $page-trans-time $page-trans-easing;
    position: absolute;
  }
  &-enter {
    opacity: 0;
    &-active {
      opacity: 1;
    }
  }
  &-leave {
    opacity: 1;
    &-active {
      opacity: 0;
    }
  }
}


================================================
FILE: client/src/style/base/_variables.scss
================================================

$twitterBlue: #00aced;
$facebookBlue: #335795;
$googleRed: #DD4B39;
$redditBlue: #99BEEB;
$githubBlack: #333;
$page-trans-time: 0.1s;
$page-trans-easing: ease-in-out;



================================================
FILE: client/src/style/main.scss
================================================
@import './vendor/bootstrap';

@import './base/variables';
@import './base/transitions';
@import './objects/buttons';


================================================
FILE: client/src/style/objects/_buttons.scss
================================================
.btn .fa.fix-left {
  float: left;
  height: 1em;
  font-size: 26px;
  border-right: thin ridge rgba(255, 255, 255, 0.3);
  width: 45px;
  margin-left: -15px;
  margin-right: -45px;
  &:after {
    border-right: thin solid white;
  }
}


.social-btn {
  font-size: 18px;
  color: white;
  &:hover, &:focus, &:active {
    color: white;
  }
  &-github {
    background-color: $githubBlack;
    &:hover, &:focus, &:active {
      background-color: lighten($githubBlack, 10%);
    }
  }
  &-google {
    background-color: $googleRed;
    &:hover, &:focus, &:active {
      background-color: lighten($googleRed, 10%);
    }
  }
  &-reddit {
    background-color: $redditBlue;
    color: black;
    &:hover, &:focus, &:active {
      background-color: lighten($redditBlue, 10%);
      color: black;
    }
  }
  &-twitter {
    background-color: $twitterBlue;
    &:hover, &:focus, &:active {
      background-color: lighten($twitterBlue, 10%);
    }
  }
  &-facebook {
    background-color: $facebookBlue;
    &:hover, &:focus, &:active {
      background-color: lighten($facebookBlue, 10%);
    }
  }
}



================================================
FILE: client/src/style/vendor/_bootstrap.scss
================================================
/*!
 * Bootstrap v3.3.6 (http://getbootstrap.com)
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

// Core variables and mixins
@import "bootstrap/variables";
@import "bootstrap/mixins";

// Reset and dependencies
@import "bootstrap/normalize";
@import "bootstrap/print";
@import "bootstrap/glyphicons";

// Core CSS
@import "bootstrap/scaffolding";
@import "bootstrap/type";
@import "bootstrap/code";
@import "bootstrap/grid";
@import "bootstrap/tables";
@import "bootstrap/forms";
@import "bootstrap/buttons";

// Components
@import "bootstrap/component-animations";
@import "bootstrap/dropdowns";
@import "bootstrap/button-groups";
@import "bootstrap/input-groups";
@import "bootstrap/navs";
@import "bootstrap/navbar";
@import "bootstrap/breadcrumbs";
@import "bootstrap/pagination";
@import "bootstrap/pager";
@import "bootstrap/labels";
@import "bootstrap/badges";
@import "bootstrap/jumbotron";
@import "bootstrap/thumbnails";
@import "bootstrap/alerts";
@import "bootstrap/progress-bars";
@import "bootstrap/media";
@import "bootstrap/list-group";
@import "bootstrap/panels";
@import "bootstrap/responsive-embed";
@import "bootstrap/wells";
@import "bootstrap/close";

// Components w/ JavaScript
@import "bootstrap/modals";
@import "bootstrap/tooltip";
@import "bootstrap/popovers";
@import "bootstrap/carousel";

// Utility classes
@import "bootstrap/utilities";
@import "bootstrap/responsive-utilities";


================================================
FILE: client/src/style/vendor/bootstrap/_alerts.scss
================================================
//
// Alerts
// --------------------------------------------------


// Base styles
// -------------------------

.alert {
  padding: $alert-padding;
  margin-bottom: $line-height-computed;
  border: 1px solid transparent;
  border-radius: $alert-border-radius;

  // Headings for larger alerts
  h4 {
    margin-top: 0;
    // Specified for the h4 to prevent conflicts of changing $headings-color
    color: inherit;
  }

  // Provide class for links that match alerts
  .alert-link {
    font-weight: $alert-link-font-weight;
  }

  // Improve alignment and spacing of inner content
  > p,
  > ul {
    margin-bottom: 0;
  }

  > p + p {
    margin-top: 5px;
  }
}

// Dismissible alerts
//
// Expand the right padding and account for the close button's positioning.

.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.
.alert-dismissible {
  padding-right: ($alert-padding + 20);

  // Adjust close link position
  .close {
    position: relative;
    top: -2px;
    right: -21px;
    color: inherit;
  }
}

// Alternate styles
//
// Generate contextual modifier classes for colorizing the alert.

.alert-success {
  @include alert-variant($alert-success-bg, $alert-success-border, $alert-success-text);
}

.alert-info {
  @include alert-variant($alert-info-bg, $alert-info-border, $alert-info-text);
}

.alert-warning {
  @include alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text);
}

.alert-danger {
  @include alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text);
}


================================================
FILE: client/src/style/vendor/bootstrap/_badges.scss
================================================
//
// Badges
// --------------------------------------------------


// Base class
.badge {
  display: inline-block;
  min-width: 10px;
  padding: 3px 7px;
  font-size: $font-size-small;
  font-weight: $badge-font-weight;
  color: $badge-color;
  line-height: $badge-line-height;
  vertical-align: middle;
  white-space: nowrap;
  text-align: center;
  background-color: $badge-bg;
  border-radius: $badge-border-radius;

  // Empty badges collapse automatically (not available in IE8)
  &:empty {
    display: none;
  }

  // Quick fix for badges in buttons
  .btn & {
    position: relative;
    top: -1px;
  }

  .btn-xs &,
  .btn-group-xs > .btn & {
    top: 0;
    padding: 1px 5px;
  }

  // [converter] extracted a& to a.badge

  // Account for badges in navs
  .list-group-item.active > &,
  .nav-pills > .active > a > & {
    color: $badge-active-color;
    background-color: $badge-active-bg;
  }

  .list-group-item > & {
    float: right;
  }

  .list-group-item > & + & {
    margin-right: 5px;
  }

  .nav-pills > li > a > & {
    margin-left: 3px;
  }
}

// Hover state, but only for links
a.badge {
  &:hover,
  &:focus {
    color: $badge-link-hover-color;
    text-decoration: none;
    cursor: pointer;
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_breadcrumbs.scss
================================================
//
// Breadcrumbs
// --------------------------------------------------


.breadcrumb {
  padding: $breadcrumb-padding-vertical $breadcrumb-padding-horizontal;
  margin-bottom: $line-height-computed;
  list-style: none;
  background-color: $breadcrumb-bg;
  border-radius: $border-radius-base;

  > li {
    display: inline-block;

    + li:before {
      // [converter] Workaround for https://github.com/sass/libsass/issues/1115
      $nbsp: "\00a0";
      content: "#{$breadcrumb-separator}#{$nbsp}"; // Unicode space added since inline-block means non-collapsing white-space
      padding: 0 5px;
      color: $breadcrumb-color;
    }
  }

  > .active {
    color: $breadcrumb-active-color;
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_button-groups.scss
================================================
//
// Button groups
// --------------------------------------------------

// Make the div behave like a button
.btn-group,
.btn-group-vertical {
  position: relative;
  display: inline-block;
  vertical-align: middle; // match .btn alignment given font-size hack above
  > .btn {
    position: relative;
    float: left;
    // Bring the "active" button to the front
    &:hover,
    &:focus,
    &:active,
    &.active {
      z-index: 2;
    }
  }
}

// Prevent double borders when buttons are next to each other
.btn-group {
  .btn + .btn,
  .btn + .btn-group,
  .btn-group + .btn,
  .btn-group + .btn-group {
    margin-left: -1px;
  }
}

// Optional: Group multiple button groups together for a toolbar
.btn-toolbar {
  margin-left: -5px; // Offset the first child's margin
  @include clearfix;

  .btn,
  .btn-group,
  .input-group {
    float: left;
  }
  > .btn,
  > .btn-group,
  > .input-group {
    margin-left: 5px;
  }
}

.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
  border-radius: 0;
}

// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match
.btn-group > .btn:first-child {
  margin-left: 0;
  &:not(:last-child):not(.dropdown-toggle) {
    @include border-right-radius(0);
  }
}
// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it
.btn-group > .btn:last-child:not(:first-child),
.btn-group > .dropdown-toggle:not(:first-child) {
  @include border-left-radius(0);
}

// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)
.btn-group > .btn-group {
  float: left;
}
.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
  border-radius: 0;
}
.btn-group > .btn-group:first-child:not(:last-child) {
  > .btn:last-child,
  > .dropdown-toggle {
    @include border-right-radius(0);
  }
}
.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
  @include border-left-radius(0);
}

// On active and open, don't show outline
.btn-group .dropdown-toggle:active,
.btn-group.open .dropdown-toggle {
  outline: 0;
}


// Sizing
//
// Remix the default button sizing classes into new ones for easier manipulation.

.btn-group-xs > .btn { @extend .btn-xs; }
.btn-group-sm > .btn { @extend .btn-sm; }
.btn-group-lg > .btn { @extend .btn-lg; }


// Split button dropdowns
// ----------------------

// Give the line between buttons some depth
.btn-group > .btn + .dropdown-toggle {
  padding-left: 8px;
  padding-right: 8px;
}
.btn-group > .btn-lg + .dropdown-toggle {
  padding-left: 12px;
  padding-right: 12px;
}

// The clickable button for toggling the menu
// Remove the gradient and set the same inset shadow as the :active state
.btn-group.open .dropdown-toggle {
  @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125));

  // Show no shadow for `.btn-link` since it has no other button styles.
  &.btn-link {
    @include box-shadow(none);
  }
}


// Reposition the caret
.btn .caret {
  margin-left: 0;
}
// Carets in other button sizes
.btn-lg .caret {
  border-width: $caret-width-large $caret-width-large 0;
  border-bottom-width: 0;
}
// Upside down carets for .dropup
.dropup .btn-lg .caret {
  border-width: 0 $caret-width-large $caret-width-large;
}


// Vertical button groups
// ----------------------

.btn-group-vertical {
  > .btn,
  > .btn-group,
  > .btn-group > .btn {
    display: block;
    float: none;
    width: 100%;
    max-width: 100%;
  }

  // Clear floats so dropdown menus can be properly placed
  > .btn-group {
    @include clearfix;
    > .btn {
      float: none;
    }
  }

  > .btn + .btn,
  > .btn + .btn-group,
  > .btn-group + .btn,
  > .btn-group + .btn-group {
    margin-top: -1px;
    margin-left: 0;
  }
}

.btn-group-vertical > .btn {
  &:not(:first-child):not(:last-child) {
    border-radius: 0;
  }
  &:first-child:not(:last-child) {
    @include border-top-radius($btn-border-radius-base);
    @include border-bottom-radius(0);
  }
  &:last-child:not(:first-child) {
    @include border-top-radius(0);
    @include border-bottom-radius($btn-border-radius-base);
  }
}
.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
  border-radius: 0;
}
.btn-group-vertical > .btn-group:first-child:not(:last-child) {
  > .btn:last-child,
  > .dropdown-toggle {
    @include border-bottom-radius(0);
  }
}
.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
  @include border-top-radius(0);
}


// Justified button groups
// ----------------------

.btn-group-justified {
  display: table;
  width: 100%;
  table-layout: fixed;
  border-collapse: separate;
  > .btn,
  > .btn-group {
    float: none;
    display: table-cell;
    width: 1%;
  }
  > .btn-group .btn {
    width: 100%;
  }

  > .btn-group .dropdown-menu {
    left: auto;
  }
}


// Checkbox and radio options
//
// In order to support the browser's form validation feedback, powered by the
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
// `display: none;` or `visibility: hidden;` as that also hides the popover.
// Simply visually hiding the inputs via `opacity` would leave them clickable in
// certain cases which is prevented by using `clip` and `pointer-events`.
// This way, we ensure a DOM element is visible to position the popover from.
//
// See https://github.com/twbs/bootstrap/pull/12794 and
// https://github.com/twbs/bootstrap/pull/14559 for more information.

[data-toggle="buttons"] {
  > .btn,
  > .btn-group > .btn {
    input[type="radio"],
    input[type="checkbox"] {
      position: absolute;
      clip: rect(0,0,0,0);
      pointer-events: none;
    }
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_buttons.scss
================================================
//
// Buttons
// --------------------------------------------------


// Base styles
// --------------------------------------------------

.btn {
  display: inline-block;
  margin-bottom: 0; // For input.btn
  font-weight: $btn-font-weight;
  text-align: center;
  vertical-align: middle;
  touch-action: manipulation;
  cursor: pointer;
  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
  border: 1px solid transparent;
  white-space: nowrap;
  @include button-size($padding-base-vertical, $padding-base-horizontal, $font-size-base, $line-height-base, $btn-border-radius-base);
  @include user-select(none);

  &,
  &:active,
  &.active {
    &:focus,
    &.focus {
      @include tab-focus;
    }
  }

  &:hover,
  &:focus,
  &.focus {
    color: $btn-default-color;
    text-decoration: none;
  }

  &:active,
  &.active {
    outline: 0;
    background-image: none;
    @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
  }

  &.disabled,
  &[disabled],
  fieldset[disabled] & {
    cursor: $cursor-disabled;
    @include opacity(.65);
    @include box-shadow(none);
  }

  // [converter] extracted a& to a.btn
}

a.btn {
  &.disabled,
  fieldset[disabled] & {
    pointer-events: none; // Future-proof disabling of clicks on `<a>` elements
  }
}


// Alternate buttons
// --------------------------------------------------

.btn-default {
  @include button-variant($btn-default-color, $btn-default-bg, $btn-default-border);
}
.btn-primary {
  @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border);
}
// Success appears as green
.btn-success {
  @include button-variant($btn-success-color, $btn-success-bg, $btn-success-border);
}
// Info appears as blue-green
.btn-info {
  @include button-variant($btn-info-color, $btn-info-bg, $btn-info-border);
}
// Warning appears as orange
.btn-warning {
  @include button-variant($btn-warning-color, $btn-warning-bg, $btn-warning-border);
}
// Danger and error appear as red
.btn-danger {
  @include button-variant($btn-danger-color, $btn-danger-bg, $btn-danger-border);
}


// Link buttons
// -------------------------

// Make a button look and behave like a link
.btn-link {
  color: $link-color;
  font-weight: normal;
  border-radius: 0;

  &,
  &:active,
  &.active,
  &[disabled],
  fieldset[disabled] & {
    background-color: transparent;
    @include box-shadow(none);
  }
  &,
  &:hover,
  &:focus,
  &:active {
    border-color: transparent;
  }
  &:hover,
  &:focus {
    color: $link-hover-color;
    text-decoration: $link-hover-decoration;
    background-color: transparent;
  }
  &[disabled],
  fieldset[disabled] & {
    &:hover,
    &:focus {
      color: $btn-link-disabled-color;
      text-decoration: none;
    }
  }
}


// Button Sizes
// --------------------------------------------------

.btn-lg {
  // line-height: ensure even-numbered height of button next to large input
  @include button-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $btn-border-radius-large);
}
.btn-sm {
  // line-height: ensure proper height of button next to small input
  @include button-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $btn-border-radius-small);
}
.btn-xs {
  @include button-size($padding-xs-vertical, $padding-xs-horizontal, $font-size-small, $line-height-small, $btn-border-radius-small);
}


// Block button
// --------------------------------------------------

.btn-block {
  display: block;
  width: 100%;
}

// Vertically space out multiple block buttons
.btn-block + .btn-block {
  margin-top: 5px;
}

// Specificity overrides
input[type="submit"],
input[type="reset"],
input[type="button"] {
  &.btn-block {
    width: 100%;
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_carousel.scss
================================================
//
// Carousel
// --------------------------------------------------


// Wrapper for the slide container and indicators
.carousel {
  position: relative;
}

.carousel-inner {
  position: relative;
  overflow: hidden;
  width: 100%;

  > .item {
    display: none;
    position: relative;
    @include transition(.6s ease-in-out left);

    // Account for jankitude on images
    > img,
    > a > img {
      @include img-responsive;
      line-height: 1;
    }

    // WebKit CSS3 transforms for supported devices
    @media all and (transform-3d), (-webkit-transform-3d) {
      @include transition-transform(0.6s ease-in-out);
      @include backface-visibility(hidden);
      @include perspective(1000px);

      &.next,
      &.active.right {
        @include translate3d(100%, 0, 0);
        left: 0;
      }
      &.prev,
      &.active.left {
        @include translate3d(-100%, 0, 0);
        left: 0;
      }
      &.next.left,
      &.prev.right,
      &.active {
        @include translate3d(0, 0, 0);
        left: 0;
      }
    }
  }

  > .active,
  > .next,
  > .prev {
    display: block;
  }

  > .active {
    left: 0;
  }

  > .next,
  > .prev {
    position: absolute;
    top: 0;
    width: 100%;
  }

  > .next {
    left: 100%;
  }
  > .prev {
    left: -100%;
  }
  > .next.left,
  > .prev.right {
    left: 0;
  }

  > .active.left {
    left: -100%;
  }
  > .active.right {
    left: 100%;
  }

}

// Left/right controls for nav
// ---------------------------

.carousel-control {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: $carousel-control-width;
  @include opacity($carousel-control-opacity);
  font-size: $carousel-control-font-size;
  color: $carousel-control-color;
  text-align: center;
  text-shadow: $carousel-text-shadow;
  background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug
  // We can't have this transition here because WebKit cancels the carousel
  // animation if you trip this while in the middle of another animation.

  // Set gradients for backgrounds
  &.left {
    @include gradient-horizontal($start-color: rgba(0,0,0,.5), $end-color: rgba(0,0,0,.0001));
  }
  &.right {
    left: auto;
    right: 0;
    @include gradient-horizontal($start-color: rgba(0,0,0,.0001), $end-color: rgba(0,0,0,.5));
  }

  // Hover/focus state
  &:hover,
  &:focus {
    outline: 0;
    color: $carousel-control-color;
    text-decoration: none;
    @include opacity(.9);
  }

  // Toggles
  .icon-prev,
  .icon-next,
  .glyphicon-chevron-left,
  .glyphicon-chevron-right {
    position: absolute;
    top: 50%;
    margin-top: -10px;
    z-index: 5;
    display: inline-block;
  }
  .icon-prev,
  .glyphicon-chevron-left {
    left: 50%;
    margin-left: -10px;
  }
  .icon-next,
  .glyphicon-chevron-right {
    right: 50%;
    margin-right: -10px;
  }
  .icon-prev,
  .icon-next {
    width:  20px;
    height: 20px;
    line-height: 1;
    font-family: serif;
  }


  .icon-prev {
    &:before {
      content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)
    }
  }
  .icon-next {
    &:before {
      content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)
    }
  }
}

// Optional indicator pips
//
// Add an unordered list with the following class and add a list item for each
// slide your carousel holds.

.carousel-indicators {
  position: absolute;
  bottom: 10px;
  left: 50%;
  z-index: 15;
  width: 60%;
  margin-left: -30%;
  padding-left: 0;
  list-style: none;
  text-align: center;

  li {
    display: inline-block;
    width:  10px;
    height: 10px;
    margin: 1px;
    text-indent: -999px;
    border: 1px solid $carousel-indicator-border-color;
    border-radius: 10px;
    cursor: pointer;

    // IE8-9 hack for event handling
    //
    // Internet Explorer 8-9 does not support clicks on elements without a set
    // `background-color`. We cannot use `filter` since that's not viewed as a
    // background color by the browser. Thus, a hack is needed.
    // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer
    //
    // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we
    // set alpha transparency for the best results possible.
    background-color: #000 \9; // IE8
    background-color: rgba(0,0,0,0); // IE9
  }
  .active {
    margin: 0;
    width:  12px;
    height: 12px;
    background-color: $carousel-indicator-active-bg;
  }
}

// Optional captions
// -----------------------------
// Hidden by default for smaller viewports
.carousel-caption {
  position: absolute;
  left: 15%;
  right: 15%;
  bottom: 20px;
  z-index: 10;
  padding-top: 20px;
  padding-bottom: 20px;
  color: $carousel-caption-color;
  text-align: center;
  text-shadow: $carousel-text-shadow;
  & .btn {
    text-shadow: none; // No shadow for button elements in carousel-caption
  }
}


// Scale up controls for tablets and up
@media screen and (min-width: $screen-sm-min) {

  // Scale up the controls a smidge
  .carousel-control {
    .glyphicon-chevron-left,
    .glyphicon-chevron-right,
    .icon-prev,
    .icon-next {
      width: ($carousel-control-font-size * 1.5);
      height: ($carousel-control-font-size * 1.5);
      margin-top: ($carousel-control-font-size / -2);
      font-size: ($carousel-control-font-size * 1.5);
    }
    .glyphicon-chevron-left,
    .icon-prev {
      margin-left: ($carousel-control-font-size / -2);
    }
    .glyphicon-chevron-right,
    .icon-next {
      margin-right: ($carousel-control-font-size / -2);
    }
  }

  // Show and left align the captions
  .carousel-caption {
    left: 20%;
    right: 20%;
    padding-bottom: 30px;
  }

  // Move up the indicators
  .carousel-indicators {
    bottom: 20px;
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_close.scss
================================================
//
// Close icons
// --------------------------------------------------


.close {
  float: right;
  font-size: ($font-size-base * 1.5);
  font-weight: $close-font-weight;
  line-height: 1;
  color: $close-color;
  text-shadow: $close-text-shadow;
  @include opacity(.2);

  &:hover,
  &:focus {
    color: $close-color;
    text-decoration: none;
    cursor: pointer;
    @include opacity(.5);
  }

  // [converter] extracted button& to button.close
}

// Additional properties for button version
// iOS requires the button element instead of an anchor tag.
// If you want the anchor version, it requires `href="#"`.
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
button.close {
  padding: 0;
  cursor: pointer;
  background: transparent;
  border: 0;
  -webkit-appearance: none;
}


================================================
FILE: client/src/style/vendor/bootstrap/_code.scss
================================================
//
// Code (inline and block)
// --------------------------------------------------


// Inline and block code styles
code,
kbd,
pre,
samp {
  font-family: $font-family-monospace;
}

// Inline code
code {
  padding: 2px 4px;
  font-size: 90%;
  color: $code-color;
  background-color: $code-bg;
  border-radius: $border-radius-base;
}

// User input typically entered via keyboard
kbd {
  padding: 2px 4px;
  font-size: 90%;
  color: $kbd-color;
  background-color: $kbd-bg;
  border-radius: $border-radius-small;
  box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);

  kbd {
    padding: 0;
    font-size: 100%;
    font-weight: bold;
    box-shadow: none;
  }
}

// Blocks of code
pre {
  display: block;
  padding: (($line-height-computed - 1) / 2);
  margin: 0 0 ($line-height-computed / 2);
  font-size: ($font-size-base - 1); // 14px to 13px
  line-height: $line-height-base;
  word-break: break-all;
  word-wrap: break-word;
  color: $pre-color;
  background-color: $pre-bg;
  border: 1px solid $pre-border-color;
  border-radius: $border-radius-base;

  // Account for some code outputs that place code tags in pre tags
  code {
    padding: 0;
    font-size: inherit;
    color: inherit;
    white-space: pre-wrap;
    background-color: transparent;
    border-radius: 0;
  }
}

// Enable scrollable blocks of code
.pre-scrollable {
  max-height: $pre-scrollable-max-height;
  overflow-y: scroll;
}


================================================
FILE: client/src/style/vendor/bootstrap/_component-animations.scss
================================================
//
// Component animations
// --------------------------------------------------

// Heads up!
//
// We don't use the `.opacity()` mixin here since it causes a bug with text
// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.

.fade {
  opacity: 0;
  @include transition(opacity .15s linear);
  &.in {
    opacity: 1;
  }
}

.collapse {
  display: none;

  &.in      { display: block; }
  // [converter] extracted tr&.in to tr.collapse.in
  // [converter] extracted tbody&.in to tbody.collapse.in
}

tr.collapse.in    { display: table-row; }

tbody.collapse.in { display: table-row-group; }

.collapsing {
  position: relative;
  height: 0;
  overflow: hidden;
  @include transition-property(height, visibility);
  @include transition-duration(.35s);
  @include transition-timing-function(ease);
}


================================================
FILE: client/src/style/vendor/bootstrap/_dropdowns.scss
================================================
//
// Dropdown menus
// --------------------------------------------------


// Dropdown arrow/caret
.caret {
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 2px;
  vertical-align: middle;
  border-top:   $caret-width-base dashed;
  border-top:   $caret-width-base solid \9; // IE8
  border-right: $caret-width-base solid transparent;
  border-left:  $caret-width-base solid transparent;
}

// The dropdown wrapper (div)
.dropup,
.dropdown {
  position: relative;
}

// Prevent the focus on the dropdown toggle when closing dropdowns
.dropdown-toggle:focus {
  outline: 0;
}

// The dropdown menu (ul)
.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: $zindex-dropdown;
  display: none; // none by default, but block on "open" of the menu
  float: left;
  min-width: 160px;
  padding: 5px 0;
  margin: 2px 0 0; // override default ul
  list-style: none;
  font-size: $font-size-base;
  text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
  background-color: $dropdown-bg;
  border: 1px solid $dropdown-fallback-border; // IE8 fallback
  border: 1px solid $dropdown-border;
  border-radius: $border-radius-base;
  @include box-shadow(0 6px 12px rgba(0,0,0,.175));
  background-clip: padding-box;

  // Aligns the dropdown menu to right
  //
  // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`
  &.pull-right {
    right: 0;
    left: auto;
  }

  // Dividers (basically an hr) within the dropdown
  .divider {
    @include nav-divider($dropdown-divider-bg);
  }

  // Links within the dropdown menu
  > li > a {
    display: block;
    padding: 3px 20px;
    clear: both;
    font-weight: normal;
    line-height: $line-height-base;
    color: $dropdown-link-color;
    white-space: nowrap; // prevent links from randomly breaking onto new lines
  }
}

// Hover/Focus state
.dropdown-menu > li > a {
  &:hover,
  &:focus {
    text-decoration: none;
    color: $dropdown-link-hover-color;
    background-color: $dropdown-link-hover-bg;
  }
}

// Active state
.dropdown-menu > .active > a {
  &,
  &:hover,
  &:focus {
    color: $dropdown-link-active-color;
    text-decoration: none;
    outline: 0;
    background-color: $dropdown-link-active-bg;
  }
}

// Disabled state
//
// Gray out text and ensure the hover/focus state remains gray

.dropdown-menu > .disabled > a {
  &,
  &:hover,
  &:focus {
    color: $dropdown-link-disabled-color;
  }

  // Nuke hover/focus effects
  &:hover,
  &:focus {
    text-decoration: none;
    background-color: transparent;
    background-image: none; // Remove CSS gradient
    @include reset-filter;
    cursor: $cursor-disabled;
  }
}

// Open state for the dropdown
.open {
  // Show the menu
  > .dropdown-menu {
    display: block;
  }

  // Remove the outline when :focus is triggered
  > a {
    outline: 0;
  }
}

// Menu positioning
//
// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown
// menu with the parent.
.dropdown-menu-right {
  left: auto; // Reset the default from `.dropdown-menu`
  right: 0;
}
// With v3, we enabled auto-flipping if you have a dropdown within a right
// aligned nav component. To enable the undoing of that, we provide an override
// to restore the default dropdown menu alignment.
//
// This is only for left-aligning a dropdown menu within a `.navbar-right` or
// `.pull-right` nav component.
.dropdown-menu-left {
  left: 0;
  right: auto;
}

// Dropdown section headers
.dropdown-header {
  display: block;
  padding: 3px 20px;
  font-size: $font-size-small;
  line-height: $line-height-base;
  color: $dropdown-header-color;
  white-space: nowrap; // as with > li > a
}

// Backdrop to catch body clicks on mobile, etc.
.dropdown-backdrop {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  z-index: ($zindex-dropdown - 10);
}

// Right aligned dropdowns
.pull-right > .dropdown-menu {
  right: 0;
  left: auto;
}

// Allow for dropdowns to go bottom up (aka, dropup-menu)
//
// Just add .dropup after the standard .dropdown class and you're set, bro.
// TODO: abstract this so that the navbar fixed styles are not placed here?

.dropup,
.navbar-fixed-bottom .dropdown {
  // Reverse the caret
  .caret {
    border-top: 0;
    border-bottom: $caret-width-base dashed;
    border-bottom: $caret-width-base solid \9; // IE8
    content: "";
  }
  // Different positioning for bottom up menu
  .dropdown-menu {
    top: auto;
    bottom: 100%;
    margin-bottom: 2px;
  }
}


// Component alignment
//
// Reiterate per navbar.less and the modified component alignment there.

@media (min-width: $grid-float-breakpoint) {
  .navbar-right {
    .dropdown-menu {
      right: 0; left: auto;
    }
    // Necessary for overrides of the default right aligned menu.
    // Will remove come v4 in all likelihood.
    .dropdown-menu-left {
      left: 0; right: auto;
    }
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_forms.scss
================================================
//
// Forms
// --------------------------------------------------


// Normalize non-controls
//
// Restyle and baseline non-control form elements.

fieldset {
  padding: 0;
  margin: 0;
  border: 0;
  // Chrome and Firefox set a `min-width: min-content;` on fieldsets,
  // so we reset that to ensure it behaves more like a standard block element.
  // See https://github.com/twbs/bootstrap/issues/12359.
  min-width: 0;
}

legend {
  display: block;
  width: 100%;
  padding: 0;
  margin-bottom: $line-height-computed;
  font-size: ($font-size-base * 1.5);
  line-height: inherit;
  color: $legend-color;
  border: 0;
  border-bottom: 1px solid $legend-border-color;
}

label {
  display: inline-block;
  max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)
  margin-bottom: 5px;
  font-weight: bold;
}


// Normalize form controls
//
// While most of our form styles require extra classes, some basic normalization
// is required to ensure optimum display with or without those classes to better
// address browser inconsistencies.

// Override content-box in Normalize (* isn't specific enough)
input[type="search"] {
  @include box-sizing(border-box);
}

// Position radios and checkboxes better
input[type="radio"],
input[type="checkbox"] {
  margin: 4px 0 0;
  margin-top: 1px \9; // IE8-9
  line-height: normal;
}

input[type="file"] {
  display: block;
}

// Make range inputs behave like textual form controls
input[type="range"] {
  display: block;
  width: 100%;
}

// Make multiple select elements height not fixed
select[multiple],
select[size] {
  height: auto;
}

// Focus for file, radio, and checkbox
input[type="file"]:focus,
input[type="radio"]:focus,
input[type="checkbox"]:focus {
  @include tab-focus;
}

// Adjust output element
output {
  display: block;
  padding-top: ($padding-base-vertical + 1);
  font-size: $font-size-base;
  line-height: $line-height-base;
  color: $input-color;
}


// Common form controls
//
// Shared size and type resets for form controls. Apply `.form-control` to any
// of the following form controls:
//
// select
// textarea
// input[type="text"]
// input[type="password"]
// input[type="datetime"]
// input[type="datetime-local"]
// input[type="date"]
// input[type="month"]
// input[type="time"]
// input[type="week"]
// input[type="number"]
// input[type="email"]
// input[type="url"]
// input[type="search"]
// input[type="tel"]
// input[type="color"]

.form-control {
  display: block;
  width: 100%;
  height: $input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)
  padding: $padding-base-vertical $padding-base-horizontal;
  font-size: $font-size-base;
  line-height: $line-height-base;
  color: $input-color;
  background-color: $input-bg;
  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
  border: 1px solid $input-border;
  border-radius: $input-border-radius; // Note: This has no effect on <select>s in some browsers, due to the limited stylability of <select>s in CSS.
  @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
  @include transition(border-color ease-in-out .15s, box-shadow ease-in-out .15s);

  // Customize the `:focus` state to imitate native WebKit styles.
  @include form-control-focus;

  // Placeholder
  @include placeholder;

  // Unstyle the caret on `<select>`s in IE10+.
  &::-ms-expand {
    border: 0;
    background-color: transparent;
  }

  // Disabled and read-only inputs
  //
  // HTML5 says that controls under a fieldset > legend:first-child won't be
  // disabled if the fieldset is disabled. Due to implementation difficulty, we
  // don't honor that edge case; we style them as disabled anyway.
  &[disabled],
  &[readonly],
  fieldset[disabled] & {
    background-color: $input-bg-disabled;
    opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655
  }

  &[disabled],
  fieldset[disabled] & {
    cursor: $cursor-disabled;
  }

  // [converter] extracted textarea& to textarea.form-control
}

// Reset height for `textarea`s
textarea.form-control {
  height: auto;
}


// Search inputs in iOS
//
// This overrides the extra rounded corners on search inputs in iOS so that our
// `.form-control` class can properly style them. Note that this cannot simply
// be added to `.form-control` as it's not specific enough. For details, see
// https://github.com/twbs/bootstrap/issues/11586.

input[type="search"] {
  -webkit-appearance: none;
}


// Special styles for iOS temporal inputs
//
// In Mobile Safari, setting `display: block` on temporal inputs causes the
// text within the input to become vertically misaligned. As a workaround, we
// set a pixel line-height that matches the given height of the input, but only
// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848
//
// Note that as of 8.3, iOS doesn't support `datetime` or `week`.

@media screen and (-webkit-min-device-pixel-ratio: 0) {
  input[type="date"],
  input[type="time"],
  input[type="datetime-local"],
  input[type="month"] {
    &.form-control {
      line-height: $input-height-base;
    }

    &.input-sm,
    .input-group-sm & {
      line-height: $input-height-small;
    }

    &.input-lg,
    .input-group-lg & {
      line-height: $input-height-large;
    }
  }
}


// Form groups
//
// Designed to help with the organization and spacing of vertical forms. For
// horizontal forms, use the predefined grid classes.

.form-group {
  margin-bottom: $form-group-margin-bottom;
}


// Checkboxes and radios
//
// Indent the labels to position radios/checkboxes as hanging controls.

.radio,
.checkbox {
  position: relative;
  display: block;
  margin-top: 10px;
  margin-bottom: 10px;

  label {
    min-height: $line-height-computed; // Ensure the input doesn't jump when there is no text
    padding-left: 20px;
    margin-bottom: 0;
    font-weight: normal;
    cursor: pointer;
  }
}
.radio input[type="radio"],
.radio-inline input[type="radio"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
  position: absolute;
  margin-left: -20px;
  margin-top: 4px \9;
}

.radio + .radio,
.checkbox + .checkbox {
  margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing
}

// Radios and checkboxes on same line
.radio-inline,
.checkbox-inline {
  position: relative;
  display: inline-block;
  padding-left: 20px;
  margin-bottom: 0;
  vertical-align: middle;
  font-weight: normal;
  cursor: pointer;
}
.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
  margin-top: 0;
  margin-left: 10px; // space out consecutive inline controls
}

// Apply same disabled cursor tweak as for inputs
// Some special care is needed because <label>s don't inherit their parent's `cursor`.
//
// Note: Neither radios nor checkboxes can be readonly.
input[type="radio"],
input[type="checkbox"] {
  &[disabled],
  &.disabled,
  fieldset[disabled] & {
    cursor: $cursor-disabled;
  }
}
// These classes are used directly on <label>s
.radio-inline,
.checkbox-inline {
  &.disabled,
  fieldset[disabled] & {
    cursor: $cursor-disabled;
  }
}
// These classes are used on elements with <label> descendants
.radio,
.checkbox {
  &.disabled,
  fieldset[disabled] & {
    label {
      cursor: $cursor-disabled;
    }
  }
}


// Static form control text
//
// Apply class to a `p` element to make any string of text align with labels in
// a horizontal form layout.

.form-control-static {
  // Size it appropriately next to real form controls
  padding-top: ($padding-base-vertical + 1);
  padding-bottom: ($padding-base-vertical + 1);
  // Remove default margin from `p`
  margin-bottom: 0;
  min-height: ($line-height-computed + $font-size-base);

  &.input-lg,
  &.input-sm {
    padding-left: 0;
    padding-right: 0;
  }
}


// Form control sizing
//
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.
//
// The `.form-group-* form-control` variations are sadly duplicated to avoid the
// issue documented in https://github.com/twbs/bootstrap/issues/15074.

@include input-size('.input-sm', $input-height-small, $padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $input-border-radius-small);
.form-group-sm {
  .form-control {
    height: $input-height-small;
    padding: $padding-small-vertical $padding-small-horizontal;
    font-size: $font-size-small;
    line-height: $line-height-small;
    border-radius: $input-border-radius-small;
  }
  select.form-control {
    height: $input-height-small;
    line-height: $input-height-small;
  }
  textarea.form-control,
  select[multiple].form-control {
    height: auto;
  }
  .form-control-static {
    height: $input-height-small;
    min-height: ($line-height-computed + $font-size-small);
    padding: ($padding-small-vertical + 1) $padding-small-horizontal;
    font-size: $font-size-small;
    line-height: $line-height-small;
  }
}

@include input-size('.input-lg', $input-height-large, $padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $input-border-radius-large);
.form-group-lg {
  .form-control {
    height: $input-height-large;
    padding: $padding-large-vertical $padding-large-horizontal;
    font-size: $font-size-large;
    line-height: $line-height-large;
    border-radius: $input-border-radius-large;
  }
  select.form-control {
    height: $input-height-large;
    line-height: $input-height-large;
  }
  textarea.form-control,
  select[multiple].form-control {
    height: auto;
  }
  .form-control-static {
    height: $input-height-large;
    min-height: ($line-height-computed + $font-size-large);
    padding: ($padding-large-vertical + 1) $padding-large-horizontal;
    font-size: $font-size-large;
    line-height: $line-height-large;
  }
}


// Form control feedback states
//
// Apply contextual and semantic states to individual form controls.

.has-feedback {
  // Enable absolute positioning
  position: relative;

  // Ensure icons don't overlap text
  .form-control {
    padding-right: ($input-height-base * 1.25);
  }
}
// Feedback icon (requires .glyphicon classes)
.form-control-feedback {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 2; // Ensure icon is above input groups
  display: block;
  width: $input-height-base;
  height: $input-height-base;
  line-height: $input-height-base;
  text-align: center;
  pointer-events: none;
}
.input-lg + .form-control-feedback,
.input-group-lg + .form-control-feedback,
.form-group-lg .form-control + .form-control-feedback {
  width: $input-height-large;
  height: $input-height-large;
  line-height: $input-height-large;
}
.input-sm + .form-control-feedback,
.input-group-sm + .form-control-feedback,
.form-group-sm .form-control + .form-control-feedback {
  width: $input-height-small;
  height: $input-height-small;
  line-height: $input-height-small;
}

// Feedback states
.has-success {
  @include form-control-validation($state-success-text, $state-success-text, $state-success-bg);
}
.has-warning {
  @include form-control-validation($state-warning-text, $state-warning-text, $state-warning-bg);
}
.has-error {
  @include form-control-validation($state-danger-text, $state-danger-text, $state-danger-bg);
}

// Reposition feedback icon if input has visible label above
.has-feedback label {

  & ~ .form-control-feedback {
    top: ($line-height-computed + 5); // Height of the `label` and its margin
  }
  &.sr-only ~ .form-control-feedback {
    top: 0;
  }
}


// Help text
//
// Apply to any element you wish to create light text for placement immediately
// below a form control. Use for general help, formatting, or instructional text.

.help-block {
  display: block; // account for any element using help-block
  margin-top: 5px;
  margin-bottom: 10px;
  color: lighten($text-color, 25%); // lighten the text some for contrast
}


// Inline forms
//
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
// forms begin stacked on extra small (mobile) devices and then go inline when
// viewports reach <768px.
//
// Requires wrapping inputs and labels with `.form-group` for proper display of
// default HTML form controls and our custom form controls (e.g., input groups).
//
// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.

// [converter] extracted from `.form-inline` for libsass compatibility
@mixin form-inline {

  // Kick in the inline
  @media (min-width: $screen-sm-min) {
    // Inline-block all the things for "inline"
    .form-group {
      display: inline-block;
      margin-bottom: 0;
      vertical-align: middle;
    }

    // In navbar-form, allow folks to *not* use `.form-group`
    .form-control {
      display: inline-block;
      width: auto; // Prevent labels from stacking above inputs in `.form-group`
      vertical-align: middle;
    }

    // Make static controls behave like regular ones
    .form-control-static {
      display: inline-block;
    }

    .input-group {
      display: inline-table;
      vertical-align: middle;

      .input-group-addon,
      .input-group-btn,
      .form-control {
        width: auto;
      }
    }

    // Input groups need that 100% width though
    .input-group > .form-control {
      width: 100%;
    }

    .control-label {
      margin-bottom: 0;
      vertical-align: middle;
    }

    // Remove default margin on radios/checkboxes that were used for stacking, and
    // then undo the floating of radios and checkboxes to match.
    .radio,
    .checkbox {
      display: inline-block;
      margin-top: 0;
      margin-bottom: 0;
      vertical-align: middle;

      label {
        padding-left: 0;
      }
    }
    .radio input[type="radio"],
    .checkbox input[type="checkbox"] {
      position: relative;
      margin-left: 0;
    }

    // Re-override the feedback icon.
    .has-feedback .form-control-feedback {
      top: 0;
    }
  }
}
// [converter] extracted as `@mixin form-inline` for libsass compatibility
.form-inline {
  @include form-inline;
}



// Horizontal forms
//
// Horizontal forms are built on grid classes and allow you to create forms with
// labels on the left and inputs on the right.

.form-horizontal {

  // Consistent vertical alignment of radios and checkboxes
  //
  // Labels also get some reset styles, but that is scoped to a media query below.
  .radio,
  .checkbox,
  .radio-inline,
  .checkbox-inline {
    margin-top: 0;
    margin-bottom: 0;
    padding-top: ($padding-base-vertical + 1); // Default padding plus a border
  }
  // Account for padding we're adding to ensure the alignment and of help text
  // and other content below items
  .radio,
  .checkbox {
    min-height: ($line-height-computed + ($padding-base-vertical + 1));
  }

  // Make form groups behave like rows
  .form-group {
    @include make-row;
  }

  // Reset spacing and right align labels, but scope to media queries so that
  // labels on narrow viewports stack the same as a default form example.
  @media (min-width: $screen-sm-min) {
    .control-label {
      text-align: right;
      margin-bottom: 0;
      padding-top: ($padding-base-vertical + 1); // Default padding plus a border
    }
  }

  // Validation states
  //
  // Reposition the icon because it's now within a grid column and columns have
  // `position: relative;` on them. Also accounts for the grid gutter padding.
  .has-feedback .form-control-feedback {
    right: floor(($grid-gutter-width / 2));
  }

  // Form group sizes
  //
  // Quick utility class for applying `.input-lg` and `.input-sm` styles to the
  // inputs and labels within a `.form-group`.
  .form-group-lg {
    @media (min-width: $screen-sm-min) {
      .control-label {
        padding-top: ($padding-large-vertical + 1);
        font-size: $font-size-large;
      }
    }
  }
  .form-group-sm {
    @media (min-width: $screen-sm-min) {
      .control-label {
        padding-top: ($padding-small-vertical + 1);
        font-size: $font-size-small;
      }
    }
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_glyphicons.scss
================================================
//
// Glyphicons for Bootstrap
//
// Since icons are fonts, they can be placed anywhere text is placed and are
// thus automatically sized to match the surrounding child. To use, create an
// inline element with the appropriate classes, like so:
//
// <a href="#"><span class="glyphicon glyphicon-star"></span> Star</a>

@at-root {
  // Import the fonts
  @font-face {
    font-family: 'Glyphicons Halflings';
    src: url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.eot'), '#{$icon-font-path}#{$icon-font-name}.eot'));
    src: url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.eot?#iefix'), '#{$icon-font-path}#{$icon-font-name}.eot?#iefix')) format('embedded-opentype'),
         url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.woff2'), '#{$icon-font-path}#{$icon-font-name}.woff2')) format('woff2'),
         url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.woff'), '#{$icon-font-path}#{$icon-font-name}.woff')) format('woff'),
         url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.ttf'), '#{$icon-font-path}#{$icon-font-name}.ttf')) format('truetype'),
         url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.svg##{$icon-font-svg-id}'), '#{$icon-font-path}#{$icon-font-name}.svg##{$icon-font-svg-id}')) format('svg');
  }
}

// Catchall baseclass
.glyphicon {
  position: relative;
  top: 1px;
  display: inline-block;
  font-family: 'Glyphicons Halflings';
  font-style: normal;
  font-weight: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

// Individual icons
.glyphicon-asterisk               { &:before { content: "\002a"; } }
.glyphicon-plus                   { &:before { content: "\002b"; } }
.glyphicon-euro,
.glyphicon-eur                    { &:before { content: "\20ac"; } }
.glyphicon-minus                  { &:before { content: "\2212"; } }
.glyphicon-cloud                  { &:before { content: "\2601"; } }
.glyphicon-envelope               { &:before { content: "\2709"; } }
.glyphicon-pencil                 { &:before { content: "\270f"; } }
.glyphicon-glass                  { &:before { content: "\e001"; } }
.glyphicon-music                  { &:before { content: "\e002"; } }
.glyphicon-search                 { &:before { content: "\e003"; } }
.glyphicon-heart                  { &:before { content: "\e005"; } }
.glyphicon-star                   { &:before { content: "\e006"; } }
.glyphicon-star-empty             { &:before { content: "\e007"; } }
.glyphicon-user                   { &:before { content: "\e008"; } }
.glyphicon-film                   { &:before { content: "\e009"; } }
.glyphicon-th-large               { &:before { content: "\e010"; } }
.glyphicon-th                     { &:before { content: "\e011"; } }
.glyphicon-th-list                { &:before { content: "\e012"; } }
.glyphicon-ok                     { &:before { content: "\e013"; } }
.glyphicon-remove                 { &:before { content: "\e014"; } }
.glyphicon-zoom-in                { &:before { content: "\e015"; } }
.glyphicon-zoom-out               { &:before { content: "\e016"; } }
.glyphicon-off                    { &:before { content: "\e017"; } }
.glyphicon-signal                 { &:before { content: "\e018"; } }
.glyphicon-cog                    { &:before { content: "\e019"; } }
.glyphicon-trash                  { &:before { content: "\e020"; } }
.glyphicon-home                   { &:before { content: "\e021"; } }
.glyphicon-file                   { &:before { content: "\e022"; } }
.glyphicon-time                   { &:before { content: "\e023"; } }
.glyphicon-road                   { &:before { content: "\e024"; } }
.glyphicon-download-alt           { &:before { content: "\e025"; } }
.glyphicon-download               { &:before { content: "\e026"; } }
.glyphicon-upload                 { &:before { content: "\e027"; } }
.glyphicon-inbox                  { &:before { content: "\e028"; } }
.glyphicon-play-circle            { &:before { content: "\e029"; } }
.glyphicon-repeat                 { &:before { content: "\e030"; } }
.glyphicon-refresh                { &:before { content: "\e031"; } }
.glyphicon-list-alt               { &:before { content: "\e032"; } }
.glyphicon-lock                   { &:before { content: "\e033"; } }
.glyphicon-flag                   { &:before { content: "\e034"; } }
.glyphicon-headphones             { &:before { content: "\e035"; } }
.glyphicon-volume-off             { &:before { content: "\e036"; } }
.glyphicon-volume-down            { &:before { content: "\e037"; } }
.glyphicon-volume-up              { &:before { content: "\e038"; } }
.glyphicon-qrcode                 { &:before { content: "\e039"; } }
.glyphicon-barcode                { &:before { content: "\e040"; } }
.glyphicon-tag                    { &:before { content: "\e041"; } }
.glyphicon-tags                   { &:before { content: "\e042"; } }
.glyphicon-book                   { &:before { content: "\e043"; } }
.glyphicon-bookmark               { &:before { content: "\e044"; } }
.glyphicon-print                  { &:before { content: "\e045"; } }
.glyphicon-camera                 { &:before { content: "\e046"; } }
.glyphicon-font                   { &:before { content: "\e047"; } }
.glyphicon-bold                   { &:before { content: "\e048"; } }
.glyphicon-italic                 { &:before { content: "\e049"; } }
.glyphicon-text-height            { &:before { content: "\e050"; } }
.glyphicon-text-width             { &:before { content: "\e051"; } }
.glyphicon-align-left             { &:before { content: "\e052"; } }
.glyphicon-align-center           { &:before { content: "\e053"; } }
.glyphicon-align-right            { &:before { content: "\e054"; } }
.glyphicon-align-justify          { &:before { content: "\e055"; } }
.glyphicon-list                   { &:before { content: "\e056"; } }
.glyphicon-indent-left            { &:before { content: "\e057"; } }
.glyphicon-indent-right           { &:before { content: "\e058"; } }
.glyphicon-facetime-video         { &:before { content: "\e059"; } }
.glyphicon-picture                { &:before { content: "\e060"; } }
.glyphicon-map-marker             { &:before { content: "\e062"; } }
.glyphicon-adjust                 { &:before { content: "\e063"; } }
.glyphicon-tint                   { &:before { content: "\e064"; } }
.glyphicon-edit                   { &:before { content: "\e065"; } }
.glyphicon-share                  { &:before { content: "\e066"; } }
.glyphicon-check                  { &:before { content: "\e067"; } }
.glyphicon-move                   { &:before { content: "\e068"; } }
.glyphicon-step-backward          { &:before { content: "\e069"; } }
.glyphicon-fast-backward          { &:before { content: "\e070"; } }
.glyphicon-backward               { &:before { content: "\e071"; } }
.glyphicon-play                   { &:before { content: "\e072"; } }
.glyphicon-pause                  { &:before { content: "\e073"; } }
.glyphicon-stop                   { &:before { content: "\e074"; } }
.glyphicon-forward                { &:before { content: "\e075"; } }
.glyphicon-fast-forward           { &:before { content: "\e076"; } }
.glyphicon-step-forward           { &:before { content: "\e077"; } }
.glyphicon-eject                  { &:before { content: "\e078"; } }
.glyphicon-chevron-left           { &:before { content: "\e079"; } }
.glyphicon-chevron-right          { &:before { content: "\e080"; } }
.glyphicon-plus-sign              { &:before { content: "\e081"; } }
.glyphicon-minus-sign             { &:before { content: "\e082"; } }
.glyphicon-remove-sign            { &:before { content: "\e083"; } }
.glyphicon-ok-sign                { &:before { content: "\e084"; } }
.glyphicon-question-sign          { &:before { content: "\e085"; } }
.glyphicon-info-sign              { &:before { content: "\e086"; } }
.glyphicon-screenshot             { &:before { content: "\e087"; } }
.glyphicon-remove-circle          { &:before { content: "\e088"; } }
.glyphicon-ok-circle              { &:before { content: "\e089"; } }
.glyphicon-ban-circle             { &:before { content: "\e090"; } }
.glyphicon-arrow-left             { &:before { content: "\e091"; } }
.glyphicon-arrow-right            { &:before { content: "\e092"; } }
.glyphicon-arrow-up               { &:before { content: "\e093"; } }
.glyphicon-arrow-down             { &:before { content: "\e094"; } }
.glyphicon-share-alt              { &:before { content: "\e095"; } }
.glyphicon-resize-full            { &:before { content: "\e096"; } }
.glyphicon-resize-small           { &:before { content: "\e097"; } }
.glyphicon-exclamation-sign       { &:before { content: "\e101"; } }
.glyphicon-gift                   { &:before { content: "\e102"; } }
.glyphicon-leaf                   { &:before { content: "\e103"; } }
.glyphicon-fire                   { &:before { content: "\e104"; } }
.glyphicon-eye-open               { &:before { content: "\e105"; } }
.glyphicon-eye-close              { &:before { content: "\e106"; } }
.glyphicon-warning-sign           { &:before { content: "\e107"; } }
.glyphicon-plane                  { &:before { content: "\e108"; } }
.glyphicon-calendar               { &:before { content: "\e109"; } }
.glyphicon-random                 { &:before { content: "\e110"; } }
.glyphicon-comment                { &:before { content: "\e111"; } }
.glyphicon-magnet                 { &:before { content: "\e112"; } }
.glyphicon-chevron-up             { &:before { content: "\e113"; } }
.glyphicon-chevron-down           { &:before { content: "\e114"; } }
.glyphicon-retweet                { &:before { content: "\e115"; } }
.glyphicon-shopping-cart          { &:before { content: "\e116"; } }
.glyphicon-folder-close           { &:before { content: "\e117"; } }
.glyphicon-folder-open            { &:before { content: "\e118"; } }
.glyphicon-resize-vertical        { &:before { content: "\e119"; } }
.glyphicon-resize-horizontal      { &:before { content: "\e120"; } }
.glyphicon-hdd                    { &:before { content: "\e121"; } }
.glyphicon-bullhorn               { &:before { content: "\e122"; } }
.glyphicon-bell                   { &:before { content: "\e123"; } }
.glyphicon-certificate            { &:before { content: "\e124"; } }
.glyphicon-thumbs-up              { &:before { content: "\e125"; } }
.glyphicon-thumbs-down            { &:before { content: "\e126"; } }
.glyphicon-hand-right             { &:before { content: "\e127"; } }
.glyphicon-hand-left              { &:before { content: "\e128"; } }
.glyphicon-hand-up                { &:before { content: "\e129"; } }
.glyphicon-hand-down              { &:before { content: "\e130"; } }
.glyphicon-circle-arrow-right     { &:before { content: "\e131"; } }
.glyphicon-circle-arrow-left      { &:before { content: "\e132"; } }
.glyphicon-circle-arrow-up        { &:before { content: "\e133"; } }
.glyphicon-circle-arrow-down      { &:before { content: "\e134"; } }
.glyphicon-globe                  { &:before { content: "\e135"; } }
.glyphicon-wrench                 { &:before { content: "\e136"; } }
.glyphicon-tasks                  { &:before { content: "\e137"; } }
.glyphicon-filter                 { &:before { content: "\e138"; } }
.glyphicon-briefcase              { &:before { content: "\e139"; } }
.glyphicon-fullscreen             { &:before { content: "\e140"; } }
.glyphicon-dashboard              { &:before { content: "\e141"; } }
.glyphicon-paperclip              { &:before { content: "\e142"; } }
.glyphicon-heart-empty            { &:before { content: "\e143"; } }
.glyphicon-link                   { &:before { content: "\e144"; } }
.glyphicon-phone                  { &:before { content: "\e145"; } }
.glyphicon-pushpin                { &:before { content: "\e146"; } }
.glyphicon-usd                    { &:before { content: "\e148"; } }
.glyphicon-gbp                    { &:before { content: "\e149"; } }
.glyphicon-sort                   { &:before { content: "\e150"; } }
.glyphicon-sort-by-alphabet       { &:before { content: "\e151"; } }
.glyphicon-sort-by-alphabet-alt   { &:before { content: "\e152"; } }
.glyphicon-sort-by-order          { &:before { content: "\e153"; } }
.glyphicon-sort-by-order-alt      { &:before { content: "\e154"; } }
.glyphicon-sort-by-attributes     { &:before { content: "\e155"; } }
.glyphicon-sort-by-attributes-alt { &:before { content: "\e156"; } }
.glyphicon-unchecked              { &:before { content: "\e157"; } }
.glyphicon-expand                 { &:before { content: "\e158"; } }
.glyphicon-collapse-down          { &:before { content: "\e159"; } }
.glyphicon-collapse-up            { &:before { content: "\e160"; } }
.glyphicon-log-in                 { &:before { content: "\e161"; } }
.glyphicon-flash                  { &:before { content: "\e162"; } }
.glyphicon-log-out                { &:before { content: "\e163"; } }
.glyphicon-new-window             { &:before { content: "\e164"; } }
.glyphicon-record                 { &:before { content: "\e165"; } }
.glyphicon-save                   { &:before { content: "\e166"; } }
.glyphicon-open                   { &:before { content: "\e167"; } }
.glyphicon-saved                  { &:before { content: "\e168"; } }
.glyphicon-import                 { &:before { content: "\e169"; } }
.glyphicon-export                 { &:before { content: "\e170"; } }
.glyphicon-send                   { &:before { content: "\e171"; } }
.glyphicon-floppy-disk            { &:before { content: "\e172"; } }
.glyphicon-floppy-saved           { &:before { content: "\e173"; } }
.glyphicon-floppy-remove          { &:before { content: "\e174"; } }
.glyphicon-floppy-save            { &:before { content: "\e175"; } }
.glyphicon-floppy-open            { &:before { content: "\e176"; } }
.glyphicon-credit-card            { &:before { content: "\e177"; } }
.glyphicon-transfer               { &:before { content: "\e178"; } }
.glyphicon-cutlery                { &:before { content: "\e179"; } }
.glyphicon-header                 { &:before { content: "\e180"; } }
.glyphicon-compressed             { &:before { content: "\e181"; } }
.glyphicon-earphone               { &:before { content: "\e182"; } }
.glyphicon-phone-alt              { &:before { content: "\e183"; } }
.glyphicon-tower                  { &:before { content: "\e184"; } }
.glyphicon-stats                  { &:before { content: "\e185"; } }
.glyphicon-sd-video               { &:before { content: "\e186"; } }
.glyphicon-hd-video               { &:before { content: "\e187"; } }
.glyphicon-subtitles              { &:before { content: "\e188"; } }
.glyphicon-sound-stereo           { &:before { content: "\e189"; } }
.glyphicon-sound-dolby            { &:before { content: "\e190"; } }
.glyphicon-sound-5-1              { &:before { content: "\e191"; } }
.glyphicon-sound-6-1              { &:before { content: "\e192"; } }
.glyphicon-sound-7-1              { &:before { content: "\e193"; } }
.glyphicon-copyright-mark         { &:before { content: "\e194"; } }
.glyphicon-registration-mark      { &:before { content: "\e195"; } }
.glyphicon-cloud-download         { &:before { content: "\e197"; } }
.glyphicon-cloud-upload           { &:before { content: "\e198"; } }
.glyphicon-tree-conifer           { &:before { content: "\e199"; } }
.glyphicon-tree-deciduous         { &:before { content: "\e200"; } }
.glyphicon-cd                     { &:before { content: "\e201"; } }
.glyphicon-save-file              { &:before { content: "\e202"; } }
.glyphicon-open-file              { &:before { content: "\e203"; } }
.glyphicon-level-up               { &:before { content: "\e204"; } }
.glyphicon-copy                   { &:before { content: "\e205"; } }
.glyphicon-paste                  { &:before { content: "\e206"; } }
// The following 2 Glyphicons are omitted for the time being because
// they currently use Unicode codepoints that are outside the
// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle
// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.
// Notably, the bug affects some older versions of the Android Browser.
// More info: https://github.com/twbs/bootstrap/issues/10106
// .glyphicon-door                   { &:before { content: "\1f6aa"; } }
// .glyphicon-key                    { &:before { content: "\1f511"; } }
.glyphicon-alert                  { &:before { content: "\e209"; } }
.glyphicon-equalizer              { &:before { content: "\e210"; } }
.glyphicon-king                   { &:before { content: "\e211"; } }
.glyphicon-queen                  { &:before { content: "\e212"; } }
.glyphicon-pawn                   { &:before { content: "\e213"; } }
.glyphicon-bishop                 { &:before { content: "\e214"; } }
.glyphicon-knight                 { &:before { content: "\e215"; } }
.glyphicon-baby-formula           { &:before { content: "\e216"; } }
.glyphicon-tent                   { &:before { content: "\26fa"; } }
.glyphicon-blackboard             { &:before { content: "\e218"; } }
.glyphicon-bed                    { &:before { content: "\e219"; } }
.glyphicon-apple                  { &:before { content: "\f8ff"; } }
.glyphicon-erase                  { &:before { content: "\e221"; } }
.glyphicon-hourglass              { &:before { content: "\231b"; } }
.glyphicon-lamp                   { &:before { content: "\e223"; } }
.glyphicon-duplicate              { &:before { content: "\e224"; } }
.glyphicon-piggy-bank             { &:before { content: "\e225"; } }
.glyphicon-scissors               { &:before { content: "\e226"; } }
.glyphicon-bitcoin                { &:before { content: "\e227"; } }
.glyphicon-btc                    { &:before { content: "\e227"; } }
.glyphicon-xbt                    { &:before { content: "\e227"; } }
.glyphicon-yen                    { &:before { content: "\00a5"; } }
.glyphicon-jpy                    { &:before { content: "\00a5"; } }
.glyphicon-ruble                  { &:before { content: "\20bd"; } }
.glyphicon-rub                    { &:before { content: "\20bd"; } }
.glyphicon-scale                  { &:before { content: "\e230"; } }
.glyphicon-ice-lolly              { &:before { content: "\e231"; } }
.glyphicon-ice-lolly-tasted       { &:before { content: "\e232"; } }
.glyphicon-education              { &:before { content: "\e233"; } }
.glyphicon-option-horizontal      { &:before { content: "\e234"; } }
.glyphicon-option-vertical        { &:before { content: "\e235"; } }
.glyphicon-menu-hamburger         { &:before { content: "\e236"; } }
.glyphicon-modal-window           { &:before { content: "\e237"; } }
.glyphicon-oil                    { &:before { content: "\e238"; } }
.glyphicon-grain                  { &:before { content: "\e239"; } }
.glyphicon-sunglasses             { &:before { content: "\e240"; } }
.glyphicon-text-size              { &:before { content: "\e241"; } }
.glyphicon-text-color             { &:before { content: "\e242"; } }
.glyphicon-text-background        { &:before { content: "\e243"; } }
.glyphicon-object-align-top       { &:before { content: "\e244"; } }
.glyphicon-object-align-bottom    { &:before { content: "\e245"; } }
.glyphicon-object-align-horizontal{ &:before { content: "\e246"; } }
.glyphicon-object-align-left      { &:before { content: "\e247"; } }
.glyphicon-object-align-vertical  { &:before { content: "\e248"; } }
.glyphicon-object-align-right     { &:before { content: "\e249"; } }
.glyphicon-triangle-right         { &:before { content: "\e250"; } }
.glyphicon-triangle-left          { &:before { content: "\e251"; } }
.glyphicon-triangle-bottom        { &:before { content: "\e252"; } }
.glyphicon-triangle-top           { &:before { content: "\e253"; } }
.glyphicon-console                { &:before { content: "\e254"; } }
.glyphicon-superscript            { &:before { content: "\e255"; } }
.glyphicon-subscript              { &:before { content: "\e256"; } }
.glyphicon-menu-left              { &:before { content: "\e257"; } }
.glyphicon-menu-right             { &:before { content: "\e258"; } }
.glyphicon-menu-down              { &:before { content: "\e259"; } }
.glyphicon-menu-up                { &:before { content: "\e260"; } }


================================================
FILE: client/src/style/vendor/bootstrap/_grid.scss
================================================
//
// Grid system
// --------------------------------------------------


// Container widths
//
// Set the container width, and override it for fixed navbars in media queries.

.container {
  @include container-fixed;

  @media (min-width: $screen-sm-min) {
    width: $container-sm;
  }
  @media (min-width: $screen-md-min) {
    width: $container-md;
  }
  @media (min-width: $screen-lg-min) {
    width: $container-lg;
  }
}


// Fluid container
//
// Utilizes the mixin meant for fixed width containers, but without any defined
// width for fluid, full width layouts.

.container-fluid {
  @include container-fixed;
}


// Row
//
// Rows contain and clear the floats of your columns.

.row {
  @include make-row;
}


// Columns
//
// Common styles for small and large grid columns

@include make-grid-columns;


// Extra small grid
//
// Columns, offsets, pushes, and pulls for extra small devices like
// smartphones.

@include make-grid(xs);


// Small grid
//
// Columns, offsets, pushes, and pulls for the small device range, from phones
// to tablets.

@media (min-width: $screen-sm-min) {
  @include make-grid(sm);
}


// Medium grid
//
// Columns, offsets, pushes, and pulls for the desktop device range.

@media (min-width: $screen-md-min) {
  @include make-grid(md);
}


// Large grid
//
// Columns, offsets, pushes, and pulls for the large desktop device range.

@media (min-width: $screen-lg-min) {
  @include make-grid(lg);
}


================================================
FILE: client/src/style/vendor/bootstrap/_input-groups.scss
================================================
//
// Input groups
// --------------------------------------------------

// Base styles
// -------------------------
.input-group {
  position: relative; // For dropdowns
  display: table;
  border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table

  // Undo padding and float of grid classes
  &[class*="col-"] {
    float: none;
    padding-left: 0;
    padding-right: 0;
  }

  .form-control {
    // Ensure that the input is always above the *appended* addon button for
    // proper border colors.
    position: relative;
    z-index: 2;

    // IE9 fubars the placeholder attribute in text inputs and the arrows on
    // select elements in input groups. To fix it, we float the input. Details:
    // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855
    float: left;

    width: 100%;
    margin-bottom: 0;
    
    &:focus {
      z-index: 3;
    }
  }
}

// Sizing options
//
// Remix the default form control sizing classes into new ones for easier
// manipulation.

.input-group-lg > .form-control,
.input-group-lg > .input-group-addon,
.input-group-lg > .input-group-btn > .btn {
  @extend .input-lg;
}
.input-group-sm > .form-control,
.input-group-sm > .input-group-addon,
.input-group-sm > .input-group-btn > .btn {
  @extend .input-sm;
}


// Display as table-cell
// -------------------------
.input-group-addon,
.input-group-btn,
.input-group .form-control {
  display: table-cell;

  &:not(:first-child):not(:last-child) {
    border-radius: 0;
  }
}
// Addon and addon wrapper for buttons
.input-group-addon,
.input-group-btn {
  width: 1%;
  white-space: nowrap;
  vertical-align: middle; // Match the inputs
}

// Text input groups
// -------------------------
.input-group-addon {
  padding: $padding-base-vertical $padding-base-horizontal;
  font-size: $font-size-base;
  font-weight: normal;
  line-height: 1;
  color: $input-color;
  text-align: center;
  background-color: $input-group-addon-bg;
  border: 1px solid $input-group-addon-border-color;
  border-radius: $input-border-radius;

  // Sizing
  &.input-sm {
    padding: $padding-small-vertical $padding-small-horizontal;
    font-size: $font-size-small;
    border-radius: $input-border-radius-small;
  }
  &.input-lg {
    padding: $padding-large-vertical $padding-large-horizontal;
    font-size: $font-size-large;
    border-radius: $input-border-radius-large;
  }

  // Nuke default margins from checkboxes and radios to vertically center within.
  input[type="radio"],
  input[type="checkbox"] {
    margin-top: 0;
  }
}

// Reset rounded corners
.input-group .form-control:first-child,
.input-group-addon:first-child,
.input-group-btn:first-child > .btn,
.input-group-btn:first-child > .btn-group > .btn,
.input-group-btn:first-child > .dropdown-toggle,
.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
  @include border-right-radius(0);
}
.input-group-addon:first-child {
  border-right: 0;
}
.input-group .form-control:last-child,
.input-group-addon:last-child,
.input-group-btn:last-child > .btn,
.input-group-btn:last-child > .btn-group > .btn,
.input-group-btn:last-child > .dropdown-toggle,
.input-group-btn:first-child > .btn:not(:first-child),
.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
  @include border-left-radius(0);
}
.input-group-addon:last-child {
  border-left: 0;
}

// Button input groups
// -------------------------
.input-group-btn {
  position: relative;
  // Jankily prevent input button groups from wrapping with `white-space` and
  // `font-size` in combination with `inline-block` on buttons.
  font-size: 0;
  white-space: nowrap;

  // Negative margin for spacing, position for bringing hovered/focused/actived
  // element above the siblings.
  > .btn {
    position: relative;
    + .btn {
      margin-left: -1px;
    }
    // Bring the "active" button to the front
    &:hover,
    &:focus,
    &:active {
      z-index: 2;
    }
  }

  // Negative margin to only have a 1px border between the two
  &:first-child {
    > .btn,
    > .btn-group {
      margin-right: -1px;
    }
  }
  &:last-child {
    > .btn,
    > .btn-group {
      z-index: 2;
      margin-left: -1px;
    }
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_jumbotron.scss
================================================
//
// Jumbotron
// --------------------------------------------------


.jumbotron {
  padding-top:    $jumbotron-padding;
  padding-bottom: $jumbotron-padding;
  margin-bottom: $jumbotron-padding;
  color: $jumbotron-color;
  background-color: $jumbotron-bg;

  h1,
  .h1 {
    color: $jumbotron-heading-color;
  }

  p {
    margin-bottom: ($jumbotron-padding / 2);
    font-size: $jumbotron-font-size;
    font-weight: 200;
  }

  > hr {
    border-top-color: darken($jumbotron-bg, 10%);
  }

  .container &,
  .container-fluid & {
    border-radius: $border-radius-large; // Only round corners at higher resolutions if contained in a container
    padding-left:  ($grid-gutter-width / 2);
    padding-right: ($grid-gutter-width / 2);
  }

  .container {
    max-width: 100%;
  }

  @media screen and (min-width: $screen-sm-min) {
    padding-top:    ($jumbotron-padding * 1.6);
    padding-bottom: ($jumbotron-padding * 1.6);

    .container &,
    .container-fluid & {
      padding-left:  ($jumbotron-padding * 2);
      padding-right: ($jumbotron-padding * 2);
    }

    h1,
    .h1 {
      font-size: $jumbotron-heading-font-size;
    }
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_labels.scss
================================================
//
// Labels
// --------------------------------------------------

.label {
  display: inline;
  padding: .2em .6em .3em;
  font-size: 75%;
  font-weight: bold;
  line-height: 1;
  color: $label-color;
  text-align: center;
  white-space: nowrap;
  vertical-align: baseline;
  border-radius: .25em;

  // [converter] extracted a& to a.label

  // Empty labels collapse automatically (not available in IE8)
  &:empty {
    display: none;
  }

  // Quick fix for labels in buttons
  .btn & {
    position: relative;
    top: -1px;
  }
}

// Add hover effects, but only for links
a.label {
  &:hover,
  &:focus {
    color: $label-link-hover-color;
    text-decoration: none;
    cursor: pointer;
  }
}

// Colors
// Contextual variations (linked labels get darker on :hover)

.label-default {
  @include label-variant($label-default-bg);
}

.label-primary {
  @include label-variant($label-primary-bg);
}

.label-success {
  @include label-variant($label-success-bg);
}

.label-info {
  @include label-variant($label-info-bg);
}

.label-warning {
  @include label-variant($label-warning-bg);
}

.label-danger {
  @include label-variant($label-danger-bg);
}


================================================
FILE: client/src/style/vendor/bootstrap/_list-group.scss
================================================
//
// List groups
// --------------------------------------------------


// Base class
//
// Easily usable on <ul>, <ol>, or <div>.

.list-group {
  // No need to set list-style: none; since .list-group-item is block level
  margin-bottom: 20px;
  padding-left: 0; // reset padding because ul and ol
}


// Individual list items
//
// Use on `li`s or `div`s within the `.list-group` parent.

.list-group-item {
  position: relative;
  display: block;
  padding: 10px 15px;
  // Place the border on the list items and negative margin up for better styling
  margin-bottom: -1px;
  background-color: $list-group-bg;
  border: 1px solid $list-group-border;

  // Round the first and last items
  &:first-child {
    @include border-top-radius($list-group-border-radius);
  }
  &:last-child {
    margin-bottom: 0;
    @include border-bottom-radius($list-group-border-radius);
  }
}


// Interactive list items
//
// Use anchor or button elements instead of `li`s or `div`s to create interactive items.
// Includes an extra `.active` modifier class for showing selected items.

a.list-group-item,
button.list-group-item {
  color: $list-group-link-color;

  .list-group-item-heading {
    color: $list-group-link-heading-color;
  }

  // Hover state
  &:hover,
  &:focus {
    text-decoration: none;
    color: $list-group-link-hover-color;
    background-color: $list-group-hover-bg;
  }
}

button.list-group-item {
  width: 100%;
  text-align: left;
}

.list-group-item {
  // Disabled state
  &.disabled,
  &.disabled:hover,
  &.disabled:focus {
    background-color: $list-group-disabled-bg;
    color: $list-group-disabled-color;
    cursor: $cursor-disabled;

    // Force color to inherit for custom content
    .list-group-item-heading {
      color: inherit;
    }
    .list-group-item-text {
      color: $list-group-disabled-text-color;
    }
  }

  // Active class on item itself, not parent
  &.active,
  &.active:hover,
  &.active:focus {
    z-index: 2; // Place active items above their siblings for proper border styling
    color: $list-group-active-color;
    background-color: $list-group-active-bg;
    border-color: $list-group-active-border;

    // Force color to inherit for custom content
    .list-group-item-heading,
    .list-group-item-heading > small,
    .list-group-item-heading > .small {
      color: inherit;
    }
    .list-group-item-text {
      color: $list-group-active-text-color;
    }
  }
}


// Contextual variants
//
// Add modifier classes to change text and background color on individual items.
// Organizationally, this must come after the `:hover` states.

@include list-group-item-variant(success, $state-success-bg, $state-success-text);
@include list-group-item-variant(info, $state-info-bg, $state-info-text);
@include list-group-item-variant(warning, $state-warning-bg, $state-warning-text);
@include list-group-item-variant(danger, $state-danger-bg, $state-danger-text);


// Custom content options
//
// Extra classes for creating well-formatted content within `.list-group-item`s.

.list-group-item-heading {
  margin-top: 0;
  margin-bottom: 5px;
}
.list-group-item-text {
  margin-bottom: 0;
  line-height: 1.3;
}


================================================
FILE: client/src/style/vendor/bootstrap/_media.scss
================================================
.media {
  // Proper spacing between instances of .media
  margin-top: 15px;

  &:first-child {
    margin-top: 0;
  }
}

.media,
.media-body {
  zoom: 1;
  overflow: hidden;
}

.media-body {
  width: 10000px;
}

.media-object {
  display: block;

  // Fix collapse in webkit from max-width: 100% and display: table-cell.
  &.img-thumbnail {
    max-width: none;
  }
}

.media-right,
.media > .pull-right {
  padding-left: 10px;
}

.media-left,
.media > .pull-left {
  padding-right: 10px;
}

.media-left,
.media-right,
.media-body {
  display: table-cell;
  vertical-align: top;
}

.media-middle {
  vertical-align: middle;
}

.media-bottom {
  vertical-align: bottom;
}

// Reset margins on headings for tighter default spacing
.media-heading {
  margin-top: 0;
  margin-bottom: 5px;
}

// Media list variation
//
// Undo default ul/ol styles
.media-list {
  padding-left: 0;
  list-style: none;
}


================================================
FILE: client/src/style/vendor/bootstrap/_mixins.scss
================================================
// Mixins
// --------------------------------------------------

// Utilities
@import "mixins/hide-text";
@import "mixins/opacity";
@import "mixins/image";
@import "mixins/labels";
@import "mixins/reset-filter";
@import "mixins/resize";
@import "mixins/responsive-visibility";
@import "mixins/size";
@import "mixins/tab-focus";
@import "mixins/reset-text";
@import "mixins/text-emphasis";
@import "mixins/text-overflow";
@import "mixins/vendor-prefixes";

// Components
@import "mixins/alerts";
@import "mixins/buttons";
@import "mixins/panels";
@import "mixins/pagination";
@import "mixins/list-group";
@import "mixins/nav-divider";
@import "mixins/forms";
@import "mixins/progress-bar";
@import "mixins/table-row";

// Skins
@import "mixins/background-variant";
@import "mixins/border-radius";
@import "mixins/gradients";

// Layout
@import "mixins/clearfix";
@import "mixins/center-block";
@import "mixins/nav-vertical-align";
@import "mixins/grid-framework";
@import "mixins/grid";


================================================
FILE: client/src/style/vendor/bootstrap/_modals.scss
================================================
//
// Modals
// --------------------------------------------------

// .modal-open      - body class for killing the scroll
// .modal           - container to scroll within
// .modal-dialog    - positioning shell for the actual modal
// .modal-content   - actual modal w/ bg and corners and shit

// Kill the scroll on the body
.modal-open {
  overflow: hidden;
}

// Container that the modal scrolls within
.modal {
  display: none;
  overflow: hidden;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: $zindex-modal;
  -webkit-overflow-scrolling: touch;

  // Prevent Chrome on Windows from adding a focus outline. For details, see
  // https://github.com/twbs/bootstrap/pull/10951.
  outline: 0;

  // When fading in the modal, animate it to slide down
  &.fade .modal-dialog {
    @include translate(0, -25%);
    @include transition-transform(0.3s ease-out);
  }
  &.in .modal-dialog { @include translate(0, 0) }
}
.modal-open .modal {
  overflow-x: hidden;
  overflow-y: auto;
}

// Shell div to position the modal with bottom padding
.modal-dialog {
  position: relative;
  width: auto;
  margin: 10px;
}

// Actual modal
.modal-content {
  position: relative;
  background-color: $modal-content-bg;
  border: 1px solid $modal-content-fallback-border-color; //old browsers fallback (ie8 etc)
  border: 1px solid $modal-content-border-color;
  border-radius: $border-radius-large;
  @include box-shadow(0 3px 9px rgba(0,0,0,.5));
  background-clip: padding-box;
  // Remove focus outline from opened modal
  outline: 0;
}

// Modal background
.modal-backdrop {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: $zindex-modal-background;
  background-color: $modal-backdrop-bg;
  // Fade for backdrop
  &.fade { @include opacity(0); }
  &.in { @include opacity($modal-backdrop-opacity); }
}

// Modal header
// Top section of the modal w/ title and dismiss
.modal-header {
  padding: $modal-title-padding;
  border-bottom: 1px solid $modal-header-border-color;
  @include clearfix;
}
// Close icon
.modal-header .close {
  margin-top: -2px;
}

// Title text within header
.modal-title {
  margin: 0;
  line-height: $modal-title-line-height;
}

// Modal body
// Where all modal content resides (sibling of .modal-header and .modal-footer)
.modal-body {
  position: relative;
  padding: $modal-inner-padding;
}

// Footer (for actions)
.modal-footer {
  padding: $modal-inner-padding;
  text-align: right; // right align buttons
  border-top: 1px solid $modal-footer-border-color;
  @include clearfix; // clear it in case folks use .pull-* classes on buttons

  // Properly space out buttons
  .btn + .btn {
    margin-left: 5px;
    margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
  }
  // but override that for button groups
  .btn-group .btn + .btn {
    margin-left: -1px;
  }
  // and override it for block buttons as well
  .btn-block + .btn-block {
    margin-left: 0;
  }
}

// Measure scrollbar width for padding body during modal show/hide
.modal-scrollbar-measure {
  position: absolute;
  top: -9999px;
  width: 50px;
  height: 50px;
  overflow: scroll;
}

// Scale up the modal
@media (min-width: $screen-sm-min) {
  // Automatically set modal's width for larger viewports
  .modal-dialog {
    width: $modal-md;
    margin: 30px auto;
  }
  .modal-content {
    @include box-shadow(0 5px 15px rgba(0,0,0,.5));
  }

  // Modal sizes
  .modal-sm { width: $modal-sm; }
}

@media (min-width: $screen-md-min) {
  .modal-lg { width: $modal-lg; }
}


================================================
FILE: client/src/style/vendor/bootstrap/_navbar.scss
================================================
//
// Navbars
// --------------------------------------------------


// Wrapper and base class
//
// Provide a static navbar from which we expand to create full-width, fixed, and
// other navbar variations.

.navbar {
  position: relative;
  min-height: $navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)
  margin-bottom: $navbar-margin-bottom;
  border: 1px solid transparent;

  // Prevent floats from breaking the navbar
  @include clearfix;

  @media (min-width: $grid-float-breakpoint) {
    border-radius: $navbar-border-radius;
  }
}


// Navbar heading
//
// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy
// styling of responsive aspects.

.navbar-header {
  @include clearfix;

  @media (min-width: $grid-float-breakpoint) {
    float: left;
  }
}


// Navbar collapse (body)
//
// Group your navbar content into this for easy collapsing and expanding across
// various device sizes. By default, this content is collapsed when <768px, but
// will expand past that for a horizontal display.
//
// To start (on mobile devices) the navbar links, forms, and buttons are stacked
// vertically and include a `max-height` to overflow in case you have too much
// content for the user's viewport.

.navbar-collapse {
  overflow-x: visible;
  padding-right: $navbar-padding-horizontal;
  padding-left:  $navbar-padding-horizontal;
  border-top: 1px solid transparent;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.1);
  @include clearfix;
  -webkit-overflow-scrolling: touch;

  &.in {
    overflow-y: auto;
  }

  @media (min-width: $grid-float-breakpoint) {
    width: auto;
    border-top: 0;
    box-shadow: none;

    &.collapse {
      display: block !important;
      height: auto !important;
      padding-bottom: 0; // Override default setting
      overflow: visible !important;
    }

    &.in {
      overflow-y: visible;
    }

    // Undo the collapse side padding for navbars with containers to ensure
    // alignment of right-aligned contents.
    .navbar-fixed-top &,
    .navbar-static-top &,
    .navbar-fixed-bottom & {
      padding-left: 0;
      padding-right: 0;
    }
  }
}

.navbar-fixed-top,
.navbar-fixed-bottom {
  .navbar-collapse {
    max-height: $navbar-collapse-max-height;

    @media (max-device-width: $screen-xs-min) and (orientation: landscape) {
      max-height: 200px;
    }
  }
}


// Both navbar header and collapse
//
// When a container is present, change the behavior of the header and collapse.

.container,
.container-fluid {
  > .navbar-header,
  > .navbar-collapse {
    margin-right: -$navbar-padding-horizontal;
    margin-left:  -$navbar-padding-horizontal;

    @media (min-width: $grid-float-breakpoint) {
      margin-right: 0;
      margin-left:  0;
    }
  }
}


//
// Navbar alignment options
//
// Display the navbar across the entirety of the page or fixed it to the top or
// bottom of the page.

// Static top (unfixed, but 100% wide) navbar
.navbar-static-top {
  z-index: $zindex-navbar;
  border-width: 0 0 1px;

  @media (min-width: $grid-float-breakpoint) {
    border-radius: 0;
  }
}

// Fix the top/bottom navbars when screen real estate supports it
.navbar-fixed-top,
.navbar-fixed-bottom {
  position: fixed;
  right: 0;
  left: 0;
  z-index: $zindex-navbar-fixed;

  // Undo the rounded corners
  @media (min-width: $grid-float-breakpoint) {
    border-radius: 0;
  }
}
.navbar-fixed-top {
  top: 0;
  border-width: 0 0 1px;
}
.navbar-fixed-bottom {
  bottom: 0;
  margin-bottom: 0; // override .navbar defaults
  border-width: 1px 0 0;
}


// Brand/project name

.navbar-brand {
  float: left;
  padding: $navbar-padding-vertical $navbar-padding-horizontal;
  font-size: $font-size-large;
  line-height: $line-height-computed;
  height: $navbar-height;

  &:hover,
  &:focus {
    text-decoration: none;
  }

  > img {
    display: block;
  }

  @media (min-width: $grid-float-breakpoint) {
    .navbar > .container &,
    .navbar > .container-fluid & {
      margin-left: -$navbar-padding-horizontal;
    }
  }
}


// Navbar toggle
//
// Custom button for toggling the `.navbar-collapse`, powered by the collapse
// JavaScript plugin.

.navbar-toggle {
  position: relative;
  float: right;
  margin-right: $navbar-padding-horizontal;
  padding: 9px 10px;
  @include navbar-vertical-align(34px);
  background-color: transparent;
  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
  border: 1px solid transparent;
  border-radius: $border-radius-base;

  // We remove the `outline` here, but later compensate by attaching `:hover`
  // styles to `:focus`.
  &:focus {
    outline: 0;
  }

  // Bars
  .icon-bar {
    display: block;
    width: 22px;
    height: 2px;
    border-radius: 1px;
  }
  .icon-bar + .icon-bar {
    margin-top: 4px;
  }

  @media (min-width: $grid-float-breakpoint) {
    display: none;
  }
}


// Navbar nav links
//
// Builds on top of the `.nav` components with its own modifier class to make
// the nav the full height of the horizontal nav (above 768px).

.navbar-nav {
  margin: ($navbar-padding-vertical / 2) (-$navbar-padding-horizontal);

  > li > a {
    padding-top:    10px;
    padding-bottom: 10px;
    line-height: $line-height-computed;
  }

  @media (max-width: $grid-float-breakpoint-max) {
    // Dropdowns get custom display when collapsed
    .open .dropdown-menu {
      position: static;
      float: none;
      width: auto;
      margin-top: 0;
      background-color: transparent;
      border: 0;
      box-shadow: none;
      > li > a,
      .dropdown-header {
        padding: 5px 15px 5px 25px;
      }
      > li > a {
        line-height: $line-height-computed;
        &:hover,
        &:focus {
          background-image: none;
        }
      }
    }
  }

  // Uncollapse the nav
  @media (min-width: $grid-float-breakpoint) {
    float: left;
    margin: 0;

    > li {
      float: left;
      > a {
        padding-top:    $navbar-padding-vertical;
        padding-bottom: $navbar-padding-vertical;
      }
    }
  }
}


// Navbar form
//
// Extension of the `.form-inline` with some extra flavor for optimum display in
// our navbars.

.navbar-form {
  margin-left: -$navbar-padding-horizontal;
  margin-right: -$navbar-padding-horizontal;
  padding: 10px $navbar-padding-horizontal;
  border-top: 1px solid transparent;
  border-bottom: 1px solid transparent;
  $shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);
  @include box-shadow($shadow);

  // Mixin behavior for optimum display
  @include form-inline;

  .form-group {
    @media (max-width: $grid-float-breakpoint-max) {
      margin-bottom: 5px;

      &:last-child {
        margin-bottom: 0;
      }
    }
  }

  // Vertically center in expanded, horizontal navbar
  @include navbar-vertical-align($input-height-base);

  // Undo 100% width for pull classes
  @media (min-width: $grid-float-breakpoint) {
    width: auto;
    border: 0;
    margin-left: 0;
    margin-right: 0;
    padding-top: 0;
    padding-bottom: 0;
    @include box-shadow(none);
  }
}


// Dropdown menus

// Menu position and menu carets
.navbar-nav > li > .dropdown-menu {
  margin-top: 0;
  @include border-top-radius(0);
}
// Menu position and menu caret support for dropups via extra dropup class
.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
  margin-bottom: 0;
  @include border-top-radius($navbar-border-radius);
  @include border-bottom-radius(0);
}


// Buttons in navbars
//
// Vertically center a button within a navbar (when *not* in a form).

.navbar-btn {
  @include navbar-vertical-align($input-height-base);

  &.btn-sm {
    @include navbar-vertical-align($input-height-small);
  }
  &.btn-xs {
    @include navbar-vertical-align(22);
  }
}


// Text in navbars
//
// Add a class to make any element properly align itself vertically within the navbars.

.navbar-text {
  @include navbar-vertical-align($line-height-computed);

  @media (min-width: $grid-float-breakpoint) {
    float: left;
    margin-left: $navbar-padding-horizontal;
    margin-right: $navbar-padding-horizontal;
  }
}


// Component alignment
//
// Repurpose the pull utilities as their own navbar utilities to avoid specificity
// issues with parents and chaining. Only do this when the navbar is uncollapsed
// though so that navbar contents properly stack and align in mobile.
//
// Declared after the navbar components to ensure more specificity on the margins.

@media (min-width: $grid-float-breakpoint) {
  .navbar-left {
    float: left !important;
  }
  .navbar-right {
    float: right !important;
  margin-right: -$navbar-padding-horizontal;

    ~ .navbar-right {
      margin-right: 0;
    }
  }
}


// Alternate navbars
// --------------------------------------------------

// Default navbar
.navbar-default {
  background-color: $navbar-default-bg;
  border-color: $navbar-default-border;

  .navbar-brand {
    color: $navbar-default-brand-color;
    &:hover,
    &:focus {
      color: $navbar-default-brand-hover-color;
      background-color: $navbar-default-brand-hover-bg;
    }
  }

  .navbar-text {
    color: $navbar-default-color;
  }

  .navbar-nav {
    > li > a {
      color: $navbar-default-link-color;

      &:hover,
      &:focus {
        color: $navbar-default-link-hover-color;
        background-color: $navbar-default-link-hover-bg;
      }
    }
    > .active > a {
      &,
      &:hover,
      &:focus {
        color: $navbar-default-link-active-color;
        background-color: $navbar-default-link-active-bg;
      }
    }
    > .disabled > a {
      &,
      &:hover,
      &:focus {
        color: $navbar-default-link-disabled-color;
        background-color: $navbar-default-link-disabled-bg;
      }
    }
  }

  .navbar-toggle {
    border-color: $navbar-default-toggle-border-color;
    &:hover,
    &:focus {
      background-color: $navbar-default-toggle-hover-bg;
    }
    .icon-bar {
      background-color: $navbar-default-toggle-icon-bar-bg;
    }
  }

  .navbar-collapse,
  .navbar-form {
    border-color: $navbar-default-border;
  }

  // Dropdown menu items
  .navbar-nav {
    // Remove background color from open dropdown
    > .open > a {
      &,
      &:hover,
      &:focus {
        background-color: $navbar-default-link-active-bg;
        color: $navbar-default-link-active-color;
      }
    }

    @media (max-width: $grid-float-breakpoint-max) {
      // Dropdowns get custom display when collapsed
      .open .dropdown-menu {
        > li > a {
          color: $navbar-default-link-color;
          &:hover,
          &:focus {
            color: $navbar-default-link-hover-color;
            background-color: $navbar-default-link-hover-bg;
          }
        }
        > .active > a {
          &,
          &:hover,
          &:focus {
            color: $navbar-default-link-active-color;
            background-color: $navbar-default-link-active-bg;
          }
        }
        > .disabled > a {
          &,
          &:hover,
          &:focus {
            color: $navbar-default-link-disabled-color;
            background-color: $navbar-default-link-disabled-bg;
          }
        }
      }
    }
  }


  // Links in navbars
  //
  // Add a class to ensure links outside the navbar nav are colored correctly.

  .navbar-link {
    color: $navbar-default-link-color;
    &:hover {
      color: $navbar-default-link-hover-color;
    }
  }

  .btn-link {
    color: $navbar-default-link-color;
    &:hover,
    &:focus {
      color: $navbar-default-link-hover-color;
    }
    &[disabled],
    fieldset[disabled] & {
      &:hover,
      &:focus {
        color: $navbar-default-link-disabled-color;
      }
    }
  }
}

// Inverse navbar

.navbar-inverse {
  background-color: $navbar-inverse-bg;
  border-color: $navbar-inverse-border;

  .navbar-brand {
    color: $navbar-inverse-brand-color;
    &:hover,
    &:focus {
      color: $navbar-inverse-brand-hover-color;
      background-color: $navbar-inverse-brand-hover-bg;
    }
  }

  .navbar-text {
    color: $navbar-inverse-color;
  }

  .navbar-nav {
    > li > a {
      color: $navbar-inverse-link-color;

      &:hover,
      &:focus {
        color: $navbar-inverse-link-hover-color;
        background-color: $navbar-inverse-link-hover-bg;
      }
    }
    > .active > a {
      &,
      &:hover,
      &:focus {
        color: $navbar-inverse-link-active-color;
        background-color: $navbar-inverse-link-active-bg;
      }
    }
    > .disabled > a {
      &,
      &:hover,
      &:focus {
        color: $navbar-inverse-link-disabled-color;
        background-color: $navbar-inverse-link-disabled-bg;
      }
    }
  }

  // Darken the responsive nav toggle
  .navbar-toggle {
    border-color: $navbar-inverse-toggle-border-color;
    &:hover,
    &:focus {
      background-color: $navbar-inverse-toggle-hover-bg;
    }
    .icon-bar {
      background-color: $navbar-inverse-toggle-icon-bar-bg;
    }
  }

  .navbar-collapse,
  .navbar-form {
    border-color: darken($navbar-inverse-bg, 7%);
  }

  // Dropdowns
  .navbar-nav {
    > .open > a {
      &,
      &:hover,
      &:focus {
        background-color: $navbar-inverse-link-active-bg;
        color: $navbar-inverse-link-active-color;
      }
    }

    @media (max-width: $grid-float-breakpoint-max) {
      // Dropdowns get custom display
      .open .dropdown-menu {
        > .dropdown-header {
          border-color: $navbar-inverse-border;
        }
        .divider {
          background-color: $navbar-inverse-border;
        }
        > li > a {
          color: $navbar-inverse-link-color;
          &:hover,
          &:focus {
            color: $navbar-inverse-link-hover-color;
            background-color: $navbar-inverse-link-hover-bg;
          }
        }
        > .active > a {
          &,
          &:hover,
          &:focus {
            color: $navbar-inverse-link-active-color;
            background-color: $navbar-inverse-link-active-bg;
          }
        }
        > .disabled > a {
          &,
          &:hover,
          &:focus {
            color: $navbar-inverse-link-disabled-color;
            background-color: $navbar-inverse-link-disabled-bg;
          }
        }
      }
    }
  }

  .navbar-link {
    color: $navbar-inverse-link-color;
    &:hover {
      color: $navbar-inverse-link-hover-color;
    }
  }

  .btn-link {
    color: $navbar-inverse-link-color;
    &:hover,
    &:focus {
      color: $navbar-inverse-link-hover-color;
    }
    &[disabled],
    fieldset[disabled] & {
      &:hover,
      &:focus {
        color: $navbar-inverse-link-disabled-color;
      }
    }
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_navs.scss
================================================
//
// Navs
// --------------------------------------------------


// Base class
// --------------------------------------------------

.nav {
  margin-bottom: 0;
  padding-left: 0; // Override default ul/ol
  list-style: none;
  @include clearfix;

  > li {
    position: relative;
    display: block;

    > a {
      position: relative;
      display: block;
      padding: $nav-link-padding;
      &:hover,
      &:focus {
        text-decoration: none;
        background-color: $nav-link-hover-bg;
      }
    }

    // Disabled state sets text to gray and nukes hover/tab effects
    &.disabled > a {
      color: $nav-disabled-link-color;

      &:hover,
      &:focus {
        color: $nav-disabled-link-hover-color;
        text-decoration: none;
        background-color: transparent;
        cursor: $cursor-disabled;
      }
    }
  }

  // Open dropdowns
  .open > a {
    &,
    &:hover,
    &:focus {
      background-color: $nav-link-hover-bg;
      border-color: $link-color;
    }
  }

  // Nav dividers (deprecated with v3.0.1)
  //
  // This should have been removed in v3 with the dropping of `.nav-list`, but
  // we missed it. We don't currently support this anywhere, but in the interest
  // of maintaining backward compatibility in case you use it, it's deprecated.
  .nav-divider {
    @include nav-divider;
  }

  // Prevent IE8 from misplacing imgs
  //
  // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989
  > li > a > img {
    max-width: none;
  }
}


// Tabs
// -------------------------

// Give the tabs something to sit on
.nav-tabs {
  border-bottom: 1px solid $nav-tabs-border-color;
  > li {
    float: left;
    // Make the list-items overlay the bottom border
    margin-bottom: -1px;

    // Actual tabs (as links)
    > a {
      margin-right: 2px;
      line-height: $line-height-base;
      border: 1px solid transparent;
      border-radius: $border-radius-base $border-radius-base 0 0;
      &:hover {
        border-color: $nav-tabs-link-hover-border-color $nav-tabs-link-hover-border-color $nav-tabs-border-color;
      }
    }

    // Active state, and its :hover to override normal :hover
    &.active > a {
      &,
      &:hover,
      &:focus {
        color: $nav-tabs-active-link-hover-color;
        background-color: $nav-tabs-active-link-hover-bg;
        border: 1px solid $nav-tabs-active-link-hover-border-color;
        border-bottom-color: transparent;
        cursor: default;
      }
    }
  }
  // pulling this in mainly for less shorthand
  &.nav-justified {
    @extend .nav-justified;
    @extend .nav-tabs-justified;
  }
}


// Pills
// -------------------------
.nav-pills {
  > li {
    float: left;

    // Links rendered as pills
    > a {
      border-radius: $nav-pills-border-radius;
    }
    + li {
      margin-left: 2px;
    }

    // Active state
    &.active > a {
      &,
      &:hover,
      &:focus {
        color: $nav-pills-active-link-hover-color;
        background-color: $nav-pills-active-link-hover-bg;
      }
    }
  }
}


// Stacked pills
.nav-stacked {
  > li {
    float: none;
    + li {
      margin-top: 2px;
      margin-left: 0; // no need for this gap between nav items
    }
  }
}


// Nav variations
// --------------------------------------------------

// Justified nav links
// -------------------------

.nav-justified {
  width: 100%;

  > li {
    float: none;
    > a {
      text-align: center;
      margin-bottom: 5px;
    }
  }

  > .dropdown .dropdown-menu {
    top: auto;
    left: auto;
  }

  @media (min-width: $screen-sm-min) {
    > li {
      display: table-cell;
      width: 1%;
      > a {
        margin-bottom: 0;
      }
    }
  }
}

// Move borders to anchors instead of bottom of list
//
// Mixin for adding on top the shared `.nav-justified` styles for our tabs
.nav-tabs-justified {
  border-bottom: 0;

  > li > a {
    // Override margin from .nav-tabs
    margin-right: 0;
    border-radius: $border-radius-base;
  }

  > .active > a,
  > .active > a:hover,
  > .active > a:focus {
    border: 1px solid $nav-tabs-justified-link-border-color;
  }

  @media (min-width: $screen-sm-min) {
    > li > a {
      border-bottom: 1px solid $nav-tabs-justified-link-border-color;
      border-radius: $border-radius-base $border-radius-base 0 0;
    }
    > .active > a,
    > .active > a:hover,
    > .active > a:focus {
      border-bottom-color: $nav-tabs-justified-active-link-border-color;
    }
  }
}


// Tabbable tabs
// -------------------------

// Hide tabbable panes to start, show them when `.active`
.tab-content {
  > .tab-pane {
    display: none;
  }
  > .active {
    display: block;
  }
}


// Dropdowns
// -------------------------

// Specific dropdowns
.nav-tabs .dropdown-menu {
  // make dropdown border overlap tab border
  margin-top: -1px;
  // Remove the top rounded corners here since there is a hard edge above the menu
  @include border-top-radius(0);
}


================================================
FILE: client/src/style/vendor/bootstrap/_normalize.scss
================================================
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */

//
// 1. Set default font family to sans-serif.
// 2. Prevent iOS and IE text size adjust after device orientation change,
//    without disabling user zoom.
//

html {
  font-family: sans-serif; // 1
  -ms-text-size-adjust: 100%; // 2
  -webkit-text-size-adjust: 100%; // 2
}

//
// Remove default margin.
//

body {
  margin: 0;
}

// HTML5 display definitions
// ==========================================================================

//
// Correct `block` display not defined for any HTML5 element in IE 8/9.
// Correct `block` display not defined for `details` or `summary` in IE 10/11
// and Firefox.
// Correct `block` display not defined for `main` in IE 11.
//

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
  display: block;
}

//
// 1. Correct `inline-block` display not defined in IE 8/9.
// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
//

audio,
canvas,
progress,
video {
  display: inline-block; // 1
  vertical-align: baseline; // 2
}

//
// Prevent modern browsers from displaying `audio` without controls.
// Remove excess height in iOS 5 devices.
//

audio:not([controls]) {
  display: none;
  height: 0;
}

//
// Address `[hidden]` styling not present in IE 8/9/10.
// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
//

[hidden],
template {
  display: none;
}

// Links
// ==========================================================================

//
// Remove the gray background color from active links in IE 10.
//

a {
  background-color: transparent;
}

//
// Improve readability of focused elements when they are also in an
// active/hover state.
//

a:active,
a:hover {
  outline: 0;
}

// Text-level semantics
// ==========================================================================

//
// Address styling not present in IE 8/9/10/11, Safari, and Chrome.
//

abbr[title] {
  border-bottom: 1px dotted;
}

//
// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
//

b,
strong {
  font-weight: bold;
}

//
// Address styling not present in Safari and Chrome.
//

dfn {
  font-style: italic;
}

//
// Address variable `h1` font-size and margin within `section` and `article`
// contexts in Firefox 4+, Safari, and Chrome.
//

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

//
// Address styling not present in IE 8/9.
//

mark {
  background: #ff0;
  color: #000;
}

//
// Address inconsistent and variable font size in all browsers.
//

small {
  font-size: 80%;
}

//
// Prevent `sub` and `sup` affecting `line-height` in all browsers.
//

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sup {
  top: -0.5em;
}

sub {
  bottom: -0.25em;
}

// Embedded content
// ==========================================================================

//
// Remove border when inside `a` element in IE 8/9/10.
//

img {
  border: 0;
}

//
// Correct overflow not hidden in IE 9/10/11.
//

svg:not(:root) {
  overflow: hidden;
}

// Grouping content
// ==========================================================================

//
// Address margin not present in IE 8/9 and Safari.
//

figure {
  margin: 1em 40px;
}

//
// Address differences between Firefox and other browsers.
//

hr {
  box-sizing: content-box;
  height: 0;
}

//
// Contain overflow in all browsers.
//

pre {
  overflow: auto;
}

//
// Address odd `em`-unit font size rendering in all browsers.
//

code,
kbd,
pre,
samp {
  font-family: monospace, monospace;
  font-size: 1em;
}

// Forms
// ==========================================================================

//
// Known limitation: by default, Chrome and Safari on OS X allow very limited
// styling of `select`, unless a `border` property is set.
//

//
// 1. Correct color not being inherited.
//    Known issue: affects color of disabled elements.
// 2. Correct font properties not being inherited.
// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
//

button,
input,
optgroup,
select,
textarea {
  color: inherit; // 1
  font: inherit; // 2
  margin: 0; // 3
}

//
// Address `overflow` set to `hidden` in IE 8/9/10/11.
//

button {
  overflow: visible;
}

//
// Address inconsistent `text-transform` inheritance for `button` and `select`.
// All other form control elements do not inherit `text-transform` values.
// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
// Correct `select` style inheritance in Firefox.
//

button,
select {
  text-transform: none;
}

//
// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
//    and `video` controls.
// 2. Correct inability to style clickable `input` types in iOS.
// 3. Improve usability and consistency of cursor style between image-type
//    `input` and others.
//

button,
html input[type="button"], // 1
input[type="reset"],
input[type="submit"] {
  -webkit-appearance: button; // 2
  cursor: pointer; // 3
}

//
// Re-set default cursor for disabled elements.
//

button[disabled],
html input[disabled] {
  cursor: default;
}

//
// Remove inner padding and border in Firefox 4+.
//

button::-moz-focus-inner,
input::-moz-focus-inner {
  border: 0;
  padding: 0;
}

//
// Address Firefox 4+ setting `line-height` on `input` using `!important` in
// the UA stylesheet.
//

input {
  line-height: normal;
}

//
// It's recommended that you don't attempt to style these elements.
// Firefox's implementation doesn't respect box-sizing, padding, or width.
//
// 1. Address box sizing set to `content-box` in IE 8/9/10.
// 2. Remove excess padding in IE 8/9/10.
//

input[type="checkbox"],
input[type="radio"] {
  box-sizing: border-box; // 1
  padding: 0; // 2
}

//
// Fix the cursor style for Chrome's increment/decrement buttons. For certain
// `font-size` values of the `input`, it causes the cursor style of the
// decrement button to change from `default` to `text`.
//

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  height: auto;
}

//
// 1. Address `appearance` set to `searchfield` in Safari and Chrome.
// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.
//

input[type="search"] {
  -webkit-appearance: textfield; // 1
  box-sizing: content-box; //2
}

//
// Remove inner padding and search cancel button in Safari and Chrome on OS X.
// Safari (but not Chrome) clips the cancel button when the search input has
// padding (and `textfield` appearance).
//

input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}

//
// Define consistent border, margin, and padding.
//

fieldset {
  border: 1px solid #c0c0c0;
  margin: 0 2px;
  padding: 0.35em 0.625em 0.75em;
}

//
// 1. Correct `color` not being inherited in IE 8/9/10/11.
// 2. Remove padding so people aren't caught out if they zero out fieldsets.
//

legend {
  border: 0; // 1
  padding: 0; // 2
}

//
// Remove default vertical scrollbar in IE 8/9/10/11.
//

textarea {
  overflow: auto;
}

//
// Don't inherit the `font-weight` (applied by a rule above).
// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
//

optgroup {
  font-weight: bold;
}

// Tables
// ==========================================================================

//
// Remove most spacing between table cells.
//

table {
  border-collapse: collapse;
  border-spacing: 0;
}

td,
th {
  padding: 0;
}


================================================
FILE: client/src/style/vendor/bootstrap/_pager.scss
================================================
//
// Pager pagination
// --------------------------------------------------


.pager {
  padding-left: 0;
  margin: $line-height-computed 0;
  list-style: none;
  text-align: center;
  @include clearfix;
  li {
    display: inline;
    > a,
    > span {
      display: inline-block;
      padding: 5px 14px;
      background-color: $pager-bg;
      border: 1px solid $pager-border;
      border-radius: $pager-border-radius;
    }

    > a:hover,
    > a:focus {
      text-decoration: none;
      background-color: $pager-hover-bg;
    }
  }

  .next {
    > a,
    > span {
      float: right;
    }
  }

  .previous {
    > a,
    > span {
      float: left;
    }
  }

  .disabled {
    > a,
    > a:hover,
    > a:focus,
    > span {
      color: $pager-disabled-color;
      background-color: $pager-bg;
      cursor: $cursor-disabled;
    }
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_pagination.scss
================================================
//
// Pagination (multiple pages)
// --------------------------------------------------
.pagination {
  display: inline-block;
  padding-left: 0;
  margin: $line-height-computed 0;
  border-radius: $border-radius-base;

  > li {
    display: inline; // Remove list-style and block-level defaults
    > a,
    > span {
      position: relative;
      float: left; // Collapse white-space
      padding: $padding-base-vertical $padding-base-horizontal;
      line-height: $line-height-base;
      text-decoration: none;
      color: $pagination-color;
      background-color: $pagination-bg;
      border: 1px solid $pagination-border;
      margin-left: -1px;
    }
    &:first-child {
      > a,
      > span {
        margin-left: 0;
        @include border-left-radius($border-radius-base);
      }
    }
    &:last-child {
      > a,
      > span {
        @include border-right-radius($border-radius-base);
      }
    }
  }

  > li > a,
  > li > span {
    &:hover,
    &:focus {
      z-index: 2;
      color: $pagination-hover-color;
      background-color: $pagination-hover-bg;
      border-color: $pagination-hover-border;
    }
  }

  > .active > a,
  > .active > span {
    &,
    &:hover,
    &:focus {
      z-index: 3;
      color: $pagination-active-color;
      background-color: $pagination-active-bg;
      border-color: $pagination-active-border;
      cursor: default;
    }
  }

  > .disabled {
    > span,
    > span:hover,
    > span:focus,
    > a,
    > a:hover,
    > a:focus {
      color: $pagination-disabled-color;
      background-color: $pagination-disabled-bg;
      border-color: $pagination-disabled-border;
      cursor: $cursor-disabled;
    }
  }
}

// Sizing
// --------------------------------------------------

// Large
.pagination-lg {
  @include pagination-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $border-radius-large);
}

// Small
.pagination-sm {
  @include pagination-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $border-radius-small);
}


================================================
FILE: client/src/style/vendor/bootstrap/_panels.scss
================================================
//
// Panels
// --------------------------------------------------


// Base class
.panel {
  margin-bottom: $line-height-computed;
  background-color: $panel-bg;
  border: 1px solid transparent;
  border-radius: $panel-border-radius;
  @include box-shadow(0 1px 1px rgba(0,0,0,.05));
}

// Panel contents
.panel-body {
  padding: $panel-body-padding;
  @include clearfix;
}

// Optional heading
.panel-heading {
  padding: $panel-heading-padding;
  border-bottom: 1px solid transparent;
  @include border-top-radius(($panel-border-radius - 1));

  > .dropdown .dropdown-toggle {
    color: inherit;
  }
}

// Within heading, strip any `h*` tag of its default margins for spacing.
.panel-title {
  margin-top: 0;
  margin-bottom: 0;
  font-size: ceil(($font-size-base * 1.125));
  color: inherit;

  > a,
  > small,
  > .small,
  > small > a,
  > .small > a {
    color: inherit;
  }
}

// Optional footer (stays gray in every modifier class)
.panel-footer {
  padding: $panel-footer-padding;
  background-color: $panel-footer-bg;
  border-top: 1px solid $panel-inner-border;
  @include border-bottom-radius(($panel-border-radius - 1));
}


// List groups in panels
//
// By default, space out list group content from panel headings to account for
// any kind of custom content between the two.

.panel {
  > .list-group,
  > .panel-collapse > .list-group {
    margin-bottom: 0;

    .list-group-item {
      border-width: 1px 0;
      border-radius: 0;
    }

    // Add border top radius for first one
    &:first-child {
      .list-group-item:first-child {
        border-top: 0;
        @include border-top-radius(($panel-border-radius - 1));
      }
    }

    // Add border bottom radius for last one
    &:last-child {
      .list-group-item:last-child {
        border-bottom: 0;
        @include border-bottom-radius(($panel-border-radius - 1));
      }
    }
  }
  > .panel-heading + .panel-collapse > .list-group {
    .list-group-item:first-child {
      @include border-top-radius(0);
    }
  }
}
// Collapse space between when there's no additional content.
.panel-heading + .list-group {
  .list-group-item:first-child {
    border-top-width: 0;
  }
}
.list-group + .panel-footer {
  border-top-width: 0;
}

// Tables in panels
//
// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and
// watch it go full width.

.panel {
  > .table,
  > .table-responsive > .table,
  > .panel-collapse > .table {
    margin-bottom: 0;

    caption {
      padding-left: $panel-body-padding;
      padding-right: $panel-body-padding;
    }
  }
  // Add border top radius for first one
  > .table:first-child,
  > .table-responsive:first-child > .table:first-child {
    @include border-top-radius(($panel-border-radius - 1));

    > thead:first-child,
    > tbody:first-child {
      > tr:first-child {
        border-top-left-radius: ($panel-border-radius - 1);
        border-top-right-radius: ($panel-border-radius - 1);

        td:first-child,
        th:first-child {
          border-top-left-radius: ($panel-border-radius - 1);
        }
        td:last-child,
        th:last-child {
          border-top-right-radius: ($panel-border-radius - 1);
        }
      }
    }
  }
  // Add border bottom radius for last one
  > .table:last-child,
  > .table-responsive:last-child > .table:last-child {
    @include border-bottom-radius(($panel-border-radius - 1));

    > tbody:last-child,
    > tfoot:last-child {
      > tr:last-child {
        border-bottom-left-radius: ($panel-border-radius - 1);
        border-bottom-right-radius: ($panel-border-radius - 1);

        td:first-child,
        th:first-child {
          border-bottom-left-radius: ($panel-border-radius - 1);
        }
        td:last-child,
        th:last-child {
          border-bottom-right-radius: ($panel-border-radius - 1);
        }
      }
    }
  }
  > .panel-body + .table,
  > .panel-body + .table-responsive,
  > .table + .panel-body,
  > .table-responsive + .panel-body {
    border-top: 1px solid $table-border-color;
  }
  > .table > tbody:first-child > tr:first-child th,
  > .table > tbody:first-child > tr:first-child td {
    border-top: 0;
  }
  > .table-bordered,
  > .table-responsive > .table-bordered {
    border: 0;
    > thead,
    > tbody,
    > tfoot {
      > tr {
        > th:first-child,
        > td:first-child {
          border-left: 0;
        }
        > th:last-child,
        > td:last-child {
          border-right: 0;
        }
      }
    }
    > thead,
    > tbody {
      > tr:first-child {
        > td,
        > th {
          border-bottom: 0;
        }
      }
    }
    > tbody,
    > tfoot {
      > tr:last-child {
        > td,
        > th {
          border-bottom: 0;
        }
      }
    }
  }
  > .table-responsive {
    border: 0;
    margin-bottom: 0;
  }
}


// Collapsable panels (aka, accordion)
//
// Wrap a series of panels in `.panel-group` to turn them into an accordion with
// the help of our collapse JavaScript plugin.

.panel-group {
  margin-bottom: $line-height-computed;

  // Tighten up margin so it's only between panels
  .panel {
    margin-bottom: 0;
    border-radius: $panel-border-radius;

    + .panel {
      margin-top: 5px;
    }
  }

  .panel-heading {
    border-bottom: 0;

    + .panel-collapse > .panel-body,
    + .panel-collapse > .list-group {
      border-top: 1px solid $panel-inner-border;
    }
  }

  .panel-footer {
    border-top: 0;
    + .panel-collapse .panel-body {
      border-bottom: 1px solid $panel-inner-border;
    }
  }
}


// Contextual variations
.panel-default {
  @include panel-variant($panel-default-border, $panel-default-text, $panel-default-heading-bg, $panel-default-border);
}
.panel-primary {
  @include panel-variant($panel-primary-border, $panel-primary-text, $panel-primary-heading-bg, $panel-primary-border);
}
.panel-success {
  @include panel-variant($panel-success-border, $panel-success-text, $panel-success-heading-bg, $panel-success-border);
}
.panel-info {
  @include panel-variant($panel-info-border, $panel-info-text, $panel-info-heading-bg, $panel-info-border);
}
.panel-warning {
  @include panel-variant($panel-warning-border, $panel-warning-text, $panel-warning-heading-bg, $panel-warning-border);
}
.panel-danger {
  @include panel-variant($panel-danger-border, $panel-danger-text, $panel-danger-heading-bg, $panel-danger-border);
}


================================================
FILE: client/src/style/vendor/bootstrap/_popovers.scss
================================================
//
// Popovers
// --------------------------------------------------


.popover {
  position: absolute;
  top: 0;
  left: 0;
  z-index: $zindex-popover;
  display: none;
  max-width: $popover-max-width;
  padding: 1px;
  // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element.
  // So reset our font and text properties to avoid inheriting weird values.
  @include reset-text;
  font-size: $font-size-base;

  background-color: $popover-bg;
  background-clip: padding-box;
  border: 1px solid $popover-fallback-border-color;
  border: 1px solid $popover-border-color;
  border-radius: $border-radius-large;
  @include box-shadow(0 5px 10px rgba(0,0,0,.2));

  // Offset the popover to account for the popover arrow
  &.top     { margin-top: -$popover-arrow-width; }
  &.right   { margin-left: $popover-arrow-width; }
  &.bottom  { margin-top: $popover-arrow-width; }
  &.left    { margin-left: -$popover-arrow-width; }
}

.popover-title {
  margin: 0; // reset heading margin
  padding: 8px 14px;
  font-size: $font-size-base;
  background-color: $popover-title-bg;
  border-bottom: 1px solid darken($popover-title-bg, 5%);
  border-radius: ($border-radius-large - 1) ($border-radius-large - 1) 0 0;
}

.popover-content {
  padding: 9px 14px;
}

// Arrows
//
// .arrow is outer, .arrow:after is inner

.popover > .arrow {
  &,
  &:after {
    position: absolute;
    display: block;
    width: 0;
    height: 0;
    border-color: transparent;
    border-style: solid;
  }
}
.popover > .arrow {
  border-width: $popover-arrow-outer-width;
}
.popover > .arrow:after {
  border-width: $popover-arrow-width;
  content: "";
}

.popover {
  &.top > .arrow {
    left: 50%;
    margin-left: -$popover-arrow-outer-width;
    border-bottom-width: 0;
    border-top-color: $popover-arrow-outer-fallback-color; // IE8 fallback
    border-top-color: $popover-arrow-outer-color;
    bottom: -$popover-arrow-outer-width;
    &:after {
      content: " ";
      bottom: 1px;
      margin-left: -$popover-arrow-width;
      border-bottom-width: 0;
      border-top-color: $popover-arrow-color;
    }
  }
  &.right > .arrow {
    top: 50%;
    left: -$popover-arrow-outer-width;
    margin-top: -$popover-arrow-outer-width;
    border-left-width: 0;
    border-right-color: $popover-arrow-outer-fallback-color; // IE8 fallback
    border-right-color: $popover-arrow-outer-color;
    &:after {
      content: " ";
      left: 1px;
      bottom: -$popover-arrow-width;
      border-left-width: 0;
      border-right-color: $popover-arrow-color;
    }
  }
  &.bottom > .arrow {
    left: 50%;
    margin-left: -$popover-arrow-outer-width;
    border-top-width: 0;
    border-bottom-color: $popover-arrow-outer-fallback-color; // IE8 fallback
    border-bottom-color: $popover-arrow-outer-color;
    top: -$popover-arrow-outer-width;
    &:after {
      content: " ";
      top: 1px;
      margin-left: -$popover-arrow-width;
      border-top-width: 0;
      border-bottom-color: $popover-arrow-color;
    }
  }

  &.left > .arrow {
    top: 50%;
    right: -$popover-arrow-outer-width;
    margin-top: -$popover-arrow-outer-width;
    border-right-width: 0;
    border-left-color: $popover-arrow-outer-fallback-color; // IE8 fallback
    border-left-color: $popover-arrow-outer-color;
    &:after {
      content: " ";
      right: 1px;
      border-right-width: 0;
      border-left-color: $popover-arrow-color;
      bottom: -$popover-arrow-width;
    }
  }
}


================================================
FILE: client/src/style/vendor/bootstrap/_pr
Download .txt
gitextract_uwmvxg_y/

├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .flowconfig
├── .gitignore
├── LICENSE
├── README.md
├── client/
│   ├── client-manifest.json
│   ├── gulpCompressionOptions.js
│   └── src/
│       ├── Layout.js
│       ├── __tests__/
│       │   └── ok.js
│       ├── actions/
│       │   └── AppActions.js
│       ├── alt.js
│       ├── components/
│       │   ├── AddNewArticleForm.js
│       │   ├── LoginForm.js
│       │   ├── ResetPasswordForm.js
│       │   ├── ResetRequestForm.js
│       │   ├── SignupForm.js
│       │   ├── index.js
│       │   └── partials/
│       │       ├── Elements.js
│       │       ├── FormErrors.js
│       │       └── index.js
│       ├── containers/
│       │   ├── AddNewArticle.js
│       │   ├── Article.js
│       │   ├── ArticleList.js
│       │   ├── Dashboard.js
│       │   ├── Home.js
│       │   ├── Login.js
│       │   ├── NoMatch.js
│       │   ├── Page.js
│       │   ├── ResetPassword.js
│       │   ├── ResetRequest.js
│       │   ├── SignUp.js
│       │   ├── Tag.js
│       │   ├── TagList.js
│       │   ├── User.js
│       │   └── index.js
│       ├── main.js
│       ├── queries/
│       │   ├── ViewerQueries.js
│       │   └── index.js
│       ├── stores/
│       │   └── AppStore.js
│       └── style/
│           ├── base/
│           │   ├── _transitions.scss
│           │   └── _variables.scss
│           ├── main.scss
│           ├── objects/
│           │   └── _buttons.scss
│           └── vendor/
│               ├── _bootstrap.scss
│               └── bootstrap/
│                   ├── _alerts.scss
│                   ├── _badges.scss
│                   ├── _breadcrumbs.scss
│                   ├── _button-groups.scss
│                   ├── _buttons.scss
│                   ├── _carousel.scss
│                   ├── _close.scss
│                   ├── _code.scss
│                   ├── _component-animations.scss
│                   ├── _dropdowns.scss
│                   ├── _forms.scss
│                   ├── _glyphicons.scss
│                   ├── _grid.scss
│                   ├── _input-groups.scss
│                   ├── _jumbotron.scss
│                   ├── _labels.scss
│                   ├── _list-group.scss
│                   ├── _media.scss
│                   ├── _mixins.scss
│                   ├── _modals.scss
│                   ├── _navbar.scss
│                   ├── _navs.scss
│                   ├── _normalize.scss
│                   ├── _pager.scss
│                   ├── _pagination.scss
│                   ├── _panels.scss
│                   ├── _popovers.scss
│                   ├── _print.scss
│                   ├── _progress-bars.scss
│                   ├── _responsive-embed.scss
│                   ├── _responsive-utilities.scss
│                   ├── _scaffolding.scss
│                   ├── _tables.scss
│                   ├── _theme.scss
│                   ├── _thumbnails.scss
│                   ├── _tooltip.scss
│                   ├── _type.scss
│                   ├── _utilities.scss
│                   ├── _variables.scss
│                   ├── _wells.scss
│                   └── mixins/
│                       ├── _alerts.scss
│                       ├── _background-variant.scss
│                       ├── _border-radius.scss
│                       ├── _buttons.scss
│                       ├── _center-block.scss
│                       ├── _clearfix.scss
│                       ├── _forms.scss
│                       ├── _gradients.scss
│                       ├── _grid-framework.scss
│                       ├── _grid.scss
│                       ├── _hide-text.scss
│                       ├── _image.scss
│                       ├── _labels.scss
│                       ├── _list-group.scss
│                       ├── _nav-divider.scss
│                       ├── _nav-vertical-align.scss
│                       ├── _opacity.scss
│                       ├── _pagination.scss
│                       ├── _panels.scss
│                       ├── _progress-bar.scss
│                       ├── _reset-filter.scss
│                       ├── _reset-text.scss
│                       ├── _resize.scss
│                       ├── _responsive-visibility.scss
│                       ├── _size.scss
│                       ├── _tab-focus.scss
│                       ├── _table-row.scss
│                       ├── _text-emphasis.scss
│                       ├── _text-overflow.scss
│                       └── _vendor-prefixes.scss
├── data/
│   ├── schema.graphql
│   └── schema.json
├── ecosystem.json
├── gulpfile.js
├── mediakit/
│   └── reactathon.ai
├── package.json
├── scripts/
│   ├── babelRelayPlugin.js
│   ├── mocha-bootload.js
│   ├── seed.js
│   ├── server.js
│   └── updateSchema.js
├── server/
│   └── src/
│       ├── __tests__/
│       │   └── testModules.js
│       ├── app.config.js
│       ├── app.js
│       ├── auth/
│       │   ├── index.js
│       │   ├── modules.js
│       │   └── passport.js
│       ├── database/
│       │   ├── index.js
│       │   ├── migrations/
│       │   │   └── .gitkeep
│       │   ├── models/
│       │   │   ├── Article.js
│       │   │   ├── Comment.js
│       │   │   ├── Flag.js
│       │   │   ├── Tag.js
│       │   │   ├── TagItem.js
│       │   │   ├── Token.js
│       │   │   ├── User.js
│       │   │   ├── Vote.js
│       │   │   ├── customTypes/
│       │   │   │   ├── URL.js
│       │   │   │   ├── email.js
│       │   │   │   └── index.js
│       │   │   └── index.js
│       │   ├── modules.js
│       │   └── seeders/
│       │       └── .gitkeep
│       ├── modules.js
│       ├── pages/
│       │   └── about.md
│       ├── public/
│       │   ├── browserconfig.xml
│       │   ├── img/
│       │   │   └── .gitkeep
│       │   └── manifest.json
│       ├── routes/
│       │   ├── api.js
│       │   ├── auth.js
│       │   ├── index.js
│       │   ├── modules.js
│       │   └── root.js
│       ├── schema/
│       │   └── index.js
│       ├── utils/
│       │   ├── fromGravatar.js
│       │   ├── getGravatar.js
│       │   ├── index.js
│       │   ├── logger.js
│       │   └── modules.js
│       └── views/
│           ├── error.hbs
│           ├── index.hbs
│           ├── layout.hbs
│           └── root.hbs
├── ssl/
│   ├── localhost.cert
│   └── localhost.key
└── tasks/
    ├── bundle.js
    ├── bundledebugdeps.js
    ├── bundledeps.js
    ├── bundlemin.js
    ├── helpers.js
    └── sass.js
Download .txt
SYMBOL INDEX (120 symbols across 24 files)

FILE: client/src/Layout.js
  class Layout (line 21) | class Layout extends React.Component {
    method constructor (line 23) | constructor() {
    method componentDidMount (line 31) | componentDidMount() {
    method componentWillUnmount (line 35) | componentWillUnmount() {
    method onChange (line 42) | onChange(state) {
    method render (line 49) | render() {

FILE: client/src/actions/AppActions.js
  class AppActionsSpec (line 4) | class AppActionsSpec {
    method constructor (line 5) | constructor() {
    method logout (line 37) | logout() {
    method login (line 65) | login({username, password}) {
    method addArticle (line 100) | addArticle({title, content}) {
    method signup (line 135) | signup({username, password, email}) {
    method toast (line 171) | toast(options) {

FILE: client/src/components/AddNewArticleForm.js
  class AddNewArticleForm (line 12) | class AddNewArticleForm extends React.Component {
    method constructor (line 14) | constructor() {
    method componentDidMount (line 23) | componentDidMount() {
    method componentWillUnmount (line 26) | componentWillUnmount() {
    method onChange (line 29) | onChange(state) {
    method render (line 106) | render() {

FILE: client/src/components/LoginForm.js
  class LoginForm (line 14) | class LoginForm extends React.Component {
    method constructor (line 16) | constructor() {
    method componentDidMount (line 25) | componentDidMount() {
    method componentWillUnmount (line 28) | componentWillUnmount() {
    method onChange (line 31) | onChange(state) {
    method render (line 117) | render() {

FILE: client/src/components/ResetPasswordForm.js
  class ResetPasswordForm (line 11) | class ResetPasswordForm extends React.Component {
    method constructor (line 13) | constructor() {
    method render (line 103) | render() {

FILE: client/src/components/ResetRequestForm.js
  class ResetRequestForm (line 10) | class ResetRequestForm extends React.Component {
    method constructor (line 12) | constructor() {
    method render (line 45) | render() {

FILE: client/src/components/SignupForm.js
  class SignupForm (line 14) | class SignupForm extends React.Component {
    method constructor (line 16) | constructor() {
    method componentDidMount (line 26) | componentDidMount() {
    method componentWillUnmount (line 29) | componentWillUnmount() {
    method onChange (line 32) | onChange(state) {
    method render (line 124) | render() {

FILE: client/src/containers/Article.js
  class ArticleComponent (line 6) | class ArticleComponent extends React.Component {
    method render (line 8) | render() {

FILE: client/src/containers/ArticleList.js
  class ArticleListComponent (line 24) | class ArticleListComponent extends React.Component {
    method render (line 37) | render() {

FILE: client/src/containers/Dashboard.js
  class DashboardComponent (line 40) | class DashboardComponent extends React.Component {
    method constructor (line 41) | constructor(props) {
    method render (line 68) | render() {

FILE: client/src/containers/Page.js
  class Page (line 5) | class Page extends React.Component {
    method constructor (line 6) | constructor(props) {
    method render (line 23) | render() {

FILE: client/src/containers/User.js
  class UserComponent (line 16) | class UserComponent extends React.Component {
    method constructor (line 17) | constructor(props) {
    method render (line 23) | render() {

FILE: client/src/main.js
  class Master (line 63) | class Master extends React.Component {
    method render (line 65) | render() {

FILE: client/src/stores/AppStore.js
  class AppStoreSpec (line 5) | class AppStoreSpec {
    method constructor (line 6) | constructor() {
    method onShowSignupModal (line 17) | onShowSignupModal() {
    method onHideSignupModal (line 21) | onHideSignupModal() {
    method onShowLoginModal (line 25) | onShowLoginModal() {
    method onHideLoginModal (line 29) | onHideLoginModal() {
    method onSignupSuccess (line 38) | onSignupSuccess(user) {
    method onSignupFail (line 45) | onSignupFail() {
    method onLoginSuccess (line 56) | onLoginSuccess(user) {
    method onLoginFail (line 62) | onLoginFail() {
    method onAddArticleSuccess (line 67) | onAddArticleSuccess() {
    method onAddArticleFail (line 70) | onAddArticleFail() {
    method onLogoutSuccess (line 78) | onLogoutSuccess() {
    method onLogoutFail (line 84) | onLogoutFail() {
    method onPushQueue (line 88) | onPushQueue(options) {
    method onShiftQueue (line 92) | onShiftQueue() {

FILE: scripts/server.js
  function exec (line 30) | function exec(command, options) {
  function startWatch (line 85) | function startWatch() {
  function changeFile (line 116) | function changeFile(filepath, root, stat) {
  function logTask (line 125) | function logTask(str) {
  function logError (line 129) | function logError(msg) {
  function logWaiting (line 140) | function logWaiting() {
  function deleteFile (line 144) | function deleteFile(filepath) {
  function debouncedCheck (line 149) | function debouncedCheck() {
  function guardedCheck (line 156) | function guardedCheck() {
  function checkFiles (line 170) | function checkFiles(filepaths) {
  function syncBrowser (line 190) | function syncBrowser() {
  function respawnServer (line 204) | function respawnServer() {
  function updateSchema (line 230) | function updateSchema() {
  function copyFiles (line 242) | function copyFiles() {
  function bundleClient (line 253) | function bundleClient(filepaths) {
  function buildStyles (line 272) | function buildStyles(filepaths) {
  function rebuildServer (line 289) | function rebuildServer(filepaths) {
  function parseFiles (line 320) | function parseFiles(filepaths) {
  function runTests (line 338) | function runTests(filepaths) {
  function lintFiles (line 358) | function lintFiles(filepaths) {
  function typecheckStatus (line 383) | function typecheckStatus() {
  function srcPath (line 395) | function srcPath(filepath) {
  function isJS (line 402) | function isJS(filepath) {
  function isScss (line 406) | function isScss(filepath) {
  function inClient (line 410) | function inClient(filepath) {
  function inServer (line 414) | function inServer(filepath) {
  function allTests (line 418) | function allTests(filepaths) {
  function isTest (line 422) | function isTest(filepath) {
  function invert (line 431) | function invert(str) {

FILE: server/src/auth/passport.js
  function isAuthenticated (line 344) | function isAuthenticated(req, res, next) {
  function isAuthorized (line 350) | function isAuthorized(req, res, next) {
  function login (line 386) | function login() {
  function createUser (line 409) | function createUser({username, password, email}) {
  function signUp (line 425) | function signUp() {
  function forgot (line 460) | function forgot() {
  function handleReset (line 510) | function handleReset() {

FILE: server/src/database/models/Article.js
  method get (line 7) | get() {
  method get (line 18) | get() {
  method get (line 36) | get() {
  method get (line 52) | get() {

FILE: server/src/database/models/Comment.js
  method get (line 7) | get() {
  method get (line 18) | get() {
  method get (line 36) | get() {
  method get (line 52) | get() {

FILE: server/src/database/models/Flag.js
  method get (line 7) | get() {

FILE: server/src/database/models/Tag.js
  method get (line 5) | get() {

FILE: server/src/database/models/Token.js
  method get (line 5) | get() {

FILE: server/src/database/models/User.js
  method get (line 6) | get() {

FILE: server/src/database/models/Vote.js
  method get (line 5) | get() {

FILE: server/src/schema/index.js
  method resolve (line 300) | resolve(user) {
  method resolve (line 306) | resolve(user) {
  method resolve (line 313) | resolve(user) {
Condensed preview — 178 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,491K chars).
[
  {
    "path": ".babelrc",
    "chars": 121,
    "preview": "{\n  \"presets\": [\"es2015\", \"stage-0\", \"react\"],\n  \"plugins\": [\"transform-flow-strip-types\", \"babel-relay-plugin-loader\"]\n"
  },
  {
    "path": ".editorconfig",
    "chars": 252,
    "preview": "; http://editorconfig.org\n\nroot = true\n\n[*.js]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntri"
  },
  {
    "path": ".eslintignore",
    "chars": 39,
    "preview": "./flow/**/*\n./tasks/**/*\n./scripts/**/*"
  },
  {
    "path": ".eslintrc",
    "chars": 6246,
    "preview": "{\n  \"parser\": \"babel-eslint\",\n  \"parserOptions\": {\n    \"ecmaFeatures\": {\n      \"jsx\": true\n    }\n  },\n  \"plugins\": [\n   "
  },
  {
    "path": ".flowconfig",
    "chars": 116,
    "preview": "[ignore]\n.*/coverage/.*\n.*/scripts/.*\n.*/node_modules/.*\n.*/public/.*\n.*/dist/.*\n\n[include]\n\n[libs]\nflow\n\n[options]\n"
  },
  {
    "path": ".gitignore",
    "chars": 6950,
    "preview": "# Created by .ignore support plugin (hsz.mobi)\n### Emacs template\n# -*- mode: gitignore; -*-\n\n\\#*\\#\n/.emacs.desktop\n/.em"
  },
  {
    "path": "LICENSE",
    "chars": 1276,
    "preview": "The MIT License (MIT)\n\nReactathon\nCopyright (c) 2016 Matt McFarland\n\nSome code heavily borrowed from hackathon-started b"
  },
  {
    "path": "README.md",
    "chars": 3281,
    "preview": "# DEPRECATED\nThis project has been superceded by the much more up-to-date, user-friendly, [react-create-app](https://git"
  },
  {
    "path": "client/client-manifest.json",
    "chars": 507,
    "preview": "{\n  \"dependencies\": {\n    \"alt\": \"0.17.9\",\n    \"classnames\": \"^2.2.1\",\n    \"highlight.js\": \"^9.0.0\",\n    \"history\": \"^1."
  },
  {
    "path": "client/gulpCompressionOptions.js",
    "chars": 1165,
    "preview": "module.exports = {\n  sequences: true,      // join consecutive statemets with the “comma operator”\n  properties: true,  "
  },
  {
    "path": "client/src/Layout.js",
    "chars": 5109,
    "preview": "import React from 'react';\nimport { Link } from 'react-router';\nimport {\n  Navbar,\n  Nav,\n  MenuItem,\n  Modal,\n  Button,"
  },
  {
    "path": "client/src/__tests__/ok.js",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "client/src/actions/AppActions.js",
    "chars": 4636,
    "preview": "import alt from '../alt';\nimport ajax from 'superagent';\n\nclass AppActionsSpec {\n  constructor() {\n    this.generateActi"
  },
  {
    "path": "client/src/alt.js",
    "chars": 67,
    "preview": "import Alt from 'alt';\n\nvar alt = new Alt();\n\n\nexport default alt;\n"
  },
  {
    "path": "client/src/components/AddNewArticleForm.js",
    "chars": 3161,
    "preview": "import React from 'react';\nimport { FormErrors } from './partials';\nimport {\n  Button,\n  Input,\n  ButtonInput\n} from 're"
  },
  {
    "path": "client/src/components/LoginForm.js",
    "chars": 3920,
    "preview": "import React from 'react';\nimport { Link } from 'react-router';\nimport { FormErrors } from './partials';\nimport { Center"
  },
  {
    "path": "client/src/components/ResetPasswordForm.js",
    "chars": 3436,
    "preview": "import React from 'react';\nimport ajax from 'superagent';\nimport { Link } from 'react-router';\nimport { FormErrors } fro"
  },
  {
    "path": "client/src/components/ResetRequestForm.js",
    "chars": 2033,
    "preview": "import React from 'react';\nimport ajax from 'superagent';\nimport { Link } from 'react-router';\n\nimport {\n  Input,\n  Butt"
  },
  {
    "path": "client/src/components/SignupForm.js",
    "chars": 3924,
    "preview": "import React from 'react';\nimport validator from 'validator';\nimport { FormErrors } from './partials';\n\nimport {\n  Butto"
  },
  {
    "path": "client/src/components/index.js",
    "chars": 253,
    "preview": "export { LoginForm } from './LoginForm';\nexport { SignupForm } from './SignupForm';\nexport { ResetRequestForm } from './"
  },
  {
    "path": "client/src/components/partials/Elements.js",
    "chars": 2837,
    "preview": "import React from 'react';\nimport { Collapse, Button } from 'react-bootstrap';\n\nconst performRedirect = (path) => (\n  wi"
  },
  {
    "path": "client/src/components/partials/FormErrors.js",
    "chars": 301,
    "preview": "import React from 'react';\nimport { Alert } from './Elements';\n\nconst ErrorItem = ({msg}) => (\n  <div>{msg}</div>\n);\n\n\ne"
  },
  {
    "path": "client/src/components/partials/index.js",
    "chars": 82,
    "preview": "export { FormErrors } from './FormErrors';\nexport { Elements } from './Elements';\n"
  },
  {
    "path": "client/src/containers/AddNewArticle.js",
    "chars": 463,
    "preview": "import React from 'react';\nimport { AddNewArticleForm } from '../components';\nexport const AddNewArticle = () => (\n  <se"
  },
  {
    "path": "client/src/containers/Article.js",
    "chars": 778,
    "preview": "import React from 'react';\nimport Relay from 'react-relay';\nimport moment from 'moment';\n\n\nclass ArticleComponent extend"
  },
  {
    "path": "client/src/containers/ArticleList.js",
    "chars": 1625,
    "preview": "import React from 'react';\nimport Relay from 'react-relay';\nimport { Link } from 'react-router';\nimport moment from 'mom"
  },
  {
    "path": "client/src/containers/Dashboard.js",
    "chars": 4242,
    "preview": "import React from 'react';\nimport Relay from 'react-relay';\nimport moment from 'moment';\n\nimport {\n  Col,\n  Row,\n  // Pa"
  },
  {
    "path": "client/src/containers/Home.js",
    "chars": 230,
    "preview": "import React from 'react';\nimport { Logo, Center } from '../components/partials/Elements';\nexport const Home = () => (\n "
  },
  {
    "path": "client/src/containers/Login.js",
    "chars": 439,
    "preview": "import React from 'react';\nimport { LoginForm } from '../components';\nexport const Login = () => (\n  <section>\n    <div\n"
  },
  {
    "path": "client/src/containers/NoMatch.js",
    "chars": 163,
    "preview": "import React from 'react';\n\nexport const NoMatch = () => (\n  <article>\n    <h3>Not Found</h3>\n    <p>Sorry, the page req"
  },
  {
    "path": "client/src/containers/Page.js",
    "chars": 881,
    "preview": "import React from 'react';\nimport ajax from 'superagent';\nimport marked from 'marked';\n\nexport class Page extends React."
  },
  {
    "path": "client/src/containers/ResetPassword.js",
    "chars": 463,
    "preview": "import React from 'react';\nimport { ResetPasswordForm } from '../components';\nexport const ResetPassword = () => (\n  <se"
  },
  {
    "path": "client/src/containers/ResetRequest.js",
    "chars": 460,
    "preview": "import React from 'react';\nimport { ResetRequestForm } from '../components';\nexport const ResetRequest = () => (\n  <sect"
  },
  {
    "path": "client/src/containers/SignUp.js",
    "chars": 442,
    "preview": "import React from 'react';\nimport { SignupForm } from '../components';\nexport const SignUp = () => (\n  <section>\n    <di"
  },
  {
    "path": "client/src/containers/Tag.js",
    "chars": 113,
    "preview": "import React from 'react';\n\nexport const Tag = () => (\n  <section>\n    <h1>TODO: Update me</h1>\n  </section>\n);\n\n"
  },
  {
    "path": "client/src/containers/TagList.js",
    "chars": 117,
    "preview": "import React from 'react';\n\nexport const TagList = () => (\n  <section>\n    <h1>TODO: Update me</h1>\n  </section>\n);\n\n"
  },
  {
    "path": "client/src/containers/User.js",
    "chars": 954,
    "preview": "import React from 'react';\nimport Relay from 'react-relay';\nimport { Col, Row } from 'react-bootstrap';\n\nconst ProfilePi"
  },
  {
    "path": "client/src/containers/index.js",
    "chars": 533,
    "preview": "export { Home } from './Home';\nexport { Article } from './Article';\nexport { ArticleList } from './ArticleList';\nexport "
  },
  {
    "path": "client/src/main.js",
    "chars": 2210,
    "preview": "/*\n *  React\n */\nimport React from 'react';\nimport { render } from 'react-dom';\n\n/*\n *  React-Router\n */\nimport {\n  brow"
  },
  {
    "path": "client/src/queries/ViewerQueries.js",
    "chars": 97,
    "preview": "import Relay from 'react-relay';\n\nexport default {\n  viewer: () => Relay.QL`query { viewer }`\n};\n"
  },
  {
    "path": "client/src/queries/index.js",
    "chars": 49,
    "preview": "export { ViewerQueries } from './ViewerQueries';\n"
  },
  {
    "path": "client/src/stores/AppStore.js",
    "chars": 2090,
    "preview": "import alt from '../alt';\nimport { AppActions } from '../actions/AppActions';\n\n\nclass AppStoreSpec {\n  constructor() {\n "
  },
  {
    "path": "client/src/style/base/_transitions.scss",
    "chars": 331,
    "preview": "$page-trans-time: 0.3s;\n$page-trans-easing: ease-in-out;\n\n.page-transition {\n  &-enter, &-leave {\n    transition: opacit"
  },
  {
    "path": "client/src/style/base/_variables.scss",
    "chars": 169,
    "preview": "\n$twitterBlue: #00aced;\n$facebookBlue: #335795;\n$googleRed: #DD4B39;\n$redditBlue: #99BEEB;\n$githubBlack: #333;\n$page-tra"
  },
  {
    "path": "client/src/style/main.scss",
    "chars": 118,
    "preview": "@import './vendor/bootstrap';\n\n@import './base/variables';\n@import './base/transitions';\n@import './objects/buttons';\n"
  },
  {
    "path": "client/src/style/objects/_buttons.scss",
    "chars": 1100,
    "preview": ".btn .fa.fix-left {\n  float: left;\n  height: 1em;\n  font-size: 26px;\n  border-right: thin ridge rgba(255, 255, 255, 0.3)"
  },
  {
    "path": "client/src/style/vendor/_bootstrap.scss",
    "chars": 1486,
    "preview": "/*!\n * Bootstrap v3.3.6 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://gi"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_alerts.scss",
    "chars": 1550,
    "preview": "//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_badges.scss",
    "chars": 1228,
    "preview": "//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n  display: inline-block;\n  m"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_breadcrumbs.scss",
    "chars": 700,
    "preview": "//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n  padding: $breadcrumb-padding-v"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_button-groups.scss",
    "chars": 5744,
    "preview": "//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-gro"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_buttons.scss",
    "chars": 3819,
    "preview": "//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_carousel.scss",
    "chars": 5725,
    "preview": "//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_close.scss",
    "chars": 815,
    "preview": "//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n  float: right;\n  font-size: ($font-s"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_code.scss",
    "chars": 1401,
    "preview": "//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\nco"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_component-animations.scss",
    "chars": 819,
    "preview": "//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `."
  },
  {
    "path": "client/src/style/vendor/bootstrap/_dropdowns.scss",
    "chars": 4889,
    "preview": "//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n  display:"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_forms.scss",
    "chars": 16176,
    "preview": "//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_glyphicons.scss",
    "chars": 20448,
    "preview": "//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus a"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_grid.scss",
    "chars": 1443,
    "preview": "//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container wi"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_input-groups.scss",
    "chars": 4317,
    "preview": "//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.i"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_jumbotron.scss",
    "chars": 1152,
    "preview": "//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n  padding-top:    $jumbotron-paddin"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_labels.scss",
    "chars": 1156,
    "preview": "//\n// Labels\n// --------------------------------------------------\n\n.label {\n  display: inline;\n  padding: .2em .6em .3e"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_list-group.scss",
    "chars": 3172,
    "preview": "//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on <ul>, <ol"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_media.scss",
    "chars": 900,
    "preview": ".media {\n  // Proper spacing between instances of .media\n  margin-top: 15px;\n\n  &:first-child {\n    margin-top: 0;\n  }\n}"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_mixins.scss",
    "chars": 986,
    "preview": "// Mixins\n// --------------------------------------------------\n\n// Utilities\n@import \"mixins/hide-text\";\n@import \"mixin"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_modals.scss",
    "chars": 3568,
    "preview": "//\n// Modals\n// --------------------------------------------------\n\n// .modal-open      - body class for killing the scr"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_navbar.scss",
    "chars": 14729,
    "preview": "//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static n"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_navs.scss",
    "chars": 4950,
    "preview": "//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// ------------------------------------"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_normalize.scss",
    "chars": 7559,
    "preview": "/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-s"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_pager.scss",
    "chars": 855,
    "preview": "//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n  padding-left: 0;\n  margin: $li"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_pagination.scss",
    "chars": 2091,
    "preview": "//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n  display: inline-"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_panels.scss",
    "chars": 6385,
    "preview": "//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n  margin-bottom: $line-heigh"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_popovers.scss",
    "chars": 3502,
    "preview": "//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n  position: absolute;\n  top: 0;\n  left"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_print.scss",
    "chars": 1939,
    "preview": "/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// =============================="
  },
  {
    "path": "client/src/style/vendor/bootstrap/_progress-bars.scss",
    "chars": 1992,
    "preview": "//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -----------------------"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_responsive-embed.scss",
    "chars": 546,
    "preview": "// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n  position: relative;\n  display:"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_responsive-utilities.scss",
    "chars": 4409,
    "preview": "//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n/"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_scaffolding.scss",
    "chars": 3032,
    "preview": "//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This r"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_tables.scss",
    "chars": 4662,
    "preview": "//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n  background-color: $table-bg;\n}\ncaption {\n"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_theme.scss",
    "chars": 8558,
    "preview": "/*!\n * Bootstrap v3.3.6 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://gi"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_thumbnails.scss",
    "chars": 892,
    "preview": "//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.th"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_tooltip.scss",
    "chars": 3007,
    "preview": "//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n  position: absolute;\n  "
  },
  {
    "path": "client/src/style/vendor/bootstrap/_type.scss",
    "chars": 6149,
    "preview": "//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_utilities.scss",
    "chars": 765,
    "preview": "//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.c"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_variables.scss",
    "chars": 31294,
    "preview": "$bootstrap-sass-asset-helper: false !default;\n//\n// Variables\n// --------------------------------------------------\n\n\n//"
  },
  {
    "path": "client/src/style/vendor/bootstrap/_wells.scss",
    "chars": 535,
    "preview": "//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n  min-height: 20px;\n  padding:"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_alerts.scss",
    "chars": 263,
    "preview": "// Alerts\n\n@mixin alert-variant($background, $border, $text-color) {\n  background-color: $background;\n  border-color: $b"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_background-variant.scss",
    "chars": 233,
    "preview": "// Contextual backgrounds\n\n// [converter] $parent hack\n@mixin bg-variant($parent, $color) {\n  #{$parent} {\n    backgroun"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_border-radius.scss",
    "chars": 492,
    "preview": "// Single side border-radius\n\n@mixin border-top-radius($radius) {\n  border-top-right-radius: $radius;\n   border-top-left"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_buttons.scss",
    "chars": 1453,
    "preview": "// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_center-block.scss",
    "chars": 126,
    "preview": "// Center-align a block level element\n\n@mixin center-block() {\n  display: block;\n  margin-left: auto;\n  margin-right: au"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_clearfix.scss",
    "chars": 611,
    "preview": "// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n//    contentedi"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_forms.scss",
    "chars": 2771,
    "preview": "// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and succ"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_gradients.scss",
    "chars": 4392,
    "preview": "// Gradients\n\n\n\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_grid-framework.scss",
    "chars": 2360,
    "preview": "// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any va"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_grid.scss",
    "chars": 3216,
    "preview": "// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n@mixin container-f"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_hide-text.scss",
    "chars": 590,
    "preview": "// CSS image replacement\n//\n// Heads up! v3 launched with only `.hide-text()`, but per our pattern for\n// mixins being r"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_image.scss",
    "chars": 1208,
    "preview": "// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the "
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_labels.scss",
    "chars": 167,
    "preview": "// Labels\n\n@mixin label-variant($color) {\n  background-color: $color;\n\n  &[href] {\n    &:hover,\n    &:focus {\n      back"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_list-group.scss",
    "chars": 672,
    "preview": "// List Groups\n\n@mixin list-group-item-variant($state, $background, $color) {\n  .list-group-item-#{$state} {\n    color: "
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_nav-divider.scss",
    "chars": 238,
    "preview": "// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n@mixin nav-divider($color: #e5e5"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_nav-vertical-align.scss",
    "chars": 370,
    "preview": "// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_opacity.scss",
    "chars": 149,
    "preview": "// Opacity\n\n@mixin opacity($opacity) {\n  opacity: $opacity;\n  // IE8 filter\n  $opacity-ie: ($opacity * 100);\n  filter: a"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_pagination.scss",
    "chars": 507,
    "preview": "// Pagination\n\n@mixin pagination-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) "
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_panels.scss",
    "chars": 543,
    "preview": "// Panels\n\n@mixin panel-variant($border, $heading-text-color, $heading-bg-color, $heading-border) {\n  border-color: $bor"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_progress-bar.scss",
    "chars": 200,
    "preview": "// Progress bars\n\n@mixin progress-bar-variant($color) {\n  background-color: $color;\n\n  // Deprecated parent class requir"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_reset-filter.scss",
    "chars": 246,
    "preview": "// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the I"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_reset-text.scss",
    "chars": 476,
    "preview": "@mixin reset-text() {\n  font-family: $font-family-base;\n  // We deliberately do NOT reset font-size.\n  font-style: norma"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_resize.scss",
    "chars": 202,
    "preview": "// Resize anything\n\n@mixin resizable($direction) {\n  resize: $direction; // Options: horizontal, vertical, both\n  overfl"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_responsive-visibility.scss",
    "chars": 514,
    "preview": "// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n// [converter] $parent "
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_size.scss",
    "chars": 147,
    "preview": "// Sizing shortcuts\n\n@mixin size($width, $height) {\n  width: $width;\n  height: $height;\n}\n\n@mixin square($size) {\n  @inc"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_tab-focus.scss",
    "chars": 165,
    "preview": "// WebKit-style focus\n\n@mixin tab-focus() {\n  // Default\n  outline: thin dotted;\n  // WebKit\n  outline: 5px auto -webkit"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_table-row.scss",
    "chars": 715,
    "preview": "// Tables\n\n@mixin table-row-variant($state, $background) {\n  // Exact selectors below required to override `.table-strip"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_text-emphasis.scss",
    "chars": 210,
    "preview": "// Typography\n\n// [converter] $parent hack\n@mixin text-emphasis-variant($parent, $color) {\n  #{$parent} {\n    color: $co"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_text-overflow.scss",
    "chars": 168,
    "preview": "// Text overflow\n// Requires inline-block or block for proper styling\n\n@mixin text-overflow() {\n  overflow: hidden;\n  te"
  },
  {
    "path": "client/src/style/vendor/bootstrap/mixins/_vendor-prefixes.scss",
    "chars": 6645,
    "preview": "// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our"
  },
  {
    "path": "data/schema.graphql",
    "chars": 3424,
    "preview": "type Article implements Node {\n  id: ID!\n  url: String\n  dateCreated: String\n  dateModified: String\n  title: String\n  co"
  },
  {
    "path": "data/schema.json",
    "chars": 96609,
    "preview": "{\n  \"data\": {\n    \"__schema\": {\n      \"queryType\": {\n        \"name\": \"Root\"\n      },\n      \"mutationType\": null,\n      \""
  },
  {
    "path": "ecosystem.json",
    "chars": 1142,
    "preview": "{\n  /**\n   * Application configuration section\n   * http://pm2.keymetrics.io/docs/usage/application-declaration/\n   */\n "
  },
  {
    "path": "gulpfile.js",
    "chars": 2284,
    "preview": "/* Module Dependencies */\nconst gulp = require('gulp');\nconst browserSync = require('browser-sync');\nconst nodemon = req"
  },
  {
    "path": "mediakit/reactathon.ai",
    "chars": 1929486,
    "preview": "%PDF-1.5\r%\r\n1 0 obj\r<</Metadata 2 0 R/OCProperties<</D<</ON[5 0 R 105 0 R 197 0 R 289 0 R 370 0 R]/Order 371 0 R/RBGroup"
  },
  {
    "path": "package.json",
    "chars": 5278,
    "preview": "{\n  \"name\": \"reactathon\",\n  \"version\": \"0.0.1\",\n  \"description\": \"Hackathon starter kit with react, react-router, relay,"
  },
  {
    "path": "scripts/babelRelayPlugin.js",
    "chars": 223,
    "preview": "import getBabelRelayPlugin from 'babel-relay-plugin';\n\nimport schema from '../data/schema.json';\n\nvar plugin = getBabelR"
  },
  {
    "path": "scripts/mocha-bootload.js",
    "chars": 110,
    "preview": "require('babel-polyfill');\nrequire('babel-core/register');\nrequire('chai').use(require('chai-as-promised'));\n\n"
  },
  {
    "path": "scripts/seed.js",
    "chars": 1152,
    "preview": "process.env.NODE_ENV = 'development';\n\nconst _ = require('lodash');\nconst faker = require('faker');\nconst database = req"
  },
  {
    "path": "scripts/server.js",
    "chars": 9195,
    "preview": "import sane from 'sane';\nimport { resolve as resolvePath } from 'path';\nimport { spawn, fork } from 'child_process';\nimp"
  },
  {
    "path": "scripts/updateSchema.js",
    "chars": 662,
    "preview": "#!/usr/bin/env babel-node --optional es7.asyncFunctions\n\nimport fs from 'fs';\nimport path from 'path';\nimport {graphql} "
  },
  {
    "path": "server/src/__tests__/testModules.js",
    "chars": 573,
    "preview": "import {\n  express,\n  path,\n  favicon,\n  logger,\n  cookieParser,\n  bodyParser\n} from '../modules';\n\nimport { expect } fr"
  },
  {
    "path": "server/src/app.config.js",
    "chars": 4491,
    "preview": "const path = require('path');\nconst envpath = path.join(__dirname, '.env.example');\nrequire('dotenv').config({path: envp"
  },
  {
    "path": "server/src/app.js",
    "chars": 4176,
    "preview": "/**\n * Import Node Modules |||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n */\nimport {\n  express,\n  path,\n  f"
  },
  {
    "path": "server/src/auth/index.js",
    "chars": 121,
    "preview": "export {\n  getUser,\n  isAuthenticated,\n  onAuthenticate,\n  signUp,\n  login,\n  forgot,\n  handleReset\n} from './passport';"
  },
  {
    "path": "server/src/auth/modules.js",
    "chars": 1176,
    "preview": "const env = process.env.NODE_ENV || 'development';\n\n// console.log(env);\n\nexport const config = require('../app.config.j"
  },
  {
    "path": "server/src/auth/passport.js",
    "chars": 15383,
    "preview": "import {\n  _,\n  passport,\n  request,\n  LocalStrategy,\n  crypto,\n  FacebookStrategy,\n  TwitterStrategy,\n  GitHubStrategy,"
  },
  {
    "path": "server/src/database/index.js",
    "chars": 504,
    "preview": "const models = require('./models');\n\nexport const db = models.sequelize;\n\nexport const Article = models.Article;\nexport "
  },
  {
    "path": "server/src/database/migrations/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "server/src/database/models/Article.js",
    "chars": 2946,
    "preview": "module.exports = function (sequelize, DataTypes) {\n\n  var Article = sequelize.define('Article',\n    {\n      type: {\n    "
  },
  {
    "path": "server/src/database/models/Comment.js",
    "chars": 2925,
    "preview": "module.exports = function (sequelize, DataTypes) {\n  var customTypes = require('./customTypes')(DataTypes);\n  var Commen"
  },
  {
    "path": "server/src/database/models/Flag.js",
    "chars": 814,
    "preview": "module.exports = function (sequelize, DataTypes) {\n\n  var Flag = sequelize.define('Flag',\n  {\n    type: {\n      type: ne"
  },
  {
    "path": "server/src/database/models/Tag.js",
    "chars": 866,
    "preview": "module.exports = function (sequelize, DataTypes) {\n  var Tag = sequelize.define('Tag', {\n      type: {\n        type: new"
  },
  {
    "path": "server/src/database/models/TagItem.js",
    "chars": 474,
    "preview": "module.exports = function (sequelize, DataTypes) {\n  return sequelize.define('TagItem', {\n    tag_id: {\n      type: Data"
  },
  {
    "path": "server/src/database/models/Token.js",
    "chars": 412,
    "preview": "module.exports = function (sequelize, DataTypes) {\n  var Token = sequelize.define('Token', {\n    type: {\n      type: new"
  },
  {
    "path": "server/src/database/models/User.js",
    "chars": 1659,
    "preview": "\nmodule.exports = function (sequelize, DataTypes) {\n  var User = sequelize.define('User', {\n    type: {\n      type: new "
  },
  {
    "path": "server/src/database/models/Vote.js",
    "chars": 804,
    "preview": "module.exports = function (sequelize, DataTypes) {\n  var Vote = sequelize.define('Vote', {\n    type: {\n      type: new D"
  },
  {
    "path": "server/src/database/models/customTypes/URL.js",
    "chars": 217,
    "preview": "/**\n * URL\n * @param DataTypes\n * @returns {{type: (number|*), validate: {isUrl: boolean}}}\n */\nmodule.exports = (DataTy"
  },
  {
    "path": "server/src/database/models/customTypes/email.js",
    "chars": 220,
    "preview": "/**\n * URL\n * @param DataTypes\n * @returns {{type: (number|*), validate: {isUrl: boolean}}}\n */\nmodule.exports = (DataTy"
  },
  {
    "path": "server/src/database/models/customTypes/index.js",
    "chars": 138,
    "preview": "module.exports = function (DataTypes) {\n  return {\n    URL: require('./URL')(DataTypes),\n    email: require('./email')(D"
  },
  {
    "path": "server/src/database/models/index.js",
    "chars": 1125,
    "preview": "import {\n  fs,\n  appConfig,\n  path,\n  Sequelize,\n} from '../modules';\n\n// console.log('appConfig', appConfig);\n// consol"
  },
  {
    "path": "server/src/database/modules.js",
    "chars": 168,
    "preview": "export const fs = require('fs');\nexport const path = require('path');\nexport const Sequelize = require('sequelize');\nexp"
  },
  {
    "path": "server/src/database/seeders/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "server/src/modules.js",
    "chars": 1003,
    "preview": "export const fs = require('fs');\nexport const express = require('express');\nexport const path = require('path');\nexport "
  },
  {
    "path": "server/src/pages/about.md",
    "chars": 90,
    "preview": "## About\n\nThis page is created in markdown, and collected by the Page Container via\nAjax.\n"
  },
  {
    "path": "server/src/public/browserconfig.xml",
    "chars": 439,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Please read: https://msdn.microsoft.com/en-us/library/ie/dn455106.aspx -->\n<"
  },
  {
    "path": "server/src/public/img/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "server/src/public/manifest.json",
    "chars": 720,
    "preview": "{\n \"name\": \"App\",\n \"icons\": [\n  {\n   \"src\": \"\\/android-icon-36x36.png\",\n   \"sizes\": \"36x36\",\n   \"type\": \"image\\/png\",\n  "
  },
  {
    "path": "server/src/routes/api.js",
    "chars": 1238,
    "preview": "import {\n  express, fs, path\n} from './modules';\n\nimport {\n  login,\n  signUp,\n  handleReset,\n  forgot } from '../auth';\n"
  },
  {
    "path": "server/src/routes/auth.js",
    "chars": 2576,
    "preview": "import {\n  express,\n  passport\n} from './modules';\n\nimport {\n  User\n} from '../database';\n\nconst auth = express.Router()"
  },
  {
    "path": "server/src/routes/index.js",
    "chars": 106,
    "preview": "export { rootRoute } from './root';\nexport { apiRoute } from './api';\nexport { authRoute } from './auth';\n"
  },
  {
    "path": "server/src/routes/modules.js",
    "chars": 234,
    "preview": "export const _ = require('lodash');\nexport const passport = require('passport');\nexport const express = require('express"
  },
  {
    "path": "server/src/routes/root.js",
    "chars": 412,
    "preview": "import {\n  express,\n  appConfig\n} from './modules';\n\nconst root = express.Router();\n\n/* GET home page. */\n\nroot.get('*',"
  },
  {
    "path": "server/src/schema/index.js",
    "chars": 14691,
    "preview": "import {\n  Article,\n  Comment,\n  Flag,\n  Tag,\n  User,\n  Vote\n} from '../database';\n\nimport {\n  fromGravatar\n} from '../u"
  },
  {
    "path": "server/src/utils/fromGravatar.js",
    "chars": 486,
    "preview": "/**\n * Moduile Dependencies\n */\nimport {\n  md5,\n  ajax } from './modules';\n\n\nexport const fromGravatar = (email, key) =>"
  },
  {
    "path": "server/src/utils/getGravatar.js",
    "chars": 471,
    "preview": "/**\n * Module Dependencies\n */\nimport {\n  md5,\n  ajax } from './modules';\n\n\nexport const getGravatar = (email) => {\n  re"
  },
  {
    "path": "server/src/utils/index.js",
    "chars": 127,
    "preview": "export { fromGravatar } from './fromGravatar';\nexport { getGravatar } from './getGravatar';\nexport { logger } from './lo"
  },
  {
    "path": "server/src/utils/logger.js",
    "chars": 346,
    "preview": "import {\n  appConfig,\n  winston\n} from './modules';\n\nconst env = process.env.NODE_ENV || 'development';\nconst config = a"
  },
  {
    "path": "server/src/utils/modules.js",
    "chars": 172,
    "preview": "export const md5 = require('md5');\nexport const ajax = require('superagent');\nexport const winston = require('winston');"
  },
  {
    "path": "server/src/views/error.hbs",
    "chars": 74,
    "preview": "<h1>{{message}}</h1>\n<h2>{{error.status}}</h2>\n<pre>{{error.stack}}</pre>\n"
  },
  {
    "path": "server/src/views/index.hbs",
    "chars": 47,
    "preview": "<h1>{{title}}</h1>\n<p>Welcome to {{title}}</p>\n"
  },
  {
    "path": "server/src/views/layout.hbs",
    "chars": 3540,
    "preview": "<!DOCTYPE html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"x-ua-compatible\" content=\"ie=edge\">\n    "
  },
  {
    "path": "server/src/views/root.hbs",
    "chars": 285,
    "preview": "\n{{#if user}}\n    <script type=\"application/json\" id=\"user\">{{{user}}}</script>\n{{/if}}\n<link rel=\"stylesheet\" href=\"//c"
  },
  {
    "path": "ssl/localhost.cert",
    "chars": 1143,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIDIDCCAgigAwIBAgIJAN7RRsm7bDC9MA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV\nBAMTCWxvY2FsaG9zdDAeFw0xNTE"
  },
  {
    "path": "ssl/localhost.key",
    "chars": 1675,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEArnI7XpQa3RHrJgYZTk+yJB7qLqx05KQZAo4BbSQCeXvJxQmP\nOziGc8jDuJDnHD6/KNbVGCS"
  },
  {
    "path": "tasks/bundle.js",
    "chars": 1095,
    "preview": "const\n  browserify = require('browserify'),\n  gulp = require('gulp'),\n  source = require('vinyl-source-stream'),\n  buffe"
  },
  {
    "path": "tasks/bundledebugdeps.js",
    "chars": 891,
    "preview": "var\n  browserify = require('browserify'),\n  gulp = require('gulp'),\n  source = require('vinyl-source-stream'),\n  buffer "
  },
  {
    "path": "tasks/bundledeps.js",
    "chars": 997,
    "preview": "var\n  browserify = require('browserify'),\n  gulp = require('gulp'),\n  source = require('vinyl-source-stream'),\n  buffer "
  },
  {
    "path": "tasks/bundlemin.js",
    "chars": 963,
    "preview": "var\n  browserify = require('browserify'),\n  gulp = require('gulp'),\n  source = require('vinyl-source-stream'),\n  buffer "
  },
  {
    "path": "tasks/helpers.js",
    "chars": 342,
    "preview": "const _ = require('lodash');\n\nexports.getNPMPackageIds = () => {\n  // read json and get dependencies' package ids\n  var "
  },
  {
    "path": "tasks/sass.js",
    "chars": 351,
    "preview": "var\n  gulp = require('gulp'),\n  sass = require('gulp-sass'),\n  gutil = require('gulp-util');\n\nmodule.exports = function("
  }
]

About this extraction

This page contains the full source code of the MattMcFarland/reactathon GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 178 files (2.3 MB), approximately 611.1k tokens, and a symbol index with 120 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!