├── models ├── .gitsave ├── plugins.js ├── User.js └── BlogPost.js ├── public ├── favicon.ico ├── humans.txt ├── js │ ├── .gitsave │ ├── view_post.js │ ├── compose.js │ ├── auth.js │ └── bootstrap.min.js.use ├── robots.txt ├── css │ ├── .gitsave │ ├── style.css │ ├── bootswatch │ │ ├── united │ │ │ ├── bootswatch.less │ │ │ └── variables.less │ │ ├── simplex │ │ │ ├── bootswatch.less │ │ │ └── variables.less │ │ ├── cerulean │ │ │ ├── bootswatch.less │ │ │ └── variables.less │ │ ├── journal │ │ │ ├── bootswatch.less │ │ │ └── variables.less │ │ ├── default │ │ │ └── variables.less │ │ ├── spacelab │ │ │ ├── variables.less │ │ │ └── bootswatch.less │ │ ├── slate │ │ │ ├── variables.less │ │ │ └── bootswatch.less │ │ ├── superhero │ │ │ ├── variables.less │ │ │ └── bootswatch.less │ │ ├── readable │ │ │ ├── variables.less │ │ │ └── bootswatch.less │ │ ├── cyborg │ │ │ ├── variables.less │ │ │ └── bootswatch.less │ │ ├── spruce │ │ │ ├── variables.less │ │ │ └── bootswatch.less │ │ └── amelia │ │ │ ├── variables.less │ │ │ └── bootswatch.less │ └── bootstrap-responsive.min.css ├── img │ ├── .gitsave │ ├── vintage_speckles.png │ ├── glyphicons-halflings.png │ └── glyphicons-halflings-white.png ├── apple-touch-icon.png └── apple-touch-icon-precomposed.png ├── routes ├── .gitsave └── index.js ├── views ├── .gitsave ├── not_found.jade ├── user_index.jade ├── includes │ ├── nav_out.jade │ ├── nav_in.jade │ ├── nav_in_multitenant.jade │ └── nav_in_admin.jade ├── about.jade ├── oauth_return.jade ├── view_post.jade ├── index.jade ├── about_gistbits.jade └── new_post.jade ├── Procfile ├── .gitignore ├── package.json ├── exports.sample.txt ├── LICENSE ├── config.js ├── README.md ├── gh-api.js └── app.js /models/.gitsave: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/humans.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/js/.gitsave: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /routes/.gitsave: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /views/.gitsave: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/css/.gitsave: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/.gitsave: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node app.js -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.*~ 2 | *~ 3 | node_modules/ 4 | exports.txt 5 | -------------------------------------------------------------------------------- /public/js/view_post.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $.post('/ajax/human_view/'+post_id); 3 | }); -------------------------------------------------------------------------------- /public/img/vintage_speckles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jazzychad/gistblog/HEAD/public/img/vintage_speckles.png -------------------------------------------------------------------------------- /public/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jazzychad/gistblog/HEAD/public/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /public/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jazzychad/gistblog/HEAD/public/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /views/not_found.jade: -------------------------------------------------------------------------------- 1 | extends index 2 | 3 | block content 4 | div.col-md-8.col-md-offset-1 5 | h1 Not Found 6 | 7 | p 8 | | Uh oh, this page doesn't exist. -------------------------------------------------------------------------------- /models/plugins.js: -------------------------------------------------------------------------------- 1 | var mongoose = require("mongoose"); 2 | 3 | var shortid = require("shortid"); 4 | 5 | var config = require("../config"); 6 | 7 | shortid.seed(config.shortid_seed); 8 | 9 | var create_shortid = function(schema, options) { 10 | schema.pre('save', function(next) { 11 | if (this.shortid == undefined) { 12 | this.shortid = shortid.generate(); 13 | } 14 | next(); 15 | }); 16 | }; 17 | 18 | 19 | module.exports.create_shortid = create_shortid; 20 | -------------------------------------------------------------------------------- /views/user_index.jade: -------------------------------------------------------------------------------- 1 | extends index 2 | 3 | block navbar 4 | if user 5 | include includes/nav_in 6 | else 7 | include includes/nav_out 8 | 9 | block content 10 | div.col-md-8.col-md-offset-2 11 | h1 12 | =author.username 13 | 14 | each post in blog_posts 15 | p 16 | h3(style="margin-top:45px") 17 | a(href="/post/"+post.gistIdStr) 18 | = post.title 19 | | — 20 | = post.tstamp.toLocaleDateString() 21 | hr 22 | -------------------------------------------------------------------------------- /public/js/compose.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 3 | marked.setOptions({ 4 | gfm: true 5 | }); 6 | 7 | var renderPreview = function(){ 8 | var md = '# ' + $('#post_title').val() + "\n\n\n" + $('#post_body').val(); 9 | marked(md, {}, function(err, content) { 10 | $('#preview').html(content); 11 | }); 12 | }; 13 | 14 | $('#post_body').bind('input propertychange', renderPreview); 15 | $('#post_title').bind('input propertychange', renderPreview); 16 | 17 | renderPreview(); 18 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gistblog", 3 | "version": "0.0.1", 4 | "private": true, 5 | "dependencies": { 6 | "express": "3.3.4", 7 | "jade": "0.25.0", 8 | "ejs": "0.7.1", 9 | "github": "0.1.8", 10 | "mongoose": "2.5.10", 11 | "shortid": "1.0.6", 12 | "MD5": "latest", 13 | "connect-auth": "0.5.1", 14 | "request": "2.11.1", 15 | "connect-mongo": "0.1.9", 16 | "toml": "0.4.1", 17 | "marked": "0.2.9", 18 | "redis": "0.8.4" 19 | }, 20 | "engines": { 21 | "node": "0.10.x", 22 | "npm": "1.3.x" 23 | } 24 | } -------------------------------------------------------------------------------- /views/includes/nav_out.jade: -------------------------------------------------------------------------------- 1 | nav.navbar.navbar-default 2 | div.container 3 | div.navbar-header 4 | a.navbar-brand(href="/")= sitename 5 | button.navbar-toggle(data-toggle="collapse", data-target="#navbar-main") 6 | span.icon-bar 7 | span.icon-bar 8 | span.icon-bar 9 | div#navbar-main.navbar-collapse.collapse 10 | ul.nav.navbar-nav 11 | li 12 | a(href="/about") about 13 | ul.nav.navbar-nav.navbar-right 14 | li.divider-vertical 15 | li 16 | a(href="/login") login with github 17 | -------------------------------------------------------------------------------- /public/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 35px; 3 | /*font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;*/ 4 | /*background: #fff url("/img/vintage_speckles.png");*/ 5 | } 6 | 7 | a { 8 | /*color: #00B7FF;*/ 9 | } 10 | 11 | /* bootstrap tweaks */ 12 | 13 | .navbar { 14 | margin-bottom: 3.5em; 15 | } 16 | 17 | .navbar .nav li span.user { 18 | padding: 23.375px 8px 19.375px; 19 | display: block; 20 | 21 | line-height: 1.25em; 22 | /*color: #eee;*/ 23 | } 24 | 25 | .navbar .nav li span.userimg { 26 | padding: 21.375px 8px 5px; 27 | display: block; 28 | line-height: 1.25em; 29 | } 30 | -------------------------------------------------------------------------------- /views/about.jade: -------------------------------------------------------------------------------- 1 | extends index 2 | 3 | block content 4 | div.col-md-7.col-md-offset-2 5 | h1 GistBlog 6 | p 7 | | Hi, I'm 8 | a(href="https://twitter.com/jazzychad") jazzychad 9 | |. You can find 10 | a(href="http://blog.jazzychad.net") my main blog over here 11 | |. 12 | 13 | p 14 | | GistBlog is a blogging system for Github users. 15 | a(href="http://txt.jazzychad.net/gist/6007164") This post gives some more detail. 16 | p 17 | | It's open-source. You can find the code here: 18 | a(href="https://github.com/jazzychad/gistblog") 19 | | https://github.com/jazzychad/gistblog 20 | 21 | -------------------------------------------------------------------------------- /public/js/auth.js: -------------------------------------------------------------------------------- 1 | $(document).ready( 2 | function() { 3 | 4 | var hash = window.location.hash.substring(1); 5 | var parts = hash.split("&"); 6 | var access_token; 7 | for (var i in parts) { 8 | var part = parts[i]; 9 | var ps = part.split("="); 10 | if (ps[0] == "access_token") { 11 | access_token = ps[1]; 12 | break; 13 | } 14 | } 15 | $.post('/auth/token', {access_token: access_token}, function(data) { 16 | console.log('sent token'); 17 | console.log(data); 18 | if (data === 'ok') { 19 | window.location = '/'; 20 | } 21 | }); 22 | 23 | }); -------------------------------------------------------------------------------- /exports.sample.txt: -------------------------------------------------------------------------------- 1 | # copy and paste these lines into your shell 2 | # where you run foreman 3 | # 4 | # change values to your sepcific setup 5 | 6 | export GISTBLOG_IS_MULTITENANT=0 7 | export ADMIN_USERID="000000" # your gh userid 8 | export SITEURL="http://localhost:5000/" 9 | export MONGOLAB_URI="mongodb://localhost/gistblogs" 10 | export GH_CONSUMER_KEY="" 11 | export GH_CONSUMER_SECRET="" 12 | export GH_CALLBACK="http://localhost:5000/oauth/callback" 13 | export EXPRESS_SESSION_SECRET="" 14 | export SHORTID_SEED=1234567890 15 | export GA_ID="" 16 | export GA_DOMAIN="" 17 | -------------------------------------------------------------------------------- /views/includes/nav_in.jade: -------------------------------------------------------------------------------- 1 | nav.navbar.navbar-default 2 | div.container 3 | div.navbar-header 4 | a.navbar-brand(href="/")= sitename 5 | button.navbar-toggle(data-toggle="collapse", data-target="#navbar-main") 6 | span.icon-bar 7 | span.icon-bar 8 | span.icon-bar 9 | div#navbar-main.navbar-collapse.collapse 10 | ul.nav.navbar-nav 11 | li 12 | a(href="/about") about 13 | ul.nav.navbar-nav.navbar-right 14 | li 15 | span.userimg 16 | img(src="#{user.avatar}", height="24", width="24") 17 | li 18 | span.nav.navbar-nav.user 19 | = user.username 20 | li.divider-vertical 21 | li 22 | a(href="/logout") logout 23 | -------------------------------------------------------------------------------- /models/User.js: -------------------------------------------------------------------------------- 1 | var mongoose = require("mongoose"); 2 | var plugins = require("./plugins"); 3 | 4 | var Schema = mongoose.Schema, ObjectId = Schema.ObjectId; 5 | 6 | var UserSchema = new Schema({ 7 | shortid: {type: String, index: true, unique: true}, 8 | views: {type: Number, default: 0}, 9 | logins: {type: Number, default: 1}, 10 | username: {type: String, index: true}, 11 | name: {type: String}, 12 | avatar: {type: String}, 13 | gh_access_token: {type: String}, 14 | gh_userid: {type: String, index: true}, 15 | is_admin: {type: Boolean, default: false}, 16 | tstamp: {type: Date, default: function(){return new Date();}} 17 | }); 18 | 19 | UserSchema.plugin(plugins.create_shortid); 20 | 21 | var User = mongoose.model('User', UserSchema); 22 | 23 | module.exports.User = User; -------------------------------------------------------------------------------- /views/includes/nav_in_multitenant.jade: -------------------------------------------------------------------------------- 1 | nav.navbar.navbar-default 2 | div.container 3 | div.navbar-header 4 | a.navbar-brand(href="/")= sitename 5 | button.navbar-toggle(data-toggle="collapse", data-target="#navbar-main") 6 | span.icon-bar 7 | span.icon-bar 8 | span.icon-bar 9 | div#navbar-main.navbar-collapse.collapse 10 | ul.nav.navbar-nav 11 | li 12 | a(href="/compose") compose 13 | li 14 | a(href="/about") about 15 | ul.nav.navbar-nav.navbar-right 16 | li 17 | span.userimg 18 | img(src="#{user.avatar}", height="24", width="24") 19 | li 20 | span.nav.navbar-nav.user 21 | = user.username 22 | li.divider-vertical 23 | li 24 | a(href="/logout") logout 25 | -------------------------------------------------------------------------------- /views/includes/nav_in_admin.jade: -------------------------------------------------------------------------------- 1 | div.navbar.navbar-default 2 | div.container 3 | div.navbar-header 4 | a.navbar-brand(href="/")= sitename 5 | button.navbar-toggle(data-toggle="collapse", data-target="#navbar-main", type="button") 6 | span.icon-bar 7 | span.icon-bar 8 | span.icon-bar 9 | div#navbar-main.navbar-collapse.collapse 10 | ul.nav.navbar-nav 11 | li 12 | a(href="/compose") compose 13 | li 14 | a(href="/about") about 15 | ul.nav.navbar-nav.navbar-right 16 | li 17 | span.userimg 18 | img(src="#{user.avatar}", height="24", width="24") 19 | li 20 | span.nav.navbar-nav.user 21 | = user.username 22 | li.divider-vertical 23 | li 24 | a(href="/logout") logout 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013 Chad Etzel - http://jazzychad.net/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /views/oauth_return.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html(lang='en') 3 | head 4 | title= sitename 5 |  -  -  6 | = title 7 | link(rel="icon", href="/img/favicon.ico", type="image/x-icon") 8 | link(rel="shortcut icon", href="/img/favicon.ico", type="image/x-icon") 9 | link(href="/css/bootstrap.min.css", rel="stylesheet") 10 | //link(href="/css/bootstrap-responsive.css", rel="stylesheet") 11 | link(href="/css/style.css", rel="stylesheet") 12 | body 13 | block navbar 14 | div.navbar.navbar-fixed-top 15 | div.navbar-inner 16 | div.container 17 | a.brand(href="/")= sitename 18 | div.nav-collapse 19 | ul.nav 20 | li 21 | a(href="/") Home 22 | ul.nav.navbar-right 23 | li.divider-vertical 24 | li 25 | a(href="/login") Login with App.net 26 | 27 | div.container 28 | block content 29 | p One Moment... 30 | 31 | 32 | script(src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js", type="text/javascript") 33 | script(src="/js/bootstrap.min.js", type="text/javascript") 34 | block scripts_extra 35 | script(src="/js/auth.js", type="text/javascript") -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | module.exports.sitename = process.env.SITE_NAME || "gistblog"; 2 | module.exports.title = "home"; 3 | 4 | module.exports.is_multitenant = parseInt(process.env.GISTBLOG_IS_MULTITENANT, 0); 5 | 6 | module.exports.about_view = process.env.ABOUT_VIEW || "about"; 7 | 8 | var allowed_users = process.env.GISTBLOG_ALLOWED_USERS; 9 | if (allowed_users && allowed_users.length) { 10 | module.exports.allowed_users = allowed_users.split(','); 11 | } else { 12 | module.exports.allowed_users = null; 13 | } 14 | 15 | module.exports.admin_userid = process.env.ADMIN_USERID; 16 | 17 | module.exports.siteurl = process.env.SITEURL; 18 | 19 | module.exports.mongo_uri = process.env.MONGOLAB_URI; 20 | module.exports.redis_uri = process.env.REDISTOGO_URL; 21 | 22 | module.exports.gh_consumer_key = process.env.GH_CONSUMER_KEY; 23 | module.exports.gh_consumer_secret = process.env.GH_CONSUMER_SECRET; 24 | module.exports.gh_application_access_token = process.env.GH_APPLICATION_ACCESS_TOKEN; 25 | module.exports.gh_callback = process.env.GH_CALLBACK; 26 | 27 | module.exports.express_session_secret = process.env.EXPRESS_SESSION_SECRET; 28 | 29 | module.exports.shortid_seed = process.env.SHORTID_SEED; 30 | 31 | module.exports.ga_id = process.env.GA_ID; 32 | module.exports.ga_domain = process.env.GA_DOMAIN; -------------------------------------------------------------------------------- /models/BlogPost.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var plugins = require("./plugins"); 3 | 4 | var Schema = mongoose.Schema, ObjectId = Schema.ObjectId; 5 | 6 | var BlogPostSchema = new Schema({ 7 | 8 | shortid: { 9 | type: String, 10 | index: true, 11 | unique: true 12 | }, 13 | ownerIdStr: { 14 | type: String 15 | }, 16 | ownerUsername: { 17 | type: String 18 | }, 19 | isDraft: { 20 | type: Boolean, 21 | default: false 22 | }, 23 | views: { 24 | type: Number, 25 | default: 0 26 | }, 27 | gistIdStr: { 28 | type: String, 29 | index: true 30 | }, 31 | visibility: { 32 | type: String, 33 | default: "private" 34 | }, 35 | isPublic: { 36 | type: Boolean, 37 | default: false 38 | }, 39 | allowedViewers: { 40 | type: Array, 41 | default: [] 42 | }, 43 | draftText: { 44 | type: String 45 | }, 46 | title: { 47 | type: String 48 | }, 49 | tstamp: { 50 | type: Date, 51 | default: function() { 52 | return new Date(); 53 | } 54 | }, 55 | timestamp: { 56 | type: Number, 57 | default: function() { 58 | return Math.floor((+new Date())/1000); 59 | } 60 | }, 61 | blurbText: { 62 | type: String 63 | } 64 | }); 65 | 66 | BlogPostSchema.plugin(plugins.create_shortid); 67 | 68 | var BlogPost = mongoose.model('BlogPost', BlogPostSchema); 69 | 70 | module.exports.BlogPost = BlogPost; 71 | 72 | 73 | -------------------------------------------------------------------------------- /views/view_post.jade: -------------------------------------------------------------------------------- 1 | extends index 2 | 3 | block navbar 4 | if user 5 | include includes/nav_in 6 | else 7 | include includes/nav_out 8 | 9 | block content 10 | div.col-md-7.col-md-offset-2 11 | h1 12 | =blog_post.title 13 | 14 | if user && user.userid && user.userid == blog_post.ownerIdStr 15 | a(href="/edit/"+blog_post.gistIdStr) 16 | | Edit Post 17 | 18 | p 19 | =blog_post.tstamp.toLocaleDateString() 20 | |   21 | if blog_post.views 22 | span(style="color:#777;") – #{blog_post.views} views 23 | 24 | p — by 25 | a(href="/user/"+blog_post.username) #{blog_post.username} 26 | 27 | p(style='white-space:pre-wrap;') 28 | | !{blog_post.body} 29 | 30 | if blog_post.isPublic 31 | hr 32 | p 33 | a(href="https://twitter.com/share", class="twitter-share-button", data-text=blog_post.title+" - ", data-size="large", data-count="none") Tweet 34 | 35 | 36 | hr 37 | 38 | 39 | block scripts_extra 40 | script(src="/js/view_post.js", type="text/javascript") 41 | script(type="text/javascript"). 42 | var post_id='#{blog_post.post_id}'; 43 | 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gistblog 2 | 3 | gistblog is a simple node.js app (easily hosted on Heroku) that uses 4 | Github for user authentication and Gists for the backing store of post 5 | data. gistblog presents a simple interface to quickly compose 6 | markdown-based posts and display them to readers. 7 | 8 | The author may publish posts as public, private, or limit viewing of 9 | posts to specific Github usernames (useful for a private post among a 10 | group of people or peer reviews of drafts before making a post public). 11 | 12 | More features coming soon. 13 | 14 | ## Example 15 | 16 | A reference implementation can be seen at: [http://txt.jazzychad.net](http://txt.jazzychad.net) 17 | 18 | ## Development 19 | 20 | To setup run the following commands: 21 | 22 | npm install -d 23 | heroku apps:create --stack cedar 24 | heroku addons:add mongolab:sandbox # free 496mg mongo tier 25 | heroku addons:add redistogo:nano # free 5mb redis server 26 | 27 | use foreman for local heroku testing 28 | 29 | **DO NOT PUT SENSITIVE KEYS OR INFORMATION IN THE SOURCE CODE 30 | EVER. PUT THEM IN ENVIRONMENT VARIABLES AND REFERENCE THEM FROM 31 | CONFIG.JS** 32 | 33 | See `exports.sample.txt` for environment variables you will need to set. 34 | 35 | ## Contributing 36 | 37 | If you would like to contribute to this project, great! Please fork 38 | this repo and get it up and running locally. Create a feature branch, 39 | and then send a pull-request once you have finished it. 40 | 41 | ## Contact 42 | 43 | Questions about how things work? Feel free to ping me on twitter 44 | @[jazzychad](https://twitter.com/jazzychad). Enterprising folks can 45 | also find my email address through my website. 46 | 47 | ## Disclaimers 48 | 49 | This code will be under active development and might change frequently. 50 | 51 | ## LICENSE 52 | 53 | MIT License. See LICENSE for info. 54 | -------------------------------------------------------------------------------- /views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | doctype 5 3 | html(lang='en') 4 | head 5 | title= sitename 6 |  -  7 | = title 8 | meta(name="viewport", content="width=device-width, initial-scale=1.0") 9 | link(rel="icon", href="/img/favicon.ico", type="image/x-icon") 10 | link(rel="shortcut icon", href="/img/favicon.ico", type="image/x-icon") 11 | link(href="/css/bootstrap.css", rel="stylesheet") 12 | link(href="/css/style.css", rel="stylesheet") 13 | body 14 | block navbar 15 | if user && user.is_admin 16 | include includes/nav_in_admin 17 | else if user && is_allowed_user 18 | include includes/nav_in_multitenant 19 | else if user 20 | include includes/nav_in 21 | else 22 | include includes/nav_out 23 | 24 | 25 | div.container 26 | block content 27 | div.col-md-8.col-md-offset-2 28 | h1 latest posts 29 | each post in blog_posts 30 | p 31 | h3(style="margin-top:45px") 32 | a(href="/post/"+post.gistIdStr) 33 | = post.title 34 | | — 35 | if post.ownerUsername 36 | a(href="/user/"+post.ownerUsername) #{post.ownerUsername} 37 |   38 | span(style="color:#777") 39 | = post.tstamp.toLocaleDateString() 40 | else 41 | = post.tstamp.toLocaleDateString() 42 | 43 | p(style="color:#777") 44 | | #{post.views} views 45 | 46 | hr 47 | 48 | 49 | script(src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js", type="text/javascript") 50 | script(src="/js/bootstrap.min.js", type="text/javascript") 51 | script. 52 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 53 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 54 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 55 | })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); 56 | 57 | ga('create', '#{ga_id}', '#{ga_domain}'); 58 | ga('send', 'pageview'); 59 | 60 | block scripts_extra 61 | 62 | -------------------------------------------------------------------------------- /views/about_gistbits.jade: -------------------------------------------------------------------------------- 1 | extends index 2 | 3 | block content 4 | div.col-md-7.col-md-offset-2 5 | h1 gistbits 6 | p 7 | | Hi, I'm 8 | a(href="http://jazzychad.net") jazzychad 9 | |. 10 | 11 | p 12 | b gistbits 13 | | is a blogging platform for Github users. Posts are stored as gists on the user's account. You can create public posts, unlisted posts (only viewable if you send someone the url), or even access-restricted posts that can only be read by certain other Github users. 14 | 15 | p 16 | | It's open-source. You can find the code here: 17 | a(href="https://github.com/jazzychad/gistblog") 18 | | https://github.com/jazzychad/gistblog 19 | 20 | p 21 | | You can host your own personal gistblog, host a multi-tenant site where anyone can post (like this one!), or even a community site which is restricted to allowing certain users to post. 22 | 23 | h2 FAQ 24 | 25 | p 26 | b Why build gistbits? 27 | p 28 | | I wanted something to quickly publish thoughts that were longer than a tweet, but less heavy-weight than a full blog post. I created my own gistblog, and people seemed interested in using a similar system, so I updated the code to support multiple authors on the same site. 29 | 30 | p 31 | b Who can post on gistbits? 32 | p 33 | | Eventually anyone with a Github account! Right now I am keeping authors to an invite-only list to see if this is actually a system that people want to use to express their thoughts. If it proves to be worthy of more users, then over time I will open it up to more people, then eventually everyone! 34 | 35 | p 36 | b How can I request access? 37 | p 38 | | Please fill out this form: 39 | a(href="https://docs.google.com/forms/d/1POhYkaPOqiaDNH4sVqyv7kLsU9hh2YF7fr5CQjyKa8w/viewform?usp=send_form") request gistbits access 40 | 41 | p 42 | b I want to write a post with images, can I? 43 | p 44 | | Great! Yes, you can, if you upload your image to an image-hosting service and then reference it from your post using the markdown syntax. I have no current or future plans to support uploading images through the gistbits interface. -------------------------------------------------------------------------------- /public/css/bootswatch/united/bootswatch.less: -------------------------------------------------------------------------------- 1 | // Bootswatch.less 2 | // Swatch: United 3 | // ----------------------------------------------------- 4 | 5 | // TYPOGRAPHY 6 | // ----------------------------------------------------- 7 | 8 | // Ubuntu web font 9 | @import url(http://fonts.googleapis.com/css?family=Ubuntu); 10 | 11 | // NAVBAR 12 | // ----------------------------------------------------- 13 | 14 | // Added dividers to items 15 | .navbar .nav > li > a { 16 | border-right: 1px solid #C03D14; 17 | border-left: 1px solid #E6633A; 18 | 19 | &:hover { 20 | background-color: @linkColorHover; 21 | } 22 | } 23 | 24 | // Lightened color of active item 25 | .navbar .nav .active > a, 26 | .navbar .nav .active > a:hover { 27 | background-color: rgba(0,0,0,.2); 28 | } 29 | 30 | // Styled item divider 31 | .navbar .divider-vertical { 32 | background-color: inherit; 33 | border-right: 0px solid #CE4213; 34 | } 35 | 36 | .navbar .navbar-text > a { 37 | color: @white; 38 | text-decoration: underline; 39 | 40 | &:hover { 41 | color: #ddd; 42 | } 43 | } 44 | 45 | .navbar-search .search-query { 46 | border: 1px solid darken(@navbarBackground, 15%); 47 | } 48 | 49 | .navbar .nav-collapse > .nav > li .dropdown-menu a { 50 | color: @linkColor; 51 | 52 | &:hover { 53 | color: @white; 54 | } 55 | } 56 | 57 | .navbar .nav-collapse.collapse > .nav li > a { 58 | color: @white; 59 | border-left: 0px solid @orange; 60 | border-right: 0px solid @orange; 61 | 62 | &:hover { 63 | background-color: #2B7CAC; 64 | } 65 | } 66 | 67 | .navbar .nav-collapse .navbar-form, 68 | .navbar .nav-collapse .navbar-search { 69 | border-top: 0px solid @orange; 70 | border-bottom: 0px solid @orange; 71 | .box-shadow(none); 72 | } 73 | 74 | // BUTTONS 75 | // ----------------------------------------------------- 76 | 77 | // Reversed gradient on primary button 78 | .btn-primary { 79 | .buttonBackground(lighten(@primaryButtonBackground, 15%), @primaryButtonBackground); 80 | } 81 | 82 | // Made warning button yellow since orange is taken 83 | .btn-warning { 84 | .buttonBackground(lighten(@yellow, 15%), @yellow); 85 | 86 | .caret { 87 | border-top-color: @white; 88 | .opacity(75); 89 | } 90 | } 91 | 92 | 93 | 94 | // ALERTS 95 | // ----------------------------------------------------- 96 | 97 | // Removed text-shadow 98 | .alert { 99 | text-shadow: none !important; 100 | } 101 | 102 | -------------------------------------------------------------------------------- /views/new_post.jade: -------------------------------------------------------------------------------- 1 | extends index 2 | 3 | block navbar 4 | if user 5 | include includes/nav_in 6 | else 7 | include includes/nav_out 8 | 9 | block content 10 | if blog_post 11 | h2 Edit Blog Post 12 | else 13 | h2 New Blog Post 14 | form.form-horizontal(method="POST", role="form") 15 | div.form-group 16 | label.control-label.col-md-2 Title 17 | div.controls.col-md-8 18 | if blog_post 19 | input(type="text", name="title", placeholder="Title", class="form-control", value=blog_post.title, id="post_title") 20 | else 21 | input(type="text", name="title", placeholder="Title", class="form-control", id="post_title") 22 | div.form-group 23 | label.control-label.col-md-2 Unlisted 24 | div.controls.col-md-8 25 | if blog_post && blog_post.is_private 26 | input(type="checkbox", name="is_private", checked="checked", disabled="true", class="form-control") 27 | else if blog_post 28 | input(type="checkbox", name="is_private", disabled="true", class="form-control") 29 | else 30 | input(type="checkbox", name="is_private") 31 | div.form-group 32 | label.control-label.col-md-2 Allowed Viewers 33 | div.controls.col-md-8 34 | if blog_post && blog_post.is_private 35 | input(type="text", name="allowed_viewers", class="form-control", id="allowed_viewers", value=blog_post.allowed_viewers_string) 36 | else if blog_post 37 | input(type="text", name="allowed_viewers", class="form-control", id="allowed_viewers", value="", disabled="true") 38 | else 39 | input(type="text", name="allowed_viewers", class="form-control", id="allowed_viewers") 40 | div.form-group 41 | label.control-label.col-md-2 Body 42 | div.controls.col-md-8 43 | textarea(name="body", rows="20", cols="15", class="form-control", id="post_body") 44 | if blog_post 45 | =blog_post.draftText || blog_post.body 46 | div.form-group 47 | div.controls.col-md-8.col-md-offset-2 48 | if blog_post 49 | input(type="hidden", name="gistId", value=blog_post.gistIdStr) 50 | input.btn.btn-primary(type="submit") 51 | 52 | hr 53 | h2 Preview 54 | p A live preview of your post (including Markdown styling) will appear below 55 | hr 56 | 57 | div#preview 58 | 59 | block scripts_extra 60 | script(src="/js/marked.js", type="text/javascript") 61 | script(src="/js/compose.js", type="text/javascript") -------------------------------------------------------------------------------- /public/css/bootswatch/simplex/bootswatch.less: -------------------------------------------------------------------------------- 1 | // Bootswatch.less 2 | // Swatch: Simplex 3 | // ----------------------------------------------------- 4 | 5 | // TYPOGRAPHY 6 | // ----------------------------------------------------- 7 | 8 | // Make headers black 9 | h1, h2, h3, h4, h5, h6 { 10 | color: @black; 11 | } 12 | 13 | // NAVBAR 14 | // ----------------------------------------------------- 15 | 16 | // Gray text color 17 | .navbar .brand, .subnav a { 18 | color: @navbarText; 19 | } 20 | 21 | // Make active item white 22 | .navbar .nav .active > a, 23 | .navbar .nav .active > a:hover { 24 | background-color: @grayDarker; 25 | color: @white; 26 | } 27 | 28 | // Remove text-shadow and make white on hover 29 | .navbar .nav > li > a { 30 | text-shadow: none; 31 | &:hover { 32 | color: @white; 33 | background-color: rgba(256, 256, 256, 0.2); 34 | } 35 | } 36 | 37 | // Remove menu item dividers on subnav 38 | .subnav .nav > li > a { 39 | border-left: 0px solid white !important; 40 | border-right: 0px solid white !important; 41 | color: @grayDark; 42 | } 43 | 44 | .btn-navbar:hover { 45 | background-color: darken(@white, 20%); 46 | background-position: 0 0; 47 | } 48 | 49 | // FORMS 50 | // ----------------------------------------------------- 51 | 52 | // Style search input 53 | .search-query { 54 | border: 1px solid #CCC; 55 | .border-radius(2px); 56 | background-color: @white; 57 | } 58 | 59 | // BUTTONS 60 | // ----------------------------------------------------- 61 | 62 | // Make buttons boxier and flatter 63 | .btn { 64 | .border-radius(2px); 65 | #gradient > .vertical-three-colors(@white, @white, 25%, darken(@white, 10%)); 66 | } 67 | 68 | .btn-warning { 69 | .caret { 70 | border-top-color: @white; 71 | .opacity(75); 72 | } 73 | } 74 | 75 | .btn-primary { 76 | .buttonBackground(lighten(@primaryButtonBackground, 5%), @primaryButtonBackground); 77 | } 78 | 79 | .btn-warning { 80 | .buttonBackground(lighten(@orange, 5%), @orange); 81 | } 82 | 83 | .btn-danger { 84 | .buttonBackground(lighten(@red, 5%), @red); 85 | } 86 | 87 | .btn-success { 88 | .buttonBackground(lighten(@green, 5%), @green); 89 | } 90 | 91 | .btn-info { 92 | .buttonBackground(lighten(#5bc0de, 5%), #5bc0de); 93 | } 94 | 95 | .btn-inverse { 96 | .buttonBackground(lighten(@purple, 5%), @purple); 97 | } 98 | 99 | // ICONS 100 | // ----------------------------------------------------- 101 | 102 | // Make icons gray 103 | i[class^="icon-"]{ 104 | opacity: 0.6; 105 | } 106 | -------------------------------------------------------------------------------- /public/css/bootswatch/cerulean/bootswatch.less: -------------------------------------------------------------------------------- 1 | // Bootswatch.less 2 | // Swatch: Cerulean 3 | // ----------------------------------------------------- 4 | 5 | // TYPOGRAPHY 6 | // ----------------------------------------------------- 7 | 8 | @import url(http://fonts.googleapis.com/css?family=Telex); 9 | 10 | h1,h2,h3,h4,h5,h6, .navbar, .subnav { 11 | font-family: 'Telex', sans-serif; 12 | } 13 | 14 | h1,h2,h3,h4,h5,h6 { 15 | color: #317EAC 16 | } 17 | 18 | // NAVBAR 19 | // ----------------------------------------------------- 20 | 21 | .navbar-inner { 22 | #gradient > .vertical-three-colors(@navbarBackground, @navbarBackground, 90%, @navbarBackgroundHighlight); 23 | } 24 | 25 | .navbar .nav .active > a, 26 | .navbar .nav .active > a:hover { 27 | background-color: @navbarBackground; 28 | background-color: rgba(0,0,0,.2); 29 | } 30 | 31 | .navbar .search-query { 32 | border: 1px solid darken(@linkColor, 10%); 33 | } 34 | 35 | // responsive menu colors 36 | 37 | .navbar .nav-collapse > .nav > li .dropdown-menu a { 38 | color: @linkColor; 39 | 40 | &:hover { 41 | color: @white; 42 | } 43 | } 44 | 45 | .navbar .nav-collapse.collapse > .nav li > a { 46 | color: @white; 47 | 48 | &:hover { 49 | background-color: #2B7CAC; 50 | } 51 | } 52 | 53 | .btn-navbar:hover { 54 | background-color: darken(@white, 20%); 55 | background-position: 0 0; 56 | } 57 | 58 | // FORMS 59 | // ----------------------------------------------------- 60 | 61 | // Warning 62 | .control-group.warning { 63 | .formFieldState(@orange, @orange, @warningBackground); 64 | } 65 | // Error 66 | .control-group.error { 67 | .formFieldState(@red, @red, @errorBackground); 68 | } 69 | // Success 70 | .control-group.success { 71 | .formFieldState(darken(@green, 10%), darken(@green, 10%), @successBackground); 72 | } 73 | 74 | // BUTTONS 75 | // ----------------------------------------------------- 76 | 77 | .btn { 78 | #gradient > .vertical-three-colors(@white, @white, 5%, darken(@white, 0%)); 79 | @shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); 80 | .box-shadow(@shadow); 81 | } 82 | 83 | .btn-warning { 84 | .caret { 85 | border-top-color: @white; 86 | .opacity(75); 87 | } 88 | } 89 | 90 | .btn-primary { 91 | .buttonBackground(lighten(@linkColor, 5%), @linkColor); 92 | } 93 | 94 | .btn-warning { 95 | .buttonBackground(lighten(@orange, 5%), @orange); 96 | } 97 | 98 | .btn-danger { 99 | .buttonBackground(lighten(@red, 5%), @red); 100 | } 101 | 102 | .btn-success { 103 | .buttonBackground(lighten(@green, 5%), @green); 104 | } 105 | 106 | .btn-info { 107 | .buttonBackground(lighten(@purple, 5%), @purple); 108 | } 109 | 110 | .btn-inverse { 111 | .buttonBackground(lighten(@yellow, 5%), @yellow); 112 | } 113 | 114 | 115 | // ICONS 116 | // ----------------------------------------------------- 117 | 118 | // Make icons gray 119 | i[class^="icon-"]{ 120 | opacity: 0.8; 121 | } -------------------------------------------------------------------------------- /gh-api.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | var qs = require('querystring'); 3 | var sys = require('util'); 4 | var GitHubApi = require('github'); 5 | 6 | module.exports.GHAPI = function(access_token) { 7 | 8 | var self = this; 9 | 10 | 11 | this.api_base = "https://api.github.com/"; 12 | this.host = "api.github.com"; 13 | this.port = 443; 14 | this.api_path_base = "/"; 15 | this.access_token = access_token; 16 | 17 | this.client = new GitHubApi({ 18 | version: "3.0.0" 19 | }); 20 | 21 | var requestCallback = function(callback) { 22 | return function(err, res, data) { 23 | if (err) { 24 | callback(err, res, data); 25 | } else { 26 | callback(null, res, JSON.parse(data)); 27 | } 28 | }; 29 | }; 30 | 31 | var JSON_stringify = function(s, emit_unicode) { 32 | var json; 33 | json = JSON.stringify(s); 34 | if (emit_unicode) { 35 | return json; 36 | } 37 | return json.replace(/[\u007f-\uffff]/g, function(c) { 38 | return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4); 39 | }); 40 | }; 41 | 42 | 43 | var get = function(path, params, callback) { 44 | if (arguments.length == 2) { 45 | callback = params; 46 | params = {access_token: self.access_token}; 47 | } else { 48 | if (!params.access_token) { 49 | params.access_token = self.access_token; 50 | } 51 | } 52 | var full_path = self.api_base + path + "?" + qs.stringify(params); 53 | console.log(full_path); 54 | request(full_path, requestCallback(callback)); 55 | }; 56 | 57 | var do_request = function(method, path, params, callback) { 58 | if (!params.access_token) { 59 | params.access_token = self.access_token; 60 | } 61 | var opts = { 62 | uri: self.api_base + path, 63 | method: method, 64 | headers: { 65 | "Authorization": "Bearer " + params.access_token, 66 | "Content-type": "application/json" 67 | }, 68 | body: JSON_stringify(params) 69 | }; 70 | console.log(sys.inspect(opts)); 71 | var finalCallback = requestCallback(callback); 72 | request(opts, finalCallback); 73 | }; 74 | 75 | var post = function(path, params, callback) { 76 | do_request("POST", path, params, callback); 77 | }; 78 | 79 | var patch = function(path, params, callback) { 80 | do_request("PATCH", path, params, callback); 81 | }; 82 | 83 | var oauth_post = function(path, params, callback) { 84 | var opts = { 85 | uri: path, 86 | method: "POST", 87 | headers: { 88 | "Content-type": "application/json" 89 | }, 90 | body: JSON_stringify(params) 91 | }; 92 | console.log(sys.inspect(opts)); 93 | var finalCallback = requestCallback(callback); 94 | request(opts, finalCallback); 95 | 96 | }; 97 | 98 | this.getAccessToken = function(code, callback) { 99 | oauth_post("https://github.com/login/oauth/access_token", {code: code, client_id: process.env.GH_CONSUMER_KEY, client_secret: process.env.GH_CONSUMER_SECRET}, callback); 100 | }; 101 | 102 | this.request = function(gh_func, opts, callback) { 103 | if (this.access_token) { 104 | this.client.authenticate({type: "oauth", "token": this.access_token}); 105 | } 106 | gh_func(opts, callback); 107 | }; 108 | }; -------------------------------------------------------------------------------- /public/css/bootswatch/simplex/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // Swatch: Simplex 4 | // ----------------------------------------------------- 5 | 6 | 7 | 8 | // GLOBAL VALUES 9 | // -------------------------------------------------- 10 | 11 | // Links 12 | @linkColor: #366DDC; 13 | @linkColorHover: darken(@linkColor, 15%); 14 | 15 | // Grays 16 | @black: #000; 17 | @grayDarker: #2C2C2C; 18 | @grayDark: #333; 19 | @gray: #555; 20 | @grayLight: #999; 21 | @grayLighter: #EEE; 22 | @white: #fff; 23 | 24 | // Accent colors 25 | @blue: #15C; 26 | @blueDark: #043755; 27 | @green: #3D9400; 28 | @red: #E32C3B; 29 | @yellow: #FFCA27; 30 | @orange: #FF6600; 31 | @pink: #ED2590; 32 | @purple: #9B479F; 33 | 34 | // Typography 35 | @baseFontSize: 13px; 36 | @baseFontFamily: arial,sans-serif; 37 | @baseLineHeight: 18px; 38 | @textColor: @black; 39 | 40 | // Buttons 41 | @primaryButtonBackground: @linkColor; 42 | 43 | 44 | 45 | // COMPONENT VARIABLES 46 | // -------------------------------------------------- 47 | 48 | // Z-index master list 49 | // Used for a bird's eye view of components dependent on the z-axis 50 | // Try to avoid customizing these :) 51 | @zindexDropdown: 1000; 52 | @zindexPopover: 1010; 53 | @zindexTooltip: 1020; 54 | @zindexFixedNavbar: 1030; 55 | @zindexModalBackdrop: 1040; 56 | @zindexModal: 1050; 57 | 58 | // Sprite icons path 59 | @iconSpritePath: "../img/glyphicons-halflings.png"; 60 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 61 | 62 | // Input placeholder text color 63 | @placeholderText: @grayLight; 64 | 65 | // Hr border color 66 | @hrBorder: @grayLighter; 67 | 68 | // Navbar 69 | @navbarHeight: 40px; 70 | @navbarBackground: @grayDarker; 71 | @navbarBackgroundHighlight: @grayDarker; 72 | @navbarLinkBackgroundHover: transparent; 73 | 74 | @navbarText: #AAA; 75 | @navbarLinkColor: @navbarText; 76 | @navbarLinkColorHover: @gray; 77 | 78 | // Form states and alerts 79 | @warningText: #c09853; 80 | @warningBackground: #fcf8e3; 81 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 82 | 83 | @errorText: #b94a48; 84 | @errorBackground: #f2dede; 85 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 86 | 87 | @successText: #468847; 88 | @successBackground: #dff0d8; 89 | @successBorder: darken(spin(@successBackground, -10), 5%); 90 | 91 | @infoText: #3a87ad; 92 | @infoBackground: #d9edf7; 93 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 94 | 95 | 96 | 97 | // GRID 98 | // -------------------------------------------------- 99 | 100 | // Default 940px grid 101 | @gridColumns: 12; 102 | @gridColumnWidth: 60px; 103 | @gridGutterWidth: 20px; 104 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 105 | 106 | // Fluid grid 107 | @fluidGridColumnWidth: 6.382978723%; 108 | @fluidGridGutterWidth: 2.127659574%; 109 | -------------------------------------------------------------------------------- /public/css/bootswatch/journal/bootswatch.less: -------------------------------------------------------------------------------- 1 | // Bootswatch.less 2 | // Swatch: Journal 3 | // ----------------------------------------------------- 4 | 5 | // SCAFFOLDING 6 | // ----------------------------------------------------- 7 | 8 | body { 9 | background-color: @baseBackgroundColor !important; 10 | } 11 | 12 | a { 13 | text-decoration: underline; 14 | } 15 | 16 | .nav a, .navbar .brand, .subnav a, a.btn { 17 | text-decoration: none; 18 | } 19 | 20 | // TYPOGRAPHY 21 | // ----------------------------------------------------- 22 | 23 | @import url('http://fonts.googleapis.com/css?family=Open+Sans:400,700'); 24 | 25 | h1, h2, h3, h4, h5, h6, .brand, .navbar, .subnav a, blockquote > p { 26 | font-family: 'Open Sans', sans-serif; 27 | color: @textColor; 28 | } 29 | 30 | h1, h2, h3, h4, h5, h6, .brand { 31 | font-weight: 700; 32 | } 33 | 34 | // NAVBAR 35 | // ----------------------------------------------------- 36 | 37 | .navbar .brand { 38 | color: @navbarLinkColor; 39 | text-shadow: none; 40 | font-weight: bold; 41 | 42 | &:hover { 43 | background-color: #EEEEEE; 44 | } 45 | } 46 | 47 | .navbar-inner { 48 | border-top: 1px solid #E5E5E5; 49 | @shadow: 0 2px 4px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); 50 | .box-shadow(@shadow); 51 | } 52 | 53 | .navbar-inner, .navbar .dropdown-menu, div.subnav, .table-bordered, .well, .prettyprint, 54 | div.subnav .nav > li:first-child > a, div.subnav .nav > li:first-child > a:hover { 55 | .border-radius(0); 56 | } 57 | 58 | .navbar .nav > li > a { 59 | text-shadow: none; 60 | } 61 | 62 | .navbar .nav .active > a, 63 | .navbar .nav .active > a:hover { 64 | color: @navbarLinkColor; 65 | background-color: rgba(0, 0, 0, 0); 66 | } 67 | 68 | .navbar .nav .active > a:hover, 69 | .navbar .nav > li > a:hover, 70 | .navbar .nav-collapse .nav li > a:hover { 71 | background-color: #EEEEEE; 72 | } 73 | 74 | .navbar .nav .dropdown-toggle .caret, 75 | .navbar .nav .open.dropdown .caret { 76 | border-top-color: @navbarLinkColor; 77 | opacity: 1; 78 | } 79 | 80 | form.navbar-form, form.navbar-search { 81 | border-top: 0px solid #eee; 82 | border-bottom: 0px solid #eee; 83 | } 84 | 85 | .navbar-search .search-query, 86 | .navbar-search .search-query:hover { 87 | border: 1px solid @grayLighter; 88 | color: @textColor; 89 | .placeholder(@gray); 90 | } 91 | 92 | .dropdown-menu { 93 | background-color: @baseBackgroundColor; 94 | 95 | a { 96 | color: @textColor; 97 | } 98 | 99 | li:hover > a { 100 | background-color: #eee; 101 | color: @textColor; 102 | } 103 | } 104 | 105 | div.subnav { 106 | background-color: @baseBackgroundColor; 107 | background-image: none; 108 | @shadow: 0 1px 2px rgba(0,0,0,.25); 109 | .box-shadow(@shadow); 110 | } 111 | 112 | .navbar .nav-collapse .nav li > a, 113 | div.subnav .nav > li > a:hover, 114 | div.subnav .nav > .active > a, 115 | div.subnav .nav > .active > a:hover { 116 | color: @textColor; 117 | text-decoration: none; 118 | font-weight: normal; 119 | } 120 | 121 | // BUTTONS 122 | // ----------------------------------------------------- 123 | 124 | .btn-primary { 125 | .buttonBackground(lighten(@linkColor, 5%), @linkColor); 126 | } 127 | 128 | 129 | // MISC 130 | // ----------------------------------------------------- 131 | 132 | // make shaded elements lightGray 133 | code, pre, pre.prettyprint, .well, .form-actions, 134 | .table-striped tbody tr:nth-child(odd) td, 135 | .table-striped tbody tr:nth-child(odd) th { 136 | background-color: @grayLighter; 137 | } 138 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , routes = require('./routes') 8 | , auth = require('connect-auth') 9 | , MongoStore = require('connect-mongo')(express) 10 | , config = require('./config') 11 | , mongoose = require('mongoose'); 12 | 13 | mongoose.connect(config.mongo_uri); 14 | 15 | var app = express(); //module.exports = express.createServer(); 16 | 17 | // Configuration 18 | 19 | app.configure(function(){ 20 | app.set('views', __dirname + '/views'); 21 | app.set('view engine', 'jade'); 22 | app.set('view options', {layout: false, pretty: false}); 23 | app.use(express.bodyParser()); 24 | app.use(express.cookieParser()); 25 | app.use(express.session({ 26 | secret: config.express_session_secret, 27 | store: new MongoStore({ 28 | url: config.mongo_uri, 29 | db: "gistblog_sessions", 30 | auto_reconnect: true, 31 | clear_interval: 600 32 | }, function() {console.log("connected to mongo!");}) 33 | })); 34 | 35 | app.use(express.methodOverride()); 36 | app.use(express.static(__dirname + '/public')); 37 | app.use(app.router); 38 | }); 39 | 40 | app.configure('development', function(){ 41 | app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 42 | //app.locals.pretty = true; 43 | }); 44 | 45 | app.configure('production', function(){ 46 | app.use(express.errorHandler()); 47 | }); 48 | 49 | var protect = function(req, res, next) { 50 | if (req.session.user) { 51 | next(); 52 | } else { 53 | res.redirect('/'); 54 | } 55 | }; 56 | 57 | var admin = function(req, res, next) { 58 | console.log('check 1: ' + req.session.user.is_admin); 59 | console.log('check 2: ' + req.session.user.userid); 60 | if (req.session.user && req.session.user.is_admin == true) { 61 | next(); 62 | } else { 63 | res.redirect('/'); 64 | } 65 | }; 66 | 67 | var access_restricted = function(req, res, next) { 68 | if (!config.is_multitenant && req.session.user && req.session.user.is_admin == true) { 69 | next(); 70 | } else if (config.is_multitenant && config.allowed_users && config.allowed_users.length) { 71 | var username = req.session.user.username.toLowerCase(); 72 | if (config.allowed_users.indexOf(username) !== -1) { 73 | next(); 74 | } else { 75 | res.redirect('/'); 76 | } 77 | } else { 78 | res.redirect('/'); 79 | } 80 | 81 | }; 82 | 83 | // Routes 84 | 85 | app.get('/', routes.index); 86 | 87 | app.get('/about', routes.about); 88 | 89 | app.get('/compose', protect, access_restricted, routes.new_post); 90 | app.post('/compose', protect, access_restricted, routes.create_post); 91 | 92 | 93 | app.get('/edit/:id', protect, access_restricted, routes.edit_post); 94 | app.post('/edit/:id', protect, access_restricted, routes.update_post_gist); 95 | 96 | 97 | app.get('/login', routes.login); 98 | app.get('/logout', routes.logout); 99 | 100 | app.get('/oauth/callback', routes.oauth_return); 101 | 102 | app.post('/ajax/human_view/:id', routes.ajax_human_view); 103 | 104 | //app.get('/p/:id', routes.bounce_shortid); 105 | //app.get('/:id', routes.view_post); 106 | 107 | app.get('/gist/:id', routes.view_post); 108 | app.get('/post/:id', routes.view_post); 109 | 110 | app.get('/user/:username', routes.user_index); 111 | 112 | var port = process.env.PORT || 3000; 113 | app.listen(port, function(){ 114 | console.log("Express server listening on port %d in %s mode", process.env.PORT, app.settings.env); 115 | }); 116 | -------------------------------------------------------------------------------- /public/css/bootswatch/default/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // ----------------------------------------------------- 4 | 5 | 6 | 7 | // GLOBAL VALUES 8 | // -------------------------------------------------- 9 | 10 | // Links 11 | @linkColor: #08c; 12 | @linkColorHover: darken(@linkColor, 15%); 13 | 14 | // Grays 15 | @black: #000; 16 | @grayDarker: #222; 17 | @grayDark: #333; 18 | @gray: #555; 19 | @grayLight: #999; 20 | @grayLighter: #eee; 21 | @white: #fff; 22 | 23 | // Accent colors 24 | @blue: #049cdb; 25 | @blueDark: #0064cd; 26 | @green: #46a546; 27 | @red: #9d261d; 28 | @yellow: #ffc40d; 29 | @orange: #f89406; 30 | @pink: #c3325f; 31 | @purple: #7a43b6; 32 | 33 | // Typography 34 | @baseFontSize: 13px; 35 | @baseFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; 36 | @baseLineHeight: 18px; 37 | @textColor: @grayDark; 38 | 39 | // Buttons 40 | @primaryButtonBackground: @linkColor; 41 | 42 | 43 | 44 | // COMPONENT VARIABLES 45 | // -------------------------------------------------- 46 | 47 | // Z-index master list 48 | // Used for a bird's eye view of components dependent on the z-axis 49 | // Try to avoid customizing these :) 50 | @zindexDropdown: 1000; 51 | @zindexPopover: 1010; 52 | @zindexTooltip: 1020; 53 | @zindexFixedNavbar: 1030; 54 | @zindexModalBackdrop: 1040; 55 | @zindexModal: 1050; 56 | 57 | // Sprite icons path 58 | @iconSpritePath: "../img/glyphicons-halflings.png"; 59 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 60 | 61 | // Input placeholder text color 62 | @placeholderText: @grayLight; 63 | 64 | // Hr border color 65 | @hrBorder: @grayLighter; 66 | 67 | // Navbar 68 | @navbarHeight: 40px; 69 | @navbarBackground: @grayDarker; 70 | @navbarBackgroundHighlight: @grayDark; 71 | @navbarLinkBackgroundHover: transparent; 72 | 73 | @navbarText: @grayLight; 74 | @navbarLinkColor: @grayLight; 75 | @navbarLinkColorHover: @white; 76 | 77 | // Form states and alerts 78 | @warningText: #c09853; 79 | @warningBackground: #fcf8e3; 80 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 81 | 82 | @errorText: #b94a48; 83 | @errorBackground: #f2dede; 84 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 85 | 86 | @successText: #468847; 87 | @successBackground: #dff0d8; 88 | @successBorder: darken(spin(@successBackground, -10), 5%); 89 | 90 | @infoText: #3a87ad; 91 | @infoBackground: #d9edf7; 92 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 93 | 94 | 95 | 96 | // GRID 97 | // -------------------------------------------------- 98 | 99 | // Default 940px grid 100 | @gridColumns: 12; 101 | @gridColumnWidth: 60px; 102 | @gridGutterWidth: 20px; 103 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 104 | 105 | // Fluid grid 106 | @fluidGridColumnWidth: 6.382978723%; 107 | @fluidGridGutterWidth: 2.127659574%; 108 | -------------------------------------------------------------------------------- /public/css/bootswatch/spacelab/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // Swatch: Spacelab 4 | // ----------------------------------------------------- 5 | 6 | 7 | // GLOBAL VALUES 8 | // -------------------------------------------------- 9 | 10 | // Links 11 | @linkColor: #4183C4; 12 | @linkColorHover: #4183C4; 13 | 14 | // Grays 15 | @black: #000; 16 | @grayDarker: #222; 17 | @grayDark: #333; 18 | @gray: #555; 19 | @grayLight: #999; 20 | @grayLighter: #eee; 21 | @white: #fff; 22 | 23 | // Accent colors 24 | @blue: #4183C4; 25 | @blueDark: #405A6A; 26 | @green: #84DE81; 27 | @red: #E5322C; 28 | @yellow: #F4CA00; 29 | @orange: #FF7D00; 30 | @pink: #F44B8C; 31 | @purple: #405A6A; 32 | 33 | // Typography 34 | @baseFontSize: 13px; 35 | @baseFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; 36 | @baseLineHeight: 18px; 37 | @textColor: @grayDark; 38 | 39 | // sans 40 | @primaryButtonBackground: @linkColor; 41 | 42 | 43 | 44 | // COMPONENT VARIABLES 45 | // -------------------------------------------------- 46 | 47 | // Z-index master list 48 | // Used for a bird's eye view of components dependent on the z-axis 49 | // Try to avoid customizing these :) 50 | @zindexDropdown: 1000; 51 | @zindexPopover: 1010; 52 | @zindexTooltip: 1020; 53 | @zindexFixedNavbar: 1030; 54 | @zindexModalBackdrop: 1040; 55 | @zindexModal: 1050; 56 | 57 | // Sprite icons path 58 | @iconSpritePath: "../img/glyphicons-halflings.png"; 59 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 60 | 61 | // Input placeholder text color 62 | @placeholderText: @grayLight; 63 | 64 | // Hr border color 65 | @hrBorder: @grayLighter; 66 | 67 | // Navbar 68 | @navbarHeight: 40px; 69 | @navbarBackground: #EAEAEA; 70 | @navbarBackgroundHighlight: lighten(@navbarBackground, 15%); 71 | @navbarLinkBackgroundHover: transparent; 72 | 73 | @navbarText: @grayDarker; 74 | @navbarLinkColor: @grayDarker; 75 | @navbarLinkColorHover: @linkColor; 76 | 77 | // Form states and alerts 78 | @warningText: #393939; 79 | @warningBackground: #F5F3B4; 80 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 81 | 82 | @errorText: @warningText; 83 | @errorBackground: #FFE9E9; 84 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 85 | 86 | @successText: #333; 87 | @successBackground: #BEDEBE; 88 | @successBorder: darken(spin(@successBackground, -10), 5%); 89 | 90 | @infoText: #1B3650; 91 | @infoBackground: #E4F0FF; 92 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 93 | 94 | 95 | 96 | // GRID 97 | // -------------------------------------------------- 98 | 99 | // Default 940px grid 100 | @gridColumns: 12; 101 | @gridColumnWidth: 60px; 102 | @gridGutterWidth: 20px; 103 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 104 | 105 | // Fluid grid 106 | @fluidGridColumnWidth: 6.382978723%; 107 | @fluidGridGutterWidth: 2.127659574%; 108 | -------------------------------------------------------------------------------- /public/css/bootswatch/slate/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // Swatch: Slate 4 | // ----------------------------------------------------- 5 | 6 | 7 | 8 | // GLOBAL VALUES 9 | // -------------------------------------------------- 10 | 11 | // Links 12 | @linkColor: @white; 13 | @linkColorHover: @white; 14 | 15 | // Grays 16 | @black: #000; 17 | @grayDarker: #272B30; 18 | @grayDark: #3A3F44; 19 | @gray: #52575C; 20 | @grayLight: #757C82; 21 | @grayLighter: #BBBFC2; 22 | @white: #fff; 23 | 24 | // Accent colors 25 | @blue: #02A1DD; 26 | @blueDark: #108CBB; 27 | @green: #87CA4D; 28 | @red: #9d261d; 29 | @yellow: #F6D30D; 30 | @orange: #f89406; 31 | @pink: #c3325f; 32 | @purple: #7a43b6; 33 | 34 | // Typography 35 | @baseFontSize: 13px; 36 | @baseFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; 37 | @baseLineHeight: 18px; 38 | @textColor: @grayLight; 39 | 40 | // Buttons 41 | @primaryButtonBackground: @grayLight; 42 | 43 | 44 | 45 | // COMPONENT VARIABLES 46 | // -------------------------------------------------- 47 | 48 | // Z-index master list 49 | // Used for a bird's eye view of components dependent on the z-axis 50 | // Try to avoid customizing these :) 51 | @zindexDropdown: 1000; 52 | @zindexPopover: 1010; 53 | @zindexTooltip: 1020; 54 | @zindexFixedNavbar: 1030; 55 | @zindexModalBackdrop: 1040; 56 | @zindexModal: 1050; 57 | 58 | // Sprite icons path 59 | @iconSpritePath: "../img/glyphicons-halflings.png"; 60 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 61 | 62 | // Input placeholder text color 63 | @placeholderText: @grayLight; 64 | 65 | // Hr border color 66 | @hrBorder: @grayLight; 67 | 68 | // Navbar 69 | @navbarHeight: 40px; 70 | @navbarBackground: @grayDark; 71 | @navbarBackgroundHighlight: @gray; 72 | @navbarLinkBackgroundHover: transparent; 73 | 74 | @navbarText: @textColor; 75 | @navbarLinkColor: @grayLighter; 76 | @navbarLinkColorHover: @grayLighter; 77 | 78 | // Form states and alerts 79 | @warningText: #c09853; 80 | @warningBackground: #fcf8e3; 81 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 82 | 83 | @errorText: #b94a48; 84 | @errorBackground: #f2dede; 85 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 86 | 87 | @successText: #468847; 88 | @successBackground: #dff0d8; 89 | @successBorder: darken(spin(@successBackground, -10), 5%); 90 | 91 | @infoText: #3a87ad; 92 | @infoBackground: #d9edf7; 93 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 94 | 95 | 96 | 97 | // GRID 98 | // -------------------------------------------------- 99 | 100 | // Default 940px grid 101 | @gridColumns: 12; 102 | @gridColumnWidth: 60px; 103 | @gridGutterWidth: 20px; 104 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 105 | 106 | // Fluid grid 107 | @fluidGridColumnWidth: 6.382978723%; 108 | @fluidGridGutterWidth: 2.127659574%; 109 | -------------------------------------------------------------------------------- /public/css/bootswatch/superhero/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // Swatch: Superhero 4 | // ----------------------------------------------------- 5 | 6 | 7 | 8 | // GLOBAL VALUES 9 | // -------------------------------------------------- 10 | 11 | // Links 12 | @linkColor: @orange; 13 | @linkColorHover: @linkColor; 14 | 15 | // Grays 16 | @black: #000; 17 | @grayDarker: #222; 18 | @grayDark: #333; 19 | @gray: #555; 20 | @grayLight: #999; 21 | @grayLighter: #eee; 22 | @white: #fff; 23 | 24 | // Accent colors 25 | @blue: #45515F; 26 | @blueDark: #2A333C; 27 | @green: #5DA028; 28 | @red: #A12932; 29 | @yellow: #E6C92E; 30 | @orange: #E36B23; 31 | @pink: #C74871; 32 | @purple: #7073CF; 33 | 34 | // Typography 35 | @baseFontSize: 15px; 36 | @baseFontFamily: Georgia,Utopia,Palatino,'Palatino Linotype',serif; 37 | @baseLineHeight: 20px; 38 | @textColor: #ECE9D7; 39 | 40 | // Buttons 41 | @primaryButtonBackground: @linkColor; 42 | 43 | 44 | 45 | // COMPONENT VARIABLES 46 | // -------------------------------------------------- 47 | 48 | // Z-index master list 49 | // Used for a bird's eye view of components dependent on the z-axis 50 | // Try to avoid customizing these :) 51 | @zindexDropdown: 1000; 52 | @zindexPopover: 1010; 53 | @zindexTooltip: 1020; 54 | @zindexFixedNavbar: 1030; 55 | @zindexModalBackdrop: 1040; 56 | @zindexModal: 1050; 57 | 58 | // Sprite icons path 59 | @iconSpritePath: "../img/glyphicons-halflings.png"; 60 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 61 | 62 | // Input placeholder text color 63 | @placeholderText: @textColor; 64 | 65 | // Hr border color 66 | @hrBorder: darken(@blueDark, 5%); 67 | 68 | // Navbar 69 | @navbarHeight: 40px; 70 | @navbarBackground: @blueDark; 71 | @navbarBackgroundHighlight: @navbarBackground; 72 | @navbarLinkBackgroundHover: transparent; 73 | 74 | @navbarText: @grayLight; 75 | @navbarLinkColor: @grayLight; 76 | @navbarLinkColorHover: @white; 77 | 78 | // Form states and alerts 79 | @warningText: #c09853; 80 | @warningBackground: #fcf8e3; 81 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 82 | 83 | @errorText: #b94a48; 84 | @errorBackground: #f2dede; 85 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 86 | 87 | @successText: #468847; 88 | @successBackground: #dff0d8; 89 | @successBorder: darken(spin(@successBackground, -10), 5%); 90 | 91 | @infoText: #3a87ad; 92 | @infoBackground: #d9edf7; 93 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 94 | 95 | 96 | 97 | // GRID 98 | // -------------------------------------------------- 99 | 100 | // Default 940px grid 101 | @gridColumns: 12; 102 | @gridColumnWidth: 60px; 103 | @gridGutterWidth: 20px; 104 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 105 | 106 | // Fluid grid 107 | @fluidGridColumnWidth: 6.382978723%; 108 | @fluidGridGutterWidth: 2.127659574%; 109 | -------------------------------------------------------------------------------- /public/css/bootswatch/readable/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // Swatch: Readable 4 | // ----------------------------------------------------- 5 | 6 | 7 | 8 | // GLOBAL VALUES 9 | // -------------------------------------------------- 10 | 11 | // Links 12 | @linkColor: @red; 13 | @linkColorHover: lighten(@linkColor, 8%); 14 | 15 | // Grays 16 | @black: #000; 17 | @grayDarker: #222; 18 | @grayDark: #333; 19 | @gray: #777; 20 | @grayLight: #999; 21 | @grayLighter: #CDCDCD; 22 | @white: #fff; 23 | 24 | // Accent colors 25 | @blue: #049cdb; 26 | @blueDark: #0064cd; 27 | @green: #46a546; 28 | @red: #9C0001; 29 | @yellow: #ffc40d; 30 | @orange: #f89406; 31 | @pink: #c3325f; 32 | @purple: #7a43b6; 33 | 34 | // Typography 35 | @baseFontSize: 19px; 36 | @baseFontFamily: Georgia, "Times New Roman", serif; 37 | @baseLineHeight: 1.6em; 38 | @textColor: #090000; 39 | 40 | // Buttons 41 | @primaryButtonBackground: @linkColor; 42 | 43 | 44 | 45 | // COMPONENT VARIABLES 46 | // -------------------------------------------------- 47 | 48 | // Z-index master list 49 | // Used for a bird's eye view of components dependent on the z-axis 50 | // Try to avoid customizing these :) 51 | @zindexDropdown: 1000; 52 | @zindexPopover: 1010; 53 | @zindexTooltip: 1020; 54 | @zindexFixedNavbar: 1030; 55 | @zindexModalBackdrop: 1040; 56 | @zindexModal: 1050; 57 | 58 | // Sprite icons path 59 | @iconSpritePath: "../img/glyphicons-halflings.png"; 60 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 61 | 62 | // Input placeholder text color 63 | @placeholderText: @gray; 64 | 65 | // Hr border color 66 | @hrBorder: @grayLighter; 67 | 68 | // Navbar 69 | @navbarHeight: 40px; 70 | @navbarBackground: @bodyBackgroundColor; 71 | @navbarBackgroundHighlight: @bodyBackgroundColor; 72 | @navbarLinkBackgroundHover: @bodyBackgroundColor; 73 | 74 | @navbarText: @textColor; 75 | @navbarLinkColor: @linkColor; 76 | @navbarLinkColorHover: @linkColorHover; 77 | 78 | // Form states and alerts 79 | @warningText: #c09853; 80 | @warningBackground: #fcf8e3; 81 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 82 | 83 | @errorText: #b94a48; 84 | @errorBackground: #f2dede; 85 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 86 | 87 | @successText: #468847; 88 | @successBackground: #dff0d8; 89 | @successBorder: darken(spin(@successBackground, -10), 5%); 90 | 91 | @infoText: #3a87ad; 92 | @infoBackground: #d9edf7; 93 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 94 | 95 | 96 | 97 | // GRID 98 | // -------------------------------------------------- 99 | 100 | // Default 940px grid 101 | @gridColumns: 12; 102 | @gridColumnWidth: 60px; 103 | @gridGutterWidth: 20px; 104 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 105 | 106 | // Fluid grid 107 | @fluidGridColumnWidth: 6.382978723%; 108 | @fluidGridGutterWidth: 2.127659574%; 109 | -------------------------------------------------------------------------------- /public/css/bootswatch/cyborg/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // Swatch: Cyborg 4 | // ----------------------------------------------------- 5 | 6 | // CUSTOM VALUES 7 | // -------------------------------------------------- 8 | 9 | 10 | // GLOBAL VALUES 11 | // -------------------------------------------------- 12 | 13 | // Links 14 | @linkColor: @blue; 15 | @linkColorHover: @white; 16 | 17 | // Grays 18 | @black: #000; 19 | @grayDarker: #020202; 20 | @grayDark: #282828; 21 | @gray: #999; 22 | @grayLight: #ADAFAE; 23 | @grayLighter: #eee; 24 | @white: #fff; 25 | 26 | // Accent colors 27 | @blue: #33B5E5; 28 | @blueDark: #0099CC; 29 | @green: #669900; 30 | @red: #CC0000; 31 | @yellow: #ECBB13; 32 | @orange: #FF8800; 33 | @pink: #FF4444; 34 | @purple: #9933CC; 35 | 36 | // Typography 37 | @baseFontSize: 13px; 38 | @baseFontFamily: 'Droid Sans', sans-serif; 39 | @baseLineHeight: 18px; 40 | @textColor: @gray; 41 | 42 | // Buttons 43 | @primaryButtonBackground: @blue; 44 | 45 | 46 | 47 | // COMPONENT VARIABLES 48 | // -------------------------------------------------- 49 | 50 | // Z-index master list 51 | // Used for a bird's eye view of components dependent on the z-axis 52 | // Try to avoid customizing these :) 53 | @zindexDropdown: 1000; 54 | @zindexPopover: 1010; 55 | @zindexTooltip: 1020; 56 | @zindexFixedNavbar: 1030; 57 | @zindexModalBackdrop: 1040; 58 | @zindexModal: 1050; 59 | 60 | // Sprite icons path 61 | @iconSpritePath: "../img/glyphicons-halflings.png"; 62 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 63 | 64 | // Input placeholder text color 65 | @placeholderText: @grayLight; 66 | 67 | // Hr border color 68 | @hrBorder: @grayDark; 69 | 70 | // Navbar 71 | @navbarHeight: 40px; 72 | @navbarBackground: @grayDarker; 73 | @navbarBackgroundHighlight: @grayDarker; 74 | @navbarLinkBackgroundHover: transparent; 75 | 76 | @navbarText: @grayLight; 77 | @navbarLinkColor: @grayLight; 78 | @navbarLinkColorHover: @white; 79 | 80 | // Form states and alerts 81 | @warningText: darken(#c09853, 10%); 82 | @warningBackground: @grayLighter; 83 | @warningBorder: transparent; 84 | 85 | @errorText: #b94a48; 86 | @errorBackground: @grayLighter; 87 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 88 | 89 | @successText: #468847; 90 | @successBackground: @grayLighter; 91 | @successBorder: darken(spin(@successBackground, -10), 5%); 92 | 93 | @infoText: @blueDark; 94 | @infoBackground: @grayLighter; 95 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 96 | 97 | 98 | 99 | // GRID 100 | // -------------------------------------------------- 101 | 102 | // Default 940px grid 103 | @gridColumns: 12; 104 | @gridColumnWidth: 60px; 105 | @gridGutterWidth: 20px; 106 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 107 | 108 | // Fluid grid 109 | @fluidGridColumnWidth: 6.382978723%; 110 | @fluidGridGutterWidth: 2.127659574%; 111 | -------------------------------------------------------------------------------- /public/css/bootswatch/united/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // Swatch: United 4 | // ----------------------------------------------------- 5 | 6 | 7 | 8 | // GLOBAL VALUES 9 | // -------------------------------------------------- 10 | 11 | // Links 12 | @linkColor: #DD4814; 13 | @linkColorHover: darken(@linkColor, 15%); 14 | 15 | // Grays 16 | @black: #000; 17 | @grayDarker: #222; 18 | @grayDark: #333; 19 | @gray: #555; 20 | @grayLight: #999; 21 | @grayLighter: #eee; 22 | @white: #fff; 23 | 24 | // Accent colors 25 | @blue: #19B6EE; 26 | @blueDark: #0064cd; 27 | @green: #38B44A; 28 | @red: #DF382C; 29 | @yellow: #EFB73E; 30 | @orange: #DD4814; 31 | @pink: #c3325f; 32 | @purple: #772953; 33 | 34 | // Typography 35 | @baseFontSize: 13px; 36 | @baseFontFamily: 'Ubuntu', Tahoma, sans-serif; 37 | @baseLineHeight: 18px; 38 | @textColor: @grayDark; 39 | 40 | // Buttons 41 | @primaryButtonBackground: @linkColor; 42 | 43 | 44 | 45 | // COMPONENT VARIABLES 46 | // -------------------------------------------------- 47 | 48 | // Z-index master list 49 | // Used for a bird's eye view of components dependent on the z-axis 50 | // Try to avoid customizing these :) 51 | @zindexDropdown: 1000; 52 | @zindexPopover: 1010; 53 | @zindexTooltip: 1020; 54 | @zindexFixedNavbar: 1030; 55 | @zindexModalBackdrop: 1040; 56 | @zindexModal: 1050; 57 | 58 | // Sprite icons path 59 | @iconSpritePath: "../img/glyphicons-halflings.png"; 60 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 61 | 62 | // Input placeholder text color 63 | @placeholderText: @grayLight; 64 | 65 | // Hr border color 66 | @hrBorder: @grayLighter; 67 | 68 | // Navbar 69 | @navbarHeight: 40px; 70 | @navbarBackground: #DD4814; 71 | @navbarBackgroundHighlight: #CE4213; 72 | @navbarLinkBackgroundHover: transparent; 73 | 74 | @navbarText: @white; 75 | @navbarLinkColor: @white; 76 | @navbarLinkColorHover: @white; 77 | 78 | // Form states and alerts 79 | @warningText: #ECA918; 80 | @warningBackground: lighten(@warningText, 40%); 81 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 82 | 83 | @errorText: #DF382C; 84 | @errorBackground: lighten(@errorText, 40%); 85 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 86 | 87 | @successText: #38B44A; 88 | @successBackground: lighten(@successText, 40%); 89 | @successBorder: darken(spin(@successBackground, -10), 5%); 90 | 91 | @infoText: #19B6EE; 92 | @infoBackground: lighten(@infoText, 40%); 93 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 94 | 95 | 96 | 97 | // GRID 98 | // -------------------------------------------------- 99 | 100 | // Default 940px grid 101 | @gridColumns: 12; 102 | @gridColumnWidth: 60px; 103 | @gridGutterWidth: 20px; 104 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 105 | 106 | // Fluid grid 107 | @fluidGridColumnWidth: 6.382978723%; 108 | @fluidGridGutterWidth: 2.127659574%; 109 | 110 | 111 | -------------------------------------------------------------------------------- /public/css/bootswatch/spruce/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // Swatch: Vintage 4 | // ----------------------------------------------------- 5 | 6 | 7 | 8 | // GLOBAL VALUES 9 | // -------------------------------------------------- 10 | 11 | // Links 12 | @linkColor: #F5F3DC; 13 | @linkColorHover: @yellow; 14 | 15 | // Grays 16 | @black: #000; 17 | @grayDarker: #222; 18 | @grayDark: #333; 19 | @gray: #555; 20 | @grayLight: #999; 21 | @grayLighter: #eee; 22 | @white: #fff; 23 | 24 | // Accent colors 25 | @blue: #01584C; 26 | @blueDark: #013435; 27 | @green: #015B4E; 28 | @red: #D14432; 29 | @yellow: #EBD90B; 30 | @orange: #FCB46B; 31 | @pink: #A15B66; 32 | @purple: #7073CF; 33 | 34 | // Typography 35 | @baseFontSize: 14px; 36 | @baseFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; 37 | @baseLineHeight: 21px; 38 | @textColor: @blueDark; 39 | 40 | // Buttons 41 | @primaryButtonBackground: @linkColor; 42 | 43 | 44 | 45 | // COMPONENT VARIABLES 46 | // -------------------------------------------------- 47 | 48 | // Z-index master list 49 | // Used for a bird's eye view of components dependent on the z-axis 50 | // Try to avoid customizing these :) 51 | @zindexDropdown: 1000; 52 | @zindexPopover: 1010; 53 | @zindexTooltip: 1020; 54 | @zindexFixedNavbar: 1030; 55 | @zindexModalBackdrop: 1040; 56 | @zindexModal: 1050; 57 | 58 | // Sprite icons path 59 | @iconSpritePath: "../img/glyphicons-halflings.png"; 60 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 61 | 62 | // Input placeholder text color 63 | @placeholderText: @textColor; 64 | 65 | // Hr border color 66 | @hrBorder: darken(@blueDark, 5%); 67 | 68 | // Navbar 69 | @navbarHeight: 40px; 70 | @navbarBackground: @blueDark; 71 | @navbarBackgroundHighlight: @navbarBackground; 72 | @navbarLinkBackgroundHover: transparent; 73 | 74 | @navbarText: @grayLight; 75 | @navbarLinkColor: @grayLight; 76 | @navbarLinkColorHover: @white; 77 | 78 | // Form states and alerts 79 | @warningText: @orange; 80 | @warningBackground: darken(#90A38F, 10%); 81 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 82 | 83 | @errorText: lighten(@red, 25%); 84 | @errorBackground: darken(#90A38F, 10%); 85 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 86 | 87 | @successText: #9ED99C; 88 | @successBackground: darken(#90A38F, 10%); 89 | @successBorder: darken(spin(@successBackground, -10), 5%); 90 | 91 | @infoText: #9BCACD; 92 | @infoBackground: darken(#90A38F, 10%); 93 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 94 | 95 | 96 | 97 | // GRID 98 | // -------------------------------------------------- 99 | 100 | // Default 940px grid 101 | @gridColumns: 12; 102 | @gridColumnWidth: 60px; 103 | @gridGutterWidth: 20px; 104 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 105 | 106 | // Fluid grid 107 | @fluidGridColumnWidth: 6.382978723%; 108 | @fluidGridGutterWidth: 2.127659574%; 109 | -------------------------------------------------------------------------------- /public/css/bootswatch/cerulean/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // Swatch: Cerulean 4 | // ----------------------------------------------------- 5 | 6 | 7 | 8 | // GLOBAL VALUES 9 | // -------------------------------------------------- 10 | 11 | // Links 12 | @linkColor: #369BD7; 13 | @linkColorHover: darken(@linkColor, 15%); 14 | 15 | // Grays 16 | @black: #000; 17 | @grayDarker: #222; 18 | @grayDark: #333; 19 | @gray: #555; 20 | @grayLight: #999; 21 | @grayLighter: #eee; 22 | @white: #fff; 23 | 24 | // Accent colors 25 | @blue: #3E78B3; 26 | @blueDark: #033C73; 27 | @green: #73A839; 28 | @red: #C71C22; 29 | @yellow: #F7B42C; 30 | @orange: #DD5600; 31 | @pink: #F49AC1; 32 | @purple: #9760B3; 33 | 34 | // Typography 35 | @baseFontSize: 13px; 36 | @baseFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; 37 | @baseLineHeight: 18px; 38 | @textColor: @gray; 39 | 40 | // Buttons 41 | @primaryButtonBackground: @linkColor; 42 | 43 | 44 | 45 | // COMPONENT VARIABLES 46 | // -------------------------------------------------- 47 | 48 | // Z-index master list 49 | // Used for a bird's eye view of components dependent on the z-axis 50 | // Try to avoid customizing these :) 51 | @zindexDropdown: 1000; 52 | @zindexPopover: 1010; 53 | @zindexTooltip: 1020; 54 | @zindexFixedNavbar: 1030; 55 | @zindexModalBackdrop: 1040; 56 | @zindexModal: 1050; 57 | 58 | // Sprite icons path 59 | @iconSpritePath: "../img/glyphicons-halflings.png"; 60 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 61 | 62 | // Input placeholder text color 63 | @placeholderText: @grayLight; 64 | 65 | // Hr border color 66 | @hrBorder: @grayLighter; 67 | 68 | // Navbar 69 | @navbarHeight: 40px; 70 | @navbarBackground: @linkColor; 71 | @navbarBackgroundHighlight: lighten(@linkColor, 10%); 72 | @navbarLinkBackgroundHover: transparent; 73 | 74 | @navbarText: @grayLighter; 75 | @navbarLinkColor: @grayLighter; 76 | @navbarLinkColorHover: @white; 77 | 78 | // Form states and alerts 79 | @warningText: darken(@linkColor, 20%); 80 | @warningBackground: lighten(@linkColor, 20%); 81 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 82 | 83 | @errorText: darken(#C45559, 5%); 84 | @errorBackground: #EDDBE3; 85 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 86 | 87 | @successText: darken(@green, 5%); 88 | @successBackground: #CDB; 89 | @successBorder: darken(spin(@successBackground, -10), 5%); 90 | 91 | @infoText: darken(#908A62, 5%); 92 | @infoBackground: #EDEBE1; 93 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 94 | 95 | 96 | 97 | // GRID 98 | // -------------------------------------------------- 99 | 100 | // Default 940px grid 101 | @gridColumns: 12; 102 | @gridColumnWidth: 60px; 103 | @gridGutterWidth: 20px; 104 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 105 | 106 | // Fluid grid 107 | @fluidGridColumnWidth: 6.382978723%; 108 | @fluidGridGutterWidth: 2.127659574%; 109 | -------------------------------------------------------------------------------- /public/css/bootswatch/amelia/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // Swatch: Amelia 4 | // ----------------------------------------------------- 5 | 6 | 7 | // CUSTOM VALUES 8 | // -------------------------------------------------- 9 | 10 | @bodyBackgroundColor: #003F4D; 11 | 12 | // GLOBAL VALUES 13 | // -------------------------------------------------- 14 | 15 | // Links 16 | @linkColor: lighten(@yellow, 15%); 17 | @linkColorHover: @linkColor; 18 | 19 | // Grays 20 | @black: #000; 21 | @grayDarker: #111; 22 | @grayDark: #333; 23 | @gray: #555; 24 | @grayLight: #aaa; 25 | @grayLighter: #ddd; 26 | @white: #fff; 27 | 28 | // Accent colors 29 | @blue: #00BCE1; 30 | @blueDark: #1269B0; 31 | @green: #7FC518; 32 | @red: #E51925; 33 | @yellow: #EAC504; 34 | @orange: #DF6E1E; 35 | @pink: #FFBCB9; 36 | @purple: #4D3A7D; 37 | 38 | // Typography 39 | @baseFontSize: 14px; 40 | @baseFontFamily: 'Cabin', Verdana, sans-serif; 41 | @baseLineHeight: 20px; 42 | @textColor: rgba(256, 256, 256, 0.9); 43 | 44 | // Buttons 45 | @primaryButtonBackground: @linkColor; 46 | 47 | 48 | 49 | // COMPONENT VARIABLES 50 | // -------------------------------------------------- 51 | 52 | // Z-index master list 53 | // Used for a bird's eye view of components dependent on the z-axis 54 | // Try to avoid customizing these :) 55 | @zindexDropdown: 1000; 56 | @zindexPopover: 1010; 57 | @zindexTooltip: 1020; 58 | @zindexFixedNavbar: 1030; 59 | @zindexModalBackdrop: 1040; 60 | @zindexModal: 1050; 61 | 62 | // Sprite icons path 63 | @iconSpritePath: "../img/glyphicons-halflings.png"; 64 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 65 | 66 | // Input placeholder text color 67 | @placeholderText: @grayLight; 68 | 69 | // Hr border color 70 | @hrBorder: transparent; 71 | 72 | // Navbar 73 | @navbarHeight: 50px; 74 | @navbarBackground: #AD1D28; 75 | @navbarBackgroundHighlight: #AD1D28; 76 | @navbarLinkBackgroundHover: transparent; 77 | 78 | @navbarText: @grayLight; 79 | @navbarLinkColor: @grayLight; 80 | @navbarLinkColorHover: @white; 81 | 82 | // Form states and alerts 83 | @warningText: #c09853; 84 | @warningBackground: #fcf8e3; 85 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 86 | 87 | @errorText: #b94a48; 88 | @errorBackground: #f2dede; 89 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 90 | 91 | @successText: #468847; 92 | @successBackground: #dff0d8; 93 | @successBorder: darken(spin(@successBackground, -10), 5%); 94 | 95 | @infoText: #3a87ad; 96 | @infoBackground: #d9edf7; 97 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 98 | 99 | 100 | 101 | // GRID 102 | // -------------------------------------------------- 103 | 104 | // Default 940px grid 105 | @gridColumns: 12; 106 | @gridColumnWidth: 60px; 107 | @gridGutterWidth: 20px; 108 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 109 | 110 | // Fluid grid 111 | @fluidGridColumnWidth: 6.382978723%; 112 | @fluidGridGutterWidth: 2.127659574%; 113 | -------------------------------------------------------------------------------- /public/css/bootswatch/journal/variables.less: -------------------------------------------------------------------------------- 1 | // Variables.less 2 | // Variables to customize the look and feel of Bootstrap 3 | // Swatch: Journal 4 | // ----------------------------------------------------- 5 | 6 | 7 | // CUSTOM VALUES 8 | // ----------------------------------------------------- 9 | 10 | @baseBackgroundColor: #FCFBFD; 11 | 12 | 13 | 14 | // GLOBAL VALUES 15 | // -------------------------------------------------- 16 | 17 | // Links 18 | @linkColor: @textColor; 19 | @linkColorHover: @gray; 20 | 21 | // Grays 22 | @black: #000; 23 | @grayDarker: #222; 24 | @grayDark: #333; 25 | @gray: #888; 26 | @grayLight: #999; 27 | @grayLighter: #eee; 28 | @white: #fff; 29 | 30 | // Accent colors 31 | @blue: #369; 32 | @blueDark: darken(@blue, 15%); 33 | @green: #22B24C; 34 | @red: #C00; 35 | @yellow: #FCFADB; 36 | @orange: #FF7F00; 37 | @pink: #CC99CC; 38 | @purple: #7a43b6; 39 | 40 | // Typography 41 | @baseFontSize: 14px; 42 | @baseFontFamily: 'Open Sans', sans-serif; 43 | @baseLineHeight: 18px; 44 | @textColor: @grayDarker; 45 | 46 | // Buttons 47 | @primaryButtonBackground: @linkColor; 48 | 49 | 50 | 51 | // COMPONENT VARIABLES 52 | // -------------------------------------------------- 53 | 54 | // Z-index master list 55 | // Used for a bird's eye view of components dependent on the z-axis 56 | // Try to avoid customizing these :) 57 | @zindexDropdown: 1000; 58 | @zindexPopover: 1010; 59 | @zindexTooltip: 1020; 60 | @zindexFixedNavbar: 1030; 61 | @zindexModalBackdrop: 1040; 62 | @zindexModal: 1050; 63 | 64 | // Sprite icons path 65 | @iconSpritePath: "../img/glyphicons-halflings.png"; 66 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 67 | 68 | // Input placeholder text color 69 | @placeholderText: @grayLight; 70 | 71 | // Hr border color 72 | @hrBorder: @grayLighter; 73 | 74 | // Navbar 75 | @navbarHeight: 40px; 76 | @navbarBackground: @baseBackgroundColor; 77 | @navbarBackgroundHighlight: @navbarBackground; 78 | @navbarLinkBackgroundHover: transparent; 79 | 80 | @navbarText: @textColor; 81 | @navbarLinkColor: @linkColor; 82 | @navbarLinkColorHover: @linkColor; 83 | 84 | // Form states and alerts 85 | @warningText: #c09853; 86 | @warningBackground: #fcf8e3; 87 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 88 | 89 | @errorText: #b94a48; 90 | @errorBackground: #f2dede; 91 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 92 | 93 | @successText: #468847; 94 | @successBackground: #dff0d8; 95 | @successBorder: darken(spin(@successBackground, -10), 5%); 96 | 97 | @infoText: #3a87ad; 98 | @infoBackground: #d9edf7; 99 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 100 | 101 | 102 | 103 | // GRID 104 | // -------------------------------------------------- 105 | 106 | // Default 940px grid 107 | @gridColumns: 12; 108 | @gridColumnWidth: 60px; 109 | @gridGutterWidth: 20px; 110 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 111 | 112 | // Fluid grid 113 | @fluidGridColumnWidth: 6.382978723%; 114 | @fluidGridGutterWidth: 2.127659574%; 115 | -------------------------------------------------------------------------------- /public/css/bootswatch/spacelab/bootswatch.less: -------------------------------------------------------------------------------- 1 | // Bootswatch.less 2 | // Swatch: Spacelab 3 | // ----------------------------------------------------- 4 | 5 | // NAVBAR 6 | // ----------------------------------------------------- 7 | 8 | // navbar style 9 | .navbar { 10 | border-bottom: 1px solid #CACACA; 11 | 12 | .brand { 13 | font-size: 20px; 14 | font-weight: bold; 15 | color: @textColor; 16 | 17 | &:hover { 18 | color: @linkColor; 19 | } 20 | } 21 | } 22 | 23 | // navbar dropshadow 24 | .navbar .navbar-inner { 25 | .box-shadow(0 1px 0 rgba(255,255,255,0.4)); 26 | .box-shadow(0 0 10px rgba(0,0,0,0.1)); 27 | } 28 | 29 | // nav item typography 30 | .navbar .nav > li > a { 31 | font-weight: bold; 32 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); 33 | } 34 | 35 | .navbar .nav .active > a { 36 | background-color: transparent; 37 | color: @textColor; 38 | 39 | &:hover { 40 | background-color: transparent; 41 | color: @linkColor; 42 | } 43 | } 44 | 45 | .navbar .nav > li > a:hover, 46 | .navbar .nav .open.dropdown .dropdown-toggle { 47 | color: @linkColor !important; 48 | } 49 | 50 | .navbar .nav .dropdown-toggle .caret { 51 | border-top-color: @textColor; 52 | opacity: 1; 53 | } 54 | 55 | .navbar .nav .open.dropdown .caret, 56 | .navbar .nav .dropdown-toggle:hover .caret { 57 | border-top-color: @linkColor !important; 58 | } 59 | 60 | .subnav .nav > li > a { 61 | font-weight: bold; 62 | color: #777; 63 | 64 | &:hover { 65 | color: @linkColor; 66 | } 67 | } 68 | 69 | .subnav .nav > li.active > a { 70 | color: @textColor; 71 | 72 | &:hover { 73 | color: @grayDark; 74 | } 75 | } 76 | 77 | .navbar-search .search-query, 78 | .navbar-search .search-query:hover { 79 | border: none; 80 | color: @grayLight; 81 | .placeholder(@grayLight); 82 | .box-shadow(inset 0 1px 2px rgba(0, 0, 0, 0.5)); 83 | 84 | &:focus, 85 | &.focused { 86 | .box-shadow(inset 0 1px 2px rgba(0, 0, 0, 0.5)); 87 | color: @textColor; 88 | } 89 | } 90 | 91 | .navbar .nav-collapse > .nav li > a { 92 | 93 | color: @textColor; 94 | 95 | .caret { 96 | border-top-color: @grayLight; 97 | } 98 | } 99 | 100 | 101 | .navbar .nav-collapse > .nav li > a:hover { 102 | text-shadow: none; 103 | color: @linkColor; 104 | background-color: transparent; 105 | 106 | .caret { 107 | border-top-color: @white; 108 | } 109 | } 110 | 111 | 112 | // BUTTON 113 | // ----------------------------------------------------- 114 | 115 | .btn { 116 | .buttonBackground(#F4F4F4, #ECECEC); 117 | } 118 | 119 | .btn-warning { 120 | .caret { 121 | border-top-color: @white; 122 | .opacity(75); 123 | } 124 | } 125 | 126 | .btn-primary { 127 | .buttonBackground(#909090, #3F3F3F); 128 | } 129 | 130 | .btn-warning { 131 | .buttonBackground(lighten(@yellow, 15%), @yellow); 132 | } 133 | 134 | .btn-danger { 135 | .buttonBackground(lighten(#DA2D2D, 15%), #DA2D2D); 136 | } 137 | 138 | .btn-success { 139 | .buttonBackground(#8ADD6D, #60B044); 140 | } 141 | 142 | .btn-info { 143 | .buttonBackground(lighten(#4488BB, 15%), #4488BB); 144 | } 145 | 146 | .btn-inverse { 147 | .buttonBackground(lighten(@purple, 5%), @purple); 148 | } 149 | 150 | // FORMS 151 | // ----------------------------------------------------- 152 | 153 | 154 | // Warning 155 | .control-group.warning { 156 | .formFieldState(#E29235, #E29235, @warningBackground); 157 | } 158 | // Error 159 | .control-group.error { 160 | .formFieldState(#C00, #C00, @errorBackground); 161 | } 162 | // Success 163 | .control-group.success { 164 | .formFieldState(#2BA949, #2BA949, @successBackground); 165 | } 166 | 167 | 168 | // LABELS 169 | // ----------------------------------------------------- 170 | 171 | .label-important { background-color: #BD2C00; } 172 | .label-warning { background-color: #E3E84D; } 173 | .label-success { background-color: #6CC644; } 174 | .label-info { background-color: #4183C4; } 175 | -------------------------------------------------------------------------------- /public/css/bootstrap-responsive.min.css: -------------------------------------------------------------------------------- 1 | .clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";} 2 | .clearfix:after{clear:both;} 3 | .hide-text{overflow:hidden;text-indent:100%;white-space:nowrap;} 4 | .input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;} 5 | .hidden{display:none;visibility:hidden;} 6 | .visible-phone{display:none;} 7 | .visible-tablet{display:none;} 8 | .visible-desktop{display:block;} 9 | .hidden-phone{display:block;} 10 | .hidden-tablet{display:block;} 11 | .hidden-desktop{display:none;} 12 | @media (max-width:767px){.visible-phone{display:block;} .hidden-phone{display:none;} .hidden-desktop{display:block;} .visible-desktop{display:none;}}@media (min-width:768px) and (max-width:979px){.visible-tablet{display:block;} .hidden-tablet{display:none;} .hidden-desktop{display:block;} .visible-desktop{display:none;}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:18px;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .modal{position:absolute;top:10px;left:10px;right:10px;width:auto;margin:0;}.modal.fade.in{top:auto;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (max-width:767px){body{padding-left:20px;padding-right:20px;} .navbar-fixed-top{margin-left:-20px;margin-right:-20px;} .container{width:auto;} .row-fluid{width:100%;} .row{margin-left:0;} .row>[class*="span"],.row-fluid>[class*="span"]{float:none;display:block;width:auto;margin:0;} .thumbnails [class*="span"]{width:auto;} input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;} .input-prepend input[class*="span"],.input-append input[class*="span"]{width:auto;}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";} .row:after{clear:both;} [class*="span"]{float:left;margin-left:20px;} .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} .span12{width:724px;} .span11{width:662px;} .span10{width:600px;} .span9{width:538px;} .span8{width:476px;} .span7{width:414px;} .span6{width:352px;} .span5{width:290px;} .span4{width:228px;} .span3{width:166px;} .span2{width:104px;} .span1{width:42px;} .offset12{margin-left:764px;} .offset11{margin-left:702px;} .offset10{margin-left:640px;} .offset9{margin-left:578px;} .offset8{margin-left:516px;} .offset7{margin-left:454px;} .offset6{margin-left:392px;} .offset5{margin-left:330px;} .offset4{margin-left:268px;} .offset3{margin-left:206px;} .offset2{margin-left:144px;} .offset1{margin-left:82px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} .row-fluid:after{clear:both;} .row-fluid>[class*="span"]{float:left;margin-left:2.762430939%;} .row-fluid>[class*="span"]:first-child{margin-left:0;} .row-fluid > .span12{width:99.999999993%;} .row-fluid > .span11{width:91.436464082%;} .row-fluid > .span10{width:82.87292817100001%;} .row-fluid > .span9{width:74.30939226%;} .row-fluid > .span8{width:65.74585634900001%;} .row-fluid > .span7{width:57.182320438000005%;} .row-fluid > .span6{width:48.618784527%;} .row-fluid > .span5{width:40.055248616%;} .row-fluid > .span4{width:31.491712705%;} .row-fluid > .span3{width:22.928176794%;} .row-fluid > .span2{width:14.364640883%;} .row-fluid > .span1{width:5.801104972%;} input,textarea,.uneditable-input{margin-left:0;} input.span12, textarea.span12, .uneditable-input.span12{width:714px;} input.span11, textarea.span11, .uneditable-input.span11{width:652px;} input.span10, textarea.span10, .uneditable-input.span10{width:590px;} input.span9, textarea.span9, .uneditable-input.span9{width:528px;} input.span8, textarea.span8, .uneditable-input.span8{width:466px;} input.span7, textarea.span7, .uneditable-input.span7{width:404px;} input.span6, textarea.span6, .uneditable-input.span6{width:342px;} input.span5, textarea.span5, .uneditable-input.span5{width:280px;} input.span4, textarea.span4, .uneditable-input.span4{width:218px;} input.span3, textarea.span3, .uneditable-input.span3{width:156px;} input.span2, textarea.span2, .uneditable-input.span2{width:94px;} input.span1, textarea.span1, .uneditable-input.span1{width:32px;}}@media (max-width:979px){body{padding-top:0;} .navbar-fixed-top{position:static;margin-bottom:18px;} .navbar-fixed-top .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .navbar .nav-collapse{clear:left;} .navbar .nav{float:none;margin:0 0 9px;} .navbar .nav>li{float:none;} .navbar .nav>li>a{margin-bottom:2px;} .navbar .nav>.divider-vertical{display:none;} .navbar .nav .nav-header{color:#999999;text-shadow:none;} .navbar .nav>li>a,.navbar .dropdown-menu a{padding:6px 15px;font-weight:bold;color:#999999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .navbar .dropdown-menu li+li a{margin-bottom:2px;} .navbar .nav>li>a:hover,.navbar .dropdown-menu a:hover{background-color:#222222;} .navbar .dropdown-menu{position:static;top:auto;left:auto;float:none;display:block;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .navbar .dropdown-menu:before,.navbar .dropdown-menu:after{display:none;} .navbar .dropdown-menu .divider{display:none;} .navbar-form,.navbar-search{float:none;padding:9px 15px;margin:9px 0;border-top:1px solid #222222;border-bottom:1px solid #222222;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);} .navbar .nav.pull-right{float:none;margin-left:0;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;} .btn-navbar{display:block;} .nav-collapse{overflow:hidden;height:0;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";} .row:after{clear:both;} [class*="span"]{float:left;margin-left:30px;} .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} .row-fluid:after{clear:both;} .row-fluid>[class*="span"]{float:left;margin-left:2.564102564%;} .row-fluid>[class*="span"]:first-child{margin-left:0;} .row-fluid > .span12{width:100%;} .row-fluid > .span11{width:91.45299145300001%;} .row-fluid > .span10{width:82.905982906%;} .row-fluid > .span9{width:74.358974359%;} .row-fluid > .span8{width:65.81196581200001%;} .row-fluid > .span7{width:57.264957265%;} .row-fluid > .span6{width:48.717948718%;} .row-fluid > .span5{width:40.170940171000005%;} .row-fluid > .span4{width:31.623931624%;} .row-fluid > .span3{width:23.076923077%;} .row-fluid > .span2{width:14.529914530000001%;} .row-fluid > .span1{width:5.982905983%;} input,textarea,.uneditable-input{margin-left:0;} input.span12, textarea.span12, .uneditable-input.span12{width:1160px;} input.span11, textarea.span11, .uneditable-input.span11{width:1060px;} input.span10, textarea.span10, .uneditable-input.span10{width:960px;} input.span9, textarea.span9, .uneditable-input.span9{width:860px;} input.span8, textarea.span8, .uneditable-input.span8{width:760px;} input.span7, textarea.span7, .uneditable-input.span7{width:660px;} input.span6, textarea.span6, .uneditable-input.span6{width:560px;} input.span5, textarea.span5, .uneditable-input.span5{width:460px;} input.span4, textarea.span4, .uneditable-input.span4{width:360px;} input.span3, textarea.span3, .uneditable-input.span3{width:260px;} input.span2, textarea.span2, .uneditable-input.span2{width:160px;} input.span1, textarea.span1, .uneditable-input.span1{width:60px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;}} 13 | -------------------------------------------------------------------------------- /public/css/bootswatch/readable/bootswatch.less: -------------------------------------------------------------------------------- 1 | // Bootswatch.less 2 | // Swatch: Readable 3 | // ----------------------------------------------------- 4 | 5 | // CUSTOM VALUES 6 | // -------------------------------------------------- 7 | 8 | @bodyBackgroundColor: #FDFDFA; 9 | 10 | 11 | // TYPOGRAPHY 12 | // ----------------------------------------------------- 13 | 14 | h1 { 15 | font-size: 2em; 16 | line-height: 2em; 17 | color: @textColor; 18 | } 19 | 20 | h2 { 21 | font-size: 1.5em; 22 | line-height: 2em; 23 | color: @textColor; 24 | } 25 | 26 | h3, h4, h5, h6 { 27 | font-size: 1em; 28 | line-height: 2em; 29 | text-transform: none; 30 | color: @textColor; 31 | } 32 | 33 | input, button, select, textarea { 34 | font-family: @baseFontFamily; 35 | } 36 | 37 | input, textarea, select { 38 | color: @textColor; 39 | } 40 | 41 | .muted, .help-block, .uneditable-input, blockquote, small { 42 | color: @grayLight; 43 | } 44 | 45 | small { 46 | font-size: 13px; 47 | } 48 | 49 | // SCAFFOLDING 50 | // ----------------------------------------------------- 51 | 52 | body { 53 | background-color: @bodyBackgroundColor; 54 | padding-top: 20px !important; 55 | } 56 | 57 | 58 | // NAVBAR 59 | // ----------------------------------------------------- 60 | 61 | .navbar { 62 | 63 | margin-left: 16px; 64 | 65 | .navbar-inner { 66 | .box-shadow(none); 67 | } 68 | 69 | .brand { 70 | color: @linkColor; 71 | font-size: @baseFontSize; 72 | font-weight: bold; 73 | line-height: 1em; 74 | padding: 10px 10px 11px; 75 | 76 | &:hover { 77 | color: @linkColorHover; 78 | } 79 | } 80 | 81 | .nav > li > a { 82 | text-shadow: none; 83 | padding: 10px; 84 | } 85 | 86 | .nav > li.active > a, 87 | .nav > li:active > a, 88 | .dropdown.open .dropdown-toggle { 89 | color: @linkColor; 90 | } 91 | 92 | .search-query { 93 | border: 1px solid #D4D4D4; 94 | .border-radius(0); 95 | color: @textColor; 96 | background-color: @white; 97 | } 98 | 99 | .nav .dropdown-toggle .caret, 100 | .nav .open.dropdown .caret { 101 | border-top-color: @linkColor; 102 | opacity: 1; 103 | } 104 | 105 | } 106 | 107 | @media (max-width: 980px) { 108 | form.navbar-form, form.navbar-search { 109 | border-top: 1px solid #D4D4D4; 110 | border-bottom: 1px solid #D4D4D4; 111 | } 112 | } 113 | 114 | .navbar-fixed-top { 115 | position: static; 116 | } 117 | 118 | div.subnav { 119 | .box-shadow(none); 120 | .border-radius(0); 121 | background-color: @white; 122 | background-image: none; 123 | 124 | .nav { 125 | padding: 0; 126 | } 127 | 128 | .nav > li.active > a, 129 | .nav > li:active > a { 130 | color: @linkColor; 131 | .box-shadow(none); 132 | background-color: transparent; 133 | } 134 | 135 | .nav > li > a:hover, 136 | .nav > li.active > a:hover, 137 | .nav > li:active > a:hover { 138 | color: @linkColorHover; 139 | .box-shadow(none); 140 | background-color: transparent; 141 | } 142 | } 143 | 144 | div.subnav-fixed { 145 | position: static; 146 | left: auto; 147 | width: 100%; 148 | margin: 0; 149 | .box-shadow(none); 150 | .border-radius(4px); 151 | border: 1px solid #E5E5E5; 152 | 153 | .nav { 154 | width: auto; 155 | padding: 0; 156 | } 157 | } 158 | 159 | .dropdown-menu { 160 | background-color: @white; 161 | border: 1px solid #D4D4D4; 162 | .border-radius(0); 163 | .box-shadow(1px 1px 1px rgba(0, 0, 0, 0.2)); 164 | 165 | li > a { 166 | color: @linkColor; 167 | } 168 | 169 | li > a:hover { 170 | color: @linkColorHover; 171 | background-color: transparent; 172 | } 173 | } 174 | 175 | .navbar .nav-collapse.collapse { 176 | 177 | .nav > li > a:last-child { 178 | margin-bottom: 10px; 179 | } 180 | 181 | li > a { 182 | color: @linkColor; 183 | .border-radius(0); 184 | font-weight: normal; 185 | 186 | &:hover { 187 | color: @linkColorHover; 188 | } 189 | } 190 | 191 | li > a:hover { 192 | background: transparent; 193 | } 194 | 195 | } 196 | 197 | // NAV 198 | // ----------------------------------------------------- 199 | 200 | .nav .dropdown .caret { 201 | opacity: 1; 202 | } 203 | 204 | .nav-tabs { 205 | 206 | li > a { 207 | .border-radius(0); 208 | } 209 | 210 | li > a:hover { 211 | background-color: @bodyBackgroundColor; 212 | } 213 | 214 | li.active > a, 215 | li.active > a:hover { 216 | color: @textColor; 217 | background-color: @bodyBackgroundColor; 218 | } 219 | } 220 | 221 | .nav-tabs.nav-stacked { 222 | 223 | li > a { 224 | background-color: @white; 225 | } 226 | 227 | 228 | li.active > a, 229 | li.active > a:hover, 230 | li > a:hover { 231 | background-color: #F5F5F5; 232 | } 233 | 234 | li:first-child > a, 235 | li:last-child > a { 236 | .border-radius(0); 237 | } 238 | } 239 | 240 | .nav-pills { 241 | 242 | li > a { 243 | .border-radius(0); 244 | } 245 | 246 | li > a:hover { 247 | background-color: @bodyBackgroundColor; 248 | } 249 | 250 | li.active > a, 251 | li.active > a:hover { 252 | color: @textColor; 253 | background-color: @bodyBackgroundColor; 254 | } 255 | } 256 | 257 | .nav-list { 258 | 259 | li > a:hover, 260 | li.active > a, 261 | li.active > a:hover { 262 | background-color: transparent; 263 | text-shadow: none; 264 | } 265 | 266 | li.active > a, 267 | li.active > a:hover { 268 | color: @textColor; 269 | } 270 | 271 | [class^="icon-"] { 272 | margin-top: 3px; 273 | opacity: 0.8; 274 | } 275 | } 276 | 277 | .breadcrumb { 278 | .border-radius(0); 279 | background-color: @white; 280 | background-image: none; 281 | } 282 | 283 | .pagination { 284 | 285 | ul { 286 | .box-shadow(none); 287 | } 288 | 289 | li > a { 290 | padding: 10px 14px; 291 | } 292 | 293 | 294 | li.active > a, 295 | li.active > a:hover { 296 | color: @textColor; 297 | background-color: #F5F5F5; 298 | } 299 | 300 | li > a, 301 | li.disabled > a, 302 | li.disabled > a:hover { 303 | background-color: @white; 304 | } 305 | 306 | li:first-child > a, 307 | li:last-child > a { 308 | .border-radius(0); 309 | } 310 | } 311 | 312 | .pager { 313 | 314 | a { 315 | .border-radius(0); 316 | } 317 | } 318 | 319 | // BUTTONS 320 | // ----------------------------------------------------- 321 | 322 | .btn-primary { 323 | .buttonBackground(lighten(@primaryButtonBackground, 10%), @primaryButtonBackground); 324 | } 325 | 326 | .btn [class^="icon-"], 327 | .btn [class*=" icon-"] { 328 | margin-top: 4px; 329 | } 330 | 331 | .btn-large [class^="icon-"], 332 | .btn-large [class*=" icon-"] { 333 | margin-top: 6px; 334 | margin-right: 2px; 335 | } 336 | 337 | .btn-small [class^="icon-"], 338 | .btn-small [class*=" icon-"] { 339 | margin-top: 3px; 340 | } 341 | 342 | .btn .caret { 343 | margin-top: 13px; 344 | } 345 | 346 | // FORMS 347 | // ----------------------------------------------------- 348 | 349 | 350 | // TABLES 351 | // ----------------------------------------------------- 352 | 353 | .table-bordered { 354 | .border-radius(0); 355 | } 356 | 357 | .table-striped { 358 | tbody { 359 | tr:nth-child(odd) td, 360 | tr:nth-child(odd) th { 361 | background-color: darken(@bodyBackgroundColor, 2%); 362 | } 363 | } 364 | } 365 | 366 | .table { 367 | tbody tr:hover td, 368 | tbody tr:hover th { 369 | background-color: darken(@bodyBackgroundColor, 4%); 370 | } 371 | } 372 | 373 | // MISCELLANEOUS 374 | // ----------------------------------------------------- 375 | 376 | .alert, 377 | .label, .label:hover { 378 | .border-radius(0); 379 | border: 1px solid #D4D4D4; 380 | color: @textColor; 381 | text-shadow: none; 382 | } 383 | 384 | .alert-heading { 385 | color: @textColor; 386 | text-shadow: none; 387 | } 388 | 389 | .label, .label:hover { 390 | background-color: @white; 391 | font-weight: normal; 392 | font-size: @baseFontSize; 393 | padding: 4px; 394 | } 395 | 396 | .label-important, .label-important:hover { background-color: @errorBackground; } 397 | 398 | .label-warning, .label-warning:hover { background-color: @warningBackground; } 399 | 400 | .label-success, .label-success:hover { background-color: @successBackground; } 401 | 402 | .label-info, .label-info:hover { background-color: @infoBackground; } 403 | 404 | .well { 405 | .box-shadow(none); 406 | border: 1px solid #D4D4D4; 407 | .border-radius(0); 408 | background-color: @white; 409 | } 410 | 411 | blockquote { 412 | border-left: 6px solid @grayLighter; 413 | 414 | &.pull-right { 415 | border-right: 6px solid @grayLighter; 416 | } 417 | 418 | p { 419 | font-size: 1em; 420 | line-height: 1.2em; 421 | } 422 | } 423 | 424 | .thumbnail { 425 | background-color: @white; 426 | } 427 | 428 | .thumbnail, .thumbnail > img { 429 | .border-radius(0); 430 | .box-shadow(none); 431 | } 432 | 433 | code, pre { 434 | .border-radius(0); 435 | background-color: @white; 436 | } 437 | 438 | .page-header { 439 | padding-bottom: 1em; 440 | border-bottom: 2px solid @grayLighter; 441 | } 442 | 443 | .form-actions { 444 | background-color: transparent; 445 | border-top: 1px solid #D4D4D4; 446 | padding-top: 2em; 447 | } 448 | 449 | footer.footer { 450 | padding-top: 2em; 451 | padding-bottom: 3em; 452 | border-top: 2px solid @grayLighter; 453 | } -------------------------------------------------------------------------------- /public/css/bootswatch/spruce/bootswatch.less: -------------------------------------------------------------------------------- 1 | // Bootswatch.less 2 | // Swatch: Vintage 3 | // ----------------------------------------------------- 4 | 5 | // TYPOGRAPHY 6 | // -------------------------------------------------- 7 | 8 | @import url('http://fonts.googleapis.com/css?family=Josefin+Slab:400,700'); 9 | 10 | h1, h2, h3, h4, h5, h6, .navbar .brand, legend, .btn, 11 | .navbar .nav > li > a, 12 | div.subnav li > a { 13 | font-family: 'Josefin Slab', serif; 14 | font-weight: 700; 15 | } 16 | 17 | h3 { font-size: 20px; } 18 | h4 { font-size: 16px; } 19 | h5 { font-size: 14px; } 20 | 21 | .alert-heading { 22 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 23 | } 24 | 25 | h1, h2, h3, h4, h5, h6 { 26 | color: @yellow; 27 | } 28 | 29 | h1 > small, h2 > small, h3 > small, h4 > small, h5 > small, h6 > small, .muted { 30 | color: @linkColor; 31 | } 32 | 33 | // SCAFFOLDING 34 | // -------------------------------------------------- 35 | 36 | body { 37 | background-color: #AEAD8E; 38 | #gradient > .vertical-three-colors (#90A38F, #AEAD8E, 60%, #90A38F); 39 | background-size: 100% 1400px; 40 | background-repeat: repeat-y !important; 41 | } 42 | 43 | blockquote { 44 | border-left: 2px solid @linkColor; 45 | 46 | &.pull-right { 47 | border-right: 2px solid @linkColor; 48 | } 49 | 50 | small { 51 | color: @blueDark; 52 | } 53 | } 54 | 55 | code, pre { 56 | color: lighten(@blueDark, 10%); 57 | background-color: @linkColor; 58 | } 59 | 60 | // NAVBAR 61 | // -------------------------------------------------- 62 | 63 | .navbar-inner { 64 | background-image: none; 65 | .box-shadow(none); 66 | } 67 | 68 | .navbar .brand { 69 | font-size: 26px; 70 | padding: 18px 20px 12px; 71 | color: @linkColor; 72 | } 73 | 74 | .navbar .nav > li > a, { 75 | font-size: 20px; 76 | padding: 22px 10px 11px; 77 | color: @linkColor; 78 | 79 | &:hover { 80 | color: @yellow; 81 | } 82 | } 83 | 84 | .navbar .nav .active > a, 85 | .navbar .nav .active > a:hover { 86 | color: @yellow; 87 | } 88 | 89 | .navbar-search { 90 | margin-top: 12px; 91 | } 92 | 93 | .navbar-search .search-query { 94 | border-color: transparent; 95 | padding: 6px 9px 2px 9px; 96 | } 97 | 98 | .navbar .nav > .dropdown.open > a { 99 | color: @yellow; 100 | } 101 | 102 | .navbar .nav > .dropdown.open > .dropdown-menu { 103 | background-color: @linkColor; 104 | color: @textColor; 105 | border-color: transparent; 106 | } 107 | 108 | .navbar .nav > .dropdown.open > .dropdown-menu a:hover { 109 | background-color: darken(#90A38F, 10%); 110 | color: @linkColor; 111 | } 112 | 113 | .dropdown-menu .divider { 114 | background-color: transparent; 115 | border-bottom: 1px solid #AEAD8E; 116 | } 117 | 118 | div.subnav { 119 | font-size: 18px; 120 | } 121 | 122 | div.subnav-fixed { 123 | top: 54px; 124 | } 125 | 126 | div.subnav { 127 | background-color: @green; 128 | background-image: none; 129 | border-color: transparent; 130 | .box-shadow(0 1px 5px rgba(0,0,0,.1)); 131 | } 132 | 133 | div.subnav .nav > li > a { 134 | color: @linkColor; 135 | border-color: transparent; 136 | background-color: transparent; 137 | } 138 | 139 | div.subnav .nav > li.active > a, 140 | div.subnav .nav > li > a:hover, 141 | div.subnav .nav > li.active > a:hover, 142 | div.subnav .dropdown.open .dropdown-toggle { 143 | background-color: transparent; 144 | border-color: transparent; 145 | color: @yellow; 146 | } 147 | 148 | div.subnav .dropdown.open > .dropdown-menu { 149 | background-color: @linkColor; 150 | color: @textColor; 151 | border-color: transparent; 152 | } 153 | 154 | div.subnav .dropdown.open > .dropdown-menu a:hover { 155 | background-color: darken(#90A38F, 10%); 156 | color: @linkColor; 157 | } 158 | 159 | .navbar .btn-navbar { 160 | margin-top: 14px; 161 | } 162 | 163 | .navbar .nav-collapse.collapse .nav li > a { 164 | color: @linkColor; 165 | 166 | &:hover { 167 | color: @yellow; 168 | background-color: @blue; 169 | } 170 | } 171 | 172 | .navbar .navbar-form, .navbar .navbar-search { 173 | border-color: transparent; 174 | .box-shadow(none); 175 | } 176 | 177 | div.subnav .nav > li + li > a { 178 | border-color: transparent; 179 | } 180 | 181 | 182 | // TABLES 183 | // -------------------------------------------------- 184 | 185 | .table-bordered { 186 | border: 2px solid @linkColor; 187 | } 188 | 189 | .table th, 190 | .table-striped tbody tr:nth-child(odd) th { 191 | background-color: darken(#90A38F, 10%); 192 | color: @linkColor; 193 | } 194 | 195 | .table tbody tr td { 196 | background-color: #C3C7AE; 197 | } 198 | 199 | .table-striped tbody tr:nth-child(odd) td { 200 | background-color: darken(#C3C7AE, 5%); 201 | } 202 | 203 | .table tbody tr:hover td { 204 | background-color: darken(#C3C7AE, 10%); 205 | } 206 | 207 | // BUTTONS 208 | // -------------------------------------------------- 209 | 210 | .btn { 211 | .buttonBackground(lighten(@blueDark, 5%), @blueDark); 212 | text-shadow: none; 213 | color: @white; 214 | border-color: transparent; 215 | .box-shadow(none); 216 | 217 | &:hover { 218 | color: @grayLighter; 219 | } 220 | } 221 | 222 | .btn-large { 223 | font-size: 18px; 224 | } 225 | 226 | .btn-primary { 227 | .buttonBackground(lighten(@blue, 10%), lighten(@blue, 5%)); 228 | } 229 | // Warning appears are orange 230 | .btn-warning { 231 | .buttonBackground(@orange, darken(@orange, 5%)); 232 | } 233 | // Danger and error appear as red 234 | .btn-danger { 235 | .buttonBackground(lighten(@red, 5%), @red); 236 | } 237 | // Success appears as green 238 | .btn-success { 239 | .buttonBackground(#62c462, #51a351); 240 | } 241 | // Info appears as a neutral blue 242 | .btn-info { 243 | .buttonBackground(#5bc0de, #2f96b4); 244 | } 245 | // Inverse appears as dark gray 246 | .btn-inverse { 247 | .buttonBackground(@yellow, darken(@yellow, 5%)); 248 | } 249 | 250 | .btn-group .dropdown-toggle { 251 | .box-shadow(none); 252 | } 253 | 254 | // NAVIGATION 255 | // -------------------------------------------------- 256 | 257 | .breadcrumb, .pagination > ul { 258 | background-color: darken(#90A38F, 10%); 259 | background-image: none; 260 | border-color: transparent; 261 | .box-shadow(none); 262 | } 263 | 264 | 265 | .breadcrumb li { 266 | color: @yellow; 267 | text-shadow: none; 268 | 269 | a { 270 | color: @linkColor; 271 | } 272 | 273 | a:hover { 274 | color: @yellow; 275 | } 276 | 277 | .divider { 278 | color: @blue; 279 | } 280 | } 281 | 282 | .pagination a { 283 | color: @linkColor; 284 | border-color: transparent; 285 | 286 | &:hover { 287 | color: @yellow; 288 | background-color: #748C73; 289 | } 290 | } 291 | 292 | .pagination .active a { 293 | color: @blue; 294 | background-color: #A2CDB5; 295 | } 296 | 297 | .pagination .disabled a, 298 | .pagination .disabled a:hover { 299 | color: @blue; 300 | } 301 | 302 | .nav-list > li > a, .nav-list .nav-header { 303 | text-shadow: none; 304 | } 305 | 306 | .nav-list .active > a, .nav-list .active > a:hover { 307 | background-color: #A2CDB5; 308 | text-shadow: none; 309 | } 310 | 311 | .nav-list li > a:hover { 312 | background-color: transparent; 313 | } 314 | 315 | .nav-tabs { 316 | border-color: transparent; 317 | } 318 | 319 | .nav-tabs > li > a, 320 | .nav-pills > li > a { 321 | background-color: #748C73; 322 | 323 | &:hover { 324 | background-color: #748C73; 325 | border-color: transparent; 326 | } 327 | } 328 | 329 | .nav-tabs > .active > a, 330 | .nav-tabs > .active > a:hover, 331 | .nav-pills .active > a, 332 | .nav-pills .active > a:hover { 333 | background-color: #A2CDB5; 334 | border-color: transparent; 335 | color: @blue; 336 | } 337 | 338 | .nav-tabs.nav-stacked > li > a { 339 | border-color: transparent; 340 | 341 | &:hover { 342 | border-color: transparent; 343 | } 344 | } 345 | 346 | .nav-tabs .open .dropdown-toggle, 347 | .nav-pills .open .dropdown-toggle { 348 | background-color: #748C73; 349 | border-color: transparent; 350 | color: @yellow; 351 | } 352 | 353 | .nav-tabs .active.open .dropdown-toggle, 354 | .nav-pills .active.open .dropdown-toggle { 355 | background-color: #A2CDB5; 356 | } 357 | 358 | .nav-tabs .dropdown-menu, 359 | .nav-pills .dropdown-menu { 360 | background-color: @linkColor; 361 | color: @textColor; 362 | border-color: transparent; 363 | 364 | a:hover { 365 | background-color: #A2CDB5; 366 | color: @linkColor; 367 | } 368 | } 369 | 370 | .nav .nav-header { 371 | color: @blue; 372 | } 373 | 374 | .tabbable > .nav-tabs, 375 | .tabbable > .nav-tabs > li > a, 376 | .tabbable > .nav-tabs > li > a:hover, 377 | .tabbable > .nav-tabs > li.active > a, 378 | .tabbable > .nav-tabs > li.active > a:hover { 379 | border-color: transparent; 380 | } 381 | 382 | .pager a { 383 | border: none; 384 | background-color: #748C73; 385 | 386 | &:hover { 387 | background-color: transparent; 388 | background-color: #748C73; 389 | } 390 | } 391 | 392 | // FORMS 393 | // -------------------------------------------------- 394 | 395 | legend { 396 | color: @yellow; 397 | } 398 | 399 | label, .help-block, input[type="file"] { 400 | color: @linkColor; 401 | } 402 | 403 | input, textarea, select { 404 | color: @textColor; 405 | } 406 | 407 | .uneditable-input { 408 | color: @gray; 409 | } 410 | 411 | legend { 412 | border-bottom: 2px solid @white; 413 | } 414 | 415 | .form-actions { 416 | background-color: transparent; 417 | border-top: none; 418 | .border-radius(4px); 419 | } 420 | 421 | // MISCELLANEOUS 422 | // -------------------------------------------------- 423 | 424 | .alert { 425 | text-shadow: none; 426 | border: none; 427 | } 428 | 429 | .label { 430 | color: @linkColor; 431 | opacity: 1; 432 | text-shadow: none; 433 | } 434 | 435 | .progress { 436 | background-color: darken(#90A38F, 10%); 437 | background-image: none; 438 | .box-shadow(none); 439 | 440 | .bar { 441 | background-image: none; 442 | background-color: #A2CDB5; 443 | } 444 | } 445 | 446 | .well { 447 | background-color: darken(#90A38F, 10%); 448 | border: none; 449 | .box-shadow(none); 450 | } 451 | 452 | .thumbnail { 453 | border: none; 454 | .box-shadow(none); 455 | 456 | img { 457 | .border-radius(4px); 458 | } 459 | } 460 | 461 | hr { 462 | border-top: none; 463 | border-bottom: 2px solid @linkColor; 464 | } 465 | 466 | .page-header { 467 | border-bottom: 2px solid @linkColor; 468 | padding-bottom: 5px; 469 | } 470 | 471 | footer.footer { 472 | border-top: 2px solid @linkColor; 473 | } 474 | -------------------------------------------------------------------------------- /public/css/bootswatch/slate/bootswatch.less: -------------------------------------------------------------------------------- 1 | // Bootswatch.less 2 | // Swatch: Slate 3 | // ----------------------------------------------------- 4 | 5 | // SCAFFOLDING 6 | // ----------------------------------------------------- 7 | 8 | body { 9 | background-color: @grayDarker; 10 | } 11 | 12 | h1, h2, h3, h4, h5, h6, body, legend, label { 13 | color: @grayLight; 14 | text-shadow: -1px -1px 0 #111; 15 | } 16 | 17 | // NAVBAR 18 | // ----------------------------------------------------- 19 | 20 | .navbar .brand { 21 | font-weight: bold; 22 | } 23 | 24 | .navbar .navbar-inner, 25 | div.subnav { 26 | #gradient > .vertical-three-colors(@gray, @grayDark, 70%, @grayDark); 27 | } 28 | 29 | .navbar .divider-vertical { 30 | background-color: transparent; 31 | border-right: none; 32 | } 33 | 34 | .navbar .brand, 35 | .navbar .nav > li > a, 36 | div.subnav .nav > li > a { 37 | color: @grayLighter; 38 | text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); 39 | border-right: 1px solid darken(@gray, 15%); 40 | } 41 | 42 | .navbar .nav > li > a, 43 | div.subnav .nav > li > a { 44 | border-left: 1px solid @gray; 45 | 46 | &:hover { 47 | color: @grayLighter; 48 | background-color: @grayDark; 49 | #gradient > .directional(@grayDarker, @grayDark, 280deg); 50 | border-left: 1px solid transparent; 51 | border-right: 1px solid transparent; 52 | } 53 | } 54 | 55 | .navbar .nav > li.active > a, 56 | div.subnav .nav > li.active > a, 57 | .navbar .nav > li.active > a:hover, 58 | div.subnav .nav > li.active > a:hover { 59 | color: @grayLighter; 60 | background-color: @grayDark; 61 | #gradient > .directional(lighten(@grayDarker, 4%), lighten(@grayDark, 4%), 280deg); 62 | border-right: 1px solid darken(@gray, 15%); 63 | } 64 | 65 | div.subnav .nav > li:first-child > a, 66 | div.subnav .nav > li:first-child > a:hover { 67 | border-left: 1px solid transparent; 68 | } 69 | 70 | div.subnav.subnav-fixed .nav > li.active:first-child > a, 71 | div.subnav.subnav-fixed .nav > li:first-child > a:hover { 72 | border-left: 1px solid darken(@gray, 15%); 73 | } 74 | 75 | div.subnav .nav > li.active:last-child > a, 76 | div.subnav .nav > li:last-child > a:hover { 77 | border-right: 1px solid darken(@gray, 15%); 78 | } 79 | 80 | div.subnav { 81 | border: 1px solid transparent; 82 | .box-shadow(0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1)); 83 | } 84 | 85 | .navbar-search .search-query { 86 | border: 1px solid darken(@gray, 15%); 87 | } 88 | 89 | .nav .nav-header { 90 | text-shadow: none; 91 | } 92 | 93 | .navbar .nav-collapse.collapse > .nav > li > a, 94 | .navbar .nav-collapse.collapse > .nav > li.active > a, 95 | .navbar .nav-collapse.collapse > .nav > li > a:hover, 96 | .navbar .nav-collapse.collapse > .nav > li.active > a:hover { 97 | color: @grayLighter; 98 | border: 1px solid transparent; 99 | .box-shadow(none); 100 | background-color: transparent; 101 | background-image: none; 102 | } 103 | 104 | .navbar .nav-collapse.collapse > .nav > li > a:hover, 105 | .navbar .nav-collapse.collapse > .nav > li.active > a:hover { 106 | background-color: @grayDarker; 107 | } 108 | 109 | @media (max-width: 979px) { 110 | .navbar .brand { 111 | border-right: none; 112 | } 113 | } 114 | 115 | // BUTTONS 116 | // ----------------------------------------------------- 117 | 118 | .btn { 119 | .buttonBackground(@gray, darken(@gray, 10%)); 120 | .border-radius(3px); 121 | border: 1px solid @grayDarker; 122 | } 123 | 124 | .btn, .btn:hover { 125 | color: @white; 126 | font-weight: bold; 127 | text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); 128 | } 129 | 130 | // Set the backgrounds 131 | // ------------------------- 132 | .btn-primary { 133 | .buttonBackground(@primaryButtonBackground, spin(@primaryButtonBackground, 20)); 134 | } 135 | // Warning appears are orange 136 | .btn-warning { 137 | .buttonBackground(lighten(@orange, 15%), @orange); 138 | } 139 | // Danger and error appear as red 140 | .btn-danger { 141 | .buttonBackground(#ee5f5b, #bd362f); 142 | } 143 | // Success appears as green 144 | .btn-success { 145 | .buttonBackground(#62c462, #51a351); 146 | } 147 | // Info appears as a neutral blue 148 | .btn-info { 149 | .buttonBackground(#5bc0de, #2f96b4); 150 | } 151 | // Inverse appears as dark gray 152 | .btn-inverse { 153 | .buttonBackground(#454545, #262626); 154 | } 155 | 156 | .caret { 157 | border-top-color: @white; 158 | } 159 | 160 | // TABLES 161 | // ----------------------------------------------------- 162 | 163 | .table th, .table td, .table tbody + tbody { 164 | border-top: 1px solid darken(@grayDarker, 5%); 165 | } 166 | 167 | .table-bordered { 168 | border: 1px solid darken(@grayDarker, 5%); 169 | th + th, 170 | td + td, 171 | th + td, 172 | td + th { 173 | border-left: 1px solid darken(@grayDarker, 5%); 174 | } 175 | // Prevent a double border 176 | thead:first-child tr:first-child th, 177 | tbody:first-child tr:first-child th, 178 | tbody:first-child tr:first-child td { 179 | border-top: 0; 180 | } 181 | } 182 | 183 | .table-striped { 184 | tbody { 185 | tr:nth-child(odd) td, 186 | tr:nth-child(odd) th { 187 | background-color: darken(@grayDark, 5%); 188 | } 189 | } 190 | } 191 | 192 | .table { 193 | tbody tr:hover td, 194 | tbody tr:hover th { 195 | background-color: @grayDark; 196 | } 197 | } 198 | 199 | // NAVIGATION 200 | // ----------------------------------------------------- 201 | 202 | .pagination > ul { 203 | .box-shadow(none); 204 | } 205 | 206 | .breadcrumb, .pagination > ul a, .pager a { 207 | border: 1px solid transparent; 208 | .box-shadow(0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1)); 209 | #gradient > .vertical-three-colors(@gray, @grayDark, 70%, @grayDark); 210 | } 211 | 212 | .breadcrumb li, .breadcrumb a, .pagination > ul a { 213 | color: @grayLighter; 214 | font-weight: bold; 215 | text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); 216 | } 217 | 218 | .breadcrumb a { 219 | color: @white; 220 | } 221 | 222 | .pagination li > a, 223 | .pagination li.disabled > a { 224 | border-left: 1px solid @gray; 225 | border-right: 1px solid darken(@gray, 15%); 226 | border-top: none; 227 | border-bottom: none; 228 | } 229 | 230 | .pagination li.disabled > a { 231 | #gradient > .vertical-three-colors(@grayLight, @gray, 70%, @gray); 232 | } 233 | 234 | .pagination > ul > li:not(.disabled) a:hover, 235 | { 236 | #gradient > .directional(@grayDarker, @grayDark, 280deg); 237 | border-left: 1px solid transparent; 238 | } 239 | 240 | .pagination > ul > li.active > a, 241 | .pagination > ul > li.active > a:hover { 242 | color: @grayLighter; 243 | background-color: @grayDark; 244 | #gradient > .directional(lighten(@grayDarker, 4%), lighten(@grayDark, 4%), 280deg); 245 | border-left: 1px solid transparent; 246 | } 247 | 248 | .pager a:hover { 249 | #gradient > .directional(@grayDarker, @grayDark, 280deg); 250 | border: 1px solid transparent; 251 | } 252 | 253 | .nav > li > a, 254 | .nav > li > a:hover, 255 | .nav > li.active > a, 256 | .nav > li.active > a:hover, 257 | .nav-tabs.nav-stacked > li > a, 258 | .nav-tabs.nav-stacked > li > a:hover { 259 | border: none; 260 | background-color: transparent; 261 | color: @grayLighter; 262 | font-weight: bold; 263 | text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); 264 | } 265 | 266 | .dropdown-menu { 267 | .box-shadow(0 5px 5px rgba(0, 0, 0, 0.2)); 268 | } 269 | 270 | .dropdown-menu, 271 | .dropdown-menu li.active a, 272 | .dropdown-menu li.active a:hover { 273 | background-color: @grayDark; 274 | } 275 | 276 | .dropdown-menu a, 277 | .dropdown-menu li.active a, 278 | .dropdown-menu li a:hover, 279 | .dropdown-menu li.active a:hover, 280 | .dropdown.open .dropdown-toggle { 281 | color: @grayLighter; 282 | } 283 | 284 | .dropdown-menu li a:hover, 285 | .dropdown-menu li.active a:hover { 286 | background-color: @grayDarker; 287 | } 288 | 289 | .navbar .dropdown-menu::after { 290 | border-bottom: 6px solid @grayDark; 291 | } 292 | 293 | .nav > li > a { 294 | border: none; 295 | .box-shadow(0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1)); 296 | #gradient > .vertical-three-colors(@gray, @grayDark, 70%, @grayDark); 297 | 298 | } 299 | 300 | .nav.nav-list .nav-header { 301 | color: @grayLight; 302 | text-shadow: -1px -1px 0 #111; 303 | } 304 | 305 | .tabs-below .nav-tabs { 306 | border-top: none; 307 | } 308 | 309 | .tabs-left .nav-tabs { 310 | border-right: none; 311 | } 312 | 313 | .tabs-right .nav-tabs { 314 | border-left: none; 315 | } 316 | 317 | // FORMS 318 | // ----------------------------------------------------- 319 | 320 | .form-actions { 321 | background-color: darken(@grayDarker, 3%); 322 | border-top: none; 323 | } 324 | 325 | .input-prepend .add-on, .input-append .add-on { 326 | background-color: @gray; 327 | border-top: 1px solid @grayLight; 328 | border-left: 1px solid @grayLight; 329 | border-bottom: 1px solid @grayDark; 330 | border-right: 1px solid @grayDark; 331 | text-shadow: none; 332 | } 333 | 334 | .uneditable-input, input[disabled], select[disabled], textarea[disabled], input[readonly], select[readonly], textarea[readonly] { 335 | text-shadow: none; 336 | color: @grayLighter; 337 | } 338 | 339 | // LABELS AND ALERTS 340 | // ----------------------------------------------------- 341 | 342 | .label, .alert { 343 | color: rgba(256, 256, 256, 0.9); 344 | text-shadow: -1px -1px 0 rgba(0, 0, 0, 0.4); 345 | .box-shadow(1px 1px 1px rgba(0, 0, 0, 0.3)); 346 | } 347 | 348 | .alert-heading { 349 | color: rgba(256, 256, 256, 0.9); 350 | text-shadow: -1px -1px 0 rgba(0, 0, 0, 0.4); 351 | } 352 | 353 | .alert { 354 | background-color: @warningText; 355 | border-color: @warningText; 356 | } 357 | 358 | .alert-success { 359 | background-color: @successText; 360 | border-color: @successText; 361 | } 362 | 363 | .alert-danger, 364 | .alert-error { 365 | background-color: @errorText; 366 | border-color: @errorText; 367 | } 368 | 369 | .alert-info { 370 | background-color: @infoText; 371 | border-color: @infoText; 372 | } 373 | 374 | // MISCELLANEOUS 375 | // ----------------------------------------------------- 376 | 377 | code, pre { 378 | background-color: #F7F7F7; 379 | border: 1px solid darken(@grayDarker, 5%); 380 | text-shadow: none; 381 | } 382 | 383 | hr, legend, .page-header, .dropdown-menu .divider { 384 | border-top: none; 385 | border-bottom: 1px solid darken(@grayDarker, 5%); 386 | background-color: transparent; 387 | } 388 | 389 | footer.footer { 390 | border-top: 1px solid darken(@grayDarker, 5%); 391 | } 392 | 393 | .well, .progress { 394 | background-color: darken(@grayDarker, 3%); 395 | .box-shadow(inset 1px 1px 1px rgba(0, 0, 0, 0.5); 396 | } 397 | 398 | .progress { 399 | #gradient > .vertical(darken(@grayDarker, 3%), darken(@grayDarker, 3%)); 400 | } 401 | 402 | .thumbnail, a.thumbnail:hover { 403 | border: 1px solid darken(@grayDarker, 5%); 404 | } 405 | -------------------------------------------------------------------------------- /public/css/bootswatch/cyborg/bootswatch.less: -------------------------------------------------------------------------------- 1 | // Bootswatch.less 2 | // Swatch: Cyborg 3 | // ----------------------------------------------------- 4 | 5 | // TYPOGRAPHY 6 | // ----------------------------------------------------- 7 | 8 | // Ubuntu web font 9 | @import url('http://fonts.googleapis.com/css?family=Droid+Sans:400,700'); 10 | 11 | h1, h2, h3, h4, h5, .navbar .brand, .navbar .nav-collapse.collapse .nav li > a { 12 | color: @grayLighter; 13 | font-weight: normal; 14 | text-shadow: none; 15 | } 16 | 17 | .navbar { 18 | font-size: 16px; 19 | } 20 | 21 | label, input, button, select, textarea { 22 | font-family: 'Droid Sans', sans-serif; 23 | color: @gray; 24 | } 25 | 26 | .navbar .search-query:-moz-placeholder { 27 | font-family: 'Droid Sans', sans-serif; 28 | color: @gray; 29 | } 30 | 31 | .navbar .search-query::-webkit-input-placeholder { 32 | font-family: 'Droid Sans', sans-serif; 33 | } 34 | 35 | blockquote { 36 | border-left: 5px solid @blue; 37 | 38 | &.pull-right { 39 | border-right: 5px solid @blue; 40 | } 41 | } 42 | 43 | // SCAFFOLDING 44 | // ----------------------------------------------------- 45 | 46 | body { 47 | background-color: #060606; 48 | #gradient > .vertical (#060606, #252A30); 49 | } 50 | 51 | .page-header { 52 | border-bottom: 2px solid @blue 53 | } 54 | 55 | // NAVBAR 56 | // ----------------------------------------------------- 57 | 58 | .navbar-inner { 59 | .border-radius(0); 60 | @shadow: none; 61 | .box-shadow(@shadow); 62 | border-bottom: 2px solid @blue 63 | } 64 | 65 | .navbar .nav li > a { 66 | padding: 13px 10px 8px; 67 | border-bottom: 3px solid rgba(0, 0, 0, 0); 68 | } 69 | 70 | .navbar .brand { 71 | padding: 12px 20px 8px; 72 | } 73 | 74 | .navbar .search-query, 75 | .navbar .search-query:focus, 76 | .navbar .search-query.focused { 77 | color: @grayLight; 78 | text-shadow: none; 79 | background-color: #222; 80 | .border-radius(1px); 81 | .placeholder(@gray); 82 | } 83 | 84 | .navbar .nav .active > a, 85 | .navbar .nav li > a:hover, 86 | .navbar .brand:hover { 87 | border-bottom: 3px solid @blue 88 | } 89 | 90 | // Added dividers to items 91 | .navbar .nav > li > a { 92 | border-left: 1px solid #222; 93 | } 94 | 95 | .dropdown-menu { 96 | background-color: #191A1A; 97 | border-left: solid 1px rgba(256,256,256,.1); 98 | .box-shadow(0 2px 4px rgba(0,0,0,.8)); 99 | } 100 | 101 | .dropdown-menu li > a:hover { 102 | background-color: @blue; 103 | border-bottom: 3px solid transparent; 104 | } 105 | 106 | .dropdown-menu .divider { 107 | background-color: #222; 108 | border-bottom: 0px solid white; 109 | } 110 | 111 | .navbar .dropdown-menu::before, 112 | .navbar .dropdown-menu::after { 113 | display: none; 114 | } 115 | 116 | .navbar .nav-collapse.collapse .nav > li > a { 117 | border-left: 0; 118 | } 119 | 120 | .navbar .nav-collapse.collapse .nav a:hover { 121 | background-color: @blue; 122 | } 123 | 124 | div.subnav { 125 | position: static; 126 | background-color: @grayDarker; 127 | background-image: none; 128 | border: 0; 129 | } 130 | 131 | div.subnav.subnav-fixed { 132 | position: relative; 133 | left: -1px; 134 | top: auto; 135 | } 136 | 137 | div.subnav .nav li > a, 138 | div.subnav .nav .active a { 139 | border-left: 1px solid #222; 140 | border-right: 0; 141 | color: @grayLighter; 142 | background-color: @grayDarker; 143 | } 144 | 145 | .subnav .nav > li > a:hover, 146 | .subnav .nav > li.active > a:hover, 147 | .subnav .nav > li:first-child > a:hover { 148 | background: transparent; 149 | border-bottom: 2px solid @blue; 150 | border-left: 1px solid #222; 151 | color: @white; 152 | } 153 | 154 | div.subnav .nav .dropdown.open { 155 | 156 | .dropdown-toggle { 157 | border: 0; 158 | border-left: 1px solid #222; 159 | border-bottom: 2px solid @blue; 160 | background-color: #060606; 161 | } 162 | 163 | .dropdown-menu { 164 | background-color: @grayDarker; 165 | border-left: 0; 166 | 167 | li > a:hover { 168 | border-bottom: 0; 169 | background: @blue; 170 | } 171 | } 172 | } 173 | 174 | @media (max-width: 768px) { 175 | div.subnav .nav > li + li > a, 176 | div.subnav .nav > li:first-child > a { 177 | border-top: 1px solid #222; 178 | border-left: 1px solid #222; 179 | } 180 | 181 | .subnav .nav > li + li > a:hover, 182 | .subnav .nav > li:first-child > a:hover { 183 | border-bottom: 0; 184 | background-color: @blue; 185 | } 186 | 187 | } 188 | 189 | // TABLES 190 | // ----------------------------------------------------- 191 | 192 | .table-bordered { 193 | border: 1px solid #222; 194 | 195 | th + th, 196 | td + td, 197 | th + td, 198 | td + th { 199 | border-left: 1px solid #222; 200 | } 201 | // Prevent a double border 202 | thead:first-child tr:first-child th, 203 | tbody:first-child tr:first-child th, 204 | tbody:first-child tr:first-child td { 205 | border-top: 0; 206 | } 207 | } 208 | 209 | .table th, .table td { 210 | border-top: 1px solid #222; 211 | } 212 | 213 | // make shaded elements light gray 214 | .breadcrumb, 215 | .table-striped tbody tr:nth-child(odd) td, 216 | .table-striped tbody tr:nth-child(odd) th { 217 | background-color: rgba(40, 40, 40, 0.5); 218 | } 219 | 220 | .table-striped tbody tr:nth-child(even) td, 221 | .table-striped tbody tr:nth-child(even) th { 222 | background-color: transparent; 223 | } 224 | 225 | .table tbody tr:hover th, 226 | .table tbody tr:hover td { 227 | background-color: @grayDark; 228 | } 229 | 230 | code, pre, pre.prettyprint { 231 | background-color: @grayLighter; 232 | } 233 | 234 | .well { 235 | background-color: rgba(40, 40, 40, 0.5); 236 | background-color: #131517; 237 | border-top: solid 1px rgba(256,256,256,.1); 238 | .box-shadow(0 2px 4px rgba(0,0,0,.8)); 239 | } 240 | 241 | 242 | .table, .well, .prettyprint, input, textarea, select { 243 | .border-radius(1px); 244 | } 245 | 246 | input, textarea, select, .uneditable-input { 247 | color: @grayDark; 248 | } 249 | 250 | 251 | // NAVIGATION 252 | // ----------------------------------------------------- 253 | 254 | 255 | .nav-list > li > a, .nav-list .nav-header { 256 | text-shadow: none; 257 | } 258 | 259 | .nav-list li > a:hover, 260 | .nav-tabs li > a:hover, 261 | .nav-tabs li.active > a, 262 | .nav-pills li > a:hover, 263 | .nav-stacked li > a:hover, 264 | .nav-stacked li.active > a { 265 | background-color: @blue; 266 | color: @white; 267 | } 268 | 269 | .nav-tabs { 270 | border-bottom: 1px solid #222; 271 | } 272 | 273 | .nav-stacked > li > a, 274 | .nav-tabs > li > a:hover, 275 | .nav-tabs > .active > a, 276 | .nav-tabs > .active > a:hover { 277 | border: 1px solid #222 !important; 278 | } 279 | 280 | .nav.nav-tabs .active a:hover { 281 | background-color: @blue; 282 | color: @white; 283 | } 284 | 285 | .nav.nav-tabs .dropdown.open, 286 | .nav.nav-pills .dropdown.open { 287 | .dropdown-toggle { 288 | background-color: #060606 !important; 289 | border-top: 0; 290 | border: 1px solid #222; 291 | } 292 | 293 | .dropdown-menu li > a:hover { border-bottom: 0; } 294 | } 295 | 296 | .tabbable .nav-tabs, .thumbnail { 297 | border-color: #222; 298 | } 299 | 300 | .breadcrumb { 301 | background-color: transparent; 302 | background-image: none; 303 | border-width: 0; 304 | .box-shadow(none); 305 | font-size: 14px; 306 | 307 | li > a { 308 | color: @blue; 309 | text-shadow: none; 310 | } 311 | 312 | li.active { 313 | text-shadow: none; 314 | } 315 | } 316 | 317 | .pagination { 318 | ul { 319 | .box-shadow(none); 320 | } 321 | 322 | a { 323 | border: 0; 324 | font-size: 14px; 325 | } 326 | 327 | a:hover, .active a { 328 | background-color: @blue; 329 | color: @white; 330 | } 331 | } 332 | 333 | // BUTTONS 334 | // ----------------------------------------------------- 335 | 336 | .btn, { 337 | border: 0; 338 | .border-radius(3px); 339 | .box-shadow(1px 1px 2px #111); 340 | .buttonBackground(darken(@gray, 20%), darken(@gray, 30%)); 341 | color: @white; 342 | text-shadow: none; 343 | 344 | &:hover { 345 | background-color: darken(@gray, 35%); 346 | text-shadow: none; 347 | color: @white; 348 | } 349 | } 350 | 351 | .btn-primary { 352 | .buttonBackground(@blueDark, darken(@blueDark, 10%)); 353 | } 354 | 355 | .btn-warning { 356 | .buttonBackground(lighten(@orange, 10%), @orange); 357 | } 358 | 359 | .btn-danger { 360 | .buttonBackground(lighten(@red, 10%), @red); 361 | } 362 | 363 | .btn-success { 364 | .buttonBackground(lighten(@green, 10%), @green); 365 | } 366 | 367 | .btn-info { 368 | .buttonBackground(darken(@gray, 40%), darken(@gray, 50%)); 369 | } 370 | 371 | .btn-inverse { 372 | .buttonBackground(lighten(@purple, 5%), @purple); 373 | } 374 | 375 | .btn-group .btn:first-child { 376 | -webkit-border-top-left-radius: 3px; 377 | -moz-border-top-left-radius: 3px; 378 | border-top-left-radius: 3px; 379 | 380 | -webkit-border-bottom-left-radius: 3px; 381 | -moz-border-bottom-left-radius: 3px; 382 | border-bottom-left-radius: 3px; 383 | } 384 | 385 | .btn-group .btn:last-child, .btn-group .dropdown-toggle { 386 | -webkit-border-top-right-radius: 3px; 387 | -moz-border-top-right-radius: 3px; 388 | border-top-right-radius: 3px; 389 | 390 | -webkit-border-bottom-right-radius: 3px; 391 | -moz-border-bottom-right-radius: 3px; 392 | border-bottom-right-radius: 3px; 393 | 394 | } 395 | 396 | .btn .caret { 397 | border-top: 4px solid black; 398 | opacity: 0.3; 399 | } 400 | 401 | .btn-group > .dropdown-menu > li > a:hover { 402 | border-bottom: 0; 403 | } 404 | 405 | .btn.disabled, .btn[disabled] { 406 | background-color: @grayLight; 407 | } 408 | 409 | // FORMS 410 | // ----------------------------------------------------- 411 | 412 | input, textarea, select { 413 | background-color: #ccc; 414 | border-color: #bbb; 415 | border-width: 2px; 416 | .placeholder(@gray); 417 | } 418 | 419 | legend, label { 420 | color: @textColor; 421 | border-bottom: 0px solid #222; 422 | } 423 | 424 | input[disabled], select[disabled], textarea[disabled], input[readonly], select[readonly], textarea[readonly], .uneditable-input { 425 | background-color: #555; 426 | border-color: #444; 427 | } 428 | 429 | input:focus, 430 | textarea:focus, 431 | input.focused, 432 | textarea.focused { 433 | border-color: rgba(82,168,236,1); 434 | outline: 0; 435 | outline: thin dotted \9; /* IE6-9 */ 436 | } 437 | 438 | input[type="file"]:focus, 439 | input[type="radio"]:focus, 440 | input[type="checkbox"]:focus, 441 | select:focus { 442 | .box-shadow(none); // override for file inputs 443 | .tab-focus(); 444 | } 445 | 446 | .form-actions { 447 | background: transparent; 448 | } 449 | 450 | .form-actions, footer.footer { 451 | border-top: 1px solid #222; 452 | } 453 | 454 | 455 | // MISCELLANEOUS 456 | // ----------------------------------------------------- 457 | 458 | 459 | .progress { 460 | background-color: #060606; 461 | background-image: none; 462 | .border-radius(0); 463 | } 464 | 465 | .label { 466 | color: @grayLighter; 467 | } 468 | 469 | .label, .alert { background-color: darken(@gray, 20%); } 470 | 471 | .label:hover { background-color: darken(@gray, 30%); } 472 | 473 | 474 | .label-important, .alert-danger, 475 | .alert-error { background-color: @red; } 476 | 477 | .label-important:hover { background-color: darken(@red, 10%); } 478 | 479 | .label-warning { background-color: darken(@orange, 10%); } 480 | 481 | .label-warning:hover { background-color: darken(@orange, 20%); } 482 | 483 | .label-success, .alert-success { background-color: darken(@green, 3%); } 484 | 485 | .label-success:hover { background-color: darken(@green, 13%); } 486 | 487 | .label-info, .alert-info { background-color: darken(@blueDark, 10%); } 488 | 489 | .label-info:hover { background-color: darken(@blueDark, 20%); } 490 | 491 | .alert, 492 | .alert .alert-heading, 493 | .alert-success, 494 | .alert-success .alert-heading, 495 | .alert-danger, 496 | .alert-error, 497 | .alert-danger .alert-heading, 498 | .alert-error .alert-heading, 499 | .alert-info, 500 | .alert-info .alert-heading { 501 | color: @grayLighter; 502 | text-shadow: none; 503 | border: none; 504 | } 505 | -------------------------------------------------------------------------------- /public/css/bootswatch/superhero/bootswatch.less: -------------------------------------------------------------------------------- 1 | // Bootswatch.less 2 | // Swatch: Superhero 3 | // ----------------------------------------------------- 4 | 5 | // TYPOGRAPHY 6 | // -------------------------------------------------- 7 | 8 | @import url(http://fonts.googleapis.com/css?family=Oswald); 9 | @import url(http://fonts.googleapis.com/css?family=Noticia+Text); 10 | 11 | h1, h2, h3, h4, h5, h6, legend, .navbar .brand, 12 | .navbar .nav > li > a, 13 | h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { 14 | font-family: 'Oswald', sans-serif; 15 | color: @orange; 16 | text-shadow: -1px 1px 0 darken(@orange, 30%); 17 | } 18 | 19 | h1, h2, legend, .navbar .brand, 20 | .navbar .nav > li > a { 21 | text-shadow: -2px 2px 0 darken(@orange, 30%); 22 | } 23 | 24 | h1 { 25 | line-height: 55px; 26 | } 27 | 28 | // SCAFFOLDING 29 | // -------------------------------------------------- 30 | 31 | code, pre { 32 | background-color: lighten(@blue, 8%); 33 | border: none; 34 | color: @textColor; 35 | } 36 | 37 | .prettyprint { 38 | border: none; 39 | text-decoration: none; 40 | } 41 | 42 | blockquote { 43 | border-left: 5px solid @blue; 44 | } 45 | 46 | blockquote.pull-right { 47 | border-right: 5px solid @blue; 48 | } 49 | 50 | // NAVBAR 51 | // -------------------------------------------------- 52 | 53 | .navbar .nav > li.active > a { 54 | color: @orange; 55 | } 56 | 57 | .navbar .brand:hover, 58 | .navbar .nav > li > a:hover, 59 | .navbar .nav > li.active > a:hover, 60 | .navbar .nav > li.dropdown.open > a, 61 | .navbar .nav > li.dropdown.open > a:hover { 62 | position: relative; 63 | top: 1px; 64 | left: -1px; 65 | color: @orange; 66 | text-shadow: -1px 1px 0 darken(@orange, 30%); 67 | } 68 | 69 | body { 70 | background-color: @blueDark; 71 | } 72 | 73 | 74 | .navbar .navbar-inner { 75 | .box-shadow(none); 76 | background-image: none; 77 | } 78 | 79 | .navbar .brand { 80 | padding: 25px 20px 15px; 81 | font-size: 30px; 82 | } 83 | 84 | .navbar .nav > li > a { 85 | padding: 27px 20px 13px; 86 | line-height: 30px; 87 | font-size: 22px; 88 | } 89 | 90 | .navbar-search { 91 | padding-top: 20px; 92 | } 93 | 94 | .navbar-search .search-query { 95 | font-family: @baseFontFamily; 96 | font-size: @baseFontSize; 97 | line-height: @baseLineHeight; 98 | color: @textColor; 99 | background-color: @blue; 100 | .box-shadow(none); 101 | border: none; 102 | } 103 | 104 | 105 | .navbar .divider-vertical { 106 | height: 70px; 107 | } 108 | 109 | .dropdown .caret { 110 | margin-top: 14px; 111 | opacity: 1; 112 | border-left: 6px solid transparent; 113 | border-right: 6px solid transparent; 114 | border-top: 6px solid lighten(@blue, 10%); 115 | } 116 | 117 | .navbar .nav .dropdown-toggle .caret, 118 | .navbar .nav .open.dropdown .caret { 119 | border-top-color: @textColor; 120 | } 121 | 122 | .navbar .dropdown-menu::before { 123 | border: none; 124 | } 125 | 126 | .navbar .dropdown-menu::after { 127 | left: 20px; 128 | border-left: 7px solid transparent; 129 | border-right: 7px solid transparent; 130 | border-bottom: 7px solid lighten(@blue, 10%); 131 | } 132 | 133 | .navbar [class^="icon-"], .navbar [class*=" icon-"] { 134 | vertical-align: 20%; 135 | } 136 | 137 | .navbar .btn-navbar { 138 | background-color: @blue; 139 | border-color: transparent; 140 | } 141 | 142 | .navbar .nav-collapse.collapse { 143 | background-color: @blue; 144 | .border-radius(4px); 145 | 146 | li > a { 147 | color: @textColor; 148 | } 149 | 150 | li > a:hover { 151 | color: @textColor; 152 | background-color: lighten(@blue, 10%); 153 | } 154 | } 155 | 156 | .navbar .nav-collapse.collapse > .nav > li > a { 157 | color: @orange; 158 | } 159 | 160 | .subnav.subnav-fixed { 161 | top: 70px; 162 | } 163 | 164 | div.subnav { 165 | background-color: @blue; 166 | background-image: none; 167 | border: none; 168 | 169 | .nav > li > a, 170 | .nav > li.active > a { 171 | border-left: none; 172 | border-right: none; 173 | color: @textColor; 174 | } 175 | 176 | .nav > li > a:hover, 177 | .nav > li.active > a:hover { 178 | background-color: lighten(@blue, 10%); 179 | } 180 | } 181 | 182 | div.subnav .nav > li + li > a { 183 | border-top: 0px solid transparent; 184 | } 185 | 186 | div.subnav .nav > li:first-child > a, 187 | div.subnav .nav > li:first-child > a:hover, 188 | div.subnav .nav > li.active:first-child > a, 189 | div.subnav .nav > li.active:first-child > a:hover { 190 | .border-radius(4px 0 0 4px); 191 | } 192 | 193 | div.subnav .nav > li.active > a, 194 | div.subnav .nav > li.active > a:hover { 195 | color: @white; 196 | background-color: @orange; 197 | background-image: none; 198 | .box-shadow(none); 199 | } 200 | 201 | div.subnav.subnav-fixed { 202 | .box-shadow(none); 203 | 204 | .nav > li > a, 205 | .nav > li.active > a, 206 | .nav > li > a:hover, 207 | .nav > li.active > a:hover { 208 | border-color: transparent; 209 | padding-left: 12px; 210 | padding-right: 12px; 211 | .border-radius(0); 212 | } 213 | 214 | 215 | .nav > li > a:hover, 216 | .nav > li.active > a:hover { 217 | color: @white; 218 | } 219 | } 220 | 221 | .dropdown-menu { 222 | background-color: lighten(@blue, 10%); 223 | border: none; 224 | 225 | a { 226 | color: @textColor; 227 | } 228 | 229 | .divider { 230 | border-bottom: none; 231 | background-color: @blue; 232 | } 233 | } 234 | 235 | @media (max-width: 768px) { 236 | div.subnav .nav > li:first-child > a, 237 | div.subnav .nav > li:first-child > a:hover, 238 | div.subnav .nav > li.active:first-child > a, 239 | div.subnav .nav > li.active:first-child > a:hover { 240 | .border-radius(4px 4px 0 0); 241 | } 242 | 243 | div.subnav .nav > li:last-child > a, 244 | div.subnav .nav > li:last-child > a:hover, 245 | div.subnav .nav > li.active:last-child > a, 246 | div.subnav .nav > li.active:last-child > a:hover { 247 | .border-radius(0 0 4px 4px); 248 | } 249 | 250 | } 251 | 252 | // TABLES 253 | // ----------------------------------------------------- 254 | 255 | .table { 256 | background-color: darken(@blue, 3%); 257 | } 258 | 259 | .table th, .table td, .table tbody + tbody { 260 | border-top: none; 261 | } 262 | 263 | .table-bordered { 264 | border: none; 265 | th + th, 266 | td + td, 267 | th + td, 268 | td + th { 269 | border-left: none; 270 | } 271 | // Prevent a double border 272 | thead:first-child tr:first-child th, 273 | tbody:first-child tr:first-child th, 274 | tbody:first-child tr:first-child td { 275 | border-top: none; 276 | } 277 | } 278 | 279 | .table-striped { 280 | tbody { 281 | tr:nth-child(odd) td, 282 | tr:nth-child(odd) th { 283 | background-color: @blue; 284 | } 285 | } 286 | } 287 | 288 | .table { 289 | tbody tr:hover td, 290 | tbody tr:hover th { 291 | background-color: lighten(@blue, 5%); 292 | } 293 | } 294 | 295 | // BUTTONS 296 | // -------------------------------------------------- 297 | 298 | .btn, 299 | .btn:hover { 300 | text-shadow: none; 301 | background-image: none; 302 | .box-shadow(-2px 2px 0 darken(@white, 80%)); 303 | border: none; 304 | } 305 | 306 | .btn-warning { 307 | background-color: @yellow; 308 | } 309 | 310 | .btn-primary, .btn-primary:hover { 311 | .box-shadow(-2px 2px 0 darken(@primaryButtonBackground, 30%)); 312 | } 313 | 314 | .btn-warning, .btn-warning:hover { 315 | .box-shadow(-2px 2px 0 darken(@yellow, 30%)); 316 | } 317 | 318 | .btn-danger, .btn-danger:hover { 319 | .box-shadow(-2px 2px 0 darken(#ee5f5b, 30%)); 320 | } 321 | 322 | .btn-success, .btn-success:hover { 323 | .box-shadow(-2px 2px 0 darken(#62c462, 30%)); 324 | } 325 | 326 | .btn-info, .btn-info:hover { 327 | .box-shadow(-2px 2px 0 darken(#5bc0de, 40%)); 328 | } 329 | 330 | .btn-inverse, .btn-inverse:hover { 331 | .box-shadow(-2px 2px 0 darken(#454545, 20%)); 332 | } 333 | 334 | 335 | 336 | .btn.dropdown-toggle, .btn.dropdown-toggle:hover { 337 | .box-shadow(0 2px 0 darken(@white, 80%)); 338 | } 339 | 340 | .btn-primary.dropdown-toggle, .btn-primary.dropdown-toggle:hover { 341 | .box-shadow(0 2px 0 darken(@primaryButtonBackground, 30%)); 342 | } 343 | 344 | .btn-warning.dropdown-toggle, .btn-warning.dropdown-toggle:hover { 345 | .box-shadow(0 2px 0 darken(@yellow, 30%)); 346 | } 347 | 348 | .btn-danger.dropdown-toggle, .btn-danger.dropdown-toggle:hover { 349 | .box-shadow(0 2px 0 darken(#ee5f5b, 30%)); 350 | } 351 | 352 | .btn-success.dropdown-toggle, .btn-success.dropdown-toggle:hover { 353 | .box-shadow(0 2px 0 darken(#62c462, 30%)); 354 | } 355 | 356 | .btn-info.dropdown-toggle, .btn-info.dropdown-toggle:hover { 357 | .box-shadow(0 2px 0 darken(#5bc0de, 40%)); 358 | } 359 | 360 | .btn-inverse.dropdown-toggle, .btn-inverse.dropdown-toggle:hover { 361 | .box-shadow(0 2px 0 darken(#454545, 20%)); 362 | } 363 | 364 | .btn.active, 365 | .btn:active { 366 | position: relative; 367 | top: 1px; 368 | left: -1px; 369 | .box-shadow(-1px 1px 0 darken(@white, 80%)) 370 | } 371 | 372 | .btn.disabled, 373 | .btn.disabled.active, 374 | .btn.disabled:active, 375 | .btn[disabled] { 376 | .box-shadow(none); 377 | text-shadow: none; 378 | top: 0; 379 | left: 0; 380 | } 381 | 382 | [class^="icon-"], [class*=" icon-"] { 383 | vertical-align: -13%; 384 | } 385 | 386 | // NAVIGATION 387 | // -------------------------------------------------- 388 | 389 | .nav-list { 390 | padding: 0 15px; 391 | } 392 | 393 | .nav-list > li > a, .nav-list .nav-header { 394 | text-shadow: none; 395 | color: @textColor; 396 | } 397 | 398 | .nav-list .active > a, .nav-list .active > a:hover { 399 | text-shadow: none; 400 | color: @white; 401 | } 402 | 403 | .nav-list li > a:hover { 404 | background-color: lighten(@blue, 10%); 405 | } 406 | 407 | .nav-tabs, .nav-tabs.nav-stacked > li > a { 408 | border-color: transparent; 409 | } 410 | 411 | .nav-tabs { 412 | > li > a { 413 | background-color: @blue; 414 | color: @textColor; 415 | } 416 | 417 | li.active > a, 418 | li.active > a:hover, 419 | &.nav-stacked > li.active > a:hover { 420 | color: @white; 421 | background-color: @orange; 422 | border-color: transparent; 423 | } 424 | 425 | li > a:hover, 426 | &.nav-stacked > li > a:hover { 427 | background-color: lighten(@blue, 10%); 428 | border-color: transparent; 429 | } 430 | } 431 | 432 | .nav-pills > li > a { 433 | color: @textColor; 434 | background-color: @blue; 435 | } 436 | 437 | .nav-pills > li:hover > a { 438 | background-color: lighten(@blue, 10%); 439 | border-color: transparent; 440 | } 441 | 442 | .nav-tabs .open .dropdown-toggle, 443 | .nav-pills .open .dropdown-toggle, 444 | .nav > .open.active > a:hover { 445 | background-color: lighten(@blue, 10%); 446 | border-color: transparent; 447 | } 448 | 449 | .dropdown.open .dropdown-menu > li > a:hover, 450 | .dropdown.open .dropdown-menu > li.active > a:hover { 451 | background-color: @orange; 452 | color: @white; 453 | } 454 | 455 | .tabbable .nav-tabs, 456 | .tabbable .nav-tabs > li.active > a, 457 | .tabbable .nav-tabs > li > a:hover, 458 | .tabbable .nav-tabs > li.active > a:hover { 459 | border-color: transparent; 460 | } 461 | 462 | .breadcrumb { 463 | background-color: @blue; 464 | background-image: none; 465 | border: none; 466 | .box-shadow(none); 467 | 468 | li { 469 | text-shadow: none; 470 | } 471 | 472 | .divider { 473 | color: @textColor; 474 | } 475 | } 476 | 477 | .pagination ul { 478 | 479 | background-color: @blue; 480 | background-image: none; 481 | border-color: transparent; 482 | 483 | li > a { 484 | border: none; 485 | color: @textColor; 486 | } 487 | 488 | li.active > a, 489 | li.active > a:hover { 490 | background: @orange; 491 | color: @white; 492 | } 493 | 494 | li > a:hover { 495 | background: lighten(@blue, 10%); 496 | } 497 | 498 | li.disabled > a, 499 | li.disabled > a:hover { 500 | background: darken(@blue, 5%); 501 | } 502 | } 503 | 504 | .pager a { 505 | color: @textColor; 506 | background-color: @blue; 507 | border-color: transparent; 508 | 509 | &:hover { 510 | background: lighten(@blue, 10%); 511 | } 512 | } 513 | 514 | // FORMS 515 | // -------------------------------------------------- 516 | 517 | input, button, select, textarea { 518 | font-family: 'Noticia Text', serif; 519 | } 520 | 521 | legend { 522 | border-bottom: none; 523 | } 524 | 525 | label { 526 | color: @textColor; 527 | line-height: 15px; 528 | } 529 | 530 | .help-block { 531 | color: @textColor; 532 | opacity: 0.6; 533 | } 534 | 535 | .form-actions { 536 | background-color: transparent; 537 | border-top: none; 538 | } 539 | 540 | // Warning 541 | .control-group.warning { 542 | .formFieldState(lighten(@warningText, 10%), lighten(@warningText, 10%), @warningBackground); 543 | } 544 | // Error 545 | .control-group.error { 546 | .formFieldState(lighten(@errorText, 10%), lighten(@errorText, 10%), @errorBackground); 547 | } 548 | // Success 549 | .control-group.success { 550 | .formFieldState(lighten(@successText, 10%), lighten(@successText, 10%), @successBackground); 551 | } 552 | 553 | // MISCELLANEOUS 554 | // -------------------------------------------------- 555 | 556 | hr, .page-header { 557 | border-bottom: none; 558 | } 559 | 560 | footer.footer { 561 | border-top: 1px solid darken(@blueDark, 5%); 562 | } 563 | 564 | .well { 565 | background-color: @blue; 566 | border: none; 567 | .box-shadow(none); 568 | } 569 | 570 | .progress { 571 | background-color: darken(@blueDark, 5%); 572 | background-image: none; 573 | .box-shadow(none); 574 | 575 | .bar { 576 | .box-shadow(none); 577 | } 578 | } 579 | 580 | .thumbnail { 581 | border: none; 582 | background: @blue; 583 | .border-radius(3px); 584 | } 585 | 586 | .label { 587 | background-color: @blue; 588 | color: @textColor; 589 | } 590 | 591 | .label-important { 592 | background-color: @errorText; 593 | } 594 | 595 | .label-warning { 596 | background-color: @orange; 597 | } 598 | 599 | .label-success { 600 | background-color: @successText; 601 | } 602 | 603 | .label-info { 604 | background-color: @infoText; 605 | } 606 | 607 | .alert { 608 | background-color: @blue; 609 | border: none; 610 | color: @textColor; 611 | text-shadow: none; 612 | 613 | a { 614 | color: lighten(@orange, 12%); 615 | } 616 | } 617 | 618 | .alert .alert-heading { 619 | color: @orange; 620 | } 621 | 622 | .alert-success { 623 | background-color: @successText; 624 | } 625 | 626 | .alert-danger, 627 | .alert-error { 628 | background-color: @errorText; 629 | } 630 | 631 | .alert-info { 632 | background-color: @infoText; 633 | } 634 | 635 | -------------------------------------------------------------------------------- /public/css/bootswatch/amelia/bootswatch.less: -------------------------------------------------------------------------------- 1 | // Bootswatch.less 2 | // Swatch: Amelia 3 | // ----------------------------------------------------- 4 | 5 | // TYPOGRAPHY 6 | // ----------------------------------------------------- 7 | 8 | @import url('http://fonts.googleapis.com/css?family=Lobster'); 9 | @import url('http://fonts.googleapis.com/css?family=Cabin:400,700'); 10 | 11 | h1, h2, h3, h4, h5, h6, 12 | h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { 13 | color: @textColor; 14 | font-weight: normal; 15 | } 16 | 17 | input, button, select, textarea, 18 | .navbar-search .search-query, 19 | h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { 20 | font-family: @baseFontFamily; 21 | } 22 | 23 | .muted { 24 | color: rgba(256, 256, 256, 0.5); 25 | } 26 | 27 | .navbar .brand, h1, h2, h3, h4, h5, legend { 28 | font-family: 'Lobster', cursive; 29 | } 30 | 31 | 32 | // SCAFFOLDING 33 | // ----------------------------------------------------- 34 | 35 | body { 36 | background-color: #4397A2; 37 | #gradient > .radial(lighten(#0F8790, 7%), #0F8790); 38 | } 39 | 40 | hr { 41 | border-bottom: 1px solid rgba(256, 256, 256, 0.3); 42 | } 43 | 44 | .page-header { 45 | border-bottom: 0px solid transparent; 46 | } 47 | 48 | footer.footer { 49 | border-top: 1px solid rgba(256, 256, 256, 0.3); 50 | } 51 | 52 | footer.footer p { 53 | color: @textColor; 54 | } 55 | 56 | // NAVBAR 57 | // ----------------------------------------------------- 58 | 59 | .navbar { 60 | .navbar-inner { 61 | .border-radius(0); 62 | } 63 | 64 | .brand { 65 | padding-top: 12px; 66 | font-size: 24px; 67 | font-weight: normal; 68 | } 69 | 70 | .nav > li > a { 71 | padding-top: 17px; 72 | padding-bottom: 14px; 73 | text-shadow: none; 74 | color: @textColor; 75 | } 76 | 77 | .nav > li.active > a { 78 | color: @white; 79 | background-color: lighten(@navbarBackground, 10%); 80 | } 81 | 82 | .nav > li > a:hover, 83 | .nav > li.active > a:hover { 84 | background-color: lighten(@navbarBackground, 10%); 85 | } 86 | 87 | .navbar-search { 88 | margin-top: 10px; 89 | } 90 | 91 | .navbar-search .search-query { 92 | border: 2px solid lighten(@navbarBackground, 10%); 93 | background-color: transparent; 94 | .border-radius(0); 95 | .box-shadow(none); 96 | 97 | &:focus, &.focus { 98 | background-color: @grayLighter; 99 | border-color: @grayLighter; 100 | text-shadow: none; 101 | padding: 4px 9px; 102 | .box-shadow(none); 103 | } 104 | 105 | } 106 | } 107 | 108 | .navbar .nav > li.dropdown.open > .dropdown-menu a:hover, 109 | div.subnav .nav > li.dropdown.open > .dropdown-menu a:hover, 110 | .dropdown-menu > li > a:hover, 111 | .nav .dropdown.open > .dropdown-menu > li > a:hover { 112 | background-color: rgba(0, 57, 59, 0.9); 113 | } 114 | 115 | div.subnav { 116 | background-color: rgba(42, 99, 105, 0.9); 117 | background-image: none; 118 | border: 0px solid transparent; 119 | .border-radius(0); 120 | .box-shadow(none); 121 | 122 | .nav > li.dropdown.open > a { 123 | border-color: transparent; 124 | background-color: rgba(256, 256, 256, 0.4); 125 | } 126 | 127 | .nav > li > a { 128 | color: @textColor; 129 | border-color: transparent; 130 | } 131 | 132 | .nav > li:first-child > a, 133 | .nav > li:first-child > a:hover { 134 | .border-radius(0); 135 | } 136 | 137 | .nav > .active > a { 138 | background-color: transparent; 139 | border-color: transparent; 140 | color: @textColor; 141 | .box-shadow(none); 142 | } 143 | 144 | .nav > .active > a:hover, 145 | .nav > li > a:hover, 146 | .nav > li.active > a:hover, { 147 | border-right-color: transparent; 148 | background-color: rgba(256, 256, 256, 0.4); 149 | color: @textColor; 150 | } 151 | } 152 | 153 | div.subnav .nav > li:first-child > a:hover { 154 | border-left-color: rgba(256, 256, 256, 0.4); 155 | border-left-width: 1px; 156 | } 157 | 158 | div.subnav-fixed { 159 | top: 50px; 160 | } 161 | 162 | .navbar .nav-collapse.collapse { 163 | 164 | li > a { 165 | color: @textColor; 166 | .border-radius(0); 167 | } 168 | 169 | li > a:hover { 170 | background-color: lighten(@navbarBackground, 10%); 171 | } 172 | 173 | .navbar-form, .navbar-search { 174 | .box-shadow(none); 175 | border-color: lighten(@navbarBackground, 10%); 176 | } 177 | 178 | .navbar-search .search-query { 179 | border: 2px solid @textColor; 180 | } 181 | } 182 | 183 | // BUTTONS 184 | // ----------------------------------------------------- 185 | 186 | .buttonBackgroundCustom(@color) { 187 | 188 | background-image: none; 189 | background-color: @color; 190 | 191 | &:hover, &:active, &.active, &.disabled, &[disabled] { 192 | background-color: darken(@color, 5%); 193 | text-shadow: none; 194 | } 195 | 196 | &:active, &.active { 197 | background-color: darken(@color, 15%); 198 | .box-shadow(none); 199 | } 200 | 201 | // IE 7 + 8 can't handle box-shadow to show active, so we darken a bit ourselves 202 | &:active, 203 | &.active { 204 | background-color: darken(@color, 15%) e("\9"); 205 | } 206 | } 207 | 208 | .btn { 209 | padding: 12px 16px; 210 | .border-radius(0); 211 | border: 0px solid transparent; 212 | text-shadow: none; 213 | .box-shadow(none); 214 | .buttonBackgroundCustom(@grayLighter); 215 | } 216 | 217 | .btn-group .btn:first-child { 218 | margin-left: 0; 219 | -webkit-border-top-left-radius: 0; 220 | -moz-border-radius-topleft: 0; 221 | border-top-left-radius: 0; 222 | -webkit-border-bottom-left-radius: 0; 223 | -moz-border-radius-bottomleft: 0; 224 | border-bottom-left-radius: 0; 225 | } 226 | 227 | .btn-group .btn:last-child, 228 | .btn-group .dropdown-toggle { 229 | -webkit-border-top-right-radius: 0; 230 | -moz-border-radius-topright: 0; 231 | border-top-right-radius: 0; 232 | -webkit-border-bottom-right-radius: 0; 233 | -moz-border-radius-bottomright: 0; 234 | border-bottom-right-radius: 0; 235 | } 236 | 237 | .btn-group .dropdown-toggle, 238 | .btn-group.open .dropdown-toggle, 239 | .btn.open .dropdown-toggle { 240 | .box-shadow(none); 241 | } 242 | 243 | 244 | .btn-warning .caret { 245 | opacity: 0.75; 246 | border-top-color: @white; 247 | } 248 | 249 | .btn-primary { 250 | .buttonBackgroundCustom(#AD1D28); 251 | } 252 | 253 | .btn-warning { 254 | .buttonBackgroundCustom(@orange); 255 | } 256 | 257 | .btn-danger { 258 | .buttonBackgroundCustom(darken(@yellow, 3%)); 259 | } 260 | 261 | .btn-success { 262 | .buttonBackgroundCustom(@green); 263 | } 264 | 265 | .btn-info { 266 | .buttonBackgroundCustom(@purple); 267 | } 268 | 269 | .btn-inverse { 270 | .buttonBackgroundCustom(#27666D); 271 | } 272 | 273 | .btn-small { 274 | padding: 13px 16px 12px; 275 | } 276 | 277 | [class^="icon-"], [class*=" icon-"] { 278 | margin-top: 2px; 279 | margin-right: 8px; 280 | } 281 | 282 | .btn-small [class^="icon-"] { 283 | margin-top: 1px; 284 | } 285 | 286 | .add-on [class^="icon-"] { 287 | margin-left: 5px; 288 | } 289 | 290 | // TABLES 291 | // ----------------------------------------------------- 292 | 293 | .table { 294 | background-color: lighten(#147E88, 10%); 295 | } 296 | 297 | .table th, .table td, 298 | .table tbody + tbody { 299 | border-top: 0px solid transparent; 300 | } 301 | 302 | .table-bordered { 303 | .border-radius(0); 304 | border: 1px solid lighten(#147E88, 12%); 305 | 306 | th, td { 307 | border-top: 1px solid lighten(#147E88, 12%); 308 | } 309 | 310 | th + th, 311 | td + td, 312 | th + td, 313 | td + th { 314 | border-left: 1px solid lighten(#147E88, 12%); 315 | } 316 | 317 | } 318 | 319 | .table-striped { 320 | tbody { 321 | tr:nth-child(odd) td, 322 | tr:nth-child(odd) th { 323 | background-color: lighten(#147E88, 15%); 324 | } 325 | } 326 | } 327 | 328 | .table { 329 | tbody tr:hover td, 330 | tbody tr:hover th { 331 | background-color: rgba(256, 256, 256, 0.4); 332 | } 333 | } 334 | 335 | 336 | // FORMS 337 | // ----------------------------------------------------- 338 | 339 | legend, label, .help-block, .input-file { 340 | color: @textColor; 341 | border: 0px solid transparent; 342 | } 343 | 344 | input, textarea, .uneditable-input { 345 | border: 0px solid transparent; 346 | padding: 10px; 347 | } 348 | 349 | select { 350 | border: 0px solid transparent; 351 | } 352 | 353 | button { 354 | margin-left: 12px; 355 | } 356 | 357 | input, textarea, .search-query, .uneditable-input, 358 | .input-append input, .input-append .uneditable-input, 359 | .input-prepend input, .input-prepend .uneditable-input { 360 | border-color: transparent; 361 | .border-radius(0); 362 | .box-shadow(none); 363 | } 364 | 365 | .form-actions { 366 | background-color: transparent; 367 | border-top: 0px solid transparent; 368 | } 369 | 370 | .control-group.warning > label, 371 | .control-group.warning .help-inline { 372 | color: lighten(@orange, 30%); 373 | } 374 | 375 | .control-group.error > label, 376 | .control-group.error .help-inline { 377 | color: lighten(@linkColor, 10%); 378 | } 379 | 380 | .control-group.success > label, 381 | .control-group.success .help-inline { 382 | color: lighten(@green, 20%); 383 | } 384 | 385 | .input-prepend .add-on, .input-append .add-on { 386 | height: 25px; 387 | padding-top: 9px; 388 | text-shadow: none; 389 | border-color: transparent; 390 | .border-radius(0); 391 | background-color: @grayLighter; 392 | } 393 | 394 | // NAVIGATION 395 | // ----------------------------------------------------- 396 | 397 | .breadcrumb, .pager > li > a { 398 | border-color: transparent; 399 | .border-radius(0); 400 | .box-shadow(none); 401 | text-shadow: none; 402 | } 403 | 404 | .breadcrumb { 405 | background-color: #3CB9C6; 406 | background-image: none; 407 | 408 | li { 409 | text-shadow: none; 410 | } 411 | 412 | .divider { 413 | color: @linkColor; 414 | } 415 | } 416 | 417 | .pager > li > a { 418 | background-color: #3CB9C6; 419 | 420 | &:hover { 421 | background-color: #8AD5DC; 422 | } 423 | } 424 | 425 | .pagination { 426 | 427 | ul { 428 | background-color: #3CB9C6; 429 | background-image: none; 430 | } 431 | 432 | li a { 433 | border: 0px solid transparent; 434 | } 435 | 436 | .disabled a, .disabled a:hover { 437 | color: @textColor; 438 | } 439 | 440 | li a:hover { 441 | background-color: rgba(256, 256, 256, 0.4); 442 | color: @linkColor; 443 | } 444 | 445 | .active a, .active a:hover { 446 | background-color: rgba(256, 256, 256, 0.4); 447 | color: @textColor; 448 | } 449 | 450 | ul, 451 | li:first-child a, 452 | li:last-child a { 453 | .border-radius(0); 454 | } 455 | 456 | } 457 | 458 | .nav-tabs .dropdown.open > .dropdown-toggle, 459 | .nav-pills .dropdown.open > .dropdown-toggle { 460 | background-color: #8AD5DC; 461 | color: @linkColor; 462 | border-color: transparent; 463 | } 464 | 465 | .nav-tabs, .nav-pills { 466 | border-color: transparent; 467 | 468 | li > a { 469 | border-color: transparent; 470 | .border-radius(0); 471 | .box-shadow(0); 472 | } 473 | 474 | li.active > a, 475 | li:active > a, 476 | li.active > a:hover, 477 | li:active > a:hover { 478 | color: @textColor; 479 | } 480 | 481 | li.active > a, 482 | li:active > a, 483 | li > a:hover, 484 | li.active > a:hover, 485 | li:active > a:hover { 486 | background-color: #8AD5DC; 487 | border-color: transparent; 488 | text-shadow: none; 489 | } 490 | } 491 | 492 | .nav-tabs, .nav-tabs > li > a { 493 | border-bottom: 1px solid rgba(256, 256, 256, 0.5); 494 | } 495 | 496 | .nav-tabs > li > a { 497 | background-color: #3CB9C6; 498 | } 499 | 500 | .nav-tabs.nav-stacked { 501 | 502 | li > a:first-child, 503 | li > a:last-child { 504 | .border-radius(0); 505 | } 506 | 507 | li > a, 508 | li > a:hover, 509 | li.active > a, 510 | li:active > a, 511 | li.active > a:hover, 512 | li:active > a:hover { 513 | border-color: transparent; 514 | } 515 | } 516 | 517 | .nav-list { 518 | .nav-header { 519 | text-shadow: none; 520 | color: @textColor; 521 | } 522 | 523 | li > a { 524 | text-shadow: none; 525 | } 526 | 527 | li.active > a, 528 | li:active > a, 529 | li > a:hover, 530 | li.active > a:hover, 531 | li:active > a:hover { 532 | background-color: #8AD5DC; 533 | text-shadow: none; 534 | } 535 | } 536 | 537 | 538 | 539 | // MISCELLANEOUS 540 | // ----------------------------------------------------- 541 | 542 | .alert, .label, .progress, .well, pre, code { 543 | border-color: transparent; 544 | .border-radius(0); 545 | .box-shadow(none); 546 | text-shadow: none; 547 | } 548 | 549 | code, pre { 550 | background-color: rgba(256, 256, 256, 0.3); 551 | padding: 2px; 552 | } 553 | 554 | .well { 555 | background-color: #3CB9C6; 556 | background-image: none; 557 | } 558 | 559 | .label, .label:hover { 560 | background-color: @grayLighter; 561 | text-shadow: none; 562 | color: @grayDark; 563 | } 564 | 565 | .label-warning, .label-warning:hover, .alert { 566 | background-color: @orange; 567 | color: @textColor; 568 | } 569 | 570 | .label-important, .label-important:hover, .alert-error { 571 | background-color: darken(@yellow, 3%); 572 | color: @textColor; 573 | } 574 | 575 | .label-success, .label-success:hover, .alert-success { 576 | background-color: @green; 577 | color: @textColor; 578 | } 579 | 580 | .label-info, .label-info:hover, .alert-info { 581 | background-color: @purple; 582 | color: @textColor; 583 | } 584 | 585 | .alert-heading { 586 | color: @textColor; 587 | } 588 | 589 | .progress { 590 | background-image: none; 591 | background-color: #27666D; 592 | 593 | .bar { 594 | .box-shadow(none); 595 | background-image: none; 596 | background-color: @orange; 597 | } 598 | } 599 | 600 | .progress-danger .bar { 601 | background-image: none; 602 | background-color: #AD1D28; 603 | } 604 | .progress-danger.progress-striped .bar { 605 | #gradient > .striped(#AD1D28); 606 | } 607 | 608 | .progress-success .bar { 609 | background-image: none; 610 | background-color: @green; 611 | } 612 | .progress-success.progress-striped .bar { 613 | #gradient > .striped(@green); 614 | } 615 | 616 | .progress-info .bar { 617 | background-image: none; 618 | background-color: @blue; 619 | } 620 | .progress-info.progress-striped .bar { 621 | #gradient > .striped(@blue); 622 | } 623 | 624 | .thumbnail { 625 | border: 0px solid transparent; 626 | .border-radius(0); 627 | .box-shadow(none); 628 | } 629 | 630 | blockquote { 631 | 632 | border-left-color: lighten(#147E88, 12%); 633 | 634 | &.pull-right { 635 | border-right-color: lighten(#147E88, 12%); 636 | } 637 | 638 | small { 639 | color: rgba(256, 256, 256, 0.6); 640 | } 641 | } -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | var config = require("../config"); 2 | var GHAPI = require("../gh-api").GHAPI; 3 | var sys = require('util'); 4 | var User = require('../models/User').User; 5 | var BlogPost = require('../models/BlogPost').BlogPost; 6 | var GitHubApi = require('github'); 7 | var redis = require('redis'); 8 | var urlparse = require('url').parse; 9 | var qs = require('querystring'); 10 | var MD = require('marked'); 11 | 12 | var github = new GitHubApi({ 13 | version: "3.0.0" 14 | }); 15 | 16 | var rclient; 17 | 18 | if (config.redis_uri) { 19 | var uri = urlparse(process.env.REDISTOGO_URL); 20 | rclient = redis.createClient(uri.port, uri.host.split(":")[0]); 21 | rclient.auth(uri.auth.split(":")[1]); 22 | } else { 23 | rclient = redis.createClient(); 24 | } 25 | 26 | 27 | function getClientIp(req) { 28 | 29 | var ipAddress; 30 | // Amazon EC2 / Heroku workaround to get real client IP 31 | var forwardedIpsStr = req.header('x-forwarded-for'); 32 | if (forwardedIpsStr) { 33 | 34 | // 'x-forwarded-for' header may return multiple IP addresses in 35 | // the format: "client IP, proxy 1 IP, proxy 2 IP" so take the 36 | // the first one 37 | var forwardedIps = forwardedIpsStr.split(','); 38 | ipAddress = forwardedIps[0]; 39 | } 40 | if (!ipAddress) { 41 | // Ensure getting client IP address still works in 42 | // development environment 43 | ipAddress = req.connection.remoteAddress; 44 | } 45 | return ipAddress; 46 | }; 47 | 48 | var render = function(res, path, opts) { 49 | opts = opts || {}; 50 | opts.config = config; 51 | opts.sitename = opts.sitename || config.sitename; 52 | opts.title = opts.title || config.title; 53 | opts.ga_id = opts.ga_id || config.ga_id; 54 | opts.ga_domain = opts.ga_domain || config.ga_domain; 55 | 56 | opts.is_allowed_user = false; 57 | if (opts.user) { 58 | var username = opts.user.username.toLowerCase(); 59 | if (opts.user && config.allowed_users == null && config.is_multitenant) { 60 | // all logged in users are allowed 61 | opts.is_allowed_user = true; 62 | } else if (opts.user && config.allowed_users && config.allowed_users.length && config.allowed_users.indexOf(username) !== -1 && config.is_multitenant) { 63 | // only some users are allowed 64 | opts.is_allowed_user = true; 65 | } 66 | } 67 | 68 | res.render(path, opts); 69 | }; 70 | 71 | var get_user = function(req, callback) { 72 | var gh_userid = req.session.user.userid; 73 | User.findOne({gh_userid: gh_userid}, function(err, doc) { 74 | if (err) { 75 | console.log("ERROR get_user: " + err); 76 | callback(err, doc); 77 | return; 78 | } 79 | if (doc) { 80 | callback(err, doc); 81 | } else { 82 | callback("no user!", doc); 83 | } 84 | }); 85 | }; 86 | 87 | exports.index = function(req, res) { 88 | BlogPost.find({isPublic: true}).sort('tstamp', -1).limit(20).exec(generic_doc_handler(res, function(docs) { 89 | render(res, 'index', {title: "Home", blog_posts: docs, user: req.session.user}); 90 | })); 91 | }; 92 | 93 | exports.about = function(req, res) { 94 | render(res, config.about_view, {title: "About", user: req.session.user}); 95 | }; 96 | 97 | exports.bounce_shortid = function(req, res) { 98 | BlogPost.findOne({shortid: req.params.id}, generic_doc_handler(res, function(doc) { 99 | res.redirect('/' + doc.gistIdStr); 100 | })); 101 | }; 102 | 103 | var render_post = function(req, res, gist, doc) { 104 | //console.log("GIST!!!!!\n" + JSON.stringify(gist, null, 4)); 105 | 106 | if (gist.owner && gist.url) { 107 | var metadata = JSON.parse(gist.files["metadata.json"].content); 108 | var viewable = false; 109 | 110 | if (gist["public"]) { 111 | viewable = true; 112 | } else { 113 | // private... 114 | if (req.session && req.session.user && gist.owner.id.toString() === req.session.user.userid) { 115 | // owner, so yes 116 | viewable = true; 117 | } else { 118 | // see if user is in allowed_viewers 119 | if (req.session && req.session.user && req.session.user.username) { 120 | var allowed_viewers = metadata.allowed_viewers || {}; 121 | for (var idx = 0; idx < allowed_viewers.length; idx++) { 122 | if (allowed_viewers[idx] === req.session.user.username) { 123 | viewable = true; 124 | break; 125 | } 126 | } 127 | } 128 | } 129 | } 130 | 131 | if (viewable) { 132 | var post = gist.files["post.md"].content; 133 | var title = metadata.title; 134 | MD(post, {gfm: true}, function(err, content) { 135 | doc.body = content; 136 | doc.title = title; 137 | doc.username = gist.owner.login; 138 | doc.post_id = gist.id; 139 | doc.tstamp = new Date(gist.created_at); 140 | 141 | render(res, 'view_post', {user: req.session.user, blog_post: doc, title: doc.title}); 142 | 143 | update_post_in_db(req, res, doc); 144 | }); 145 | } else { 146 | render(res, 'not_found', {title: "Not Found", user: req.session.user}); 147 | } 148 | } else { 149 | 150 | // don't remove too eagerly, this could wipe out valid posts 151 | // e.g. if the server is down or returns malformed json 152 | // //BlogPost.findOne({gistIdStr: req.params.id}).remove(); 153 | 154 | //res.end('invalid post id'); 155 | render(res, 'not_found', {title: "Not Found", user: req.session.user}); 156 | } 157 | }; 158 | 159 | var get_gist_from_github = function(req, gistIdStr, callback) { 160 | var access_token = (req.session && req.session.user ? req.session.user.access_token : null); 161 | var ghapi = new GHAPI(access_token); 162 | ghapi.request(ghapi.client.gists.get, {id: gistIdStr}, function(err, gist) { 163 | if (err) { 164 | console.log('view_post error w/ api: ' + err); 165 | callback(err, null); 166 | return; 167 | } 168 | callback(null, gist); 169 | }); 170 | }; 171 | 172 | exports.view_post = function(req, res) { 173 | BlogPost.findOne({gistIdStr: req.params.id}, function(e, doc) { 174 | if (e) { 175 | res.end('fatal error :('); 176 | return; 177 | } 178 | if (!doc) { 179 | render(res, 'not_found', {title: "Not Found", user: req.session.user}); 180 | return; 181 | } 182 | 183 | rclient.get("gistblog:post:" + req.params.id + ":json", function(rerror, rresult) { 184 | if (rerror) { 185 | res.end('fatal redis error'); 186 | return; 187 | } 188 | if (rresult) { 189 | console.log('redis hit!' + req.params.id); 190 | render_post(req, res, JSON.parse(rresult), doc); 191 | } else { 192 | 193 | get_gist_from_github(req, req.params.id, function(err, gist) { 194 | if (err) { 195 | console.log('view_post error w/ api: ' + err); 196 | res.end('error....'); 197 | return; 198 | } 199 | // render post 200 | render_post(req, res, gist, doc); 201 | // cache in redis 202 | rclient.setex("gistblog:post:" + req.params.id + ":json", 60000, JSON.stringify(gist)); 203 | }); 204 | } 205 | }); 206 | }); 207 | }; 208 | 209 | exports.user_index = function(req, res) { 210 | User.findOne({username: req.params.username}, generic_doc_handler(res, function(doc) { 211 | BlogPost.find({ownerIdStr: doc.gh_userid, isPublic: true}).sort('tstamp', -1).exec(generic_doc_handler(res, function(docs) { 212 | render(res, 'user_index', {title: doc.username, blog_posts: docs, user: req.session.user, author: doc}); 213 | })); 214 | })); 215 | }; 216 | 217 | exports.ajax_human_view = function(req, res) { 218 | BlogPost.findOne({gistIdStr: req.params.id}, generic_doc_handler(res, function(blog_post) { 219 | blog_post.views++; 220 | update_post_in_db(req, res, blog_post); 221 | res.end('ok'); 222 | })); 223 | }; 224 | 225 | var generic_doc_handler = function(res, callback) { 226 | return function(err, doc) { 227 | if (err) { 228 | res.end('fatal error'); 229 | return; 230 | } 231 | 232 | if (doc) { 233 | callback(doc); 234 | } else { 235 | res.end('no such item'); 236 | 237 | } 238 | }; 239 | }; 240 | 241 | exports.new_post = function(req, res) { 242 | render(res, 'new_post', {user: req.session.user, blog_post: null, title: "New Post"}); 243 | }; 244 | 245 | exports.edit_post = function(req, res) { 246 | BlogPost.findOne({gistIdStr: req.params.id}, function(e, doc) { 247 | if (!e && doc) { 248 | // make sure user is owner of post 249 | if (doc.ownerIdStr !== req.session.user.userid) { 250 | res.end('not allowed'); 251 | return; 252 | } 253 | get_gist_from_github(req, doc.gistIdStr, function(err, gist) { 254 | var metadata = JSON.parse(gist.files["metadata.json"].content); 255 | var post = gist.files["post.md"].content; 256 | var title = metadata.title; 257 | doc.body = post; 258 | doc.allowed_viewers_string = metadata.allowed_viewers ? metadata.allowed_viewers.join(", ") : ""; 259 | doc.is_private = metadata.visibility == "private" || metadata.visbility == "private"; 260 | doc.title = title; 261 | doc.username = gist.owner.login; 262 | doc.post_id = gist.id; 263 | render(res, 'new_post', {user: req.session.user, blog_post: doc, title: doc.title}); 264 | }); 265 | 266 | 267 | } else { 268 | res.end('error getting post!'); 269 | } 270 | }); 271 | }; 272 | 273 | exports.create_post = function(req, res) { 274 | publish_post(req, res, true, null); 275 | }; 276 | 277 | exports.update_post_gist = function(req, res) { 278 | BlogPost.findOne({gistIdStr: req.body.gistId}, function(e, doc) { 279 | if (!e && doc) { 280 | publish_post(req, res, false, doc); 281 | } else { 282 | res.end('error updating post!'); 283 | } 284 | }); 285 | }; 286 | 287 | var publish_post = function(req, res, is_newpost, blog_post) { 288 | get_user(req, function(err, user) { 289 | if (err) { 290 | res.end('error!'); 291 | return; 292 | } 293 | if (user) { 294 | if (is_newpost) { 295 | blog_post = new BlogPost(); 296 | } 297 | 298 | 299 | blog_post.title = req.body.title.trim(); 300 | blog_post.ownerIdStr = user.gh_userid; 301 | blog_post.ownerUsername = user.username; 302 | blog_post.save(function(e, d) { 303 | if (e) { 304 | console.log('error saving 1st time: ' + e); 305 | return; 306 | } 307 | console.log('new post shortid: ' + d.shortid); 308 | 309 | var ghapi = new GHAPI(user.gh_access_token); 310 | var entities; 311 | if (process.env.NODE_ENV === "production") { 312 | 313 | } 314 | var func = is_newpost ? ghapi.client.gists.create : ghapi.client.gists.edit; 315 | console.log("IS_PRIVATE IS " + req.body.is_private); 316 | var is_private = req.body.is_private == "on" ? true : false; 317 | var visibility = is_private ? "private" : "public"; 318 | var metadata = { 319 | title: req.body.title.trim(), 320 | visbility: visibility, 321 | visibility: visibility 322 | }; 323 | if (req.body.allowed_viewers && req.body.allowed_viewers.length && is_private) { 324 | metadata.allowed_viewers = req.body.allowed_viewers.split(",").map(function(item){return item.trim();}); 325 | } 326 | var opts = { 327 | description: blog_post.title, 328 | "public": !is_private, 329 | files: { 330 | "post.md": { 331 | content: req.body.body.trim() 332 | }, 333 | "metadata.json" : { 334 | content: JSON.stringify(metadata, null, 4) 335 | } 336 | } 337 | }; 338 | if (!is_newpost) { 339 | opts.id = blog_post.gistIdStr; 340 | } 341 | ghapi.request(func, opts, function(err2, gist) { 342 | if (err2) { 343 | console.log('error posting gist: ' + err2); 344 | return; 345 | } 346 | //console.log("GIST!!!!!"); 347 | //console.log(sys.inspect(gist)); 348 | //console.log("<<<< GIST!!!!!!"); 349 | if (!gist.url) { 350 | res.end('something went terribly wrong :('); 351 | return; 352 | } 353 | d.gistIdStr = gist.id.toString(); 354 | d.visibility = visibility; 355 | d.isPublic = !is_private; 356 | d.save(function(ee, dd) { 357 | if (ee) { 358 | console.log('error saving 2nd time: ' + ee); 359 | return; 360 | } 361 | // invalidate cache if updated so latest is visible next time 362 | if (!is_newpost) { 363 | rclient.del("gistblog:post:" + req.params.id + ":json", function(rerr, rresult) { 364 | res.redirect('/post/'+ dd.gistIdStr); 365 | }); 366 | } else { 367 | res.redirect('/post/'+ dd.gistIdStr); 368 | } 369 | 370 | }); 371 | }); 372 | }); 373 | 374 | 375 | } else { 376 | 377 | res.end('no user!'); 378 | return; 379 | } 380 | }); 381 | }; 382 | 383 | var update_post_in_db = function(req, res, blog_post, callback) { 384 | if (blog_post && blog_post.save) { 385 | blog_post.save(function(err, doc) { 386 | if (callback) { 387 | callback(); 388 | } 389 | }); 390 | } 391 | }; 392 | 393 | exports.login = function(req, res) { 394 | res.redirect("https://github.com/login/oauth/authorize?client_id=" + config.gh_consumer_key + "&response_type=token&redirect_uri=" + config.gh_callback + "&scope=gist"); 395 | }; 396 | 397 | exports.logout = function(req, res) { 398 | req.session.destroy(function(err) { 399 | if (err) { 400 | console.log("error logging out: " + err); 401 | } 402 | res.redirect("/"); 403 | }); 404 | }; 405 | 406 | exports.oauth_return = function(req, res) { 407 | //console.log("code is: " + req.query.code); 408 | var ghapi = new GHAPI(); 409 | ghapi.getAccessToken(req.query.code, function(err, result, data) { 410 | //console.log(data); 411 | //console.log("got access token: " + data.access_token); 412 | if (data.error) { 413 | res.end('error: ' + data.error); 414 | return; 415 | } 416 | //github.authenticate({type: "oauth", "token": data.access_token}); 417 | //console.log('kicking off get.user'); 418 | //github.user.get({}, function(err, user) { 419 | ghapi.access_token = data.access_token; 420 | ghapi.request(ghapi.client.user.get, {}, function(err, user) { 421 | //console.log("got user result: " + JSON.stringify(user)); 422 | req.session.user = { 423 | "userid": user.id.toString(), 424 | "username": user.login, 425 | "avatar": user.avatar_url, 426 | "access_token": data.access_token, 427 | "is_admin": user.id.toString() === config.admin_userid ? true : false, 428 | "name": user.name 429 | }; 430 | //console.log('user.id: ' + user.id.toString()); 431 | //console.log('config.admin: ' + config.admin_userid); 432 | 433 | User.findOne({gh_userid: user.id}, function(err, doc) { 434 | if (err) { 435 | console.log("ERROR: " + err); 436 | res.end('error'); 437 | return; 438 | } 439 | if (!doc) { 440 | doc = new User(); 441 | } 442 | doc.username = user.login; 443 | doc.gh_userid = user.id.toString(); 444 | doc.name = user.name; 445 | doc.gh_access_token = data.access_token; 446 | doc.avatar = user.avatar_url; 447 | doc.is_admin = user.id.toString() === config.admin_userid ? true : false; 448 | doc.save(function(e,d){}); 449 | 450 | res.redirect('/'); 451 | }); 452 | }); 453 | }); 454 | }; 455 | -------------------------------------------------------------------------------- /public/js/bootstrap.min.js.use: -------------------------------------------------------------------------------- 1 | /** 2 | * Bootstrap.js by @fat & @mdo 3 | * Copyright 2012 Twitter, Inc. 4 | * http://www.apache.org/licenses/LICENSE-2.0.txt 5 | */ 6 | !function(a){a(function(){"use strict",a.support.transition=function(){var b=document.body||document.documentElement,c=b.style,d=c.transition!==undefined||c.WebkitTransition!==undefined||c.MozTransition!==undefined||c.MsTransition!==undefined||c.OTransition!==undefined;return d&&{end:function(){var b="TransitionEnd";return a.browser.webkit?b="webkitTransitionEnd":a.browser.mozilla?b="transitionend":a.browser.opera&&(b="oTransitionEnd"),b}()}}()})}(window.jQuery),!function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype={constructor:c,close:function(b){function f(){e.trigger("closed").remove()}var c=a(this),d=c.attr("data-target"),e;d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),e=a(d),e.trigger("close"),b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.trigger("close").removeClass("in"),a.support.transition&&e.hasClass("fade")?e.on(a.support.transition.end,f):f()}},a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("alert");e||d.data("alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a(function(){a("body").on("click.alert.data-api",b,c.prototype.close)})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.button.defaults,c)};b.prototype={constructor:b,setState:function(a){var b="disabled",c=this.$element,d=c.data(),e=c.is("input")?"val":"html";a+="Text",d.resetText||c.data("resetText",c[e]()),c[e](d[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},toggle:function(){var a=this.$element.parent('[data-toggle="buttons-radio"]');a&&a.find(".active").removeClass("active"),this.$element.toggleClass("active")}},a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("button"),f=typeof c=="object"&&c;e||d.data("button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.defaults={loadingText:"loading..."},a.fn.button.Constructor=b,a(function(){a("body").on("click.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle")})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.carousel.defaults,c),this.options.slide&&this.slide(this.options.slide),this.options.pause=="hover"&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.prototype={cycle:function(){return this.interval=setInterval(a.proxy(this.next,this),this.options.interval),this},to:function(b){var c=this.$element.find(".active"),d=c.parent().children(),e=d.index(c),f=this;if(b>d.length-1||b<0)return;return this.sliding?this.$element.one("slid",function(){f.to(b)}):e==b?this.pause().cycle():this.slide(b>e?"next":"prev",a(d[b]))},pause:function(){return clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(b,c){var d=this.$element.find(".active"),e=c||d[b](),f=this.interval,g=b=="next"?"left":"right",h=b=="next"?"first":"last",i=this;this.sliding=!0,f&&this.pause(),e=e.length?e:this.$element.find(".item")[h]();if(e.hasClass("active"))return;return!a.support.transition&&this.$element.hasClass("slide")?(this.$element.trigger("slide"),d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")):(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),this.$element.trigger("slide"),this.$element.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)})),f&&this.cycle(),this}},a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("carousel"),f=typeof c=="object"&&c;e||d.data("carousel",e=new b(this,f)),typeof c=="number"?e.to(c):typeof c=="string"||(c=f.slide)?e[c]():e.cycle()})},a.fn.carousel.defaults={interval:5e3,pause:"hover"},a.fn.carousel.Constructor=b,a(function(){a("body").on("click.carousel.data-api","[data-slide]",function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=!e.data("modal")&&a.extend({},e.data(),c.data());e.carousel(f),b.preventDefault()})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.collapse.defaults,c),this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.prototype={constructor:b,dimension:function(){var a=this.$element.hasClass("width");return a?"width":"height"},show:function(){var b=this.dimension(),c=a.camelCase(["scroll",b].join("-")),d=this.$parent&&this.$parent.find(".in"),e;d&&d.length&&(e=d.data("collapse"),d.collapse("hide"),e||d.data("collapse",null)),this.$element[b](0),this.transition("addClass","show","shown"),this.$element[b](this.$element[0][c])},hide:function(){var a=this.dimension();this.reset(this.$element[a]()),this.transition("removeClass","hide","hidden"),this.$element[a](0)},reset:function(a){var b=this.dimension();return this.$element.removeClass("collapse")[b](a||"auto")[0].offsetWidth,this.$element[a?"addClass":"removeClass"]("collapse"),this},transition:function(b,c,d){var e=this,f=function(){c=="show"&&e.reset(),e.$element.trigger(d)};this.$element.trigger(c)[b]("in"),a.support.transition&&this.$element.hasClass("collapse")?this.$element.one(a.support.transition.end,f):f()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("collapse"),f=typeof c=="object"&&c;e||d.data("collapse",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.collapse.defaults={toggle:!0},a.fn.collapse.Constructor=b,a(function(){a("body").on("click.collapse.data-api","[data-toggle=collapse]",function(b){var c=a(this),d,e=c.attr("data-target")||b.preventDefault()||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),f=a(e).data("collapse")?"toggle":c.data();a(e).collapse(f)})})}(window.jQuery),!function(a){function d(){a(b).parent().removeClass("open")}"use strict";var b='[data-toggle="dropdown"]',c=function(b){var c=a(b).on("click.dropdown.data-api",this.toggle);a("html").on("click.dropdown.data-api",function(){c.parent().removeClass("open")})};c.prototype={constructor:c,toggle:function(b){var c=a(this),e=c.attr("data-target"),f,g;return e||(e=c.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,"")),f=a(e),f.length||(f=c.parent()),g=f.hasClass("open"),d(),!g&&f.toggleClass("open"),!1}},a.fn.dropdown=function(b){return this.each(function(){var d=a(this),e=d.data("dropdown");e||d.data("dropdown",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.dropdown.Constructor=c,a(function(){a("html").on("click.dropdown.data-api",d),a("body").on("click.dropdown.data-api",b,c.prototype.toggle)})}(window.jQuery),!function(a){function c(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),d.call(b)},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),d.call(b)})}function d(a){this.$element.hide().trigger("hidden"),e.call(this)}function e(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('