david 5 years ago
parent
commit
1fe5df7aef
  1. 11
      README.md
  2. 57
      app.py
  3. 18
      factoriocp.conf.sample
  4. 121
      factoriocp.py
  5. 7381
      static/css/bootstrap-flex.css
  6. 1
      static/css/bootstrap-flex.css.map
  7. 7
      static/css/bootstrap-flex.min.css
  8. 1
      static/css/bootstrap-flex.min.css.map
  9. 996
      static/css/bootstrap-grid.css
  10. 1
      static/css/bootstrap-grid.css.map
  11. 2
      static/css/bootstrap-grid.min.css
  12. 1
      static/css/bootstrap-grid.min.css.map
  13. 453
      static/css/bootstrap-reboot.css
  14. 1
      static/css/bootstrap-reboot.css.map
  15. 2
      static/css/bootstrap-reboot.min.css
  16. 1
      static/css/bootstrap-reboot.min.css.map
  17. 6686
      static/css/bootstrap.css
  18. 1
      static/css/bootstrap.css.map
  19. 7
      static/css/bootstrap.min.css
  20. 1
      static/css/bootstrap.min.css.map
  21. 45
      static/css/signin.css
  22. 30
      static/css/sticky-footer.css
  23. BIN
      static/favicon.ico
  24. 3430
      static/js/bootstrap.js
  25. 7
      static/js/bootstrap.min.js
  26. 71
      views/default.tpl
  27. 55
      views/login.tpl

11
README.md

@ -2,4 +2,13 @@
_a very basic factorio server control panel_
Features:
* spawn server(s)
* spawn server(s)
## Installation
```
git clone https://socialg.it/david/factoriocp.git
cd factoriocp
wget https://raw.githubusercontent.com/bottlepy/bottle/0.12.10/bottle.py
```

57
app.py

@ -1,57 +0,0 @@
# imports
import requests
from configparser import ConfigParser
from bottle import route, run, template, error, get, \
post, request, response, redirect, \
static_file
# config
configfile = "app.conf"
config = ConfigParser()
config.read(configfile)
if config['DEFAULT']['app_name']:
app_name = config['DEFAULT']['app_name']
else:
app_name = "FactorioCP"
if config['DEFAULT']['static_files']:
static_files = config['DEFAULT']['static_files']
else:
static_files = "static"
if config['DEFAULT']['cookie_secret']:
cookie_secret = config['DEFAULT']['cookie_secret']
else:
cookie_secret = "norealsecretDTR47SNI2390LGFsn4T-LASED2309h"
if config['DEFAULT']['cookie_max_age']:
cookie_max_age = int(config['DEFAULT']['cookie_max_age'])
else:
cookie_max_age=3600
if config['DEFAULT']['cookie_name']:
cookie_name = config['DEFAULT']['cookie_name']
else:
cookie_name = "factoriocp"
# functions
# routing
@get('/')
def home():
pass
# run development webserver
run(host='localhost', port=8000, debug=True, reloader=True)
# run prod server
#run(host='0.0.0.0', port=8000)

18
factoriocp.conf.sample

@ -0,0 +1,18 @@
# factoriocp sample configfile
# rename this file to app.conf
[DEFAULT]
app_name=factoriocp
cookie_name=factoriocp
cookie_max_age=3600
cookie_secret=something secret like this 0rE5vYvF 0rDbj5Io Z0h28k-k 12jtcRW0
static_files=/path/to/static/files
[server]
host=localhost
port=8000
debug=True
[factorio]
path=/path/to/factorio/servers
users=username anotheruser athirduser

121
factoriocp.py

