├── .about.yml
├── .gitignore
├── .jshintrc
├── .rspec
├── .ruby-version
├── .travis.yml
├── CONTRIBUTING.md
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── LICENSE.md
├── README.md
├── Rakefile
├── _config.yml
├── _config.yml.sample
├── _data
├── import-public.rb
├── partners.yml
├── project_filter.yml
├── projects.json.example
└── projects
│ ├── C2.yml
│ ├── all.json
│ ├── api-data-gov.yml
│ ├── betaFEC.yml
│ ├── calc.yml
│ ├── cloud.gov.yml
│ ├── collegescorecard.yml
│ ├── dap.yml
│ ├── dashboard.yml
│ ├── dataact.yml
│ ├── developer-program.yml
│ ├── discovery.yml
│ ├── ekip-api.yml
│ ├── fbopen.yml
│ ├── federalist.yml
│ ├── foia.yml
│ ├── myra.yml
│ ├── myusa.yml
│ ├── openopps.yml
│ ├── peacecorps-site.yml
│ ├── pulse.yml
│ ├── sbirez.yml
│ ├── uscis.yml
│ └── useiti-report.yml
├── _includes
├── ascii.html
├── dashboard-contact.html
├── footer.html
├── head.html
├── list-partners-preview.html
├── list-partners.html
├── project-code.html
├── project-links.html
├── projectlist.html
└── scripts.html
├── _layouts
├── bare.html
└── project.html
├── _plugins
├── build.rb
└── dashboard.rb
├── assets
├── _sass
│ ├── _custom.scss
│ ├── base
│ │ ├── _base.scss
│ │ ├── _buttons.scss
│ │ ├── _flashes.scss
│ │ ├── _forms.scss
│ │ ├── _grid-settings.scss
│ │ ├── _lists.scss
│ │ ├── _tables.scss
│ │ ├── _typography.scss
│ │ ├── _variables.scss
│ │ ├── extends
│ │ │ ├── _button.scss
│ │ │ ├── _clearfix.scss
│ │ │ └── _hide-text.scss
│ │ └── mixins
│ │ │ └── _flash.scss
│ ├── bourbon
│ │ ├── _bourbon-deprecated-upcoming.scss
│ │ ├── _bourbon.scss
│ │ ├── addons
│ │ │ ├── _button.scss
│ │ │ ├── _clearfix.scss
│ │ │ ├── _directional-values.scss
│ │ │ ├── _ellipsis.scss
│ │ │ ├── _font-family.scss
│ │ │ ├── _hide-text.scss
│ │ │ ├── _html5-input-types.scss
│ │ │ ├── _position.scss
│ │ │ ├── _prefixer.scss
│ │ │ ├── _retina-image.scss
│ │ │ ├── _size.scss
│ │ │ ├── _timing-functions.scss
│ │ │ ├── _triangle.scss
│ │ │ └── _word-wrap.scss
│ │ ├── css3
│ │ │ ├── _animation.scss
│ │ │ ├── _appearance.scss
│ │ │ ├── _backface-visibility.scss
│ │ │ ├── _background-image.scss
│ │ │ ├── _background.scss
│ │ │ ├── _border-image.scss
│ │ │ ├── _border-radius.scss
│ │ │ ├── _box-sizing.scss
│ │ │ ├── _calc.scss
│ │ │ ├── _columns.scss
│ │ │ ├── _filter.scss
│ │ │ ├── _flex-box.scss
│ │ │ ├── _font-face.scss
│ │ │ ├── _font-feature-settings.scss
│ │ │ ├── _hidpi-media-query.scss
│ │ │ ├── _hyphens.scss
│ │ │ ├── _image-rendering.scss
│ │ │ ├── _keyframes.scss
│ │ │ ├── _linear-gradient.scss
│ │ │ ├── _perspective.scss
│ │ │ ├── _placeholder.scss
│ │ │ ├── _radial-gradient.scss
│ │ │ ├── _transform.scss
│ │ │ ├── _transition.scss
│ │ │ └── _user-select.scss
│ │ ├── functions
│ │ │ ├── _assign.scss
│ │ │ ├── _color-lightness.scss
│ │ │ ├── _flex-grid.scss
│ │ │ ├── _golden-ratio.scss
│ │ │ ├── _grid-width.scss
│ │ │ ├── _modular-scale.scss
│ │ │ ├── _px-to-em.scss
│ │ │ ├── _px-to-rem.scss
│ │ │ ├── _strip-units.scss
│ │ │ ├── _tint-shade.scss
│ │ │ ├── _transition-property-name.scss
│ │ │ └── _unpack.scss
│ │ ├── helpers
│ │ │ ├── _convert-units.scss
│ │ │ ├── _gradient-positions-parser.scss
│ │ │ ├── _is-num.scss
│ │ │ ├── _linear-angle-parser.scss
│ │ │ ├── _linear-gradient-parser.scss
│ │ │ ├── _linear-positions-parser.scss
│ │ │ ├── _linear-side-corner-parser.scss
│ │ │ ├── _radial-arg-parser.scss
│ │ │ ├── _radial-gradient-parser.scss
│ │ │ ├── _radial-positions-parser.scss
│ │ │ ├── _render-gradients.scss
│ │ │ ├── _shape-size-stripper.scss
│ │ │ └── _str-to-num.scss
│ │ └── settings
│ │ │ ├── _asset-pipeline.scss
│ │ │ ├── _prefixer.scss
│ │ │ └── _px-to-em.scss
│ └── neat
│ │ ├── _neat-helpers.scss
│ │ ├── _neat.scss
│ │ ├── functions
│ │ ├── _new-breakpoint.scss
│ │ └── _private.scss
│ │ ├── grid
│ │ ├── _fill-parent.scss
│ │ ├── _grid.scss
│ │ ├── _media.scss
│ │ ├── _omega.scss
│ │ ├── _outer-container.scss
│ │ ├── _pad.scss
│ │ ├── _private.scss
│ │ ├── _reset.scss
│ │ ├── _row.scss
│ │ ├── _shift.scss
│ │ ├── _span-columns.scss
│ │ ├── _to-deprecate.scss
│ │ └── _visual-grid.scss
│ │ └── settings
│ │ ├── _grid.scss
│ │ └── _visual-grid.scss
├── css
│ ├── 18f.css
│ ├── fonts.css
│ ├── ie8
│ │ └── ie.css
│ ├── normalize.css
│ └── styles.scss
├── fonts
│ ├── 18f-font.eot
│ ├── 18f-font.svg
│ ├── 18f-font.ttf
│ └── 18f-font.woff
├── images
│ ├── 18f.png
│ ├── always-be-shipping_orange.png
│ ├── favicons
│ │ ├── 18f-center-114.png
│ │ ├── 18f-center-144.png
│ │ ├── 18f-center-16.png
│ │ ├── 18f-center-200.png
│ │ ├── 18f-center-32.png
│ │ ├── 18f-center-57.png
│ │ ├── 18f-center-72.png
│ │ ├── favicon.ico
│ │ └── favicon.png
│ ├── logo-18f.png
│ └── logo-gsa.png
└── js
│ ├── 18f.js
│ ├── federated-analytics.js
│ ├── html5shiv.js
│ ├── ie8
│ ├── html5shiv.js
│ └── respond.js
│ ├── jquery-2.1.1.min.js
│ ├── main.js
│ ├── preview-bundle.js
│ ├── preview.js
│ ├── respond.js
│ └── underscore.js
├── deploy
├── fabfile.py
├── hookshot.js
├── team-api-importer-config.json
├── team-api-importer-deploy.sh
├── team-api-importer-server.js
└── team-api-importer.js
├── favicon.png
├── go
├── gulpfile.js
├── index.html
├── package.json
├── pages
└── project
│ ├── doi-extractives-data.md
│ ├── fedspendingtransparency.md
│ ├── midas.md
│ ├── mirage.md
│ └── openfec.md
├── preview.html
├── spec
├── homepage_spec.rb
├── project_spec.rb
└── spec_helper.rb
├── stages.html
└── tests
├── team_api_importer_test.js
└── test.rb
/.about.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # .about.yml project metadata
3 | #
4 | # Short name that acts as the project identifier (required)
5 | name: dashboard
6 |
7 | # Full proper name of the project (required)
8 | full_name: Dashboard
9 |
10 | # The type of content in the repo
11 | # values: app, docs, policy
12 | type: app
13 |
14 | # Describes whether a project team, working group/guild, etc. owns the repo (required)
15 | # values: guild, working-group, project
16 | owner_type: project
17 |
18 | # Name of the main project repo if this is a sub-repo; name of the working group/guild repo if this is a working group/guild subproject
19 | #parent:
20 |
21 | # Maturity stage of the project (required)
22 | # values: discovery, alpha, beta, live
23 | stage: live
24 |
25 | # Whether or not the project is actively maintained (required)
26 | # values: active, deprecated
27 | status: active
28 |
29 | # Description of the project
30 | description: |
31 | A site to track our projects' status, to provide transparency and insight
32 | into 18F work and values.
33 |
34 | # Should be 'true' if the project has a continuous build (required)
35 | # values: true, false
36 | testable: true
37 |
38 | # Team members contributing to the project (required)
39 | # Items:
40 | # - github: GitHub user name
41 | # id: Internal team identifier/user name
42 | # role: Team member's role; leads should be designated as 'lead'
43 | team:
44 | - github: gboone
45 | role: lead
46 |
47 | # Partners for whom the project is developed
48 | partners:
49 | - 18F
50 |
51 | # Brief descriptions of significant project developments
52 | #milestones:
53 | #-
54 |
55 | # Technologies used to build the project
56 | stack:
57 | - Ruby
58 | - Jekyll
59 | - NodeJS
60 |
61 | # Brief description of the project's outcomes
62 | #impact:
63 |
64 | # Services used to supply project status information
65 | # Items:
66 | # - name: Name of the service
67 | # category: Type of the service
68 | # url: URL for detailed information
69 | # badge: URL for the status badge
70 | #services:
71 | #-
72 |
73 | # Licenses that apply to the project and/or its components (required)
74 | # Items by property name pattern:
75 | # .*:
76 | # name: Name of the license from the Software Package Data Exchange (SPDX): https://spdx.org/licenses/
77 | # url: URL for the text of the license
78 | licenses:
79 | dashboard:
80 | name: CC0-1.0
81 | url: https://github.com/18F/team_api/blob/master/LICENSE.md
82 |
83 | # Blogs or websites associated with project development
84 | #blog:
85 | #-
86 |
87 | # Links to project artifacts
88 | # Items:
89 | # - url: URL for the link
90 | # text: Anchor text for the link
91 | links:
92 | - url: https://18f.gsa.gov/dashboard/
93 | text: Live 18F Dashboard
94 |
95 | # Email addresses of points-of-contact
96 | contact:
97 | - url: mailto:gregory.boone@gsa.gov
98 | text: Greg Boone
99 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /_site
2 | .sass-cache
3 | .DS_Store
4 | *.log
5 | *.pyc
6 | _data/projects.json
7 | node_modules/
8 | assets/js/preview-bundle.js
9 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "asi": false,
3 | "bitwise": true,
4 | "browser": true,
5 | "camelcase": true,
6 | "curly": true,
7 | "forin": true,
8 | "immed": true,
9 | "latedef": "nofunc",
10 | "maxlen": 80,
11 | "newcap": true,
12 | "noarg": true,
13 | "noempty": true,
14 | "nonew": true,
15 | "predef": [
16 | "$",
17 | "jQuery",
18 |
19 | "jasmine",
20 | "beforeEach",
21 | "describe",
22 | "it",
23 |
24 | "angular",
25 | "inject",
26 | "module",
27 |
28 | "Promise"
29 | ],
30 | "quotmark": true,
31 | "trailing": true,
32 | "undef": true,
33 | "unused": true
34 | }
35 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --color
2 | --require spec_helper
3 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | 2.2.3
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 |
3 | language: ruby
4 | rvm:
5 | - 2.2.3
6 |
7 | before_install: npm install
8 |
9 | script: "./go ci_build"
10 |
11 | branches:
12 | only:
13 | - staging
14 | - production
15 |
16 | git:
17 | submodules: false
18 |
19 | notifications:
20 | email:
21 | recipients:
22 | - gregory.boone@gsa.gov
23 | on_success: change
24 | on_failure: change
25 |
26 | cache: bundler
27 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Running the site locally
2 |
3 | ```bash
4 | ./go init
5 | ./go serve
6 | open http://localhost:4000/dashboard/
7 | ```
8 |
9 | ## Making changes
10 |
11 | Please create a branch and submit changes as a pull request to the staging branch.
12 |
13 | ### Data
14 |
15 | To modify project information, see the instructions in [data-private](https://github.com/18F/data-private).
16 |
17 | ## Accepting/Merging Pull Requests
18 |
19 | Typically pull Requests should be merged by a different person who opened them, ensuring that at least one other person has eyes on it. If you see an open pull request that you agree with add a comment and :+1: -- a :+1: by itself merely indicates
20 | that you like the direction and think it is a good idea, if you have reviewed the code or text, please comment that you have done so. Unless it is a very small change or critical fix, pull requests should remain open for 24 hours to give everyone on the team a chance to chime in.
21 |
22 | When a pull request is merged to staging it is automatically deployed to: [https://staging.18f.gov/dashboard/](https://staging.18f.gov/dashboard/)
23 |
24 | Whoever merged the staging pull request, should look at staging and then if all looks good, open a pull request to production which anyone else on the team can merge.
25 |
26 | ## Public domain
27 |
28 | This project is in the public domain within the United States, and
29 | copyright and related rights in the work worldwide are waived through
30 | the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/).
31 |
32 | All contributions to this project will be released under the CC0
33 | dedication. By submitting a pull request, you are agreeing to comply
34 | with this waiver of copyright interest.
35 |
36 | Submit pull requests to the `staging` branch.
37 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:latest
2 | MAINTAINER "steven.harms@gsa.gov"
3 | EXPOSE 4000
4 | RUN locale-gen en_US.UTF-8
5 | ENV LANG en_US.UTF-8
6 | ENV LANGUAGE en_US:en
7 | ENV LC_ALL en_US.UTF-8
8 | RUN apt-get -y update && apt-get -y upgrade
9 | RUN apt-get install -y git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev build-essential
10 | RUN useradd -ms /bin/bash dashboard
11 | ADD . /home/dashboard/dashboard/
12 | RUN chown -R dashboard /home/dashboard
13 | USER dashboard
14 | WORKDIR /home/dashboard
15 | RUN git clone git://github.com/sstephenson/rbenv.git /home/dashboard/.rbenv
16 | RUN echo 'export PATH="$HOME/.rbenv/bin:$PATH"' | tee -a /home/dashboard/.bashrc /home/dashboard/.bash_profile
17 | RUN echo 'eval "$(rbenv init -)"' | tee -a /home/dashboard/.bashrc /home/dashboard/.bash_profile
18 | RUN git clone git://github.com/sstephenson/ruby-build.git /home/dashboard/.rbenv/plugins/ruby-build
19 | RUN echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' | tee -a /home/dashboard/.bashrc /home/dashboard/.bash_profile
20 | RUN git clone https://github.com/sstephenson/rbenv-gem-rehash.git ~/.rbenv/plugins/rbenv-gem-rehash
21 | RUN bash --login -c "/home/dashboard/.rbenv/bin/rbenv install 2.2.3"
22 | RUN bash --login -c "/home/dashboard/.rbenv/bin/rbenv global 2.2.3"
23 | RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.1/install.sh | bash
24 | RUN echo 'export NVM_DIR="$HOME/.nvm"' | tee -a $HOME/.bash_profile
25 | RUN echo '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"' | tee -a $HOME/.bash_profile
26 | RUN bash --login -c "nvm install 5.4.0 && nvm alias default 5.4.0"
27 | RUN bash --login -c "gem install bundle"
28 | RUN bash --login -c "cd /home/dashboard/dashboard && nvm use 5.4.0 && ./go init"
29 | RUN sed -i -e "s/^ exec_cmd 'bundle exec jekyll serve --trace'\$/ exec_cmd 'bundle exec jekyll serve -H 0.0.0.0 --trace'/" /home/dashboard/dashboard/go
30 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | ruby '2.2.3'
4 | gem 'jekyll-sitemap'
5 | gem 'jekyll', '3.0.1'
6 | gem 'hash-joiner'
7 | gem 'safe_yaml'
8 |
9 | group :tests do
10 | gem 'capybara'
11 | gem 'rspec'
12 | gem 'poltergeist'
13 | gem 'travis'
14 | end
15 |
16 | group :jekyll_plugins do
17 | gem 'jekyll-redirect-from', '~> 0.9'
18 | end
19 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | addressable (2.3.8)
5 | backports (3.6.7)
6 | capybara (2.4.4)
7 | mime-types (>= 1.16)
8 | nokogiri (>= 1.3.3)
9 | rack (>= 1.0.0)
10 | rack-test (>= 0.5.4)
11 | xpath (~> 2.0)
12 | cliver (0.3.2)
13 | coderay (1.1.0)
14 | colorator (0.1)
15 | diff-lcs (1.2.5)
16 | ethon (0.7.4)
17 | ffi (>= 1.3.0)
18 | faraday (0.9.2)
19 | multipart-post (>= 1.2, < 3)
20 | faraday_middleware (0.10.0)
21 | faraday (>= 0.7.4, < 0.10)
22 | ffi (1.9.10)
23 | gh (0.14.0)
24 | addressable
25 | backports
26 | faraday (~> 0.8)
27 | multi_json (~> 1.0)
28 | net-http-persistent (>= 2.7)
29 | net-http-pipeline
30 | hash-joiner (0.0.7)
31 | safe_yaml
32 | highline (1.7.8)
33 | jekyll (3.0.1)
34 | colorator (~> 0.1)
35 | jekyll-sass-converter (~> 1.0)
36 | jekyll-watch (~> 1.1)
37 | kramdown (~> 1.3)
38 | liquid (~> 3.0)
39 | mercenary (~> 0.3.3)
40 | rouge (~> 1.7)
41 | safe_yaml (~> 1.0)
42 | jekyll-redirect-from (0.9.0)
43 | jekyll (>= 2.0)
44 | jekyll-sass-converter (1.3.0)
45 | sass (~> 3.2)
46 | jekyll-sitemap (0.9.0)
47 | jekyll-watch (1.3.0)
48 | listen (~> 3.0)
49 | json (1.8.3)
50 | kramdown (1.9.0)
51 | launchy (2.4.3)
52 | addressable (~> 2.3)
53 | liquid (3.0.6)
54 | listen (3.0.5)
55 | rb-fsevent (>= 0.9.3)
56 | rb-inotify (>= 0.9)
57 | mercenary (0.3.5)
58 | method_source (0.8.2)
59 | mime-types (2.99)
60 | mini_portile2 (2.0.0)
61 | multi_json (1.11.2)
62 | multipart-post (2.0.0)
63 | net-http-persistent (2.9.4)
64 | net-http-pipeline (1.0.1)
65 | nokogiri (1.6.7)
66 | mini_portile2 (~> 2.0.0.rc2)
67 | poltergeist (1.8.1)
68 | capybara (~> 2.1)
69 | cliver (~> 0.3.1)
70 | multi_json (~> 1.0)
71 | websocket-driver (>= 0.2.0)
72 | pry (0.9.12.6)
73 | coderay (~> 1.0)
74 | method_source (~> 0.8)
75 | slop (~> 3.4)
76 | pusher-client (0.6.2)
77 | json
78 | websocket (~> 1.0)
79 | rack (1.6.4)
80 | rack-test (0.6.3)
81 | rack (>= 1.0)
82 | rb-fsevent (0.9.6)
83 | rb-inotify (0.9.5)
84 | ffi (>= 0.5.0)
85 | rouge (1.10.1)
86 | rspec (3.4.0)
87 | rspec-core (~> 3.4.0)
88 | rspec-expectations (~> 3.4.0)
89 | rspec-mocks (~> 3.4.0)
90 | rspec-core (3.4.1)
91 | rspec-support (~> 3.4.0)
92 | rspec-expectations (3.4.0)
93 | diff-lcs (>= 1.2.0, < 2.0)
94 | rspec-support (~> 3.4.0)
95 | rspec-mocks (3.4.0)
96 | diff-lcs (>= 1.2.0, < 2.0)
97 | rspec-support (~> 3.4.0)
98 | rspec-support (3.4.1)
99 | safe_yaml (1.0.4)
100 | sass (3.4.19)
101 | slop (3.6.0)
102 | travis (1.8.0)
103 | addressable (~> 2.3)
104 | backports
105 | faraday (~> 0.9)
106 | faraday_middleware (~> 0.9, >= 0.9.1)
107 | gh (~> 0.13)
108 | highline (~> 1.6)
109 | launchy (~> 2.1)
110 | pry (~> 0.9, < 0.10)
111 | pusher-client (~> 0.4)
112 | typhoeus (~> 0.6, >= 0.6.8)
113 | typhoeus (0.7.3)
114 | ethon (>= 0.7.4)
115 | websocket (1.2.2)
116 | websocket-driver (0.6.3)
117 | websocket-extensions (>= 0.1.0)
118 | websocket-extensions (0.1.2)
119 | xpath (2.0.0)
120 | nokogiri (~> 1.3)
121 |
122 | PLATFORMS
123 | ruby
124 |
125 | DEPENDENCIES
126 | capybara
127 | hash-joiner
128 | jekyll (= 3.0.1)
129 | jekyll-redirect-from (~> 0.9)
130 | jekyll-sitemap
131 | poltergeist
132 | rspec
133 | safe_yaml
134 | travis
135 |
136 | BUNDLED WITH
137 | 1.10.6
138 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rspec'
2 |
3 | RSpec::Core::RakeTask.new :spec do |t|
4 | end
5 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | markdown: kramdown
2 |
3 | title: 18F Digital Services Delivery
4 | description: "18F builds effective, user-centric digital services focused on the interaction between government and the people and businesses it serves."
5 |
6 | sass:
7 | sass_dir: assets/_sass
8 |
9 | destination: _site/dashboard
10 | baseurl: /dashboard
11 | #baseurl: localhost:4000
12 | exclude:
13 | - CONTRIBUTING.md
14 | - Gemfile
15 | - Gemfile.lock
16 | - LICENSE.md
17 | - README.md
18 | - deploy
19 | - go
20 | - gulpfile.js
21 | - node_modules
22 | - package.json
23 | - tests
24 | - vendor
25 | - assets/js/preview.js
26 |
27 | gems:
28 | - jekyll-redirect-from
29 | # To disable fetching from the Team API and to build from local data, remove this section
30 | team_api:
31 | #baseurl: http://localhost:4001/public/api/
32 | #suffix: api.json
33 | baseurl: https://team-api.18f.gov/public/api/
34 | host: team-api.18f.gov
35 |
--------------------------------------------------------------------------------
/_config.yml.sample:
--------------------------------------------------------------------------------
1 | markdown: kramdown
2 |
3 | title: 18F Digital Services Delivery
4 | description: "18F builds effective, user-centric digital services focused on the interaction between government and the people and businesses it serves."
5 |
6 | sass:
7 | sass_dir: assets/_sass
8 |
9 | destination: _site/dashboard
10 | baseurl: /dashboard
11 | #baseurl: localhost:4000
12 | exclude:
13 | - CONTRIBUTING.md
14 | - Gemfile
15 | - Gemfile.lock
16 | - LICENSE.md
17 | - README.md
18 | - deploy
19 | - go
20 | - gulpfile.js
21 | - node_modules
22 | - package.json
23 | - tests
24 | - vendor
25 |
26 | # If you would like to pull projects from an api, make sure your API is well structured to match the dashboard and has a `projects` endpoint. Then, use `baseurl` and `host` below with the relevan information about your API and run `./go update_data` This will overwrite your local `projects.json` file.
27 | team_api:
28 | #baseurl: http://localhost:4001/public/api/
29 | #suffix: api.json
30 |
--------------------------------------------------------------------------------
/_data/import-public.rb:
--------------------------------------------------------------------------------
1 | # Imports project data from the 18F Public Hub API.
2 | #
3 | # Author: Mike Bland (michael.bland@gsa.gov)
4 | # Date: 2014-12-22
5 | require 'json'
6 | require 'open-uri'
7 | require 'safe_yaml'
8 | require 'fileutils'
9 |
10 | def load_from_team_api(project)
11 | open(project) { |api_data|
12 | unless api_data.status[0] == "404"
13 | JSON.load(api_data.read)
14 | end
15 | }
16 | end
17 |
18 | def update_from_api(local, api_data)
19 | unless local == api_data
20 | local.merge(api_data)
21 | else
22 | local
23 | end
24 | end
25 |
26 | # merges the "all projects" hash with the hash sourced from a YAML file and
27 | # returns writes the new hash back to the file.
28 | def merge_local_with_api(filename)
29 | project = YAML.safe_load_file(filename)
30 | api_data = JSON.parse(open("_data/projects/all.json").read)
31 | unless project.nil?
32 | new_data = update_from_api(project, api_data[project['name']])
33 | end
34 | end
35 |
36 | def filter_dashboard_fields(project)
37 | filter = YAML.safe_load_file('_data/project_filter.yml')['fields']
38 | project.keep_if { |key, value|
39 | filter.include? key
40 | }
41 | end
42 |
43 | if File.exists?('_config.yml')
44 | config = YAML.safe_load_file('_config.yml')
45 | filter = YAML.safe_load_file('_data/project_filter.yml')['projects']
46 | PROJECT_DATA_URL = "#{config['team_api']['baseurl']}projects/"
47 |
48 | # Get a dump of all the projects in the Team API
49 | open(PROJECT_DATA_URL) do |projects|
50 | open(File.join('_data', 'projects', 'all.json'), 'w') do |f|
51 | f.write JSON.pretty_generate(
52 | JSON.parse(projects.read)['results'].map { |p| [p['name'], p] }.to_h)
53 | end
54 | end
55 |
56 | # Create a YML file for all the projects listed in the project_filter
57 | # if the file doesn't exist already, it is sourced 100% from the team_api,
58 | # if it does exist, merge it with the team api's data.
59 | filter.each do |d|
60 | filename = File.join('_data', 'projects', "#{d}.yml")
61 | if File.exists?(filename)
62 | project = merge_local_with_api(filename)
63 | else
64 | projects = JSON.parse(open("_data/projects/all.json").read)
65 | project = projects[d]
66 | end
67 | # Filter the project data against the fields we use on the Dashboard
68 | unless project.nil?
69 | clean_data = filter_dashboard_fields(project)
70 | File.open(filename, 'w') { |f| f.write YAML.dump(clean_data) }
71 | end
72 | end
73 |
74 | # If any of the files still contain errors, let us know about them.
75 | files = Dir.glob('_data/projects/*.yml')
76 | files.each do |file|
77 | yaml = YAML.safe_load_file(file)
78 | if yaml['errors']
79 | puts "There are errors in the #{yaml['name']} file."
80 | end
81 | end
82 | end
83 |
--------------------------------------------------------------------------------
/_data/partners.yml:
--------------------------------------------------------------------------------
1 | 18f:
2 | url: https://18f.gsa.gov
3 | full_name: 18F
4 | u-s-department-of-treasury:
5 | url: http://treasury.gov
6 | full_name: U.S. Department of Treasury
7 | gsa:
8 | url: http://gsa.gov
9 | full_name: General Services Administration
10 | acronym: GSA
11 | general-services-administration:
12 | url: http://gsa.gov
13 | department-of-education:
14 | url: http://ed.gov
15 | full_name: Department of Education
16 | acronym: ED
17 | federal-election-commission:
18 | url: http://fec.gov
19 | full_name: Federal Election Commission
20 | acronym: FEC
21 | air-force:
22 | url: http://af.mil
23 | full_name: United States Air Force
24 | acronym: USAF
25 | department-of-homeland-security:
26 | url: http://dhs.gov
27 | full_name: Department of Homeland Security
28 | acronym: DHS
29 | u-s-citizenship-and-immigration-services:
30 | url: http://uscis.gov
31 | full_name: U.S. Citizenship and Immigration Services
32 | acronym: USCIS
33 | peace-corps:
34 | url: http://peacecorps.gov
35 | full_name: Peace Corps
36 | census:
37 | url: http://census.gov
38 | full_name: U.S. Census
39 | fcc:
40 | url: http://fcc.gov
41 | full_name: Federal Communications Commission
42 | acronym: FCC
43 | fda:
44 | url: http://fda.gov
45 | full_name: U.S. Food and Drug Administration
46 | acronym: FDA
47 | nrel:
48 | url: http://nrel.gov
49 | full_name: National Renewable Energy Laboratory
50 | acronym: NREL
51 | usda:
52 | url: http://usda.gov
53 | full_name: Department of Agriculture
54 | acronym: USDA
55 | regulations-gov:
56 | url: http://regulations.gov
57 | department-of-the-interior:
58 | url: http://interior.gov
59 | acronym: DOI
60 | full_name: U.S. Department of the Interior
61 | department-of-state:
62 | url: http://www.state.gov
63 | full_name: State Department
64 | department-of-health-and-human-services:
65 | url: http://www.hhs.gov/
66 | full_name: Department of Health and Human Services
67 | acronym: DHS
68 | department-of-justice:
69 | url: http://www.justice.gov/
70 | full_name: Justice Department
71 | acronym: DOJ
72 | small-business-administration:
73 | url: https://www.sba.gov/
74 | full_name: Small Business Administration
75 | acronym: SBA
76 | department-of-labor:
77 | url: https://www.dol.gov/
78 | full_name: Department of Labor
79 | acronym: DOL
80 |
--------------------------------------------------------------------------------
/_data/project_filter.yml:
--------------------------------------------------------------------------------
1 | # This file should contain only the identifiers of projects that should be
2 | # published to the Dashboard from the Team API.
3 | projects:
4 | - api-data-gov
5 | - betaFEC
6 | - C2
7 | - calc
8 | - cloud.gov
9 | - collegescorecard
10 | - dap
11 | - dashboard
12 | - dataact
13 | - developer-program
14 | - discovery
15 | - ekip-api
16 | - fbopen
17 | - federalist
18 | - foia
19 | - openopps
20 | - myra
21 | - myusa
22 | - peacecorps-site
23 | - pulse
24 | - sbirez
25 | - uscis
26 | - useiti-report
27 | fields:
28 | - full_name
29 | - stage
30 | - description
31 | - contact
32 | - blog
33 | - impact
34 | - partners
35 | - milestones
36 | - github
37 | - licenses
38 | - links
39 | - errors
40 | - name
41 | - parent
42 |
--------------------------------------------------------------------------------
/_data/projects/C2.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: C2
3 | github:
4 | name: 18F/C2
5 | description: an approval process automation tool
6 | description: More than a quarter million federal employees use government credit cards, called purchase cards, to buy small items like office supplies and furniture. Each purchase needs to be approved and audited to prevent fraud. With our partners at the General Service Administration's Public Buildings Service in Washington, D.C., we built a simplified, email-based purchasing approval tool for purchase card holders authorized to buy office supplies for the government. We designed it to be intuitive and convenient so that federal employees could drastically reduce the time they spend on purchase card approvals.
7 | partners:
8 | - GSA National Capital Region
9 | - 18F
10 | - GSA Common Acquisition Platform
11 | stage: live
12 | impact: As C2 streamlines the purchase card approval process, government employees can spend more time performing their essential work and less time on the paperwork required to buy their micropurchases. An updated process will help restore public confidence that government employees are only using cards for valid purchases and save the government agencies millions of dollars by creating a more reliable, efficient approval system for micropurchases.
13 | milestones:
14 | contact:
15 | - url: https://cap.18f.gov/feedback
16 | text: C2 support
17 | - url: https://github.com/18F/C2/issues
18 | text: C2 GitHub issues
19 | licenses:
20 | C2:
21 | name: CC0-1.0
22 | url: https://github.com/18F/C2/blob/master/LICENSE.md
23 | links:
24 | - url: https://cap.18f.gov/
25 | text: C2 website
26 | full_name: C2
27 |
--------------------------------------------------------------------------------
/_data/projects/api-data-gov.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: api-data-gov
3 | github:
4 | - 18F/api.data.gov
5 | - NREL/api-umbrella
6 | description: 'A hosted, shared-service that provides an API key, analytics, and proxy
7 | solution for government web services. We are currently accepting clients for this
8 | free service: contact us to learn more.'
9 | partners:
10 | - Census
11 | - Federal Communications Commission
12 | - U.S. Food and Drug Administration
13 | - General Services Administration
14 | - National Renewable Energy Laboratory
15 | - Regulations.gov
16 | - Department of Agriculture
17 | stage: beta
18 | impact: 2,800 API users and 66 million API requests have been served since the service launched in July 2013.
19 | milestones:
20 | contact:
21 | - api.data.gov@gsa.gov
22 | licenses:
23 | fbopen: Public Domain (CC0)
24 | links:
25 | - https://api.data.gov
26 | - https://api.data.gov/metrics
27 | - https://api.data.gov/about
28 | - https://nrel.github.io/api-umbrella/
29 | blog:
30 | - API
31 | full_name: api.data.gov
32 |
--------------------------------------------------------------------------------
/_data/projects/betaFEC.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: betaFEC
3 | full_name: betaFEC
4 | stage: beta
5 | description: The Federal Election Commission (FEC) has long been a pioneer of open data. 18F was able to help the FEC build its first public API, and a new site on top of that API. This site helps make campaign finance information more accessible to the public, as part of a larger redesign of the FEC’s online presence.
6 | links:
7 | - url: https://beta.fec.gov
8 | text: betaFEC
9 | - url: https://api.open.fec.gov/developers
10 | text: betaFEC API Documentation
11 | milestones:
12 | - 'June 2014: Project Discovery stage started'
13 | - 'May 2015: Alpha testing of the API and website'
14 | - 'July 2015: Beta testing of the API'
15 | - 'October 2015: Public release of the beta site'
16 | partners:
17 | - Federal Election Commission
18 | impact: The new site makes it easy to search, share, and understand campaign finance data.
19 | licenses:
20 | betaFEC:
21 | name: CC0-1.0
22 | url: https://github.com/18F/openfec/blob/master/LICENSE.md
23 | blog:
24 | - fec
25 | contact:
26 | - url: mailto:leah.bannon@gsa.gov
27 | text: Leah Bannon
28 |
--------------------------------------------------------------------------------
/_data/projects/calc.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: calc
3 | github:
4 | - 18F/calc
5 | description: The Contract Awarded Labor Category (CALC) tool helps the federal contracting community make smarter, faster buying decisions by allowing them to search for hourly labor rates across numerous government contracts. The CALC tool is helping contracting officers move from paper-based research to simple, efficient online search.
6 | partners:
7 | - General Services Administration
8 | impact: Saves contracting officers in the federal government hours of work every week and provides them with better data. By having a tool that understands fair and reasonable prices, contracting officers will be better equipped to negotiate with vendors, which will ensure that the government is spending taxpayer dollars wisely and in the most efficient way.
9 | stage: live
10 | milestones:
11 | - 'November 2014: Initial discovery stage begins'
12 | - 'November 2014: Begin building alpha'
13 | - 'March 2015: Name changed from "Hourglass" to "CALC"'
14 | - 'May 2015: Public beta launched'
15 | - 'July 2015: Second release with price analysis tools, status changed to live'
16 | contact:
17 | - nicholas.brethauer@gsa.gov
18 | licenses:
19 | mirage: Public Domain (CC0)
20 | links:
21 | - https://trello.com/b/LjXJaVbZ/hourglass
22 | - https://calc.gsa.gov
23 | full_name: CALC
24 |
--------------------------------------------------------------------------------
/_data/projects/cloud.gov.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: cloud.gov
3 | full_name: cloud.gov Platform-As-A-Service
4 | stage: alpha
5 | description: cloud.gov includes a Platform-as-a-Service (PaaS) specifically built for government, based on the open source Cloud Foundry. It provides a secure, scalable platform for teams to build and host their application or website. It can help development teams work faster and cheaper by handling much of their deployment complexity. The cloud.gov platform is currently in a small pilot program, but we will be expanding access over time.
6 | partners:
7 | - 18F
8 | - GSA
9 | impact: Gives government teams the ability to develop, run, and manage web applications without the complexity and cost of building and maintaining infrastructure.
10 | licenses:
11 | cg-landing:
12 | name: CC0
13 | url: https://github.com/18F/cg-landing/blob/master/LICENSE.md
14 | blog:
15 | - cloud-gov
16 | links:
17 | - url: https://cloud.gov/
18 | text: cloud.gov
19 | - url: https://18f.storiesonboard.com/m/gov-dev
20 | text: Roadmap/ChangeLog story map (in StoriesOnBoard)
21 | - url: https://trello.com/b/ChGzyepo/gov-dev
22 | text: Sprint Status (in Trello)
23 | - url: https://www.google.com/calendar/embed?src=gsa.gov_0samf7guodi7o2jhdp0ec99aks%40group.calendar.google.com&ctz=America/Los_Angeles
24 | text: Project Calendar (standups, reviews, and planning meetings)
25 | contact:
26 | - url: mailto:bret.mogilefsky@gsa.gov
27 | text: Bret Mogilefsky
28 | github:
29 | name: 18F/cg-landing
30 | description: 18F landing page for cloud.gov
31 |
--------------------------------------------------------------------------------
/_data/projects/collegescorecard.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: collegescorecard
3 | full_name: College Scorecard
4 | stage: live
5 | description: In September, 18F worked with USDS and the Department of Education on College Scorecard, a clearinghouse to provide the clearest, most accessible, and reliable national data on college cost, graduation, debt, and post-college earnings.
6 | links:
7 | - url: https://collegescorecard.ed.gov/
8 | text: College Scorecard
9 | - url: https://collegescorecard.ed.gov/data/
10 | text: College Scorecard Data
11 | partners:
12 | - Department of Education
13 | contact:
14 | - url: mailto:holly.allen@gsa.gov
15 | text: Holly Allen
16 | milestones:
17 | - 'June 2015: Kick-off meeting'
18 | - 'August 2015: Private beta launched'
19 | - 'September 2015: Public live launch'
20 | impact: Millions of college applicants, and those who support and advise them, can now make more informed decisions based on data related to college cost, graduation rates, debt, and post-degree earnings.
21 | licenses:
22 | collegescorecard:
23 | name: Public Domain (CC0)
24 | url: https://creativecommons.org/publicdomain/zero/1.0/
25 |
--------------------------------------------------------------------------------
/_data/projects/dap.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: dap
3 | github:
4 | - gsa/analytics.usa.gov
5 | - 18f/analytics-reporter
6 | description: 18F worked with the Digital Analytics Program, the U.S. Digital Service, and the White House to build and host a lightweight dashboard and public dataset that shows web traffic across the .gov domain.
7 | impact: Gives agencies a tool to make data-driven decisions and gives the public an easy way to see .gov traffic as well as what kinds of technology people are using to access .gov websites.
8 | partners:
9 | - General Services Administration
10 | stage: beta
11 | milestones:
12 | - 'May 2012: Digital Government Strategy calls for a government-wide analytics program'
13 | - 'May 2013: Digital Analytics Program announced'
14 | - 'August 2014: Full Digital Analytics Program access expanded to all federal staff
15 | at participating agencies'
16 | - 'March 2015: Analytics.USA.gov announced'
17 | contact:
18 | - dap@gsa.gov
19 | licenses:
20 | analytics.usa.gov: Public Domain (CC0)
21 | links:
22 | - https://analytics.usa.gov
23 | - https://github.com/gsa/analytics.usa.gov
24 | full_name: Analytics.USA.gov
25 |
--------------------------------------------------------------------------------
/_data/projects/dashboard.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: dashboard
3 | full_name: Dashboard
4 | stage: live
5 | description: 18F, as part of it's commitment to working in the open, needed a way to catalog and allow the public to track our work. We developed the 18F Dashboard to track our projects' status and to give more transparency and insight into our work and values.
6 | impact: Partner agencies and members of the public can better understand our work.
7 | licenses:
8 | dashboard:
9 | name: CC0-1.0
10 | url: https://github.com/18F/team_api/blob/master/LICENSE.md
11 | links:
12 | - url: https://18f.gsa.gov/dashboard/
13 | text: Live 18F Dashboard
14 | contact:
15 | - url: mailto:gregory.boone@gsa.gov
16 | text: Greg Boone
17 | partners:
18 | - 18F
19 |
--------------------------------------------------------------------------------
/_data/projects/dataact.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: dataact
3 | github:
4 | - fedspendingtransparency/fedspendingtransparency.github.io
5 | description: The DATA Act was signed in 2014 to bring transparency into how the federal government spends money. 18F advises the Treasury Department on how to implement the DATA Act, and provides agency outreach, technical assistance, and content.
6 | partners:
7 | - U.S. Department of Treasury
8 | impact: Makes it easier for the public to understand how trillions of tax dollars are spent by the government every year.
9 | stage: alpha
10 | milestones:
11 | - 'January 2015: 18F began work on project'
12 | contact:
13 | - kaitlin.devine@gsa.gov
14 | licenses:
15 | fedspendingtransparency: Public Domain (CC0)
16 | links:
17 | - https://fedspendingtransparency.github.io/
18 | full_name: DATA Act
19 |
--------------------------------------------------------------------------------
/_data/projects/developer-program.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: developer-program
3 | github:
4 | - 18F/API-All-the-X
5 | description: The /Developer program provides comprehensive support and resources for any federal agency engaged in the production or use of APIs.
6 | partners:
7 | - General Services Administration
8 | stage: live
9 | impact: "Helps federal agencies develop useful, robust APIs through educational resource and tools. The program has served ver 70 agencies, including each cabinet department, the National Archives,the Federal Communications Commission, the Consumer Financial Protection Bureau, and the
10 | Office of Personnel Management."
11 | milestones:
12 | - 'January 2014: 18F began work on project'
13 | - 'May 2014: API Usability Program Launched'
14 | - 'May 2014: /Developer Program Website v2.0 Announced'
15 | - 'September 2014: 20th API Usability Participant'
16 | contact:
17 | - gray.brooks@gsa.gov
18 | licenses:
19 | API-All-the-X: Public Domain (CC0)
20 | links:
21 | - https://pages.18f.gov/API-All-the-X/
22 | blog:
23 | - "/developer"
24 | full_name: "/Developer Program"
25 |
--------------------------------------------------------------------------------
/_data/projects/discovery.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: discovery
3 | github:
4 | - 18F/discovery
5 | description: Discovery allows federal acquisition personnel to conduct initial market research more easily and quickly, allowing users to discover and research vendors offering work across a number of professional service categories.
6 | partners:
7 | - General Services Administration
8 | impact: Makes the procurement process a lot easier for GSA’s contracting officers — the people who are responsible for buying products and services for the federal government. Discovery lets these contracting officers find and sort vendors based on their experience levels and other attributes, saving them hours of time in the process.
9 | stage: beta
10 | milestones:
11 | - 'May 2014: Initial Discovery stage began for task order generator project'
12 | - 'June 2014: Project pivoted based on user interviews and Discovery stage began for
13 | market research tool'
14 | - 'July 2014: Work on Alpha stage began for market research tool'
15 | - 'November 2014: Alpha work complete'
16 | - 'February 2015: Name changed from "Mirage" to "Discovery"'
17 | contact:
18 | - josh.ruihley@gsa.gov
19 | licenses:
20 | mirage: Public Domain (CC0)
21 | links:
22 | - http://gsa.gov/oasis
23 | - https://discovery.gsa.gov
24 | full_name: 'Discovery: OASIS Market Research Tool'
25 |
--------------------------------------------------------------------------------
/_data/projects/ekip-api.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: ekip-api
3 | full_name: Every Kid in a Park
4 | stage: live
5 | description: "In 2015, President Obama formally announced the Every Kid in a Park program, which provides fourth graders and their families with free access to more than 2,000 federally-managed sites. 18F worked with the Department of the Interior to create the program’s website, which was written at a fourth grade level with the help of fourth graders."
6 | partners:
7 | - U.S. Department of the Interior
8 | milestones:
9 | - February 2015 - PIF Design Studio
10 | - March 2015 - Mini-Hackathon
11 | - May 2015 - UMD Kid's Team Testing at White House
12 | - June 2015 - 18F began work on the project
13 | - July 2015 - Ticketing Application Demo
14 | - September 1, 2015 - Site Launch
15 | impact: |
16 | Designed by and for fourth graders, this site provides an optimized user experience to generate a paper pass to visit more than 2,000 federally-managed sites.
17 | licenses:
18 | ekip-api:
19 | name: CC0-1.0
20 | url: https://github.com/18F/team_api/blob/master/LICENSE.md
21 | links:
22 | - url: https://everykidinapark.gov/
23 | text: Every Kid in a Park Website
24 | contact:
25 | - url: mailto:shashank.khandelwal@gsa.gov
26 | text: Shashank Khandelwal
27 | - url: mailto:christopher.goranson@gsa.gov
28 | text: Christopher Goranson
29 | github:
30 | name: 18F/ekip-api
31 | description: 'The source for the Every Kid in a Park website. '
32 |
--------------------------------------------------------------------------------
/_data/projects/fbopen.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: fbopen
3 | github:
4 | name: 18F/fbopen
5 | description: An open API server, data import tools, and sample apps to help small
6 | businesses search for opportunities to work with the U.S. government.
7 | description: FBOpen helps small businesses search for opportunities to work with the U.S. government through an open API server, data import tools, and sample applications.
8 | partners:
9 | stage: beta
10 | impact: Makes finding opportunities to work with the U.S. government easier and more effective.
11 | milestones:
12 | - 'May 2014: 18F took over project maintenance from Presidential Innovation Fellows
13 | program'
14 | contact:
15 | - fbopen@gsa.gov
16 | licenses:
17 | fbopen:
18 | id: CC0
19 | url: https://github.com/18F/fbopen/tree/master/LICENSE.md
20 | links:
21 | - url: https://pages.18f.gov/fbopen
22 | text: FBOpen API Documentation
23 | blog:
24 | - fbopen
25 | full_name: FBOpen
26 |
--------------------------------------------------------------------------------
/_data/projects/federalist.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: federalist
3 | full_name: Federalist
4 | stage: beta
5 | description: Federalist is a unified interface for publishing static government websites.
6 | It automates common tasks for integrating GitHub, Amazon Web Services and content
7 | editing to provide a simple way for developers to launch new websites or more easily
8 | manage existing ones.
9 | partners:
10 | - GSA
11 | licenses:
12 | federalist:
13 | name: CC0
14 | url: https://github.com/18F/federalist/blob/master/LICENSE.md
15 | links:
16 | - url: https://federalist.18f.gov
17 | text: Federalist site
18 | contact:
19 | - url: mailto:david.cole@gsa.gov
20 | text: David Cole
21 |
--------------------------------------------------------------------------------
/_data/projects/foia.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: foia
3 | github:
4 | - 18F/foia
5 | - 18F/foia-hub
6 | description: A new tool to search for the correct agency or office to make a FOIA
7 | request.
8 | partners:
9 | - Department of Justice
10 | - FOIA agency task force
11 | impact: The U.S. Federal Government processed nearly 700,000 FOIA requests in fiscal
12 | year 2013.
13 | stage: alpha
14 | milestones:
15 | - 'June 2014: Project Discovery stage started'
16 | - 'April 2015: open.foia.gov is deployed. '
17 | contact:
18 | - 18f/foia/issues
19 | licenses:
20 | foia: Public Domain (CC0)
21 | foia-hub: Public Domain (CC0)
22 | links:
23 | - https://trello.com/b/D0r2UOz0/foia-scrum-board
24 | blog:
25 | - foia
26 | full_name: FOIA Modernization
27 |
--------------------------------------------------------------------------------
/_data/projects/myra.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: myra
3 | github:
4 | - 18F/myra
5 | description: Landing page design for Treasury’s My Retirement Account program, which
6 | will provide a simple, safe, and affordable way for individuals to start saving
7 | for retirement.
8 | partners:
9 | - U.S. Department of Treasury
10 | impact: Millions of Americans do not have access to an employer-sponsored retirement
11 | plan, which includes more than 50% of full-time and 75% of part-time workers.
12 | stage: live
13 | milestones:
14 | - 'August 2014: Project discovery stage started'
15 | - 'September 2014: Project moved from discovery to alpha'
16 | - 'December 2014: Project launched'
17 | - 'June 2015: Project handed off to partner'
18 | contact:
19 | - christopher.cairns@gsa.gov
20 | licenses:
21 | myra: Public Domain (CC0)
22 | links:
23 | - https://myra.treasury.gov
24 | full_name: myRA
25 |
--------------------------------------------------------------------------------
/_data/projects/myusa.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: myusa
3 | github:
4 | - 18F/myusa
5 | description: A digital services platform for Americans to register, sign in, and manage
6 | ongoing transactions with U.S. Federal Government services.
7 | partners:
8 | - General Services Administration
9 | - Department of Homeland Security
10 | - Small Business Administration
11 | - Department of Labor
12 | impact: The millions of Americans who conduct online transactions with U.S. government.
13 | stage: alpha
14 | milestones:
15 | - 'June 2014: 18F began work on project'
16 | - 'September 2014: Alpha delivered to clients and user testing started'
17 | contact:
18 | - myusa@gsa.gov
19 | licenses:
20 | myusa: Public Domain (CC0)
21 | links:
22 | - https://my.usa.gov
23 | full_name: MyUSA
24 |
--------------------------------------------------------------------------------
/_data/projects/openopps.yml:
--------------------------------------------------------------------------------
1 | ---
2 | full_name: Open Opportunities
3 | name: openopps
4 | github:
5 | - 18F/openopps-platform
6 | description: |
7 | Open Opportunities is creating a network of federal employees that will lead to a more effective, efficient, responsive government by sharing skills and collaborating on projects that support the mission of an agency or the government as a whole. Only 37% of federal employees surveyed believe that creativity & innovation are rewarded. From a total audience of 2.7 million federal employees, the initial target audience are motivate, mission-driven individuals who identify and solve problems for our nation.
8 | partners:
9 | - General Services Administration
10 | - Department of State
11 | - Department of Health and Human Services
12 | stage: live
13 | impact: |
14 | Amplify the work of 1 million federal employees.
15 | milestones:
16 | - 'September 2014: GSA OHRM signs IAA for GSA Rotational Details and Project Network
17 | to move to Open Opportunities'
18 | - 'September 2015: Authority To Operate'
19 | - 'August 2015: Open Opportunities expands beyond DigitalGov tasks, OCSIT & 18F roadmaps
20 | converge'
21 | - 'January 2015: HHS transitions FairTrade pilot into Open Opportunities community'
22 | - 'October 2014: GSA hosts Midas open source hack night in DC'
23 | - 'October 2014: DigitalGov Open Opportunities pilot starts'
24 | - 'September 2014: GSA OCSIT signs MOU for Open Opportunities to move to Midas platform'
25 | - 'September 2014: 18F launches https://midas.18f.us for use by early adopters'
26 | - 'June 2014: State Department launches Alpha as Crowdwork'
27 | - 'May 2014: HHS launches Alpha as FairTrade'
28 | - 'January 2014: 18F begins work on project'
29 | - 'June 2013: State Department begins project Discovery stage with Presidential Innovation
30 | Fellows'
31 | links:
32 | - url: https://openopps.digitalgov.gov
33 | text: Open Opportunities (live website)
34 | contact:
35 | - url: mailto:openopps@gsa.gov
36 | text: Open Opportunities Team
37 | blog:
38 | - midas
39 | licenses:
40 | dashboard:
41 | name: CC0-1.0
42 | url: https://github.com/18F/openopps-platform/blob/master/LICENSE.md
43 | errors:
44 | - The property '#/' did not contain a required property of 'testable' in schema 153c6056-e293-5b85-aaf3-894bae47b9fb#
45 | - 'Unknown Team Member: rogeruiz'
46 |
--------------------------------------------------------------------------------
/_data/projects/peacecorps-site.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: peacecorps-site
3 | github:
4 | - 18F/peacecorps-site
5 | description: A redesign of peacecorps.gov, offering a new, user-focused experience
6 | for users.
7 | partners:
8 | - Peace Corps
9 | impact: 7,000 Peace Corps Volunteers in the field, hundreds of thousands Prospective/Returned
10 | Volunteers, friends, and family.
11 | stage: beta
12 | contact:
13 | - sean.herron@gsa.gov
14 | licenses:
15 | links:
16 | - https://beta.peacecorps.gov
17 | full_name: PeaceCorps.gov
18 |
--------------------------------------------------------------------------------
/_data/projects/pulse.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: pulse
3 | github:
4 | - 18F/pulse
5 | - 18F/domain-scan
6 | description: A lightweight dashboard that uses the official .gov domain list to measure
7 | HTTPS integration and participation in the Digital Analytics Program.
8 | partners:
9 | - General Services Administration
10 | stage: beta
11 | milestones:
12 | - 'April 2015: 18F began work on project'
13 | - 'May 2015: Site launched and developed in the open'
14 | - 'June 2015: Pulse.CIO.gov announced'
15 | contact:
16 | - pulse@cio.gov
17 | licenses:
18 | pulse: Public Domain (CC0)
19 | links:
20 | - https://pulse.cio.gov
21 | - https://github.com/18F/pulse
22 | full_name: Pulse
23 |
--------------------------------------------------------------------------------
/_data/projects/sbirez.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: sbirez
3 | github:
4 | - 18F/afsbirez
5 | description: An application to simplify, streamline, and unify the Small Business
6 | Innovation Research application process.
7 | partners:
8 | - Air Force
9 | impact: To encourage new small businesses to work with the Federal Government.
10 | stage: alpha
11 | milestones:
12 | - 'May 2014: 18F began work on project'
13 | contact:
14 | - david.best@gsa.gov
15 | licenses:
16 | sbirez: Public Domain (CC0)
17 | full_name: SBIR-EZ
18 |
--------------------------------------------------------------------------------
/_data/projects/uscis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: uscis
3 | contact: 18f-uscis-projects@gsa.gov
4 | stage: alpha
5 | description: 'We are helping to reimagine and modernize immigration and visa processes:
6 | building tools that improve the applicant process, providing clear and simple information
7 | to the public, and creating new tools that make the processing of immigration forms
8 | faster and more efficient.'
9 | impact: Every year, hundreds of thousands of individuals travel to the United States
10 | in pursuit of work, education, leisure, or with the hope of becoming a US resident
11 | or citizen.
12 | full_name: USCIS projects
13 | partners:
14 | - U.S. Citizenship and Immigration Services
15 |
--------------------------------------------------------------------------------
/_data/projects/useiti-report.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: useiti-report
3 | full_name: The United States Extractives Industries Transparency Initiative (USEITI)
4 | stage: beta
5 | description: |
6 | This site and open data portal supports the President’s Open Gov Partnership National Action Plan commitment to the Extractive Industries Transparency Initiative.
7 | partners:
8 | - U.S. Department of the Interior
9 | milestones:
10 | - July 2014 - 18F began work on project
11 | - September 2014 Alpha site launched
12 | - December 2014 Beta site launched
13 | - December 2015 First annual report due
14 | impact: |
15 | Revenue from the sale of natural resources on Federal lands totaled $97.5 billion between 2003 to 2013.
16 | licenses:
17 | doi-extractives-data:
18 | name: CC0-1.0
19 | url: https://github.com/18F/doi-extractives-data/blob/master/LICENSE.md
20 | links:
21 | - url: https://useiti.doi.gov
22 | text: U.S. EITI
23 | - url: https://eiti.org
24 | text: Extractive Industries Transparency Initiative (Global site)
25 | contact:
26 | - url: mailto:michelle.herzfeld@gsa.gov
27 | text: Michelle Hertzfeld
28 | errors:
29 | - 'Unknown Team Member: corey.mahoney'
30 |
--------------------------------------------------------------------------------
/_includes/ascii.html:
--------------------------------------------------------------------------------
1 |
58 |
--------------------------------------------------------------------------------
/_includes/dashboard-contact.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_includes/footer.html:
--------------------------------------------------------------------------------
1 |
35 |
--------------------------------------------------------------------------------
/_includes/head.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | {% if page.title %}
27 |
18F — {{ page.title }}
28 |
29 | {% else %}
30 | {{ site.title }}
31 |
32 | {% endif %}
33 |
34 | {% for project in site.data.projects %}
35 | {% if project.project == page.title %}
36 | {% assign isproject = true %}
37 | {% if project.description %}
38 |
39 |
40 | {% endif %}
41 | {% endif %}
42 | {% endfor %}
43 |
44 | {% if isproject != true %}
45 | {% if page.description %}
46 |
47 |
48 | {% else %}
49 |
50 |
51 | {% endif %}
52 | {% endif %}
53 |
54 |
55 | {% if page.image %}
56 |
57 |
58 | {% else %}
59 |
60 |
61 |
62 | {% endif %}
63 |
64 |
65 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
90 |
91 |
92 |
94 |
95 |
100 |
101 | {% include ascii.html %}
102 |
--------------------------------------------------------------------------------
/_includes/list-partners-preview.html:
--------------------------------------------------------------------------------
1 | Preview of the partner list is not yet available
2 |
3 |
6 |
--------------------------------------------------------------------------------
/_includes/list-partners.html:
--------------------------------------------------------------------------------
1 | {% for agency in project.partners %}
2 | {% capture agencyname %}{{ agency | slugify }}{% endcapture %}
3 | {% capture partnerurl %}{% for partner in site.data.partners %}{% if partner[0] == agencyname or partner[1].full_name == agency %}{{ partner[1].url }}{% break %}{% else %}{% endif %}{% endfor %}{% endcapture %}
4 | {% if include.style == "list" %}
5 | {% unless partnerurl == empty %}
6 | {{ agency }}
7 | {% else %}
8 | {{agency}}
9 | {% endunless %}
10 | {% elsif include.style == "strong" %}
11 | {% unless partnerurl == empty %}
12 | {{agency}} {% unless forloop.rindex == 1 %}, {% endunless%}
13 | {% else %}
14 | {{ agency }}{% unless forloop.rindex == 1 %}, {% endunless%}
15 | {% endunless %}
16 | {% endif %}
17 | {% endfor %}
18 |
--------------------------------------------------------------------------------
/_includes/project-code.html:
--------------------------------------------------------------------------------
1 | {% if current_url.name && current_url.description %}
2 | {% assign full_repo_name = current_url.name %}
3 | {% assign repo_name = current_url.name | split: "/" | last %}
4 | {% assign repo_desc = current_url.description %}
5 | {% else %}
6 | {% assign full_repo_name = current_url %}
7 | {% assign repo_name = current_url | split: "/" | last %}
8 | {% endif %}
9 |
10 |
11 | {% if repo_desc %}
12 |
{{ repo_desc }}
13 | {% endif %}
14 |
15 | Issues:
16 | Stars:
17 | Forks:
18 | {% if current_license[repo_name] %}
19 | {% if current_license[repo_name].name %}
20 | {% assign license_name = current_license[repo_name].name %}
21 | {% else %}
22 | {% assign license_name = current_license[repo_name] %}
23 | {% endif %}
24 | {% capture branch %}{% if current_branch %}{{ current_branch | map: repo_name }}{% else %}master{%endif%}{% endcapture %}
25 | License: {{ license_name }}
26 | {% endif %}
27 |
28 |
29 |
--------------------------------------------------------------------------------
/_includes/project-links.html:
--------------------------------------------------------------------------------
1 | {% assign has_api = false %}
2 | {% assign has_process = false %}
3 | {% for item in current_links %}
4 | {% if item.category == 'api' %}
5 | {% assign has_api = true %}
6 | {% endif %}
7 | {% if item.category == 'process' %}
8 | {% assign has_process = true %}
9 | {% endif %}
10 | {% endfor %}
11 |
12 |
13 | {% if has_api == true %}
14 |
15 |
api links
16 |
{% for item in current_links %}
17 | {% if item.category == 'api' %}
18 | {{ item.text }} {% endif %}{% endfor %}
19 |
20 |
21 | {% endif %}
22 |
23 |
24 | {% if has_process == true %}
25 |
26 |
process links
27 |
{% for item in current_links %}
28 | {% if item.category == 'process' %}
29 | {{ item.text }} {% endif %}{% endfor %}
30 |
31 |
32 | {% endif %}
33 |
34 |
35 |
36 |
related links
37 |
{% for item in current_links %}
38 | {% if item.category != 'api' and item.category != 'process' and item.category != 'repo' %}
39 | {% if item.url %}{{ item.text }} {% else %}{{ item }} {% endif %}
40 | {% endif %}{% endfor %}
41 |
42 |
43 |
--------------------------------------------------------------------------------
/_includes/projectlist.html:
--------------------------------------------------------------------------------
1 |
2 |
Projects currently in this phase:
3 |
4 | {% for project in site.data.projects %}
5 | {% if project[1]['stage'] == include.stage %}
6 | {{ project[1]['full_name'] }}
7 | {% endif %}
8 | {% endfor %}
9 |
10 |
11 |
--------------------------------------------------------------------------------
/_includes/scripts.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
8 |
9 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/_layouts/bare.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% include head.html %}
5 |
6 |
7 |
8 |
9 |
10 |
This site is in alpha . The content contained is not final.
11 |
12 |
13 |
14 |
15 |
21 |
22 |
23 | {{ content }}
24 |
25 |
26 |
27 |
28 | {% include footer.html %}
29 | {% include scripts.html %}
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/_plugins/build.rb:
--------------------------------------------------------------------------------
1 | `npm install`
2 |
--------------------------------------------------------------------------------
/_plugins/dashboard.rb:
--------------------------------------------------------------------------------
1 | require 'jekyll'
2 | require 'json'
3 | require 'open-uri'
4 |
5 | module Dashboard
6 | # Generates an individual project page from project data.
7 | class ProjectPage < Jekyll::Page
8 | private_class_method :new
9 | attr_reader :site
10 |
11 | def initialize(site, project_id)
12 | @site = site
13 | @base = site.source
14 | @dir = File.join 'project', project_id
15 | @name = 'index.html'
16 |
17 | process @name
18 | read_yaml File.join(@base, '_layouts'), 'project.html'
19 | end
20 |
21 | # TODO(mbland): Remove this once the Team API is standardized.
22 | FIELDS_TO_TRANSLATE = {
23 | 'project' => 'full_name',
24 | 'mission' => 'description'
25 | }
26 |
27 | def self.munge_licenses(project_data)
28 | licenses = project_data['licenses']
29 | unless licenses.nil?
30 | project_data['licenses'] = licenses.map do |key, value|
31 | [key, (value.instance_of?(Hash) ? value['name'] : value)]
32 | end.to_h
33 | end
34 | end
35 |
36 | def self.get_github_description(project_name, projects)
37 | if projects[project_name] && projects[project_name]['github']
38 | projects[project_name]['github'][0]['description']
39 | end
40 | end
41 |
42 | def self.get_repo_name_from_url(url, projects)
43 | project_name = full_name = url['url']
44 | parts = project_name.split '/'
45 | if parts.length > 1
46 | project_name = parts[-1]
47 | full_name = parts[-2, 2].join '/'
48 | end
49 | desc = get_github_description project_name, projects
50 | { 'name' => full_name,
51 | 'description' => (url['text'] || desc || '')
52 | }
53 | end
54 |
55 | def self.append_repo_links(project_data, projects)
56 | links = project_data['links']
57 | if links && project_data['github']
58 | repo_links = links.map do |link|
59 | get_repo_name_from_url(link, projects) if link['category'] == 'repo'
60 | end.compact
61 | project_data['github'] += repo_links
62 | end
63 | end
64 |
65 | def self.munge_github(project_data, projects)
66 | github = project_data['github']
67 | unless github.is_a?(Array) || github.nil?
68 | project_data['github'] = [github]
69 | end
70 | append_repo_links(project_data, projects)
71 | end
72 |
73 | def self.munge_project_data(project_data, projects)
74 | FIELDS_TO_TRANSLATE.each do |from, to|
75 | project_data[to] = project_data[from] unless project_data[to]
76 | end
77 | original_name = project_data['name']
78 | if original_name.scan(/[A-Z]/).size > 0
79 | project_data['redirect_from'] = []
80 | project_data['redirect_from'].push("project/#{original_name}")
81 | end
82 | project_data['name'] = original_name.downcase
83 |
84 | munge_licenses project_data
85 | munge_github project_data, projects
86 | end
87 |
88 | def self.create(site, project_id, project_data)
89 | unless project_id == "all"
90 | page = new site, project_id
91 | munge_project_data project_data, site.data['projects']
92 | page.data['project'] = project_data
93 | page.data['title'] = project_data['full_name']
94 | site.pages << page
95 | end
96 | end
97 | end
98 |
99 | # Processes site data, generates authorization artifacts, publishes an API,
100 | # and generates cross-linked Hub pages.
101 | class Generator < ::Jekyll::Generator
102 | safe true
103 |
104 | # Executes all of the data processing and artifact/page generation phases
105 | # for the Hub.
106 | def generate(site)
107 | assign_children_to_parents site.data['projects']
108 | generate_project_pages site
109 | end
110 |
111 | # we want to exclude a project if parent = child or if ref'ed as a link
112 | def exclude_project?(project, parent, projects)
113 | return true if parent.nil? || parent == project || !projects[parent]
114 | repos = projects[parent]['links'].select do |r|
115 | r['category'] == 'repo' && r['url'].include?(project)
116 | end
117 | return true unless repos.empty?
118 | end
119 |
120 | def assign_children_to_parents(projects)
121 | projects.each do |id, p|
122 | parent = p['parent']
123 | next if exclude_project?(id, parent, projects)
124 | children = (projects[parent]['children'] || []) << p
125 | projects[parent]['children'] = children
126 | end
127 | end
128 |
129 | def generate_project_pages(site)
130 | site.data['projects'].delete('all')
131 | site.data['projects'].each do |project_id, project|
132 | ProjectPage.create site, project_id.downcase, project
133 | end
134 | end
135 | end
136 | end
137 |
--------------------------------------------------------------------------------
/assets/_sass/base/_base.scss:
--------------------------------------------------------------------------------
1 | // Bitters v0.10.0
2 | // http://bitters.bourbon.io
3 |
4 | // Variables
5 | @import 'variables';
6 |
7 | // Neat Settings -- uncomment if using Neat -- must be imported before Neat
8 | @import 'grid-settings';
9 |
10 | // Mixins
11 | @import 'mixins/flash';
12 |
13 | // Extends
14 | @import 'extends/button';
15 | @import 'extends/clearfix';
16 | @import 'extends/hide-text';
17 |
18 | // Typography and Elements
19 | @import 'typography';
20 | @import 'forms';
21 | @import 'tables';
22 | @import 'lists';
23 | @import 'flashes';
24 | @import 'buttons';
25 |
--------------------------------------------------------------------------------
/assets/_sass/base/_buttons.scss:
--------------------------------------------------------------------------------
1 | button,
2 | input[type="submit"] {
3 | @extend %button;
4 | @include appearance(none);
5 | border: none;
6 | cursor: pointer;
7 | user-select: none;
8 | vertical-align: middle;
9 | white-space: nowrap;
10 | }
11 |
--------------------------------------------------------------------------------
/assets/_sass/base/_flashes.scss:
--------------------------------------------------------------------------------
1 | %flash-alert {
2 | @include flash($alert-color);
3 | }
4 |
5 | %flash-error {
6 | @include flash($error-color);
7 | }
8 |
9 | %flash-notice {
10 | @include flash($notice-color);
11 | }
12 |
13 | %flash-success {
14 | @include flash($success-color);
15 | }
16 |
--------------------------------------------------------------------------------
/assets/_sass/base/_forms.scss:
--------------------------------------------------------------------------------
1 | fieldset {
2 | background: lighten($base-border-color, 10);
3 | border: 1px solid $base-border-color;
4 | margin: 0 0 ($base-line-height / 2) 0;
5 | padding: $base-line-height;
6 | }
7 |
8 | input,
9 | label,
10 | select {
11 | display: block;
12 | font-family: $form-font-family;
13 | font-size: $form-font-size;
14 | }
15 |
16 | label {
17 | font-weight: bold;
18 | margin-bottom: $base-line-height / 4;
19 |
20 | &.required:after {
21 | content: "*";
22 | }
23 |
24 | abbr {
25 | display: none;
26 | }
27 | }
28 |
29 | textarea,
30 | #{$all-text-inputs},
31 | select[multiple=multiple] {
32 | @include box-sizing(border-box);
33 | @include transition(border-color);
34 | background-color: white;
35 | border-radius: $form-border-radius;
36 | border: 1px solid $form-border-color;
37 | box-shadow: $form-box-shadow;
38 | font-family: $form-font-family;
39 | font-size: $form-font-size;
40 | margin-bottom: $base-line-height / 2;
41 | padding: ($base-line-height / 3) ($base-line-height / 3);
42 | width: 100%;
43 |
44 | &:hover {
45 | border-color: $form-border-color-hover;
46 | }
47 |
48 | &:focus {
49 | border-color: $form-border-color-focus;
50 | box-shadow: $form-box-shadow-focus;
51 | outline: none;
52 | }
53 | }
54 |
55 | textarea {
56 | resize: vertical;
57 | }
58 |
59 | input[type="search"] {
60 | @include appearance(none);
61 | }
62 |
63 | input[type="checkbox"], input[type="radio"] {
64 | display: inline;
65 | margin-right: $base-line-height / 4;
66 | }
67 |
68 | input[type="file"] {
69 | margin-bottom: $base-line-height / 2;
70 | padding-bottom: ($base-line-height / 3);
71 | width: 100%;
72 | }
73 |
74 | select {
75 | width: auto;
76 | max-width: 100%;
77 | margin-bottom: $base-line-height;
78 | }
79 |
--------------------------------------------------------------------------------
/assets/_sass/base/_grid-settings.scss:
--------------------------------------------------------------------------------
1 | @import '../neat/neat-helpers'; // or '../neat/neat-helpers' when not in Rails
2 |
3 | // Breakpoint variables
4 | //********************************************************
5 | //$biggest: new-breakpoint(min-width 1430px); //untested
6 | //////BASE SIZE HERE//////
7 | $small: new-breakpoint(max-width 1130px);
8 | $smaller: new-breakpoint(max-width 995px);
9 | $smallest: new-breakpoint(max-width 785px);
10 | $tiny: new-breakpoint(max-width 590px);
11 | $tinier: new-breakpoint(max-width 480px); //only used in hero unit
12 | $tiniest: new-breakpoint(max-width 390px);
13 |
--------------------------------------------------------------------------------
/assets/_sass/base/_lists.scss:
--------------------------------------------------------------------------------
1 | ul, ol {
2 | margin: 0;
3 | padding: 0;
4 | list-style-type: none;
5 |
6 | &%default-ul {
7 | list-style-type: disc;
8 | margin-bottom: $base-line-height / 2;
9 | padding-left: $base-line-height;
10 | }
11 |
12 | &%default-ol {
13 | list-style-type: decimal;
14 | margin-bottom: $base-line-height / 2;
15 | padding-left: $base-line-height;
16 | }
17 | }
18 |
19 | dl {
20 | margin-bottom: $base-line-height / 2;
21 |
22 | dt {
23 | font-weight: bold;
24 | margin-top: $base-line-height / 2;
25 | }
26 |
27 | dd {
28 | margin: 0;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/assets/_sass/base/_tables.scss:
--------------------------------------------------------------------------------
1 | table {
2 | border-collapse: collapse;
3 | margin: ($base-line-height / 2) 0;
4 | table-layout: fixed;
5 | width: 100%;
6 | }
7 |
8 | th {
9 | border-bottom: 1px solid darken($base-border-color, 15%);
10 | font-weight: bold;
11 | padding: ($base-line-height / 2) 0;
12 | text-align: left;
13 | }
14 |
15 | td {
16 | border-bottom: 1px solid $base-border-color;
17 | padding: ($base-line-height / 2) 0;
18 | }
19 |
20 | tr, td, th {
21 | vertical-align: middle;
22 | }
23 |
--------------------------------------------------------------------------------
/assets/_sass/base/_typography.scss:
--------------------------------------------------------------------------------
1 | body {
2 | -webkit-font-smoothing: antialiased;
3 | background-color: $base-background-color;
4 | color: $base-font-color;
5 | font-family: $base-font-family;
6 | font-size: $base-font-size;
7 | line-height: $unitless-line-height;
8 | }
9 |
10 | h1, h2, h3, h4, h5, h6 {
11 | font-family: $header-font-family;
12 | line-height: $header-line-height;
13 | margin: 0;
14 | text-rendering: optimizeLegibility; // Fix the character spacing for headings
15 | }
16 |
17 | h1 {
18 | font-size: $base-font-size * 2.25; // 16 * 2.25 = 36px
19 | }
20 |
21 | h2 {
22 | font-size: $base-font-size * 2; // 16 * 2 = 32px
23 | }
24 |
25 | h3 {
26 | font-size: $base-font-size * 1.75; // 16 * 1.75 = 28px
27 | }
28 |
29 | h4 {
30 | font-size: $base-font-size * 1.5; // 16 * 1.5 = 24px
31 | }
32 |
33 | h5 {
34 | font-size: $base-font-size * 1.25; // 16 * 1.25 = 20px
35 | }
36 |
37 | h6 {
38 | font-size: $base-font-size;
39 | }
40 |
41 | p {
42 | margin: 0 0 ($base-line-height * .5);
43 | }
44 |
45 | a {
46 | @include transition(0.1s linear);
47 | color: $base-link-color;
48 | text-decoration: underline;
49 |
50 | &:hover {
51 | color: $hover-link-color;
52 | }
53 |
54 | &:active, &:focus {
55 | color: $hover-link-color;
56 | outline: none;
57 | }
58 | }
59 |
60 | hr {
61 | border-bottom: 1px solid $base-border-color;
62 | border-left: none;
63 | border-right: none;
64 | border-top: none;
65 | margin: $base-line-height 0;
66 | }
67 |
68 | img {
69 | margin: 0;
70 | max-width: 100%;
71 | }
72 |
73 | blockquote {
74 | border-left: 2px solid $base-border-color;
75 | color: lighten($base-font-color, 15);
76 | margin: $base-line-height 0;
77 | padding-left: $base-line-height / 2;
78 | }
79 |
80 | cite {
81 | color: lighten($base-font-color, 25);
82 | font-style: italic;
83 |
84 | &:before {
85 | content: '\2014 \00A0';
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/assets/_sass/base/_variables.scss:
--------------------------------------------------------------------------------
1 | // 18F Fonts
2 | $raleway: Raleway,'Helvetica Neue',Helvetica,Arial,sans-serif;
3 | $open-sans: 'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;
4 |
5 | // Typography
6 | $sans-serif: $open-sans;
7 | $serif: $georgia;
8 | $base-font-family: $sans-serif;
9 | $header-font-family: $raleway;
10 |
11 | // Sizes
12 | $base-font-size: 1em;
13 | $base-line-height: $base-font-size * 1.5;
14 | $unitless-line-height: $base-line-height / ($base-line-height * 0 + 1); // Strip units from line-height: https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#Prefer_unitless_numbers_for_line-height_values
15 | $header-line-height: $base-font-size * 1.1;
16 | $base-border-radius: em(3);
17 | // 18F Sizes
18 | $small-text: 0.8em;
19 |
20 | // Colors
21 | $dark-gray: #333;
22 | $medium-gray: #999;
23 | $light-gray: #DDD;
24 | $light-red: #FBE3E4;
25 | $light-yellow: #FFF6BF;
26 | $light-green: #E6EFC2;
27 | // 18F Colors
28 | $blue: #1188ff;
29 | $medium-blue: #06d;
30 | $dark-blue: #03253e;
31 | $green: #5cb85c;
32 | $red: #c21;
33 |
34 | // Background Color
35 | $base-background-color: white;
36 |
37 | // Font Colors
38 | $base-font-color: $dark-gray;
39 | $base-accent-color: $medium-blue;
40 |
41 | // Link Colors
42 | $base-link-color: $base-accent-color;
43 | $hover-link-color: $red;
44 | $base-button-color: $base-link-color;
45 | $hover-button-color: darken($base-accent-color, 15);
46 |
47 | // Border color
48 | $base-border-color: $light-gray;
49 |
50 | // Flash Colors
51 | $alert-color: $light-yellow;
52 | $error-color: $light-red;
53 | $notice-color: $light-yellow;
54 | $success-color: $light-green;
55 |
56 | // Forms
57 | $form-border-color: $base-border-color;
58 | $form-border-color-hover: darken($base-border-color, 10);
59 | $form-border-color-focus: $base-accent-color;
60 | $form-border-radius: $base-border-radius;
61 | $form-box-shadow: inset 0 1px 3px rgba(0,0,0,0.06);
62 | $form-box-shadow-focus: $form-box-shadow, 0 0 5px rgba(darken($form-border-color-focus, 5), 0.7);
63 | $form-font-size: $base-font-size * 1.1;
64 | $form-font-family: $base-font-family;
65 |
--------------------------------------------------------------------------------
/assets/_sass/base/extends/_button.scss:
--------------------------------------------------------------------------------
1 | %button {
2 | -webkit-font-smoothing: antialiased;
3 | background-color: $base-button-color;
4 | border-radius: $base-border-radius;
5 | color: white;
6 | display: inline-block;
7 | font-size: $base-font-size;
8 | font-weight: bold;
9 | line-height: 1;
10 | padding: .75em 1em;
11 | text-decoration: none;
12 |
13 | &:hover {
14 | background-color: $hover-button-color;
15 | color: white;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/assets/_sass/base/extends/_clearfix.scss:
--------------------------------------------------------------------------------
1 | %clearfix {
2 | @include clearfix;
3 | }
4 |
--------------------------------------------------------------------------------
/assets/_sass/base/extends/_hide-text.scss:
--------------------------------------------------------------------------------
1 | %hide-text {
2 | @include hide-text;
3 | }
4 |
--------------------------------------------------------------------------------
/assets/_sass/base/mixins/_flash.scss:
--------------------------------------------------------------------------------
1 | @mixin flash($color) {
2 | background: $color;
3 | color: darken($color, 60);
4 | font-weight: bold;
5 | margin-bottom: $base-line-height / 2;
6 | padding: $base-line-height / 2;
7 |
8 | a {
9 | color: darken($color, 70);
10 |
11 | &:hover {
12 | color: darken($color, 90);
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/_bourbon-deprecated-upcoming.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // These mixins/functions are deprecated
3 | // They will be removed in the next MAJOR version release
4 | //************************************************************************//
5 | @mixin inline-block {
6 | display: inline-block;
7 | @warn "inline-block mixin is deprecated and will be removed in the next major version release";
8 | }
9 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/_bourbon.scss:
--------------------------------------------------------------------------------
1 | // Settings
2 | @import "settings/prefixer";
3 | @import "settings/px-to-em";
4 | @import "settings/asset-pipeline";
5 |
6 | // Custom Helpers
7 | @import "helpers/convert-units";
8 | @import "helpers/gradient-positions-parser";
9 | @import "helpers/is-num";
10 | @import "helpers/linear-angle-parser";
11 | @import "helpers/linear-gradient-parser";
12 | @import "helpers/linear-positions-parser";
13 | @import "helpers/linear-side-corner-parser";
14 | @import "helpers/radial-arg-parser";
15 | @import "helpers/radial-positions-parser";
16 | @import "helpers/radial-gradient-parser";
17 | @import "helpers/render-gradients";
18 | @import "helpers/shape-size-stripper";
19 | @import "helpers/str-to-num";
20 |
21 | // Custom Functions
22 | @import "functions/assign";
23 | @import "functions/color-lightness";
24 | @import "functions/flex-grid";
25 | @import "functions/golden-ratio";
26 | @import "functions/grid-width";
27 | @import "functions/modular-scale";
28 | @import "functions/px-to-em";
29 | @import "functions/px-to-rem";
30 | @import "functions/strip-units";
31 | @import "functions/tint-shade";
32 | @import "functions/transition-property-name";
33 | @import "functions/unpack";
34 |
35 | // CSS3 Mixins
36 | @import "css3/animation";
37 | @import "css3/appearance";
38 | @import "css3/backface-visibility";
39 | @import "css3/background";
40 | @import "css3/background-image";
41 | @import "css3/border-image";
42 | @import "css3/border-radius";
43 | @import "css3/box-sizing";
44 | @import "css3/calc";
45 | @import "css3/columns";
46 | @import "css3/filter";
47 | @import "css3/flex-box";
48 | @import "css3/font-face";
49 | @import "css3/font-feature-settings";
50 | @import "css3/hyphens";
51 | @import "css3/hidpi-media-query";
52 | @import "css3/image-rendering";
53 | @import "css3/keyframes";
54 | @import "css3/linear-gradient";
55 | @import "css3/perspective";
56 | @import "css3/radial-gradient";
57 | @import "css3/transform";
58 | @import "css3/transition";
59 | @import "css3/user-select";
60 | @import "css3/placeholder";
61 |
62 | // Addons & other mixins
63 | @import "addons/button";
64 | @import "addons/clearfix";
65 | @import "addons/directional-values";
66 | @import "addons/ellipsis";
67 | @import "addons/font-family";
68 | @import "addons/hide-text";
69 | @import "addons/html5-input-types";
70 | @import "addons/position";
71 | @import "addons/prefixer";
72 | @import "addons/retina-image";
73 | @import "addons/size";
74 | @import "addons/timing-functions";
75 | @import "addons/triangle";
76 | @import "addons/word-wrap";
77 |
78 | // Soon to be deprecated Mixins
79 | @import "bourbon-deprecated-upcoming";
80 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_clearfix.scss:
--------------------------------------------------------------------------------
1 | // Modern micro clearfix provides an easy way to contain floats without adding additional markup.
2 | //
3 | // Example usage:
4 | //
5 | // // Contain all floats within .wrapper
6 | // .wrapper {
7 | // @include clearfix;
8 | // .content,
9 | // .sidebar {
10 | // float : left;
11 | // }
12 | // }
13 |
14 | @mixin clearfix {
15 | &:after {
16 | content:"";
17 | display:table;
18 | clear:both;
19 | }
20 | }
21 |
22 | // Acknowledgements
23 | // Beat *that* clearfix: [Thierry Koblentz](http://www.css-101.org/articles/clearfix/latest-new-clearfix-so-far.php)
24 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_directional-values.scss:
--------------------------------------------------------------------------------
1 | // directional-property mixins are shorthands
2 | // for writing properties like the following
3 | //
4 | // @include margin(null 0 10px);
5 | // ------
6 | // margin-right: 0;
7 | // margin-bottom: 10px;
8 | // margin-left: 0;
9 | //
10 | // - or -
11 | //
12 | // @include border-style(dotted null);
13 | // ------
14 | // border-top-style: dotted;
15 | // border-bottom-style: dotted;
16 | //
17 | // ------
18 | //
19 | // Note: You can also use false instead of null
20 |
21 | @function collapse-directionals($vals) {
22 | $output: null;
23 |
24 | $A: nth( $vals, 1 );
25 | $B: if( length($vals) < 2, $A, nth($vals, 2));
26 | $C: if( length($vals) < 3, $A, nth($vals, 3));
27 | $D: if( length($vals) < 2, $A, nth($vals, if( length($vals) < 4, 2, 4) ));
28 |
29 | @if $A == 0 { $A: 0 }
30 | @if $B == 0 { $B: 0 }
31 | @if $C == 0 { $C: 0 }
32 | @if $D == 0 { $D: 0 }
33 |
34 | @if $A == $B and $A == $C and $A == $D { $output: $A }
35 | @else if $A == $C and $B == $D { $output: $A $B }
36 | @else if $B == $D { $output: $A $B $C }
37 | @else { $output: $A $B $C $D }
38 |
39 | @return $output;
40 | }
41 |
42 | @function contains-falsy($list) {
43 | @each $item in $list {
44 | @if not $item {
45 | @return true;
46 | }
47 | }
48 |
49 | @return false;
50 | }
51 |
52 | @mixin directional-property($pre, $suf, $vals) {
53 | // Property Names
54 | $top: $pre + "-top" + if($suf, "-#{$suf}", "");
55 | $bottom: $pre + "-bottom" + if($suf, "-#{$suf}", "");
56 | $left: $pre + "-left" + if($suf, "-#{$suf}", "");
57 | $right: $pre + "-right" + if($suf, "-#{$suf}", "");
58 | $all: $pre + if($suf, "-#{$suf}", "");
59 |
60 | $vals: collapse-directionals($vals);
61 |
62 | @if contains-falsy($vals) {
63 | @if nth($vals, 1) { #{$top}: nth($vals, 1); }
64 |
65 | @if length($vals) == 1 {
66 | @if nth($vals, 1) { #{$right}: nth($vals, 1); }
67 | } @else {
68 | @if nth($vals, 2) { #{$right}: nth($vals, 2); }
69 | }
70 |
71 | // prop: top/bottom right/left
72 | @if length($vals) == 2 {
73 | @if nth($vals, 1) { #{$bottom}: nth($vals, 1); }
74 | @if nth($vals, 2) { #{$left}: nth($vals, 2); }
75 |
76 | // prop: top right/left bottom
77 | } @else if length($vals) == 3 {
78 | @if nth($vals, 3) { #{$bottom}: nth($vals, 3); }
79 | @if nth($vals, 2) { #{$left}: nth($vals, 2); }
80 |
81 | // prop: top right bottom left
82 | } @else if length($vals) == 4 {
83 | @if nth($vals, 3) { #{$bottom}: nth($vals, 3); }
84 | @if nth($vals, 4) { #{$left}: nth($vals, 4); }
85 | }
86 |
87 | // prop: top/right/bottom/left
88 | } @else {
89 | #{$all}: $vals;
90 | }
91 | }
92 |
93 | @mixin margin($vals...) {
94 | @include directional-property(margin, false, $vals...);
95 | }
96 |
97 | @mixin padding($vals...) {
98 | @include directional-property(padding, false, $vals...);
99 | }
100 |
101 | @mixin border-style($vals...) {
102 | @include directional-property(border, style, $vals...);
103 | }
104 |
105 | @mixin border-color($vals...) {
106 | @include directional-property(border, color, $vals...);
107 | }
108 |
109 | @mixin border-width($vals...) {
110 | @include directional-property(border, width, $vals...);
111 | }
112 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_ellipsis.scss:
--------------------------------------------------------------------------------
1 | @mixin ellipsis($width: 100%) {
2 | display: inline-block;
3 | max-width: $width;
4 | overflow: hidden;
5 | text-overflow: ellipsis;
6 | white-space: nowrap;
7 | }
8 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_font-family.scss:
--------------------------------------------------------------------------------
1 | $georgia: Georgia, Cambria, "Times New Roman", Times, serif;
2 | $helvetica: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
3 | $lucida-grande: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
4 | $monospace: "Bitstream Vera Sans Mono", Consolas, Courier, monospace;
5 | $verdana: Verdana, Geneva, sans-serif;
6 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_hide-text.scss:
--------------------------------------------------------------------------------
1 | @mixin hide-text {
2 | overflow: hidden;
3 |
4 | &:before {
5 | content: "";
6 | display: block;
7 | width: 0;
8 | height: 100%;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_html5-input-types.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Generate a variable ($all-text-inputs) with a list of all html5
3 | // input types that have a text-based input, excluding textarea.
4 | // http://diveintohtml5.org/forms.html
5 | //************************************************************************//
6 | $inputs-list: 'input[type="email"]',
7 | 'input[type="number"]',
8 | 'input[type="password"]',
9 | 'input[type="search"]',
10 | 'input[type="tel"]',
11 | 'input[type="text"]',
12 | 'input[type="url"]',
13 |
14 | // Webkit & Gecko may change the display of these in the future
15 | 'input[type="color"]',
16 | 'input[type="date"]',
17 | 'input[type="datetime"]',
18 | 'input[type="datetime-local"]',
19 | 'input[type="month"]',
20 | 'input[type="time"]',
21 | 'input[type="week"]';
22 |
23 | // Bare inputs
24 | //************************************************************************//
25 | $all-text-inputs: assign-inputs($inputs-list);
26 |
27 | // Hover Pseudo-class
28 | //************************************************************************//
29 | $all-text-inputs-hover: assign-inputs($inputs-list, hover);
30 |
31 | // Focus Pseudo-class
32 | //************************************************************************//
33 | $all-text-inputs-focus: assign-inputs($inputs-list, focus);
34 |
35 |
36 |
37 | // You must use interpolation on the variable:
38 | // #{$all-text-inputs}
39 | // #{$all-text-inputs-hover}
40 | // #{$all-text-inputs-focus}
41 |
42 | // Example
43 | //************************************************************************//
44 | // #{$all-text-inputs}, textarea {
45 | // border: 1px solid red;
46 | // }
47 |
48 |
49 |
50 | //************************************************************************//
51 | // Generate a variable ($all-button-inputs) with a list of all html5
52 | // input types that have a button-based input, excluding button.
53 | //************************************************************************//
54 | $inputs-button-list: 'input[type="button"]',
55 | 'input[type="reset"]',
56 | 'input[type="submit"]';
57 |
58 | // Bare inputs
59 | //************************************************************************//
60 | $all-button-inputs: assign-inputs($inputs-button-list);
61 |
62 | // Hover Pseudo-class
63 | //************************************************************************//
64 | $all-button-inputs-hover: assign-inputs($inputs-button-list, hover);
65 |
66 | // Focus Pseudo-class
67 | //************************************************************************//
68 | $all-button-inputs-focus: assign-inputs($inputs-button-list, focus);
69 |
70 | // Active Pseudo-class
71 | //************************************************************************//
72 | $all-button-inputs-active: assign-inputs($inputs-button-list, active);
73 |
74 |
75 |
76 | // You must use interpolation on the variable:
77 | // #{$all-button-inputs}
78 | // #{$all-button-inputs-hover}
79 | // #{$all-button-inputs-focus}
80 | // #{$all-button-inputs-active}
81 |
82 | // Example
83 | //************************************************************************//
84 | // #{$all-button-inputs}, button {
85 | // border: 1px solid red;
86 | // }
87 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_position.scss:
--------------------------------------------------------------------------------
1 | @mixin position ($position: relative, $coordinates: null null null null) {
2 |
3 | @if type-of($position) == list {
4 | $coordinates: $position;
5 | $position: relative;
6 | }
7 |
8 | $coordinates: unpack($coordinates);
9 |
10 | $top: nth($coordinates, 1);
11 | $right: nth($coordinates, 2);
12 | $bottom: nth($coordinates, 3);
13 | $left: nth($coordinates, 4);
14 |
15 | position: $position;
16 |
17 | @if ($top and $top == auto) or (type-of($top) == number) {
18 | top: $top;
19 | }
20 |
21 | @if ($right and $right == auto) or (type-of($right) == number) {
22 | right: $right;
23 | }
24 |
25 | @if ($bottom and $bottom == auto) or (type-of($bottom) == number) {
26 | bottom: $bottom;
27 | }
28 |
29 | @if ($left and $left == auto) or (type-of($left) == number) {
30 | left: $left;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_prefixer.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Example: @include prefixer(border-radius, $radii, webkit ms spec);
3 | //************************************************************************//
4 | // Variables located in /settings/_prefixer.scss
5 |
6 | @mixin prefixer ($property, $value, $prefixes) {
7 | @each $prefix in $prefixes {
8 | @if $prefix == webkit {
9 | @if $prefix-for-webkit {
10 | -webkit-#{$property}: $value;
11 | }
12 | }
13 | @else if $prefix == moz {
14 | @if $prefix-for-mozilla {
15 | -moz-#{$property}: $value;
16 | }
17 | }
18 | @else if $prefix == ms {
19 | @if $prefix-for-microsoft {
20 | -ms-#{$property}: $value;
21 | }
22 | }
23 | @else if $prefix == o {
24 | @if $prefix-for-opera {
25 | -o-#{$property}: $value;
26 | }
27 | }
28 | @else if $prefix == spec {
29 | @if $prefix-for-spec {
30 | #{$property}: $value;
31 | }
32 | }
33 | @else {
34 | @warn "Unrecognized prefix: #{$prefix}";
35 | }
36 | }
37 | }
38 |
39 | @mixin disable-prefix-for-all() {
40 | $prefix-for-webkit: false !global;
41 | $prefix-for-mozilla: false !global;
42 | $prefix-for-microsoft: false !global;
43 | $prefix-for-opera: false !global;
44 | $prefix-for-spec: false !global;
45 | }
46 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_retina-image.scss:
--------------------------------------------------------------------------------
1 | @mixin retina-image($filename, $background-size, $extension: png, $retina-filename: null, $retina-suffix: _2x, $asset-pipeline: $asset-pipeline) {
2 | @if $asset-pipeline {
3 | background-image: image-url("#{$filename}.#{$extension}");
4 | }
5 | @else {
6 | background-image: url("#{$filename}.#{$extension}");
7 | }
8 |
9 | @include hidpi {
10 | @if $asset-pipeline {
11 | @if $retina-filename {
12 | background-image: image-url("#{$retina-filename}.#{$extension}");
13 | }
14 | @else {
15 | background-image: image-url("#{$filename}#{$retina-suffix}.#{$extension}");
16 | }
17 | }
18 |
19 | @else {
20 | @if $retina-filename {
21 | background-image: url("#{$retina-filename}.#{$extension}");
22 | }
23 | @else {
24 | background-image: url("#{$filename}#{$retina-suffix}.#{$extension}");
25 | }
26 | }
27 |
28 | background-size: $background-size;
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_size.scss:
--------------------------------------------------------------------------------
1 | @mixin size($size) {
2 | $height: nth($size, 1);
3 | $width: $height;
4 |
5 | @if length($size) > 1 {
6 | $height: nth($size, 2);
7 | }
8 |
9 | @if $height == auto or (type-of($height) == number and not unitless($height)) {
10 | height: $height;
11 | }
12 |
13 | @if $width == auto or (type-of($width) == number and not unitless($width)) {
14 | width: $width;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_timing-functions.scss:
--------------------------------------------------------------------------------
1 | // CSS cubic-bezier timing functions. Timing functions courtesy of jquery.easie (github.com/jaukia/easie)
2 | // Timing functions are the same as demo'ed here: http://jqueryui.com/resources/demos/effect/easing.html
3 |
4 | // EASE IN
5 | $ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530);
6 | $ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190);
7 | $ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220);
8 | $ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060);
9 | $ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715);
10 | $ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035);
11 | $ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335);
12 | $ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045);
13 |
14 | // EASE OUT
15 | $ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940);
16 | $ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000);
17 | $ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000);
18 | $ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000);
19 | $ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000);
20 | $ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000);
21 | $ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000);
22 | $ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275);
23 |
24 | // EASE IN OUT
25 | $ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955);
26 | $ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000);
27 | $ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000);
28 | $ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000);
29 | $ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950);
30 | $ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000);
31 | $ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860);
32 | $ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550);
33 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_triangle.scss:
--------------------------------------------------------------------------------
1 | @mixin triangle ($size, $color, $direction) {
2 | height: 0;
3 | width: 0;
4 |
5 | $width: nth($size, 1);
6 | $height: nth($size, length($size));
7 |
8 | $foreground-color: nth($color, 1);
9 | $background-color: if(length($color) == 2, nth($color, 2), transparent);
10 |
11 | @if ($direction == up) or ($direction == down) or ($direction == right) or ($direction == left) {
12 |
13 | $width: $width / 2;
14 | $height: if(length($size) > 1, $height, $height/2);
15 |
16 | @if $direction == up {
17 | border-left: $width solid $background-color;
18 | border-right: $width solid $background-color;
19 | border-bottom: $height solid $foreground-color;
20 |
21 | } @else if $direction == right {
22 | border-top: $width solid $background-color;
23 | border-bottom: $width solid $background-color;
24 | border-left: $height solid $foreground-color;
25 |
26 | } @else if $direction == down {
27 | border-left: $width solid $background-color;
28 | border-right: $width solid $background-color;
29 | border-top: $height solid $foreground-color;
30 |
31 | } @else if $direction == left {
32 | border-top: $width solid $background-color;
33 | border-bottom: $width solid $background-color;
34 | border-right: $height solid $foreground-color;
35 | }
36 | }
37 |
38 | @else if ($direction == up-right) or ($direction == up-left) {
39 | border-top: $height solid $foreground-color;
40 |
41 | @if $direction == up-right {
42 | border-left: $width solid $background-color;
43 |
44 | } @else if $direction == up-left {
45 | border-right: $width solid $background-color;
46 | }
47 | }
48 |
49 | @else if ($direction == down-right) or ($direction == down-left) {
50 | border-bottom: $height solid $foreground-color;
51 |
52 | @if $direction == down-right {
53 | border-left: $width solid $background-color;
54 |
55 | } @else if $direction == down-left {
56 | border-right: $width solid $background-color;
57 | }
58 | }
59 |
60 | @else if ($direction == inset-up) {
61 | border-width: $height $width;
62 | border-style: solid;
63 | border-color: $background-color $background-color $foreground-color;
64 | }
65 |
66 | @else if ($direction == inset-down) {
67 | border-width: $height $width;
68 | border-style: solid;
69 | border-color: $foreground-color $background-color $background-color;
70 | }
71 |
72 | @else if ($direction == inset-right) {
73 | border-width: $width $height;
74 | border-style: solid;
75 | border-color: $background-color $background-color $background-color $foreground-color;
76 | }
77 |
78 | @else if ($direction == inset-left) {
79 | border-width: $width $height;
80 | border-style: solid;
81 | border-color: $background-color $foreground-color $background-color $background-color;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/addons/_word-wrap.scss:
--------------------------------------------------------------------------------
1 | @mixin word-wrap($wrap: break-word) {
2 | word-wrap: $wrap;
3 |
4 | @if $wrap == break-word {
5 | overflow-wrap: break-word;
6 | word-break: break-all;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_animation.scss:
--------------------------------------------------------------------------------
1 | // http://www.w3.org/TR/css3-animations/#the-animation-name-property-
2 | // Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties.
3 |
4 | // Official animation shorthand property.
5 | @mixin animation ($animations...) {
6 | @include prefixer(animation, $animations, webkit moz spec);
7 | }
8 |
9 | // Individual Animation Properties
10 | @mixin animation-name ($names...) {
11 | @include prefixer(animation-name, $names, webkit moz spec);
12 | }
13 |
14 |
15 | @mixin animation-duration ($times...) {
16 | @include prefixer(animation-duration, $times, webkit moz spec);
17 | }
18 |
19 |
20 | @mixin animation-timing-function ($motions...) {
21 | // ease | linear | ease-in | ease-out | ease-in-out
22 | @include prefixer(animation-timing-function, $motions, webkit moz spec);
23 | }
24 |
25 |
26 | @mixin animation-iteration-count ($values...) {
27 | // infinite |
28 | @include prefixer(animation-iteration-count, $values, webkit moz spec);
29 | }
30 |
31 |
32 | @mixin animation-direction ($directions...) {
33 | // normal | alternate
34 | @include prefixer(animation-direction, $directions, webkit moz spec);
35 | }
36 |
37 |
38 | @mixin animation-play-state ($states...) {
39 | // running | paused
40 | @include prefixer(animation-play-state, $states, webkit moz spec);
41 | }
42 |
43 |
44 | @mixin animation-delay ($times...) {
45 | @include prefixer(animation-delay, $times, webkit moz spec);
46 | }
47 |
48 |
49 | @mixin animation-fill-mode ($modes...) {
50 | // none | forwards | backwards | both
51 | @include prefixer(animation-fill-mode, $modes, webkit moz spec);
52 | }
53 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_appearance.scss:
--------------------------------------------------------------------------------
1 | @mixin appearance ($value) {
2 | @include prefixer(appearance, $value, webkit moz ms o spec);
3 | }
4 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_backface-visibility.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Backface-visibility mixin
3 | //************************************************************************//
4 | @mixin backface-visibility($visibility) {
5 | @include prefixer(backface-visibility, $visibility, webkit spec);
6 | }
7 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_background-image.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Background-image property for adding multiple background images with
3 | // gradients, or for stringing multiple gradients together.
4 | //************************************************************************//
5 |
6 | @mixin background-image($images...) {
7 | $webkit-images: ();
8 | $spec-images: ();
9 |
10 | @each $image in $images {
11 | $webkit-image: ();
12 | $spec-image: ();
13 |
14 | @if (type-of($image) == string) {
15 | $url-str: str-slice($image, 0, 3);
16 | $gradient-type: str-slice($image, 0, 6);
17 |
18 | @if $url-str == "url" {
19 | $webkit-image: $image;
20 | $spec-image: $image;
21 | }
22 |
23 | @else if $gradient-type == "linear" {
24 | $gradients: _linear-gradient-parser($image);
25 | $webkit-image: map-get($gradients, webkit-image);
26 | $spec-image: map-get($gradients, spec-image);
27 | }
28 |
29 | @else if $gradient-type == "radial" {
30 | $gradients: _radial-gradient-parser($image);
31 | $webkit-image: map-get($gradients, webkit-image);
32 | $spec-image: map-get($gradients, spec-image);
33 | }
34 | }
35 |
36 | $webkit-images: append($webkit-images, $webkit-image, comma);
37 | $spec-images: append($spec-images, $spec-image, comma);
38 | }
39 |
40 | background-image: $webkit-images;
41 | background-image: $spec-images;
42 | }
43 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_background.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Background property for adding multiple backgrounds using shorthand
3 | // notation.
4 | //************************************************************************//
5 |
6 | @mixin background($backgrounds...) {
7 | $webkit-backgrounds: ();
8 | $spec-backgrounds: ();
9 |
10 | @each $background in $backgrounds {
11 | $webkit-background: ();
12 | $spec-background: ();
13 | $background-type: type-of($background);
14 |
15 | @if $background-type == string or list {
16 | $background-str: if($background-type == list, nth($background, 1), $background);
17 |
18 | $url-str: str-slice($background-str, 0, 3);
19 | $gradient-type: str-slice($background-str, 0, 6);
20 |
21 | @if $url-str == "url" {
22 | $webkit-background: $background;
23 | $spec-background: $background;
24 | }
25 |
26 | @else if $gradient-type == "linear" {
27 | $gradients: _linear-gradient-parser("#{$background}");
28 | $webkit-background: map-get($gradients, webkit-image);
29 | $spec-background: map-get($gradients, spec-image);
30 | }
31 |
32 | @else if $gradient-type == "radial" {
33 | $gradients: _radial-gradient-parser("#{$background}");
34 | $webkit-background: map-get($gradients, webkit-image);
35 | $spec-background: map-get($gradients, spec-image);
36 | }
37 |
38 | @else {
39 | $webkit-background: $background;
40 | $spec-background: $background;
41 | }
42 | }
43 |
44 | @else {
45 | $webkit-background: $background;
46 | $spec-background: $background;
47 | }
48 |
49 | $webkit-backgrounds: append($webkit-backgrounds, $webkit-background, comma);
50 | $spec-backgrounds: append($spec-backgrounds, $spec-background, comma);
51 | }
52 |
53 | background: $webkit-backgrounds;
54 | background: $spec-backgrounds;
55 | }
56 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_border-image.scss:
--------------------------------------------------------------------------------
1 | @mixin border-image($borders...) {
2 | $webkit-borders: ();
3 | $spec-borders: ();
4 |
5 | @each $border in $borders {
6 | $webkit-border: ();
7 | $spec-border: ();
8 | $border-type: type-of($border);
9 |
10 | @if $border-type == string or list {
11 | $border-str: if($border-type == list, nth($border, 1), $border);
12 |
13 | $url-str: str-slice($border-str, 0, 3);
14 | $gradient-type: str-slice($border-str, 0, 6);
15 |
16 | @if $url-str == "url" {
17 | $webkit-border: $border;
18 | $spec-border: $border;
19 | }
20 |
21 | @else if $gradient-type == "linear" {
22 | $gradients: _linear-gradient-parser("#{$border}");
23 | $webkit-border: map-get($gradients, webkit-image);
24 | $spec-border: map-get($gradients, spec-image);
25 | }
26 |
27 | @else if $gradient-type == "radial" {
28 | $gradients: _radial-gradient-parser("#{$border}");
29 | $webkit-border: map-get($gradients, webkit-image);
30 | $spec-border: map-get($gradients, spec-image);
31 | }
32 |
33 | @else {
34 | $webkit-border: $border;
35 | $spec-border: $border;
36 | }
37 | }
38 |
39 | @else {
40 | $webkit-border: $border;
41 | $spec-border: $border;
42 | }
43 |
44 | $webkit-borders: append($webkit-borders, $webkit-border, comma);
45 | $spec-borders: append($spec-borders, $spec-border, comma);
46 | }
47 |
48 | -webkit-border-image: $webkit-borders;
49 | border-image: $spec-borders;
50 | border-style: solid;
51 | }
52 |
53 | //Examples:
54 | // @include border-image(url("image.png"));
55 | // @include border-image(url("image.png") 20 stretch);
56 | // @include border-image(linear-gradient(45deg, orange, yellow));
57 | // @include border-image(linear-gradient(45deg, orange, yellow) stretch);
58 | // @include border-image(linear-gradient(45deg, orange, yellow) 20 30 40 50 stretch round);
59 | // @include border-image(radial-gradient(top, cover, orange, yellow, orange));
60 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_border-radius.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Shorthand Border-radius mixins
3 | //************************************************************************//
4 | @mixin border-top-radius($radii) {
5 | @include prefixer(border-top-left-radius, $radii, spec);
6 | @include prefixer(border-top-right-radius, $radii, spec);
7 | }
8 |
9 | @mixin border-bottom-radius($radii) {
10 | @include prefixer(border-bottom-left-radius, $radii, spec);
11 | @include prefixer(border-bottom-right-radius, $radii, spec);
12 | }
13 |
14 | @mixin border-left-radius($radii) {
15 | @include prefixer(border-top-left-radius, $radii, spec);
16 | @include prefixer(border-bottom-left-radius, $radii, spec);
17 | }
18 |
19 | @mixin border-right-radius($radii) {
20 | @include prefixer(border-top-right-radius, $radii, spec);
21 | @include prefixer(border-bottom-right-radius, $radii, spec);
22 | }
23 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_box-sizing.scss:
--------------------------------------------------------------------------------
1 | @mixin box-sizing ($box) {
2 | // content-box | border-box | inherit
3 | @include prefixer(box-sizing, $box, webkit moz spec);
4 | }
5 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_calc.scss:
--------------------------------------------------------------------------------
1 | @mixin calc($property, $value) {
2 | #{$property}: -webkit-calc(#{$value});
3 | #{$property}: calc(#{$value});
4 | }
5 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_columns.scss:
--------------------------------------------------------------------------------
1 | @mixin columns($arg: auto) {
2 | // ||
3 | @include prefixer(columns, $arg, webkit moz spec);
4 | }
5 |
6 | @mixin column-count($int: auto) {
7 | // auto || integer
8 | @include prefixer(column-count, $int, webkit moz spec);
9 | }
10 |
11 | @mixin column-gap($length: normal) {
12 | // normal || length
13 | @include prefixer(column-gap, $length, webkit moz spec);
14 | }
15 |
16 | @mixin column-fill($arg: auto) {
17 | // auto || length
18 | @include prefixer(column-fill, $arg, webkit moz spec);
19 | }
20 |
21 | @mixin column-rule($arg) {
22 | // || ||
23 | @include prefixer(column-rule, $arg, webkit moz spec);
24 | }
25 |
26 | @mixin column-rule-color($color) {
27 | @include prefixer(column-rule-color, $color, webkit moz spec);
28 | }
29 |
30 | @mixin column-rule-style($style: none) {
31 | // none | hidden | dashed | dotted | double | groove | inset | inset | outset | ridge | solid
32 | @include prefixer(column-rule-style, $style, webkit moz spec);
33 | }
34 |
35 | @mixin column-rule-width ($width: none) {
36 | @include prefixer(column-rule-width, $width, webkit moz spec);
37 | }
38 |
39 | @mixin column-span($arg: none) {
40 | // none || all
41 | @include prefixer(column-span, $arg, webkit moz spec);
42 | }
43 |
44 | @mixin column-width($length: auto) {
45 | // auto || length
46 | @include prefixer(column-width, $length, webkit moz spec);
47 | }
48 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_filter.scss:
--------------------------------------------------------------------------------
1 | @mixin filter($function: none) {
2 | // [
3 | @include prefixer(perspective, $depth, webkit moz spec);
4 | }
5 |
6 | @mixin perspective-origin($value: 50% 50%) {
7 | @include prefixer(perspective-origin, $value, webkit moz spec);
8 | }
9 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_placeholder.scss:
--------------------------------------------------------------------------------
1 | @mixin placeholder {
2 | $placeholders: ":-webkit-input" ":-moz" "-moz" "-ms-input";
3 | @each $placeholder in $placeholders {
4 | &:#{$placeholder}-placeholder {
5 | @content;
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_radial-gradient.scss:
--------------------------------------------------------------------------------
1 | // Requires Sass 3.1+
2 | @mixin radial-gradient($G1, $G2,
3 | $G3: null, $G4: null,
4 | $G5: null, $G6: null,
5 | $G7: null, $G8: null,
6 | $G9: null, $G10: null,
7 | $pos: null,
8 | $shape-size: null,
9 | $fallback: null) {
10 |
11 | $data: _radial-arg-parser($G1, $G2, $pos, $shape-size);
12 | $G1: nth($data, 1);
13 | $G2: nth($data, 2);
14 | $pos: nth($data, 3);
15 | $shape-size: nth($data, 4);
16 |
17 | $full: $G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10;
18 |
19 | // Strip deprecated cover/contain for spec
20 | $shape-size-spec: _shape-size-stripper($shape-size);
21 |
22 | // Set $G1 as the default fallback color
23 | $first-color: nth($full, 1);
24 | $fallback-color: nth($first-color, 1);
25 |
26 | @if (type-of($fallback) == color) or ($fallback == "transparent") {
27 | $fallback-color: $fallback;
28 | }
29 |
30 | // Add Commas and spaces
31 | $shape-size: if($shape-size, '#{$shape-size}, ', null);
32 | $pos: if($pos, '#{$pos}, ', null);
33 | $pos-spec: if($pos, 'at #{$pos}', null);
34 | $shape-size-spec: if(($shape-size-spec != ' ') and ($pos == null), '#{$shape-size-spec}, ', '#{$shape-size-spec} ');
35 |
36 | background-color: $fallback-color;
37 | background-image: -webkit-radial-gradient(unquote(#{$pos}#{$shape-size}#{$full}));
38 | background-image: unquote("radial-gradient(#{$shape-size-spec}#{$pos-spec}#{$full})");
39 | }
40 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_transform.scss:
--------------------------------------------------------------------------------
1 | @mixin transform($property: none) {
2 | // none |
3 | @include prefixer(transform, $property, webkit moz ms o spec);
4 | }
5 |
6 | @mixin transform-origin($axes: 50%) {
7 | // x-axis - left | center | right | length | %
8 | // y-axis - top | center | bottom | length | %
9 | // z-axis - length
10 | @include prefixer(transform-origin, $axes, webkit moz ms o spec);
11 | }
12 |
13 | @mixin transform-style ($style: flat) {
14 | @include prefixer(transform-style, $style, webkit moz ms o spec);
15 | }
16 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_transition.scss:
--------------------------------------------------------------------------------
1 | // Shorthand mixin. Supports multiple parentheses-deliminated values for each variable.
2 | // Example: @include transition (all 2s ease-in-out);
3 | // @include transition (opacity 1s ease-in 2s, width 2s ease-out);
4 | // @include transition-property (transform, opacity);
5 |
6 | @mixin transition ($properties...) {
7 | // Fix for vendor-prefix transform property
8 | $needs-prefixes: false;
9 | $webkit: ();
10 | $moz: ();
11 | $spec: ();
12 |
13 | // Create lists for vendor-prefixed transform
14 | @each $list in $properties {
15 | @if nth($list, 1) == "transform" {
16 | $needs-prefixes: true;
17 | $list1: -webkit-transform;
18 | $list2: -moz-transform;
19 | $list3: ();
20 |
21 | @each $var in $list {
22 | $list3: join($list3, $var);
23 |
24 | @if $var != "transform" {
25 | $list1: join($list1, $var);
26 | $list2: join($list2, $var);
27 | }
28 | }
29 |
30 | $webkit: append($webkit, $list1);
31 | $moz: append($moz, $list2);
32 | $spec: append($spec, $list3);
33 | }
34 |
35 | // Create lists for non-prefixed transition properties
36 | @else {
37 | $webkit: append($webkit, $list, comma);
38 | $moz: append($moz, $list, comma);
39 | $spec: append($spec, $list, comma);
40 | }
41 | }
42 |
43 | @if $needs-prefixes {
44 | -webkit-transition: $webkit;
45 | -moz-transition: $moz;
46 | transition: $spec;
47 | }
48 | @else {
49 | @if length($properties) >= 1 {
50 | @include prefixer(transition, $properties, webkit moz spec);
51 | }
52 |
53 | @else {
54 | $properties: all 0.15s ease-out 0s;
55 | @include prefixer(transition, $properties, webkit moz spec);
56 | }
57 | }
58 | }
59 |
60 | @mixin transition-property ($properties...) {
61 | -webkit-transition-property: transition-property-names($properties, 'webkit');
62 | -moz-transition-property: transition-property-names($properties, 'moz');
63 | transition-property: transition-property-names($properties, false);
64 | }
65 |
66 | @mixin transition-duration ($times...) {
67 | @include prefixer(transition-duration, $times, webkit moz spec);
68 | }
69 |
70 | @mixin transition-timing-function ($motions...) {
71 | // ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier()
72 | @include prefixer(transition-timing-function, $motions, webkit moz spec);
73 | }
74 |
75 | @mixin transition-delay ($times...) {
76 | @include prefixer(transition-delay, $times, webkit moz spec);
77 | }
78 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/css3/_user-select.scss:
--------------------------------------------------------------------------------
1 | @mixin user-select($arg: none) {
2 | @include prefixer(user-select, $arg, webkit moz ms spec);
3 | }
4 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_assign.scss:
--------------------------------------------------------------------------------
1 | @function assign-inputs($inputs, $pseudo: null) {
2 | $list : ();
3 |
4 | @each $input in $inputs {
5 | $input: unquote($input);
6 | $input: if($pseudo, $input + ":" + $pseudo, $input);
7 | $list: append($list, $input, comma);
8 | }
9 |
10 | @return $list;
11 | }
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_color-lightness.scss:
--------------------------------------------------------------------------------
1 | // Programatically determines whether a color is light or dark
2 | // Returns a boolean
3 | // More details here http://robots.thoughtbot.com/closer-look-color-lightness
4 |
5 | @function is-light($hex-color) {
6 | $-local-red: red(rgba($hex-color, 1.0));
7 | $-local-green: green(rgba($hex-color, 1.0));
8 | $-local-blue: blue(rgba($hex-color, 1.0));
9 |
10 | $-local-lightness: ($-local-red * 0.2126 + $-local-green * 0.7152 + $-local-blue * 0.0722) / 255;
11 |
12 | @return $-local-lightness > .6;
13 | }
14 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_flex-grid.scss:
--------------------------------------------------------------------------------
1 | // Flexible grid
2 | @function flex-grid($columns, $container-columns: $fg-max-columns) {
3 | $width: $columns * $fg-column + ($columns - 1) * $fg-gutter;
4 | $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
5 | @return percentage($width / $container-width);
6 | }
7 |
8 | // Flexible gutter
9 | @function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) {
10 | $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
11 | @return percentage($gutter / $container-width);
12 | }
13 |
14 | // The $fg-column, $fg-gutter and $fg-max-columns variables must be defined in your base stylesheet to properly use the flex-grid function.
15 | // This function takes the fluid grid equation (target / context = result) and uses columns to help define each.
16 | //
17 | // The calculation presumes that your column structure will be missing the last gutter:
18 | //
19 | // -- column -- gutter -- column -- gutter -- column
20 | //
21 | // $fg-column: 60px; // Column Width
22 | // $fg-gutter: 25px; // Gutter Width
23 | // $fg-max-columns: 12; // Total Columns For Main Container
24 | //
25 | // div {
26 | // width: flex-grid(4); // returns (315px / 995px) = 31.65829%;
27 | // margin-left: flex-gutter(); // returns (25px / 995px) = 2.51256%;
28 | //
29 | // p {
30 | // width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%;
31 | // float: left;
32 | // margin: flex-gutter(4); // returns (25px / 315px) = 7.936508%;
33 | // }
34 | //
35 | // blockquote {
36 | // float: left;
37 | // width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%;
38 | // }
39 | // }
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_golden-ratio.scss:
--------------------------------------------------------------------------------
1 | @function golden-ratio($value, $increment) {
2 | @return modular-scale($value, $increment, $golden)
3 | }
4 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_grid-width.scss:
--------------------------------------------------------------------------------
1 | @function grid-width($n) {
2 | @return $n * $gw-column + ($n - 1) * $gw-gutter;
3 | }
4 |
5 | // The $gw-column and $gw-gutter variables must be defined in your base stylesheet to properly use the grid-width function.
6 | //
7 | // $gw-column: 100px; // Column Width
8 | // $gw-gutter: 40px; // Gutter Width
9 | //
10 | // div {
11 | // width: grid-width(4); // returns 520px;
12 | // margin-left: $gw-gutter; // returns 40px;
13 | // }
14 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_modular-scale.scss:
--------------------------------------------------------------------------------
1 | // Scaling Variables
2 | $golden: 1.618;
3 | $minor-second: 1.067;
4 | $major-second: 1.125;
5 | $minor-third: 1.2;
6 | $major-third: 1.25;
7 | $perfect-fourth: 1.333;
8 | $augmented-fourth: 1.414;
9 | $perfect-fifth: 1.5;
10 | $minor-sixth: 1.6;
11 | $major-sixth: 1.667;
12 | $minor-seventh: 1.778;
13 | $major-seventh: 1.875;
14 | $octave: 2;
15 | $major-tenth: 2.5;
16 | $major-eleventh: 2.667;
17 | $major-twelfth: 3;
18 | $double-octave: 4;
19 |
20 | @function modular-scale($value, $increment, $ratio) {
21 | $v1: nth($value, 1);
22 | $v2: nth($value, length($value));
23 | $value: $v1;
24 |
25 | // scale $v2 to just above $v1
26 | @while $v2 > $v1 {
27 | $v2: ($v2 / $ratio); // will be off-by-1
28 | }
29 | @while $v2 < $v1 {
30 | $v2: ($v2 * $ratio); // will fix off-by-1
31 | }
32 |
33 | // check AFTER scaling $v2 to prevent double-counting corner-case
34 | $double-stranded: $v2 > $v1;
35 |
36 | @if $increment > 0 {
37 | @for $i from 1 through $increment {
38 | @if $double-stranded and ($v1 * $ratio) > $v2 {
39 | $value: $v2;
40 | $v2: ($v2 * $ratio);
41 | } @else {
42 | $v1: ($v1 * $ratio);
43 | $value: $v1;
44 | }
45 | }
46 | }
47 |
48 | @if $increment < 0 {
49 | // adjust $v2 to just below $v1
50 | @if $double-stranded {
51 | $v2: ($v2 / $ratio);
52 | }
53 |
54 | @for $i from $increment through -1 {
55 | @if $double-stranded and ($v1 / $ratio) < $v2 {
56 | $value: $v2;
57 | $v2: ($v2 / $ratio);
58 | } @else {
59 | $v1: ($v1 / $ratio);
60 | $value: $v1;
61 | }
62 | }
63 | }
64 |
65 | @return $value;
66 | }
67 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_px-to-em.scss:
--------------------------------------------------------------------------------
1 | // Convert pixels to ems
2 | // eg. for a relational value of 12px write em(12) when the parent is 16px
3 | // if the parent is another value say 24px write em(12, 24)
4 |
5 | @function em($pxval, $base: $em-base) {
6 | @if not unitless($pxval) {
7 | $pxval: strip-units($pxval);
8 | }
9 | @if not unitless($base) {
10 | $base: strip-units($base);
11 | }
12 | @return ($pxval / $base) * 1em;
13 | }
14 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_px-to-rem.scss:
--------------------------------------------------------------------------------
1 | // Convert pixels to rems
2 | // eg. for a relational value of 12px write rem(12)
3 | // Assumes $em-base is the font-size of
4 |
5 | @function rem($pxval) {
6 | @if not unitless($pxval) {
7 | $pxval: strip-units($pxval);
8 | }
9 |
10 | $base: $em-base;
11 | @if not unitless($base) {
12 | $base: strip-units($base);
13 | }
14 | @return ($pxval / $base) * 1rem;
15 | }
16 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_strip-units.scss:
--------------------------------------------------------------------------------
1 | // Srtips the units from a value. e.g. 12px -> 12
2 |
3 | @function strip-units($val) {
4 | @return ($val / ($val * 0 + 1));
5 | }
6 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_tint-shade.scss:
--------------------------------------------------------------------------------
1 | // Add percentage of white to a color
2 | @function tint($color, $percent){
3 | @return mix(white, $color, $percent);
4 | }
5 |
6 | // Add percentage of black to a color
7 | @function shade($color, $percent){
8 | @return mix(black, $color, $percent);
9 | }
10 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_transition-property-name.scss:
--------------------------------------------------------------------------------
1 | // Return vendor-prefixed property names if appropriate
2 | // Example: transition-property-names((transform, color, background), moz) -> -moz-transform, color, background
3 | //************************************************************************//
4 | @function transition-property-names($props, $vendor: false) {
5 | $new-props: ();
6 |
7 | @each $prop in $props {
8 | $new-props: append($new-props, transition-property-name($prop, $vendor), comma);
9 | }
10 |
11 | @return $new-props;
12 | }
13 |
14 | @function transition-property-name($prop, $vendor: false) {
15 | // put other properties that need to be prefixed here aswell
16 | @if $vendor and $prop == transform {
17 | @return unquote('-'+$vendor+'-'+$prop);
18 | }
19 | @else {
20 | @return $prop;
21 | }
22 | }
--------------------------------------------------------------------------------
/assets/_sass/bourbon/functions/_unpack.scss:
--------------------------------------------------------------------------------
1 | // Convert shorthand to the 4-value syntax
2 |
3 | @function unpack($shorthand) {
4 | @if length($shorthand) == 1 {
5 | @return nth($shorthand, 1) nth($shorthand, 1) nth($shorthand, 1) nth($shorthand, 1);
6 | }
7 | @else if length($shorthand) == 2 {
8 | @return nth($shorthand, 1) nth($shorthand, 2) nth($shorthand, 1) nth($shorthand, 2);
9 | }
10 | @else if length($shorthand) == 3 {
11 | @return nth($shorthand, 1) nth($shorthand, 2) nth($shorthand, 3) nth($shorthand, 2);
12 | }
13 | @else {
14 | @return $shorthand;
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_convert-units.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Helper function for str-to-num fn.
3 | // Source: http://sassmeister.com/gist/9647408
4 | //************************************************************************//
5 | @function _convert-units($number, $unit) {
6 | $strings: 'px' 'cm' 'mm' '%' 'ch' 'pica' 'in' 'em' 'rem' 'pt' 'pc' 'ex' 'vw' 'vh' 'vmin' 'vmax', 'deg', 'rad', 'grad', 'turn';
7 | $units: 1px 1cm 1mm 1% 1ch 1pica 1in 1em 1rem 1pt 1pc 1ex 1vw 1vh 1vmin 1vmax, 1deg, 1rad, 1grad, 1turn;
8 | $index: index($strings, $unit);
9 |
10 | @if not $index {
11 | @warn "Unknown unit `#{$unit}`.";
12 | @return false;
13 | }
14 | @return $number * nth($units, $index);
15 | }
16 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_gradient-positions-parser.scss:
--------------------------------------------------------------------------------
1 | @function _gradient-positions-parser($gradient-type, $gradient-positions) {
2 | @if $gradient-positions
3 | and ($gradient-type == linear)
4 | and (type-of($gradient-positions) != color) {
5 | $gradient-positions: _linear-positions-parser($gradient-positions);
6 | }
7 | @else if $gradient-positions
8 | and ($gradient-type == radial)
9 | and (type-of($gradient-positions) != color) {
10 | $gradient-positions: _radial-positions-parser($gradient-positions);
11 | }
12 | @return $gradient-positions;
13 | }
14 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_is-num.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Helper for linear-gradient-parser
3 | //************************************************************************//
4 | @function _is-num($char) {
5 | $values: '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 0 1 2 3 4 5 6 7 8 9;
6 | $index: index($values, $char);
7 | @return if($index, true, false);
8 | }
9 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_linear-angle-parser.scss:
--------------------------------------------------------------------------------
1 | // Private function for linear-gradient-parser
2 | @function _linear-angle-parser($image, $first-val, $prefix, $suffix) {
3 | $offset: null;
4 | $unit-short: str-slice($first-val, str-length($first-val) - 2, str-length($first-val));
5 | $unit-long: str-slice($first-val, str-length($first-val) - 3, str-length($first-val));
6 |
7 | @if ($unit-long == "grad") or
8 | ($unit-long == "turn") {
9 | $offset: if($unit-long == "grad", -100grad * 3, -0.75turn);
10 | }
11 |
12 | @else if ($unit-short == "deg") or
13 | ($unit-short == "rad") {
14 | $offset: if($unit-short == "deg", -90 * 3, 1.6rad);
15 | }
16 |
17 | @if $offset {
18 | $num: _str-to-num($first-val);
19 |
20 | @return (
21 | webkit-image: -webkit- + $prefix + ($offset - $num) + $suffix,
22 | spec-image: $image
23 | );
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_linear-gradient-parser.scss:
--------------------------------------------------------------------------------
1 | @function _linear-gradient-parser($image) {
2 | $image: unquote($image);
3 | $gradients: ();
4 | $start: str-index($image, "(");
5 | $end: str-index($image, ",");
6 | $first-val: str-slice($image, $start + 1, $end - 1);
7 |
8 | $prefix: str-slice($image, 0, $start);
9 | $suffix: str-slice($image, $end, str-length($image));
10 |
11 | $has-multiple-vals: str-index($first-val, " ");
12 | $has-single-position: unquote(_position-flipper($first-val) + "");
13 | $has-angle: _is-num(str-slice($first-val, 0, 0));
14 |
15 | @if $has-multiple-vals {
16 | $gradients: _linear-side-corner-parser($image, $first-val, $prefix, $suffix, $has-multiple-vals);
17 | }
18 |
19 | @else if $has-single-position != "" {
20 | $pos: unquote($has-single-position + "");
21 |
22 | $gradients: (
23 | webkit-image: -webkit- + $image,
24 | spec-image: $prefix + "to " + $pos + $suffix
25 | );
26 | }
27 |
28 | @else if $has-angle {
29 | // Rotate degree for webkit
30 | $gradients: _linear-angle-parser($image, $first-val, $prefix, $suffix);
31 | }
32 |
33 | @else {
34 | $gradients: (
35 | webkit-image: -webkit- + $image,
36 | spec-image: $image
37 | );
38 | }
39 |
40 | @return $gradients;
41 | }
42 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_linear-positions-parser.scss:
--------------------------------------------------------------------------------
1 | @function _linear-positions-parser($pos) {
2 | $type: type-of(nth($pos, 1));
3 | $spec: null;
4 | $degree: null;
5 | $side: null;
6 | $corner: null;
7 | $length: length($pos);
8 | // Parse Side and corner positions
9 | @if ($length > 1) {
10 | @if nth($pos, 1) == "to" { // Newer syntax
11 | $side: nth($pos, 2);
12 |
13 | @if $length == 2 { // eg. to top
14 | // Swap for backwards compatability
15 | $degree: _position-flipper(nth($pos, 2));
16 | }
17 | @else if $length == 3 { // eg. to top left
18 | $corner: nth($pos, 3);
19 | }
20 | }
21 | @else if $length == 2 { // Older syntax ("top left")
22 | $side: _position-flipper(nth($pos, 1));
23 | $corner: _position-flipper(nth($pos, 2));
24 | }
25 |
26 | @if ("#{$side} #{$corner}" == "left top") or ("#{$side} #{$corner}" == "top left") {
27 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
28 | }
29 | @else if ("#{$side} #{$corner}" == "right top") or ("#{$side} #{$corner}" == "top right") {
30 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
31 | }
32 | @else if ("#{$side} #{$corner}" == "right bottom") or ("#{$side} #{$corner}" == "bottom right") {
33 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
34 | }
35 | @else if ("#{$side} #{$corner}" == "left bottom") or ("#{$side} #{$corner}" == "bottom left") {
36 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
37 | }
38 | $spec: to $side $corner;
39 | }
40 | @else if $length == 1 {
41 | // Swap for backwards compatability
42 | @if $type == string {
43 | $degree: $pos;
44 | $spec: to _position-flipper($pos);
45 | }
46 | @else {
47 | $degree: -270 - $pos; //rotate the gradient opposite from spec
48 | $spec: $pos;
49 | }
50 | }
51 | $degree: unquote($degree + ",");
52 | $spec: unquote($spec + ",");
53 | @return $degree $spec;
54 | }
55 |
56 | @function _position-flipper($pos) {
57 | @return if($pos == left, right, null)
58 | if($pos == right, left, null)
59 | if($pos == top, bottom, null)
60 | if($pos == bottom, top, null);
61 | }
62 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_linear-side-corner-parser.scss:
--------------------------------------------------------------------------------
1 | // Private function for linear-gradient-parser
2 | @function _linear-side-corner-parser($image, $first-val, $prefix, $suffix, $has-multiple-vals) {
3 | $val-1: str-slice($first-val, 0, $has-multiple-vals - 1 );
4 | $val-2: str-slice($first-val, $has-multiple-vals + 1, str-length($first-val));
5 | $val-3: null;
6 | $has-val-3: str-index($val-2, " ");
7 |
8 | @if $has-val-3 {
9 | $val-3: str-slice($val-2, $has-val-3 + 1, str-length($val-2));
10 | $val-2: str-slice($val-2, 0, $has-val-3 - 1);
11 | }
12 |
13 | $pos: _position-flipper($val-1) _position-flipper($val-2) _position-flipper($val-3);
14 | $pos: unquote($pos + "");
15 |
16 | // Use old spec for webkit
17 | @if $val-1 == "to" {
18 | @return (
19 | webkit-image: -webkit- + $prefix + $pos + $suffix,
20 | spec-image: $image
21 | );
22 | }
23 |
24 | // Bring the code up to spec
25 | @else {
26 | @return (
27 | webkit-image: -webkit- + $image,
28 | spec-image: $prefix + "to " + $pos + $suffix
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_radial-arg-parser.scss:
--------------------------------------------------------------------------------
1 | @function _radial-arg-parser($G1, $G2, $pos, $shape-size) {
2 | @each $value in $G1, $G2 {
3 | $first-val: nth($value, 1);
4 | $pos-type: type-of($first-val);
5 | $spec-at-index: null;
6 |
7 | // Determine if spec was passed to mixin
8 | @if type-of($value) == list {
9 | $spec-at-index: if(index($value, at), index($value, at), false);
10 | }
11 | @if $spec-at-index {
12 | @if $spec-at-index > 1 {
13 | @for $i from 1 through ($spec-at-index - 1) {
14 | $shape-size: $shape-size nth($value, $i);
15 | }
16 | @for $i from ($spec-at-index + 1) through length($value) {
17 | $pos: $pos nth($value, $i);
18 | }
19 | }
20 | @else if $spec-at-index == 1 {
21 | @for $i from ($spec-at-index + 1) through length($value) {
22 | $pos: $pos nth($value, $i);
23 | }
24 | }
25 | $G1: null;
26 | }
27 |
28 | // If not spec calculate correct values
29 | @else {
30 | @if ($pos-type != color) or ($first-val != "transparent") {
31 | @if ($pos-type == number)
32 | or ($first-val == "center")
33 | or ($first-val == "top")
34 | or ($first-val == "right")
35 | or ($first-val == "bottom")
36 | or ($first-val == "left") {
37 |
38 | $pos: $value;
39 |
40 | @if $pos == $G1 {
41 | $G1: null;
42 | }
43 | }
44 |
45 | @else if
46 | ($first-val == "ellipse")
47 | or ($first-val == "circle")
48 | or ($first-val == "closest-side")
49 | or ($first-val == "closest-corner")
50 | or ($first-val == "farthest-side")
51 | or ($first-val == "farthest-corner")
52 | or ($first-val == "contain")
53 | or ($first-val == "cover") {
54 |
55 | $shape-size: $value;
56 |
57 | @if $value == $G1 {
58 | $G1: null;
59 | }
60 |
61 | @else if $value == $G2 {
62 | $G2: null;
63 | }
64 | }
65 | }
66 | }
67 | }
68 | @return $G1, $G2, $pos, $shape-size;
69 | }
70 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_radial-gradient-parser.scss:
--------------------------------------------------------------------------------
1 | @function _radial-gradient-parser($image) {
2 | $image: unquote($image);
3 | $gradients: ();
4 | $start: str-index($image, "(");
5 | $end: str-index($image, ",");
6 | $first-val: str-slice($image, $start + 1, $end - 1);
7 |
8 | $prefix: str-slice($image, 0, $start);
9 | $suffix: str-slice($image, $end, str-length($image));
10 |
11 | $is-spec-syntax: str-index($first-val, "at");
12 |
13 | @if $is-spec-syntax and $is-spec-syntax > 1 {
14 | $keyword: str-slice($first-val, 1, $is-spec-syntax - 2);
15 | $pos: str-slice($first-val, $is-spec-syntax + 3, str-length($first-val));
16 | $pos: append($pos, $keyword, comma);
17 |
18 | $gradients: (
19 | webkit-image: -webkit- + $prefix + $pos + $suffix,
20 | spec-image: $image
21 | )
22 | }
23 |
24 | @else if $is-spec-syntax == 1 {
25 | $pos: str-slice($first-val, $is-spec-syntax + 3, str-length($first-val));
26 |
27 | $gradients: (
28 | webkit-image: -webkit- + $prefix + $pos + $suffix,
29 | spec-image: $image
30 | )
31 | }
32 |
33 | @else if str-index($image, "cover") or str-index($image, "contain") {
34 | @warn "Radial-gradient needs to be updated to conform to latest spec.";
35 |
36 | $gradients: (
37 | webkit-image: null,
38 | spec-image: $image
39 | )
40 | }
41 |
42 | @else {
43 | $gradients: (
44 | webkit-image: -webkit- + $image,
45 | spec-image: $image
46 | )
47 | }
48 |
49 | @return $gradients;
50 | }
51 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_radial-positions-parser.scss:
--------------------------------------------------------------------------------
1 | @function _radial-positions-parser($gradient-pos) {
2 | $shape-size: nth($gradient-pos, 1);
3 | $pos: nth($gradient-pos, 2);
4 | $shape-size-spec: _shape-size-stripper($shape-size);
5 |
6 | $pre-spec: unquote(if($pos, "#{$pos}, ", null))
7 | unquote(if($shape-size, "#{$shape-size},", null));
8 | $pos-spec: if($pos, "at #{$pos}", null);
9 |
10 | $spec: "#{$shape-size-spec} #{$pos-spec}";
11 |
12 | // Add comma
13 | @if ($spec != ' ') {
14 | $spec: "#{$spec},"
15 | }
16 |
17 | @return $pre-spec $spec;
18 | }
19 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_render-gradients.scss:
--------------------------------------------------------------------------------
1 | // User for linear and radial gradients within background-image or border-image properties
2 |
3 | @function _render-gradients($gradient-positions, $gradients, $gradient-type, $vendor: false) {
4 | $pre-spec: null;
5 | $spec: null;
6 | $vendor-gradients: null;
7 | @if $gradient-type == linear {
8 | @if $gradient-positions {
9 | $pre-spec: nth($gradient-positions, 1);
10 | $spec: nth($gradient-positions, 2);
11 | }
12 | }
13 | @else if $gradient-type == radial {
14 | $pre-spec: nth($gradient-positions, 1);
15 | $spec: nth($gradient-positions, 2);
16 | }
17 |
18 | @if $vendor {
19 | $vendor-gradients: -#{$vendor}-#{$gradient-type}-gradient(#{$pre-spec} $gradients);
20 | }
21 | @else if $vendor == false {
22 | $vendor-gradients: "#{$gradient-type}-gradient(#{$spec} #{$gradients})";
23 | $vendor-gradients: unquote($vendor-gradients);
24 | }
25 | @return $vendor-gradients;
26 | }
27 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_shape-size-stripper.scss:
--------------------------------------------------------------------------------
1 | @function _shape-size-stripper($shape-size) {
2 | $shape-size-spec: null;
3 | @each $value in $shape-size {
4 | @if ($value == "cover") or ($value == "contain") {
5 | $value: null;
6 | }
7 | $shape-size-spec: "#{$shape-size-spec} #{$value}";
8 | }
9 | @return $shape-size-spec;
10 | }
11 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/helpers/_str-to-num.scss:
--------------------------------------------------------------------------------
1 | //************************************************************************//
2 | // Helper function for linear/radial-gradient-parsers.
3 | // Source: http://sassmeister.com/gist/9647408
4 | //************************************************************************//
5 | @function _str-to-num($string) {
6 | // Matrices
7 | $strings: '0' '1' '2' '3' '4' '5' '6' '7' '8' '9';
8 | $numbers: 0 1 2 3 4 5 6 7 8 9;
9 |
10 | // Result
11 | $result: 0;
12 | $divider: 0;
13 | $minus: false;
14 |
15 | // Looping through all characters
16 | @for $i from 1 through str-length($string) {
17 | $character: str-slice($string, $i, $i);
18 | $index: index($strings, $character);
19 |
20 | @if $character == '-' {
21 | $minus: true;
22 | }
23 |
24 | @else if $character == '.' {
25 | $divider: 1;
26 | }
27 |
28 | @else {
29 | @if not $index {
30 | $result: if($minus, $result * -1, $result);
31 | @return _convert-units($result, str-slice($string, $i));
32 | }
33 |
34 | $number: nth($numbers, $index);
35 |
36 | @if $divider == 0 {
37 | $result: $result * 10;
38 | }
39 |
40 | @else {
41 | // Move the decimal dot to the left
42 | $divider: $divider * 10;
43 | $number: $number / $divider;
44 | }
45 |
46 | $result: $result + $number;
47 | }
48 | }
49 | @return if($minus, $result * -1, $result);
50 | }
51 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/settings/_asset-pipeline.scss:
--------------------------------------------------------------------------------
1 | $asset-pipeline: false !default;
2 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/settings/_prefixer.scss:
--------------------------------------------------------------------------------
1 | // Variable settings for /addons/prefixer.scss
2 | $prefix-for-webkit: true !default;
3 | $prefix-for-mozilla: true !default;
4 | $prefix-for-microsoft: true !default;
5 | $prefix-for-opera: true !default;
6 | $prefix-for-spec: true !default; // required for keyframe mixin
7 |
--------------------------------------------------------------------------------
/assets/_sass/bourbon/settings/_px-to-em.scss:
--------------------------------------------------------------------------------
1 | $em-base: 16px !default;
2 |
--------------------------------------------------------------------------------
/assets/_sass/neat/_neat-helpers.scss:
--------------------------------------------------------------------------------
1 | // Functions
2 | @import "functions/private";
3 | @import "functions/new-breakpoint";
4 |
5 | // Settings
6 | @import "settings/grid";
7 | @import "settings/visual-grid";
8 |
--------------------------------------------------------------------------------
/assets/_sass/neat/_neat.scss:
--------------------------------------------------------------------------------
1 | // Bourbon Neat 1.6.0.pre
2 | // MIT Licensed
3 | // Copyright (c) 2012-2013 thoughtbot, inc.
4 |
5 | // Helpers
6 | @import "neat-helpers";
7 |
8 | // Grid
9 | @import "grid/private";
10 | @import "grid/reset";
11 | @import "grid/grid";
12 | @import "grid/omega";
13 | @import "grid/outer-container";
14 | @import "grid/span-columns";
15 | @import "grid/row";
16 | @import "grid/shift";
17 | @import "grid/pad";
18 | @import "grid/fill-parent";
19 | @import "grid/media";
20 | @import "grid/to-deprecate";
21 | @import "grid/visual-grid";
22 |
--------------------------------------------------------------------------------
/assets/_sass/neat/functions/_new-breakpoint.scss:
--------------------------------------------------------------------------------
1 | @function new-breakpoint($query:$feature $value $columns, $total-columns: $grid-columns) {
2 |
3 | @if length($query) == 1 {
4 | $query: $default-feature nth($query, 1) $total-columns;
5 | }
6 |
7 | @else if length($query) % 2 == 0 {
8 | $query: append($query, $total-columns);
9 | }
10 |
11 | @if not belongs-to($query, $visual-grid-breakpoints) {
12 | $visual-grid-breakpoints: append($visual-grid-breakpoints, $query, comma) !global;
13 | }
14 |
15 | @return $query;
16 | }
17 |
--------------------------------------------------------------------------------
/assets/_sass/neat/functions/_private.scss:
--------------------------------------------------------------------------------
1 | // Checks if a number is even
2 | @function is-even($int) {
3 | @if $int%2 == 0 {
4 | @return true;
5 | }
6 |
7 | @return false;
8 | }
9 |
10 | // Checks if an element belongs to a list
11 | @function belongs-to($tested-item, $list) {
12 | @each $item in $list {
13 | @if $item == $tested-item {
14 | @return true;
15 | }
16 | }
17 |
18 | @return false;
19 | }
20 |
21 | // Contains display value
22 | @function contains-display-value($query) {
23 | @if belongs-to(table, $query) or belongs-to(block, $query) or belongs-to(inline-block, $query) or belongs-to(inline, $query) {
24 | @return true;
25 | }
26 |
27 | @return false;
28 | }
29 |
30 | // Parses the first argument of span-columns()
31 | @function container-span($span: $span) {
32 | @if length($span) == 3 {
33 | $container-columns: nth($span, 3);
34 | @return $container-columns;
35 | }
36 |
37 | @else if length($span) == 2 {
38 | $container-columns: nth($span, 2);
39 | @return $container-columns;
40 | }
41 |
42 | @else {
43 | @return $grid-columns;
44 | }
45 | }
46 |
47 | @function container-shift($shift: $shift) {
48 | $parent-columns: $grid-columns !global !default;
49 |
50 | @if length($shift) == 3 {
51 | $container-columns: nth($shift, 3);
52 | @return $container-columns;
53 | }
54 |
55 | @else if length($shift) == 2 {
56 | $container-columns: nth($shift, 2);
57 | @return $container-columns;
58 | }
59 |
60 | @else {
61 | @return $parent-columns;
62 | }
63 | }
64 |
65 | // Generates a striped background
66 | @function gradient-stops($grid-columns, $color: $visual-grid-color) {
67 | $transparent: rgba(0,0,0,0);
68 |
69 | $column-width: flex-grid(1, $grid-columns);
70 | $gutter-width: flex-gutter($grid-columns);
71 | $column-offset: $column-width;
72 |
73 | $values: ($transparent 0, $color 0);
74 |
75 | @for $i from 1 to $grid-columns*2 {
76 | @if is-even($i) {
77 | $values: append($values, $transparent $column-offset, comma);
78 | $values: append($values, $color $column-offset, comma);
79 | $column-offset: $column-offset + $column-width;
80 | }
81 |
82 | @else {
83 | $values: append($values, $color $column-offset, comma);
84 | $values: append($values, $transparent $column-offset, comma);
85 | $column-offset: $column-offset + $gutter-width;
86 | }
87 | }
88 |
89 | @return $values;
90 | }
91 |
92 | // Layout direction
93 | @function get-direction($layout, $default) {
94 | $direction: nil;
95 |
96 | @if $layout == LTR or $layout == RTL {
97 | $direction: direction-from-layout($layout);
98 | } @else {
99 | $direction: direction-from-layout($default);
100 | }
101 |
102 | @return $direction;
103 | }
104 |
105 | @function direction-from-layout($layout) {
106 | $direction: nil;
107 |
108 | @if $layout == LTR {
109 | $direction: right;
110 | } @else {
111 | $direction: left;
112 | }
113 |
114 | @return $direction;
115 | }
116 |
117 | @function get-opposite-direction($direction) {
118 | $opposite-direction: left;
119 |
120 | @if $direction == left {
121 | $opposite-direction: right;
122 | }
123 |
124 | @return $opposite-direction;
125 | }
126 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_fill-parent.scss:
--------------------------------------------------------------------------------
1 | @mixin fill-parent() {
2 | width: 100%;
3 |
4 | @if $border-box-sizing == false {
5 | @include box-sizing(border-box);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_grid.scss:
--------------------------------------------------------------------------------
1 | @if $border-box-sizing == true {
2 | * {
3 | @include box-sizing(border-box);
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_media.scss:
--------------------------------------------------------------------------------
1 | @mixin media($query:$feature $value $columns, $total-columns: $grid-columns) {
2 | @if length($query) == 1 {
3 | @media screen and ($default-feature: nth($query, 1)) {
4 | $default-grid-columns: $grid-columns;
5 | $grid-columns: $total-columns !global;
6 | @content;
7 | $grid-columns: $default-grid-columns !global;
8 | }
9 | }
10 |
11 | @else {
12 | $loopTo: length($query);
13 | $mediaQuery: 'screen and ';
14 | $default-grid-columns: $grid-columns;
15 | $grid-columns: $total-columns !global;
16 |
17 | @if length($query) % 2 != 0 {
18 | $grid-columns: nth($query, $loopTo) !global;
19 | $loopTo: $loopTo - 1;
20 | }
21 |
22 | $i: 1;
23 | @while $i <= $loopTo {
24 | $mediaQuery: $mediaQuery + '(' + nth($query, $i) + ': ' + nth($query, $i + 1) + ') ';
25 |
26 | @if ($i + 1) != $loopTo {
27 | $mediaQuery: $mediaQuery + 'and ';
28 | }
29 |
30 | $i: $i + 2;
31 | }
32 |
33 | @media #{$mediaQuery} {
34 | @content;
35 | $grid-columns: $default-grid-columns !global;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_omega.scss:
--------------------------------------------------------------------------------
1 | // Remove last element gutter
2 | @mixin omega($query: block, $direction: default) {
3 | $table: if(belongs-to(table, $query), true, false);
4 | $auto: if(belongs-to(auto, $query), true, false);
5 |
6 | @if $direction != default {
7 | @warn "The omega mixin will no longer take a $direction argument. To change the layout direction, use row($direction) or set $default-layout-direction instead."
8 | } @else {
9 | $direction: get-direction($layout-direction, $default-layout-direction);
10 | }
11 |
12 | @if $table {
13 | @warn "The omega mixin no longer removes padding in table layouts."
14 | }
15 |
16 | @if length($query) == 1 {
17 | @if $auto {
18 | &:last-child {
19 | margin-#{$direction}: 0;
20 | }
21 | }
22 |
23 | @else if contains-display-value($query) and $table == false {
24 | margin-#{$direction}: 0;
25 | }
26 |
27 | @else {
28 | @include nth-child($query, $direction);
29 | }
30 | }
31 |
32 | @else if length($query) == 2 {
33 | @if $auto {
34 | &:last-child {
35 | margin-#{$direction}: 0;
36 | }
37 | }
38 |
39 | @else {
40 | @include nth-child(nth($query, 1), $direction);
41 | }
42 | }
43 |
44 | @else {
45 | @warn "Too many arguments passed to the omega() mixin."
46 | }
47 | }
48 |
49 | @mixin nth-child($query, $direction) {
50 | $opposite-direction: get-opposite-direction($direction);
51 |
52 | &:nth-child(#{$query}) {
53 | margin-#{$direction}: 0;
54 | }
55 |
56 | @if type-of($query) == number {
57 | &:nth-child(#{$query}+1) {
58 | clear: $opposite-direction;
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_outer-container.scss:
--------------------------------------------------------------------------------
1 | @mixin outer-container {
2 | @include clearfix;
3 | max-width: $max-width;
4 | margin: {
5 | left: auto;
6 | right: auto;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_pad.scss:
--------------------------------------------------------------------------------
1 | @mixin pad($padding: flex-gutter()) {
2 | $padding-list: null;
3 | @each $value in $padding {
4 | $value: if($value == 'default', flex-gutter(), $value);
5 | $padding-list: join($padding-list, $value);
6 | }
7 | padding: $padding-list;
8 | }
9 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_private.scss:
--------------------------------------------------------------------------------
1 | $parent-columns: $grid-columns !default;
2 | $fg-column: $column;
3 | $fg-gutter: $gutter;
4 | $fg-max-columns: $grid-columns;
5 | $container-display-table: false !default;
6 | $layout-direction: nil !default;
7 |
8 | @function flex-grid($columns, $container-columns: $fg-max-columns) {
9 | $width: $columns * $fg-column + ($columns - 1) * $fg-gutter;
10 | $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
11 | @return percentage($width / $container-width);
12 | }
13 |
14 | @function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) {
15 | $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
16 | @return percentage($gutter / $container-width);
17 | }
18 |
19 | @function grid-width($n) {
20 | @return $n * $gw-column + ($n - 1) * $gw-gutter;
21 | }
22 |
23 | @function get-parent-columns($columns) {
24 | @if $columns != $grid-columns {
25 | $parent-columns: $columns !global;
26 | } @else {
27 | $parent-columns: $grid-columns !global;
28 | }
29 |
30 | @return $parent-columns;
31 | }
32 |
33 | @function is-display-table($container-is-display-table, $display) {
34 | $display-table: false;
35 |
36 | @if $container-is-display-table == true {
37 | $display-table: true;
38 | } @else if $display == table {
39 | $display-table: true;
40 | }
41 |
42 | @return $display-table;
43 | }
44 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_reset.scss:
--------------------------------------------------------------------------------
1 | @mixin reset-display {
2 | $container-display-table: false !global;
3 | }
4 |
5 | @mixin reset-layout-direction {
6 | $layout-direction: $default-layout-direction !global;
7 | }
8 |
9 | @mixin reset-all {
10 | @include reset-display;
11 | @include reset-layout-direction;
12 | }
13 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_row.scss:
--------------------------------------------------------------------------------
1 | @mixin row($display: block, $direction: $default-layout-direction) {
2 | @include clearfix;
3 | $layout-direction: $direction !global;
4 |
5 | @if $display == table {
6 | display: table;
7 | @include fill-parent;
8 | table-layout: fixed;
9 | $container-display-table: true !global;
10 | }
11 |
12 | @else {
13 | display: block;
14 | $container-display-table: false !global;
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_shift.scss:
--------------------------------------------------------------------------------
1 | @mixin shift($n-columns: 1) {
2 | @include shift-in-context($n-columns);
3 | }
4 |
5 | @mixin shift-in-context($shift: $columns of $container-columns) {
6 | $n-columns: nth($shift, 1);
7 | $parent-columns: container-shift($shift) !global;
8 |
9 | $direction: get-direction($layout-direction, $default-layout-direction);
10 | $opposite-direction: get-opposite-direction($direction);
11 |
12 | margin-#{$opposite-direction}: $n-columns * flex-grid(1, $parent-columns) + $n-columns * flex-gutter($parent-columns);
13 |
14 | // Reset nesting context
15 | $parent-columns: $grid-columns !global;
16 | }
17 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_span-columns.scss:
--------------------------------------------------------------------------------
1 | @mixin span-columns($span: $columns of $container-columns, $display: block) {
2 | $columns: nth($span, 1);
3 | $container-columns: container-span($span);
4 |
5 | // Set nesting context (used by shift())
6 | $parent-columns: get-parent-columns($container-columns) !global;
7 |
8 | $direction: get-direction($layout-direction, $default-layout-direction);
9 | $opposite-direction: get-opposite-direction($direction);
10 |
11 | $display-table: is-display-table($container-display-table, $display);
12 |
13 | @if $display-table {
14 | display: table-cell;
15 | width: percentage($columns / $container-columns);
16 | } @else {
17 | float: #{$opposite-direction};
18 |
19 | @if $display != no-display {
20 | display: block;
21 | }
22 |
23 | @if $display == collapse {
24 | @warn "The 'collapse' argument will be deprecated. Use 'block-collapse' instead."
25 | }
26 |
27 | @if $display == collapse or $display == block-collapse {
28 | width: flex-grid($columns, $container-columns) + flex-gutter($container-columns);
29 |
30 | &:last-child {
31 | width: flex-grid($columns, $container-columns);
32 | }
33 |
34 | } @else {
35 | margin-#{$direction}: flex-gutter($container-columns);
36 | width: flex-grid($columns, $container-columns);
37 |
38 | &:last-child {
39 | margin-#{$direction}: 0;
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_to-deprecate.scss:
--------------------------------------------------------------------------------
1 | @mixin breakpoint($query:$feature $value $columns, $total-columns: $grid-columns) {
2 | @warn "The breakpoint() mixin was renamed to media() in Neat 1.0. Please update your project with the new syntax before the next version bump.";
3 |
4 | @if length($query) == 1 {
5 | @media screen and ($default-feature: nth($query, 1)) {
6 | $default-grid-columns: $grid-columns;
7 | $grid-columns: $total-columns;
8 | @content;
9 | $grid-columns: $default-grid-columns;
10 | }
11 | }
12 |
13 | @else if length($query) == 2 {
14 | @media screen and (nth($query, 1): nth($query, 2)) {
15 | $default-grid-columns: $grid-columns;
16 | $grid-columns: $total-columns;
17 | @content;
18 | $grid-columns: $default-grid-columns;
19 | }
20 | }
21 |
22 | @else if length($query) == 3 {
23 | @media screen and (nth($query, 1): nth($query, 2)) {
24 | $default-grid-columns: $grid-columns;
25 | $grid-columns: nth($query, 3);
26 | @content;
27 | $grid-columns: $default-grid-columns;
28 | }
29 | }
30 |
31 | @else if length($query) == 4 {
32 | @media screen and (nth($query, 1): nth($query, 2)) and (nth($query, 3): nth($query, 4)) {
33 | $default-grid-columns: $grid-columns;
34 | $grid-columns: $total-columns;
35 | @content;
36 | $grid-columns: $default-grid-columns;
37 | }
38 | }
39 |
40 | @else if length($query) == 5 {
41 | @media screen and (nth($query, 1): nth($query, 2)) and (nth($query, 3): nth($query, 4)) {
42 | $default-grid-columns: $grid-columns;
43 | $grid-columns: nth($query, 5);
44 | @content;
45 | $grid-columns: $default-grid-columns;
46 | }
47 | }
48 |
49 | @else {
50 | @warn "Wrong number of arguments for breakpoint(). Read the documentation for more details.";
51 | }
52 | }
53 |
54 | @mixin nth-omega($nth, $display: block, $direction: default) {
55 | @warn "The nth-omega() mixin is deprecated. Please use omega() instead.";
56 | @include omega($nth $display, $direction);
57 | }
58 |
--------------------------------------------------------------------------------
/assets/_sass/neat/grid/_visual-grid.scss:
--------------------------------------------------------------------------------
1 | @mixin grid-column-gradient($values...) {
2 | background-image: deprecated-webkit-gradient(linear, left top, left bottom, $values);
3 | background-image: -webkit-linear-gradient(left, $values);
4 | background-image: -moz-linear-gradient(left, $values);
5 | background-image: -ms-linear-gradient(left, $values);
6 | background-image: -o-linear-gradient(left, $values);
7 | background-image: unquote("linear-gradient(left, #{$values})");
8 | }
9 |
10 | @if $visual-grid == true or $visual-grid == yes {
11 | body:before {
12 | content: '';
13 | display: inline-block;
14 | @include grid-column-gradient(gradient-stops($grid-columns));
15 | height: 100%;
16 | left: 0;
17 | margin: 0 auto;
18 | max-width: $max-width;
19 | opacity: $visual-grid-opacity;
20 | position: fixed;
21 | right: 0;
22 | width: 100%;
23 | pointer-events: none;
24 |
25 | @if $visual-grid-index == back {
26 | z-index: -1;
27 | }
28 |
29 | @else if $visual-grid-index == front {
30 | z-index: 9999;
31 | }
32 |
33 | @each $breakpoint in $visual-grid-breakpoints {
34 | @if $breakpoint != nil {
35 | @include media($breakpoint) {
36 | @include grid-column-gradient(gradient-stops($grid-columns));
37 | }
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/assets/_sass/neat/settings/_grid.scss:
--------------------------------------------------------------------------------
1 | $column: golden-ratio(1em, 3) !default; // Column width
2 | $gutter: golden-ratio(1em, 1) !default; // Gutter between each two columns
3 | $grid-columns: 12 !default; // Total number of columns in the grid
4 | $max-width: em(1088) !default; // Max-width of the outer container
5 | $border-box-sizing: true !default; // Makes all elements have a border-box layout
6 | $default-feature: min-width; // Default @media feature for the breakpoint() mixin
7 | $default-layout-direction: LTR !default;
8 |
--------------------------------------------------------------------------------
/assets/_sass/neat/settings/_visual-grid.scss:
--------------------------------------------------------------------------------
1 | $visual-grid: false !default; // Display the base grid
2 | $visual-grid-color: #EEE !default;
3 | $visual-grid-index: back !default; // Show grid behind content (back) or overlay it over the content (front)
4 | $visual-grid-opacity: 0.4 !default;
5 | $visual-grid-breakpoints: () !default;
6 |
--------------------------------------------------------------------------------
/assets/css/fonts.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /* comment out when working locally */
4 | @font-face {
5 | font-family: "18f";
6 | src:url("/dashboard/assets/fonts/18f-font.eot");
7 | src:url("/dashboard/assets/fonts/18f-font.eot?#iefix") format("embedded-opentype"),
8 | url("/dashboard/assets/fonts/18f-font.woff") format("woff"),
9 | url("/dashboard/assets/fonts/18f-font.ttf") format("truetype"),
10 | url("/dashboard/assets/fonts/18f-font.svg#untitled-font-1") format("svg");
11 | font-weight: normal;
12 | font-style: normal;
13 |
14 | }
15 |
16 | /* comment out for live site */
17 | /*@font-face {
18 | font-family: "18f";
19 | src:url("/assets/fonts/18f-font.eot");
20 | src:url("/assets/fonts/18f-font.eot?#iefix") format("embedded-opentype"),
21 | url("/assets/fonts/18f-font.woff") format("woff"),
22 | url("/assets/fonts/18f-font.ttf") format("truetype"),
23 | url("/assets/fonts/18f-font.svg#untitled-font-1") format("svg");
24 | font-weight: normal;
25 | font-style: normal;
26 |
27 | }*/
28 |
29 | [data-icon]:before {
30 | font-family: "18f" !important;
31 | content: attr(data-icon);
32 | font-style: normal !important;
33 | font-weight: normal !important;
34 | font-variant: normal !important;
35 | text-transform: none !important;
36 | speak: none;
37 | line-height: 1;
38 | -webkit-font-smoothing: antialiased;
39 | -moz-osx-font-smoothing: grayscale;
40 | }
41 |
42 | [class^="icon-"]:before,
43 | [class*=" icon-"]:before {
44 | font-family: "18f" !important;
45 | font-style: normal !important;
46 | font-weight: normal !important;
47 | font-variant: normal !important;
48 | text-transform: none !important;
49 | speak: none;
50 | line-height: 1;
51 | -webkit-font-smoothing: antialiased;
52 | -moz-osx-font-smoothing: grayscale;
53 | }
54 |
55 | .icon-lightbulb:before {
56 | content: "a";
57 | }
58 | .icon-github1:before {
59 | content: "b";
60 | }
61 | .icon-github2:before {
62 | content: "c";
63 | }
64 | .icon-github3:before {
65 | content: "d";
66 | }
67 | .icon-18f-logo:before {
68 | content: "e";
69 | }
70 | .icon-camera:before {
71 | content: "f";
72 | }
73 | .icon-twitter:before {
74 | content: "g";
75 | }
76 | .icon-spinner:before {
77 | content: "l";
78 | }
79 | .icon-email:before {
80 | content: "h";
81 | }
82 | .icon-lastfm:before {
83 | content: "i";
84 | }
85 | .icon-linkedin:before {
86 | content: "j";
87 | }
88 | .icon-anchor:before {
89 | content: "k";
90 | }
91 | body {
92 | font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
93 | font-weight: 300;
94 | line-height: 1.8em;
95 | }
96 |
97 | h1, h2, h3, h4, h5, h6 {
98 | font-family: 'Raleway', 'Helvetica Neue', Helvetica, Arial, sans-serif;
99 | font-weight: 600;
100 | }
101 |
102 | a {
103 | color:#06d;
104 | text-decoration: underline;
105 | }
106 | a:hover {color:#c21;}
107 |
108 | /* SPINNER */
109 | .icon-spin {
110 | display: inline-block;
111 | -webkit-animation: spin 2s infinite linear;
112 | -moz-animation: spin 2s infinite linear;
113 | -o-animation: spin 2s infinite linear;
114 | animation: spin 2s infinite linear;
115 | }
116 | @-webkit-keyframes spin {
117 | 0% {
118 | -webkit-transform: rotate(0deg);
119 | }
120 | 100% {
121 | -webkit-transform: rotate(359deg);
122 | }
123 | }
124 | @-moz-keyframes spin {
125 | 0% {
126 | -moz-transform: rotate(0deg);
127 | }
128 | 100% {
129 | -moz-transform: rotate(359deg);
130 | }
131 | }
132 | @-o-keyframes spin {
133 | 0% {
134 | -o-transform: rotate(0deg);
135 | }
136 | 100% {
137 | -o-transform: rotate(359deg);
138 | }
139 | }
140 | @-ms-keyframes spin {
141 | 0% {
142 | -ms-transform: rotate(0deg);
143 | }
144 | 100% {
145 | -ms-transform: rotate(359deg);
146 | }
147 | }
148 | @keyframes spin {
149 | 0% {
150 | transform: rotate(0deg);
151 | }
152 | 100% {
153 | transform: rotate(359deg);
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/assets/css/ie8/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 | }
--------------------------------------------------------------------------------
/assets/css/styles.scss:
--------------------------------------------------------------------------------
1 | ---
2 | ---
3 |
4 | // *******************************************
5 | // Import all scss, ending with custom styles
6 | // *******************************************
7 |
8 | // bourbon.io
9 | @import 'bourbon/bourbon';
10 |
11 | // bitters.bourbon.io
12 | @import 'base/base';
13 |
14 | // neat.bourbon.io
15 | @import 'neat/neat';
16 |
17 | // custom styles
18 | @import "custom";
19 |
--------------------------------------------------------------------------------
/assets/fonts/18f-font.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/fonts/18f-font.eot
--------------------------------------------------------------------------------
/assets/fonts/18f-font.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/fonts/18f-font.ttf
--------------------------------------------------------------------------------
/assets/fonts/18f-font.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/fonts/18f-font.woff
--------------------------------------------------------------------------------
/assets/images/18f.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/18f.png
--------------------------------------------------------------------------------
/assets/images/always-be-shipping_orange.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/always-be-shipping_orange.png
--------------------------------------------------------------------------------
/assets/images/favicons/18f-center-114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/favicons/18f-center-114.png
--------------------------------------------------------------------------------
/assets/images/favicons/18f-center-144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/favicons/18f-center-144.png
--------------------------------------------------------------------------------
/assets/images/favicons/18f-center-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/favicons/18f-center-16.png
--------------------------------------------------------------------------------
/assets/images/favicons/18f-center-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/favicons/18f-center-200.png
--------------------------------------------------------------------------------
/assets/images/favicons/18f-center-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/favicons/18f-center-32.png
--------------------------------------------------------------------------------
/assets/images/favicons/18f-center-57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/favicons/18f-center-57.png
--------------------------------------------------------------------------------
/assets/images/favicons/18f-center-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/favicons/18f-center-72.png
--------------------------------------------------------------------------------
/assets/images/favicons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/favicons/favicon.ico
--------------------------------------------------------------------------------
/assets/images/favicons/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/favicons/favicon.png
--------------------------------------------------------------------------------
/assets/images/logo-18f.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/logo-18f.png
--------------------------------------------------------------------------------
/assets/images/logo-gsa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/assets/images/logo-gsa.png
--------------------------------------------------------------------------------
/assets/js/18f.js:
--------------------------------------------------------------------------------
1 | // friendly console message
2 |
3 | // IE needs plaintext, sigh
4 | // window._ie = true;
5 | if (window._ie) {
6 | console.log("Oh hi there! By all means, poke around.");
7 | console.log("");
8 | 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");
9 | console.log("And check us out on GitHub generally! We're an open source team. https://github.com/18F");
10 | }
11 |
12 | // otherwise, let's get fancy
13 | else {
14 | var styles = {
15 | big: "font-size: 24pt; font-weight: bold; color: #18f",
16 | medium: "font-size: 10pt",
17 | medium_bold: "font-size: 10pt; font-weight: bold",
18 | medium_link: "font-size: 10pt; color: #18f" // works in Firebug, not Chrome
19 | };
20 | console.log("%cOh hi there! Please poke around.", styles.big);
21 | console.log(" ");
22 | 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);
23 | 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);
24 | }
25 |
26 |
27 | /*
28 | Browser warning widget, for IE8.
29 | */
30 | var $buoop = {vs:{i:8,f:10,o:12,s:5}};
31 | $buoop.ol = window.onload;
32 | window.onload=function(){
33 | try {if ($buoop.ol) $buoop.ol();}catch (e) {}
34 | var e = document.createElement("script");
35 | e.setAttribute("type", "text/javascript");
36 | e.setAttribute("src", "//browser-update.org/update.js");
37 | document.body.appendChild(e);
38 | }
39 |
40 | //Initial load of page
41 | window.onload=function() { sizeContent() };
42 |
43 | //Every resize of window
44 | $(window).resize(sizeContent);
45 |
46 | //Dynamically assign height
47 | function sizeContent() {
48 | var newHeight = $("#slide").height() - 10 + "px";
49 | $("#hero").css("height", newHeight);
50 | }
51 |
--------------------------------------------------------------------------------
/assets/js/main.js:
--------------------------------------------------------------------------------
1 | var modules = [];
2 | var GITHUB_API = "https://api.github.com/";
3 | var GOVCODE_API = "https://api.govcode.org/"
4 | var ORGANIZATION = "18f";
5 | // team api will always be at the same server the dashboard is running on, this
6 | // makes it flexible for local dev environments by sniffing out the beginning of
7 | // url and lopping any subdirectories off the browser's current document
8 | var docUrl = document.URL;
9 | var substrBegin = docUrl.startsWith('https://') ? 8 : 7;
10 | var urlRootIndex = docUrl.substr(substrBegin).indexOf('/');
11 | var urlRoot = docUrl.substr(0,urlRootIndex+substrBegin);
12 | var TEAM = urlRoot+"/api/data/team.json"
13 |
14 | modules[0] = function(repo_name) {
15 | $.getJSON(GOVCODE_API+"repos/"+repo_name, function(data) {
16 | var issues = data['OpenIssues'];
17 | var stars = data['Stargazers'];
18 | var forks = data['Forks'];
19 | var name = repo_name.replace(/[\. ,:-]+/g, "-");
20 | $("."+name + " .issues").append(""+issues);
21 | $("."+name + " .stars").append(""+stars);
22 | $("."+name + " .forks").append(""+forks);
23 | }).error(function () {
24 | $("."+name + " .issues").append("Not available.");
25 | $("."+name + " .stars").append("Not available.");
26 | $("."+name + " .forks").append("Not available.");
27 | });
28 | }
29 |
30 | modules[1] = function() {
31 | $.getJSON(TEAM, function(data) {
32 | var staffers = $(".staff > li");
33 | _.each(staffers, function(staffer) {
34 | console.log(staffer);
35 | var name = $(staffer).attr('class');
36 | var obj = _.where(data, {"name":name})[0];
37 | $(staffer).text(obj.full_name);
38 | });
39 | });
40 | }
41 |
42 | $(document).ready(function() {
43 | render_dashboard();
44 | });
45 |
46 | var render_modules = function(name) {
47 | modules[0](name);
48 | modules[1]();
49 | }
50 |
51 | var render_dashboard = function() {
52 | var ghURLs = $(".github-url");
53 | _.each(ghURLs, function(ghURL) {
54 | var url = $(ghURL).attr("href");
55 | var slugIndex = url.lastIndexOf("/");
56 | var name = url.substr(slugIndex+1);
57 | render_modules(name);
58 | });
59 | }
60 |
--------------------------------------------------------------------------------
/assets/js/preview.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 |
3 | var _ = require('underscore');
4 | var marked = require('marked');
5 | var yaml = require('yamljs');
6 | var liquid = require('liquid.js');
7 |
8 | marked.setOptions({
9 | gfm: true
10 | });
11 |
12 | liquid.readTemplateFile = function(path) {
13 | console.log('path', path);
14 | if (includes[path]) return includes[path];
15 | return '';
16 | }
17 |
18 | var aboutYmlValidator = require('about-yml-validator');
19 | var validator = new aboutYmlValidator();
20 |
21 | var includes = {
22 | 'list-partners.html': fs.readFileSync(__dirname + '/../../_includes/list-partners-preview.html', 'utf8'),
23 | 'project-code.html': fs.readFileSync(__dirname + '/../../_includes/project-code.html', 'utf8'),
24 | 'project-links.html': fs.readFileSync(__dirname + '/../../_includes/project-links.html', 'utf8')
25 | };
26 |
27 | var url = cleanGithubUrl(window.location.search);
28 | var xhr = new XMLHttpRequest();
29 | xhr.addEventListener("load", handleAboutYml);
30 |
31 | xhr.open('GET', url);
32 | xhr.send();
33 |
34 | function handleAboutYml (e) {
35 | var res = e.target,
36 | aboutYml, errors, yml;
37 | if (res.status !== 200) return;
38 |
39 | aboutYml = yaml.parse(res.responseText);
40 | errors = validator.validate(res.responseText);
41 |
42 | if (errors) aboutYml['errors'] = errors;
43 |
44 | yml = addMissingNotices(aboutYml);
45 | yml['description'] = parseMarkdown(yml['description']);
46 | yml['impact'] = parseMarkdown(yml['impact']);
47 |
48 | insertYmlInHtml(yml);
49 |
50 | }
51 |
52 | function parseMarkdown (field) {
53 | field = field.replace(/\\n/g, '\n'); // escaped in yaml parser?
54 | var md = marked(field);
55 | return md;
56 | }
57 |
58 | function addMissingNotices (yml) {
59 | var whitelist = window.w = {
60 | 'full_name': 'Missing full_name',
61 | 'description': 'Missing description',
62 | 'contact': 'Missing contact',
63 | 'blog': 'Missing blog',
64 | 'impact': 'Missing impact',
65 | 'partners': ['Missing partners'],
66 | 'milestones': ['Missing milestones'],
67 | 'github': ['Missing github'],
68 | 'links': ['Missing links']
69 | };
70 |
71 | return _.defaults({}, yml, whitelist);
72 | }
73 |
74 | function insertYmlInHtml (yml) {
75 | var template = compileLiquidTemplate();
76 | var html = template.render({ page: { project: yml }});
77 | document.querySelector('[role=main]').innerHTML = html;
78 | }
79 |
80 | function compileLiquidTemplate () {
81 | var templateSrc = fs.readFileSync(__dirname + '/../../_layouts/project.html', 'utf8');
82 | templateSrc = templateSrc.replace(/---[\s\S]*---/, '');
83 | templateSrc = templateSrc.replace(/include (.*?) /g, "include '$1' ");
84 |
85 | return liquid.parse(templateSrc);
86 | }
87 |
88 | function cleanGithubUrl (url) {
89 | return url.replace('?url=', '')
90 | .replace('https://github.com','https://raw.githubusercontent.com')
91 | .replace('blob/', '');
92 | }
93 |
--------------------------------------------------------------------------------
/deploy/fabfile.py:
--------------------------------------------------------------------------------
1 | import time
2 | from fabric.api import run, execute, env, cd
3 |
4 | """
5 | Manage auto-deploy webhooks remotely.
6 |
7 | Staging hooks:
8 |
9 | forever start -l $HOME/hookshot.log -a deploy/hookshot.js -p 3001 -b staging -c "cd $HOME/staging/current && git pull && git submodule update && jekyll build >> $HOME/hookshot.log"
10 | forever restart deploy/hookshot.js -p 3001 -b staging -c "cd $HOME/staging/current && git pull && git submodule update && jekyll build >> $HOME/hookshot.log"
11 | forever stop deploy/hookshot.js -p 3001 -b staging -c "cd $HOME/staging/current && git pull && git submodule update && jekyll build >> $HOME/hookshot.log"
12 |
13 | Production hook:
14 |
15 | forever start -l $HOME/hookshot.log -a deploy/hookshot.js -p 4001 -b production -c "cd $HOME/production/current && git pull && git submodule update && jekyll build >> $HOME/hookshot.log"
16 | forever restart deploy/hookshot.js -p 4001 -b production -c "cd $HOME/production/current && git pull && git submodule update && jekyll build >> $HOME/hookshot.log"
17 | forever stop deploy/hookshot.js -p 4001 -b production -c "cd $HOME/production/current && git pull && git submodule update && jekyll build >> $HOME/hookshot.log"
18 | """
19 |
20 | # which hook to restart. defaults to staging, override with:
21 | # fab [command] --set env=production"
22 | environment = env.get('env', 'staging')
23 |
24 | port = {
25 | "staging": 3001,
26 | "production": 4001
27 | }[environment]
28 | # expects an SSH entry named '18f-site', rather than hardcoded server details
29 | env.use_ssh_config = True
30 | env.hosts = ["18f-site"]
31 |
32 | home = "/home/site"
33 | log = "%s/dashboard.log" % home
34 | current = "%s/%s/dashboard" % (home, environment)
35 | now = time.strftime("%Y-%m-%d", time.localtime())
36 |
37 | # principal command to run upon update
38 |
39 | deploy_cmd = "/opt/install/rbenv/shims/ruby ./go deploy >> %s" % (log)
40 |
41 | ## can be run on their own
42 |
43 | def start():
44 | if type(port) != int:
45 | exit(1)
46 |
47 | with cd(current):
48 | run(
49 | "forever start -l %s -a deploy/hookshot.js -p %i -b %s -c \"%s\""
50 | % (log, port, environment, deploy_cmd)
51 | )
52 |
53 | def stop():
54 | with cd(current):
55 | run(
56 | "forever stop deploy/hookshot.js -p %i -b %s -c \"%s\""
57 | % (port, environment, deploy_cmd)
58 | )
59 |
60 | def restart():
61 | with cd(current):
62 | run(
63 | "forever start -l %s -a deploy/hookshot.js -p %i -b %s -c \"%s\""
64 | % (log, port, environment, deploy_cmd)
65 | )
66 |
--------------------------------------------------------------------------------
/deploy/hookshot.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | var hookshot = require("hookshot");
4 | var spawn = require("child_process").spawn;
5 | var options = require('minimist')(process.argv.slice(2));
6 |
7 | var branch = options.b || options.branch;
8 | var command = options.c || options.command;
9 | var port = options.p || options.port;
10 |
11 | if (!branch || !command || !port) {
12 | console.error("--branch, --command, and --port are all required.")
13 | process.exit(1);
14 | }
15 |
16 | hookshot('refs/heads/' + branch, command).listen(port);
17 |
18 | console.log("Huzzah! Listening on port " + port + " for push events on " + branch + ".")
19 |
--------------------------------------------------------------------------------
/deploy/team-api-importer-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "port": 5000,
3 | "bundler": "/opt/install/rbenv/shims/bundle",
4 | "teamApiRepo": "18F/team-api.18f.gov",
5 | "teamApiBranch": "master",
6 | "repoDirs": [
7 | "/home/site/staging/dashboard"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/deploy/team-api-importer-deploy.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | /usr/bin/ssh site@18f.gsa.gov \
4 | /usr/local/bin/forever start -l /home/site/team-api-importer.log \
5 | -a /home/site/staging/dashboard/deploy/team-api-importer-server.js
6 |
--------------------------------------------------------------------------------
/deploy/team-api-importer-server.js:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 | /* jshint node: true */
3 | /* jshint bitwise: false */
4 | //
5 | // Webhook listener triggering 18F Dashboard rebuilds upon Team API updates
6 | //
7 | // Author: Mike Bland (michael.bland@gsa.gov)
8 | // Date: 2015-09-03
9 | 'use strict';
10 |
11 | var hookshot = require('hookshot');
12 | var teamApiImporter = require('./team-api-importer');
13 | var config = require('./team-api-importer-config.json');
14 |
15 | hookshot().on('refs/heads/' + config.teamApiBranch, function(info) {
16 | teamApiImporter.buildSitesIfValidUpdate(info, config)
17 | .then(teamApiImporter.logResult, teamApiImporter.logResult);
18 | }).listen(config.port);
19 |
20 | console.log('Listening on port ' + config.port + ' for Team API updates.');
21 |
--------------------------------------------------------------------------------
/deploy/team-api-importer.js:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 | /* jshint node: true */
3 | /* jshint bitwise: false */
4 | //
5 | // Author: Mike Bland (michael.bland@gsa.gov)
6 | // Date: 2015-09-03
7 | 'use strict';
8 |
9 | var childProcess = require('child_process');
10 |
11 | var exports = module.exports = {};
12 |
13 | function TeamApiImporter(repoDir, bundler) {
14 | this.repoDir = repoDir;
15 | this.bundler = bundler;
16 | }
17 |
18 | TeamApiImporter.prototype.spawn = function (actionDescription, path, args) {
19 | var that = this;
20 | return new Promise(function(resolve, reject) {
21 | var spawnOpts = { cwd: that.repoDir, stdio: 'inherit' };
22 | var childProc = childProcess.spawn(path, args, spawnOpts);
23 | childProc.on('close', function onProcessClose(exitStatus) {
24 | if (exitStatus !== 0) {
25 | reject(new Error(that.repoDir + ': ' + actionDescription));
26 | } else {
27 | resolve();
28 | }
29 | });
30 | });
31 | };
32 |
33 | TeamApiImporter.prototype.bundleInstall = function () {
34 | return this.spawn('bundle install', this.bundler, ['install']);
35 | };
36 |
37 | TeamApiImporter.prototype.jekyllBuild = function () {
38 | return this.spawn('jekyll build', this.bundler,
39 | ['exec', 'jekyll', 'build', '--trace']);
40 | };
41 |
42 | exports.isValidUpdate = function(info, teamApiRepo) {
43 | return info.ref !== undefined &&
44 | info.repository.full_name === teamApiRepo; // jshint ignore:line
45 | };
46 |
47 | exports.logResult = function(err) {
48 | if (err) {
49 | console.error('Error importing Team API update:', err);
50 | } else {
51 | console.log('Importing Team API update succeeded');
52 | }
53 | };
54 |
55 | function createImporterPromise(repoDir, bundler) {
56 | var updater = new TeamApiImporter(repoDir, bundler);
57 | return updater.bundleInstall()
58 | .then(function() { return updater.jekyllBuild(); });
59 | }
60 |
61 | exports.buildSitesIfValidUpdate = function (info, config) {
62 | if (!exports.isValidUpdate(info, config.teamApiRepo)) {
63 | return Promise.reject('update payload is not valid');
64 | }
65 | if (config.repoDirs.length === 0) {
66 | return Promise.reject('config.repoDirs is empty');
67 | }
68 |
69 | var repoDirs = config.repoDirs.slice(0);
70 | var updatePromise = createImporterPromise(repoDirs.shift(), config.bundler);
71 |
72 | repoDirs.map(function (repoDir) {
73 | updatePromise = updatePromise.then(
74 | function() { return createImporterPromise(repoDir, config.bundler); });
75 | });
76 |
77 | return updatePromise;
78 | };
79 |
80 | exports.TeamApiImporter = TeamApiImporter;
81 |
--------------------------------------------------------------------------------
/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/18F/dashboard/d3e6b9990842ef39daf2e5ca2f4c4e950e847b56/favicon.png
--------------------------------------------------------------------------------
/go:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env ruby
2 | #
3 | # 18F Hub - Docs & connections between team members, projects, and skill sets
4 | #
5 | # Written in 2015 by Mike Bland (michael.bland@gsa.gov)
6 | # on behalf of the 18F team, part of the US General Services Administration:
7 | # https://18f.gsa.gov/
8 | #
9 | # To the extent possible under law, the author(s) have dedicated all copyright
10 | # and related and neighboring rights to this software to the public domain
11 | # worldwide. This software is distributed without any warranty.
12 | #
13 | # You should have received a copy of the CC0 Public Domain Dedication along
14 | # with this software. If not, see
15 | # .
16 | #
17 | # @author Mike Bland (michael.bland@gsa.gov)
18 | #
19 | # ----
20 | #
21 | # ./go script: unified development environment interface
22 | #
23 | # Inspired by:
24 | # http://www.thoughtworks.com/insights/blog/praise-go-script-part-i
25 | # http://www.thoughtworks.com/insights/blog/praise-go-script-part-ii
26 | #
27 | # Author: Mike Bland (michael.bland@gsa.gov)
28 | # Date: 2015-01-10
29 | def exec_cmd(cmd)
30 | exit $?.exitstatus unless system(cmd)
31 | end
32 |
33 | def init
34 | begin
35 | require 'bundler'
36 | rescue LoadError
37 | puts "Installing Bundler gem..."
38 | exec_cmd 'gem install bundler'
39 | puts "Bundler installed; installing gems"
40 | end
41 | exec_cmd 'bundle install'
42 | install_node_modules
43 | end
44 |
45 | def install_gems
46 | exec_cmd 'bundle install'
47 | exec_cmd 'git add Gemfile.lock'
48 | end
49 |
50 | def install_node_modules
51 | exec_cmd 'npm install'
52 | end
53 |
54 | def update_data
55 | exec_cmd 'bundle exec ruby _data/import-public.rb'
56 | end
57 |
58 | def serve
59 | puts 'Updating from the team API'
60 | update_data
61 | exec_cmd 'npm run watchify &'
62 | exec_cmd 'bundle exec jekyll serve --trace'
63 | end
64 |
65 | def build
66 | puts 'Building the site...'
67 | exec_cmd('npm run browserify')
68 | exec_cmd('bundle exec jekyll b --trace')
69 | puts 'Site built successfully.'
70 | end
71 |
72 | def ci_build
73 | puts 'Building the site...'
74 | exec_cmd('npm run browserify')
75 | exec_cmd('bundle exec jekyll b --trace')
76 | exec_cmd('bundle exec jekyll serve --detach')
77 | puts 'Testing the build'
78 | ci_test
79 | puts 'Killing Jekyll'
80 | exec_cmd('pkill -f jekyll')
81 | puts 'Done!'
82 | end
83 |
84 | def deploy
85 | puts 'Pulling the latest changes...'
86 | exec_cmd('git pull')
87 | puts 'Building the site...'
88 | exec_cmd('/opt/install/rbenv/shims/bundle exec jekyll b --trace')
89 | puts 'Site built successfully.'
90 | require 'time'
91 | puts Time.now()
92 | end
93 |
94 | def test_build
95 | exec_cmd 'rspec'
96 | end
97 |
98 | def ci_test
99 | exec_cmd 'bundle exec rspec --tag "~type:missing"'
100 | end
101 |
102 | COMMANDS = {
103 | :init => 'Set up the Hub dev environment',
104 | :install_gems => 'Execute Bundler to update gem set',
105 | :install_node_modules => 'Install Node dependencies',
106 | :update_data => 'Updates data files from data-private',
107 | :serve => 'Serves the site at localhost:4000',
108 | :build => 'Builds the site',
109 | :ci_build => 'Builds the site for a CI system',
110 | :deploy => 'Pulls the latest changes and rebuilds the site',
111 | :test_build => 'Tests the build generated the correct number of project pages.'
112 | }
113 |
114 | def usage(exitstatus: 0)
115 | puts <
12 | {{page.title}}
13 | We are building digital services for the American people. Follow our progress and get involved here.
14 |
40 |
41 |
42 |
43 | {% for p in site.data.projects %}
44 | {% assign project_name = p[0] %}{% assign project = p[1] %}
45 | {% if project.status != "Hold" %}
46 |
47 |
50 |
51 |
{% if project.description %}{{ project.description }}{% else %}Project description coming soon.{% endif %}
52 |
53 |
54 |
55 |
{% if project.partners.size == 1 %}Partner: {%else%}Partners: {%endif%}{% if project.partners %}{% include list-partners.html style="strong" %}{% else %}Coming soon{% endif %}
56 | {% if project.github %}
57 | {% if project.github.first.name %}
58 | {% assign repo_name = project.github.first.name %}
59 | {% else %}
60 | {% assign repo_name = project.github.first %}
61 | {% endif %}
62 |
/ Code /
63 | {% endif %}
64 |
/ Metrics /
65 |
66 | {% capture blog %}{{ project.blogTag | default: project.blog }}{% endcapture %}
67 | {% assign tags = blog | split: ',' %}
68 | {% if tags.size > 0 %}
69 |
70 | /
71 |
72 | {% for t in tags %}
73 | News
74 | /
75 | {% endfor %}
76 |
77 |
78 | {% endif %}
79 |
80 |
81 |
82 | {% endif %}
83 | {% endfor %}
84 |
85 |
86 |
87 | {% include dashboard-contact.html %}
88 |
89 |
90 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "18f-dashboard",
3 | "repository": "git@github.com:18F/dashboard.git",
4 | "scripts": {
5 | "install": "npm run browserify",
6 | "browserify": "browserify assets/js/preview.js -o assets/js/preview-bundle.js -t brfs",
7 | "watchify": "watchify assets/js/preview.js -o assets/js/preview-bundle.js -t brfs"
8 | },
9 | "engines": {
10 | "node": ">=0.12.7"
11 | },
12 | "license": "CC0-1.0",
13 | "dependencies": {
14 | "about-yml-validator": "git+https://github.com/18F/about-yml-npm.git",
15 | "brfs": "^1.4.1",
16 | "browserify": "^12.0.1",
17 | "chai": "^3.2.0",
18 | "chai-as-promised": "^5.1.0",
19 | "gulp": "^3.9.0",
20 | "gulp-jshint": "^1.11.2",
21 | "gulp-mocha": "^2.1.3",
22 | "jshint": "^2.8.0",
23 | "liquid.js": "^1.3.2",
24 | "marked": "^0.3.5",
25 | "mocha": "^2.2.5",
26 | "mock-spawn": "^0.2.6",
27 | "sinon": "^1.15.4",
28 | "sinon-chai": "^2.8.0",
29 | "underscore": "^1.8.3",
30 | "watchify": "^3.6.1",
31 | "yamljs": "^0.2.4"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/pages/project/doi-extractives-data.md:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: project/doi-extractives-data/
3 | redirect_to:
4 | - /dashboard/project/useiti-report/
5 | ---
6 |
--------------------------------------------------------------------------------
/pages/project/fedspendingtransparency.md:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: project/openfec/
3 | redirect_to:
4 | - /dashboard/project/dataact/
5 | ---
6 |
--------------------------------------------------------------------------------
/pages/project/midas.md:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: project/midas/
3 | redirect_to:
4 | - /dashboard/project/openopps/
5 | ---
6 |
--------------------------------------------------------------------------------
/pages/project/mirage.md:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: project/mirage/
3 | redirect_to:
4 | - /dashboard/project/discovery/
5 | ---
6 |
--------------------------------------------------------------------------------
/pages/project/openfec.md:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: project/openfec/
3 | redirect_to:
4 | - /dashboard/project/betafec/
5 | ---
6 |
--------------------------------------------------------------------------------
/preview.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: project
3 | title: Live Preview
4 | permalink: /project/preview/
5 | ---
6 |
7 |
8 |
--------------------------------------------------------------------------------
/spec/homepage_spec.rb:
--------------------------------------------------------------------------------
1 | data = YAML.load_file('_data/project_filter.yml')
2 | projects = data['projects']
3 | RSpec.describe "the homepage", :type => :feature do
4 | it "loads with the expected number of projects listed" do
5 | visit 'http://127.0.0.1:4000/dashboard/'
6 | expect(page).to have_selector('.dashboard-projects-content', count:projects.count)
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/spec/project_spec.rb:
--------------------------------------------------------------------------------
1 | data = YAML.load_file('_data/project_filter.yml')
2 | projects = data['projects']
3 | RSpec.describe "project page", :type => :feature do
4 | projects.each_with_index do |project, index|
5 | it "#{project} should not have errors" do
6 | visit_url(project)
7 | expect(page).not_to have_selector(".project-errors")
8 | end
9 | it "#{project} should have the basic project header", :type => 'missing' do
10 | visit_url(project)
11 | page.should have_css(".dashboard-project")
12 | end
13 |
14 | it "#{project} should have a status", :type => 'missing' do
15 | visit_url(project)
16 | page.should have_css(".dashboard-project .status")
17 | end
18 |
19 | it "#{project} should have a contact", :type => 'missing' do
20 | visit_url(project)
21 | page.should have_css(".project-contact") # add css for "contact"
22 | end
23 |
24 | it "#{project} should have an impact statement", :type => 'missing' do
25 | visit_url(project)
26 | page.should have_css(".project-impact")
27 | end
28 | end
29 | end
30 |
31 | def visit_url(endpoint)
32 | visit "http://localhost:4000/dashboard/project/#{endpoint}/"
33 | end
34 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | require 'rspec'
2 | require 'capybara/rspec'
3 | require 'capybara/poltergeist'
4 | require 'safe_yaml'
5 |
6 | # This will ensure we are connecting to a remote server
7 | Capybara.run_server = false
8 | Capybara.default_driver = :poltergeist
9 | Capybara.register_driver :poltergeist do |app|
10 | Capybara::Poltergeist::Driver.new(app, :browser => :poltergeist, :js_errors => false)
11 | end
12 |
13 | Capybara.javascript_driver = :poltergeist
14 | SafeYAML::OPTIONS[:default_mode] = :safe
15 |
--------------------------------------------------------------------------------
/stages.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: bare
3 | title: Project Stage Definitions
4 | permalink: /stages/
5 | ---
6 |
7 |
8 | back to main dashboard
9 | {{page.title}}
10 | These are the agile development and human-centered design stages that we use at 18F to build products and services. We are still drafting our definitions and guidelines, so if you want to learn more, we recommend GOV.UK's excellent work in this area .
11 |
12 |
13 |
14 |
15 |
16 |
discovery
17 |
18 |
19 |
Who are your users and what are their true needs? In this phase, you will start to answer those questions so that you can plan to build a useful product. Conducting primary research (interviewing and observing the actual users) is ideal. In addition to the users’ needs, you will explore other stakeholders’ needs, such as specific client or policy requirements. Learn more about our inspiration for the discovery stage.
20 |
21 | {% include projectlist.html stage="discovery" %}
22 |
23 |
24 |
25 |
alpha
26 |
27 |
28 |
Build one or more prototypes based on the research from the Discovery phase. Test the prototypes with small groups of actual users. Work closely with designers and developers to implement changes based on user feedback. Frequently release iterations to a small group of testers. Discover technical and design needs during this process (e.g., choose and test initial tech stack). Learn more about our inspiration for the alpha stage.
29 |
30 | {% include projectlist.html stage="alpha" %}
31 |
32 |
33 |
34 |
beta
35 |
36 |
37 |
Stage and test working software on the public web for use by a subset of the target audience. Implement changes based on user behavior and feedback. Resolve policy compliance or technical integration issues. Define and then validate statistically significant metrics for improvement. May include a time-boxed Authority to Operate. Learn more about our inspiration for the beta stage.
38 |
39 | {% include projectlist.html stage="beta" %}
40 |
41 |
42 |
43 |
live
44 |
45 |
46 |
Open the site to all users. Necessary security, performance, and policy requirements have been met, including a continuous and final Authority to Operate (ATO). Continue to iteratively improve the service based on analytics and user feedback. Learn more about our inspiration for the live stage.
47 |
48 | {% include projectlist.html stage="live" %}
49 |
50 |
51 |
52 | {% include dashboard-contact.html %}
53 |
54 |
--------------------------------------------------------------------------------
/tests/team_api_importer_test.js:
--------------------------------------------------------------------------------
1 | /* jshint node: true */
2 | /* jshint expr: true */
3 | /* jshint mocha: true */
4 | 'use strict';
5 |
6 | var path = require('path');
7 | var teamApiImporter = require(
8 | path.resolve(path.dirname(__dirname), 'deploy', 'team-api-importer.js'));
9 | var chai = require('chai');
10 | var chaiAsPromised = require('chai-as-promised');
11 | var sinon = require('sinon');
12 | var sinonChai = require('sinon-chai');
13 | var childProcess = require('child_process');
14 | var mockSpawn = require('mock-spawn');
15 |
16 | var expect = chai.expect;
17 | chai.should();
18 | chai.use(chaiAsPromised);
19 | chai.use(sinonChai);
20 |
21 | describe ('isValidUpdate', function() {
22 | it('should return false if the payload is empty', function() {
23 | var payload = { };
24 | expect(teamApiImporter.isValidUpdate(payload, '18F/team-api')).to.be.false;
25 | });
26 |
27 | it('should return false if ref is undefined', function() {
28 | var payload = {
29 | 'repository': {'full_name': '18F/team-api'},
30 | };
31 | expect(teamApiImporter.isValidUpdate(payload, '18F/team-api')).to.be.false;
32 | });
33 |
34 | it('should return false if not from the Team API repository', function() {
35 | var payload = {
36 | 'ref': 'is present',
37 | 'repository': {'full_name': 'mbland/team-api'}};
38 | expect(teamApiImporter.isValidUpdate(payload, '18F/team-api')).to.be.false;
39 | });
40 |
41 | it('should return true', function() {
42 | var payload = {
43 | 'ref': 'is present',
44 | 'repository': {'full_name': '18F/team-api'},
45 | };
46 | expect(teamApiImporter.isValidUpdate(payload, '18F/team-api')).to.be.true;
47 | });
48 | });
49 |
50 | describe('logResult', function() {
51 | beforeEach(function() {
52 | sinon.spy(console, 'log');
53 | sinon.spy(console, 'error');
54 | });
55 |
56 | afterEach(function() {
57 | console.error.restore();
58 | console.log.restore();
59 | });
60 |
61 | it('should log a normal message to the console if no error', function() {
62 | teamApiImporter.logResult();
63 | console.log.should.have.been.calledWith(
64 | 'Importing Team API update succeeded');
65 | console.error.should.not.have.been.called;
66 | });
67 |
68 | it('should log an error message to the console if error present', function() {
69 | teamApiImporter.logResult('whoops');
70 | console.error.should.have.been.calledWith(
71 | 'Error importing Team API update:', 'whoops');
72 | console.log.should.not.have.been.called;
73 | });
74 | });
75 |
76 | describe('buildSitesIfValidUpdate', function() {
77 | var origSpawn, mySpawn;
78 |
79 | beforeEach(function() {
80 | origSpawn = childProcess.spawn;
81 | mySpawn = mockSpawn();
82 | childProcess.spawn = mySpawn;
83 | });
84 |
85 | afterEach(function() { childProcess.spawn = origSpawn; });
86 |
87 | function validPayload() {
88 | return {
89 | 'ref': 'is present',
90 | 'repository': {'full_name': '18F/team-api'},
91 | };
92 | }
93 |
94 | function validConfig() {
95 | return {
96 | 'bundler': '/usr/bin/bundle',
97 | 'teamApiRepo': '18F/team-api',
98 | 'repoDirs': [ '/staging', '/production' ]
99 | };
100 | }
101 |
102 | function spawnCalls() {
103 | return mySpawn.calls.map(function(value) {
104 | return value.opts.cwd + ': ' + value.command + ' ' + value.args.join(' ');
105 | });
106 | }
107 |
108 | it('should do nothing if the update is not valid', function() {
109 | return teamApiImporter.buildSitesIfValidUpdate({}, validConfig())
110 | .should.be.rejectedWith('update payload is not valid');
111 | });
112 |
113 | it('should do nothing if config.repoDirs is empty', function() {
114 | var config = validConfig();
115 | config.repoDirs = [];
116 | return teamApiImporter.buildSitesIfValidUpdate(validPayload(), config)
117 | .should.be.rejectedWith('config.repoDirs is empty');
118 | });
119 |
120 | it('should build a single repoDir', function(done) {
121 | var config = validConfig();
122 | config.repoDirs.pop();
123 | mySpawn.setDefault(mySpawn.simple(0));
124 |
125 | function validateSingleRepoDir() {
126 | expect(spawnCalls()).to.eql([
127 | '/staging: /usr/bin/bundle install',
128 | '/staging: /usr/bin/bundle exec jekyll build --trace'
129 | ]);
130 | }
131 |
132 | teamApiImporter.buildSitesIfValidUpdate(validPayload(), config)
133 | .should.be.fulfilled.then(validateSingleRepoDir).should.notify(done);
134 | });
135 |
136 | it('should build the second repoDir after the first', function(done) {
137 | mySpawn.setDefault(mySpawn.simple(0));
138 |
139 | function validateMultipleRepoDirs() {
140 | expect(spawnCalls()).to.eql([
141 | '/staging: /usr/bin/bundle install',
142 | '/staging: /usr/bin/bundle exec jekyll build --trace',
143 | '/production: /usr/bin/bundle install',
144 | '/production: /usr/bin/bundle exec jekyll build --trace'
145 | ]);
146 | }
147 |
148 | teamApiImporter.buildSitesIfValidUpdate(validPayload(), validConfig())
149 | .should.be.fulfilled.then(validateMultipleRepoDirs).should.notify(done);
150 | });
151 |
152 | it('should exit with a failure if a step fails', function(done) {
153 | mySpawn.sequence.add(mySpawn.simple(0));
154 | mySpawn.sequence.add(mySpawn.simple(0));
155 | mySpawn.sequence.add(mySpawn.simple(1));
156 |
157 | function validateFailure() {
158 | expect(spawnCalls()).to.eql([
159 | '/staging: /usr/bin/bundle install',
160 | '/staging: /usr/bin/bundle exec jekyll build --trace',
161 | '/production: /usr/bin/bundle install',
162 | ]);
163 | }
164 |
165 | teamApiImporter.buildSitesIfValidUpdate(validPayload(), validConfig())
166 | .should.be.rejectedWith(Error, '/production: bundle install')
167 | .then(validateFailure).should.notify(done);
168 | });
169 | });
170 |
--------------------------------------------------------------------------------
/tests/test.rb:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env ruby
2 | require 'safe_yaml'
3 |
4 | data = SafeYAML.load_file '_data/project_filter.yml', safe: true
5 | redirects = Dir.glob('pages/project/*')
6 | # we expect one page generated for each project in the project filter, plus any redirects, plus 1 for the preview page.
7 | expect_size = data['projects'].size + redirects.size + 1
8 | actual_size = Dir.glob('_site/dashboard/project/*').size
9 | if expect_size == actual_size
10 | puts "Dashboard pages generated correctly. There are #{actual_size} projects."
11 | exit 0
12 | else
13 | puts "Expected #{expect_size} projects generated but #{actual_size} were generated."
14 | exit 1
15 | end
16 |
--------------------------------------------------------------------------------