├── abb ├── abb │ ├── __init__.py │ ├── static │ │ ├── content.json │ │ ├── favicon.png │ │ ├── images │ │ │ ├── bkg.png │ │ │ └── blacktocat.png │ │ ├── fonts │ │ │ ├── 18f-font.eot │ │ │ ├── 18f-font.ttf │ │ │ ├── 18f-font.woff │ │ │ └── 18f-font.svg │ │ ├── admin │ │ │ ├── img │ │ │ │ ├── icon-no.gif │ │ │ │ ├── nav-bg.gif │ │ │ │ ├── default-bg.gif │ │ │ │ ├── icon-yes.gif │ │ │ │ ├── icon_alert.gif │ │ │ │ ├── icon_clock.gif │ │ │ │ ├── icon_error.gif │ │ │ │ ├── icon-unknown.gif │ │ │ │ ├── icon_addlink.gif │ │ │ │ ├── icon_success.gif │ │ │ │ ├── tooltag-add.png │ │ │ │ ├── changelist-bg.gif │ │ │ │ ├── deleted-overlay.gif │ │ │ │ ├── icon_calendar.gif │ │ │ │ ├── icon_changelink.gif │ │ │ │ ├── icon_deletelink.gif │ │ │ │ ├── icon_searchbox.png │ │ │ │ ├── inline-delete.png │ │ │ │ ├── inline-restore.png │ │ │ │ ├── nav-bg-grabber.gif │ │ │ │ ├── nav-bg-reverse.gif │ │ │ │ ├── nav-bg-selected.gif │ │ │ │ ├── selector-icons.gif │ │ │ │ ├── selector-search.gif │ │ │ │ ├── sorting-icons.gif │ │ │ │ ├── changelist-bg_rtl.gif │ │ │ │ ├── default-bg-reverse.gif │ │ │ │ ├── gis │ │ │ │ │ ├── move_vertex_off.png │ │ │ │ │ └── move_vertex_on.png │ │ │ │ ├── inline-delete-8bit.png │ │ │ │ ├── inline-restore-8bit.png │ │ │ │ ├── inline-splitter-bg.gif │ │ │ │ └── tooltag-arrowright.png │ │ │ ├── js │ │ │ │ ├── jquery.init.js │ │ │ │ ├── prepopulate.min.js │ │ │ │ ├── collapse.min.js │ │ │ │ ├── collapse.js │ │ │ │ ├── LICENSE-JQUERY.txt │ │ │ │ ├── prepopulate.js │ │ │ │ ├── timeparse.js │ │ │ │ ├── actions.min.js │ │ │ │ ├── admin │ │ │ │ │ └── RelatedObjectLookups.js │ │ │ │ ├── inlines.min.js │ │ │ │ ├── SelectBox.js │ │ │ │ ├── actions.js │ │ │ │ ├── urlify.js │ │ │ │ ├── calendar.js │ │ │ │ ├── core.js │ │ │ │ └── SelectFilter2.js │ │ │ └── css │ │ │ │ ├── dashboard.css │ │ │ │ ├── login.css │ │ │ │ ├── ie.css │ │ │ │ ├── rtl.css │ │ │ │ ├── changelists.css │ │ │ │ └── forms.css │ │ ├── styles │ │ │ ├── ie.css │ │ │ ├── fonts.css │ │ │ ├── 18f.min.css │ │ │ └── 18f.css │ │ ├── README.md │ │ ├── LICENSE.md │ │ ├── js │ │ │ ├── slideshow.js │ │ │ └── 18f.js │ │ └── index.html │ ├── urls.py │ ├── wsgi.py │ └── settings.py ├── hours │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0002_auto_20150314_1900.py │ │ └── 0001_initial.py │ ├── static │ │ ├── content.json │ │ ├── favicon.png │ │ ├── images │ │ │ ├── bkg.png │ │ │ └── blacktocat.png │ │ ├── fonts │ │ │ ├── 18f-font.eot │ │ │ ├── 18f-font.ttf │ │ │ ├── 18f-font.woff │ │ │ └── 18f-font.svg │ │ ├── styles │ │ │ ├── ie.css │ │ │ ├── fonts.css │ │ │ ├── 18f.min.css │ │ │ └── 18f.css │ │ ├── README.md │ │ ├── LICENSE.md │ │ ├── js │ │ │ ├── slideshow.js │ │ │ └── 18f.js │ │ └── index.html │ ├── tests.py │ ├── forms.py │ ├── lib │ │ └── load.py │ ├── templates │ │ ├── view_all.html │ │ ├── home.html │ │ ├── success.html │ │ ├── edit.html │ │ └── base.html │ ├── admin.py │ ├── views.py │ ├── models.py │ └── fixtures │ │ ├── projects.csv │ │ └── initial_data.json └── manage.py ├── runtime.txt ├── .cfignore ├── Procfile ├── .gitignore ├── docs └── abb_screenshot.png ├── requirements.txt ├── manifest.yml ├── CONTRIBUTING.md ├── init.sh ├── readme.md ├── convert.sh └── LICENSE.md /abb/abb/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /abb/hours/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.4.1 2 | -------------------------------------------------------------------------------- /abb/hours/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.cfignore: -------------------------------------------------------------------------------- 1 | db.sqlite3 2 | *.pyc 3 | env 4 | .env 5 | local_settings.py 6 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: waitress-serve --port=$VCAP_APP_PORT abb.wsgi:application -------------------------------------------------------------------------------- /abb/abb/static/content.json: -------------------------------------------------------------------------------- 1 | { "name" : "Arwen", "reponame" : "changeme" } 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | db.sqlite3 2 | *.pyc 3 | env 4 | .env 5 | local_settings.py 6 | .DS_Store -------------------------------------------------------------------------------- /abb/hours/static/content.json: -------------------------------------------------------------------------------- 1 | { "name" : "Arwen", "reponame" : "changeme" } 2 | -------------------------------------------------------------------------------- /abb/hours/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /docs/abb_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/docs/abb_screenshot.png -------------------------------------------------------------------------------- /abb/abb/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/favicon.png -------------------------------------------------------------------------------- /abb/abb/static/images/bkg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/images/bkg.png -------------------------------------------------------------------------------- /abb/hours/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/hours/static/favicon.png -------------------------------------------------------------------------------- /abb/hours/static/images/bkg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/hours/static/images/bkg.png -------------------------------------------------------------------------------- /abb/abb/static/fonts/18f-font.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/fonts/18f-font.eot -------------------------------------------------------------------------------- /abb/abb/static/fonts/18f-font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/fonts/18f-font.ttf -------------------------------------------------------------------------------- /abb/abb/static/fonts/18f-font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/fonts/18f-font.woff -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon-no.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon-no.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/nav-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/nav-bg.gif -------------------------------------------------------------------------------- /abb/abb/static/images/blacktocat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/images/blacktocat.png -------------------------------------------------------------------------------- /abb/hours/static/fonts/18f-font.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/hours/static/fonts/18f-font.eot -------------------------------------------------------------------------------- /abb/hours/static/fonts/18f-font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/hours/static/fonts/18f-font.ttf -------------------------------------------------------------------------------- /abb/hours/static/fonts/18f-font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/hours/static/fonts/18f-font.woff -------------------------------------------------------------------------------- /abb/abb/static/admin/img/default-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/default-bg.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon-yes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon-yes.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon_alert.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon_alert.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon_clock.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon_clock.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon_error.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon_error.gif -------------------------------------------------------------------------------- /abb/hours/static/images/blacktocat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/hours/static/images/blacktocat.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | dj-database-url==0.3.0 2 | Django==1.7.6 3 | psycopg2==2.6 4 | waitress==0.8.9 5 | whitenoise==1.0.6 6 | -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon-unknown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon-unknown.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon_addlink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon_addlink.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon_success.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon_success.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/tooltag-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/tooltag-add.png -------------------------------------------------------------------------------- /abb/abb/static/admin/img/changelist-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/changelist-bg.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/deleted-overlay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/deleted-overlay.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon_calendar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon_calendar.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon_changelink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon_changelink.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon_deletelink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon_deletelink.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/icon_searchbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/icon_searchbox.png -------------------------------------------------------------------------------- /abb/abb/static/admin/img/inline-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/inline-delete.png -------------------------------------------------------------------------------- /abb/abb/static/admin/img/inline-restore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/inline-restore.png -------------------------------------------------------------------------------- /abb/abb/static/admin/img/nav-bg-grabber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/nav-bg-grabber.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/nav-bg-reverse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/nav-bg-reverse.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/nav-bg-selected.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/nav-bg-selected.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/selector-icons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/selector-icons.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/selector-search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/selector-search.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/sorting-icons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/sorting-icons.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/changelist-bg_rtl.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/changelist-bg_rtl.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/default-bg-reverse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/default-bg-reverse.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/gis/move_vertex_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/gis/move_vertex_off.png -------------------------------------------------------------------------------- /abb/abb/static/admin/img/gis/move_vertex_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/gis/move_vertex_on.png -------------------------------------------------------------------------------- /abb/abb/static/admin/img/inline-delete-8bit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/inline-delete-8bit.png -------------------------------------------------------------------------------- /abb/abb/static/admin/img/inline-restore-8bit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/inline-restore-8bit.png -------------------------------------------------------------------------------- /abb/abb/static/admin/img/inline-splitter-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/inline-splitter-bg.gif -------------------------------------------------------------------------------- /abb/abb/static/admin/img/tooltag-arrowright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/abb/master/abb/abb/static/admin/img/tooltag-arrowright.png -------------------------------------------------------------------------------- /manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # all applications use these settings and services 3 | memory: 512M 4 | instances: 1 5 | applications: 6 | - name: abb 7 | path: . 8 | timeout: 180 -------------------------------------------------------------------------------- /abb/hours/forms.py: -------------------------------------------------------------------------------- 1 | from django.forms import ModelForm 2 | from hours.models import Record, Timesheet 3 | 4 | class TimesheetForm(ModelForm): 5 | class Meta: 6 | model = Timesheet 7 | fields = ['reporting_period','records'] -------------------------------------------------------------------------------- /abb/hours/lib/load.py: -------------------------------------------------------------------------------- 1 | from models import Project 2 | import csv 3 | with open('hours/fixtures/projects.csv','r') as f: 4 | projects = csv.reader(f) 5 | for project in projects: 6 | p = Project(name=project[0], billable=project[1]).save() -------------------------------------------------------------------------------- /abb/hours/templates/view_all.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block content %} 3 |

Always Be Billin'

4 | {% for timesheet in timesheets %} 5 | {{timesheet.reporting_period}} 6 | {% endfor %} 7 | {% endblock %} -------------------------------------------------------------------------------- /abb/abb/static/styles/ie.css: -------------------------------------------------------------------------------- 1 | .jumbotron { 2 | padding-top: 0 !important; 3 | padding-bottom: 0 !important; 4 | } 5 | .mantra { 6 | background-image: url(../images/lightbulb-100.png); 7 | } 8 | .jumbotron .container-fluid { 9 | background: url(../images/tagline-bg.png) 0 0 repeat; 10 | } -------------------------------------------------------------------------------- /abb/hours/static/styles/ie.css: -------------------------------------------------------------------------------- 1 | .jumbotron { 2 | padding-top: 0 !important; 3 | padding-bottom: 0 !important; 4 | } 5 | .mantra { 6 | background-image: url(../images/lightbulb-100.png); 7 | } 8 | .jumbotron .container-fluid { 9 | background: url(../images/tagline-bg.png) 0 0 repeat; 10 | } -------------------------------------------------------------------------------- /abb/hours/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block content %} 3 |

Always Be Billin'