@ -0,0 +1,121 @@
# imports
import requests
from configparser import ConfigParser
from bottle import route, run, template, error, get, \
post, request, response, redirect, \
static_file
# config
configfile = "factoriocp.conf"
config = ConfigParser()
config.read(configfile)
# functions
# verify session
def logged_in():
username = request.get_cookie(config['DEFAULT']['cookie_name'],
secret=config['DEFAULT']['cookie_secret'])
if username:
return username
else:
return False
# authenticate against factorio.com
def log_in(username, password):
data = { "username": username, "password": password }
l = requests.post("https://auth.factorio.com/api-login", data=data)
if l.status_code == 200:
response.set_cookie(config['DEFAULT']['cookie_name'],
username,
secret=config['DEFAULT']['cookie_secret'],
max_age=config['DEFAULT']['cookie_max_age'])
return True
else:
return False
# get a list of server dicts
def get_servers():
pass
return [{ "name": "Creative fun", "version": "0.14.20", "status": "online" },
{ "name": "Mad enemies", "version": "0.14.19", "status": "offline" }]
# routing
# render main page
@get('/')
def home():
username = logged_in()
message = request.get_cookie(config['DEFAULT']['cookie_name'] + "_message",
secret=config['DEFAULT']['cookie_secret'])
if username:
# render homepage
servers = get_servers()
return template('default',
username=username,
servers=servers,
app_name=config['DEFAULT']['app_name'],
message=message)
else:
# render login
return template('login',
app_name=config['DEFAULT']['app_name'],
cookie_max_age=int(config['DEFAULT']['cookie_max_age']),
message=message)
# get login credentials
@post('/login')
def post_login():
username = request.forms.get('username')
password = request.forms.get('password')
if log_in(username, password):
message = { "message": "You have logged in successfully", "alert": "success" }
response.set_cookie(config['DEFAULT']['cookie_name'] + "_message",
message,
secret=config['DEFAULT']['cookie_secret'],
max_age=5)
redirect('/')
else:
message = { "message": "User or password wrong", "alert": "danger" }
response.set_cookie(config['DEFAULT']['cookie_name'] + "_message",
message,
secret=config['DEFAULT']['cookie_secret'],
max_age=5)
redirect('/')
# delete cookie
@get('/logout')
@get('/logout/')
def logout():
if logged_in():
response.delete_cookie(config['DEFAULT']['cookie_name'])
message = { "message": "You have logged out successfully", "alert": "success" }
response.set_cookie(config['DEFAULT']['cookie_name'] + "_message",
message,
secret=config['DEFAULT']['cookie_secret'],
max_age=5)
redirect('/')
else:
redirect('/')
# serve static files
@get('/static/<filename:path>')
def send_static(filename):
return static_file(filename, root=config['DEFAULT']['static_files'])
# run webserver
if __name__ == "__main__":
if str(config['server']['debug']) == "True":
run(host=config['server']['host'],
port=config['server']['port'],
debug=True,
reloader=True)
else:
run(host=config['server']['host'],
port=config['server']['port'])

7381
static/css/bootstrap-flex.css

File diff suppressed because it is too large

1
static/css/bootstrap-flex.css.map

File diff suppressed because one or more lines are too long

7
static/css/bootstrap-flex.min.css

File diff suppressed because one or more lines are too long

1
static/css/bootstrap-flex.min.css.map

File diff suppressed because one or more lines are too long

996
static/css/bootstrap-grid.css