4 | 5 | 6 | {% endblock %} -------------------------------------------------------------------------------- /abb/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "abb.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /abb/abb/static/admin/js/jquery.init.js: -------------------------------------------------------------------------------- 1 | /* Puts the included jQuery into our own namespace using noConflict and passing 2 | * it 'true'. This ensures that the included jQuery doesn't pollute the global 3 | * namespace (i.e. this preserves pre-existing values for both window.$ and 4 | * window.jQuery). 5 | */ 6 | var django = django || {}; 7 | django.jQuery = jQuery.noConflict(true); 8 | -------------------------------------------------------------------------------- /abb/abb/static/admin/js/prepopulate.min.js: -------------------------------------------------------------------------------- 1 | (function(b){b.fn.prepopulate=function(e,g){return this.each(function(){var a=b(this),d=function(){if(!a.data("_changed")){var f=[];b.each(e,function(h,c){c=b(c);c.val().length>0&&f.push(c.val())});a.val(URLify(f.join(" "),g))}};a.data("_changed",false);a.change(function(){a.data("_changed",true)});a.val()||b(e.join(",")).keyup(d).change(d).focus(d)})}})(django.jQuery); 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Public domain 2 | 3 | This project is in the public domain within the United States, and 4 | copyright and related rights in the work worldwide are waived through 5 | the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/). 6 | 7 | All contributions to this project will be released under the CC0 8 | dedication. By submitting a pull request, you are agreeing to comply 9 | with this waiver of copyright interest. -------------------------------------------------------------------------------- /abb/hours/templates/success.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | Hello World 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "------ Create database tables ------" 3 | python abb/manage.py migrate --noinput 4 | 5 | echo "------ create default admin user ------" 6 | echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', '', 'changeme')" | python abb/manage.py shell 7 | 8 | echo "------- load data ------" 9 | python abb/manage.py loaddata hours/fixtures/initial_data.json 10 | 11 | echo "------ starting django  ------" 12 | cd abb && waitress-serve --port=$VCAP_APP_PORT abb.wsgi:application -------------------------------------------------------------------------------- /abb/hours/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | from hours.models import Project, Record, ReportingPeriod, Timesheet 5 | 6 | @admin.register(Project) 7 | class ProjectAdmin(admin.ModelAdmin): 8 | pass 9 | 10 | @admin.register(Timesheet) 11 | class TimesheetAdmin(admin.ModelAdmin): 12 | pass 13 | 14 | @admin.register(Record) 15 | class RecordAdmin(admin.ModelAdmin): 16 | pass 17 | 18 | @admin.register(ReportingPeriod) 19 | class ReportingPeriodAdmin(admin.ModelAdmin): 20 | pass -------------------------------------------------------------------------------- /abb/abb/static/admin/css/dashboard.css: -------------------------------------------------------------------------------- 1 | /* DASHBOARD */ 2 | 3 | .dashboard .module table th { 4 | width: 100%; 5 | } 6 | 7 | .dashboard .module table td { 8 | white-space: nowrap; 9 | } 10 | 11 | .dashboard .module table td a { 12 | display: block; 13 | padding-right: .6em; 14 | } 15 | 16 | /* RECENT ACTIONS MODULE */ 17 | 18 | .module ul.actionlist { 19 | margin-left: 0; 20 | } 21 | 22 | ul.actionlist li { 23 | list-style-type: none; 24 | } 25 | 26 | ul.actionlist li { 27 | overflow: hidden; 28 | text-overflow: ellipsis; 29 | -o-text-overflow: ellipsis; 30 | } 31 | -------------------------------------------------------------------------------- /abb/abb/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, include, url 2 | from django.contrib import admin 3 | from django.conf import settings 4 | from django.conf.urls.static import static 5 | 6 | urlpatterns = patterns('', 7 | # Examples: 8 | # url(r'^$', 'abb.views.home', name='home'), 9 | # url(r'^blog/', include('blog.urls')), 10 | url(r'^$', 'hours.views.home', name='home'), 11 | url(r'^admin/', include(admin.site.urls)), 12 | url(r'^timesheets','hours.views.view_all',name='view_all'), 13 | url(r'^timesheet/create$', 'hours.views.new_timesheet', name='new_timesheet') 14 | ) -------------------------------------------------------------------------------- /abb/abb/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for abb project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | from django.core.wsgi import get_wsgi_application 12 | 13 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "abb.settings") 14 | # important that the whitenoise import is after the line above 15 | from whitenoise.django import DjangoWhiteNoise 16 | 17 | application = get_wsgi_application() 18 | application = DjangoWhiteNoise(application) -------------------------------------------------------------------------------- /abb/abb/static/admin/js/collapse.min.js: -------------------------------------------------------------------------------- 1 | (function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){a(b).find("div.errors").length==0&&a(b).addClass("collapsed").find("h2").first().append(' ('+gettext("Show")+")")});a("fieldset.collapse a.collapse-toggle").click(function(){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", 2 | [a(this).attr("id")]);return false})})})(django.jQuery); 3 | -------------------------------------------------------------------------------- /abb/abb/static/admin/js/collapse.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $(document).ready(function() { 3 | // Add anchor tag for Show/Hide link 4 | $("fieldset.collapse").each(function(i, elem) { 5 | // Don't hide if fields in this fieldset have errors 6 | if ($(elem).find("div.errors").length == 0) { 7 | $(elem).addClass("collapsed").find("h2").first().append(' (' + gettext("Show") + 9 | ')'); 10 | } 11 | }); 12 | // Add toggle to anchor tag 13 | $("fieldset.collapse a.collapse-toggle").click(function(ev) { 14 | if ($(this).closest("fieldset").hasClass("collapsed")) { 15 | // Show 16 | $(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]); 17 | } else { 18 | // Hide 19 | $(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]); 20 | } 21 | return false; 22 | }); 23 | }); 24 | })(django.jQuery); 25 | -------------------------------------------------------------------------------- /abb/abb/static/README.md: -------------------------------------------------------------------------------- 1 | # Create an 18F-branded microsite by forking this site. 2 | 3 | Basic instructions: 4 | * Fork this site. 5 | * Rename it. 6 | * Add specific content, especially to index.html. 7 | * Change this README.md! 8 | 9 | This repo is meant to cloned. This micro-site template is used to 10 | automatically create new microsites which can be easily customized. 11 | If you are the owner if this README, you have probably already cloned 12 | it and should replace it with something far more specific. 13 | 14 | ### Public domain 15 | 16 | This project is in the worldwide [public domain](LICENSE.md). As stated in [CONTRIBUTING](CONTRIBUTING.md): 17 | 18 | > This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/). 19 | > 20 | > All contributions to this project will be released under the CC0 21 | >dedication. By submitting a pull request, you are agreeing to comply 22 | >with this waiver of copyright interest. 23 | -------------------------------------------------------------------------------- /abb/hours/static/README.md: -------------------------------------------------------------------------------- 1 | # Create an 18F-branded microsite by forking this site. 2 | 3 | Basic instructions: 4 | * Fork this site. 5 | * Rename it. 6 | * Add specific content, especially to index.html. 7 | * Change this README.md! 8 | 9 | This repo is meant to cloned. This micro-site template is used to 10 | automatically create new microsites which can be easily customized. 11 | If you are the owner if this README, you have probably already cloned 12 | it and should replace it with something far more specific. 13 | 14 | ### Public domain 15 | 16 | This project is in the worldwide [public domain](LICENSE.md). As stated in [CONTRIBUTING](CONTRIBUTING.md): 17 | 18 | > This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/). 19 | > 20 | > All contributions to this project will be released under the CC0 21 | >dedication. By submitting a pull request, you are agreeing to comply 22 | >with this waiver of copyright interest. 23 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Always Be Billin' 2 | 3 | WIP. 4 | 5 | [18F](https://18f.gsa.gov) is a great place to work because of its non-governmenty business model. The best feature this model is the ability to charge our clients fees that cover not just the direct work we provide, but also the overhead activities that make our team better every day, like Guilds, Workgroups, Hub, and 20% time projects. 6 | 7 | To ensure we can sustain this model (as well as export it to other digital service teams!), it is critical that we accurately report what we worked on each week. This allows for each of our clients to pay their fair share and for 18F to properly manage its human resources (also known as people). 8 | 9 | Since June 2014, we have addressed this need by recording weekly activities in a Google Sheet. With 110+ employees and 25+ projects, this system is getting a bit unwieldy. For the next iteration, 18F is putting together an easy-to-use Django application. This will (hopefully) help recording your weekly activities easier, as well as make data extraction and analysis more painless. 10 | 11 | Here's a screenshot: 12 | 13 | ![](docs/abb_screenshot.png) 14 | -------------------------------------------------------------------------------- /abb/hours/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, render_to_response,redirect 2 | from django.views.decorators.csrf import csrf_protect 3 | # Create your views here. 4 | 5 | from hours.models import Record, Project, Timesheet, ReportingPeriod 6 | 7 | def home (request): 8 | return render(request, "home.html") 9 | 10 | def view_all (request): 11 | timesheets = Timesheet.objects.all().filter(employee=request.user) 12 | return render(request, "view_all.html", {"timesheets":timesheets}) 13 | 14 | @csrf_protect 15 | def new_timesheet (request): 16 | projects = Project.objects.all() 17 | weeks = ReportingPeriod.objects.last() 18 | if request.method == "POST": 19 | form = request.POST 20 | period = ReportingPeriod.objects.get(pk=form["week"]) 21 | t = Timesheet(employee=request.user, reporting_period=period) 22 | t.save() 23 | t.records = [] 24 | f = dict(form.lists()) 25 | for pr in f["project"]: 26 | r = Record(project=Project.objects.get(pk=pr), hours=f["percentage"].pop(0)) 27 | print(r) 28 | r.save() 29 | t.records.add(r) 30 | t.save() 31 | return redirect ("/") 32 | return render (request, 'edit.html', {"projects":projects, "weeks":weeks}) -------------------------------------------------------------------------------- /abb/abb/static/admin/js/LICENSE-JQUERY.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 John Resig, http://jquery.com/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /abb/abb/static/admin/css/login.css: -------------------------------------------------------------------------------- 1 | /* LOGIN FORM */ 2 | 3 | body.login { 4 | background: #eee; 5 | } 6 | 7 | .login #container { 8 | background: white; 9 | border: 1px solid #ccc; 10 | width: 28em; 11 | min-width: 300px; 12 | margin-left: auto; 13 | margin-right: auto; 14 | margin-top: 100px; 15 | } 16 | 17 | .login #content-main { 18 | width: 100%; 19 | } 20 | 21 | .login form { 22 | margin-top: 1em; 23 | } 24 | 25 | .login .form-row { 26 | padding: 4px 0; 27 | float: left; 28 | width: 100%; 29 | } 30 | 31 | .login .form-row label { 32 | padding-right: 0.5em; 33 | line-height: 2em; 34 | font-size: 1em; 35 | clear: both; 36 | color: #333; 37 | } 38 | 39 | .login .form-row #id_username, .login .form-row #id_password { 40 | clear: both; 41 | padding: 6px; 42 | width: 100%; 43 | -webkit-box-sizing: border-box; 44 | -moz-box-sizing: border-box; 45 | box-sizing: border-box; 46 | } 47 | 48 | .login span.help { 49 | font-size: 10px; 50 | display: block; 51 | } 52 | 53 | .login .submit-row { 54 | clear: both; 55 | padding: 1em 0 0 9.4em; 56 | } 57 | 58 | .login .password-reset-link { 59 | text-align: center; 60 | } 61 | -------------------------------------------------------------------------------- /abb/hours/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | from django.contrib.auth.models import User 5 | 6 | # Create your models here. 7 | 8 | class ReportingPeriod (models.Model): 9 | date_from = models.DateField() 10 | date_to = models.DateField() 11 | 12 | def __str__(self): 13 | return self.date_from.strftime("%m/%d/%y") + " -- " + self.date_to.strftime("%m/%d/%y") 14 | 15 | class Project (models.Model): 16 | name = models.CharField(max_length=200, blank=False, null=False) 17 | billable = models.BooleanField(default=True) 18 | description = models.TextField(blank=True, null=False) 19 | 20 | def __str__(self): 21 | return self.name 22 | 23 | class Record (models.Model): 24 | project = models.ForeignKey(Project) 25 | hours = models.IntegerField() 26 | 27 | def __str__(self): 28 | return self.project.name + " (" + str(self.hours) + ")" 29 | 30 | class Timesheet (models.Model): 31 | employee = models.ForeignKey(User, blank=True, null=True) 32 | reporting_period = models.ForeignKey(ReportingPeriod) 33 | created = models.DateTimeField(auto_now_add=True) 34 | modified = models.DateTimeField(auto_now=True) 35 | records = models.ManyToManyField(Record) 36 | 37 | def get_absolute_url(self): 38 | return "timesheet/" + str(self.id) -------------------------------------------------------------------------------- /abb/abb/static/admin/css/ie.css: -------------------------------------------------------------------------------- 1 | /* IE 6 & 7 */ 2 | 3 | /* Proper fixed width for dashboard in IE6 */ 4 | 5 | .dashboard #content { 6 | *width: 768px; 7 | } 8 | 9 | .dashboard #content-main { 10 | *width: 535px; 11 | } 12 | 13 | /* IE 6 ONLY */ 14 | 15 | /* Keep header from flowing off the page */ 16 | 17 | #container { 18 | _position: static; 19 | } 20 | 21 | /* Put the right sidebars back on the page */ 22 | 23 | .colMS #content-related { 24 | _margin-right: 0; 25 | _margin-left: 10px; 26 | _position: static; 27 | } 28 | 29 | /* Put the left sidebars back on the page */ 30 | 31 | .colSM #content-related { 32 | _margin-right: 10px; 33 | _margin-left: -115px; 34 | _position: static; 35 | } 36 | 37 | .form-row { 38 | _height: 1%; 39 | } 40 | 41 | /* Fix right margin for changelist filters in IE6 */ 42 | 43 | #changelist-filter ul { 44 | _margin-right: -10px; 45 | } 46 | 47 | /* IE ignores min-height, but treats height as if it were min-height */ 48 | 49 | .change-list .filtered { 50 | _height: 400px; 51 | } 52 | 53 | /* IE doesn't know alpha transparency in PNGs */ 54 | 55 | .inline-deletelink { 56 | background: transparent url(../img/inline-delete-8bit.png) no-repeat; 57 | } 58 | 59 | /* IE7 doesn't support inline-block */ 60 | .change-list ul.toplinks li { 61 | zoom: 1; 62 | *display: inline; 63 | } -------------------------------------------------------------------------------- /abb/hours/fixtures/projects.csv: -------------------------------------------------------------------------------- 1 | name,billable 2 | Out of Office,False 3 | 18F General,False 4 | PIF Program,False 5 | 18F Admin/Ops,False 6 | 18F Recruiting/Interviewing,False 7 | Ops/Acquisitions,False 8 | Ops/Legal,False 9 | Ops/Budget & Finance ,False 10 | Ops/Project Luca,False 11 | Outreach/18F Site,False 12 | "Outreach/Communications (blogs, messaging, etc)",False 13 | Outreach/Events,False 14 | Guilds,False 15 | Workgroups,False 16 | API.Data.gov,False 17 | /Developer Program,False 18 | MyUSA,True 19 | FOIA Modernization,True 20 | openFEC,True 21 | 18F’s Open Source Policy,False 22 | Air Force Small Biz,True 23 | USCIS,True 24 | Midas,True 25 | FBOpen,False 26 | CAP Communicart,True 27 | Peace Corps,True 28 | Consulting Services,False 29 | Income Verification Pilot,True 30 | Web Maker / NotAlone.gov,True 31 | Web Maker / myRA,True 32 | Web Maker / EITI,True 33 | OASIS,True 34 | 18F Dashboard,False 35 | GSA CIO Support,False 36 | Consulting / DOL WHD,True 37 | Consulting / GSA OHRM,True 38 | Consulting / SSA DCPS,True 39 | Consulting / DATA Act,True 40 | Consulting / Navy Reserve - R2S,True 41 | GSA - FICAM,True 42 | Trusted Internet Connection 3.0,False 43 | Platform as a Service,False 44 | Climate Project,False 45 | Digital Analytics Program,False 46 | Agile Corps,False 47 | Dogfood,False 48 | R2H,False 49 | Seeds,False 50 | Consulting - Agile BPA,False 51 | Developer Program - CMS,True -------------------------------------------------------------------------------- /abb/abb/static/LICENSE.md: -------------------------------------------------------------------------------- 1 | As a work of the United States Government, this project is in the 2 | public domain within the United States. 3 | 4 | Additionally, we waive copyright and related rights in the work 5 | worldwide through the CC0 1.0 Universal public domain dedication. 6 | 7 | ## CC0 1.0 Universal Summary 8 | 9 | This is a human-readable summary of the 10 | [Legal Code (read the full text)](https://creativecommons.org/publicdomain/zero/1.0/legalcode). 11 | 12 | ### No Copyright 13 | 14 | The person who associated a work with this deed has dedicated the work to 15 | the public domain by waiving all of his or her rights to the work worldwide 16 | under copyright law, including all related and neighboring rights, to the 17 | extent allowed by law. 18 | 19 | You can copy, modify, distribute and perform the work, even for commercial 20 | purposes, all without asking permission. 21 | 22 | ### Other Information 23 | 24 | In no way are the patent or trademark rights of any person affected by CC0, 25 | nor are the rights that other persons may have in the work or in how the 26 | work is used, such as publicity or privacy rights. 27 | 28 | Unless expressly stated otherwise, the person who associated a work with 29 | this deed makes no warranties about the work, and disclaims liability for 30 | all uses of the work, to the fullest extent permitted by applicable law. 31 | When using or citing the work, you should not imply endorsement by the 32 | author or the affirmer. 33 | -------------------------------------------------------------------------------- /abb/hours/static/LICENSE.md: -------------------------------------------------------------------------------- 1 | As a work of the United States Government, this project is in the 2 | public domain within the United States. 3 | 4 | Additionally, we waive copyright and related rights in the work 5 | worldwide through the CC0 1.0 Universal public domain dedication. 6 | 7 | ## CC0 1.0 Universal Summary 8 | 9 | This is a human-readable summary of the 10 | [Legal Code (read the full text)](https://creativecommons.org/publicdomain/zero/1.0/legalcode). 11 | 12 | ### No Copyright 13 | 14 | The person who associated a work with this deed has dedicated the work to 15 | the public domain by waiving all of his or her rights to the work worldwide 16 | under copyright law, including all related and neighboring rights, to the 17 | extent allowed by law. 18 | 19 | You can copy, modify, distribute and perform the work, even for commercial 20 | purposes, all without asking permission. 21 | 22 | ### Other Information 23 | 24 | In no way are the patent or trademark rights of any person affected by CC0, 25 | nor are the rights that other persons may have in the work or in how the 26 | work is used, such as publicity or privacy rights. 27 | 28 | Unless expressly stated otherwise, the person who associated a work with 29 | this deed makes no warranties about the work, and disclaims liability for 30 | all uses of the work, to the fullest extent permitted by applicable law. 31 | When using or citing the work, you should not imply endorsement by the 32 | author or the affirmer. 33 | -------------------------------------------------------------------------------- /convert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # CSV to JSON converter using BASH 3 | # Usage ./csv2json input.csv > output.json 4 | 5 | input=$1 6 | 7 | [ -z $1 ] && echo "No CSV input file specified" && exit 1 8 | [ ! -e $input ] && echo "Unable to locate $1" && exit 1 9 | 10 | read first_line < $input 11 | a=0 12 | headings=`echo $first_line | awk -F, {'print NF'}` 13 | lines=`cat $input | wc -l` 14 | while [ $a -lt $headings ] 15 | do 16 | head_array[$a]=$(echo $first_line | awk -v x=$(($a + 1)) -F"," '{print $x}') 17 | a=$(($a+1)) 18 | done 19 | 20 | c=0 21 | echo "{" 22 | while [ $c -lt $lines ] 23 | do 24 | read each_line 25 | if [ $c -ne 0 ]; then 26 | d=0 27 | echo -n "{" 28 | while [ $d -lt $headings ] 29 | do 30 | each_element=$(echo $each_line | awk -v y=$(($d + 1)) -F"," '{print $y}') 31 | if [ $d -ne $(($headings-1)) ]; then 32 | echo -n ${head_array[$d]}":"$each_element"," 33 | else 34 | echo -n ${head_array[$d]}":"$each_element 35 | fi 36 | d=$(($d+1)) 37 | done 38 | if [ $c -eq $(($lines-1)) ]; then 39 | echo "}" 40 | else 41 | echo "}," 42 | fi 43 | fi 44 | c=$(($c+1)) 45 | done < $input 46 | echo "}" 47 | -------------------------------------------------------------------------------- /abb/abb/static/admin/js/prepopulate.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $.fn.prepopulate = function(dependencies, maxLength) { 3 | /* 4 | Depends on urlify.js 5 | Populates a selected field with the values of the dependent fields, 6 | URLifies and shortens the string. 7 | dependencies - array of dependent fields ids 8 | maxLength - maximum length of the URLify'd string 9 | */ 10 | return this.each(function() { 11 | var prepopulatedField = $(this); 12 | 13 | var populate = function () { 14 | // Bail if the field's value has been changed by the user 15 | if (prepopulatedField.data('_changed')) { 16 | return; 17 | } 18 | 19 | var values = []; 20 | $.each(dependencies, function(i, field) { 21 | field = $(field); 22 | if (field.val().length > 0) { 23 | values.push(field.val()); 24 | } 25 | }); 26 | prepopulatedField.val(URLify(values.join(' '), maxLength)); 27 | }; 28 | 29 | prepopulatedField.data('_changed', false); 30 | prepopulatedField.change(function() { 31 | prepopulatedField.data('_changed', true); 32 | }); 33 | 34 | if (!prepopulatedField.val()) { 35 | $(dependencies.join(',')).keyup(populate).change(populate).focus(populate); 36 | } 37 | }); 38 | }; 39 | })(django.jQuery); 40 | -------------------------------------------------------------------------------- /abb/hours/migrations/0002_auto_20150314_1900.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | from django.conf import settings 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('hours', '0001_initial'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='Timesheet', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, serialize=False, primary_key=True, verbose_name='ID')), 20 | ('created', models.DateTimeField(auto_now_add=True)), 21 | ('modified', models.DateTimeField(auto_now=True)), 22 | ('employee', models.ForeignKey(to=settings.AUTH_USER_MODEL, blank=True, null=True)), 23 | ('records', models.ManyToManyField(to='hours.Record')), 24 | ('reporting_period', models.ForeignKey(to='hours.ReportingPeriod')), 25 | ], 26 | options={ 27 | }, 28 | bases=(models.Model,), 29 | ), 30 | migrations.RemoveField( 31 | model_name='record', 32 | name='created', 33 | ), 34 | migrations.RemoveField( 35 | model_name='record', 36 | name='employee', 37 | ), 38 | migrations.RemoveField( 39 | model_name='record', 40 | name='modified', 41 | ), 42 | migrations.RemoveField( 43 | model_name='record', 44 | name='reporting_period', 45 | ), 46 | ] 47 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | As a work of the United States Government, this project is in the 2 | public domain within the United States. 3 | 4 | Additionally, we waive copyright and related rights in the work 5 | worldwide through the CC0 1.0 Universal public domain dedication. 6 | 7 | ## CC0 1.0 Universal Summary 8 | 9 | This is a human-readable summary of the 10 | [Legal Code (read the full text)](https://creativecommons.org/publicdomain/zero/1.0/legalcode). 11 | 12 | ### No Copyright 13 | 14 | The person who associated a work with this deed has dedicated the work to 15 | the public domain by waiving all of his or her rights to the work worldwide 16 | under copyright law, including all related and neighboring rights, to the 17 | extent allowed by law. 18 | 19 | You can copy, modify, distribute and perform the work, even for commercial 20 | purposes, all without asking permission. 21 | 22 | ### Other Information 23 | 24 | In no way are the patent or trademark rights of any person affected by CC0, 25 | nor are the rights that other persons may have in the work or in how the 26 | work is used, such as publicity or privacy rights. 27 | 28 | Unless expressly stated otherwise, the person who associated a work with 29 | this deed makes no warranties about the work, and disclaims liability for 30 | all uses of the work, to the fullest extent permitted by applicable law. 31 | When using or citing the work, you should not imply endorsement by the 32 | author or the affirmer. 33 | 34 | ## Exceptions 35 | - [jQuery](http://jquery.com/) and [Sizzle](http://sizzlejs.com/) by The jQuery 36 | Foundation are licensed under the MIT License. 37 | - [kss-node] (https://github.com/kss-node/kss-node) are licensed under the MIT 38 | License. -------------------------------------------------------------------------------- /abb/hours/templates/edit.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} {% block content %} 2 |

Always Be Billin'

3 |
4 | {% csrf_token %} 5 |
6 | Week 7 |
8 | 9 | {{weeks}}
10 |
11 |
12 | Projects 13 |
14 |
15 |
16 |
17 | 22 |
23 |
24 |
25 |
26 | 27 |
28 |
29 |
30 |
31 |
32 |
33 | 34 |
35 |
36 | Submit 37 |
38 | 39 |
40 |
41 |
42 | 43 | {% endblock %} {% block extra_js %} 44 | 53 | {% endblock %} 54 | -------------------------------------------------------------------------------- /abb/abb/static/js/slideshow.js: -------------------------------------------------------------------------------- 1 | var Slideshow = (function($){ 2 | var TIMER = ''; 3 | var TIMEOUT = 10000; 4 | var TRANSITION_TIME = 400; 5 | 6 | var _$slideshow = $('#slideshow'); 7 | var _$wrapper = $('.slideshow-wrapper'); 8 | var _$photo_credit = $('.photo-credit'); 9 | var _$deck = _$slideshow.find('.slide'); 10 | 11 | var _findSlideIndex = function (slide) { 12 | var i = 0; 13 | var _$slide = slide; 14 | for (var i = 0; i < _$deck.length-1; i++) { 15 | var _$existing_slide = $(_$deck[i]); 16 | if (_$slide.attr('style') == _$existing_slide.attr('style')) { 17 | return i; 18 | } 19 | } 20 | } 21 | 22 | var init = function () { 23 | var num = Math.floor((Math.random()*_$deck.length)+1); // get random slide 24 | display(num); 25 | TIMER = setTimeout('Slideshow.cycle();',TIMEOUT); 26 | }; 27 | 28 | var display = function (num) { 29 | $('.slideshow-wrapper > .slide').addClass('fadeOut'); 30 | var _$slide = $(_$deck[num-1]).clone(); 31 | var caption = ' ' + _$slide.data('caption') + ''; 32 | _$wrapper.append(_$slide); 33 | $('.slideshow-wrapper .fadeOut').fadeOut(TRANSITION_TIME,function () { 34 | $(this).remove(); 35 | }); 36 | 37 | _$wrapper.children('.slide').show(); 38 | _$photo_credit.html(caption).show(); 39 | }; 40 | 41 | var cycle = function () { 42 | var cur_slide = _$wrapper.children('.slide'); 43 | var cur_index = _findSlideIndex(cur_slide); 44 | var new_index = 0; 45 | 46 | if (cur_index < _$deck.length) { 47 | new_index = cur_index+2; 48 | } else { 49 | new_index = 1; // start over at beginning 50 | } 51 | display(new_index); 52 | clearTimeout(TIMER); 53 | TIMER = setTimeout('Slideshow.cycle();',TIMEOUT); 54 | }; 55 | 56 | var checkArrow = function (e) { 57 | e = e || window.event; 58 | 59 | if (e.keyCode == '39') { 60 | cycle(); 61 | } 62 | } 63 | 64 | return { 65 | init : init, 66 | cycle : cycle, 67 | checkArrow : checkArrow 68 | }; 69 | 70 | })(jQuery); 71 | 72 | Slideshow.init(); 73 | 74 | document.onkeydown = Slideshow.checkArrow; 75 | 76 | -------------------------------------------------------------------------------- /abb/hours/static/js/slideshow.js: -------------------------------------------------------------------------------- 1 | var Slideshow = (function($){ 2 | var TIMER = ''; 3 | var TIMEOUT = 10000; 4 | var TRANSITION_TIME = 400; 5 | 6 | var _$slideshow = $('#slideshow'); 7 | var _$wrapper = $('.slideshow-wrapper'); 8 | var _$photo_credit = $('.photo-credit'); 9 | var _$deck = _$slideshow.find('.slide'); 10 | 11 | var _findSlideIndex = function (slide) { 12 | var i = 0; 13 | var _$slide = slide; 14 | for (var i = 0; i < _$deck.length-1; i++) { 15 | var _$existing_slide = $(_$deck[i]); 16 | if (_$slide.attr('style') == _$existing_slide.attr('style')) { 17 | return i; 18 | } 19 | } 20 | } 21 | 22 | var init = function () { 23 | var num = Math.floor((Math.random()*_$deck.length)+1); // get random slide 24 | display(num); 25 | TIMER = setTimeout('Slideshow.cycle();',TIMEOUT); 26 | }; 27 | 28 | var display = function (num) { 29 | $('.slideshow-wrapper > .slide').addClass('fadeOut'); 30 | var _$slide = $(_$deck[num-1]).clone(); 31 | var caption = ' ' + _$slide.data('caption') + ''; 32 | _$wrapper.append(_$slide); 33 | $('.slideshow-wrapper .fadeOut').fadeOut(TRANSITION_TIME,function () { 34 | $(this).remove(); 35 | }); 36 | 37 | _$wrapper.children('.slide').show(); 38 | _$photo_credit.html(caption).show(); 39 | }; 40 | 41 | var cycle = function () { 42 | var cur_slide = _$wrapper.children('.slide'); 43 | var cur_index = _findSlideIndex(cur_slide); 44 | var new_index = 0; 45 | 46 | if (cur_index < _$deck.length) { 47 | new_index = cur_index+2; 48 | } else { 49 | new_index = 1; // start over at beginning 50 | } 51 | display(new_index); 52 | clearTimeout(TIMER); 53 | TIMER = setTimeout('Slideshow.cycle();',TIMEOUT); 54 | }; 55 | 56 | var checkArrow = function (e) { 57 | e = e || window.event; 58 | 59 | if (e.keyCode == '39') { 60 | cycle(); 61 | } 62 | } 63 | 64 | return { 65 | init : init, 66 | cycle : cycle, 67 | checkArrow : checkArrow 68 | }; 69 | 70 | })(jQuery); 71 | 72 | Slideshow.init(); 73 | 74 | document.onkeydown = Slideshow.checkArrow; 75 | 76 | -------------------------------------------------------------------------------- /abb/hours/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | from django.conf import settings 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='Project', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), 19 | ('name', models.CharField(max_length=200)), 20 | ('billable', models.BooleanField(default=True)), 21 | ('description', models.TextField(blank=True)), 22 | ], 23 | options={ 24 | }, 25 | bases=(models.Model,), 26 | ), 27 | migrations.CreateModel( 28 | name='Record', 29 | fields=[ 30 | ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), 31 | ('hours', models.IntegerField()), 32 | ('created', models.DateTimeField(auto_now_add=True)), 33 | ('modified', models.DateTimeField(auto_now=True)), 34 | ('employee', models.ForeignKey(null=True, to=settings.AUTH_USER_MODEL, blank=True)), 35 | ('project', models.ForeignKey(to='hours.Project')), 36 | ], 37 | options={ 38 | }, 39 | bases=(models.Model,), 40 | ), 41 | migrations.CreateModel( 42 | name='ReportingPeriod', 43 | fields=[ 44 | ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), 45 | ('date_from', models.DateField()), 46 | ('date_to', models.DateField()), 47 | ], 48 | options={ 49 | }, 50 | bases=(models.Model,), 51 | ), 52 | migrations.AddField( 53 | model_name='record', 54 | name='reporting_period', 55 | field=models.ForeignKey(to='hours.ReportingPeriod'), 56 | preserve_default=True, 57 | ), 58 | ] 59 | -------------------------------------------------------------------------------- /abb/abb/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for abb project. 3 | 4 | For more information on this file, see 5 | https://docs.djangoproject.com/en/1.7/topics/settings/ 6 | 7 | For the full list of settings and their values, see 8 | https://docs.djangoproject.com/en/1.7/ref/settings/ 9 | """ 10 | 11 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 12 | import os 13 | BASE_DIR = os.path.dirname(os.path.dirname(__file__)) 14 | 15 | 16 | # Quick-start development settings - unsuitable for production 17 | # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ 18 | 19 | # SECURITY WARNING: keep the secret key used in production secret! 20 | SECRET_KEY = '#l-9%c0$9!!b0aq_9g6lq+s8-l&4z2jslba!+fu5a$git89kfc' 21 | 22 | # SECURITY WARNING: don't run with debug turned on in production! 23 | DEBUG = True 24 | 25 | TEMPLATE_DEBUG = True 26 | 27 | ALLOWED_HOSTS = [] 28 | 29 | # Application definition 30 | 31 | INSTALLED_APPS = ( 32 | 'django.contrib.admin', 33 | 'django.contrib.auth', 34 | 'django.contrib.contenttypes', 35 | 'django.contrib.sessions', 36 | 'django.contrib.messages', 37 | 'django.contrib.staticfiles', 38 | 'hours' 39 | ) 40 | 41 | MIDDLEWARE_CLASSES = ( 42 | 'django.contrib.sessions.middleware.SessionMiddleware', 43 | 'django.middleware.common.CommonMiddleware', 44 | 'django.middleware.csrf.CsrfViewMiddleware', 45 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 46 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 47 | 'django.contrib.messages.middleware.MessageMiddleware', 48 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 49 | ) 50 | 51 | ROOT_URLCONF = 'abb.urls' 52 | 53 | WSGI_APPLICATION = 'abb.wsgi.application' 54 | 55 | 56 | # Database 57 | # https://docs.djangoproject.com/en/1.7/ref/settings/#databases 58 | 59 | DATABASES = { 60 | 'default': { 61 | 'ENGINE': 'django.db.backends.sqlite3', 62 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 63 | } 64 | } 65 | 66 | # import dj_database_url 67 | # DATABASES = {} 68 | # DATABASES['default'] = dj_database_url.config() 69 | 70 | # Internationalization 71 | # https://docs.djangoproject.com/en/1.7/topics/i18n/ 72 | 73 | LANGUAGE_CODE = 'en-us' 74 | 75 | TIME_ZONE = 'UTC' 76 | 77 | USE_I18N = True 78 | 79 | USE_L10N = True 80 | 81 | USE_TZ = True 82 | 83 | 84 | # Static files (CSS, JavaScript, Images) 85 | # https://docs.djangoproject.com/en/1.7/howto/static-files/ 86 | 87 | STATIC_URL = '/static/' 88 | STATIC_ROOT = os.path.join(BASE_DIR, "abb/static") 89 | 90 | 91 | STATICFILES_DIRS = ( 92 | os.path.join(BASE_DIR, "hours/static"), 93 | ) -------------------------------------------------------------------------------- /abb/abb/static/admin/js/timeparse.js: -------------------------------------------------------------------------------- 1 | var timeParsePatterns = [ 2 | // 9 3 | { re: /^\d{1,2}$/i, 4 | handler: function(bits) { 5 | if (bits[0].length == 1) { 6 | return '0' + bits[0] + ':00'; 7 | } else { 8 | return bits[0] + ':00'; 9 | } 10 | } 11 | }, 12 | // 13:00 13 | { re: /^\d{2}[:.]\d{2}$/i, 14 | handler: function(bits) { 15 | return bits[0].replace('.', ':'); 16 | } 17 | }, 18 | // 9:00 19 | { re: /^\d[:.]\d{2}$/i, 20 | handler: function(bits) { 21 | return '0' + bits[0].replace('.', ':'); 22 | } 23 | }, 24 | // 3 am / 3 a.m. / 3am 25 | { re: /^(\d+)\s*([ap])(?:.?m.?)?$/i, 26 | handler: function(bits) { 27 | var hour = parseInt(bits[1]); 28 | if (hour == 12) { 29 | hour = 0; 30 | } 31 | if (bits[2].toLowerCase() == 'p') { 32 | if (hour == 12) { 33 | hour = 0; 34 | } 35 | return (hour + 12) + ':00'; 36 | } else { 37 | if (hour < 10) { 38 | return '0' + hour + ':00'; 39 | } else { 40 | return hour + ':00'; 41 | } 42 | } 43 | } 44 | }, 45 | // 3.30 am / 3:15 a.m. / 3.00am 46 | { re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i, 47 | handler: function(bits) { 48 | var hour = parseInt(bits[1]); 49 | var mins = parseInt(bits[2]); 50 | if (mins < 10) { 51 | mins = '0' + mins; 52 | } 53 | if (hour == 12) { 54 | hour = 0; 55 | } 56 | if (bits[3].toLowerCase() == 'p') { 57 | if (hour == 12) { 58 | hour = 0; 59 | } 60 | return (hour + 12) + ':' + mins; 61 | } else { 62 | if (hour < 10) { 63 | return '0' + hour + ':' + mins; 64 | } else { 65 | return hour + ':' + mins; 66 | } 67 | } 68 | } 69 | }, 70 | // noon 71 | { re: /^no/i, 72 | handler: function(bits) { 73 | return '12:00'; 74 | } 75 | }, 76 | // midnight 77 | { re: /^mid/i, 78 | handler: function(bits) { 79 | return '00:00'; 80 | } 81 | } 82 | ]; 83 | 84 | function parseTimeString(s) { 85 | for (var i = 0; i < timeParsePatterns.length; i++) { 86 | var re = timeParsePatterns[i].re; 87 | var handler = timeParsePatterns[i].handler; 88 | var bits = re.exec(s); 89 | if (bits) { 90 | return handler(bits); 91 | } 92 | } 93 | return s; 94 | } 95 | -------------------------------------------------------------------------------- /abb/abb/static/admin/js/actions.min.js: -------------------------------------------------------------------------------- 1 | (function(a){var f;a.fn.actions=function(q){var b=a.extend({},a.fn.actions.defaults,q),g=a(this),e=!1,m=function(c){c?k():l();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).prop("checked",function(){var a;c==g.length?(a=!0,k()):(a=!1,n());return a})},k=function(){a(b.acrossClears).hide(); 2 | a(b.acrossQuestions).show();a(b.allContainer).hide()},p=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},l=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},n=function(){l();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};a(b.counterContainer).show();a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass); 3 | h();1==a(b.acrossInput).val()&&p()});a(b.allToggle).show().click(function(){m(a(this).prop("checked"));h()});a("a",b.acrossQuestions).click(function(c){c.preventDefault();a(b.acrossInput).val(1);p()});a("a",b.acrossClears).click(function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);n();m(0);h()});f=null;a(g).click(function(c){c||(c=window.event);var d=c.target?c.target:c.srcElement;if(f&&a.data(f)!=a.data(d)&&!0===c.shiftKey){var e=!1;a(f).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass, 4 | d.checked);a(g).each(function(){if(a.data(this)==a.data(f)||a.data(this)==a.data(d))e=e?!1:!0;e&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);f=d;h()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(a){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))}); 5 | a('form#changelist-form input[name="_save"]').click(function(c){var d=!1;a("select option:selected",b.actionContainer).each(function(){a(this).val()&&(d=!0)});if(d)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})}; 6 | a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery); 7 | -------------------------------------------------------------------------------- /abb/abb/static/styles/fonts.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @font-face { 4 | font-family: "18f"; 5 | src:url("../fonts/18f-font.eot"); 6 | src:url("../fonts/18f-font.eot?#iefix") format("embedded-opentype"), 7 | url("../fonts/18f-font.woff") format("woff"), 8 | url("../fonts/18f-font.ttf") format("truetype"), 9 | url("../fonts/18f-font.svg#untitled-font-1") format("svg"); 10 | font-weight: normal; 11 | font-style: normal; 12 | 13 | } 14 | 15 | [data-icon]:before { 16 | font-family: "18f" !important; 17 | content: attr(data-icon); 18 | font-style: normal !important; 19 | font-weight: normal !important; 20 | font-variant: normal !important; 21 | text-transform: none !important; 22 | speak: none; 23 | line-height: 1; 24 | -webkit-font-smoothing: antialiased; 25 | -moz-osx-font-smoothing: grayscale; 26 | } 27 | 28 | [class^="icon-"]:before, 29 | [class*=" icon-"]:before { 30 | font-family: "18f" !important; 31 | font-style: normal !important; 32 | font-weight: normal !important; 33 | font-variant: normal !important; 34 | text-transform: none !important; 35 | speak: none; 36 | line-height: 1; 37 | -webkit-font-smoothing: antialiased; 38 | -moz-osx-font-smoothing: grayscale; 39 | } 40 | 41 | .icon-lightbulb:before { 42 | content: "a"; 43 | } 44 | .icon-github1:before { 45 | content: "b"; 46 | } 47 | .icon-github2:before { 48 | content: "c"; 49 | } 50 | .icon-github3:before { 51 | content: "d"; 52 | } 53 | .icon-18f-logo:before { 54 | content: "e"; 55 | } 56 | .icon-camera:before { 57 | content: "f"; 58 | } 59 | .icon-twitter:before { 60 | content: "g"; 61 | } 62 | .icon-spinner:before { 63 | content: "l"; 64 | } 65 | .icon-email:before { 66 | content: "h"; 67 | } 68 | .icon-lastfm:before { 69 | content: "i"; 70 | } 71 | .icon-linkedin:before { 72 | content: "j"; 73 | } 74 | .icon-anchor:before { 75 | content: "k"; 76 | } 77 | body { 78 | font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; 79 | font-weight: 300; 80 | line-height: 1.8em; 81 | } 82 | 83 | h1, h2, h3, h4, h5, h6 { 84 | font-family: 'Raleway', 'Helvetica Neue', Helvetica, Arial, sans-serif; 85 | font-weight: 600; 86 | } 87 | 88 | a { 89 | color:#06d; 90 | text-decoration: underline; 91 | } 92 | a:hover {color:#c21;} 93 | 94 | /* SPINNER */ 95 | .icon-spin { 96 | display: inline-block; 97 | -webkit-animation: spin 2s infinite linear; 98 | -moz-animation: spin 2s infinite linear; 99 | -o-animation: spin 2s infinite linear; 100 | animation: spin 2s infinite linear; 101 | } 102 | @-webkit-keyframes spin { 103 | 0% { 104 | -webkit-transform: rotate(0deg); 105 | } 106 | 100% { 107 | -webkit-transform: rotate(359deg); 108 | } 109 | } 110 | @-moz-keyframes spin { 111 | 0% { 112 | -moz-transform: rotate(0deg); 113 | } 114 | 100% { 115 | -moz-transform: rotate(359deg); 116 | } 117 | } 118 | @-o-keyframes spin { 119 | 0% { 120 | -o-transform: rotate(0deg); 121 | } 122 | 100% { 123 | -o-transform: rotate(359deg); 124 | } 125 | } 126 | @-ms-keyframes spin { 127 | 0% { 128 | -ms-transform: rotate(0deg); 129 | } 130 | 100% { 131 | -ms-transform: rotate(359deg); 132 | } 133 | } 134 | @keyframes spin { 135 | 0% { 136 | transform: rotate(0deg); 137 | } 138 | 100% { 139 | transform: rotate(359deg); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /abb/hours/static/styles/fonts.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @font-face { 4 | font-family: "18f"; 5 | src:url("../fonts/18f-font.eot"); 6 | src:url("../fonts/18f-font.eot?#iefix") format("embedded-opentype"), 7 | url("../fonts/18f-font.woff") format("woff"), 8 | url("../fonts/18f-font.ttf") format("truetype"), 9 | url("../fonts/18f-font.svg#untitled-font-1") format("svg"); 10 | font-weight: normal; 11 | font-style: normal; 12 | 13 | } 14 | 15 | [data-icon]:before { 16 | font-family: "18f" !important; 17 | content: attr(data-icon); 18 | font-style: normal !important; 19 | font-weight: normal !important; 20 | font-variant: normal !important; 21 | text-transform: none !important; 22 | speak: none; 23 | line-height: 1; 24 | -webkit-font-smoothing: antialiased; 25 | -moz-osx-font-smoothing: grayscale; 26 | } 27 | 28 | [class^="icon-"]:before, 29 | [class*=" icon-"]:before { 30 | font-family: "18f" !important; 31 | font-style: normal !important; 32 | font-weight: normal !important; 33 | font-variant: normal !important; 34 | text-transform: none !important; 35 | speak: none; 36 | line-height: 1; 37 | -webkit-font-smoothing: antialiased; 38 | -moz-osx-font-smoothing: grayscale; 39 | } 40 | 41 | .icon-lightbulb:before { 42 | content: "a"; 43 | } 44 | .icon-github1:before { 45 | content: "b"; 46 | } 47 | .icon-github2:before { 48 | content: "c"; 49 | } 50 | .icon-github3:before { 51 | content: "d"; 52 | } 53 | .icon-18f-logo:before { 54 | content: "e"; 55 | } 56 | .icon-camera:before { 57 | content: "f"; 58 | } 59 | .icon-twitter:before { 60 | content: "g"; 61 | } 62 | .icon-spinner:before { 63 | content: "l"; 64 | } 65 | .icon-email:before { 66 | content: "h"; 67 | } 68 | .icon-lastfm:before { 69 | content: "i"; 70 | } 71 | .icon-linkedin:before { 72 | content: "j"; 73 | } 74 | .icon-anchor:before { 75 | content: "k"; 76 | } 77 | body { 78 | font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; 79 | font-weight: 300; 80 | line-height: 1.8em; 81 | } 82 | 83 | h1, h2, h3, h4, h5, h6 { 84 | font-family: 'Raleway', 'Helvetica Neue', Helvetica, Arial, sans-serif; 85 | font-weight: 600; 86 | } 87 | 88 | a { 89 | color:#06d; 90 | text-decoration: underline; 91 | } 92 | a:hover {color:#c21;} 93 | 94 | /* SPINNER */ 95 | .icon-spin { 96 | display: inline-block; 97 | -webkit-animation: spin 2s infinite linear; 98 | -moz-animation: spin 2s infinite linear; 99 | -o-animation: spin 2s infinite linear; 100 | animation: spin 2s infinite linear; 101 | } 102 | @-webkit-keyframes spin { 103 | 0% { 104 | -webkit-transform: rotate(0deg); 105 | } 106 | 100% { 107 | -webkit-transform: rotate(359deg); 108 | } 109 | } 110 | @-moz-keyframes spin { 111 | 0% { 112 | -moz-transform: rotate(0deg); 113 | } 114 | 100% { 115 | -moz-transform: rotate(359deg); 116 | } 117 | } 118 | @-o-keyframes spin { 119 | 0% { 120 | -o-transform: rotate(0deg); 121 | } 122 | 100% { 123 | -o-transform: rotate(359deg); 124 | } 125 | } 126 | @-ms-keyframes spin { 127 | 0% { 128 | -ms-transform: rotate(0deg); 129 | } 130 | 100% { 131 | -ms-transform: rotate(359deg); 132 | } 133 | } 134 | @keyframes spin { 135 | 0% { 136 | transform: rotate(0deg); 137 | } 138 | 100% { 139 | transform: rotate(359deg); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /abb/abb/static/admin/js/admin/RelatedObjectLookups.js: -------------------------------------------------------------------------------- 1 | // Handles related-objects functionality: lookup link for raw_id_fields 2 | // and Add Another links. 3 | 4 | function html_unescape(text) { 5 | // Unescape a string that was escaped using django.utils.html.escape. 6 | text = text.replace(/</g, '<'); 7 | text = text.replace(/>/g, '>'); 8 | text = text.replace(/"/g, '"'); 9 | text = text.replace(/'/g, "'"); 10 | text = text.replace(/&/g, '&'); 11 | return text; 12 | } 13 | 14 | // IE doesn't accept periods or dashes in the window name, but the element IDs 15 | // we use to generate popup window names may contain them, therefore we map them 16 | // to allowed characters in a reversible way so that we can locate the correct 17 | // element when the popup window is dismissed. 18 | function id_to_windowname(text) { 19 | text = text.replace(/\./g, '__dot__'); 20 | text = text.replace(/\-/g, '__dash__'); 21 | return text; 22 | } 23 | 24 | function windowname_to_id(text) { 25 | text = text.replace(/__dot__/g, '.'); 26 | text = text.replace(/__dash__/g, '-'); 27 | return text; 28 | } 29 | 30 | function showRelatedObjectLookupPopup(triggeringLink) { 31 | var name = triggeringLink.id.replace(/^lookup_/, ''); 32 | name = id_to_windowname(name); 33 | var href; 34 | if (triggeringLink.href.search(/\?/) >= 0) { 35 | href = triggeringLink.href + '&_popup=1'; 36 | } else { 37 | href = triggeringLink.href + '?_popup=1'; 38 | } 39 | var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); 40 | win.focus(); 41 | return false; 42 | } 43 | 44 | function dismissRelatedLookupPopup(win, chosenId) { 45 | var name = windowname_to_id(win.name); 46 | var elem = document.getElementById(name); 47 | if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) { 48 | elem.value += ',' + chosenId; 49 | } else { 50 | document.getElementById(name).value = chosenId; 51 | } 52 | win.close(); 53 | } 54 | 55 | function showAddAnotherPopup(triggeringLink) { 56 | var name = triggeringLink.id.replace(/^add_/, ''); 57 | name = id_to_windowname(name); 58 | var href = triggeringLink.href; 59 | if (href.indexOf('?') == -1) { 60 | href += '?_popup=1'; 61 | } else { 62 | href += '&_popup=1'; 63 | } 64 | var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); 65 | win.focus(); 66 | return false; 67 | } 68 | 69 | function dismissAddAnotherPopup(win, newId, newRepr) { 70 | // newId and newRepr are expected to have previously been escaped by 71 | // django.utils.html.escape. 72 | newId = html_unescape(newId); 73 | newRepr = html_unescape(newRepr); 74 | var name = windowname_to_id(win.name); 75 | var elem = document.getElementById(name); 76 | var o; 77 | if (elem) { 78 | var elemName = elem.nodeName.toUpperCase(); 79 | if (elemName == 'SELECT') { 80 | o = new Option(newRepr, newId); 81 | elem.options[elem.options.length] = o; 82 | o.selected = true; 83 | } else if (elemName == 'INPUT') { 84 | if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) { 85 | elem.value += ',' + newId; 86 | } else { 87 | elem.value = newId; 88 | } 89 | } 90 | } else { 91 | var toId = name + "_to"; 92 | o = new Option(newRepr, newId); 93 | SelectBox.add_to_cache(toId, o); 94 | SelectBox.redisplay(toId); 95 | } 96 | win.close(); 97 | } 98 | -------------------------------------------------------------------------------- /abb/hours/fixtures/initial_data.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"model":"hours.project","fields":{"name":"Out of Office","billable":false}}, 3 | {"model":"hours.project","fields":{"name":"18F General","billable":false}}, 4 | {"model":"hours.project","fields":{"name":"PIF Program","billable":false}}, 5 | {"model":"hours.project","fields":{"name":"18F Admin/Ops","billable":false}}, 6 | {"model":"hours.project","fields":{"name":"18F Recruiting/Interviewing","billable":false}}, 7 | {"model":"hours.project","fields":{"name":"Ops/Acquisitions","billable":false}}, 8 | {"model":"hours.project","fields":{"name":"Ops/Legal","billable":false}}, 9 | {"model":"hours.project","fields":{"name":"Ops/Budget & Finance ","billable":false}}, 10 | {"model":"hours.project","fields":{"name":"Ops/Project Luca","billable":false}}, 11 | {"model":"hours.project","fields":{"name":"Outreach/18F Site","billable":false}}, 12 | {"model":"hours.project","fields":{"name":"Outreach/Communications (blogs, messaging, etc)","billable": false}}, 13 | {"model":"hours.project","fields":{"name":"Outreach/Events","billable":false}}, 14 | {"model":"hours.project","fields":{"name":"Guilds","billable":false}}, 15 | {"model":"hours.project","fields":{"name":"Workgroups","billable":false}}, 16 | {"model":"hours.project","fields":{"name":"API.Data.gov","billable":false}}, 17 | {"model":"hours.project","fields":{"name":"/Developer Program","billable":false}}, 18 | {"model":"hours.project","fields":{"name":"MyUSA","billable":true}}, 19 | {"model":"hours.project","fields":{"name":"FOIA Modernization","billable":true}}, 20 | {"model":"hours.project","fields":{"name":"openFEC","billable":true}}, 21 | {"model":"hours.project","fields":{"name":"18F’s Open Source Policy","billable":false}}, 22 | {"model":"hours.project","fields":{"name":"Air Force Small Biz","billable":true}}, 23 | {"model":"hours.project","fields":{"name":"USCIS","billable":true}}, 24 | {"model":"hours.project","fields":{"name":"Midas","billable":true}}, 25 | {"model":"hours.project","fields":{"name":"FBOpen","billable":false}}, 26 | {"model":"hours.project","fields":{"name":"CAP Communicart","billable":true}}, 27 | {"model":"hours.project","fields":{"name":"Peace Corps","billable":true}}, 28 | {"model":"hours.project","fields":{"name":"Consulting Services","billable":false}}, 29 | {"model":"hours.project","fields":{"name":"Income Verification Pilot","billable":true}}, 30 | {"model":"hours.project","fields":{"name":"Web Maker / NotAlone.gov","billable":true}}, 31 | {"model":"hours.project","fields":{"name":"Web Maker / myRA","billable":true}}, 32 | {"model":"hours.project","fields":{"name":"Web Maker / EITI","billable":true}}, 33 | {"model":"hours.project","fields":{"name":"OASIS","billable":true}}, 34 | {"model":"hours.project","fields":{"name":"18F Dashboard","billable":false}}, 35 | {"model":"hours.project","fields":{"name":"GSA CIO Support","billable":false}}, 36 | {"model":"hours.project","fields":{"name":"Consulting / DOL WHD","billable":true}}, 37 | {"model":"hours.project","fields":{"name":"Consulting / GSA OHRM","billable":true}}, 38 | {"model":"hours.project","fields":{"name":"Consulting / SSA DCPS","billable":true}}, 39 | {"model":"hours.project","fields":{"name":"Consulting / DATA Act","billable":true}}, 40 | {"model":"hours.project","fields":{"name":"Consulting / Navy Reserve - R2S","billable":true}}, 41 | {"model":"hours.project","fields":{"name":"GSA - FICAM","billable":true}}, 42 | {"model":"hours.project","fields":{"name":"Trusted Internet Connection 3.0","billable":false}}, 43 | {"model":"hours.project","fields":{"name":"Platform as a Service","billable":false}}, 44 | {"model":"hours.project","fields":{"name":"Climate Project","billable":false}}, 45 | {"model":"hours.project","fields":{"name":"Digital Analytics Program","billable":false}}, 46 | {"model":"hours.project","fields":{"name":"Agile Corps","billable":false}}, 47 | {"model":"hours.project","fields":{"name":"Dogfood","billable":false}}, 48 | {"model":"hours.project","fields":{"name":"R2H","billable":false}}, 49 | {"model":"hours.project","fields":{"name":"Seeds","billable":false}}, 50 | {"model":"hours.project","fields":{"name":"Consulting - Agile BPA","billable":false}} 51 | ] 52 | -------------------------------------------------------------------------------- /abb/abb/static/admin/js/inlines.min.js: -------------------------------------------------------------------------------- 1 | (function(a){a.fn.formset=function(g){var b=a.extend({},a.fn.formset.defaults,g),i=a(this);g=i.parent();var m=function(e,k,h){var j=RegExp("("+k+"-(\\d+|__prefix__))");k=k+"-"+h;a(e).prop("for")&&a(e).prop("for",a(e).prop("for").replace(j,k));if(e.id)e.id=e.id.replace(j,k);if(e.name)e.name=e.name.replace(j,k)},l=a("#id_"+b.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),d=parseInt(l.val(),10),c=a("#id_"+b.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off");l=c.val()===""||c.val()-l.val()>0;i.each(function(){a(this).not("."+ 2 | b.emptyCssClass).addClass(b.formCssClass)});if(i.length&&l){var f;if(i.prop("tagName")=="TR"){i=this.eq(-1).children().length;g.append(''+b.addText+"");f=g.find("tr:last a")}else{i.filter(":last").after('
'+b.addText+"
");f=i.filter(":last").next().find("a")}f.click(function(e){e.preventDefault();var k=a("#id_"+b.prefix+"-TOTAL_FORMS");e=a("#"+ 3 | b.prefix+"-empty");var h=e.clone(true);h.removeClass(b.emptyCssClass).addClass(b.formCssClass).attr("id",b.prefix+"-"+d);if(h.is("tr"))h.children(":last").append('
'+b.deleteText+"
");else h.is("ul")||h.is("ol")?h.append('
  • '+b.deleteText+"
  • "):h.children(":first").append(''+b.deleteText+""); 4 | h.find("*").each(function(){m(this,b.prefix,k.val())});h.insertBefore(a(e));a(k).val(parseInt(k.val(),10)+1);d+=1;c.val()!==""&&c.val()-k.val()<=0&&f.parent().hide();h.find("a."+b.deleteCssClass).click(function(j){j.preventDefault();j=a(this).parents("."+b.formCssClass);j.remove();d-=1;b.removed&&b.removed(j);j=a("."+b.formCssClass);a("#id_"+b.prefix+"-TOTAL_FORMS").val(j.length);if(c.val()===""||c.val()-j.length>0)f.parent().show();for(var n=0,o=j.length;n b) return 1; 100 | if (a < b) return -1; 101 | } 102 | catch (e) { 103 | // silently fail on IE 'unknown' exception 104 | } 105 | return 0; 106 | } ); 107 | }, 108 | select_all: function(id) { 109 | var box = document.getElementById(id); 110 | for (var i = 0; i < box.options.length; i++) { 111 | box.options[i].selected = 'selected'; 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /abb/abb/static/admin/css/rtl.css: -------------------------------------------------------------------------------- 1 | body { 2 | direction: rtl; 3 | } 4 | 5 | /* LOGIN */ 6 | 7 | .login .form-row { 8 | float: right; 9 | } 10 | 11 | .login .form-row label { 12 | float: right; 13 | padding-left: 0.5em; 14 | padding-right: 0; 15 | text-align: left; 16 | } 17 | 18 | .login .submit-row { 19 | clear: both; 20 | padding: 1em 9.4em 0 0; 21 | } 22 | 23 | /* GLOBAL */ 24 | 25 | th { 26 | text-align: right; 27 | } 28 | 29 | .module h2, .module caption { 30 | text-align: right; 31 | } 32 | 33 | .addlink, .changelink { 34 | padding-left: 0px; 35 | padding-right: 12px; 36 | background-position: 100% 0.2em; 37 | } 38 | 39 | .deletelink { 40 | padding-left: 0px; 41 | padding-right: 12px; 42 | background-position: 100% 0.25em; 43 | } 44 | 45 | .object-tools { 46 | float: left; 47 | } 48 | 49 | thead th:first-child, 50 | tfoot td:first-child { 51 | border-left: 1px solid #ddd !important; 52 | } 53 | 54 | /* LAYOUT */ 55 | 56 | #user-tools { 57 | right: auto; 58 | left: 0; 59 | text-align: left; 60 | } 61 | 62 | div.breadcrumbs { 63 | text-align: right; 64 | } 65 | 66 | #content-main { 67 | float: right; 68 | } 69 | 70 | #content-related { 71 | float: left; 72 | margin-left: -19em; 73 | margin-right: auto; 74 | } 75 | 76 | .colMS { 77 | margin-left: 20em !important; 78 | margin-right: 10px !important; 79 | } 80 | 81 | /* SORTABLE TABLES */ 82 | 83 | table thead th.sorted .sortoptions { 84 | float: left; 85 | } 86 | 87 | thead th.sorted .text { 88 | padding-right: 0; 89 | padding-left: 42px; 90 | } 91 | 92 | /* dashboard styles */ 93 | 94 | .dashboard .module table td a { 95 | padding-left: .6em; 96 | padding-right: 12px; 97 | } 98 | 99 | /* changelists styles */ 100 | 101 | .change-list .filtered { 102 | background: white url(../img/changelist-bg_rtl.gif) top left repeat-y !important; 103 | } 104 | 105 | .change-list .filtered table { 106 | border-left: 1px solid #ddd; 107 | border-right: 0px none; 108 | } 109 | 110 | #changelist-filter { 111 | right: auto; 112 | left: 0; 113 | border-left: 0px none; 114 | border-right: 1px solid #ddd; 115 | } 116 | 117 | .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { 118 | margin-right: 0px !important; 119 | margin-left: 160px !important; 120 | } 121 | 122 | #changelist-filter li.selected { 123 | border-left: 0px none; 124 | padding-left: 0px; 125 | margin-left: 0; 126 | border-right: 5px solid #ccc; 127 | padding-right: 5px; 128 | margin-right: -10px; 129 | } 130 | 131 | .filtered .actions { 132 | border-left:1px solid #DDDDDD; 133 | margin-left:160px !important; 134 | border-right: 0 none; 135 | margin-right:0 !important; 136 | } 137 | 138 | #changelist table tbody td:first-child, #changelist table tbody th:first-child { 139 | border-right: 0; 140 | border-left: 1px solid #ddd; 141 | } 142 | 143 | /* FORMS */ 144 | 145 | .aligned label { 146 | padding: 0 0 3px 1em; 147 | float: right; 148 | } 149 | 150 | .submit-row { 151 | text-align: left 152 | } 153 | 154 | .submit-row p.deletelink-box { 155 | float: right; 156 | } 157 | 158 | .submit-row .deletelink { 159 | background: url(../img/icon_deletelink.gif) 0 50% no-repeat; 160 | padding-right: 14px; 161 | } 162 | 163 | .vDateField, .vTimeField { 164 | margin-left: 2px; 165 | } 166 | 167 | form ul.inline li { 168 | float: right; 169 | padding-right: 0; 170 | padding-left: 7px; 171 | } 172 | 173 | input[type=submit].default, .submit-row input.default { 174 | float: left; 175 | } 176 | 177 | fieldset .field-box { 178 | float: right; 179 | margin-left: 20px; 180 | margin-right: 0; 181 | } 182 | 183 | .errorlist li { 184 | background-position: 100% .3em; 185 | padding: 4px 25px 4px 5px; 186 | } 187 | 188 | .errornote { 189 | background-position: 100% .3em; 190 | padding: 4px 25px 4px 5px; 191 | } 192 | 193 | /* WIDGETS */ 194 | 195 | .calendarnav-previous { 196 | top: 0; 197 | left: auto; 198 | right: 0; 199 | } 200 | 201 | .calendarnav-next { 202 | top: 0; 203 | right: auto; 204 | left: 0; 205 | } 206 | 207 | .calendar caption, .calendarbox h2 { 208 | text-align: center; 209 | } 210 | 211 | .selector { 212 | float: right; 213 | } 214 | 215 | .selector .selector-filter { 216 | text-align: right; 217 | } 218 | 219 | .inline-deletelink { 220 | float: left; 221 | } 222 | 223 | /* MISC */ 224 | 225 | .inline-related h2, .inline-group h2 { 226 | text-align: right 227 | } 228 | 229 | .inline-related h3 span.delete { 230 | padding-right: 20px; 231 | padding-left: inherit; 232 | left: 10px; 233 | right: inherit; 234 | float:left; 235 | } 236 | 237 | .inline-related h3 span.delete label { 238 | margin-left: inherit; 239 | margin-right: 2px; 240 | } 241 | 242 | /* IE7 specific bug fixes */ 243 | 244 | div.colM { 245 | position: relative; 246 | } 247 | 248 | .submit-row input { 249 | float: left; 250 | } -------------------------------------------------------------------------------- /abb/abb/static/js/18f.js: -------------------------------------------------------------------------------- 1 | 2 | $(document).ready(function () { 3 | // load posts from tumblr 4 | var blog = '18fblog.tumblr.com'; 5 | var months = [ 6 | 'January', 7 | 'February', 8 | 'March', 9 | 'April', 10 | 'May', 11 | 'June', 12 | 'July', 13 | 'August', 14 | 'September', 15 | 'October', 16 | 'November', 17 | 'December' 18 | ]; 19 | 20 | 21 | // get tumblr posts 22 | $.ajax({ 23 | url: '//api.tumblr.com/v2/blog/' + blog + '/posts/text?notes_info=true&limit=3&filter=text&api_key=cA9agkd1WdAsFUFL5iq1Wnn0m4Dmcv5vf5otES3Ou08r2D3Ldu', 24 | type: 'GET', 25 | contentType: 'application/json', 26 | dataType: 'jsonp', 27 | jsonpCallback: 'jsonp', 28 | success: function (result) { 29 | $("#blog-loading").hide(); 30 | for (i in result.response.posts) { 31 | // render post to the page 32 | var post = result.response.posts[i]; 33 | $('#blog' + i + ' .blog-title').html(post.title); 34 | $('#blog' + i + ' .blog-title').attr('href', post.post_url); 35 | $('#blog' + i + ' .blog-text').html(post.body); 36 | $('#blog' + i + ' .readmore').attr('href', post.post_url); 37 | var tagHtml = ''; 38 | for (j in post.tags) { 39 | if (j != 0) { 40 | tagHtml += ', '; 41 | } 42 | tagHtml += '' + post.tags[j] + ''; 43 | } 44 | $('#blog' + i + ' .blog-tags').html(tagHtml); 45 | var d = new Date(post.timestamp * 1000); 46 | var date = months[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear(); 47 | $('#blog' + i + ' .blog-date').html(date); 48 | $('#blog' + i).show(); 49 | } 50 | $(".blog-snippet").dotdotdot({ 51 | watch: "window", 52 | after: "a.readmore" 53 | }); 54 | }, 55 | error: function (e) { 56 | $("#blog-loading .error").show(); 57 | } 58 | }); 59 | 60 | // linear fade-ins 61 | $('.fadeIn').each(function (e) { 62 | $(this).addClass('fade-'+e); 63 | var t = setTimeout("$('.fade-"+e+"').fadeIn(500)",500*e); 64 | }); 65 | 66 | // team hover effect 67 | $('.bio').mouseenter(function () { 68 | var $img = $(this).find('.team-img'); 69 | $img.data('original',$img.attr('src')); 70 | $(this).append(''); 71 | var $hover_img = $(this).find('.hover-img'); 72 | $hover_img.width($img.width()).height($img.height()); 73 | $hover_img.animate({ 74 | opacity: 1 75 | }, 'fast'); 76 | }).mouseleave(function () { 77 | var $img = $(this).find('.team-img'); 78 | $(this).find('.hover-img').fadeOut('slow',function () { 79 | $(this).remove(); 80 | }); 81 | }); 82 | 83 | // img preloader 84 | $('body').append('
    '); 85 | $('.bio').find('img').each( function() { 86 | var src = $(this).data('color'); 87 | var $pre = $('#preloader'); 88 | $pre.append(""); 89 | }); 90 | 91 | // slider preloader 92 | $('#slideshow .slide').each( function() { 93 | var src = ($(this).css('background-image')); 94 | src = src.replace('url(','').replace(')',''); 95 | var $pre = $('#preloader'); 96 | $pre.append(""); 97 | }); 98 | }); 99 | 100 | // IE Form Placeholders 101 | $(function() { 102 | if(!$.support.placeholder) { 103 | var active = document.activeElement; 104 | $(':text').focus(function () { 105 | if ($(this).attr('placeholder') != '' && $(this).val() == $(this).attr('placeholder')) { 106 | $(this).val('').removeClass('hasPlaceholder'); 107 | } 108 | }).blur(function () { 109 | if ($(this).attr('placeholder') != '' && ($(this).val() == '' || $(this).val() == $(this).attr('placeholder'))) { 110 | $(this).val($(this).attr('placeholder')).addClass('hasPlaceholder'); 111 | } 112 | }); 113 | $(':text').blur(); 114 | $(active).focus(); 115 | $('form').submit(function () { 116 | $(this).find('.hasPlaceholder').each(function() { $(this).val(''); }); 117 | }); 118 | } 119 | }); 120 | 121 | // friendly console message 122 | 123 | // IE needs plaintext, sigh 124 | // window._ie = true; 125 | if (window._ie) { 126 | console.log("Oh hi there! By all means, poke around."); 127 | console.log(""); 128 | console.log("If you find a bug or want to talk, we're at 18f@gsa.gov and track issues on https://github.com/18f/18f.gsa.gov/issues"); 129 | console.log("And check us out on GitHub generally! We're an open source team. https://github.com/18f"); 130 | } 131 | 132 | // otherwise, let's get fancy 133 | else { 134 | var styles = { 135 | big: "font-size: 24pt; font-weight: bold; color: #18f", 136 | medium: "font-size: 10pt", 137 | medium_bold: "font-size: 10pt; font-weight: bold", 138 | medium_link: "font-size: 10pt; color: #18f" // works in Firebug, not Chrome 139 | }; 140 | console.log("%cOh hi there! Please poke around.", styles.big); 141 | console.log(" "); 142 | console.log("%cIf you find a bug or want to talk, we're at %c18f@gsa.gov%c and track issues on %chttps://github.com/18f/18f.gsa.gov/issues", styles.medium, styles.medium_bold, styles.medium, styles.medium_link); 143 | console.log("%cAnd check us out on GitHub generally! We're an %copen source team%c. %chttps://github.com/18f", styles.medium, styles.medium_bold, styles.medium, styles.medium_link); 144 | } 145 | -------------------------------------------------------------------------------- /abb/hours/static/js/18f.js: -------------------------------------------------------------------------------- 1 | 2 | $(document).ready(function () { 3 | // load posts from tumblr 4 | var blog = '18fblog.tumblr.com'; 5 | var months = [ 6 | 'January', 7 | 'February', 8 | 'March', 9 | 'April', 10 | 'May', 11 | 'June', 12 | 'July', 13 | 'August', 14 | 'September', 15 | 'October', 16 | 'November', 17 | 'December' 18 | ]; 19 | 20 | 21 | // get tumblr posts 22 | $.ajax({ 23 | url: '//api.tumblr.com/v2/blog/' + blog + '/posts/text?notes_info=true&limit=3&filter=text&api_key=cA9agkd1WdAsFUFL5iq1Wnn0m4Dmcv5vf5otES3Ou08r2D3Ldu', 24 | type: 'GET', 25 | contentType: 'application/json', 26 | dataType: 'jsonp', 27 | jsonpCallback: 'jsonp', 28 | success: function (result) { 29 | $("#blog-loading").hide(); 30 | for (i in result.response.posts) { 31 | // render post to the page 32 | var post = result.response.posts[i]; 33 | $('#blog' + i + ' .blog-title').html(post.title); 34 | $('#blog' + i + ' .blog-title').attr('href', post.post_url); 35 | $('#blog' + i + ' .blog-text').html(post.body); 36 | $('#blog' + i + ' .readmore').attr('href', post.post_url); 37 | var tagHtml = ''; 38 | for (j in post.tags) { 39 | if (j != 0) { 40 | tagHtml += ', '; 41 | } 42 | tagHtml += '' + post.tags[j] + ''; 43 | } 44 | $('#blog' + i + ' .blog-tags').html(tagHtml); 45 | var d = new Date(post.timestamp * 1000); 46 | var date = months[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear(); 47 | $('#blog' + i + ' .blog-date').html(date); 48 | $('#blog' + i).show(); 49 | } 50 | $(".blog-snippet").dotdotdot({ 51 | watch: "window", 52 | after: "a.readmore" 53 | }); 54 | }, 55 | error: function (e) { 56 | $("#blog-loading .error").show(); 57 | } 58 | }); 59 | 60 | // linear fade-ins 61 | $('.fadeIn').each(function (e) { 62 | $(this).addClass('fade-'+e); 63 | var t = setTimeout("$('.fade-"+e+"').fadeIn(500)",500*e); 64 | }); 65 | 66 | // team hover effect 67 | $('.bio').mouseenter(function () { 68 | var $img = $(this).find('.team-img'); 69 | $img.data('original',$img.attr('src')); 70 | $(this).append(''); 71 | var $hover_img = $(this).find('.hover-img'); 72 | $hover_img.width($img.width()).height($img.height()); 73 | $hover_img.animate({ 74 | opacity: 1 75 | }, 'fast'); 76 | }).mouseleave(function () { 77 | var $img = $(this).find('.team-img'); 78 | $(this).find('.hover-img').fadeOut('slow',function () { 79 | $(this).remove(); 80 | }); 81 | }); 82 | 83 | // img preloader 84 | $('body').append('
    '); 85 | $('.bio').find('img').each( function() { 86 | var src = $(this).data('color'); 87 | var $pre = $('#preloader'); 88 | $pre.append(""); 89 | }); 90 | 91 | // slider preloader 92 | $('#slideshow .slide').each( function() { 93 | var src = ($(this).css('background-image')); 94 | src = src.replace('url(','').replace(')',''); 95 | var $pre = $('#preloader'); 96 | $pre.append(""); 97 | }); 98 | }); 99 | 100 | // IE Form Placeholders 101 | $(function() { 102 | if(!$.support.placeholder) { 103 | var active = document.activeElement; 104 | $(':text').focus(function () { 105 | if ($(this).attr('placeholder') != '' && $(this).val() == $(this).attr('placeholder')) { 106 | $(this).val('').removeClass('hasPlaceholder'); 107 | } 108 | }).blur(function () { 109 | if ($(this).attr('placeholder') != '' && ($(this).val() == '' || $(this).val() == $(this).attr('placeholder'))) { 110 | $(this).val($(this).attr('placeholder')).addClass('hasPlaceholder'); 111 | } 112 | }); 113 | $(':text').blur(); 114 | $(active).focus(); 115 | $('form').submit(function () { 116 | $(this).find('.hasPlaceholder').each(function() { $(this).val(''); }); 117 | }); 118 | } 119 | }); 120 | 121 | // friendly console message 122 | 123 | // IE needs plaintext, sigh 124 | // window._ie = true; 125 | if (window._ie) { 126 | console.log("Oh hi there! By all means, poke around."); 127 | console.log(""); 128 | console.log("If you find a bug or want to talk, we're at 18f@gsa.gov and track issues on https://github.com/18f/18f.gsa.gov/issues"); 129 | console.log("And check us out on GitHub generally! We're an open source team. https://github.com/18f"); 130 | } 131 | 132 | // otherwise, let's get fancy 133 | else { 134 | var styles = { 135 | big: "font-size: 24pt; font-weight: bold; color: #18f", 136 | medium: "font-size: 10pt", 137 | medium_bold: "font-size: 10pt; font-weight: bold", 138 | medium_link: "font-size: 10pt; color: #18f" // works in Firebug, not Chrome 139 | }; 140 | console.log("%cOh hi there! Please poke around.", styles.big); 141 | console.log(" "); 142 | console.log("%cIf you find a bug or want to talk, we're at %c18f@gsa.gov%c and track issues on %chttps://github.com/18f/18f.gsa.gov/issues", styles.medium, styles.medium_bold, styles.medium, styles.medium_link); 143 | console.log("%cAnd check us out on GitHub generally! We're an %copen source team%c. %chttps://github.com/18f", styles.medium, styles.medium_bold, styles.medium, styles.medium_link); 144 | } 145 | -------------------------------------------------------------------------------- /abb/abb/static/admin/js/actions.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | var lastChecked; 3 | 4 | $.fn.actions = function(opts) { 5 | var options = $.extend({}, $.fn.actions.defaults, opts); 6 | var actionCheckboxes = $(this); 7 | var list_editable_changed = false; 8 | var checker = function(checked) { 9 | if (checked) { 10 | showQuestion(); 11 | } else { 12 | reset(); 13 | } 14 | $(actionCheckboxes).prop("checked", checked) 15 | .parent().parent().toggleClass(options.selectedClass, checked); 16 | }, 17 | updateCounter = function() { 18 | var sel = $(actionCheckboxes).filter(":checked").length; 19 | // _actions_icnt is defined in the generated HTML 20 | // and contains the total amount of objects in the queryset 21 | $(options.counterContainer).html(interpolate( 22 | ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), { 23 | sel: sel, 24 | cnt: _actions_icnt 25 | }, true)); 26 | $(options.allToggle).prop("checked", function() { 27 | var value; 28 | if (sel == actionCheckboxes.length) { 29 | value = true; 30 | showQuestion(); 31 | } else { 32 | value = false; 33 | clearAcross(); 34 | } 35 | return value; 36 | }); 37 | }, 38 | showQuestion = function() { 39 | $(options.acrossClears).hide(); 40 | $(options.acrossQuestions).show(); 41 | $(options.allContainer).hide(); 42 | }, 43 | showClear = function() { 44 | $(options.acrossClears).show(); 45 | $(options.acrossQuestions).hide(); 46 | $(options.actionContainer).toggleClass(options.selectedClass); 47 | $(options.allContainer).show(); 48 | $(options.counterContainer).hide(); 49 | }, 50 | reset = function() { 51 | $(options.acrossClears).hide(); 52 | $(options.acrossQuestions).hide(); 53 | $(options.allContainer).hide(); 54 | $(options.counterContainer).show(); 55 | }, 56 | clearAcross = function() { 57 | reset(); 58 | $(options.acrossInput).val(0); 59 | $(options.actionContainer).removeClass(options.selectedClass); 60 | }; 61 | // Show counter by default 62 | $(options.counterContainer).show(); 63 | // Check state of checkboxes and reinit state if needed 64 | $(this).filter(":checked").each(function(i) { 65 | $(this).parent().parent().toggleClass(options.selectedClass); 66 | updateCounter(); 67 | if ($(options.acrossInput).val() == 1) { 68 | showClear(); 69 | } 70 | }); 71 | $(options.allToggle).show().click(function() { 72 | checker($(this).prop("checked")); 73 | updateCounter(); 74 | }); 75 | $("a", options.acrossQuestions).click(function(event) { 76 | event.preventDefault(); 77 | $(options.acrossInput).val(1); 78 | showClear(); 79 | }); 80 | $("a", options.acrossClears).click(function(event) { 81 | event.preventDefault(); 82 | $(options.allToggle).prop("checked", false); 83 | clearAcross(); 84 | checker(0); 85 | updateCounter(); 86 | }); 87 | lastChecked = null; 88 | $(actionCheckboxes).click(function(event) { 89 | if (!event) { event = window.event; } 90 | var target = event.target ? event.target : event.srcElement; 91 | if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey === true) { 92 | var inrange = false; 93 | $(lastChecked).prop("checked", target.checked) 94 | .parent().parent().toggleClass(options.selectedClass, target.checked); 95 | $(actionCheckboxes).each(function() { 96 | if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) { 97 | inrange = (inrange) ? false : true; 98 | } 99 | if (inrange) { 100 | $(this).prop("checked", target.checked) 101 | .parent().parent().toggleClass(options.selectedClass, target.checked); 102 | } 103 | }); 104 | } 105 | $(target).parent().parent().toggleClass(options.selectedClass, target.checked); 106 | lastChecked = target; 107 | updateCounter(); 108 | }); 109 | $('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() { 110 | list_editable_changed = true; 111 | }); 112 | $('form#changelist-form button[name="index"]').click(function(event) { 113 | if (list_editable_changed) { 114 | return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.")); 115 | } 116 | }); 117 | $('form#changelist-form input[name="_save"]').click(function(event) { 118 | var action_changed = false; 119 | $('select option:selected', options.actionContainer).each(function() { 120 | if ($(this).val()) { 121 | action_changed = true; 122 | } 123 | }); 124 | if (action_changed) { 125 | if (list_editable_changed) { 126 | return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")); 127 | } else { 128 | return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button.")); 129 | } 130 | } 131 | }); 132 | }; 133 | /* Setup plugin defaults */ 134 | $.fn.actions.defaults = { 135 | actionContainer: "div.actions", 136 | counterContainer: "span.action-counter", 137 | allContainer: "div.actions span.all", 138 | acrossInput: "div.actions input.select-across", 139 | acrossQuestions: "div.actions span.question", 140 | acrossClears: "div.actions span.clear", 141 | allToggle: "#action-toggle", 142 | selectedClass: "selected" 143 | }; 144 | })(django.jQuery); 145 | -------------------------------------------------------------------------------- /abb/abb/static/admin/js/urlify.js: -------------------------------------------------------------------------------- 1 | var LATIN_MAP = { 2 | 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç': 3 | 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I', 4 | 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö': 5 | 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U', 6 | 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 7 | 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 8 | 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 9 | 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 10 | 'ú': 'u', 'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y' 11 | }; 12 | var LATIN_SYMBOLS_MAP = { 13 | '©':'(c)' 14 | }; 15 | var GREEK_MAP = { 16 | 'α':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'θ':'8', 17 | 'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p', 18 | 'ρ':'r', 'σ':'s', 'τ':'t', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w', 19 | 'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s', 20 | 'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i', 21 | 'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8', 22 | 'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P', 23 | 'Ρ':'R', 'Σ':'S', 'Τ':'T', 'Υ':'Y', 'Φ':'F', 'Χ':'X', 'Ψ':'PS', 'Ω':'W', 24 | 'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I', 25 | 'Ϋ':'Y' 26 | }; 27 | var TURKISH_MAP = { 28 | 'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U', 29 | 'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G' 30 | }; 31 | var RUSSIAN_MAP = { 32 | 'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'yo', 'ж':'zh', 33 | 'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o', 34 | 'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c', 35 | 'ч':'ch', 'ш':'sh', 'щ':'sh', 'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu', 36 | 'я':'ya', 37 | 'А':'A', 'Б':'B', 'В':'V', 'Г':'G', 'Д':'D', 'Е':'E', 'Ё':'Yo', 'Ж':'Zh', 38 | 'З':'Z', 'И':'I', 'Й':'J', 'К':'K', 'Л':'L', 'М':'M', 'Н':'N', 'О':'O', 39 | 'П':'P', 'Р':'R', 'С':'S', 'Т':'T', 'У':'U', 'Ф':'F', 'Х':'H', 'Ц':'C', 40 | 'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu', 41 | 'Я':'Ya' 42 | }; 43 | var UKRAINIAN_MAP = { 44 | 'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g' 45 | }; 46 | var CZECH_MAP = { 47 | 'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u', 48 | 'ž':'z', 'Č':'C', 'Ď':'D', 'Ě':'E', 'Ň': 'N', 'Ř':'R', 'Š':'S', 'Ť':'T', 49 | 'Ů':'U', 'Ž':'Z' 50 | }; 51 | var POLISH_MAP = { 52 | 'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ó':'o', 'ś':'s', 'ź':'z', 53 | 'ż':'z', 'Ą':'A', 'Ć':'C', 'Ę':'E', 'Ł':'L', 'Ń':'N', 'Ó':'O', 'Ś':'S', 54 | 'Ź':'Z', 'Ż':'Z' 55 | }; 56 | var LATVIAN_MAP = { 57 | 'ā':'a', 'č':'c', 'ē':'e', 'ģ':'g', 'ī':'i', 'ķ':'k', 'ļ':'l', 'ņ':'n', 58 | 'š':'s', 'ū':'u', 'ž':'z', 'Ā':'A', 'Č':'C', 'Ē':'E', 'Ģ':'G', 'Ī':'I', 59 | 'Ķ':'K', 'Ļ':'L', 'Ņ':'N', 'Š':'S', 'Ū':'U', 'Ž':'Z' 60 | }; 61 | var ARABIC_MAP = { 62 | 'أ':'a', 'ب':'b', 'ت':'t', 'ث': 'th', 'ج':'g', 'ح':'h', 'خ':'kh', 'د':'d', 63 | 'ذ':'th', 'ر':'r', 'ز':'z', 'س':'s', 'ش':'sh', 'ص':'s', 'ض':'d', 'ط':'t', 64 | 'ظ':'th', 'ع':'aa', 'غ':'gh', 'ف':'f', 'ق':'k', 'ك':'k', 'ل':'l', 'م':'m', 65 | 'ن':'n', 'ه':'h', 'و':'o', 'ي':'y' 66 | }; 67 | var LITHUANIAN_MAP = { 68 | 'ą':'a', 'č':'c', 'ę':'e', 'ė':'e', 'į':'i', 'š':'s', 'ų':'u', 'ū':'u', 69 | 'ž':'z', 70 | 'Ą':'A', 'Č':'C', 'Ę':'E', 'Ė':'E', 'Į':'I', 'Š':'S', 'Ų':'U', 'Ū':'U', 71 | 'Ž':'Z' 72 | }; 73 | var SERBIAN_MAP = { 74 | 'ђ':'dj', 'ј':'j', 'љ':'lj', 'њ':'nj', 'ћ':'c', 'џ':'dz', 'đ':'dj', 75 | 'Ђ':'Dj', 'Ј':'j', 'Љ':'Lj', 'Њ':'Nj', 'Ћ':'C', 'Џ':'Dz', 'Đ':'Dj' 76 | }; 77 | var AZERBAIJANI_MAP = { 78 | 'ç':'c', 'ə':'e', 'ğ':'g', 'ı':'i', 'ö':'o', 'ş':'s', 'ü':'u', 79 | 'Ç':'C', 'Ə':'E', 'Ğ':'G', 'İ':'I', 'Ö':'O', 'Ş':'S', 'Ü':'U' 80 | }; 81 | 82 | var ALL_DOWNCODE_MAPS = [ 83 | LATIN_MAP, 84 | LATIN_SYMBOLS_MAP, 85 | GREEK_MAP, 86 | TURKISH_MAP, 87 | RUSSIAN_MAP, 88 | UKRAINIAN_MAP, 89 | CZECH_MAP, 90 | POLISH_MAP, 91 | LATVIAN_MAP, 92 | ARABIC_MAP, 93 | LITHUANIAN_MAP, 94 | SERBIAN_MAP, 95 | AZERBAIJANI_MAP 96 | ]; 97 | 98 | var Downcoder = { 99 | 'Initialize': function() { 100 | if (Downcoder.map) { // already made 101 | return; 102 | } 103 | Downcoder.map = {}; 104 | Downcoder.chars = []; 105 | for (var i=0; ih1{text-align:left;color:#fff;font-size:4.2em;text-shadow:1px 1px 6px #000;padding:30px 50px;background-color:#03253e;background-color:rgba(0,0,0,.4)}.jumbotron .container-fluid>h3{color:#fff;font-size:40px;text-shadow:1px 1px 6px #000}@media (max-width:992px){.jumbotron{height:650px}.jumbotron .container-fluid{top:280px}.jumbotron .container-fluid>h1{font-size:4em;padding:20px}}@media (max-width:550px){.jumbotron{height:480px}.jumbotron .container-fluid{top:170px;padding:0}.jumbotron .container-fluid>h1{font-size:3em}}@media (max-width:360px){.jumbotron{height:400px}.jumbotron .container-fluid>h1{font-size:30px;line-height:1.2em;padding:20px}}@media (min-width:551px){.jumbotron .container-fluid{margin-left:-15px}}.jumbotron.header{height:100px;background-color:#c21}.jumbotron.header .container-fluid{position:absolute;top:0;padding:13px 50px;background-color:#03253e;background-color:rgba(0,0,0,.4);z-index:20}@media (max-width:550px){.jumbotron.header{height:60px}.jumbotron.header .container-fluid{padding:0 20px}.jumbotron.header .container-fluid>h3{font-size:2em}}.photo-credit{color:#fff;font-size:1em;text-shadow:1px 1px 2px #000;padding:17px 20px 15px 50px;background-color:rgba(0,0,0,.4)}.photo-credit i{vertical-align:middle}.photo-credit .icon-camera{font-size:30px;margin-right:10px}.photo-credit a{color:#fff;text-decoration:none}.photo-credit a:hover{color:#c21;text-decoration:none}@media (max-width:992px){.photo-credit{padding:17px 20px}}@media (max-width:550px){.photo-credit{font-size:.8em;line-height:1em;display:block;padding:10px 20px;margin-top:-10px}.photo-credit .icon-camera{font-size:20px}}.section{margin-top:40px;margin-bottom:40px}.section .small{line-height:1.6em}.mantra{background-image:url(../images/lightbulb.png);background-size:10%;background-position:90% 50%;background-repeat:no-repeat;padding-top:20px;padding-bottom:20px}@media (max-width:992px){.mantra{background:0 0}}.mantra h2{margin:0}@media (max-width:360px){.mantra h2{font-size:1.7em}}.mantra h2>strong{color:#c21}.mantra p{font-size:14px;padding-top:20px;margin:0}.blog h4{font-size:20px;font-weight:700}.blog h4>a{color:#c21;text-decoration:none}.blog h4>a:hover{color:#c21;text-decoration:underline}.blog .blog-entry{display:none;padding:10px 0}#blog-loading h4{text-align:center;padding:20px;color:#606060}#blog-loading .error{text-align:center;color:#c21;display:none}.blog-md{font-size:13px;font-weight:400;line-height:1.5em;padding-bottom:10px}.blog-md a{text-decoration:none;font-weight:700}.blog-md a:hover{text-decoration:underline}.blog-snippet{max-height:8em;overflow:hidden}.footer{border-top:5px solid #18f;background-color:#03253e;height:auto;color:#fff;padding-top:20px;padding-bottom:20px}.footer div{padding-top:10px;padding-bottom:10px}.footer img{max-width:100%;max-height:100px}.footer a{color:#fff;text-decoration:none}.footer a:hover{text-decoration:underline}.footer .tagline{float:right}@media (max-width:790px){.footer .tagline{float:none}}.responsive-container{position:relative;padding-bottom:56.25%;padding-top:30px;height:0;overflow:hidden}.responsive-container iframe{position:absolute;top:0;left:0;width:100%;height:100%}@media (max-width:992px){.wrap{margin-bottom:3em}}#slideshow{display:none}.slide{height:100%;background-size:cover;-moz-background-size:cover;background-position:center;position:absolute;left:0;top:0;width:100%}.slideshow-wrapper{overflow:hidden}.slideshow-wrapper .slide{z-index:1}.slideshow-wrapper .fadeOut{z-index:2}.fadeIn{display:none}.bio{margin:1em 0;position:relative}.bio strong{float:left;clear:both}.bio .img-circle{margin:1em auto;float:left;width:200px;height:200px}.bio br{clear:both}.bio h4{clear:both;margin:8px 0 2px}.bio .name{font-weight:700;font-size:15px}.bio .hover-img{position:absolute;left:15px;top:0;opacity:0}.bio a i,.no-decoration{text-decoration:none!important;color:#000!important}.bio a{text-decoration:none}.bio h4{color:#c21}@media (max-width:992px){.bio .img-circle{height:225px;width:225px}.bio .name{top:120px}}@media (max-width:550px){.bio .img-circle{height:120px;width:120px}.bio .name{top:100px}}@media (max-width:768px){.bio .no-decoration{font-size:2em}}@media (max-width:360px){.bio .img-circle{width:75px;height:75px}.bio .name{top:80px}.bio .no-decoration{font-size:1.5em}.bio.col-xs-6{min-height:145px}}a.btn{text-decoration:none}#preloader{position:absolute;left:-20000em;width:1px;height:1px;overflow:hidden}.hasPlaceholder{color:#777} -------------------------------------------------------------------------------- /abb/hours/static/styles/18f.min.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";@font-face{font-family:"18f";src:url(../fonts/18f-font.eot);src:url(../fonts/18f-font.eot?#iefix) format("embedded-opentype"),url(../fonts/18f-font.woff) format("woff"),url(../fonts/18f-font.ttf) format("truetype"),url(../fonts/18f-font.svg#untitled-font-1) format("svg");font-weight:400;font-style:normal}[data-icon]:before{font-family:"18f"!important;content:attr(data-icon);font-style:normal!important;font-weight:400!important;font-variant:normal!important;text-transform:none!important;speak:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}[class*=" icon-"]:before,[class^=icon-]:before{font-family:"18f"!important;font-style:normal!important;font-weight:400!important;font-variant:normal!important;text-transform:none!important;speak:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-lightbulb:before{content:"a"}.icon-github1:before{content:"b"}.icon-github2:before{content:"c"}.icon-github3:before{content:"d"}.icon-18f-logo:before{content:"e"}.icon-camera:before{content:"f"}.icon-twitter:before{content:"g"}.icon-spinner:before{content:"l"}.icon-email:before{content:"h"}.icon-lastfm:before{content:"i"}.icon-linkedin:before{content:"j"}.icon-anchor:before{content:"k"}body{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:300;line-height:1.8em}h1,h2,h3,h4,h5,h6{font-family:Raleway,'Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:600}a{color:#06d;text-decoration:underline}a:hover{color:#c21}.icon-spin{display:inline-block;-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.jumbotron{background-color:#03253e;padding:0;margin:0;height:720px;position:relative}#logo{height:150px;width:150px;position:absolute;top:50px;left:50px;z-index:20}@media (max-width:992px){#logo{height:100px;width:100px;top:20px;left:20px}}@media (max-width:360px){#logo{height:75px;width:75px}}.jumbotron .container-fluid{position:absolute;top:360px;max-width:860px;z-index:20}.jumbotron .container-fluid>h1{text-align:left;color:#fff;font-size:4.2em;text-shadow:1px 1px 6px #000;padding:30px 50px;background-color:#03253e;background-color:rgba(0,0,0,.4)}.jumbotron .container-fluid>h3{color:#fff;font-size:40px;text-shadow:1px 1px 6px #000}@media (max-width:992px){.jumbotron{height:650px}.jumbotron .container-fluid{top:280px}.jumbotron .container-fluid>h1{font-size:4em;padding:20px}}@media (max-width:550px){.jumbotron{height:480px}.jumbotron .container-fluid{top:170px;padding:0}.jumbotron .container-fluid>h1{font-size:3em}}@media (max-width:360px){.jumbotron{height:400px}.jumbotron .container-fluid>h1{font-size:30px;line-height:1.2em;padding:20px}}@media (min-width:551px){.jumbotron .container-fluid{margin-left:-15px}}.jumbotron.header{height:100px;background-color:#c21}.jumbotron.header .container-fluid{position:absolute;top:0;padding:13px 50px;background-color:#03253e;background-color:rgba(0,0,0,.4);z-index:20}@media (max-width:550px){.jumbotron.header{height:60px}.jumbotron.header .container-fluid{padding:0 20px}.jumbotron.header .container-fluid>h3{font-size:2em}}.photo-credit{color:#fff;font-size:1em;text-shadow:1px 1px 2px #000;padding:17px 20px 15px 50px;background-color:rgba(0,0,0,.4)}.photo-credit i{vertical-align:middle}.photo-credit .icon-camera{font-size:30px;margin-right:10px}.photo-credit a{color:#fff;text-decoration:none}.photo-credit a:hover{color:#c21;text-decoration:none}@media (max-width:992px){.photo-credit{padding:17px 20px}}@media (max-width:550px){.photo-credit{font-size:.8em;line-height:1em;display:block;padding:10px 20px;margin-top:-10px}.photo-credit .icon-camera{font-size:20px}}.section{margin-top:40px;margin-bottom:40px}.section .small{line-height:1.6em}.mantra{background-image:url(../images/lightbulb.png);background-size:10%;background-position:90% 50%;background-repeat:no-repeat;padding-top:20px;padding-bottom:20px}@media (max-width:992px){.mantra{background:0 0}}.mantra h2{margin:0}@media (max-width:360px){.mantra h2{font-size:1.7em}}.mantra h2>strong{color:#c21}.mantra p{font-size:14px;padding-top:20px;margin:0}.blog h4{font-size:20px;font-weight:700}.blog h4>a{color:#c21;text-decoration:none}.blog h4>a:hover{color:#c21;text-decoration:underline}.blog .blog-entry{display:none;padding:10px 0}#blog-loading h4{text-align:center;padding:20px;color:#606060}#blog-loading .error{text-align:center;color:#c21;display:none}.blog-md{font-size:13px;font-weight:400;line-height:1.5em;padding-bottom:10px}.blog-md a{text-decoration:none;font-weight:700}.blog-md a:hover{text-decoration:underline}.blog-snippet{max-height:8em;overflow:hidden}.footer{border-top:5px solid #18f;background-color:#03253e;height:auto;color:#fff;padding-top:20px;padding-bottom:20px}.footer div{padding-top:10px;padding-bottom:10px}.footer img{max-width:100%;max-height:100px}.footer a{color:#fff;text-decoration:none}.footer a:hover{text-decoration:underline}.footer .tagline{float:right}@media (max-width:790px){.footer .tagline{float:none}}.responsive-container{position:relative;padding-bottom:56.25%;padding-top:30px;height:0;overflow:hidden}.responsive-container iframe{position:absolute;top:0;left:0;width:100%;height:100%}@media (max-width:992px){.wrap{margin-bottom:3em}}#slideshow{display:none}.slide{height:100%;background-size:cover;-moz-background-size:cover;background-position:center;position:absolute;left:0;top:0;width:100%}.slideshow-wrapper{overflow:hidden}.slideshow-wrapper .slide{z-index:1}.slideshow-wrapper .fadeOut{z-index:2}.fadeIn{display:none}.bio{margin:1em 0;position:relative}.bio strong{float:left;clear:both}.bio .img-circle{margin:1em auto;float:left;width:200px;height:200px}.bio br{clear:both}.bio h4{clear:both;margin:8px 0 2px}.bio .name{font-weight:700;font-size:15px}.bio .hover-img{position:absolute;left:15px;top:0;opacity:0}.bio a i,.no-decoration{text-decoration:none!important;color:#000!important}.bio a{text-decoration:none}.bio h4{color:#c21}@media (max-width:992px){.bio .img-circle{height:225px;width:225px}.bio .name{top:120px}}@media (max-width:550px){.bio .img-circle{height:120px;width:120px}.bio .name{top:100px}}@media (max-width:768px){.bio .no-decoration{font-size:2em}}@media (max-width:360px){.bio .img-circle{width:75px;height:75px}.bio .name{top:80px}.bio .no-decoration{font-size:1.5em}.bio.col-xs-6{min-height:145px}}a.btn{text-decoration:none}#preloader{position:absolute;left:-20000em;width:1px;height:1px;overflow:hidden}.hasPlaceholder{color:#777} -------------------------------------------------------------------------------- /abb/abb/static/admin/css/changelists.css: -------------------------------------------------------------------------------- 1 | /* CHANGELISTS */ 2 | 3 | #changelist { 4 | position: relative; 5 | width: 100%; 6 | } 7 | 8 | #changelist table { 9 | width: 100%; 10 | } 11 | 12 | .change-list .hiddenfields { display:none; } 13 | 14 | .change-list .filtered table { 15 | border-right: 1px solid #ddd; 16 | } 17 | 18 | .change-list .filtered { 19 | min-height: 400px; 20 | } 21 | 22 | .change-list .filtered { 23 | background: white url(../img/changelist-bg.gif) top right repeat-y !important; 24 | } 25 | 26 | .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { 27 | margin-right: 160px !important; 28 | width: auto !important; 29 | } 30 | 31 | .change-list .filtered table tbody th { 32 | padding-right: 1em; 33 | } 34 | 35 | #changelist-form .results { 36 | overflow-x: auto; 37 | } 38 | 39 | #changelist .toplinks { 40 | border-bottom: 1px solid #ccc !important; 41 | } 42 | 43 | #changelist .paginator { 44 | color: #666; 45 | border-top: 1px solid #eee; 46 | border-bottom: 1px solid #eee; 47 | background: white url(../img/nav-bg.gif) 0 180% repeat-x; 48 | overflow: hidden; 49 | } 50 | 51 | .change-list .filtered .paginator { 52 | border-right: 1px solid #ddd; 53 | } 54 | 55 | /* CHANGELIST TABLES */ 56 | 57 | #changelist table thead th { 58 | padding: 0; 59 | white-space: nowrap; 60 | vertical-align: middle; 61 | } 62 | 63 | #changelist table thead th.action-checkbox-column { 64 | width: 1.5em; 65 | text-align: center; 66 | } 67 | 68 | #changelist table tbody td, #changelist table tbody th { 69 | border-left: 1px solid #ddd; 70 | } 71 | 72 | #changelist table tbody td:first-child, #changelist table tbody th:first-child { 73 | border-left: 0; 74 | border-right: 1px solid #ddd; 75 | } 76 | 77 | #changelist table tbody td.action-checkbox { 78 | text-align:center; 79 | } 80 | 81 | #changelist table tfoot { 82 | color: #666; 83 | } 84 | 85 | /* TOOLBAR */ 86 | 87 | #changelist #toolbar { 88 | padding: 3px; 89 | border-bottom: 1px solid #ddd; 90 | background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; 91 | color: #666; 92 | } 93 | 94 | #changelist #toolbar form input { 95 | font-size: 11px; 96 | padding: 1px 2px; 97 | } 98 | 99 | #changelist #toolbar form #searchbar { 100 | padding: 2px; 101 | } 102 | 103 | #changelist #changelist-search img { 104 | vertical-align: middle; 105 | } 106 | 107 | /* FILTER COLUMN */ 108 | 109 | #changelist-filter { 110 | position: absolute; 111 | top: 0; 112 | right: 0; 113 | z-index: 1000; 114 | width: 160px; 115 | border-left: 1px solid #ddd; 116 | background: #efefef; 117 | margin: 0; 118 | } 119 | 120 | #changelist-filter h2 { 121 | font-size: 11px; 122 | padding: 2px 5px; 123 | border-bottom: 1px solid #ddd; 124 | } 125 | 126 | #changelist-filter h3 { 127 | font-size: 12px; 128 | margin-bottom: 0; 129 | } 130 | 131 | #changelist-filter ul { 132 | padding-left: 0; 133 | margin-left: 10px; 134 | } 135 | 136 | #changelist-filter li { 137 | list-style-type: none; 138 | margin-left: 0; 139 | padding-left: 0; 140 | } 141 | 142 | #changelist-filter a { 143 | color: #999; 144 | } 145 | 146 | #changelist-filter a:hover { 147 | color: #036; 148 | } 149 | 150 | #changelist-filter li.selected { 151 | border-left: 5px solid #ccc; 152 | padding-left: 5px; 153 | margin-left: -10px; 154 | } 155 | 156 | #changelist-filter li.selected a { 157 | color: #5b80b2 !important; 158 | } 159 | 160 | /* DATE DRILLDOWN */ 161 | 162 | .change-list ul.toplinks { 163 | display: block; 164 | background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x; 165 | border-top: 1px solid white; 166 | float: left; 167 | padding: 0 !important; 168 | margin: 0 !important; 169 | width: 100%; 170 | } 171 | 172 | .change-list ul.toplinks li { 173 | padding: 3px 6px; 174 | font-weight: bold; 175 | list-style-type: none; 176 | display: inline-block; 177 | } 178 | 179 | .change-list ul.toplinks .date-back a { 180 | color: #999; 181 | } 182 | 183 | .change-list ul.toplinks .date-back a:hover { 184 | color: #036; 185 | } 186 | 187 | /* PAGINATOR */ 188 | 189 | .paginator { 190 | font-size: 11px; 191 | padding-top: 10px; 192 | padding-bottom: 10px; 193 | line-height: 22px; 194 | margin: 0; 195 | border-top: 1px solid #ddd; 196 | } 197 | 198 | .paginator a:link, .paginator a:visited { 199 | padding: 2px 6px; 200 | border: solid 1px #ccc; 201 | background: white; 202 | text-decoration: none; 203 | } 204 | 205 | .paginator a.showall { 206 | padding: 0 !important; 207 | border: none !important; 208 | } 209 | 210 | .paginator a.showall:hover { 211 | color: #036 !important; 212 | background: transparent !important; 213 | } 214 | 215 | .paginator .end { 216 | border-width: 2px !important; 217 | margin-right: 6px; 218 | } 219 | 220 | .paginator .this-page { 221 | padding: 2px 6px; 222 | font-weight: bold; 223 | font-size: 13px; 224 | vertical-align: top; 225 | } 226 | 227 | .paginator a:hover { 228 | color: white; 229 | background: #5b80b2; 230 | border-color: #036; 231 | } 232 | 233 | /* ACTIONS */ 234 | 235 | .filtered .actions { 236 | margin-right: 160px !important; 237 | border-right: 1px solid #ddd; 238 | } 239 | 240 | #changelist table input { 241 | margin: 0; 242 | } 243 | 244 | #changelist table tbody tr.selected { 245 | background-color: #FFFFCC; 246 | } 247 | 248 | #changelist .actions { 249 | color: #999; 250 | padding: 3px; 251 | border-top: 1px solid #fff; 252 | border-bottom: 1px solid #ddd; 253 | background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x; 254 | } 255 | 256 | #changelist .actions.selected { 257 | background: #fffccf; 258 | border-top: 1px solid #fffee8; 259 | border-bottom: 1px solid #edecd6; 260 | } 261 | 262 | #changelist .actions span.all, 263 | #changelist .actions span.action-counter, 264 | #changelist .actions span.clear, 265 | #changelist .actions span.question { 266 | font-size: 11px; 267 | margin: 0 0.5em; 268 | display: none; 269 | } 270 | 271 | #changelist .actions:last-child { 272 | border-bottom: none; 273 | } 274 | 275 | #changelist .actions select { 276 | border: 1px solid #aaa; 277 | margin-left: 0.5em; 278 | padding: 1px 2px; 279 | } 280 | 281 | #changelist .actions label { 282 | font-size: 11px; 283 | margin-left: 0.5em; 284 | } 285 | 286 | #changelist #action-toggle { 287 | display: none; 288 | } 289 | 290 | #changelist .actions .button { 291 | font-size: 11px; 292 | padding: 1px 2px; 293 | } 294 | -------------------------------------------------------------------------------- /abb/hours/templates/base.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 79 | 80 | 81 |
    82 |
    83 |
    84 |
    85 | {% block content %} 86 | {% endblock %} 87 |
    88 |
    89 |
    90 | 91 | 92 | 93 | 96 | {% block extra_js %} 97 | {% endblock %} 98 | 99 | -------------------------------------------------------------------------------- /abb/abb/static/admin/css/forms.css: -------------------------------------------------------------------------------- 1 | @import url('widgets.css'); 2 | 3 | /* FORM ROWS */ 4 | 5 | .form-row { 6 | overflow: hidden; 7 | padding: 8px 12px; 8 | font-size: 11px; 9 | border-bottom: 1px solid #eee; 10 | } 11 | 12 | .form-row img, .form-row input { 13 | vertical-align: middle; 14 | } 15 | 16 | form .form-row p { 17 | padding-left: 0; 18 | font-size: 11px; 19 | } 20 | 21 | .hidden { 22 | display: none; 23 | } 24 | 25 | /* FORM LABELS */ 26 | 27 | form h4 { 28 | margin: 0 !important; 29 | padding: 0 !important; 30 | border: none !important; 31 | } 32 | 33 | label { 34 | font-weight: normal !important; 35 | color: #666; 36 | font-size: 12px; 37 | } 38 | 39 | .required label, label.required { 40 | font-weight: bold !important; 41 | color: #333 !important; 42 | } 43 | 44 | /* RADIO BUTTONS */ 45 | 46 | form ul.radiolist li { 47 | list-style-type: none; 48 | } 49 | 50 | form ul.radiolist label { 51 | float: none; 52 | display: inline; 53 | } 54 | 55 | form ul.inline { 56 | margin-left: 0; 57 | padding: 0; 58 | } 59 | 60 | form ul.inline li { 61 | float: left; 62 | padding-right: 7px; 63 | } 64 | 65 | /* ALIGNED FIELDSETS */ 66 | 67 | .aligned label { 68 | display: block; 69 | padding: 3px 10px 0 0; 70 | float: left; 71 | width: 8em; 72 | word-wrap: break-word; 73 | } 74 | 75 | .aligned ul label { 76 | display: inline; 77 | float: none; 78 | width: auto; 79 | } 80 | 81 | .colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { 82 | width: 350px; 83 | } 84 | 85 | form .aligned p, form .aligned ul { 86 | margin-left: 7em; 87 | padding-left: 30px; 88 | } 89 | 90 | form .aligned table p { 91 | margin-left: 0; 92 | padding-left: 0; 93 | } 94 | 95 | form .aligned p.help { 96 | padding-left: 38px; 97 | } 98 | 99 | .aligned .vCheckboxLabel { 100 | float: none !important; 101 | display: inline; 102 | padding-left: 4px; 103 | } 104 | 105 | .colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { 106 | width: 610px; 107 | } 108 | 109 | .checkbox-row p.help { 110 | margin-left: 0; 111 | padding-left: 0 !important; 112 | } 113 | 114 | fieldset .field-box { 115 | float: left; 116 | margin-right: 20px; 117 | } 118 | 119 | /* WIDE FIELDSETS */ 120 | 121 | .wide label { 122 | width: 15em !important; 123 | } 124 | 125 | form .wide p { 126 | margin-left: 15em; 127 | } 128 | 129 | form .wide p.help { 130 | padding-left: 38px; 131 | } 132 | 133 | .colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { 134 | width: 450px; 135 | } 136 | 137 | /* COLLAPSED FIELDSETS */ 138 | 139 | fieldset.collapsed * { 140 | display: none; 141 | } 142 | 143 | fieldset.collapsed h2, fieldset.collapsed { 144 | display: block !important; 145 | } 146 | 147 | fieldset.collapsed h2 { 148 | background-image: url(../img/nav-bg.gif); 149 | background-position: bottom left; 150 | color: #999; 151 | } 152 | 153 | fieldset.collapsed .collapse-toggle { 154 | background: transparent; 155 | display: inline !important; 156 | } 157 | 158 | /* MONOSPACE TEXTAREAS */ 159 | 160 | fieldset.monospace textarea { 161 | font-family: "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace; 162 | } 163 | 164 | /* SUBMIT ROW */ 165 | 166 | .submit-row { 167 | padding: 5px 7px; 168 | text-align: right; 169 | background: white url(../img/nav-bg.gif) 0 100% repeat-x; 170 | border: 1px solid #ccc; 171 | margin: 5px 0; 172 | overflow: hidden; 173 | } 174 | 175 | body.popup .submit-row { 176 | overflow: auto; 177 | } 178 | 179 | .submit-row input { 180 | margin: 0 0 0 5px; 181 | } 182 | 183 | .submit-row p { 184 | margin: 0.3em; 185 | } 186 | 187 | .submit-row p.deletelink-box { 188 | float: left; 189 | } 190 | 191 | .submit-row .deletelink { 192 | background: url(../img/icon_deletelink.gif) 0 50% no-repeat; 193 | padding-left: 14px; 194 | } 195 | 196 | /* CUSTOM FORM FIELDS */ 197 | 198 | .vSelectMultipleField { 199 | vertical-align: top !important; 200 | } 201 | 202 | .vCheckboxField { 203 | border: none; 204 | } 205 | 206 | .vDateField, .vTimeField { 207 | margin-right: 2px; 208 | } 209 | 210 | .vDateField { 211 | min-width: 6.85em; 212 | } 213 | 214 | .vTimeField { 215 | min-width: 4.7em; 216 | } 217 | 218 | .vURLField { 219 | width: 30em; 220 | } 221 | 222 | .vLargeTextField, .vXMLLargeTextField { 223 | width: 48em; 224 | } 225 | 226 | .flatpages-flatpage #id_content { 227 | height: 40.2em; 228 | } 229 | 230 | .module table .vPositiveSmallIntegerField { 231 | width: 2.2em; 232 | } 233 | 234 | .vTextField { 235 | width: 20em; 236 | } 237 | 238 | .vIntegerField { 239 | width: 5em; 240 | } 241 | 242 | .vBigIntegerField { 243 | width: 10em; 244 | } 245 | 246 | .vForeignKeyRawIdAdminField { 247 | width: 5em; 248 | } 249 | 250 | /* INLINES */ 251 | 252 | .inline-group { 253 | padding: 0; 254 | border: 1px solid #ccc; 255 | margin: 10px 0; 256 | } 257 | 258 | .inline-group .aligned label { 259 | width: 8em; 260 | } 261 | 262 | .inline-related { 263 | position: relative; 264 | } 265 | 266 | .inline-related h3 { 267 | margin: 0; 268 | color: #666; 269 | padding: 3px 5px; 270 | font-size: 11px; 271 | background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; 272 | border-bottom: 1px solid #ddd; 273 | } 274 | 275 | .inline-related h3 span.delete { 276 | float: right; 277 | } 278 | 279 | .inline-related h3 span.delete label { 280 | margin-left: 2px; 281 | font-size: 11px; 282 | } 283 | 284 | .inline-related fieldset { 285 | margin: 0; 286 | background: #fff; 287 | border: none; 288 | width: 100%; 289 | } 290 | 291 | .inline-related fieldset.module h3 { 292 | margin: 0; 293 | padding: 2px 5px 3px 5px; 294 | font-size: 11px; 295 | text-align: left; 296 | font-weight: bold; 297 | background: #bcd; 298 | color: #fff; 299 | } 300 | 301 | .inline-group .tabular fieldset.module { 302 | border: none; 303 | border-bottom: 1px solid #ddd; 304 | } 305 | 306 | .inline-related.tabular fieldset.module table { 307 | width: 100%; 308 | } 309 | 310 | .last-related fieldset { 311 | border: none; 312 | } 313 | 314 | .inline-group .tabular tr.has_original td { 315 | padding-top: 2em; 316 | } 317 | 318 | .inline-group .tabular tr td.original { 319 | padding: 2px 0 0 0; 320 | width: 0; 321 | _position: relative; 322 | } 323 | 324 | .inline-group .tabular th.original { 325 | width: 0px; 326 | padding: 0; 327 | } 328 | 329 | .inline-group .tabular td.original p { 330 | position: absolute; 331 | left: 0; 332 | height: 1.1em; 333 | padding: 2px 7px; 334 | overflow: hidden; 335 | font-size: 9px; 336 | font-weight: bold; 337 | color: #666; 338 | _width: 700px; 339 | } 340 | 341 | .inline-group ul.tools { 342 | padding: 0; 343 | margin: 0; 344 | list-style: none; 345 | } 346 | 347 | .inline-group ul.tools li { 348 | display: inline; 349 | padding: 0 5px; 350 | } 351 | 352 | .inline-group div.add-row, 353 | .inline-group .tabular tr.add-row td { 354 | color: #666; 355 | padding: 3px 5px; 356 | border-bottom: 1px solid #ddd; 357 | background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; 358 | } 359 | 360 | .inline-group .tabular tr.add-row td { 361 | padding: 4px 5px 3px; 362 | border-bottom: none; 363 | } 364 | 365 | .inline-group ul.tools a.add, 366 | .inline-group div.add-row a, 367 | .inline-group .tabular tr.add-row td a { 368 | background: url(../img/icon_addlink.gif) 0 50% no-repeat; 369 | padding-left: 14px; 370 | font-size: 11px; 371 | outline: 0; /* Remove dotted border around link */ 372 | } 373 | 374 | .empty-form { 375 | display: none; 376 | } 377 | -------------------------------------------------------------------------------- /abb/abb/static/admin/js/core.js: -------------------------------------------------------------------------------- 1 | // Core javascript helper functions 2 | 3 | // basic browser identification & version 4 | var isOpera = (navigator.userAgent.indexOf("Opera")>=0) && parseFloat(navigator.appVersion); 5 | var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]); 6 | 7 | // Cross-browser event handlers. 8 | function addEvent(obj, evType, fn) { 9 | if (obj.addEventListener) { 10 | obj.addEventListener(evType, fn, false); 11 | return true; 12 | } else if (obj.attachEvent) { 13 | var r = obj.attachEvent("on" + evType, fn); 14 | return r; 15 | } else { 16 | return false; 17 | } 18 | } 19 | 20 | function removeEvent(obj, evType, fn) { 21 | if (obj.removeEventListener) { 22 | obj.removeEventListener(evType, fn, false); 23 | return true; 24 | } else if (obj.detachEvent) { 25 | obj.detachEvent("on" + evType, fn); 26 | return true; 27 | } else { 28 | return false; 29 | } 30 | } 31 | 32 | function cancelEventPropagation(e) { 33 | if (!e) e = window.event; 34 | e.cancelBubble = true; 35 | if (e.stopPropagation) e.stopPropagation(); 36 | } 37 | 38 | // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]); 39 | function quickElement() { 40 | var obj = document.createElement(arguments[0]); 41 | if (arguments[2]) { 42 | var textNode = document.createTextNode(arguments[2]); 43 | obj.appendChild(textNode); 44 | } 45 | var len = arguments.length; 46 | for (var i = 3; i < len; i += 2) { 47 | obj.setAttribute(arguments[i], arguments[i+1]); 48 | } 49 | arguments[1].appendChild(obj); 50 | return obj; 51 | } 52 | 53 | // "a" is reference to an object 54 | function removeChildren(a) { 55 | while (a.hasChildNodes()) a.removeChild(a.lastChild); 56 | } 57 | 58 | // ---------------------------------------------------------------------------- 59 | // Cross-browser xmlhttp object 60 | // from http://jibbering.com/2002/4/httprequest.html 61 | // ---------------------------------------------------------------------------- 62 | var xmlhttp; 63 | /*@cc_on @*/ 64 | /*@if (@_jscript_version >= 5) 65 | try { 66 | xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); 67 | } catch (e) { 68 | try { 69 | xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 70 | } catch (E) { 71 | xmlhttp = false; 72 | } 73 | } 74 | @else 75 | xmlhttp = false; 76 | @end @*/ 77 | if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { 78 | xmlhttp = new XMLHttpRequest(); 79 | } 80 | 81 | // ---------------------------------------------------------------------------- 82 | // Find-position functions by PPK 83 | // See http://www.quirksmode.org/js/findpos.html 84 | // ---------------------------------------------------------------------------- 85 | function findPosX(obj) { 86 | var curleft = 0; 87 | if (obj.offsetParent) { 88 | while (obj.offsetParent) { 89 | curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft); 90 | obj = obj.offsetParent; 91 | } 92 | // IE offsetParent does not include the top-level 93 | if (isIE && obj.parentElement){ 94 | curleft += obj.offsetLeft - obj.scrollLeft; 95 | } 96 | } else if (obj.x) { 97 | curleft += obj.x; 98 | } 99 | return curleft; 100 | } 101 | 102 | function findPosY(obj) { 103 | var curtop = 0; 104 | if (obj.offsetParent) { 105 | while (obj.offsetParent) { 106 | curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop); 107 | obj = obj.offsetParent; 108 | } 109 | // IE offsetParent does not include the top-level 110 | if (isIE && obj.parentElement){ 111 | curtop += obj.offsetTop - obj.scrollTop; 112 | } 113 | } else if (obj.y) { 114 | curtop += obj.y; 115 | } 116 | return curtop; 117 | } 118 | 119 | //----------------------------------------------------------------------------- 120 | // Date object extensions 121 | // ---------------------------------------------------------------------------- 122 | 123 | Date.prototype.getTwelveHours = function() { 124 | hours = this.getHours(); 125 | if (hours == 0) { 126 | return 12; 127 | } 128 | else { 129 | return hours <= 12 ? hours : hours-12 130 | } 131 | } 132 | 133 | Date.prototype.getTwoDigitMonth = function() { 134 | return (this.getMonth() < 9) ? '0' + (this.getMonth()+1) : (this.getMonth()+1); 135 | } 136 | 137 | Date.prototype.getTwoDigitDate = function() { 138 | return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate(); 139 | } 140 | 141 | Date.prototype.getTwoDigitTwelveHour = function() { 142 | return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours(); 143 | } 144 | 145 | Date.prototype.getTwoDigitHour = function() { 146 | return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours(); 147 | } 148 | 149 | Date.prototype.getTwoDigitMinute = function() { 150 | return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes(); 151 | } 152 | 153 | Date.prototype.getTwoDigitSecond = function() { 154 | return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds(); 155 | } 156 | 157 | Date.prototype.getHourMinute = function() { 158 | return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute(); 159 | } 160 | 161 | Date.prototype.getHourMinuteSecond = function() { 162 | return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond(); 163 | } 164 | 165 | Date.prototype.strftime = function(format) { 166 | var fields = { 167 | c: this.toString(), 168 | d: this.getTwoDigitDate(), 169 | H: this.getTwoDigitHour(), 170 | I: this.getTwoDigitTwelveHour(), 171 | m: this.getTwoDigitMonth(), 172 | M: this.getTwoDigitMinute(), 173 | p: (this.getHours() >= 12) ? 'PM' : 'AM', 174 | S: this.getTwoDigitSecond(), 175 | w: '0' + this.getDay(), 176 | x: this.toLocaleDateString(), 177 | X: this.toLocaleTimeString(), 178 | y: ('' + this.getFullYear()).substr(2, 4), 179 | Y: '' + this.getFullYear(), 180 | '%' : '%' 181 | }; 182 | var result = '', i = 0; 183 | while (i < format.length) { 184 | if (format.charAt(i) === '%') { 185 | result = result + fields[format.charAt(i + 1)]; 186 | ++i; 187 | } 188 | else { 189 | result = result + format.charAt(i); 190 | } 191 | ++i; 192 | } 193 | return result; 194 | } 195 | 196 | // ---------------------------------------------------------------------------- 197 | // String object extensions 198 | // ---------------------------------------------------------------------------- 199 | String.prototype.pad_left = function(pad_length, pad_string) { 200 | var new_string = this; 201 | for (var i = 0; new_string.length < pad_length; i++) { 202 | new_string = pad_string + new_string; 203 | } 204 | return new_string; 205 | } 206 | 207 | // ---------------------------------------------------------------------------- 208 | // Get the computed style for and element 209 | // ---------------------------------------------------------------------------- 210 | function getStyle(oElm, strCssRule){ 211 | var strValue = ""; 212 | if(document.defaultView && document.defaultView.getComputedStyle){ 213 | strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); 214 | } 215 | else if(oElm.currentStyle){ 216 | strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){ 217 | return p1.toUpperCase(); 218 | }); 219 | strValue = oElm.currentStyle[strCssRule]; 220 | } 221 | return strValue; 222 | } 223 | -------------------------------------------------------------------------------- /abb/abb/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 77 | 78 | 79 |
    80 |
    81 |
    82 |
    83 |

    This is your very own site, YOUR_CONFIGURED_MICROSITE_NAME_HERE

    84 |

    YOUR_CONFIGURED_MICROSITE_NAME_HERE IS COOL! 85 | However, the time has come to replace this text with something 86 | more appropriate.

    87 |

    This is a second paragraph, which should also be replaced.

    88 |

    This is a third paragraph, which should also be 89 | replaced.

    90 |
    91 |
    92 |
    93 | 97 |
    98 |

    Follow us here:

    99 |

    100 | Twitter @18F
    101 | GitHub / 18F
    102 |

    103 |
    104 |
    105 |
    106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /abb/hours/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 77 | 78 | 79 |
    80 |
    81 |
    82 |
    83 |

    This is your very own site, YOUR_CONFIGURED_MICROSITE_NAME_HERE

    84 |

    YOUR_CONFIGURED_MICROSITE_NAME_HERE IS COOL! 85 | However, the time has come to replace this text with something 86 | more appropriate.

    87 |

    This is a second paragraph, which should also be replaced.

    88 |

    This is a third paragraph, which should also be 89 | replaced.

    90 |
    91 |
    92 |
    93 | 97 |
    98 |

    Follow us here:

    99 |

    100 | Twitter @18F
    101 | GitHub / 18F
    102 |

    103 |
    104 |
    105 |
    106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /abb/abb/static/styles/18f.css: -------------------------------------------------------------------------------- 1 | .jumbotron { 2 | background-color: #03253e; 3 | padding: 0; 4 | margin: 0; 5 | height: 720px; 6 | position: relative; 7 | } 8 | #logo { 9 | height: 150px; 10 | width: 150px; 11 | position: absolute; 12 | top: 50px; 13 | left: 50px; 14 | z-index: 20; 15 | } 16 | @media (max-width: 992px) { 17 | #logo { 18 | height: 100px; 19 | width: 100px; 20 | top: 20px; 21 | left: 20px; 22 | } 23 | } 24 | @media (max-width: 360px) { 25 | #logo { 26 | height: 75px; 27 | width: 75px; 28 | } 29 | } 30 | .jumbotron .container-fluid { 31 | position: absolute; 32 | top: 360px; 33 | max-width: 860px; 34 | z-index: 20; 35 | } 36 | .jumbotron .container-fluid > h1 { 37 | text-align: left; 38 | color: #fff; 39 | font-size: 4.2em; 40 | text-shadow: 1px 1px 6px #000; 41 | padding: 30px 50px; 42 | background-color: #03253e; /* For browsers that don't support opacity */ 43 | background-color: rgba(0,0,0,.4); 44 | } 45 | .jumbotron .container-fluid > h3 { 46 | color: #fff; 47 | font-size: 40px; 48 | text-shadow: 1px 1px 6px #000; 49 | } 50 | @media (max-width: 992px) { 51 | .jumbotron { 52 | height: 650px; 53 | } 54 | .jumbotron .container-fluid { 55 | top:280px; 56 | } 57 | .jumbotron .container-fluid > h1 { 58 | font-size: 4em; 59 | padding:20px; 60 | } 61 | } 62 | @media (max-width: 550px) { 63 | .jumbotron { 64 | height: 480px; 65 | } 66 | .jumbotron .container-fluid { 67 | top: 170px; 68 | padding: 0; 69 | } 70 | .jumbotron .container-fluid > h1 { 71 | font-size: 3em; 72 | } 73 | } 74 | @media (max-width: 360px) { 75 | .jumbotron { 76 | height:400px; 77 | } 78 | .jumbotron .container-fluid > h1 { 79 | font-size: 30px; 80 | line-height: 1.2em; 81 | padding: 20px; 82 | } 83 | } 84 | @media (min-width:551px) { 85 | .jumbotron .container-fluid { 86 | margin-left: -15px; 87 | } 88 | } 89 | 90 | .jumbotron.header { 91 | height: 100px; 92 | background-color: #c21; 93 | } 94 | .jumbotron.header .container-fluid { 95 | position: absolute; 96 | top: 0px; 97 | padding: 13px 50px; 98 | background-color: #03253e; /* For browsers that don't support opacity */ 99 | background-color: rgba(0,0,0,.4); 100 | z-index: 20; 101 | } 102 | @media (max-width: 550px) { 103 | .jumbotron.header { 104 | height: 60px; 105 | } 106 | .jumbotron.header .container-fluid { 107 | padding: 0 20px; 108 | } 109 | .jumbotron.header .container-fluid > h3 { 110 | font-size:2em; 111 | } 112 | } 113 | 114 | .photo-credit { 115 | color:#fff; 116 | font-size: 1em; 117 | text-shadow: 1px 1px 2px #000; 118 | padding: 17px 20px 15px 50px; 119 | background-color: rgba(0,0,0,.4); 120 | } 121 | .photo-credit i { 122 | vertical-align: middle; 123 | } 124 | .photo-credit .icon-camera { 125 | font-size: 30px; 126 | margin-right:10px; 127 | } 128 | .photo-credit a { 129 | color:#fff; 130 | text-decoration:none; 131 | } 132 | .photo-credit a:hover { 133 | color:#c21; 134 | text-decoration:none; 135 | } 136 | @media (max-width: 992px) { 137 | .photo-credit { 138 | padding: 17px 20px; 139 | } 140 | } 141 | @media (max-width: 550px) { 142 | .photo-credit { 143 | font-size: .8em; 144 | line-height: 1em; 145 | display: block; 146 | padding: 10px 20px; 147 | margin-top: -10px; 148 | } 149 | .photo-credit .icon-camera { 150 | font-size: 20px; 151 | } 152 | } 153 | 154 | .section { 155 | margin-top:40px; 156 | margin-bottom:40px; 157 | } 158 | .section .small { 159 | line-height: 1.6em; 160 | } 161 | 162 | .mantra { 163 | background-image: url(../images/lightbulb.png); 164 | background-size: 10%; 165 | background-position: 90% 50%; 166 | background-repeat: no-repeat; 167 | padding-top: 20px; 168 | padding-bottom: 20px; 169 | } 170 | @media (max-width: 992px) { 171 | .mantra { 172 | background:none; 173 | } 174 | } 175 | .mantra h2 { 176 | margin:0; 177 | } 178 | @media (max-width: 360px) { 179 | .mantra h2 { 180 | font-size: 1.7em; 181 | } 182 | } 183 | .mantra h2 > strong { 184 | color: #c21;} 185 | .mantra p { 186 | font-size: 14px; 187 | padding-top:20px; 188 | margin:0; 189 | } 190 | 191 | .blog h4 { 192 | font-size: 20px; 193 | font-weight: 700; 194 | } 195 | .blog h4 > a { 196 | color:#c21; 197 | text-decoration: none; 198 | } 199 | .blog h4 > a:hover { 200 | color:#c21; 201 | text-decoration: underline; 202 | } 203 | 204 | .blog .blog-entry { 205 | display: none; 206 | padding: 10px 0; 207 | } 208 | 209 | #blog-loading h4 { 210 | text-align: center; 211 | padding: 20px; 212 | color: #606060; 213 | } 214 | #blog-loading .error { 215 | text-align: center; 216 | color: #c21; 217 | display: none; 218 | } 219 | 220 | .blog-md { 221 | font-size: 13px; 222 | font-weight: 400; 223 | line-height: 1.5em; 224 | padding-bottom: 10px; 225 | } 226 | .blog-md a { 227 | text-decoration: none; 228 | font-weight: 700; 229 | } 230 | .blog-md a:hover { 231 | text-decoration: underline; 232 | } 233 | .blog-snippet { 234 | max-height: 8em; 235 | overflow: hidden; 236 | } 237 | 238 | .footer { 239 | border-top: 5px solid #18f; 240 | background-color: #03253e; 241 | height: auto; 242 | color: #fff; 243 | padding-top: 20px; 244 | padding-bottom: 20px; 245 | } 246 | .footer div { 247 | padding-top: 10px; 248 | padding-bottom: 10px; 249 | } 250 | .footer img { 251 | max-width: 100%; 252 | max-height: 100px; 253 | } 254 | .footer a { 255 | color:#fff; 256 | text-decoration: none; 257 | } 258 | .footer a:hover { 259 | text-decoration: underline; 260 | } 261 | .footer .tagline { 262 | float: right; 263 | } 264 | @media (max-width: 790px) { 265 | .footer .tagline { 266 | float:none; 267 | } 268 | } 269 | 270 | /* 271 | RESPONSIVE EMBEDS 272 | */ 273 | .responsive-container { 274 | position: relative; 275 | padding-bottom: 56.25%; 276 | padding-top: 30px; 277 | height: 0; 278 | overflow: hidden; 279 | } 280 | .responsive-container iframe { 281 | position: absolute; 282 | top: 0; 283 | left: 0; 284 | width: 100%; 285 | height: 100%; 286 | } 287 | @media (max-width: 992px) { 288 | .wrap { 289 | margin-bottom: 3em; 290 | } 291 | } 292 | 293 | /* 294 | SLIDESHOW 295 | */ 296 | #slideshow { 297 | /* fade that fool in */ 298 | display: none; 299 | } 300 | .slide { 301 | height: 100%; 302 | background-size: cover; 303 | -moz-background-size: cover; /* Firefox 3.6 */ 304 | background-position: center; /* Internet Explorer 7/8 */ 305 | position: absolute; 306 | left: 0; 307 | top: 0; 308 | width: 100%; 309 | } 310 | .slideshow-wrapper { overflow: hidden; } 311 | .slideshow-wrapper .slide { z-index: 1; } 312 | .slideshow-wrapper .fadeOut { z-index: 2; } 313 | .fadeIn { display: none; } 314 | 315 | /* 316 | TEAM 317 | */ 318 | .bio { margin: 1.0em 0; position: relative; } 319 | .bio strong { float: left; clear: both; } 320 | .bio .img-circle { margin: 1.0em auto; float: left; width: 200px; height: 200px; } 321 | .bio br { clear: both; } 322 | .bio h4 { clear: both; margin: 8px 0 2px 0; } 323 | .bio .name { 324 | font-weight: 700; 325 | font-size: 15px; 326 | } 327 | .bio .hover-img { position: absolute; left: 15px; top: 0; opacity: 0; } 328 | .bio a i, .no-decoration { text-decoration: none !important; color: #000 !important; } 329 | .bio a { text-decoration: none; } 330 | .bio h4 { color: #c21;} 331 | @media (max-width: 992px) { 332 | .bio .img-circle { 333 | height: 225px; 334 | width: 225px; 335 | } 336 | .bio .name { 337 | top: 120px; 338 | } 339 | } 340 | @media (max-width: 550px) { 341 | .bio .img-circle { 342 | height: 120px; 343 | width: 120px; 344 | } 345 | .bio .name { 346 | top: 100px; 347 | } 348 | } 349 | @media (max-width: 768px) { 350 | .bio .no-decoration { 351 | font-size: 2.0em; 352 | } 353 | } 354 | @media (max-width: 360px) { 355 | .bio .img-circle { 356 | width: 75px; 357 | height: 75px; 358 | } 359 | .bio .name { 360 | top: 80px; 361 | } 362 | .bio .no-decoration { 363 | font-size: 1.5em; 364 | } 365 | .bio.col-xs-6 { 366 | min-height: 145px; 367 | } 368 | } 369 | a.btn { 370 | text-decoration: none; 371 | } 372 | 373 | #preloader { 374 | position: absolute; 375 | left: -20000em; 376 | width: 1px; 377 | height: 1px; 378 | overflow: hidden; 379 | } 380 | 381 | /* IE */ 382 | .hasPlaceholder {color: #777;} 383 | -------------------------------------------------------------------------------- /abb/hours/static/styles/18f.css: -------------------------------------------------------------------------------- 1 | .jumbotron { 2 | background-color: #03253e; 3 | padding: 0; 4 | margin: 0; 5 | height: 720px; 6 | position: relative; 7 | } 8 | #logo { 9 | height: 150px; 10 | width: 150px; 11 | position: absolute; 12 | top: 50px; 13 | left: 50px; 14 | z-index: 20; 15 | } 16 | @media (max-width: 992px) { 17 | #logo { 18 | height: 100px; 19 | width: 100px; 20 | top: 20px; 21 | left: 20px; 22 | } 23 | } 24 | @media (max-width: 360px) { 25 | #logo { 26 | height: 75px; 27 | width: 75px; 28 | } 29 | } 30 | .jumbotron .container-fluid { 31 | position: absolute; 32 | top: 360px; 33 | max-width: 860px; 34 | z-index: 20; 35 | } 36 | .jumbotron .container-fluid > h1 { 37 | text-align: left; 38 | color: #fff; 39 | font-size: 4.2em; 40 | text-shadow: 1px 1px 6px #000; 41 | padding: 30px 50px; 42 | background-color: #03253e; /* For browsers that don't support opacity */ 43 | background-color: rgba(0,0,0,.4); 44 | } 45 | .jumbotron .container-fluid > h3 { 46 | color: #fff; 47 | font-size: 40px; 48 | text-shadow: 1px 1px 6px #000; 49 | } 50 | @media (max-width: 992px) { 51 | .jumbotron { 52 | height: 650px; 53 | } 54 | .jumbotron .container-fluid { 55 | top:280px; 56 | } 57 | .jumbotron .container-fluid > h1 { 58 | font-size: 4em; 59 | padding:20px; 60 | } 61 | } 62 | @media (max-width: 550px) { 63 | .jumbotron { 64 | height: 480px; 65 | } 66 | .jumbotron .container-fluid { 67 | top: 170px; 68 | padding: 0; 69 | } 70 | .jumbotron .container-fluid > h1 { 71 | font-size: 3em; 72 | } 73 | } 74 | @media (max-width: 360px) { 75 | .jumbotron { 76 | height:400px; 77 | } 78 | .jumbotron .container-fluid > h1 { 79 | font-size: 30px; 80 | line-height: 1.2em; 81 | padding: 20px; 82 | } 83 | } 84 | @media (min-width:551px) { 85 | .jumbotron .container-fluid { 86 | margin-left: -15px; 87 | } 88 | } 89 | 90 | .jumbotron.header { 91 | height: 100px; 92 | background-color: #c21; 93 | } 94 | .jumbotron.header .container-fluid { 95 | position: absolute; 96 | top: 0px; 97 | padding: 13px 50px; 98 | background-color: #03253e; /* For browsers that don't support opacity */ 99 | background-color: rgba(0,0,0,.4); 100 | z-index: 20; 101 | } 102 | @media (max-width: 550px) { 103 | .jumbotron.header { 104 | height: 60px; 105 | } 106 | .jumbotron.header .container-fluid { 107 | padding: 0 20px; 108 | } 109 | .jumbotron.header .container-fluid > h3 { 110 | font-size:2em; 111 | } 112 | } 113 | 114 | .photo-credit { 115 | color:#fff; 116 | font-size: 1em; 117 | text-shadow: 1px 1px 2px #000; 118 | padding: 17px 20px 15px 50px; 119 | background-color: rgba(0,0,0,.4); 120 | } 121 | .photo-credit i { 122 | vertical-align: middle; 123 | } 124 | .photo-credit .icon-camera { 125 | font-size: 30px; 126 | margin-right:10px; 127 | } 128 | .photo-credit a { 129 | color:#fff; 130 | text-decoration:none; 131 | } 132 | .photo-credit a:hover { 133 | color:#c21; 134 | text-decoration:none; 135 | } 136 | @media (max-width: 992px) { 137 | .photo-credit { 138 | padding: 17px 20px; 139 | } 140 | } 141 | @media (max-width: 550px) { 142 | .photo-credit { 143 | font-size: .8em; 144 | line-height: 1em; 145 | display: block; 146 | padding: 10px 20px; 147 | margin-top: -10px; 148 | } 149 | .photo-credit .icon-camera { 150 | font-size: 20px; 151 | } 152 | } 153 | 154 | .section { 155 | margin-top:40px; 156 | margin-bottom:40px; 157 | } 158 | .section .small { 159 | line-height: 1.6em; 160 | } 161 | 162 | .mantra { 163 | background-image: url(../images/lightbulb.png); 164 | background-size: 10%; 165 | background-position: 90% 50%; 166 | background-repeat: no-repeat; 167 | padding-top: 20px; 168 | padding-bottom: 20px; 169 | } 170 | @media (max-width: 992px) { 171 | .mantra { 172 | background:none; 173 | } 174 | } 175 | .mantra h2 { 176 | margin:0; 177 | } 178 | @media (max-width: 360px) { 179 | .mantra h2 { 180 | font-size: 1.7em; 181 | } 182 | } 183 | .mantra h2 > strong { 184 | color: #c21;} 185 | .mantra p { 186 | font-size: 14px; 187 | padding-top:20px; 188 | margin:0; 189 | } 190 | 191 | .blog h4 { 192 | font-size: 20px; 193 | font-weight: 700; 194 | } 195 | .blog h4 > a { 196 | color:#c21; 197 | text-decoration: none; 198 | } 199 | .blog h4 > a:hover { 200 | color:#c21; 201 | text-decoration: underline; 202 | } 203 | 204 | .blog .blog-entry { 205 | display: none; 206 | padding: 10px 0; 207 | } 208 | 209 | #blog-loading h4 { 210 | text-align: center; 211 | padding: 20px; 212 | color: #606060; 213 | } 214 | #blog-loading .error { 215 | text-align: center; 216 | color: #c21; 217 | display: none; 218 | } 219 | 220 | .blog-md { 221 | font-size: 13px; 222 | font-weight: 400; 223 | line-height: 1.5em; 224 | padding-bottom: 10px; 225 | } 226 | .blog-md a { 227 | text-decoration: none; 228 | font-weight: 700; 229 | } 230 | .blog-md a:hover { 231 | text-decoration: underline; 232 | } 233 | .blog-snippet { 234 | max-height: 8em; 235 | overflow: hidden; 236 | } 237 | 238 | .footer { 239 | border-top: 5px solid #18f; 240 | background-color: #03253e; 241 | height: auto; 242 | color: #fff; 243 | padding-top: 20px; 244 | padding-bottom: 20px; 245 | } 246 | .footer div { 247 | padding-top: 10px; 248 | padding-bottom: 10px; 249 | } 250 | .footer img { 251 | max-width: 100%; 252 | max-height: 100px; 253 | } 254 | .footer a { 255 | color:#fff; 256 | text-decoration: none; 257 | } 258 | .footer a:hover { 259 | text-decoration: underline; 260 | } 261 | .footer .tagline { 262 | float: right; 263 | } 264 | @media (max-width: 790px) { 265 | .footer .tagline { 266 | float:none; 267 | } 268 | } 269 | 270 | /* 271 | RESPONSIVE EMBEDS 272 | */ 273 | .responsive-container { 274 | position: relative; 275 | padding-bottom: 56.25%; 276 | padding-top: 30px; 277 | height: 0; 278 | overflow: hidden; 279 | } 280 | .responsive-container iframe { 281 | position: absolute; 282 | top: 0; 283 | left: 0; 284 | width: 100%; 285 | height: 100%; 286 | } 287 | @media (max-width: 992px) { 288 | .wrap { 289 | margin-bottom: 3em; 290 | } 291 | } 292 | 293 | /* 294 | SLIDESHOW 295 | */ 296 | #slideshow { 297 | /* fade that fool in */ 298 | display: none; 299 | } 300 | .slide { 301 | height: 100%; 302 | background-size: cover; 303 | -moz-background-size: cover; /* Firefox 3.6 */ 304 | background-position: center; /* Internet Explorer 7/8 */ 305 | position: absolute; 306 | left: 0; 307 | top: 0; 308 | width: 100%; 309 | } 310 | .slideshow-wrapper { overflow: hidden; } 311 | .slideshow-wrapper .slide { z-index: 1; } 312 | .slideshow-wrapper .fadeOut { z-index: 2; } 313 | .fadeIn { display: none; } 314 | 315 | /* 316 | TEAM 317 | */ 318 | .bio { margin: 1.0em 0; position: relative; } 319 | .bio strong { float: left; clear: both; } 320 | .bio .img-circle { margin: 1.0em auto; float: left; width: 200px; height: 200px; } 321 | .bio br { clear: both; } 322 | .bio h4 { clear: both; margin: 8px 0 2px 0; } 323 | .bio .name { 324 | font-weight: 700; 325 | font-size: 15px; 326 | } 327 | .bio .hover-img { position: absolute; left: 15px; top: 0; opacity: 0; } 328 | .bio a i, .no-decoration { text-decoration: none !important; color: #000 !important; } 329 | .bio a { text-decoration: none; } 330 | .bio h4 { color: #c21;} 331 | @media (max-width: 992px) { 332 | .bio .img-circle { 333 | height: 225px; 334 | width: 225px; 335 | } 336 | .bio .name { 337 | top: 120px; 338 | } 339 | } 340 | @media (max-width: 550px) { 341 | .bio .img-circle { 342 | height: 120px; 343 | width: 120px; 344 | } 345 | .bio .name { 346 | top: 100px; 347 | } 348 | } 349 | @media (max-width: 768px) { 350 | .bio .no-decoration { 351 | font-size: 2.0em; 352 | } 353 | } 354 | @media (max-width: 360px) { 355 | .bio .img-circle { 356 | width: 75px; 357 | height: 75px; 358 | } 359 | .bio .name { 360 | top: 80px; 361 | } 362 | .bio .no-decoration { 363 | font-size: 1.5em; 364 | } 365 | .bio.col-xs-6 { 366 | min-height: 145px; 367 | } 368 | } 369 | a.btn { 370 | text-decoration: none; 371 | } 372 | 373 | #preloader { 374 | position: absolute; 375 | left: -20000em; 376 | width: 1px; 377 | height: 1px; 378 | overflow: hidden; 379 | } 380 | 381 | /* IE */ 382 | .hasPlaceholder {color: #777;} 383 | -------------------------------------------------------------------------------- /abb/abb/static/fonts/18f-font.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by Fontastic.me 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /abb/hours/static/fonts/18f-font.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by Fontastic.me 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /abb/abb/static/admin/js/SelectFilter2.js: -------------------------------------------------------------------------------- 1 | /* 2 | SelectFilter2 - Turns a multiple-select box into a filter interface. 3 | 4 | Requires core.js, SelectBox.js and addevent.js. 5 | */ 6 | (function($) { 7 | function findForm(node) { 8 | // returns the node of the form containing the given node 9 | if (node.tagName.toLowerCase() != 'form') { 10 | return findForm(node.parentNode); 11 | } 12 | return node; 13 | } 14 | 15 | window.SelectFilter = { 16 | init: function(field_id, field_name, is_stacked, admin_static_prefix) { 17 | if (field_id.match(/__prefix__/)){ 18 | // Don't initialize on empty forms. 19 | return; 20 | } 21 | var from_box = document.getElementById(field_id); 22 | from_box.id += '_from'; // change its ID 23 | from_box.className = 'filtered'; 24 | 25 | var ps = from_box.parentNode.getElementsByTagName('p'); 26 | for (var i=0; i, because it just gets in the way. 29 | from_box.parentNode.removeChild(ps[i]); 30 | } else if (ps[i].className.indexOf("help") != -1) { 31 | // Move help text up to the top so it isn't below the select 32 | // boxes or wrapped off on the side to the right of the add 33 | // button: 34 | from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild); 35 | } 36 | } 37 | 38 | //
    or
    39 | var selector_div = quickElement('div', from_box.parentNode); 40 | selector_div.className = is_stacked ? 'selector stacked' : 'selector'; 41 | 42 | //
    43 | var selector_available = quickElement('div', selector_div); 44 | selector_available.className = 'selector-available'; 45 | var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name])); 46 | quickElement('img', title_available, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of available %s. You may choose some by selecting them in the box below and then clicking the "Choose" arrow between the two boxes.'), [field_name])); 47 | 48 | var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); 49 | filter_p.className = 'selector-filter'; 50 | 51 | var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input"); 52 | 53 | var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_static_prefix + 'img/selector-search.gif', 'class', 'help-tooltip', 'alt', '', 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])); 54 | 55 | filter_p.appendChild(document.createTextNode(' ')); 56 | 57 | var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter")); 58 | filter_input.id = field_id + '_input'; 59 | 60 | selector_available.appendChild(from_box); 61 | var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_all_link'); 62 | choose_all.className = 'selector-chooseall'; 63 | 64 | //
      65 | var selector_chooser = quickElement('ul', selector_div); 66 | selector_chooser.className = 'selector-chooser'; 67 | var add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_link'); 68 | add_link.className = 'selector-add'; 69 | var remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_link'); 70 | remove_link.className = 'selector-remove'; 71 | 72 | //
      73 | var selector_chosen = quickElement('div', selector_div); 74 | selector_chosen.className = 'selector-chosen'; 75 | var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); 76 | quickElement('img', title_chosen, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of chosen %s. You may remove some by selecting them in the box below and then clicking the "Remove" arrow between the two boxes.'), [field_name])); 77 | 78 | var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name')); 79 | to_box.className = 'filtered'; 80 | var clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_all_link'); 81 | clear_all.className = 'selector-clearall'; 82 | 83 | from_box.setAttribute('name', from_box.getAttribute('name') + '_old'); 84 | 85 | // Set up the JavaScript event handlers for the select box filter interface 86 | addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); }); 87 | addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); }); 88 | addEvent(from_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); 89 | addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); 90 | addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); }); 91 | addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); }); 92 | addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); }); 93 | SelectBox.init(field_id + '_from'); 94 | SelectBox.init(field_id + '_to'); 95 | // Move selected from_box options to to_box 96 | SelectBox.move(field_id + '_from', field_id + '_to'); 97 | 98 | if (!is_stacked) { 99 | // In horizontal mode, give the same height to the two boxes. 100 | var j_from_box = $(from_box); 101 | var j_to_box = $(to_box); 102 | var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); } 103 | if (j_from_box.outerHeight() > 0) { 104 | resize_filters(); // This fieldset is already open. Resize now. 105 | } else { 106 | // This fieldset is probably collapsed. Wait for its 'show' event. 107 | j_to_box.closest('fieldset').one('show.fieldset', resize_filters); 108 | } 109 | } 110 | 111 | // Initial icon refresh 112 | SelectFilter.refresh_icons(field_id); 113 | }, 114 | refresh_icons: function(field_id) { 115 | var from = $('#' + field_id + '_from'); 116 | var to = $('#' + field_id + '_to'); 117 | var is_from_selected = from.find('option:selected').length > 0; 118 | var is_to_selected = to.find('option:selected').length > 0; 119 | // Active if at least one item is selected 120 | $('#' + field_id + '_add_link').toggleClass('active', is_from_selected); 121 | $('#' + field_id + '_remove_link').toggleClass('active', is_to_selected); 122 | // Active if the corresponding box isn't empty 123 | $('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0); 124 | $('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0); 125 | }, 126 | filter_key_up: function(event, field_id) { 127 | var from = document.getElementById(field_id + '_from'); 128 | // don't submit form if user pressed Enter 129 | if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) { 130 | from.selectedIndex = 0; 131 | SelectBox.move(field_id + '_from', field_id + '_to'); 132 | from.selectedIndex = 0; 133 | return false; 134 | } 135 | var temp = from.selectedIndex; 136 | SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value); 137 | from.selectedIndex = temp; 138 | return true; 139 | }, 140 | filter_key_down: function(event, field_id) { 141 | var from = document.getElementById(field_id + '_from'); 142 | // right arrow -- move across 143 | if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) { 144 | var old_index = from.selectedIndex; 145 | SelectBox.move(field_id + '_from', field_id + '_to'); 146 | from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index; 147 | return false; 148 | } 149 | // down arrow -- wrap around 150 | if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) { 151 | from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1; 152 | } 153 | // up arrow -- wrap around 154 | if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) { 155 | from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1; 156 | } 157 | return true; 158 | } 159 | } 160 | 161 | })(django.jQuery); 162 | --------------------------------------------------------------------------------