@ -0,0 +1,996 @@
.container {
margin-left: auto;
margin-right: auto;
padding-left: 15px;
padding-right: 15px;
}
.container::after {
content: "";
display: table;
clear: both;
}
@media (min-width: 576px) {
.container {
width: 540px;
max-width: 100%;
}
}
@media (min-width: 768px) {
.container {
width: 720px;
max-width: 100%;
}
}
@media (min-width: 992px) {
.container {
width: 960px;
max-width: 100%;
}
}
@media (min-width: 1200px) {
.container {
width: 1140px;
max-width: 100%;
}
}
.container-fluid {
margin-left: auto;
margin-right: auto;
padding-left: 15px;
padding-right: 15px;
}
.container-fluid::after {
content: "";
display: table;
clear: both;
}
.row {
margin-right: -15px;
margin-left: -15px;
}
.row::after {
content: "";
display: table;
clear: both;
}
@media (min-width: 576px) {
.row {
margin-right: -15px;
margin-left: -15px;
}
}
@media (min-width: 768px) {
.row {
margin-right: -15px;
margin-left: -15px;
}
}
@media (min-width: 992px) {
.row {
margin-right: -15px;
margin-left: -15px;
}
}
@media (min-width: 1200px) {
.row {
margin-right: -15px;
margin-left: -15px;
}
}
.col-xs, .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12, .col-sm, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-md, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-lg, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 {
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
@media (min-width: 576px) {
.col-xs, .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12, .col-sm, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-md, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-lg, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 {
padding-right: 15px;
padding-left: 15px;
}
}
@media (min-width: 768px) {
.col-xs, .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12, .col-sm, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-md, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-lg, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 {
padding-right: 15px;
padding-left: 15px;
}
}
@media (min-width: 992px) {
.col-xs, .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12, .col-sm, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-md, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-lg, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 {
padding-right: 15px;
padding-left: 15px;
}
}
@media (min-width: 1200px) {
.col-xs, .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12, .col-sm, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-md, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-lg, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 {
padding-right: 15px;
padding-left: 15px;
}
}
.col-xs-1 {
float: left;
width: 8.333333%;
}
.col-xs-2 {
float: left;
width: 16.666667%;
}
.col-xs-3 {
float: left;
width: 25%;
}
.col-xs-4 {
float: left;
width: 33.333333%;
}
.col-xs-5 {
float: left;
width: 41.666667%;
}
.col-xs-6 {
float: left;
width: 50%;
}
.col-xs-7 {
float: left;
width: 58.333333%;
}
.col-xs-8 {
float: left;
width: 66.666667%;
}
.col-xs-9 {
float: left;
width: 75%;
}
.col-xs-10 {
float: left;
width: 83.333333%;
}
.col-xs-11 {
float: left;
width: 91.666667%;
}
.col-xs-12 {
float: left;
width: 100%;
}
.pull-xs-0 {
right: auto;
}
.pull-xs-1 {
right: 8.333333%;
}
.pull-xs-2 {
right: 16.666667%;
}
.pull-xs-3 {
right: 25%;
}
.pull-xs-4 {
right: 33.333333%;
}
.pull-xs-5 {
right: 41.666667%;
}
.pull-xs-6 {
right: 50%;
}
.pull-xs-7 {
right: 58.333333%;
}
.pull-xs-8 {
right: 66.666667%;
}
.pull-xs-9 {
right: 75%;
}
.pull-xs-10 {
right: 83.333333%;
}
.pull-xs-11 {
right: 91.666667%;
}
.pull-xs-12 {
right: 100%;
}
.push-xs-0 {
left: auto;
}
.push-xs-1 {
left: 8.333333%;
}
.push-xs-2 {
left: 16.666667%;
}
.push-xs-3 {
left: 25%;
}
.push-xs-4 {
left: 33.333333%;
}
.push-xs-5 {
left: 41.666667%;
}
.push-xs-6 {
left: 50%;
}
.push-xs-7 {
left: 58.333333%;
}
.push-xs-8 {
left: 66.666667%;
}
.push-xs-9 {
left: 75%;
}
.push-xs-10 {
left: 83.333333%;
}
.push-xs-11 {
left: 91.666667%;
}
.push-xs-12 {
left: 100%;
}
.offset-xs-1 {
margin-left: 8.333333%;
}
.offset-xs-2 {
margin-left: 16.666667%;
}
.offset-xs-3 {
margin-left: 25%;
}
.offset-xs-4 {
margin-left: 33.333333%;
}
.offset-xs-5 {
margin-left: 41.666667%;
}
.offset-xs-6 {
margin-left: 50%;
}
.offset-xs-7 {
margin-left: 58.333333%;
}
.offset-xs-8 {
margin-left: 66.666667%;
}
.offset-xs-9 {
margin-left: 75%;
}
.offset-xs-10 {
margin-left: 83.333333%;
}
.offset-xs-11 {
margin-left: 91.666667%;
}
@media (min-width: 576px) {
.col-sm-1 {
float: left;
width: 8.333333%;
}
.col-sm-2 {
float: left;
width: 16.666667%;
}
.col-sm-3 {
float: left;
width: 25%;
}
.col-sm-4 {
float: left;
width: 33.333333%;
}
.col-sm-5 {
float: left;
width: 41.666667%;
}
.col-sm-6 {
float: left;
width: 50%;
}
.col-sm-7 {
float: left;
width: 58.333333%;
}
.col-sm-8 {
float: left;
width: 66.666667%;
}
.col-sm-9 {
float: left;
width: 75%;
}
.col-sm-10 {
float: left;
width: 83.333333%;
}
.col-sm-11 {
float: left;
width: 91.666667%;
}
.col-sm-12 {
float: left;
width: 100%;
}
.pull-sm-0 {
right: auto;
}
.pull-sm-1 {
right: 8.333333%;
}
.pull-sm-2 {
right: 16.666667%;
}
.pull-sm-3 {
right: 25%;
}
.pull-sm-4 {
right: 33.333333%;
}
.pull-sm-5 {
right: 41.666667%;
}
.pull-sm-6 {
right: 50%;
}
.pull-sm-7 {
right: 58.333333%;
}
.pull-sm-8 {
right: 66.666667%;
}
.pull-sm-9 {
right: 75%;
}
.pull-sm-10 {
right: 83.333333%;
}
.pull-sm-11 {
right: 91.666667%;
}
.pull-sm-12 {
right: 100%;
}
.push-sm-0 {
left: auto;
}
.push-sm-1 {
left: 8.333333%;
}
.push-sm-2 {
left: 16.666667%;
}
.push-sm-3 {
left: 25%;
}
.push-sm-4 {
left: 33.333333%;
}
.push-sm-5 {
left: 41.666667%;
}
.push-sm-6 {
left: 50%;
}
.push-sm-7 {
left: 58.333333%;
}
.push-sm-8 {
left: 66.666667%;
}
.push-sm-9 {
left: 75%;
}
.push-sm-10 {
left: 83.333333%;
}
.push-sm-11 {
left: 91.666667%;
}
.push-sm-12 {
left: 100%;
}
.offset-sm-0 {
margin-left: 0%;
}
.offset-sm-1 {
margin-left: 8.333333%;
}
.offset-sm-2 {
margin-left: 16.666667%;
}
.offset-sm-3 {
margin-left: 25%;
}
.offset-sm-4 {
margin-left: 33.333333%;
}
.offset-sm-5 {
margin-left: 41.666667%;
}
.offset-sm-6 {
margin-left: 50%;
}
.offset-sm-7 {
margin-left: 58.333333%;
}
.offset-sm-8 {
margin-left: 66.666667%;
}
.offset-sm-9 {
margin-left: 75%;
}
.offset-sm-10 {
margin-left: 83.333333%;
}
.offset-sm-11 {
margin-left: 91.666667%;
}
}
@media (min-width: 768px) {
.col-md-1 {
float: left;
width: 8.333333%;
}
.col-md-2 {
float: left;
width: 16.666667%;
}
.col-md-3 {
float: left;
width: 25%;
}
.col-md-4 {
float: left;
width: 33.333333%;
}
.col-md-5 {
float: left;
width: 41.666667%;
}
.col-md-6 {
float: left;
width: 50%;
}
.col-md-7 {
float: left;
width: 58.333333%;
}
.col-md-8 {
float: left;
width: 66.666667%;
}
.col-md-9 {
float: left;
width: 75%;
}
.col-md-10 {
float: left;
width: 83.333333%;
}
.col-md-11 {
float: left;
width: 91.666667%;
}
.col-md-12 {
float: left;
width: 100%;
}
.pull-md-0 {
right: auto;
}
.pull-md-1 {
right: 8.333333%;
}
.pull-md-2 {
right: 16.666667%;
}
.pull-md-3 {
right: 25%;
}
.pull-md-4 {
right: 33.333333%;
}
.pull-md-5 {
right: 41.666667%;
}
.pull-md-6 {
right: 50%;
}
.pull-md-7 {
right: 58.333333%;
}
.pull-md-8 {
right: 66.666667%;
}
.pull-md-9 {
right: 75%;
}
.pull-md-10 {
right: 83.333333%;
}
.pull-md-11 {
right: 91.666667%;
}
.pull-md-12 {
right: 100%;
}
.push-md-0 {
left: auto;
}
.push-md-1 {
left: 8.333333%;
}
.push-md-2 {
left: 16.666667%;
}
.push-md-3 {
left: 25%;
}
.push-md-4 {
left: 33.333333%;
}
.push-md-5 {
left: 41.666667%;
}
.push-md-6 {
left: 50%;
}
.push-md-7 {
left: 58.333333%;
}
.push-md-8 {
left: 66.666667%;
}
.push-md-9 {
left: 75%;
}
.push-md-10 {
left: 83.333333%;
}
.push-md-11 {
left: 91.666667%;
}
.push-md-12 {
left: 100%;
}
.offset-md-0 {
margin-left: 0%;
}
.offset-md-1 {
margin-left: 8.333333%;
}
.offset-md-2 {
margin-left: 16.666667%;
}
.offset-md-3 {
margin-left: 25%;
}
.offset-md-4 {
margin-left: 33.333333%;
}
.offset-md-5 {
margin-left: 41.666667%;
}
.offset-md-6 {
margin-left: 50%;
}
.offset-md-7 {
margin-left: 58.333333%;
}
.offset-md-8 {
margin-left: 66.666667%;
}
.offset-md-9 {
margin-left: 75%;
}
.offset-md-10 {
margin-left: 83.333333%;
}
.offset-md-11 {
margin-left: 91.666667%;
}
}
@media (min-width: 992px) {
.col-lg-1 {
float: left;
width: 8.333333%;
}
.col-lg-2 {
float: left;
width: 16.666667%;
}
.col-lg-3 {
float: left;
width: 25%;
}
.col-lg-4 {
float: left;
width: 33.333333%;
}
.col-lg-5 {
float: left;
width: 41.666667%;
}
.col-lg-6 {
float: left;
width: 50%;
}
.col-lg-7 {
float: left;
width: 58.333333%;
}
.col-lg-8 {
float: left;
width: 66.666667%;
}
.col-lg-9 {
float: left;
width: 75%;
}
.col-lg-10 {
float: left;
width: 83.333333%;
}
.col-lg-11 {
float: left;
width: 91.666667%;
}
.col-lg-12 {
float: left;
width: 100%;
}
.pull-lg-0 {
right: auto;
}
.pull-lg-1 {
right: 8.333333%;
}
.pull-lg-2 {
right: 16.666667%;
}
.pull-lg-3 {
right: 25%;
}
.pull-lg-4 {
right: 33.333333%;
}
.pull-lg-5 {
right: 41.666667%;
}
.pull-lg-6 {
right: 50%;
}
.pull-lg-7 {
right: 58.333333%;
}
.pull-lg-8 {
right: 66.666667%;
}
.pull-lg-9 {
right: 75%;
}
.pull-lg-10 {
right: 83.333333%;
}
.pull-lg-11 {
right: 91.666667%;
}
.pull-lg-12 {
right: 100%;
}
.push-lg-0 {
left: auto;
}
.push-lg-1 {
left: 8.333333%;
}
.push-lg-2 {
left: 16.666667%;
}
.push-lg-3 {
left: 25%;
}
.push-lg-4 {
left: 33.333333%;
}
.push-lg-5 {
left: 41.666667%;
}
.push-lg-6 {
left: 50%;
}
.push-lg-7 {
left: 58.333333%;
}
.push-lg-8 {
left: 66.666667%;
}
.push-lg-9 {
left: 75%;
}
.push-lg-10 {
left: 83.333333%;
}
.push-lg-11 {
left: 91.666667%;
}
.push-lg-12 {
left: 100%;
}
.offset-lg-0 {
margin-left: 0%;
}
.offset-lg-1 {
margin-left: 8.333333%;
}
.offset-lg-2 {
margin-left: 16.666667%;
}
.offset-lg-3 {
margin-left: 25%;
}
.offset-lg-4 {
margin-left: 33.333333%;
}
.offset-lg-5 {
margin-left: 41.666667%;
}
.offset-lg-6 {
margin-left: 50%;
}
.offset-lg-7 {
margin-left: 58.333333%;
}
.offset-lg-8 {
margin-left: 66.666667%;
}
.offset-lg-9 {
margin-left: 75%;
}
.offset-lg-10 {
margin-left: 83.333333%;
}
.offset-lg-11 {
margin-left: 91.666667%;
}
}
@media (min-width: 1200px) {
.col-xl-1 {
float: left;
width: 8.333333%;
}
.col-xl-2 {
float: left;
width: 16.666667%;
}
.col-xl-3 {
float: left;
width: 25%;
}
.col-xl-4 {
float: left;
width: 33.333333%;
}
.col-xl-5 {
float: left;
width: 41.666667%;
}
.col-xl-6 {
float: left;
width: 50%;
}
.col-xl-7 {
float: left;
width: 58.333333%;
}
.col-xl-8 {
float: left;
width: 66.666667%;
}
.col-xl-9 {
float: left;
width: 75%;
}
.col-xl-10 {
float: left;
width: 83.333333%;
}
.col-xl-11 {
float: left;
width: 91.666667%;
}
.col-xl-12 {
float: left;
width: 100%;
}
.pull-xl-0 {
right: auto;
}
.pull-xl-1 {
right: 8.333333%;
}
.pull-xl-2 {
right: 16.666667%;
}
.pull-xl-3 {
right: 25%;
}
.pull-xl-4 {
right: 33.333333%;
}
.pull-xl-5 {
right: 41.666667%;
}
.pull-xl-6 {
right: 50%;
}
.pull-xl-7 {
right: 58.333333%;
}
.pull-xl-8 {
right: 66.666667%;
}
.pull-xl-9 {
right: 75%;
}
.pull-xl-10 {
right: 83.333333%;
}
.pull-xl-11 {
right: 91.666667%;
}
.pull-xl-12 {
right: 100%;
}
.push-xl-0 {
left: auto;
}
.push-xl-1 {
left: 8.333333%;
}
.push-xl-2 {
left: 16.666667%;
}
.push-xl-3 {
left: 25%;
}
.push-xl-4 {
left: 33.333333%;
}
.push-xl-5 {
left: 41.666667%;
}
.push-xl-6 {
left: 50%;
}
.push-xl-7 {
left: 58.333333%;
}
.push-xl-8 {
left: 66.666667%;
}
.push-xl-9 {
left: 75%;
}
.push-xl-10 {
left: 83.333333%;
}
.push-xl-11 {
left: 91.666667%;
}
.push-xl-12 {
left: 100%;
}
.offset-xl-0 {
margin-left: 0%;
}
.offset-xl-1 {
margin-left: 8.333333%;
}
.offset-xl-2 {
margin-left: 16.666667%;
}
.offset-xl-3 {
margin-left: 25%;
}
.offset-xl-4 {
margin-left: 33.333333%;
}
.offset-xl-5 {
margin-left: 41.666667%;
}
.offset-xl-6 {
margin-left: 50%;
}
.offset-xl-7 {
margin-left: 58.333333%;
}
.offset-xl-8 {
margin-left: 66.666667%;
}
.offset-xl-9 {
margin-left: 75%;
}
.offset-xl-10 {
margin-left: 83.333333%;
}
.offset-xl-11 {
margin-left: 91.666667%;
}
}
/*# sourceMappingURL=bootstrap-grid.css.map */

1
static/css/bootstrap-grid.css.map

File diff suppressed because one or more lines are too long

2
static/css/bootstrap-grid.min.css

File diff suppressed because one or more lines are too long

1
static/css/bootstrap-grid.min.css.map

File diff suppressed because one or more lines are too long

453
static/css/bootstrap-reboot.css

@ -0,0 +1,453 @@
/*! normalize.css v4.2.0 | MIT License | github.com/necolas/normalize.css */
html {
font-family: sans-serif;
line-height: 1.15;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
main,
menu,
nav,
section,
summary {
display: block;
}
audio,
canvas,
progress,
video {
display: inline-block;
}
audio:not([controls]) {
display: none;
height: 0;
}
progress {
vertical-align: baseline;
}
template,
[hidden] {
display: none;
}
a {
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
a:active,
a:hover {
outline-width: 0;
}
abbr[title] {
border-bottom: none;
text-decoration: underline;
text-decoration: underline dotted;
}
b,
strong {
font-weight: inherit;
}
b,
strong {
font-weight: bolder;
}
dfn {
font-style: italic;
}
h1 {
font-size: 2em;
margin: 0.67em 0;
}
mark {
background-color: #ff0;
color: #000;
}
small {
font-size: 80%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
img {
border-style: none;
}
svg:not(:root) {
overflow: hidden;
}
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
figure {
margin: 1em 40px;
}
hr {
-webkit-box-sizing: content-box;
box-sizing: content-box;
height: 0;
overflow: visible;
}
button,
input,
optgroup,
select,
textarea {
font: inherit;
margin: 0;
}
optgroup {
font-weight: bold;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html [type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
legend {
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: inherit;
display: table;
max-width: 100%;
padding: 0;
white-space: normal;
}
textarea {
overflow: auto;
}
[type="checkbox"],
[type="radio"] {
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-input-placeholder {
color: inherit;
opacity: 0.54;
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
html {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
*,
*::before,
*::after {
-webkit-box-sizing: inherit;
box-sizing: inherit;
}
@-ms-viewport {
width: device-width;
}
html {
font-size: 16px;
-ms-overflow-style: scrollbar;
-webkit-tap-highlight-color: transparent;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 1rem;
line-height: 1.5;
color: #373a3c;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: none !important;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: .5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
cursor: help;
border-bottom: 1px dotted #818a91;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: bold;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
a {
color: #0275d8;
text-decoration: none;
}
a:focus, a:hover {
color: #014c8c;
text-decoration: underline;
}
a:focus {
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: none;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
}
[role="button"] {
cursor: pointer;
}
a,
area,
button,
[role="button"],
input,
label,
select,
summary,
textarea {
-ms-touch-action: manipulation;
touch-action: manipulation;
}
table {
border-collapse: collapse;
background-color: transparent;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #818a91;
text-align: left;
caption-side: bottom;
}
th {
text-align: left;
}
label {
display: inline-block;
margin-bottom: .5rem;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
textarea {
line-height: inherit;
}
input[type="radio"]:disabled,
input[type="checkbox"]:disabled {
cursor: not-allowed;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
}
input[type="search"] {
-webkit-appearance: none;
}
output {
display: inline-block;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

1
static/css/bootstrap-reboot.css.map

File diff suppressed because one or more lines are too long

2
static/css/bootstrap-reboot.min.css

@ -0,0 +1,2 @@
/*! normalize.css v4.2.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}[hidden],template{display:none}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color