diff --git a/.gitignore b/.gitignore index 6a78689..de1cc8a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ _build/ .DS_Store dev.db .coverage +staticfiles diff --git a/LICENSE b/LICENSE index 22b1246..c654e8e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,30 @@ +registrasion-demo +----------------- + +# Copyright (c) 2016-2017 Christopher Neugebauer and contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +pinaxcon +-------- + # Copyright (c) 2009-2015 James Tauber and contributors # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -17,3 +44,30 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. + + +bootstrap-sass +-------------- + +The MIT License (MIT) + +Copyright (c) 2011-2016 Twitter, Inc +Copyright (c) 2011-2016 The Bootstrap Authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/fixtures/sitetree.json b/fixtures/sitetree.json index 44273d6..d344ec0 100644 --- a/fixtures/sitetree.json +++ b/fixtures/sitetree.json @@ -17,7 +17,7 @@ "description": "", "insitetree": true, "hint": "", - "url": "pages_page \"about/\"", + "url": "page_about", "inbreadcrumbs": true, "title": "About", "tree": 1, @@ -40,7 +40,7 @@ "description": "", "insitetree": true, "hint": "", - "url": "pages_page \"venue/\"", + "url": "page_venue", "inbreadcrumbs": true, "title": "Venue", "tree": 1, @@ -109,9 +109,9 @@ "description": "", "insitetree": true, "hint": "", - "url": "sponsor_apply", + "url": "page_sponsor_info", "inbreadcrumbs": true, - "title": "Apply to be a Sponsor", + "title": "Prospectus", "tree": 1, "access_perm_type": 1, "alias": null, diff --git a/gondor.yml b/gondor.yml deleted file mode 100644 index 0eabdb0..0000000 --- a/gondor.yml +++ /dev/null @@ -1,7 +0,0 @@ -buildpack: https://buildpack.gondor.io/python -site: eldarion-conferences/pinaxcon -deploy: - services: - - web -branches: - master: primary diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 9cbbd87..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Setup - */ -process.title = process.title || 'gulp'; - -/** - * Dependencies - */ -const path = require('path'); -const gulp = require('gulp'); - -/** - * Setup - */ -const tasks = require(path.resolve(__dirname, 'gulp/tasks')); -const config = require(path.resolve(__dirname, 'gulp/config')); - -/** - * Tasks - */ -gulp.task('build:clean', function buildClean() { - tasks.clean(config.paths.build); - return tasks.clean(config.paths.dist); -}); - -gulp.task('build:styles', function buildStyles() { - return tasks.css(config.styles.source, {less: {paths: config.styles.npmPaths}}) - .pipe(gulp.dest(config.styles.dist)); -}); - -gulp.task('build:js', function buildJS() { - return tasks.browserify(config.scripts.main) - .pipe(gulp.dest(config.scripts.dist)); -}); - -gulp.task('manifest', function manifest() { - return tasks.rev(config.manifest.source) - .pipe(gulp.dest(config.paths.dist)) - .pipe(tasks.manifest()) - .pipe(gulp.dest(config.paths.build)); -}); - -gulp.task('build:copy-icons', function() {
 - return tasks.copy(config.fonts.sources) - .pipe(gulp.dest(config.fonts.dist));
 -}); -gulp.task('build:copy-images', function() { - return tasks.copy(config.images.sources).pipe(gulp.dest(config.images.dist)); -}); - -gulp.task('build:script-include', function () { - return tasks.handlebars(config.templates.manifestPath, config.templates.scriptsTemplate, config.staticUrlRoot) - .pipe(gulp.dest(config.templates.destination)); -}); - -gulp.task('build:style-include', function () { - return tasks.handlebars(config.templates.manifestPath, config.templates.stylesTemplate, config.staticUrlRoot) - .pipe(gulp.dest(config.templates.destination)); -}); - -gulp.task('test', function test() { - return tasks.test(config.test.all); -}); - -gulp.task('test:req', function testReq() { - return tasks.test(config.test.req); -}); - -gulp.task('test:components', function testComponents() { - return tasks.test(config.test.components); -}); - -gulp.task('xo', function xo() { - return tasks.xo(config.xo.source); -}); - -gulp.task('optimize:js', function () { - return tasks.optimizejs(config.optimize.js.source, config.optimize.js.options, config.optimize.js.dist); -}); - -gulp.task('optimize:css', function () { - return tasks.optimizecss(config.optimize.css.source, config.optimize.css.options, config.optimize.css.dist); -}); - -/** - * Compound Tasks - */ -gulp.task('watch', function watch() { - gulp.watch(config.watch.styles, gulp.series(['build:styles', 'manifest', 'build:style-include'])); - gulp.watch(config.watch.scripts, gulp.series(['build:js', 'manifest', 'build:script-include'])); -}); - -gulp.task('build', gulp.series([ - 'xo', - 'build:clean', - gulp.parallel([ - 'build:styles', - 'build:js', - 'build:copy-icons', - 'build:copy-images' - ]), - 'manifest', - 'build:script-include', - 'build:style-include' -])); - -gulp.task('default', gulp.series([ - 'build', - 'watch' -])); - -gulp.task('release', gulp.series([ - 'build', - 'optimize:js', - 'optimize:css' -])); diff --git a/pinaxcon/settings.py b/pinaxcon/settings.py index bffc833..5b8ea59 100644 --- a/pinaxcon/settings.py +++ b/pinaxcon/settings.py @@ -56,22 +56,23 @@ MEDIA_URL = "/site_media/media/" # Don"t put anything in this directory yourself; store your static files # in apps" "static/" subdirectories and in STATICFILES_DIRS. # Example: "/home/media/media.lawrence.com/static/" -STATIC_ROOT = os.path.join(PACKAGE_ROOT, "site_media", "static") +STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles') # URL prefix for static files. # Example: "http://media.lawrence.com/static/" -STATIC_URL = "/site_media/static/" +STATIC_URL = '/static/' # Additional locations of static files -STATICFILES_DIRS = [ - os.path.join(PROJECT_ROOT, "static", "dist"), -] +STATICFILES_DIRS = ( + os.path.join(PROJECT_ROOT, 'static'), +) # List of finder classes that know how to find static files in # various locations. STATICFILES_FINDERS = [ "django.contrib.staticfiles.finders.FileSystemFinder", "django.contrib.staticfiles.finders.AppDirectoriesFinder", + "compressor.finders.CompressorFinder", ] # Make this unique, and don't share it with anybody. @@ -155,6 +156,7 @@ INSTALLED_APPS = [ # Registrasion "registrasion", + "symposion_templates", # Registrasion-stipe "pinax.stripe", @@ -171,6 +173,9 @@ INSTALLED_APPS = [ #testing "django_nose", + + # stylesheets and js + 'compressor', ] # A sample logging configuration. The only tangible logging @@ -202,6 +207,10 @@ LOGGING = { } } +COMPRESS_PRECOMPILERS = ( + ('text/x-scss', 'django_libsass.SassCompiler'), +) + FIXTURE_DIRS = [ os.path.join(PROJECT_ROOT, "fixtures"), ] diff --git a/pinaxcon/templates/_footer.html b/pinaxcon/templates/_footer.html index 4c0ecd3..d309112 100644 --- a/pinaxcon/templates/_footer.html +++ b/pinaxcon/templates/_footer.html @@ -1,7 +1,8 @@
- ©2016 + © 2017
- Site powered by Symposion. + Site powered by Symposion + and Registrasion.
diff --git a/pinaxcon/templates/_scripts.html b/pinaxcon/templates/_scripts.html index 518102b..5e4ba92 100644 --- a/pinaxcon/templates/_scripts.html +++ b/pinaxcon/templates/_scripts.html @@ -1 +1,10 @@ - +{% load compress %} +{% load staticfiles %} + + + + +{% compress js %} + + +{% endcompress %} diff --git a/pinaxcon/templates/_styles.html b/pinaxcon/templates/_styles.html index f6e4cd8..1bf398f 100644 --- a/pinaxcon/templates/_styles.html +++ b/pinaxcon/templates/_styles.html @@ -1 +1,7 @@ - +{% load compress %} +{% load staticfiles %} + + +{% compress css %} + +{% endcompress %} diff --git a/pinaxcon/templates/homepage.html b/pinaxcon/templates/homepage.html index dba73ad..25cd868 100644 --- a/pinaxcon/templates/homepage.html +++ b/pinaxcon/templates/homepage.html @@ -1,12 +1,10 @@ {% extends "site_base.html" %} {% load i18n %} -{% load pinax_boxes_tags %} - -{% block head_title %}{% trans "Welcome" %}{% endblock %} {% block body_class %}home{% endblock %} {% block body %} - {% box "homepage" %} +

{{ SITE_NAME }}

+

Welcome to the demo site.

{% endblock %} diff --git a/pinaxcon/templates/page_with_title_and_lede.html b/pinaxcon/templates/page_with_title_and_lede.html new file mode 100644 index 0000000..2e3a687 --- /dev/null +++ b/pinaxcon/templates/page_with_title_and_lede.html @@ -0,0 +1,18 @@ +{% extends "site_base.html" %} + +{% block head_title %}{% block title %}{% endblock %}{% endblock %} + +{% block body %} + + {% block heading_base %} +

{% block heading %}{% endblock %}

+ {% endblock %} + + {% block lede_base %} +

{% block lede %}{% endblock %}

+ {% endblock %} + + {% block content %} + {% endblock %} + +{% endblock %} diff --git a/pinaxcon/templates/pages/about.html b/pinaxcon/templates/pages/about.html new file mode 100644 index 0000000..48fe0c8 --- /dev/null +++ b/pinaxcon/templates/pages/about.html @@ -0,0 +1,9 @@ +{% extends "page_with_title_and_lede.html" %} + +{% block title %}About {{ SITE_NAME }}{% endblock %} +{% block heading %}About {{ SITE_NAME }}{% endblock %} +{% block lede %}{{ SITE_NAME }} is the premier demo conference site for Symposion and Registrasion{% endblock %} + +{% block content %} +

I am the body content

+{% endblock %} diff --git a/pinaxcon/templates/pages/sponsors/info.html b/pinaxcon/templates/pages/sponsors/info.html new file mode 100644 index 0000000..a213eb1 --- /dev/null +++ b/pinaxcon/templates/pages/sponsors/info.html @@ -0,0 +1,9 @@ +{% extends "page_with_title_and_lede.html" %} + +{% block title %}Sponsorship Prospectus{% endblock %} +{% block heading %}Sponsorship Prospectus{% endblock %} +{% block lede %}{{ SITE_NAME }} wants sponsors.{% endblock %} + +{% block content %} +

I am the body content

+{% endblock %} diff --git a/pinaxcon/templates/pages/venue.html b/pinaxcon/templates/pages/venue.html new file mode 100644 index 0000000..ee3ea28 --- /dev/null +++ b/pinaxcon/templates/pages/venue.html @@ -0,0 +1,9 @@ +{% extends "page_with_title_and_lede.html" %} + +{% block title %}Venue{% endblock %} +{% block heading %}Venue{% endblock %} +{% block lede %}{{ SITE_NAME }} is being held on a Django Hosting facility, somewhere.{% endblock %} + +{% block content %} +

I am the body content

+{% endblock %} diff --git a/pinaxcon/templates/site_base.html b/pinaxcon/templates/site_base.html index f551155..74e2fd5 100644 --- a/pinaxcon/templates/site_base.html +++ b/pinaxcon/templates/site_base.html @@ -5,12 +5,10 @@ {% load i18n %} {% load sitetree %} - {% block styles %} {% include "_styles.html" %} {% endblock %} - {% block extra_head_base %} {% block extra_head %}{% endblock %} {% endblock %} @@ -46,7 +44,6 @@ {% block scripts %} {% include "_scripts.html" %} - {% endblock %} {% block extra_body_base %} diff --git a/pinaxcon/templates/symposion/conference/user_list.html b/pinaxcon/templates/symposion/conference/user_list.html deleted file mode 100644 index 502698f..0000000 --- a/pinaxcon/templates/symposion/conference/user_list.html +++ /dev/null @@ -1,95 +0,0 @@ -{% extends "site_base.html" %} - -{% load i18n %} -{% load sitetree %} - -{% block head_title %}User List{% endblock %} - -{% block extra_style %} - -{% endblock %} - -{% block body_outer %} -

User List

- - - - - - - - - {% for user in users %} - - - - - - {% endfor %} - -
{% trans "Email" %}{% trans "Name" %}{% trans "Speaker Profile?" %}
{{ user.email }}{{ user.get_full_name }} - {% if user.speaker_profile %} - {{ user.speaker_profile }} - {% else %} - create - {% endif %} -
-{% endblock %} - -{% block extra_script %} - - - - -{% endblock %} diff --git a/pinaxcon/templates/symposion/emails/proposal_new_message/message.html b/pinaxcon/templates/symposion/emails/proposal_new_message/message.html deleted file mode 100644 index b56af29..0000000 --- a/pinaxcon/templates/symposion/emails/proposal_new_message/message.html +++ /dev/null @@ -1,13 +0,0 @@ -{% load account_tags %} -{% load i18n %} -{% user_display message.user as user %} -

- {% blocktrans with title=proposal.title %}{{ user }} has added a message on {{ title }}.{% endblocktrans %} -

-
- {{ message.message|safe }} -
-

- {% if reviewer %}{% url 'review_detail' proposal.pk as detail_url %}{% else %}{% url 'proposal_detail' proposal.pk as detail_url %}{% endif %} - {% blocktrans %} Respond online at http://{{ current_site }}{{ detail_url }}#proposal-feedback{% endblocktrans %} -

diff --git a/pinaxcon/templates/symposion/emails/proposal_new_message/subject.txt b/pinaxcon/templates/symposion/emails/proposal_new_message/subject.txt deleted file mode 100644 index d710715..0000000 --- a/pinaxcon/templates/symposion/emails/proposal_new_message/subject.txt +++ /dev/null @@ -1 +0,0 @@ -{% load account_tags i18n %}{% user_display message.user as user %}{% blocktrans with title=proposal.title %}New message on "{{ title }}" from {{ user }}{% endblocktrans %} diff --git a/pinaxcon/templates/symposion/emails/proposal_updated/message.html b/pinaxcon/templates/symposion/emails/proposal_updated/message.html deleted file mode 100644 index 93a5a26..0000000 --- a/pinaxcon/templates/symposion/emails/proposal_updated/message.html +++ /dev/null @@ -1,10 +0,0 @@ -{% load account_tags %} -{% load i18n %} -{% user_display user as username %} -

- {% blocktrans with title=proposal.title %}{{ username }} has made changes to {{ title }} which you have previously reviewed or commented on.{% endblocktrans %} -

-

- {% url 'review_detail' proposal.pk as detail_url %} - {% blocktrans %}View the latest version of the proposal online at http://{{ current_site }}{{ detail_url }}{% endblocktrans %} -

diff --git a/pinaxcon/templates/symposion/emails/proposal_updated/subject.txt b/pinaxcon/templates/symposion/emails/proposal_updated/subject.txt deleted file mode 100644 index 379a071..0000000 --- a/pinaxcon/templates/symposion/emails/proposal_updated/subject.txt +++ /dev/null @@ -1 +0,0 @@ -{% load account_tags i18n %}{% user_display user as username %}{% blocktrans with title=proposal.title %}"{{ title }}" has been updated by {{ username }}{% endblocktrans %} diff --git a/pinaxcon/templates/symposion/emails/speaker_addition/message.html b/pinaxcon/templates/symposion/emails/speaker_addition/message.html deleted file mode 100644 index 9bebdf7..0000000 --- a/pinaxcon/templates/symposion/emails/speaker_addition/message.html +++ /dev/null @@ -1,10 +0,0 @@ -{% load i18n %} -{% url 'dashboard' as dashboard_url %} -{% blocktrans with username=proposal.speaker.name site_name=current_site.name title=proposal.title %} -

{{ username }} attached you as an additional speaker to a - talk proposal for {{ site_name }} entitled "{{ title }}".

- -

For more details, visit the {{ site_name }} speaker dashboard: - http://{{ current_site }}{{ dashboard_url ]} -

-{% endblocktrans %} diff --git a/pinaxcon/templates/symposion/emails/speaker_addition/subject.txt b/pinaxcon/templates/symposion/emails/speaker_addition/subject.txt deleted file mode 100644 index d8970d5..0000000 --- a/pinaxcon/templates/symposion/emails/speaker_addition/subject.txt +++ /dev/null @@ -1 +0,0 @@ -{% load i18n %}{% blocktrans with name=proposal.speaker.name title=proposal.title %}{{ name }} has invited you to join as a speaker on {{ title }}{% endblocktrans %} diff --git a/pinaxcon/templates/symposion/emails/speaker_invite/message.html b/pinaxcon/templates/symposion/emails/speaker_invite/message.html deleted file mode 100644 index f4265db..0000000 --- a/pinaxcon/templates/symposion/emails/speaker_invite/message.html +++ /dev/null @@ -1,14 +0,0 @@ -{% load i18n %} -{% url 'speaker_create_token' token as token_url %} -{% blocktrans with invitator=proposal.speaker.name title=proposal.title site_name=current_site.name %} -

{{ invitator }} attached you as an additional speaker to a - talk proposal for {{ site_name }} entitled "{{ title }}".

- -

Go to

- -

http://{{ current_site }}{{ token_url }}

- -

to confirm.

- -

If you don't have account on the website, you will be asked to create one.

-{% endblocktrans %} diff --git a/pinaxcon/templates/symposion/emails/speaker_invite/subject.txt b/pinaxcon/templates/symposion/emails/speaker_invite/subject.txt deleted file mode 100644 index d8970d5..0000000 --- a/pinaxcon/templates/symposion/emails/speaker_invite/subject.txt +++ /dev/null @@ -1 +0,0 @@ -{% load i18n %}{% blocktrans with name=proposal.speaker.name title=proposal.title %}{{ name }} has invited you to join as a speaker on {{ title }}{% endblocktrans %} diff --git a/pinaxcon/templates/symposion/emails/speaker_no_profile/message.html b/pinaxcon/templates/symposion/emails/speaker_no_profile/message.html deleted file mode 100644 index da21357..0000000 --- a/pinaxcon/templates/symposion/emails/speaker_no_profile/message.html +++ /dev/null @@ -1,12 +0,0 @@ -{% load i18n %} -{% url 'speaker_create_token' token as token_url %} -{% blocktrans with username=proposal.speaker.name site_name=current_site.name title=proposal.title %} -

{{ username }} attached you as an additional speaker to a - talk proposal for {{ site_name }} entitled "{{ title }}".

- -

Go to

- -

http://{{ current_site }}{{ token_url }}

- -

to confirm and fill out your speaker profile.

-{% endblocktrans %} diff --git a/pinaxcon/templates/symposion/emails/speaker_no_profile/subject.txt b/pinaxcon/templates/symposion/emails/speaker_no_profile/subject.txt deleted file mode 100644 index d8970d5..0000000 --- a/pinaxcon/templates/symposion/emails/speaker_no_profile/subject.txt +++ /dev/null @@ -1 +0,0 @@ -{% load i18n %}{% blocktrans with name=proposal.speaker.name title=proposal.title %}{{ name }} has invited you to join as a speaker on {{ title }}{% endblocktrans %} diff --git a/pinaxcon/templates/symposion/emails/sponsor_signup/message.html b/pinaxcon/templates/symposion/emails/sponsor_signup/message.html deleted file mode 100644 index c10b13d..0000000 --- a/pinaxcon/templates/symposion/emails/sponsor_signup/message.html +++ /dev/null @@ -1,12 +0,0 @@ -{% load i18n %} -{% blocktrans with sponsor_name=sponsor.name applicant=sponsor.applicant contact=sponsor.contact_name email=sponsor.contact_email level=sponsor.level %} -

{{ sponsor_name }} has applied to be a sponsor.

- - -{% endblocktrans %} diff --git a/pinaxcon/templates/symposion/emails/sponsor_signup/subject.txt b/pinaxcon/templates/symposion/emails/sponsor_signup/subject.txt deleted file mode 100644 index 15d23fa..0000000 --- a/pinaxcon/templates/symposion/emails/sponsor_signup/subject.txt +++ /dev/null @@ -1 +0,0 @@ -{% load i18n %}{% trans "New Sponsor Application" %} diff --git a/pinaxcon/templates/symposion/emails/teams_user_applied/message.html b/pinaxcon/templates/symposion/emails/teams_user_applied/message.html deleted file mode 100644 index b05d6c8..0000000 --- a/pinaxcon/templates/symposion/emails/teams_user_applied/message.html +++ /dev/null @@ -1,12 +0,0 @@ -{% load i18n account_tags %} -{% user_display user as username %} -{% blocktrans with team_name=team team_url=team.get_absolute_url site_name=current_site.name site_url=current_site %} -

- User "{{ username }}" has applied to join {{ team_name }} on {{ site_name }}. -

- -

- To accept this application and see any other pending applications, visit the following url: - http://{{ site_url }}{{ team_url }} -

-{% endblocktrans %} diff --git a/pinaxcon/templates/symposion/emails/teams_user_applied/subject.txt b/pinaxcon/templates/symposion/emails/teams_user_applied/subject.txt deleted file mode 100644 index 84b2938..0000000 --- a/pinaxcon/templates/symposion/emails/teams_user_applied/subject.txt +++ /dev/null @@ -1 +0,0 @@ -{% load i18n account_tags %}{% user_display user as username %}{% blocktrans %}{{ username}} has applied to to join "{{ team }}"{% endblocktrans %} \ No newline at end of file diff --git a/pinaxcon/templates/symposion/emails/teams_user_invited/message.html b/pinaxcon/templates/symposion/emails/teams_user_invited/message.html deleted file mode 100644 index b498d24..0000000 --- a/pinaxcon/templates/symposion/emails/teams_user_invited/message.html +++ /dev/null @@ -1,12 +0,0 @@ -{% load i18n account_tags %} - -{% blocktrans with team_name=team team_url=team.get_absolute_url site_name=current_site.name site_url=current_site %} -

- You have been invited to join {{ team_name }} on {{ site_name }}. -

- -

- To accept this invitation, visit the following url: - http://{{ site_url }}{{ team_url }} -

-{% endblocktrans %} \ No newline at end of file diff --git a/pinaxcon/templates/symposion/emails/teams_user_invited/subject.txt b/pinaxcon/templates/symposion/emails/teams_user_invited/subject.txt deleted file mode 100644 index 434412b..0000000 --- a/pinaxcon/templates/symposion/emails/teams_user_invited/subject.txt +++ /dev/null @@ -1 +0,0 @@ -{% load i18n %}{% blocktrans %}You have been invited to join "{{ team }}"{% endblocktrans %} \ No newline at end of file diff --git a/pinaxcon/templates/symposion/proposals/_pending_proposal_row.html b/pinaxcon/templates/symposion/proposals/_pending_proposal_row.html deleted file mode 100644 index 2ea6ba6..0000000 --- a/pinaxcon/templates/symposion/proposals/_pending_proposal_row.html +++ /dev/null @@ -1,42 +0,0 @@ -{% load i18n %} - - - - {{ proposal.title }} - - - {{ proposal.kind.name }} - - - {% if proposal.cancelled %} - {% trans 'Cancelled' %} - {% else %} - {% if request.user == proposal.speaker.user %} - {% if proposal.result.status == "accepted" %} - {% trans 'Accepted' %} - {% else %} - {% trans 'Submitted' %} - {% endif %} - {% else %} - {% trans 'Invited' %} - {% endif %} - {% endif %} - - - - {% if not proposal.cancelled %} -
- - {% trans 'Choose Response' %} - - - -
- {% endif %} - - diff --git a/pinaxcon/templates/symposion/proposals/_proposal_fields.html b/pinaxcon/templates/symposion/proposals/_proposal_fields.html deleted file mode 100644 index 12ab45f..0000000 --- a/pinaxcon/templates/symposion/proposals/_proposal_fields.html +++ /dev/null @@ -1,60 +0,0 @@ -{% load i18n %} - -
-
{% trans "Submitted by" %}
-
{{ proposal.speaker }}
- -
{% trans "Track" %}
-
{{ proposal.track }} 
- -
{% trans "Audience Level" %}
-
{{ proposal.get_audience_level_display }} 
- - {% if proposal.additional_speakers.all %} -
{% trans "Additional Speakers" %}
-
- {% for speaker in proposal.additional_speakers.all %} -
  • - {% if speaker.user %} - {{ speaker.name }} <{{ speaker.email }}> - {% else %} - {{ speaker.email }} ({% trans "Invitation Sent" %}) - {% endif %} -
  • - {% endfor %} -
    - {% endif %} - -
    {% trans "Description" %}
    -
    {{ proposal.description }} 
    - -
    {% trans "Abstract" %}
    -
    {{ proposal.abstract_html|safe }} 
    - -
    {% trans "Notes" %}
    -
    {{ proposal.additional_notes_html|safe }} 
    - -
    {% trans "Speaker Bio" %}
    -
    {{ proposal.speaker.biography|safe }} 
    - -
    {% trans "Documents" %}
    -
    - {% if proposal.supporting_documents.exists %} - - {% for document in proposal.supporting_documents.all %} - - - - - {% endfor %} -
    {{ document.description }} -
    - {% csrf_token %} - -
    -
    - {% else %} - No supporting documents attached to this proposal. - {% endif %} -
    -
    diff --git a/pinaxcon/templates/symposion/proposals/_proposal_row.html b/pinaxcon/templates/symposion/proposals/_proposal_row.html deleted file mode 100644 index bc8b2f2..0000000 --- a/pinaxcon/templates/symposion/proposals/_proposal_row.html +++ /dev/null @@ -1,32 +0,0 @@ - - - {{ proposal.title }} - - - {{ proposal.kind.name }} - - - {% if proposal.cancelled %} - Cancelled - {% else %} - {% if request.user == proposal.speaker.user %} - {% if proposal.result.status == "accepted" %} - Accepted - {% else %} - Submitted - {% endif %} - {% else %} - Associated - {% endif %} - {% endif %} - - - - {% if not proposal.cancelled %} - {% if request.user == proposal.speaker.user and proposal.can_edit %} - Edit - Manage Additional Speakers - {% endif %} - {% endif %} - - diff --git a/pinaxcon/templates/symposion/proposals/base.html b/pinaxcon/templates/symposion/proposals/base.html deleted file mode 100644 index d6a6615..0000000 --- a/pinaxcon/templates/symposion/proposals/base.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "site_base.html" %} - -{% block body_outer %} - {% block body %}{% endblock %} -{% endblock %} diff --git a/pinaxcon/templates/symposion/proposals/document_create.html b/pinaxcon/templates/symposion/proposals/document_create.html deleted file mode 100644 index c39fcea..0000000 --- a/pinaxcon/templates/symposion/proposals/document_create.html +++ /dev/null @@ -1,17 +0,0 @@ -{% extends "symposion/proposals/base.html" %} - -{% load bootstrap %} - -{% block page_title %}Upload Document to '{{ proposal.title }}'{% endblock %} - -{% block body %} -
    - {% csrf_token %} -
    - {{ form|bootstrap_horizontal }} -
    -
    - -
    -
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/proposals/proposal_cancel.html b/pinaxcon/templates/symposion/proposals/proposal_cancel.html deleted file mode 100644 index a13f7f7..0000000 --- a/pinaxcon/templates/symposion/proposals/proposal_cancel.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends "symposion/proposals/base.html" %} - -{% load i18n %} - -{% block head_title %}{% trans 'Cancel Proposal' %}{% endblock %} - -{% block body %} -

    Cancel: {{ proposal.title }}

    - -
    - {% csrf_token %} -

    Are you sure you want to cancel {{ proposal.title }}?

    - - {% trans 'No, keep it for now' %} -
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/proposals/proposal_detail.html b/pinaxcon/templates/symposion/proposals/proposal_detail.html deleted file mode 100644 index 2d65fe7..0000000 --- a/pinaxcon/templates/symposion/proposals/proposal_detail.html +++ /dev/null @@ -1,119 +0,0 @@ -{% extends "symposion/proposals/base.html" %} - -{% load i18n %} -{% load account_tags %} -{% load bootstrap %} - -{% block head_title %}{{ proposal.title }}{% endblock %} - -{% block body %} -
    - {% if not proposal.cancelled %} - {% if request.user == proposal.speaker.user %} - - {% trans "Edit this proposal" %} - - - {% trans "Cancel this proposal" %} - - {% else %} - - {% trans "Remove me from this proposal" %} - - {% endif %} - {% else %} - {% trans 'Cancelled' } - {% endif %} -
    - -

    #{{ proposal.number }}: {{ proposal.title }} ({{ proposal.speaker }}, Track: {{ proposal.track }})

    - -
    - -
    -
    - {% include "symposion/proposals/_proposal_fields.html" %} -
    - {% if request.user == proposal.speaker.user %} -
    -

    {% trans 'Supporting Documents' %}

    - - {% if proposal.supporting_documents.exists %} - - {% for document in proposal.supporting_documents.all %} - - - - - {% endfor %} -
    {{ document.description }} -
    - {% csrf_token %} - -
    -
    - {% else %} -

    {% trans 'No supporting documents attached to this proposal.' %}

    - {% endif %} - {% trans 'Add Document' %} -
    - {% endif %} - - {% if message_form %} -
    - -

    {% trans 'Conversation with Reviewers' %}

    - - {% for message in proposal.messages.all %} -
    -
    {{ message.message|safe }}
    - -
    -
    - {% endfor %} - -

    {% trans 'Leave a Message' %}

    - -

    {% trans 'You can leave a message for the reviewers here.' %}

    - -
    - {% csrf_token %} -
    - {{ message_form|bootstrap }} -
    -
    - -
    -
    -
    - {% endif %} -
    -
    -{% endblock %} - -{% block extra_script %} - - -{% endblock extra_script %} diff --git a/pinaxcon/templates/symposion/proposals/proposal_edit.html b/pinaxcon/templates/symposion/proposals/proposal_edit.html deleted file mode 100644 index 219d107..0000000 --- a/pinaxcon/templates/symposion/proposals/proposal_edit.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "symposion/proposals/base.html" %} - -{% load bootstrap %} - -{% block head_title %}Editing {{ proposal.title }}{% endblock %} - -{% block body %} -

    Edit: {{ proposal.title }}

    - -

    Manage speakers

    - -
    - {% csrf_token %} -
    - {{ form|bootstrap }} -
    -
    - - Cancel -
    -
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/proposals/proposal_leave.html b/pinaxcon/templates/symposion/proposals/proposal_leave.html deleted file mode 100644 index dbaad04..0000000 --- a/pinaxcon/templates/symposion/proposals/proposal_leave.html +++ /dev/null @@ -1,11 +0,0 @@ -{% extends "symposion/proposals/base.html" %} - -{% block body %} -

    Leaving {{ proposal.title }}

    - -
    - {% csrf_token %} -

    Are you sure you wish to leave as a speaker on {{ proposal.title }}?

    - -
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/proposals/proposal_speaker_manage.html b/pinaxcon/templates/symposion/proposals/proposal_speaker_manage.html deleted file mode 100644 index 0127b41..0000000 --- a/pinaxcon/templates/symposion/proposals/proposal_speaker_manage.html +++ /dev/null @@ -1,41 +0,0 @@ -{% extends "symposion/proposals/base.html" %} - -{% load i18n %} -{% load bootstrap %} - -{% block body %} -

    {% trans 'Proposal:' %} {{ proposal.title }}

    - -

    - {% trans 'Edit proposal' %} - -

    - -

    {% trans 'Current Speakers' %}

    - - {% for speaker in speakers %} - {% if speaker.user %} -

    {{ speaker.name }} — {{ speaker.email }}

    - {% else %} -

    {{ speaker.email }} — {% trans 'pending invitation' %}

    - {% endif %} - {% endfor %} - -

    {% trans 'Add another speaker' %}

    - -
    - {% csrf_token %} - {{ add_speaker_form|bootstrap }} -
    - -
    -
    -{% endblock %} - -{% block extra_body %} - -{% endblock %} diff --git a/pinaxcon/templates/symposion/proposals/proposal_submit.html b/pinaxcon/templates/symposion/proposals/proposal_submit.html deleted file mode 100644 index a2face3..0000000 --- a/pinaxcon/templates/symposion/proposals/proposal_submit.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "symposion/proposals/base.html" %} - -{% load pinax_boxes_tags %} -{% load i18n %} - -{% block page_title %}{% trans "Submit A Proposal" %}{% endblock %} - -{% block body %} - {% box "proposal_submit" %} - - {% if kinds %} -

    Select what kind of proposal you'd like to submit:

    - - {% for kind in kinds %} - {{ kind }} - {% endfor %} - {% else %} -

    Proposals are not currently open for submission.

    - {% endif %} -{% endblock %} diff --git a/pinaxcon/templates/symposion/proposals/proposal_submit_kind.html b/pinaxcon/templates/symposion/proposals/proposal_submit_kind.html deleted file mode 100644 index c90de0d..0000000 --- a/pinaxcon/templates/symposion/proposals/proposal_submit_kind.html +++ /dev/null @@ -1,26 +0,0 @@ -{% extends "symposion/proposals/base.html" %} - -{% load bootstrap %} -{% load pinax_boxes_tags %} -{% load i18n %} - -{% block page_title %}Submit a Proposal for a {{ kind.name }}{% endblock %} - -{% block body %} - {% box "example_proposal" %} - -
    - {% csrf_token %} -
    - {{ proposal_form|bootstrap_horizontal }} -
    -
    -

    - You will be able to edit your proposal after it has been submitted. The program committee may ask questions, provide feedback, and even suggest changes to your proposal as part of the review processes. -

    - - - -
    -
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/reviews/_result_notification_prepare_help.html b/pinaxcon/templates/symposion/reviews/_result_notification_prepare_help.html deleted file mode 100644 index e0ef7dd..0000000 --- a/pinaxcon/templates/symposion/reviews/_result_notification_prepare_help.html +++ /dev/null @@ -1,7 +0,0 @@ - Body may include the following variables which will be substituted in the email with a value - specific to each proposal: - \ No newline at end of file diff --git a/pinaxcon/templates/symposion/reviews/_review_table.html b/pinaxcon/templates/symposion/reviews/_review_table.html deleted file mode 100644 index 1570f7f..0000000 --- a/pinaxcon/templates/symposion/reviews/_review_table.html +++ /dev/null @@ -1,37 +0,0 @@ -{% load i18n %} - - - - - - - - - - - - - - - - {% for proposal in proposals %} - - - - - - - - - - - - {% endfor %} - -
    #{% trans "Speaker / Title" %}{% trans "Category" %}{% trans "+1" %}{% trans "+0" %}{% trans "-0" %}{% trans "-1" %}
    {{ proposal.number }} - - {{ proposal.speaker }} -
    - {{ proposal.title }} -
    -
    {{ proposal.track }}{{ proposal.comment_count }}{{ proposal.plus_one }}{{ proposal.plus_zero }}{{ proposal.minus_zero }}{{ proposal.minus_one }}{{ proposal.user_vote|default:"" }}
    diff --git a/pinaxcon/templates/symposion/reviews/access_not_permitted.html b/pinaxcon/templates/symposion/reviews/access_not_permitted.html deleted file mode 100644 index 0d0d0e5..0000000 --- a/pinaxcon/templates/symposion/reviews/access_not_permitted.html +++ /dev/null @@ -1,10 +0,0 @@ -{% extends "symposion/reviews/base.html" %} - -{% block body %} -

    Access Not Permitted

    - -

    - Sorry, you do not have permission to access this page. If you - believe this is a bug, please contact us immediately. -

    -{% endblock %} diff --git a/pinaxcon/templates/symposion/reviews/base.html b/pinaxcon/templates/symposion/reviews/base.html deleted file mode 100644 index 84d3e20..0000000 --- a/pinaxcon/templates/symposion/reviews/base.html +++ /dev/null @@ -1,112 +0,0 @@ -{% extends "site_base.html" %} - -{% load i18n %} -{% load sitetree %} - -{% block extra_style %} - -{% endblock %} - -{% block body_class %}reviews{% endblock %} - -{% block body_outer %} -
    -
    - {% block sidebar %} - {% for section in review_sections %} -
    -
    -

    {{ section }}

    -
    -
    - - {% trans "All Reviews" %} - - {% comment %} -
  • - - {% trans "Your Assignments" %} - -
  • - {% endcomment %} - - {% trans "Voting Status" %} - - {% if request.user.is_staff %} - Result Notification - {% endif %} -
    - {% endfor %} - {% endblock %} -
    -
    - {% block body %} - {% endblock %} -
    -
    -{% endblock %} - -{% block extra_script %} - - - - -{% endblock %} diff --git a/pinaxcon/templates/symposion/reviews/result_notification.html b/pinaxcon/templates/symposion/reviews/result_notification.html deleted file mode 100644 index ed3fbd4..0000000 --- a/pinaxcon/templates/symposion/reviews/result_notification.html +++ /dev/null @@ -1,156 +0,0 @@ -{% extends "symposion/reviews/base.html" %} - -{% load i18n %} - - -{% block body_class %}{{ block.super }} review-results{% endblock %} - -{% block extra_style %} - -{% endblock %} - -{% block body %} - - - -

    Result Notification

    - -
    - - {% csrf_token %} - -

    - Select one or more proposals (0 currently selected) -
    - then pick an email template - -
    - -

    - - - - - - - - - - - - - {% for proposal in proposals %} - - - - - - - - - {% endfor %} - -
    #{% trans "Speaker / Title" %}{% trans "Category" %}{% trans "Status" %}{% trans "Notified?" %}
    {{ proposal.number }} - - {{ proposal.speaker }} -
    - {{ proposal.title }} -
    -
    {{ proposal.track }} - {% with proposal.result.status as status %} -
    - {% if status != "undecided" %} - {{ status }} - {% endif %} -
    - {% endwith %} -
    - {% if proposal.notifications.exists %}yes{% endif %} -
    -
    -{% endblock %} - -{% block extra_script %} - -{% endblock %} diff --git a/pinaxcon/templates/symposion/reviews/result_notification_prepare.html b/pinaxcon/templates/symposion/reviews/result_notification_prepare.html deleted file mode 100644 index 2abc8f8..0000000 --- a/pinaxcon/templates/symposion/reviews/result_notification_prepare.html +++ /dev/null @@ -1,49 +0,0 @@ -{% extends "symposion/reviews/base.html" %} - -{% load i18n %} - -{% block body %} -

    Result Notification Prepare

    - -
    -
    -

    Proposals

    - - {% for proposal in proposals %} - - - - {% endfor %} -
    - {{ proposal.speaker }} ({{ proposal.speaker.email }}) -
    - {{ proposal.title }} -
    -
    -
    -

    Email

    - -
    - - {% csrf_token %} - - - -
    - - -
    - - -
    - - - - {% include "symposion/reviews/_result_notification_prepare_help.html" %} - - - Cancel -
    -
    - -{% endblock %} diff --git a/pinaxcon/templates/symposion/reviews/review_admin.html b/pinaxcon/templates/symposion/reviews/review_admin.html deleted file mode 100644 index 6b6fe81..0000000 --- a/pinaxcon/templates/symposion/reviews/review_admin.html +++ /dev/null @@ -1,56 +0,0 @@ -{% extends "symposion/reviews/base.html" %} - -{% block body %} -

    Reviewers

    - - - - - - - - - - - {% for reviewer in reviewers %} - - - - - - - - - - {% endfor %} -
    - Reviewer - - Proposals
    Reviewed - -
    - Comments - - +1 - - +0 - - −0 - - −1 -
    - {{ reviewer.get_full_name }} - - {{ reviewer.total_votes }} - - {{ reviewer.comment_count }} - - {{ reviewer.plus_one }} - - {{ reviewer.plus_zero }} - - {{ reviewer.minus_zero }} - - {{ reviewer.minus_one }} -
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/reviews/review_assignment.html b/pinaxcon/templates/symposion/reviews/review_assignment.html deleted file mode 100644 index bfe60be..0000000 --- a/pinaxcon/templates/symposion/reviews/review_assignment.html +++ /dev/null @@ -1,32 +0,0 @@ -{% extends "symposion/reviews/base.html" %} - -{% block body %} -

    Review Assignments

    - - {% if assignments %} - - - - - - - {% for assignment in assignments %} - - - - - {% endfor %} -
    ProposalOpted outOpt out
    - - {{ assignment.proposal.title }} - - -
    - {% csrf_token %} - -
    -
    - {% else %} -

    You do not have any assignments.

    - {% endif %} -{% endblock %} diff --git a/pinaxcon/templates/symposion/reviews/review_bulk_accept.html b/pinaxcon/templates/symposion/reviews/review_bulk_accept.html deleted file mode 100644 index 81f1e57..0000000 --- a/pinaxcon/templates/symposion/reviews/review_bulk_accept.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "symposion/reviews/base.html" %} - -{% load bootstrap %} - -{% block body %} - -

    Bulk Accept

    -
    - {% csrf_token %} - {{ form|bootstrap }} -
    - -
    -
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/reviews/review_comment.html b/pinaxcon/templates/symposion/reviews/review_comment.html deleted file mode 100644 index d7fa96a..0000000 --- a/pinaxcon/templates/symposion/reviews/review_comment.html +++ /dev/null @@ -1,2 +0,0 @@ -{{ proposal }}: proposal obj -{{ form }}: comment form obj diff --git a/pinaxcon/templates/symposion/reviews/review_detail.html b/pinaxcon/templates/symposion/reviews/review_detail.html deleted file mode 100644 index 76e1bbd..0000000 --- a/pinaxcon/templates/symposion/reviews/review_detail.html +++ /dev/null @@ -1,186 +0,0 @@ -{% extends "symposion/reviews/base.html" %} - -{% load i18n %} -{% load bootstrap %} -{% load account_tags %} - - -{% block body %} - {% if request.user.is_staff %} -
    -
    - {% csrf_token %} -
    - {% if proposal.result.status == "accepted" %} - Accepted - - {% else %} - {% if proposal.result.status == "rejected" %} - Rejected - - {% else %} - {% if proposal.result.status == "standby" %} - Standby - - {% else %} - Undecided - - {% endif %} - {% endif %} - {% endif %} -
    -
    -
    - {% endif %} - -

    #{{ proposal.number }}: {{ proposal.title }} ({{ proposal.speaker }})

    - -
    - -
    -
    - {% include "symposion/proposals/_proposal_fields.html" %} -
    -
    - -

    {% trans "Current Results" %}

    - - - - - - - - - - - - - - - - -
    +1 votes+0 votes-0 votes-1 votes{% trans "Total Responses" %} -
    {{ proposal.plus_one }}{{ proposal.plus_zero }}{{ proposal.minus_zero }}{{ proposal.minus_one }}{{ proposal.total_votes }}
    - -
    - - {% if review_form %} -
    - {% trans "Submit Review" %} -

    Enter your vote and any comment to go along with it. You can revise your vote or comment multiple times with an existing vote (your previously recorded score will be replaced during calculations). Your vote and comments are not public and will only be viewable by other reviewers.

    - {% csrf_token %} - {{ review_form|bootstrap }} -
    - -
    -
    - {% else %} -

    You do not have permission to vote on this proposal.

    - {% endif %} - - {% if reviews %} -
    Review Comments
    - {% for review in reviews %} -
    -
    - {{ review.vote }} -
    - {% if is_manager %} -
    -
    - {% csrf_token %} - -
    -
    - {% endif %} -
    - {% user_display review.user %} - {{ review.submitted_at|timesince }} ago
    - {{ review.comment|safe }} -
    -
    - {% endfor %} - {% endif %} -
    -
    - {% if review_messages %} -

    {% trans "Conversation with the submitter" %}

    - {% for message in review_messages %} -
    -
    - {% user_display message.user %} - {{ message.submitted_at|timesince }} ago
    - {{ message.message|safe }} -
    -
    - {% endfor %} -
    - {% endif %} - -
    - {% trans "Send a message" %} -

    - {% blocktrans %} - If you'd like to communicate with the submitter, use the following form and he or she will be - notified and given the opportunity to respond. - {% endblocktrans %} -

    - {% csrf_token %} - {{ message_form|bootstrap }} -
    - -
    -
    -
    -
    -
    -{% endblock %} - -{% block extra_script %} - - - -{% endblock %} diff --git a/pinaxcon/templates/symposion/reviews/review_list.html b/pinaxcon/templates/symposion/reviews/review_list.html deleted file mode 100644 index 45693d2..0000000 --- a/pinaxcon/templates/symposion/reviews/review_list.html +++ /dev/null @@ -1,17 +0,0 @@ -{% extends "symposion/reviews/base.html" %} - - -{% block body_class %}{{ block.super }} review-list{% endblock %} - -{% block body %} -

    {{ section }}

    - {% if reviewed == 'all_reviews' %} -

    All proposals

    - {% elif reviewed == 'user_reviewed' %} -

    Proposals you have reviewed

    - {% else %} -

    Proposals you have not yet reviewed

    - {% endif %} - - {% include "symposion/reviews/_review_table.html" %} -{% endblock %} diff --git a/pinaxcon/templates/symposion/reviews/review_review.html b/pinaxcon/templates/symposion/reviews/review_review.html deleted file mode 100644 index 4f5b040..0000000 --- a/pinaxcon/templates/symposion/reviews/review_review.html +++ /dev/null @@ -1,77 +0,0 @@ -{% extends "site_base.html" %} - -{% load bootstrap %} - -{% block body_class %}review{% endblock %} - -{% block body %} -

    Proposal Review

    - -
    -

    {{ proposal.title }}

    - -

    - {% if proposal.cancelled %} - Cancelled - {% endif %} -

    - -
    - {{ proposal.description }} -
    - -

    Type: {{ proposal.get_session_type_display }}

    - -

    Abstract

    -
    - {{ proposal.abstract_html|safe }} -
    - -

    Audience level: {{ proposal.get_audience_level_display }}

    - -

    Submitting speaker: {{ proposal.speaker }}

    {# @@@ bio? #} - - {% if proposal.additional_speakers.all %} -

    Additional speakers:

    -
      - {% for speaker in proposal.additional_speakers.all %} - {% if speaker.user %} -
    • {{ speaker.name }} — {{ speaker.email }}
    • - {% else %} -
    • {{ speaker.email }} — pending invitation
    • - {% endif %} - {% endfor %} -
    - {% endif %} - -

    Additional Notes (private from submitter)

    -
    - {{ proposal.additional_notes }} -
    -
    - -

    Review

    - -
    - {% csrf_token %} -
    - {{ review_form|bootstrap }} -
    - -
    -
    -
    - -

    Comment

    - -
    - {% csrf_token %} -
    - {{ comment_form|bootstrap }} -
    - -
    -
    -
    - -{% endblock %} diff --git a/pinaxcon/templates/symposion/reviews/review_stats.html b/pinaxcon/templates/symposion/reviews/review_stats.html deleted file mode 100644 index ac21cc1..0000000 --- a/pinaxcon/templates/symposion/reviews/review_stats.html +++ /dev/null @@ -1,85 +0,0 @@ -{% extends "symposion/reviews/base.html" %} - -{% block body_class %}{{ block.super }} voting-status {{ key }}{% endblock %} - -{% block body %} -

    Voting Status ({{ section_slug }})

    - - {% if key %} -
    - - -
    - {% if key == "positive" %} -

    Positive - proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and at least one +1 and no −1s

    - {% endif %} - {% if key == "negative" %} -

    Negative - proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and at least one −1 and no +1s

    - {% endif %} - {% if key == "indifferent" %} -

    Indifferent - proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and neither a +1 or a −1

    - {% endif %} - {% if key == "controversial" %} -

    Controversial - proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and both a +1 and −1

    - {% endif %} - {% if key == "too_few" %} -

    Too Few Reviews - proposals with fewer than {{ vote_threshold }} vote{{ vote_threshold|pluralize }}

    - {% endif %} - - {% include "symposion/reviews/_review_table.html" %} - -
    - {% else %} -

    Reviews are placed into one of five buckets depending on the state of their votes:

    - -
    -
    - Positive - {{ proposals.positive|length }} -
    -
    - proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and at least one +1 and no −1s -
    -
    - Negative - {{ proposals.negative|length }} -
    -
    - proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and at least one −1 and no +1s -
    -
    - Indifferent - {{ proposals.indifferent|length }} -
    -
    - proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and neither a +1 or a −1 -
    -
    - Controversial - {{ proposals.controversial|length }} -
    -
    - proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and both a +1 and −1 -
    -
    - Too Few Reviews - {{ proposals.too_few|length }} -
    -
    - proposals with fewer than {{ vote_threshold }} vote{{ vote_threshold|pluralize }} -
    -
    - {% endif %} - -{% endblock %} diff --git a/pinaxcon/templates/symposion/schedule/_edit_grid.html b/pinaxcon/templates/symposion/schedule/_edit_grid.html deleted file mode 100644 index 713909f..0000000 --- a/pinaxcon/templates/symposion/schedule/_edit_grid.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - {% for room in timetable.rooms %} - - {% endfor %} - - - - {% for row in timetable %} - - - {% for slot in row.slots %} - - {% endfor %} - {% if forloop.last %} - - {% endif %} - - {% endfor %} - -
     {{ room.name }}
    {{ row.time|date:"h:iA" }} - {% if slot.kind.label == "talk" or slot.kind.label == "tutorial" %} - {% if not slot.content %} - + - {% else %} - {{ slot.content.title }} - {{ slot.content.speaker }} - {% endif %} - {% else %} - {% if slot.content_override.raw %} - {{ slot.content_override.rendered|safe }} - {% else %} - {{ slot.kind.label }} - {% endif %} - — edit - {% endif %} -
    diff --git a/pinaxcon/templates/symposion/schedule/_grid.html b/pinaxcon/templates/symposion/schedule/_grid.html deleted file mode 100644 index 5df035b..0000000 --- a/pinaxcon/templates/symposion/schedule/_grid.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - {% for room in timetable.rooms %} - - {% endfor %} - - - - {% for row in timetable %} - - - {% for slot in row.slots %} - - {% endfor %} - {% if forloop.last %} - - {% endif %} - - {% endfor %} - -
     {{ room.name }}
    {{ row.time|date:"h:iA" }} - {% if slot.kind.label == "talk" or slot.kind.label == "tutorial" %} - {% if not slot.content %} - {% else %} - - {{ slot.content.title }} - - - {{ slot.content.speakers|join:", " }} - - {% endif %} - {% else %} - {% if slot.content_override.raw %} - {{ slot.content_override.rendered|safe }} - {% else %} - {{ slot.kind.label }} - {% endif %} - {% endif %} -
    diff --git a/pinaxcon/templates/symposion/schedule/_slot_edit.html b/pinaxcon/templates/symposion/schedule/_slot_edit.html deleted file mode 100644 index 1283aab..0000000 --- a/pinaxcon/templates/symposion/schedule/_slot_edit.html +++ /dev/null @@ -1,14 +0,0 @@ -{% load i18n bootstrap %} - diff --git a/pinaxcon/templates/symposion/schedule/presentation_detail.html b/pinaxcon/templates/symposion/schedule/presentation_detail.html deleted file mode 100644 index 4813f2e..0000000 --- a/pinaxcon/templates/symposion/schedule/presentation_detail.html +++ /dev/null @@ -1,35 +0,0 @@ -{% extends "site_base.html" %} - -{% load sitetree %} - -{% block head_title %}Presentation: {{ presentation.title }}{% endblock %} - -{% block breadcrumbs %}{% sitetree_breadcrumbs from "main" %}{% endblock %} - -{% block body %} - {% if presentation.slot %} -

    - {{ presentation.slot.day.date|date:"l" }} - {{ presentation.slot.start}}–{{ presentation.slot.end }} -

    - {% endif %} -

    {{ presentation.title }}

    - -

    - {% for speaker in presentation.speakers %} - {{ speaker }}{% if not forloop.last %}, {% endif %}{% endfor %} -

    - -
    -
    Audience level:
    -
    {{ presentation.proposal.get_audience_level_display }}
    -
    - -

    Description

    - -
    {{ presentation.description }}
    - -

    Abstract

    - -
    {{ presentation.abstract|safe }}
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/schedule/schedule_conference.html b/pinaxcon/templates/symposion/schedule/schedule_conference.html deleted file mode 100644 index 777a001..0000000 --- a/pinaxcon/templates/symposion/schedule/schedule_conference.html +++ /dev/null @@ -1,31 +0,0 @@ -{% extends "site_base.html" %} - -{% load i18n %} -{% load pinax_boxes_tags %} -{% load cache %} - -{% block head_title %}Conference Schedule{% endblock %} - -{% block body_class %}full{% endblock %} - -{% block right %} -{% endblock %} - -{% block body_outer %} -
    -

    Conference Schedule

    - {% block breadcrumbs %}{% endblock %} -
    - {% box "schedule_top" %} - - {% for section in sections %} - {% cache 600 "schedule-table" section.schedule.section %} - {% for timetable in section.days %} -

    {{ section.schedule.section.name }} — {{ timetable.day.date }}

    - {% include "symposion/schedule/_grid.html" %} - {% endfor %} - {% endcache %} - {% endfor %} - - {% box "schedule_bottom" %} -{% endblock %} diff --git a/pinaxcon/templates/symposion/schedule/schedule_detail.html b/pinaxcon/templates/symposion/schedule/schedule_detail.html deleted file mode 100644 index 679a807..0000000 --- a/pinaxcon/templates/symposion/schedule/schedule_detail.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "site_base.html" %} - -{% load i18n %} -{% load pinax_boxes_tags %} -{% load cache %} -{% load sitetree %} - -{% block head_title %}Conference Schedule{% endblock %} - -{% block body_class %}full{% endblock %} - -{% block right %} -{% endblock %} - -{% block body_outer %} -
    -

    {{ schedule.section }} Schedule

    - {% block breadcrumbs %}{% sitetree_breadcrumbs from "main" %}{% endblock %} -
    - {% box "schedule_top_"|add:schedule.section.name|slugify %} - - {% cache 600 "schedule-table" schedule.section %} - {% for timetable in days %} -

    {{ timetable.day.date }}

    - {% include "symposion/schedule/_grid.html" %} - {% endfor %} - {% endcache %} - - {% box "schedule_bottom" %} -{% endblock %} diff --git a/pinaxcon/templates/symposion/schedule/schedule_edit.html b/pinaxcon/templates/symposion/schedule/schedule_edit.html deleted file mode 100644 index a30e029..0000000 --- a/pinaxcon/templates/symposion/schedule/schedule_edit.html +++ /dev/null @@ -1,58 +0,0 @@ -{% extends "site_base.html" %} - -{% load i18n %} - -{% block head_title %}Conference Schedule Edit{% endblock %} - -{% block body_class %}full{% endblock %} - -{% block right %} -{% endblock %} - -{% block extra_head %} - -{% endblock %} - -{% block body_outer %} -

    Schedule Edit

    - - {% for timetable in days %} -

    {{ timetable.day.date }}

    - {% include "symposion/schedule/_edit_grid.html" %} - {% endfor %} -
    {% csrf_token %} - {{ form.as_p }} - - -
    - -{% endblock %} - -{% block extra_script %} - - -{% endblock %} diff --git a/pinaxcon/templates/symposion/schedule/schedule_list.html b/pinaxcon/templates/symposion/schedule/schedule_list.html deleted file mode 100644 index b67ccb7..0000000 --- a/pinaxcon/templates/symposion/schedule/schedule_list.html +++ /dev/null @@ -1,51 +0,0 @@ -{% extends "site_base.html" %} - -{% load i18n %} -{% load cache %} -{% load sitetree %} - -{% block head_title %}Presentation Listing{% endblock %} - -{% block extra_head %} - -{% endblock %} - -{% block breadcrumbs %}{% sitetree_breadcrumbs from "main" %}{% endblock %} - -{% block body %} -

    Accepted {{ schedule.section.name }}

    - {% cache 600 "schedule-list" schedule.section.name %} - {% for presentation in presentations %} -
    -
    -

    {{ presentation.title }}

    -

    {{ presentation.speakers|join:", " }}

    - {{ presentation.description }} - {% if presentation.slot %} -

    - {{ presentation.slot.day.date|date:"l" }} - {{ presentation.slot.start}}–{{ presentation.slot.end }} - in - {{ presentation.slot.rooms|join:", " }} -

    - {% endif %} -
    -
    - {% endfor %} - {% endcache %} -{% endblock %} diff --git a/pinaxcon/templates/symposion/speakers/base.html b/pinaxcon/templates/symposion/speakers/base.html deleted file mode 100644 index 5c4b85b..0000000 --- a/pinaxcon/templates/symposion/speakers/base.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "site_base_onecolumn.html" %} diff --git a/pinaxcon/templates/symposion/speakers/speaker_create.html b/pinaxcon/templates/symposion/speakers/speaker_create.html deleted file mode 100644 index 7475f83..0000000 --- a/pinaxcon/templates/symposion/speakers/speaker_create.html +++ /dev/null @@ -1,23 +0,0 @@ -{% extends "symposion/speakers/base.html" %} - -{% load bootstrap %} -{% load i18n %} -{% load pinax_boxes_tags %} - -{% block page_title %}{% trans "Create Speaker Profile" %}{% endblock %} - -{% block body %} - {% box "speaker-profile" %} - -
    - {% csrf_token %} - {% trans "Create Speaker Profile" %} -
    - {{ speaker_form|bootstrap }} -
    -
    - - Cancel -
    -
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/speakers/speaker_edit.html b/pinaxcon/templates/symposion/speakers/speaker_edit.html deleted file mode 100644 index 6fc590f..0000000 --- a/pinaxcon/templates/symposion/speakers/speaker_edit.html +++ /dev/null @@ -1,23 +0,0 @@ -{% extends "symposion/speakers/base.html" %} - -{% load bootstrap %} -{% load i18n %} -{% load pinax_boxes_tags %} - -{% block page_title %}{% trans "Edit Speaker Profile" %}{% endblock %} - -{% block body %} - {% box "speaker-profile" %} - -
    - {% csrf_token %} - {% trans "Edit Speaker Profile" %} -
    - {{ speaker_form|bootstrap }} -
    -
    - - Cancel -
    -
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/speakers/speaker_profile.html b/pinaxcon/templates/symposion/speakers/speaker_profile.html deleted file mode 100644 index 794f710..0000000 --- a/pinaxcon/templates/symposion/speakers/speaker_profile.html +++ /dev/null @@ -1,41 +0,0 @@ -{% extends "site_base.html" %} - -{% load i18n %} -{% load thumbnail %} - - -{% block head_title %}{{ speaker.name }}{% endblock %} - -{% block body %} -
    -
    - {% if speaker.photo %} - {{ speaker.name }} - {% else %} -   - {% endif %} -
    -
    - {% if speaker.user == request.user or request.user.is_staff %} - Edit - {% endif %} -

    {{ speaker.name }}

    -
    {{ speaker.biography|safe }}
    - -

    Presentations

    - {% for presentation in presentations %} -

    {{ presentation.title }}

    - {% if presentation.slot %} -

    - {{ presentation.slot.day.date|date:"l" }} - {{ presentation.slot.start}}–{{ presentation.slot.end }} - in - {{ presentation.slot.rooms|join:", " }} -

    - {% endif %} - {% empty %} -

    No presentations. This page is only visible to staff until there is a presentation.

    - {% endfor %} -

    -
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/sponsorship/_horizontal_by_level.html b/pinaxcon/templates/symposion/sponsorship/_horizontal_by_level.html deleted file mode 100644 index 3d48be1..0000000 --- a/pinaxcon/templates/symposion/sponsorship/_horizontal_by_level.html +++ /dev/null @@ -1,12 +0,0 @@ -{% load sponsorship_tags %} - -{% sponsor_levels as levels %} - - diff --git a/pinaxcon/templates/symposion/sponsorship/_sponsor_link.html b/pinaxcon/templates/symposion/sponsorship/_sponsor_link.html deleted file mode 100644 index 5c09e91..0000000 --- a/pinaxcon/templates/symposion/sponsorship/_sponsor_link.html +++ /dev/null @@ -1,11 +0,0 @@ -{% load thumbnail %} - -{% spaceless %} - - {% if dimensions %} - - {% else %} - - {% endif %} - -{% endspaceless %} diff --git a/pinaxcon/templates/symposion/sponsorship/_vertical_by_level.html b/pinaxcon/templates/symposion/sponsorship/_vertical_by_level.html deleted file mode 100644 index 78dd052..0000000 --- a/pinaxcon/templates/symposion/sponsorship/_vertical_by_level.html +++ /dev/null @@ -1,14 +0,0 @@ -{% load sponsorship_tags %} - -{% sponsor_levels as levels %} - - diff --git a/pinaxcon/templates/symposion/sponsorship/_wall.html b/pinaxcon/templates/symposion/sponsorship/_wall.html deleted file mode 100644 index 36f42b6..0000000 --- a/pinaxcon/templates/symposion/sponsorship/_wall.html +++ /dev/null @@ -1,9 +0,0 @@ -{% load sponsorship_tags %} - -{% sponsors as sponsors %} - - diff --git a/pinaxcon/templates/symposion/sponsorship/add.html b/pinaxcon/templates/symposion/sponsorship/add.html deleted file mode 100644 index 90e2b9e..0000000 --- a/pinaxcon/templates/symposion/sponsorship/add.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "site_base.html" %} - -{% load bootstrap %} -{% load i18n %} -{% load pinax_boxes_tags %} - -{% block head_title %}{% trans "Add a Sponsor" %}{% endblock %} - -{% block body_class %}sponsorships{% endblock %} - -{% block body %} -
    - {% csrf_token %} - {% trans "Add a Sponsor" %} - {{ form|bootstrap_horizontal }} -
    - - Cancel -
    -
    - -{% endblock %} diff --git a/pinaxcon/templates/symposion/sponsorship/apply.html b/pinaxcon/templates/symposion/sponsorship/apply.html deleted file mode 100644 index f717fb9..0000000 --- a/pinaxcon/templates/symposion/sponsorship/apply.html +++ /dev/null @@ -1,28 +0,0 @@ -{% extends "site_base.html" %} - -{% load bootstrap %} -{% load i18n %} -{% load pinax_boxes_tags %} - -{% block head_title %}{% trans "Apply to be a Sponsor" %}{% endblock %} - -{% block body_class %}sponsorships{% endblock %} - -{% block body %} - - {% box "sponsorship-apply" %} - -
    - {% csrf_token %} - {% trans "Apply to Be a Sponsor" %} - {{ form|bootstrap_horizontal }} -
    - - Cancel -

    - By submitting this sponsor application you are agreeing to the terms and conditions. -

    -
    -
    - -{% endblock %} diff --git a/pinaxcon/templates/symposion/sponsorship/detail.html b/pinaxcon/templates/symposion/sponsorship/detail.html deleted file mode 100644 index da19741..0000000 --- a/pinaxcon/templates/symposion/sponsorship/detail.html +++ /dev/null @@ -1,40 +0,0 @@ -{% extends "site_base.html" %} - -{% load bootstrap %} -{% load i18n %} - -{% block head_title %}{{ sponsor }}{% endblock %} - -{% block page_title %}{% trans "Sponsorship" %}{% endblock %} - -{% block body %} -

    {{ sponsor.name }} ({{ sponsor.level }})

    - -
    - {% csrf_token %} -
    - {{ form|bootstrap_horizontal }} -
    - -

    {{ sponsor.level }} Sponsor Benefits

    - - {{ formset.management_form }} - {{ formset.non_form_errors }} - - {% for form in formset.forms %} -
    - -
    - {{ form }} -

    {{ form.instance.benefit.description }}

    -
    -
    - {% endfor %} - -
    - - Cancel -
    - -
    -{% endblock %} diff --git a/pinaxcon/templates/symposion/sponsorship/list.html b/pinaxcon/templates/symposion/sponsorship/list.html deleted file mode 100644 index 9d23ae9..0000000 --- a/pinaxcon/templates/symposion/sponsorship/list.html +++ /dev/null @@ -1,40 +0,0 @@ -{% extends "site_base.html" %} - -{% load sponsorship_tags %} -{% load thumbnail %} -{% load i18n %} - -{% block head_title %}{% trans "About Our Sponsors" %}{% endblock %} - -{% block body_class %}sponsorships{% endblock %} - -{% block body_outer %} -

    {% trans "About Our Sponsors" %}

    - Learn how to become a sponsor - - {% sponsor_levels as levels %} - {% for level in levels %} - {% if level.sponsors %} -

    {{ level.name }}

    - - {% for sponsor in level.sponsors %} - {% if sponsor.website_logo %} -
    -
    -

    - - {{ sponsor.name }} - -

    -
    -
    -
    {{ sponsor.name }}
    -

    {{ sponsor.external_url }}

    -

    {{ sponsor.listing_text|urlize|linebreaks }}

    -
    -
    - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} -{% endblock %} diff --git a/pinaxcon/templates/symposion/teams/team_detail.html b/pinaxcon/templates/symposion/teams/team_detail.html deleted file mode 100644 index 495535e..0000000 --- a/pinaxcon/templates/symposion/teams/team_detail.html +++ /dev/null @@ -1,99 +0,0 @@ -{% extends "site_base.html" %} - -{% load bootstrap %} - -{% block head_title %}{{ team.name }}{% endblock %} - -{% block body_outer %} -
    - {% if can_join %} -
    - {% csrf_token %} - -
    - {% endif %} - - {% if can_leave %} -
    - {% csrf_token %} - -
    - {% endif %} - - {% if can_apply %} -
    - {% csrf_token %} - -
    - {% endif %} -
    - -

    {{ team.name }}{% if state %} {{ state }}{% endif %}

    - - {% if team.description %}

    {{ team.description }}

    {% endif %} - - {% if state == "invited" %}

    You have been invited to join this team. Click join to the right to accept.

    {% endif %} - - {% if user.is_staff or state == "manager" %} - {% if team.managers %} -

    Managers

    - - {% for membership in team.managers %} - - - - - {% endfor %} -
    {{ membership.user.email }}{% if user == membership.user %} you{% endif %} -
    {% csrf_token %}
    -
    - {% endif %} - {% if team.members %} -

    Team Members

    - - {% for membership in team.members %} - - - - - {% endfor %} -
    {{ membership.user.email }}{% if user == membership.user %} you{% endif %} -
    {% csrf_token %}
    -
    - {% endif %} - {% if team.applicants and team.access == "application" %} -

    Applicants

    - - {% for membership in team.applicants %} - - - - - {% endfor %} -
    {{ membership.user.email }} -
    {% csrf_token %}
    -
    {% csrf_token %}
    -
    - {% endif %} - {% if team.invitees %} -

    Invitees

    - - {% for membership in team.invitees %} - - - - {% endfor %} -
    {{ membership.user.email }}
    - {% endif %} - {% if invite_form %} -
    - {% csrf_token %} - Invite User to Team - {{ invite_form|bootstrap_horizontal }} -
    - -
    -
    - {% endif %} - {% endif %} -{% endblock %} diff --git a/pinaxcon/urls.py b/pinaxcon/urls.py index 0c2901e..5f09a25 100644 --- a/pinaxcon/urls.py +++ b/pinaxcon/urls.py @@ -10,6 +10,15 @@ import symposion.views urlpatterns = [ url(r"^$", TemplateView.as_view(template_name="homepage.html"), name="home"), + + url(r"^about$", TemplateView.as_view(template_name="pages/about.html"), name="page_about"), + url(r"^venue$", TemplateView.as_view(template_name="pages/venue.html"), name="page_venue"), + url( + r"^sponsors/info$", + TemplateView.as_view(template_name="pages/sponsors/info.html"), + name="page_sponsor_info", + ), + url(r"^admin/", include(admin.site.urls)), url(r"^account/", include("account.urls")), diff --git a/requirements.txt b/requirements.txt index 5e93507..ddc61b9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ dj-static==0.0.6 dj-database-url==0.4.0 pinax-pages==0.4.2 pinax-boxes==2.1.2 +django-libsass==0.7 # For testing django-nose==1.4.3 @@ -16,3 +17,4 @@ coverage==4.0.3 https://github.com/chrisjrn/registrasion/tarball/master#egg=registrasion https://github.com/pinax/symposion/tarball/ad81810#egg=symposion https://github.com/chrisjrn/registrasion-stripe/tarball/master#egg=registrasion-stripe +https://github.com/chrisjrn/symposion-bootstrap-templates/tarball/master#egg=symposion-bootstrap-templates diff --git a/static/STATIC_README.md b/static/STATIC_README.md deleted file mode 100644 index 1575caf..0000000 --- a/static/STATIC_README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Static Media - -We are using `gulp` and `npm` for our static build process. - -Do NOT edit anything in the `dist/` directory. - -Local development uses media from `dist/` and we are firm believers in building -static assets and committing them to the repo before deployments. This way we -always are testing and exercise exactly what will be served in production. It -also makes our deployment simpler. diff --git a/static/dist/fonts/glyphicons-halflings-regular.eot b/static/bootstrap/fonts/bootstrap/glyphicons-halflings-regular.eot similarity index 100% rename from static/dist/fonts/glyphicons-halflings-regular.eot rename to static/bootstrap/fonts/bootstrap/glyphicons-halflings-regular.eot diff --git a/static/dist/fonts/glyphicons-halflings-regular.svg b/static/bootstrap/fonts/bootstrap/glyphicons-halflings-regular.svg similarity index 100% rename from static/dist/fonts/glyphicons-halflings-regular.svg rename to static/bootstrap/fonts/bootstrap/glyphicons-halflings-regular.svg diff --git a/static/dist/fonts/glyphicons-halflings-regular.ttf b/static/bootstrap/fonts/bootstrap/glyphicons-halflings-regular.ttf similarity index 100% rename from static/dist/fonts/glyphicons-halflings-regular.ttf rename to static/bootstrap/fonts/bootstrap/glyphicons-halflings-regular.ttf diff --git a/static/dist/fonts/glyphicons-halflings-regular.woff b/static/bootstrap/fonts/bootstrap/glyphicons-halflings-regular.woff similarity index 100% rename from static/dist/fonts/glyphicons-halflings-regular.woff rename to static/bootstrap/fonts/bootstrap/glyphicons-halflings-regular.woff diff --git a/static/dist/fonts/glyphicons-halflings-regular.woff2 b/static/bootstrap/fonts/bootstrap/glyphicons-halflings-regular.woff2 similarity index 100% rename from static/dist/fonts/glyphicons-halflings-regular.woff2 rename to static/bootstrap/fonts/bootstrap/glyphicons-halflings-regular.woff2 diff --git a/static/bootstrap/images/.keep b/static/bootstrap/images/.keep new file mode 100644 index 0000000..e69de29 diff --git a/static/bootstrap/javascripts/bootstrap-sprockets.js b/static/bootstrap/javascripts/bootstrap-sprockets.js new file mode 100644 index 0000000..fb01d63 --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap-sprockets.js @@ -0,0 +1,12 @@ +//= require ./bootstrap/transition +//= require ./bootstrap/alert +//= require ./bootstrap/button +//= require ./bootstrap/carousel +//= require ./bootstrap/collapse +//= require ./bootstrap/dropdown +//= require ./bootstrap/modal +//= require ./bootstrap/tab +//= require ./bootstrap/affix +//= require ./bootstrap/scrollspy +//= require ./bootstrap/tooltip +//= require ./bootstrap/popover diff --git a/static/bootstrap/javascripts/bootstrap.js b/static/bootstrap/javascripts/bootstrap.js new file mode 100644 index 0000000..8a2e99a --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap.js @@ -0,0 +1,2377 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under the MIT license + */ + +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') +} + ++function ($) { + 'use strict'; + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4') + } +}(jQuery); + +/* ======================================================================== + * Bootstrap: transition.js v3.3.7 + * http://getbootstrap.com/javascript/#transitions + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + + return false // explicit for ie8 ( ._.) + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + + if (!$.support.transition) return + + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) + } + } + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: alert.js v3.3.7 + * http://getbootstrap.com/javascript/#alerts + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.3.7' + + Alert.TRANSITION_DURATION = 150 + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = $(selector === '#' ? [] : selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.closest('.alert') + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(Alert.TRANSITION_DURATION) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: button.js v3.3.7 + * http://getbootstrap.com/javascript/#buttons + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.3.7' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state += 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + $el[val](data[state] == null ? this.options[state] : data[state]) + + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d).prop(d, true) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d).prop(d, false) + } + }, this), 0) + } + + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + if ($input.prop('checked')) changed = false + $parent.find('.active').removeClass('active') + this.$element.addClass('active') + } else if ($input.prop('type') == 'checkbox') { + if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false + this.$element.toggleClass('active') + } + $input.prop('checked', this.$element.hasClass('active')) + if (changed) $input.trigger('change') + } else { + this.$element.attr('aria-pressed', !this.$element.hasClass('active')) + this.$element.toggleClass('active') + } + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + var old = $.fn.button + + $.fn.button = Plugin + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target).closest('.btn') + Plugin.call($btn, 'toggle') + if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { + // Prevent double click on radios, and the double selections (so cancellation) on checkboxes + e.preventDefault() + // The target component still receive the focus + if ($btn.is('input,button')) $btn.trigger('focus') + else $btn.find('input:visible,button:visible').first().trigger('focus') + } + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { + $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: carousel.js v3.3.7 + * http://getbootstrap.com/javascript/#carousel + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = null + this.sliding = null + this.interval = null + this.$active = null + this.$items = null + + this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) + + this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + } + + Carousel.VERSION = '3.3.7' + + Carousel.TRANSITION_DURATION = 600 + + Carousel.DEFAULTS = { + interval: 5000, + pause: 'hover', + wrap: true, + keyboard: true + } + + Carousel.prototype.keydown = function (e) { + if (/input|textarea/i.test(e.target.tagName)) return + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return + } + + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.getItemForDirection = function (direction, active) { + var activeIndex = this.getItemIndex(active) + var willWrap = (direction == 'prev' && activeIndex === 0) + || (direction == 'next' && activeIndex == (this.$items.length - 1)) + if (willWrap && !this.options.wrap) return active + var delta = direction == 'prev' ? -1 : 1 + var itemIndex = (activeIndex + delta) % this.$items.length + return this.$items.eq(itemIndex) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || this.getItemForDirection(type, $active) + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var that = this + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd(Carousel.TRANSITION_DURATION) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + var clickHandler = function (e) { + var href + var $this = $(this) + var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + if (!$target.hasClass('carousel')) return + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + Plugin.call($target, options) + + if (slideIndex) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + } + + $(document) + .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) + .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: collapse.js v3.3.7 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + +/* jshint latedef: false */ + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + + '[data-toggle="collapse"][data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.3.7' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + + Plugin.call($target, option) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: dropdown.js v3.3.7 + * http://getbootstrap.com/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.3.7' + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = selector && $(selector) + + return $parent && $parent.length ? $parent : $this.parent() + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) + }) + } + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $(document.createElement('div')) + .addClass('dropdown-backdrop') + .insertAfter($(this)) + .on('click', clearMenus) + } + + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger($.Event('shown.bs.dropdown', relatedTarget)) + } + + return false + } + + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return + + var $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + if (!isActive && e.which != 27 || isActive && e.which == 27) { + if (e.which == 27) $parent.find(toggle).trigger('focus') + return $this.trigger('click') + } + + var desc = ' li:not(.disabled):visible a' + var $items = $parent.find('.dropdown-menu' + desc) + + if (!$items.length) return + + var index = $items.index(e.target) + + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items.eq(index).trigger('focus') + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) + .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: modal.js v3.3.7 + * http://getbootstrap.com/javascript/#modals + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$dialog = this.$element.find('.modal-dialog') + this.$backdrop = null + this.isShown = null + this.originalBodyPad = null + this.scrollbarWidth = 0 + this.ignoreBackdropClick = false + + if (this.options.remote) { + this.$element + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.3.7' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { + backdrop: true, + keyboard: true, + show: true + } + + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } + + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') + + this.escape() + this.resize() + + this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + + this.$dialog.on('mousedown.dismiss.bs.modal', function () { + that.$element.one('mouseup.dismiss.bs.modal', function (e) { + if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true + }) + }) + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position + } + + that.$element + .show() + .scrollTop(0) + + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$dialog // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .off('click.dismiss.bs.modal') + .off('mouseup.dismiss.bs.modal') + + this.$dialog.off('mousedown.dismiss.bs.modal') + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (document !== e.target && + this.$element[0] !== e.target && + !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $(document.createElement('div')) + .addClass('modal-backdrop ' + animate) + .appendTo(this.$body) + + this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { + if (this.ignoreBackdropClick) { + this.ignoreBackdropClick = false + return + } + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus() + : this.hide() + }, this)) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + this.adjustDialog() + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + var fullWindowWidth = window.innerWidth + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 + var documentElementRect = document.documentElement.getBoundingClientRect() + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) + } + this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth + this.scrollbarWidth = this.measureScrollbar() + } + + Modal.prototype.setScrollbar = function () { + var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) + this.originalBodyPad = document.body.style.paddingRight || '' + if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + } + + Modal.prototype.resetScrollbar = function () { + this.$body.css('padding-right', this.originalBodyPad) + } + + Modal.prototype.measureScrollbar = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } + + + // MODAL PLUGIN DEFINITION + // ======================= + + function Plugin(option, _relatedTarget) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.modal') + var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + var href = $this.attr('href') + var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + + if ($this.is('a')) e.preventDefault() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tooltip.js v3.3.7 + * http://getbootstrap.com/javascript/#tooltip + * Inspired by the original jQuery.tipsy by Jason Frame + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TOOLTIP PUBLIC CLASS DEFINITION + // =============================== + + var Tooltip = function (element, options) { + this.type = null + this.options = null + this.enabled = null + this.timeout = null + this.hoverState = null + this.$element = null + this.inState = null + + this.init('tooltip', element, options) + } + + Tooltip.VERSION = '3.3.7' + + Tooltip.TRANSITION_DURATION = 150 + + Tooltip.DEFAULTS = { + animation: true, + placement: 'top', + selector: false, + template: '', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + container: false, + viewport: { + selector: 'body', + padding: 0 + } + } + + Tooltip.prototype.init = function (type, element, options) { + this.enabled = true + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) + this.inState = { click: false, hover: false, focus: false } + + if (this.$element[0] instanceof document.constructor && !this.options.selector) { + throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') + } + + var triggers = this.options.trigger.split(' ') + + for (var i = triggers.length; i--;) { + var trigger = triggers[i] + + if (trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (trigger != 'manual') { + var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' + var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' + + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + } + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + Tooltip.prototype.getDefaults = function () { + return Tooltip.DEFAULTS + } + + Tooltip.prototype.getOptions = function (options) { + options = $.extend({}, this.getDefaults(), this.$element.data(), options) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay, + hide: options.delay + } + } + + return options + } + + Tooltip.prototype.getDelegateOptions = function () { + var options = {} + var defaults = this.getDefaults() + + this._options && $.each(this._options, function (key, value) { + if (defaults[key] != value) options[key] = value + }) + + return options + } + + Tooltip.prototype.enter = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true + } + + if (self.tip().hasClass('in') || self.hoverState == 'in') { + self.hoverState = 'in' + return + } + + clearTimeout(self.timeout) + + self.hoverState = 'in' + + if (!self.options.delay || !self.options.delay.show) return self.show() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + Tooltip.prototype.isInStateTrue = function () { + for (var key in this.inState) { + if (this.inState[key]) return true + } + + return false + } + + Tooltip.prototype.leave = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false + } + + if (self.isInStateTrue()) return + + clearTimeout(self.timeout) + + self.hoverState = 'out' + + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + Tooltip.prototype.show = function () { + var e = $.Event('show.bs.' + this.type) + + if (this.hasContent() && this.enabled) { + this.$element.trigger(e) + + var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) + if (e.isDefaultPrevented() || !inDom) return + var that = this + + var $tip = this.tip() + + var tipId = this.getUID(this.type) + + this.setContent() + $tip.attr('id', tipId) + this.$element.attr('aria-describedby', tipId) + + if (this.options.animation) $tip.addClass('fade') + + var placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + var autoToken = /\s?auto?\s?/i + var autoPlace = autoToken.test(placement) + if (autoPlace) placement = placement.replace(autoToken, '') || 'top' + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + .addClass(placement) + .data('bs.' + this.type, this) + + this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) + this.$element.trigger('inserted.bs.' + this.type) + + var pos = this.getPosition() + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (autoPlace) { + var orgPlacement = placement + var viewportDim = this.getPosition(this.$viewport) + + placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : + placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : + placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : + placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : + placement + + $tip + .removeClass(orgPlacement) + .addClass(placement) + } + + var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) + + this.applyPlacement(calculatedOffset, placement) + + var complete = function () { + var prevHoverState = that.hoverState + that.$element.trigger('shown.bs.' + that.type) + that.hoverState = null + + if (prevHoverState == 'out') that.leave(that) + } + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + } + } + + Tooltip.prototype.applyPlacement = function (offset, placement) { + var $tip = this.tip() + var width = $tip[0].offsetWidth + var height = $tip[0].offsetHeight + + // manually read margins because getBoundingClientRect includes difference + var marginTop = parseInt($tip.css('margin-top'), 10) + var marginLeft = parseInt($tip.css('margin-left'), 10) + + // we must check for NaN for ie 8/9 + if (isNaN(marginTop)) marginTop = 0 + if (isNaN(marginLeft)) marginLeft = 0 + + offset.top += marginTop + offset.left += marginLeft + + // $.fn.offset doesn't round pixel values + // so we use setOffset directly with our own function B-0 + $.offset.setOffset($tip[0], $.extend({ + using: function (props) { + $tip.css({ + top: Math.round(props.top), + left: Math.round(props.left) + }) + } + }, offset), 0) + + $tip.addClass('in') + + // check to see if placing tip in new offset caused the tip to resize itself + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (placement == 'top' && actualHeight != height) { + offset.top = offset.top + height - actualHeight + } + + var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) + + if (delta.left) offset.left += delta.left + else offset.top += delta.top + + var isVertical = /top|bottom/.test(placement) + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' + + $tip.offset(offset) + this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) + } + + Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { + this.arrow() + .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') + .css(isVertical ? 'top' : 'left', '') + } + + Tooltip.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + + $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + $tip.removeClass('fade in top bottom left right') + } + + Tooltip.prototype.hide = function (callback) { + var that = this + var $tip = $(this.$tip) + var e = $.Event('hide.bs.' + this.type) + + function complete() { + if (that.hoverState != 'in') $tip.detach() + if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. + that.$element + .removeAttr('aria-describedby') + .trigger('hidden.bs.' + that.type) + } + callback && callback() + } + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + $tip.removeClass('in') + + $.support.transition && $tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + + this.hoverState = null + + return this + } + + Tooltip.prototype.fixTitle = function () { + var $e = this.$element + if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') + } + } + + Tooltip.prototype.hasContent = function () { + return this.getTitle() + } + + Tooltip.prototype.getPosition = function ($element) { + $element = $element || this.$element + + var el = $element[0] + var isBody = el.tagName == 'BODY' + + var elRect = el.getBoundingClientRect() + if (elRect.width == null) { + // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 + elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) + } + var isSvg = window.SVGElement && el instanceof window.SVGElement + // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. + // See https://github.com/twbs/bootstrap/issues/20280 + var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) + var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } + var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null + + return $.extend({}, elRect, scroll, outerDims, elOffset) + } + + Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { + return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : + /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } + + } + + Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { + var delta = { top: 0, left: 0 } + if (!this.$viewport) return delta + + var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 + var viewportDimensions = this.getPosition(this.$viewport) + + if (/right|left/.test(placement)) { + var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll + var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight + if (topEdgeOffset < viewportDimensions.top) { // top overflow + delta.top = viewportDimensions.top - topEdgeOffset + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset + } + } else { + var leftEdgeOffset = pos.left - viewportPadding + var rightEdgeOffset = pos.left + viewportPadding + actualWidth + if (leftEdgeOffset < viewportDimensions.left) { // left overflow + delta.left = viewportDimensions.left - leftEdgeOffset + } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset + } + } + + return delta + } + + Tooltip.prototype.getTitle = function () { + var title + var $e = this.$element + var o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + Tooltip.prototype.getUID = function (prefix) { + do prefix += ~~(Math.random() * 1000000) + while (document.getElementById(prefix)) + return prefix + } + + Tooltip.prototype.tip = function () { + if (!this.$tip) { + this.$tip = $(this.options.template) + if (this.$tip.length != 1) { + throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') + } + } + return this.$tip + } + + Tooltip.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) + } + + Tooltip.prototype.enable = function () { + this.enabled = true + } + + Tooltip.prototype.disable = function () { + this.enabled = false + } + + Tooltip.prototype.toggleEnabled = function () { + this.enabled = !this.enabled + } + + Tooltip.prototype.toggle = function (e) { + var self = this + if (e) { + self = $(e.currentTarget).data('bs.' + this.type) + if (!self) { + self = new this.constructor(e.currentTarget, this.getDelegateOptions()) + $(e.currentTarget).data('bs.' + this.type, self) + } + } + + if (e) { + self.inState.click = !self.inState.click + if (self.isInStateTrue()) self.enter(self) + else self.leave(self) + } else { + self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + } + } + + Tooltip.prototype.destroy = function () { + var that = this + clearTimeout(this.timeout) + this.hide(function () { + that.$element.off('.' + that.type).removeData('bs.' + that.type) + if (that.$tip) { + that.$tip.detach() + } + that.$tip = null + that.$arrow = null + that.$viewport = null + that.$element = null + }) + } + + + // TOOLTIP PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tooltip') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tooltip + + $.fn.tooltip = Plugin + $.fn.tooltip.Constructor = Tooltip + + + // TOOLTIP NO CONFLICT + // =================== + + $.fn.tooltip.noConflict = function () { + $.fn.tooltip = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: popover.js v3.3.7 + * http://getbootstrap.com/javascript/#popovers + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // POPOVER PUBLIC CLASS DEFINITION + // =============================== + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') + + Popover.VERSION = '3.3.7' + + Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { + placement: 'right', + trigger: 'click', + content: '', + template: '' + }) + + + // NOTE: POPOVER EXTENDS tooltip.js + // ================================ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) + + Popover.prototype.constructor = Popover + + Popover.prototype.getDefaults = function () { + return Popover.DEFAULTS + } + + Popover.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + var content = this.getContent() + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) + $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events + this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' + ](content) + + $tip.removeClass('fade top bottom left right in') + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() + } + + Popover.prototype.hasContent = function () { + return this.getTitle() || this.getContent() + } + + Popover.prototype.getContent = function () { + var $e = this.$element + var o = this.options + + return $e.attr('data-content') + || (typeof o.content == 'function' ? + o.content.call($e[0]) : + o.content) + } + + Popover.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.arrow')) + } + + + // POPOVER PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.popover') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.popover + + $.fn.popover = Plugin + $.fn.popover.Constructor = Popover + + + // POPOVER NO CONFLICT + // =================== + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: scrollspy.js v3.3.7 + * http://getbootstrap.com/javascript/#scrollspy + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // SCROLLSPY CLASS DEFINITION + // ========================== + + function ScrollSpy(element, options) { + this.$body = $(document.body) + this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) + this.options = $.extend({}, ScrollSpy.DEFAULTS, options) + this.selector = (this.options.target || '') + ' .nav li > a' + this.offsets = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 + + this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) + this.refresh() + this.process() + } + + ScrollSpy.VERSION = '3.3.7' + + ScrollSpy.DEFAULTS = { + offset: 10 + } + + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } + + ScrollSpy.prototype.refresh = function () { + var that = this + var offsetMethod = 'offset' + var offsetBase = 0 + + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() + + if (!$.isWindow(this.$scrollElement[0])) { + offsetMethod = 'position' + offsetBase = this.$scrollElement.scrollTop() + } + + this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + that.offsets.push(this[0]) + that.targets.push(this[1]) + }) + } + + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } + + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) + && this.activate(targets[i]) + } + } + + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target + + this.clear() + + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + var active = $(selector) + .parents('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } + + active.trigger('activate.bs.scrollspy') + } + + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') + } + + + // SCROLLSPY PLUGIN DEFINITION + // =========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.scrollspy + + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy + + + // SCROLLSPY NO CONFLICT + // ===================== + + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } + + + // SCROLLSPY DATA-API + // ================== + + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tab.js v3.3.7 + * http://getbootstrap.com/javascript/#tabs + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TAB CLASS DEFINITION + // ==================== + + var Tab = function (element) { + // jscs:disable requireDollarBeforejQueryAssignment + this.element = $(element) + // jscs:enable requireDollarBeforejQueryAssignment + } + + Tab.VERSION = '3.3.7' + + Tab.TRANSITION_DURATION = 150 + + Tab.prototype.show = function () { + var $this = this.element + var $ul = $this.closest('ul:not(.dropdown-menu)') + var selector = $this.data('target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + if ($this.parent('li').hasClass('active')) return + + var $previous = $ul.find('.active:last a') + var hideEvent = $.Event('hide.bs.tab', { + relatedTarget: $this[0] + }) + var showEvent = $.Event('show.bs.tab', { + relatedTarget: $previous[0] + }) + + $previous.trigger(hideEvent) + $this.trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + var $target = $(selector) + + this.activate($this.closest('li'), $ul) + this.activate($target, $target.parent(), function () { + $previous.trigger({ + type: 'hidden.bs.tab', + relatedTarget: $this[0] + }) + $this.trigger({ + type: 'shown.bs.tab', + relatedTarget: $previous[0] + }) + }) + } + + Tab.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active') + var transition = callback + && $.support.transition + && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', false) + + element + .addClass('active') + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if (element.parent('.dropdown-menu').length) { + element + .closest('li.dropdown') + .addClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + } + + callback && callback() + } + + $active.length && transition ? + $active + .one('bsTransitionEnd', next) + .emulateTransitionEnd(Tab.TRANSITION_DURATION) : + next() + + $active.removeClass('in') + } + + + // TAB PLUGIN DEFINITION + // ===================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tab') + + if (!data) $this.data('bs.tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tab + + $.fn.tab = Plugin + $.fn.tab.Constructor = Tab + + + // TAB NO CONFLICT + // =============== + + $.fn.tab.noConflict = function () { + $.fn.tab = old + return this + } + + + // TAB DATA-API + // ============ + + var clickHandler = function (e) { + e.preventDefault() + Plugin.call($(this), 'show') + } + + $(document) + .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) + .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: affix.js v3.3.7 + * http://getbootstrap.com/javascript/#affix + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // AFFIX CLASS DEFINITION + // ====================== + + var Affix = function (element, options) { + this.options = $.extend({}, Affix.DEFAULTS, options) + + this.$target = $(this.options.target) + .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) + + this.$element = $(element) + this.affixed = null + this.unpin = null + this.pinnedOffset = null + + this.checkPosition() + } + + Affix.VERSION = '3.3.7' + + Affix.RESET = 'affix affix-top affix-bottom' + + Affix.DEFAULTS = { + offset: 0, + target: window + } + + Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + var targetHeight = this.$target.height() + + if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false + + if (this.affixed == 'bottom') { + if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' + return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' + } + + var initializing = this.affixed == null + var colliderTop = initializing ? scrollTop : position.top + var colliderHeight = initializing ? targetHeight : height + + if (offsetTop != null && scrollTop <= offsetTop) return 'top' + if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' + + return false + } + + Affix.prototype.getPinnedOffset = function () { + if (this.pinnedOffset) return this.pinnedOffset + this.$element.removeClass(Affix.RESET).addClass('affix') + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + return (this.pinnedOffset = position.top - scrollTop) + } + + Affix.prototype.checkPositionWithEventLoop = function () { + setTimeout($.proxy(this.checkPosition, this), 1) + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var height = this.$element.height() + var offset = this.options.offset + var offsetTop = offset.top + var offsetBottom = offset.bottom + var scrollHeight = Math.max($(document).height(), $(document.body).height()) + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + + var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) + + if (this.affixed != affix) { + if (this.unpin != null) this.$element.css('top', '') + + var affixType = 'affix' + (affix ? '-' + affix : '') + var e = $.Event(affixType + '.bs.affix') + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null + + this.$element + .removeClass(Affix.RESET) + .addClass(affixType) + .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') + } + + if (affix == 'bottom') { + this.$element.offset({ + top: scrollHeight - height - offsetBottom + }) + } + } + + + // AFFIX PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.affix') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.affix + + $.fn.affix = Plugin + $.fn.affix.Constructor = Affix + + + // AFFIX NO CONFLICT + // ================= + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + // AFFIX DATA-API + // ============== + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + var data = $spy.data() + + data.offset = data.offset || {} + + if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom + if (data.offsetTop != null) data.offset.top = data.offsetTop + + Plugin.call($spy, data) + }) + }) + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap.min.js b/static/bootstrap/javascripts/bootstrap.min.js new file mode 100644 index 0000000..9bcd2fc --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/static/bootstrap/javascripts/bootstrap/affix.js b/static/bootstrap/javascripts/bootstrap/affix.js new file mode 100644 index 0000000..7f65168 --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/affix.js @@ -0,0 +1,162 @@ +/* ======================================================================== + * Bootstrap: affix.js v3.3.7 + * http://getbootstrap.com/javascript/#affix + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // AFFIX CLASS DEFINITION + // ====================== + + var Affix = function (element, options) { + this.options = $.extend({}, Affix.DEFAULTS, options) + + this.$target = $(this.options.target) + .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) + + this.$element = $(element) + this.affixed = null + this.unpin = null + this.pinnedOffset = null + + this.checkPosition() + } + + Affix.VERSION = '3.3.7' + + Affix.RESET = 'affix affix-top affix-bottom' + + Affix.DEFAULTS = { + offset: 0, + target: window + } + + Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + var targetHeight = this.$target.height() + + if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false + + if (this.affixed == 'bottom') { + if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' + return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' + } + + var initializing = this.affixed == null + var colliderTop = initializing ? scrollTop : position.top + var colliderHeight = initializing ? targetHeight : height + + if (offsetTop != null && scrollTop <= offsetTop) return 'top' + if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' + + return false + } + + Affix.prototype.getPinnedOffset = function () { + if (this.pinnedOffset) return this.pinnedOffset + this.$element.removeClass(Affix.RESET).addClass('affix') + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + return (this.pinnedOffset = position.top - scrollTop) + } + + Affix.prototype.checkPositionWithEventLoop = function () { + setTimeout($.proxy(this.checkPosition, this), 1) + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var height = this.$element.height() + var offset = this.options.offset + var offsetTop = offset.top + var offsetBottom = offset.bottom + var scrollHeight = Math.max($(document).height(), $(document.body).height()) + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + + var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) + + if (this.affixed != affix) { + if (this.unpin != null) this.$element.css('top', '') + + var affixType = 'affix' + (affix ? '-' + affix : '') + var e = $.Event(affixType + '.bs.affix') + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null + + this.$element + .removeClass(Affix.RESET) + .addClass(affixType) + .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') + } + + if (affix == 'bottom') { + this.$element.offset({ + top: scrollHeight - height - offsetBottom + }) + } + } + + + // AFFIX PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.affix') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.affix + + $.fn.affix = Plugin + $.fn.affix.Constructor = Affix + + + // AFFIX NO CONFLICT + // ================= + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + // AFFIX DATA-API + // ============== + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + var data = $spy.data() + + data.offset = data.offset || {} + + if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom + if (data.offsetTop != null) data.offset.top = data.offsetTop + + Plugin.call($spy, data) + }) + }) + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap/alert.js b/static/bootstrap/javascripts/bootstrap/alert.js new file mode 100644 index 0000000..db97f3b --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/alert.js @@ -0,0 +1,94 @@ +/* ======================================================================== + * Bootstrap: alert.js v3.3.7 + * http://getbootstrap.com/javascript/#alerts + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.3.7' + + Alert.TRANSITION_DURATION = 150 + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = $(selector === '#' ? [] : selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.closest('.alert') + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(Alert.TRANSITION_DURATION) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap/button.js b/static/bootstrap/javascripts/bootstrap/button.js new file mode 100644 index 0000000..843b39c --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/button.js @@ -0,0 +1,125 @@ +/* ======================================================================== + * Bootstrap: button.js v3.3.7 + * http://getbootstrap.com/javascript/#buttons + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.3.7' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state += 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + $el[val](data[state] == null ? this.options[state] : data[state]) + + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d).prop(d, true) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d).prop(d, false) + } + }, this), 0) + } + + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + if ($input.prop('checked')) changed = false + $parent.find('.active').removeClass('active') + this.$element.addClass('active') + } else if ($input.prop('type') == 'checkbox') { + if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false + this.$element.toggleClass('active') + } + $input.prop('checked', this.$element.hasClass('active')) + if (changed) $input.trigger('change') + } else { + this.$element.attr('aria-pressed', !this.$element.hasClass('active')) + this.$element.toggleClass('active') + } + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + var old = $.fn.button + + $.fn.button = Plugin + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target).closest('.btn') + Plugin.call($btn, 'toggle') + if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { + // Prevent double click on radios, and the double selections (so cancellation) on checkboxes + e.preventDefault() + // The target component still receive the focus + if ($btn.is('input,button')) $btn.trigger('focus') + else $btn.find('input:visible,button:visible').first().trigger('focus') + } + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { + $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) + }) + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap/carousel.js b/static/bootstrap/javascripts/bootstrap/carousel.js new file mode 100644 index 0000000..6ff954c --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/carousel.js @@ -0,0 +1,237 @@ +/* ======================================================================== + * Bootstrap: carousel.js v3.3.7 + * http://getbootstrap.com/javascript/#carousel + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = null + this.sliding = null + this.interval = null + this.$active = null + this.$items = null + + this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) + + this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + } + + Carousel.VERSION = '3.3.7' + + Carousel.TRANSITION_DURATION = 600 + + Carousel.DEFAULTS = { + interval: 5000, + pause: 'hover', + wrap: true, + keyboard: true + } + + Carousel.prototype.keydown = function (e) { + if (/input|textarea/i.test(e.target.tagName)) return + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return + } + + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.getItemForDirection = function (direction, active) { + var activeIndex = this.getItemIndex(active) + var willWrap = (direction == 'prev' && activeIndex === 0) + || (direction == 'next' && activeIndex == (this.$items.length - 1)) + if (willWrap && !this.options.wrap) return active + var delta = direction == 'prev' ? -1 : 1 + var itemIndex = (activeIndex + delta) % this.$items.length + return this.$items.eq(itemIndex) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || this.getItemForDirection(type, $active) + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var that = this + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd(Carousel.TRANSITION_DURATION) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + var clickHandler = function (e) { + var href + var $this = $(this) + var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + if (!$target.hasClass('carousel')) return + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + Plugin.call($target, options) + + if (slideIndex) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + } + + $(document) + .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) + .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap/collapse.js b/static/bootstrap/javascripts/bootstrap/collapse.js new file mode 100644 index 0000000..1203869 --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/collapse.js @@ -0,0 +1,212 @@ +/* ======================================================================== + * Bootstrap: collapse.js v3.3.7 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + +/* jshint latedef: false */ + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + + '[data-toggle="collapse"][data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.3.7' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + + Plugin.call($target, option) + }) + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap/dropdown.js b/static/bootstrap/javascripts/bootstrap/dropdown.js new file mode 100644 index 0000000..04e9c2d --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/dropdown.js @@ -0,0 +1,165 @@ +/* ======================================================================== + * Bootstrap: dropdown.js v3.3.7 + * http://getbootstrap.com/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.3.7' + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = selector && $(selector) + + return $parent && $parent.length ? $parent : $this.parent() + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) + }) + } + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $(document.createElement('div')) + .addClass('dropdown-backdrop') + .insertAfter($(this)) + .on('click', clearMenus) + } + + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger($.Event('shown.bs.dropdown', relatedTarget)) + } + + return false + } + + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return + + var $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + if (!isActive && e.which != 27 || isActive && e.which == 27) { + if (e.which == 27) $parent.find(toggle).trigger('focus') + return $this.trigger('click') + } + + var desc = ' li:not(.disabled):visible a' + var $items = $parent.find('.dropdown-menu' + desc) + + if (!$items.length) return + + var index = $items.index(e.target) + + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items.eq(index).trigger('focus') + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) + .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap/modal.js b/static/bootstrap/javascripts/bootstrap/modal.js new file mode 100644 index 0000000..f84142d --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/modal.js @@ -0,0 +1,339 @@ +/* ======================================================================== + * Bootstrap: modal.js v3.3.7 + * http://getbootstrap.com/javascript/#modals + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$dialog = this.$element.find('.modal-dialog') + this.$backdrop = null + this.isShown = null + this.originalBodyPad = null + this.scrollbarWidth = 0 + this.ignoreBackdropClick = false + + if (this.options.remote) { + this.$element + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.3.7' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { + backdrop: true, + keyboard: true, + show: true + } + + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } + + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') + + this.escape() + this.resize() + + this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + + this.$dialog.on('mousedown.dismiss.bs.modal', function () { + that.$element.one('mouseup.dismiss.bs.modal', function (e) { + if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true + }) + }) + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position + } + + that.$element + .show() + .scrollTop(0) + + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$dialog // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .off('click.dismiss.bs.modal') + .off('mouseup.dismiss.bs.modal') + + this.$dialog.off('mousedown.dismiss.bs.modal') + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (document !== e.target && + this.$element[0] !== e.target && + !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $(document.createElement('div')) + .addClass('modal-backdrop ' + animate) + .appendTo(this.$body) + + this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { + if (this.ignoreBackdropClick) { + this.ignoreBackdropClick = false + return + } + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus() + : this.hide() + }, this)) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + this.adjustDialog() + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + var fullWindowWidth = window.innerWidth + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 + var documentElementRect = document.documentElement.getBoundingClientRect() + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) + } + this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth + this.scrollbarWidth = this.measureScrollbar() + } + + Modal.prototype.setScrollbar = function () { + var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) + this.originalBodyPad = document.body.style.paddingRight || '' + if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + } + + Modal.prototype.resetScrollbar = function () { + this.$body.css('padding-right', this.originalBodyPad) + } + + Modal.prototype.measureScrollbar = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } + + + // MODAL PLUGIN DEFINITION + // ======================= + + function Plugin(option, _relatedTarget) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.modal') + var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + var href = $this.attr('href') + var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + + if ($this.is('a')) e.preventDefault() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap/popover.js b/static/bootstrap/javascripts/bootstrap/popover.js new file mode 100644 index 0000000..efe1956 --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/popover.js @@ -0,0 +1,108 @@ +/* ======================================================================== + * Bootstrap: popover.js v3.3.7 + * http://getbootstrap.com/javascript/#popovers + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // POPOVER PUBLIC CLASS DEFINITION + // =============================== + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') + + Popover.VERSION = '3.3.7' + + Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { + placement: 'right', + trigger: 'click', + content: '', + template: '' + }) + + + // NOTE: POPOVER EXTENDS tooltip.js + // ================================ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) + + Popover.prototype.constructor = Popover + + Popover.prototype.getDefaults = function () { + return Popover.DEFAULTS + } + + Popover.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + var content = this.getContent() + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) + $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events + this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' + ](content) + + $tip.removeClass('fade top bottom left right in') + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() + } + + Popover.prototype.hasContent = function () { + return this.getTitle() || this.getContent() + } + + Popover.prototype.getContent = function () { + var $e = this.$element + var o = this.options + + return $e.attr('data-content') + || (typeof o.content == 'function' ? + o.content.call($e[0]) : + o.content) + } + + Popover.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.arrow')) + } + + + // POPOVER PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.popover') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.popover + + $.fn.popover = Plugin + $.fn.popover.Constructor = Popover + + + // POPOVER NO CONFLICT + // =================== + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap/scrollspy.js b/static/bootstrap/javascripts/bootstrap/scrollspy.js new file mode 100644 index 0000000..fe19809 --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/scrollspy.js @@ -0,0 +1,172 @@ +/* ======================================================================== + * Bootstrap: scrollspy.js v3.3.7 + * http://getbootstrap.com/javascript/#scrollspy + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // SCROLLSPY CLASS DEFINITION + // ========================== + + function ScrollSpy(element, options) { + this.$body = $(document.body) + this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) + this.options = $.extend({}, ScrollSpy.DEFAULTS, options) + this.selector = (this.options.target || '') + ' .nav li > a' + this.offsets = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 + + this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) + this.refresh() + this.process() + } + + ScrollSpy.VERSION = '3.3.7' + + ScrollSpy.DEFAULTS = { + offset: 10 + } + + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } + + ScrollSpy.prototype.refresh = function () { + var that = this + var offsetMethod = 'offset' + var offsetBase = 0 + + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() + + if (!$.isWindow(this.$scrollElement[0])) { + offsetMethod = 'position' + offsetBase = this.$scrollElement.scrollTop() + } + + this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + that.offsets.push(this[0]) + that.targets.push(this[1]) + }) + } + + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } + + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) + && this.activate(targets[i]) + } + } + + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target + + this.clear() + + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + var active = $(selector) + .parents('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } + + active.trigger('activate.bs.scrollspy') + } + + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') + } + + + // SCROLLSPY PLUGIN DEFINITION + // =========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.scrollspy + + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy + + + // SCROLLSPY NO CONFLICT + // ===================== + + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } + + + // SCROLLSPY DATA-API + // ================== + + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap/tab.js b/static/bootstrap/javascripts/bootstrap/tab.js new file mode 100644 index 0000000..c4a8635 --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/tab.js @@ -0,0 +1,155 @@ +/* ======================================================================== + * Bootstrap: tab.js v3.3.7 + * http://getbootstrap.com/javascript/#tabs + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TAB CLASS DEFINITION + // ==================== + + var Tab = function (element) { + // jscs:disable requireDollarBeforejQueryAssignment + this.element = $(element) + // jscs:enable requireDollarBeforejQueryAssignment + } + + Tab.VERSION = '3.3.7' + + Tab.TRANSITION_DURATION = 150 + + Tab.prototype.show = function () { + var $this = this.element + var $ul = $this.closest('ul:not(.dropdown-menu)') + var selector = $this.data('target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + if ($this.parent('li').hasClass('active')) return + + var $previous = $ul.find('.active:last a') + var hideEvent = $.Event('hide.bs.tab', { + relatedTarget: $this[0] + }) + var showEvent = $.Event('show.bs.tab', { + relatedTarget: $previous[0] + }) + + $previous.trigger(hideEvent) + $this.trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + var $target = $(selector) + + this.activate($this.closest('li'), $ul) + this.activate($target, $target.parent(), function () { + $previous.trigger({ + type: 'hidden.bs.tab', + relatedTarget: $this[0] + }) + $this.trigger({ + type: 'shown.bs.tab', + relatedTarget: $previous[0] + }) + }) + } + + Tab.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active') + var transition = callback + && $.support.transition + && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', false) + + element + .addClass('active') + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if (element.parent('.dropdown-menu').length) { + element + .closest('li.dropdown') + .addClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + } + + callback && callback() + } + + $active.length && transition ? + $active + .one('bsTransitionEnd', next) + .emulateTransitionEnd(Tab.TRANSITION_DURATION) : + next() + + $active.removeClass('in') + } + + + // TAB PLUGIN DEFINITION + // ===================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tab') + + if (!data) $this.data('bs.tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tab + + $.fn.tab = Plugin + $.fn.tab.Constructor = Tab + + + // TAB NO CONFLICT + // =============== + + $.fn.tab.noConflict = function () { + $.fn.tab = old + return this + } + + + // TAB DATA-API + // ============ + + var clickHandler = function (e) { + e.preventDefault() + Plugin.call($(this), 'show') + } + + $(document) + .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) + .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap/tooltip.js b/static/bootstrap/javascripts/bootstrap/tooltip.js new file mode 100644 index 0000000..e35d9c7 --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/tooltip.js @@ -0,0 +1,520 @@ +/* ======================================================================== + * Bootstrap: tooltip.js v3.3.7 + * http://getbootstrap.com/javascript/#tooltip + * Inspired by the original jQuery.tipsy by Jason Frame + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TOOLTIP PUBLIC CLASS DEFINITION + // =============================== + + var Tooltip = function (element, options) { + this.type = null + this.options = null + this.enabled = null + this.timeout = null + this.hoverState = null + this.$element = null + this.inState = null + + this.init('tooltip', element, options) + } + + Tooltip.VERSION = '3.3.7' + + Tooltip.TRANSITION_DURATION = 150 + + Tooltip.DEFAULTS = { + animation: true, + placement: 'top', + selector: false, + template: '', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + container: false, + viewport: { + selector: 'body', + padding: 0 + } + } + + Tooltip.prototype.init = function (type, element, options) { + this.enabled = true + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) + this.inState = { click: false, hover: false, focus: false } + + if (this.$element[0] instanceof document.constructor && !this.options.selector) { + throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') + } + + var triggers = this.options.trigger.split(' ') + + for (var i = triggers.length; i--;) { + var trigger = triggers[i] + + if (trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (trigger != 'manual') { + var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' + var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' + + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + } + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + Tooltip.prototype.getDefaults = function () { + return Tooltip.DEFAULTS + } + + Tooltip.prototype.getOptions = function (options) { + options = $.extend({}, this.getDefaults(), this.$element.data(), options) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay, + hide: options.delay + } + } + + return options + } + + Tooltip.prototype.getDelegateOptions = function () { + var options = {} + var defaults = this.getDefaults() + + this._options && $.each(this._options, function (key, value) { + if (defaults[key] != value) options[key] = value + }) + + return options + } + + Tooltip.prototype.enter = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true + } + + if (self.tip().hasClass('in') || self.hoverState == 'in') { + self.hoverState = 'in' + return + } + + clearTimeout(self.timeout) + + self.hoverState = 'in' + + if (!self.options.delay || !self.options.delay.show) return self.show() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + Tooltip.prototype.isInStateTrue = function () { + for (var key in this.inState) { + if (this.inState[key]) return true + } + + return false + } + + Tooltip.prototype.leave = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false + } + + if (self.isInStateTrue()) return + + clearTimeout(self.timeout) + + self.hoverState = 'out' + + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + Tooltip.prototype.show = function () { + var e = $.Event('show.bs.' + this.type) + + if (this.hasContent() && this.enabled) { + this.$element.trigger(e) + + var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) + if (e.isDefaultPrevented() || !inDom) return + var that = this + + var $tip = this.tip() + + var tipId = this.getUID(this.type) + + this.setContent() + $tip.attr('id', tipId) + this.$element.attr('aria-describedby', tipId) + + if (this.options.animation) $tip.addClass('fade') + + var placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + var autoToken = /\s?auto?\s?/i + var autoPlace = autoToken.test(placement) + if (autoPlace) placement = placement.replace(autoToken, '') || 'top' + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + .addClass(placement) + .data('bs.' + this.type, this) + + this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) + this.$element.trigger('inserted.bs.' + this.type) + + var pos = this.getPosition() + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (autoPlace) { + var orgPlacement = placement + var viewportDim = this.getPosition(this.$viewport) + + placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : + placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : + placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : + placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : + placement + + $tip + .removeClass(orgPlacement) + .addClass(placement) + } + + var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) + + this.applyPlacement(calculatedOffset, placement) + + var complete = function () { + var prevHoverState = that.hoverState + that.$element.trigger('shown.bs.' + that.type) + that.hoverState = null + + if (prevHoverState == 'out') that.leave(that) + } + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + } + } + + Tooltip.prototype.applyPlacement = function (offset, placement) { + var $tip = this.tip() + var width = $tip[0].offsetWidth + var height = $tip[0].offsetHeight + + // manually read margins because getBoundingClientRect includes difference + var marginTop = parseInt($tip.css('margin-top'), 10) + var marginLeft = parseInt($tip.css('margin-left'), 10) + + // we must check for NaN for ie 8/9 + if (isNaN(marginTop)) marginTop = 0 + if (isNaN(marginLeft)) marginLeft = 0 + + offset.top += marginTop + offset.left += marginLeft + + // $.fn.offset doesn't round pixel values + // so we use setOffset directly with our own function B-0 + $.offset.setOffset($tip[0], $.extend({ + using: function (props) { + $tip.css({ + top: Math.round(props.top), + left: Math.round(props.left) + }) + } + }, offset), 0) + + $tip.addClass('in') + + // check to see if placing tip in new offset caused the tip to resize itself + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (placement == 'top' && actualHeight != height) { + offset.top = offset.top + height - actualHeight + } + + var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) + + if (delta.left) offset.left += delta.left + else offset.top += delta.top + + var isVertical = /top|bottom/.test(placement) + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' + + $tip.offset(offset) + this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) + } + + Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { + this.arrow() + .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') + .css(isVertical ? 'top' : 'left', '') + } + + Tooltip.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + + $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + $tip.removeClass('fade in top bottom left right') + } + + Tooltip.prototype.hide = function (callback) { + var that = this + var $tip = $(this.$tip) + var e = $.Event('hide.bs.' + this.type) + + function complete() { + if (that.hoverState != 'in') $tip.detach() + if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. + that.$element + .removeAttr('aria-describedby') + .trigger('hidden.bs.' + that.type) + } + callback && callback() + } + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + $tip.removeClass('in') + + $.support.transition && $tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + + this.hoverState = null + + return this + } + + Tooltip.prototype.fixTitle = function () { + var $e = this.$element + if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') + } + } + + Tooltip.prototype.hasContent = function () { + return this.getTitle() + } + + Tooltip.prototype.getPosition = function ($element) { + $element = $element || this.$element + + var el = $element[0] + var isBody = el.tagName == 'BODY' + + var elRect = el.getBoundingClientRect() + if (elRect.width == null) { + // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 + elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) + } + var isSvg = window.SVGElement && el instanceof window.SVGElement + // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. + // See https://github.com/twbs/bootstrap/issues/20280 + var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) + var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } + var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null + + return $.extend({}, elRect, scroll, outerDims, elOffset) + } + + Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { + return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : + /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } + + } + + Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { + var delta = { top: 0, left: 0 } + if (!this.$viewport) return delta + + var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 + var viewportDimensions = this.getPosition(this.$viewport) + + if (/right|left/.test(placement)) { + var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll + var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight + if (topEdgeOffset < viewportDimensions.top) { // top overflow + delta.top = viewportDimensions.top - topEdgeOffset + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset + } + } else { + var leftEdgeOffset = pos.left - viewportPadding + var rightEdgeOffset = pos.left + viewportPadding + actualWidth + if (leftEdgeOffset < viewportDimensions.left) { // left overflow + delta.left = viewportDimensions.left - leftEdgeOffset + } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset + } + } + + return delta + } + + Tooltip.prototype.getTitle = function () { + var title + var $e = this.$element + var o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + Tooltip.prototype.getUID = function (prefix) { + do prefix += ~~(Math.random() * 1000000) + while (document.getElementById(prefix)) + return prefix + } + + Tooltip.prototype.tip = function () { + if (!this.$tip) { + this.$tip = $(this.options.template) + if (this.$tip.length != 1) { + throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') + } + } + return this.$tip + } + + Tooltip.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) + } + + Tooltip.prototype.enable = function () { + this.enabled = true + } + + Tooltip.prototype.disable = function () { + this.enabled = false + } + + Tooltip.prototype.toggleEnabled = function () { + this.enabled = !this.enabled + } + + Tooltip.prototype.toggle = function (e) { + var self = this + if (e) { + self = $(e.currentTarget).data('bs.' + this.type) + if (!self) { + self = new this.constructor(e.currentTarget, this.getDelegateOptions()) + $(e.currentTarget).data('bs.' + this.type, self) + } + } + + if (e) { + self.inState.click = !self.inState.click + if (self.isInStateTrue()) self.enter(self) + else self.leave(self) + } else { + self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + } + } + + Tooltip.prototype.destroy = function () { + var that = this + clearTimeout(this.timeout) + this.hide(function () { + that.$element.off('.' + that.type).removeData('bs.' + that.type) + if (that.$tip) { + that.$tip.detach() + } + that.$tip = null + that.$arrow = null + that.$viewport = null + that.$element = null + }) + } + + + // TOOLTIP PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tooltip') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tooltip + + $.fn.tooltip = Plugin + $.fn.tooltip.Constructor = Tooltip + + + // TOOLTIP NO CONFLICT + // =================== + + $.fn.tooltip.noConflict = function () { + $.fn.tooltip = old + return this + } + +}(jQuery); diff --git a/static/bootstrap/javascripts/bootstrap/transition.js b/static/bootstrap/javascripts/bootstrap/transition.js new file mode 100644 index 0000000..db76596 --- /dev/null +++ b/static/bootstrap/javascripts/bootstrap/transition.js @@ -0,0 +1,59 @@ +/* ======================================================================== + * Bootstrap: transition.js v3.3.7 + * http://getbootstrap.com/javascript/#transitions + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + + return false // explicit for ie8 ( ._.) + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + + if (!$.support.transition) return + + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) + } + } + }) + +}(jQuery); diff --git a/static/bootstrap/stylesheets/_bootstrap-compass.scss b/static/bootstrap/stylesheets/_bootstrap-compass.scss new file mode 100644 index 0000000..8fbc3cd --- /dev/null +++ b/static/bootstrap/stylesheets/_bootstrap-compass.scss @@ -0,0 +1,9 @@ +@function twbs-font-path($path) { + @return font-url($path, true); +} + +@function twbs-image-path($path) { + @return image-url($path, true); +} + +$bootstrap-sass-asset-helper: true; diff --git a/static/bootstrap/stylesheets/_bootstrap-mincer.scss b/static/bootstrap/stylesheets/_bootstrap-mincer.scss new file mode 100644 index 0000000..0c4655e --- /dev/null +++ b/static/bootstrap/stylesheets/_bootstrap-mincer.scss @@ -0,0 +1,19 @@ +// Mincer asset helper functions +// +// This must be imported into a .css.ejs.scss file. +// Then, <% %>-interpolations will be parsed as strings by Sass, and evaluated by EJS after Sass compilation. + + +@function twbs-font-path($path) { + // do something like following + // from "path/to/font.ext#suffix" to "<%- asset_path(path/to/font.ext)) + #suffix %>" + // from "path/to/font.ext?#suffix" to "<%- asset_path(path/to/font.ext)) + ?#suffix %>" + // or from "path/to/font.ext" just "<%- asset_path(path/to/font.ext)) %>" + @return "<%- asset_path("#{$path}".replace(/[#?].*$/, '')) + "#{$path}".replace(/(^[^#?]*)([#?]?.*$)/, '$2') %>"; +} + +@function twbs-image-path($file) { + @return "<%- asset_path("#{$file}") %>"; +} + +$bootstrap-sass-asset-helper: true; diff --git a/static/bootstrap/stylesheets/_bootstrap-sprockets.scss b/static/bootstrap/stylesheets/_bootstrap-sprockets.scss new file mode 100644 index 0000000..9fffc1e --- /dev/null +++ b/static/bootstrap/stylesheets/_bootstrap-sprockets.scss @@ -0,0 +1,9 @@ +@function twbs-font-path($path) { + @return font-path($path); +} + +@function twbs-image-path($path) { + @return image-path($path); +} + +$bootstrap-sass-asset-helper: true; diff --git a/static/bootstrap/stylesheets/_bootstrap.scss b/static/bootstrap/stylesheets/_bootstrap.scss new file mode 100644 index 0000000..e72d1de --- /dev/null +++ b/static/bootstrap/stylesheets/_bootstrap.scss @@ -0,0 +1,56 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +// Core variables and mixins +@import "bootstrap/variables"; +@import "bootstrap/mixins"; + +// Reset and dependencies +@import "bootstrap/normalize"; +@import "bootstrap/print"; +@import "bootstrap/glyphicons"; + +// Core CSS +@import "bootstrap/scaffolding"; +@import "bootstrap/type"; +@import "bootstrap/code"; +@import "bootstrap/grid"; +@import "bootstrap/tables"; +@import "bootstrap/forms"; +@import "bootstrap/buttons"; + +// Components +@import "bootstrap/component-animations"; +@import "bootstrap/dropdowns"; +@import "bootstrap/button-groups"; +@import "bootstrap/input-groups"; +@import "bootstrap/navs"; +@import "bootstrap/navbar"; +@import "bootstrap/breadcrumbs"; +@import "bootstrap/pagination"; +@import "bootstrap/pager"; +@import "bootstrap/labels"; +@import "bootstrap/badges"; +@import "bootstrap/jumbotron"; +@import "bootstrap/thumbnails"; +@import "bootstrap/alerts"; +@import "bootstrap/progress-bars"; +@import "bootstrap/media"; +@import "bootstrap/list-group"; +@import "bootstrap/panels"; +@import "bootstrap/responsive-embed"; +@import "bootstrap/wells"; +@import "bootstrap/close"; + +// Components w/ JavaScript +@import "bootstrap/modals"; +@import "bootstrap/tooltip"; +@import "bootstrap/popovers"; +@import "bootstrap/carousel"; + +// Utility classes +@import "bootstrap/utilities"; +@import "bootstrap/responsive-utilities"; diff --git a/static/bootstrap/stylesheets/bootstrap/_alerts.scss b/static/bootstrap/stylesheets/bootstrap/_alerts.scss new file mode 100644 index 0000000..7d1e1fd --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_alerts.scss @@ -0,0 +1,73 @@ +// +// Alerts +// -------------------------------------------------- + + +// Base styles +// ------------------------- + +.alert { + padding: $alert-padding; + margin-bottom: $line-height-computed; + border: 1px solid transparent; + border-radius: $alert-border-radius; + + // Headings for larger alerts + h4 { + margin-top: 0; + // Specified for the h4 to prevent conflicts of changing $headings-color + color: inherit; + } + + // Provide class for links that match alerts + .alert-link { + font-weight: $alert-link-font-weight; + } + + // Improve alignment and spacing of inner content + > p, + > ul { + margin-bottom: 0; + } + + > p + p { + margin-top: 5px; + } +} + +// Dismissible alerts +// +// Expand the right padding and account for the close button's positioning. + +.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0. +.alert-dismissible { + padding-right: ($alert-padding + 20); + + // Adjust close link position + .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; + } +} + +// Alternate styles +// +// Generate contextual modifier classes for colorizing the alert. + +.alert-success { + @include alert-variant($alert-success-bg, $alert-success-border, $alert-success-text); +} + +.alert-info { + @include alert-variant($alert-info-bg, $alert-info-border, $alert-info-text); +} + +.alert-warning { + @include alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text); +} + +.alert-danger { + @include alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text); +} diff --git a/static/bootstrap/stylesheets/bootstrap/_badges.scss b/static/bootstrap/stylesheets/bootstrap/_badges.scss new file mode 100644 index 0000000..70002e0 --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_badges.scss @@ -0,0 +1,68 @@ +// +// Badges +// -------------------------------------------------- + + +// Base class +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: $font-size-small; + font-weight: $badge-font-weight; + color: $badge-color; + line-height: $badge-line-height; + vertical-align: middle; + white-space: nowrap; + text-align: center; + background-color: $badge-bg; + border-radius: $badge-border-radius; + + // Empty badges collapse automatically (not available in IE8) + &:empty { + display: none; + } + + // Quick fix for badges in buttons + .btn & { + position: relative; + top: -1px; + } + + .btn-xs &, + .btn-group-xs > .btn & { + top: 0; + padding: 1px 5px; + } + + // [converter] extracted a& to a.badge + + // Account for badges in navs + .list-group-item.active > &, + .nav-pills > .active > a > & { + color: $badge-active-color; + background-color: $badge-active-bg; + } + + .list-group-item > & { + float: right; + } + + .list-group-item > & + & { + margin-right: 5px; + } + + .nav-pills > li > a > & { + margin-left: 3px; + } +} + +// Hover state, but only for links +a.badge { + &:hover, + &:focus { + color: $badge-link-hover-color; + text-decoration: none; + cursor: pointer; + } +} diff --git a/static/bootstrap/stylesheets/bootstrap/_breadcrumbs.scss b/static/bootstrap/stylesheets/bootstrap/_breadcrumbs.scss new file mode 100644 index 0000000..b61f0c7 --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_breadcrumbs.scss @@ -0,0 +1,28 @@ +// +// Breadcrumbs +// -------------------------------------------------- + + +.breadcrumb { + padding: $breadcrumb-padding-vertical $breadcrumb-padding-horizontal; + margin-bottom: $line-height-computed; + list-style: none; + background-color: $breadcrumb-bg; + border-radius: $border-radius-base; + + > li { + display: inline-block; + + + li:before { + // [converter] Workaround for https://github.com/sass/libsass/issues/1115 + $nbsp: "\00a0"; + content: "#{$breadcrumb-separator}#{$nbsp}"; // Unicode space added since inline-block means non-collapsing white-space + padding: 0 5px; + color: $breadcrumb-color; + } + } + + > .active { + color: $breadcrumb-active-color; + } +} diff --git a/static/bootstrap/stylesheets/bootstrap/_button-groups.scss b/static/bootstrap/stylesheets/bootstrap/_button-groups.scss new file mode 100644 index 0000000..4b385f5 --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_button-groups.scss @@ -0,0 +1,244 @@ +// +// Button groups +// -------------------------------------------------- + +// Make the div behave like a button +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; // match .btn alignment given font-size hack above + > .btn { + position: relative; + float: left; + // Bring the "active" button to the front + &:hover, + &:focus, + &:active, + &.active { + z-index: 2; + } + } +} + +// Prevent double borders when buttons are next to each other +.btn-group { + .btn + .btn, + .btn + .btn-group, + .btn-group + .btn, + .btn-group + .btn-group { + margin-left: -1px; + } +} + +// Optional: Group multiple button groups together for a toolbar +.btn-toolbar { + margin-left: -5px; // Offset the first child's margin + @include clearfix; + + .btn, + .btn-group, + .input-group { + float: left; + } + > .btn, + > .btn-group, + > .input-group { + margin-left: 5px; + } +} + +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} + +// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match +.btn-group > .btn:first-child { + margin-left: 0; + &:not(:last-child):not(.dropdown-toggle) { + @include border-right-radius(0); + } +} +// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + @include border-left-radius(0); +} + +// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) { + > .btn:last-child, + > .dropdown-toggle { + @include border-right-radius(0); + } +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + @include border-left-radius(0); +} + +// On active and open, don't show outline +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + + +// Sizing +// +// Remix the default button sizing classes into new ones for easier manipulation. + +.btn-group-xs > .btn { @extend .btn-xs; } +.btn-group-sm > .btn { @extend .btn-sm; } +.btn-group-lg > .btn { @extend .btn-lg; } + + +// Split button dropdowns +// ---------------------- + +// Give the line between buttons some depth +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} + +// The clickable button for toggling the menu +// Remove the gradient and set the same inset shadow as the :active state +.btn-group.open .dropdown-toggle { + @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); + + // Show no shadow for `.btn-link` since it has no other button styles. + &.btn-link { + @include box-shadow(none); + } +} + + +// Reposition the caret +.btn .caret { + margin-left: 0; +} +// Carets in other button sizes +.btn-lg .caret { + border-width: $caret-width-large $caret-width-large 0; + border-bottom-width: 0; +} +// Upside down carets for .dropup +.dropup .btn-lg .caret { + border-width: 0 $caret-width-large $caret-width-large; +} + + +// Vertical button groups +// ---------------------- + +.btn-group-vertical { + > .btn, + > .btn-group, + > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; + } + + // Clear floats so dropdown menus can be properly placed + > .btn-group { + @include clearfix; + > .btn { + float: none; + } + } + + > .btn + .btn, + > .btn + .btn-group, + > .btn-group + .btn, + > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; + } +} + +.btn-group-vertical > .btn { + &:not(:first-child):not(:last-child) { + border-radius: 0; + } + &:first-child:not(:last-child) { + @include border-top-radius($btn-border-radius-base); + @include border-bottom-radius(0); + } + &:last-child:not(:first-child) { + @include border-top-radius(0); + @include border-bottom-radius($btn-border-radius-base); + } +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) { + > .btn:last-child, + > .dropdown-toggle { + @include border-bottom-radius(0); + } +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + @include border-top-radius(0); +} + + +// Justified button groups +// ---------------------- + +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; + > .btn, + > .btn-group { + float: none; + display: table-cell; + width: 1%; + } + > .btn-group .btn { + width: 100%; + } + + > .btn-group .dropdown-menu { + left: auto; + } +} + + +// Checkbox and radio options +// +// In order to support the browser's form validation feedback, powered by the +// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use +// `display: none;` or `visibility: hidden;` as that also hides the popover. +// Simply visually hiding the inputs via `opacity` would leave them clickable in +// certain cases which is prevented by using `clip` and `pointer-events`. +// This way, we ensure a DOM element is visible to position the popover from. +// +// See https://github.com/twbs/bootstrap/pull/12794 and +// https://github.com/twbs/bootstrap/pull/14559 for more information. + +[data-toggle="buttons"] { + > .btn, + > .btn-group > .btn { + input[type="radio"], + input[type="checkbox"] { + position: absolute; + clip: rect(0,0,0,0); + pointer-events: none; + } + } +} diff --git a/static/bootstrap/stylesheets/bootstrap/_buttons.scss b/static/bootstrap/stylesheets/bootstrap/_buttons.scss new file mode 100644 index 0000000..6452b70 --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_buttons.scss @@ -0,0 +1,168 @@ +// +// Buttons +// -------------------------------------------------- + + +// Base styles +// -------------------------------------------------- + +.btn { + display: inline-block; + margin-bottom: 0; // For input.btn + font-weight: $btn-font-weight; + text-align: center; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 + border: 1px solid transparent; + white-space: nowrap; + @include button-size($padding-base-vertical, $padding-base-horizontal, $font-size-base, $line-height-base, $btn-border-radius-base); + @include user-select(none); + + &, + &:active, + &.active { + &:focus, + &.focus { + @include tab-focus; + } + } + + &:hover, + &:focus, + &.focus { + color: $btn-default-color; + text-decoration: none; + } + + &:active, + &.active { + outline: 0; + background-image: none; + @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); + } + + &.disabled, + &[disabled], + fieldset[disabled] & { + cursor: $cursor-disabled; + @include opacity(.65); + @include box-shadow(none); + } + + // [converter] extracted a& to a.btn +} + +a.btn { + &.disabled, + fieldset[disabled] & { + pointer-events: none; // Future-proof disabling of clicks on `` elements + } +} + + +// Alternate buttons +// -------------------------------------------------- + +.btn-default { + @include button-variant($btn-default-color, $btn-default-bg, $btn-default-border); +} +.btn-primary { + @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border); +} +// Success appears as green +.btn-success { + @include button-variant($btn-success-color, $btn-success-bg, $btn-success-border); +} +// Info appears as blue-green +.btn-info { + @include button-variant($btn-info-color, $btn-info-bg, $btn-info-border); +} +// Warning appears as orange +.btn-warning { + @include button-variant($btn-warning-color, $btn-warning-bg, $btn-warning-border); +} +// Danger and error appear as red +.btn-danger { + @include button-variant($btn-danger-color, $btn-danger-bg, $btn-danger-border); +} + + +// Link buttons +// ------------------------- + +// Make a button look and behave like a link +.btn-link { + color: $link-color; + font-weight: normal; + border-radius: 0; + + &, + &:active, + &.active, + &[disabled], + fieldset[disabled] & { + background-color: transparent; + @include box-shadow(none); + } + &, + &:hover, + &:focus, + &:active { + border-color: transparent; + } + &:hover, + &:focus { + color: $link-hover-color; + text-decoration: $link-hover-decoration; + background-color: transparent; + } + &[disabled], + fieldset[disabled] & { + &:hover, + &:focus { + color: $btn-link-disabled-color; + text-decoration: none; + } + } +} + + +// Button Sizes +// -------------------------------------------------- + +.btn-lg { + // line-height: ensure even-numbered height of button next to large input + @include button-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $btn-border-radius-large); +} +.btn-sm { + // line-height: ensure proper height of button next to small input + @include button-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $btn-border-radius-small); +} +.btn-xs { + @include button-size($padding-xs-vertical, $padding-xs-horizontal, $font-size-small, $line-height-small, $btn-border-radius-small); +} + + +// Block button +// -------------------------------------------------- + +.btn-block { + display: block; + width: 100%; +} + +// Vertically space out multiple block buttons +.btn-block + .btn-block { + margin-top: 5px; +} + +// Specificity overrides +input[type="submit"], +input[type="reset"], +input[type="button"] { + &.btn-block { + width: 100%; + } +} diff --git a/static/bootstrap/stylesheets/bootstrap/_carousel.scss b/static/bootstrap/stylesheets/bootstrap/_carousel.scss new file mode 100644 index 0000000..753d881 --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_carousel.scss @@ -0,0 +1,270 @@ +// +// Carousel +// -------------------------------------------------- + + +// Wrapper for the slide container and indicators +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + overflow: hidden; + width: 100%; + + > .item { + display: none; + position: relative; + @include transition(.6s ease-in-out left); + + // Account for jankitude on images + > img, + > a > img { + @include img-responsive; + line-height: 1; + } + + // WebKit CSS3 transforms for supported devices + @media all and (transform-3d), (-webkit-transform-3d) { + @include transition-transform(0.6s ease-in-out); + @include backface-visibility(hidden); + @include perspective(1000px); + + &.next, + &.active.right { + @include translate3d(100%, 0, 0); + left: 0; + } + &.prev, + &.active.left { + @include translate3d(-100%, 0, 0); + left: 0; + } + &.next.left, + &.prev.right, + &.active { + @include translate3d(0, 0, 0); + left: 0; + } + } + } + + > .active, + > .next, + > .prev { + display: block; + } + + > .active { + left: 0; + } + + > .next, + > .prev { + position: absolute; + top: 0; + width: 100%; + } + + > .next { + left: 100%; + } + > .prev { + left: -100%; + } + > .next.left, + > .prev.right { + left: 0; + } + + > .active.left { + left: -100%; + } + > .active.right { + left: 100%; + } + +} + +// Left/right controls for nav +// --------------------------- + +.carousel-control { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: $carousel-control-width; + @include opacity($carousel-control-opacity); + font-size: $carousel-control-font-size; + color: $carousel-control-color; + text-align: center; + text-shadow: $carousel-text-shadow; + background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug + // We can't have this transition here because WebKit cancels the carousel + // animation if you trip this while in the middle of another animation. + + // Set gradients for backgrounds + &.left { + @include gradient-horizontal($start-color: rgba(0,0,0,.5), $end-color: rgba(0,0,0,.0001)); + } + &.right { + left: auto; + right: 0; + @include gradient-horizontal($start-color: rgba(0,0,0,.0001), $end-color: rgba(0,0,0,.5)); + } + + // Hover/focus state + &:hover, + &:focus { + outline: 0; + color: $carousel-control-color; + text-decoration: none; + @include opacity(.9); + } + + // Toggles + .icon-prev, + .icon-next, + .glyphicon-chevron-left, + .glyphicon-chevron-right { + position: absolute; + top: 50%; + margin-top: -10px; + z-index: 5; + display: inline-block; + } + .icon-prev, + .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; + } + .icon-next, + .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; + } + .icon-prev, + .icon-next { + width: 20px; + height: 20px; + line-height: 1; + font-family: serif; + } + + + .icon-prev { + &:before { + content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039) + } + } + .icon-next { + &:before { + content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A) + } + } +} + +// Optional indicator pips +// +// Add an unordered list with the following class and add a list item for each +// slide your carousel holds. + +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; + + li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid $carousel-indicator-border-color; + border-radius: 10px; + cursor: pointer; + + // IE8-9 hack for event handling + // + // Internet Explorer 8-9 does not support clicks on elements without a set + // `background-color`. We cannot use `filter` since that's not viewed as a + // background color by the browser. Thus, a hack is needed. + // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer + // + // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we + // set alpha transparency for the best results possible. + background-color: #000 \9; // IE8 + background-color: rgba(0,0,0,0); // IE9 + } + .active { + margin: 0; + width: 12px; + height: 12px; + background-color: $carousel-indicator-active-bg; + } +} + +// Optional captions +// ----------------------------- +// Hidden by default for smaller viewports +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: $carousel-caption-color; + text-align: center; + text-shadow: $carousel-text-shadow; + & .btn { + text-shadow: none; // No shadow for button elements in carousel-caption + } +} + + +// Scale up controls for tablets and up +@media screen and (min-width: $screen-sm-min) { + + // Scale up the controls a smidge + .carousel-control { + .glyphicon-chevron-left, + .glyphicon-chevron-right, + .icon-prev, + .icon-next { + width: ($carousel-control-font-size * 1.5); + height: ($carousel-control-font-size * 1.5); + margin-top: ($carousel-control-font-size / -2); + font-size: ($carousel-control-font-size * 1.5); + } + .glyphicon-chevron-left, + .icon-prev { + margin-left: ($carousel-control-font-size / -2); + } + .glyphicon-chevron-right, + .icon-next { + margin-right: ($carousel-control-font-size / -2); + } + } + + // Show and left align the captions + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + + // Move up the indicators + .carousel-indicators { + bottom: 20px; + } +} diff --git a/static/bootstrap/stylesheets/bootstrap/_close.scss b/static/bootstrap/stylesheets/bootstrap/_close.scss new file mode 100644 index 0000000..3b74d8a --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_close.scss @@ -0,0 +1,36 @@ +// +// Close icons +// -------------------------------------------------- + + +.close { + float: right; + font-size: ($font-size-base * 1.5); + font-weight: $close-font-weight; + line-height: 1; + color: $close-color; + text-shadow: $close-text-shadow; + @include opacity(.2); + + &:hover, + &:focus { + color: $close-color; + text-decoration: none; + cursor: pointer; + @include opacity(.5); + } + + // [converter] extracted button& to button.close +} + +// Additional properties for button version +// iOS requires the button element instead of an anchor tag. +// If you want the anchor version, it requires `href="#"`. +// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} diff --git a/static/bootstrap/stylesheets/bootstrap/_code.scss b/static/bootstrap/stylesheets/bootstrap/_code.scss new file mode 100644 index 0000000..caa5f06 --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_code.scss @@ -0,0 +1,69 @@ +// +// Code (inline and block) +// -------------------------------------------------- + + +// Inline and block code styles +code, +kbd, +pre, +samp { + font-family: $font-family-monospace; +} + +// Inline code +code { + padding: 2px 4px; + font-size: 90%; + color: $code-color; + background-color: $code-bg; + border-radius: $border-radius-base; +} + +// User input typically entered via keyboard +kbd { + padding: 2px 4px; + font-size: 90%; + color: $kbd-color; + background-color: $kbd-bg; + border-radius: $border-radius-small; + box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); + + kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + box-shadow: none; + } +} + +// Blocks of code +pre { + display: block; + padding: (($line-height-computed - 1) / 2); + margin: 0 0 ($line-height-computed / 2); + font-size: ($font-size-base - 1); // 14px to 13px + line-height: $line-height-base; + word-break: break-all; + word-wrap: break-word; + color: $pre-color; + background-color: $pre-bg; + border: 1px solid $pre-border-color; + border-radius: $border-radius-base; + + // Account for some code outputs that place code tags in pre tags + code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; + } +} + +// Enable scrollable blocks of code +.pre-scrollable { + max-height: $pre-scrollable-max-height; + overflow-y: scroll; +} diff --git a/static/bootstrap/stylesheets/bootstrap/_component-animations.scss b/static/bootstrap/stylesheets/bootstrap/_component-animations.scss new file mode 100644 index 0000000..ca3b43c --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_component-animations.scss @@ -0,0 +1,37 @@ +// +// Component animations +// -------------------------------------------------- + +// Heads up! +// +// We don't use the `.opacity()` mixin here since it causes a bug with text +// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552. + +.fade { + opacity: 0; + @include transition(opacity .15s linear); + &.in { + opacity: 1; + } +} + +.collapse { + display: none; + + &.in { display: block; } + // [converter] extracted tr&.in to tr.collapse.in + // [converter] extracted tbody&.in to tbody.collapse.in +} + +tr.collapse.in { display: table-row; } + +tbody.collapse.in { display: table-row-group; } + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + @include transition-property(height, visibility); + @include transition-duration(.35s); + @include transition-timing-function(ease); +} diff --git a/static/bootstrap/stylesheets/bootstrap/_dropdowns.scss b/static/bootstrap/stylesheets/bootstrap/_dropdowns.scss new file mode 100644 index 0000000..aac8459 --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_dropdowns.scss @@ -0,0 +1,216 @@ +// +// Dropdown menus +// -------------------------------------------------- + + +// Dropdown arrow/caret +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: $caret-width-base dashed; + border-top: $caret-width-base solid \9; // IE8 + border-right: $caret-width-base solid transparent; + border-left: $caret-width-base solid transparent; +} + +// The dropdown wrapper (div) +.dropup, +.dropdown { + position: relative; +} + +// Prevent the focus on the dropdown toggle when closing dropdowns +.dropdown-toggle:focus { + outline: 0; +} + +// The dropdown menu (ul) +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: $zindex-dropdown; + display: none; // none by default, but block on "open" of the menu + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; // override default ul + list-style: none; + font-size: $font-size-base; + text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) + background-color: $dropdown-bg; + border: 1px solid $dropdown-fallback-border; // IE8 fallback + border: 1px solid $dropdown-border; + border-radius: $border-radius-base; + @include box-shadow(0 6px 12px rgba(0,0,0,.175)); + background-clip: padding-box; + + // Aligns the dropdown menu to right + // + // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]` + &.pull-right { + right: 0; + left: auto; + } + + // Dividers (basically an hr) within the dropdown + .divider { + @include nav-divider($dropdown-divider-bg); + } + + // Links within the dropdown menu + > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: $line-height-base; + color: $dropdown-link-color; + white-space: nowrap; // prevent links from randomly breaking onto new lines + } +} + +// Hover/Focus state +.dropdown-menu > li > a { + &:hover, + &:focus { + text-decoration: none; + color: $dropdown-link-hover-color; + background-color: $dropdown-link-hover-bg; + } +} + +// Active state +.dropdown-menu > .active > a { + &, + &:hover, + &:focus { + color: $dropdown-link-active-color; + text-decoration: none; + outline: 0; + background-color: $dropdown-link-active-bg; + } +} + +// Disabled state +// +// Gray out text and ensure the hover/focus state remains gray + +.dropdown-menu > .disabled > a { + &, + &:hover, + &:focus { + color: $dropdown-link-disabled-color; + } + + // Nuke hover/focus effects + &:hover, + &:focus { + text-decoration: none; + background-color: transparent; + background-image: none; // Remove CSS gradient + @include reset-filter; + cursor: $cursor-disabled; + } +} + +// Open state for the dropdown +.open { + // Show the menu + > .dropdown-menu { + display: block; + } + + // Remove the outline when :focus is triggered + > a { + outline: 0; + } +} + +// Menu positioning +// +// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown +// menu with the parent. +.dropdown-menu-right { + left: auto; // Reset the default from `.dropdown-menu` + right: 0; +} +// With v3, we enabled auto-flipping if you have a dropdown within a right +// aligned nav component. To enable the undoing of that, we provide an override +// to restore the default dropdown menu alignment. +// +// This is only for left-aligning a dropdown menu within a `.navbar-right` or +// `.pull-right` nav component. +.dropdown-menu-left { + left: 0; + right: auto; +} + +// Dropdown section headers +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: $font-size-small; + line-height: $line-height-base; + color: $dropdown-header-color; + white-space: nowrap; // as with > li > a +} + +// Backdrop to catch body clicks on mobile, etc. +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: ($zindex-dropdown - 10); +} + +// Right aligned dropdowns +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +// Allow for dropdowns to go bottom up (aka, dropup-menu) +// +// Just add .dropup after the standard .dropdown class and you're set, bro. +// TODO: abstract this so that the navbar fixed styles are not placed here? + +.dropup, +.navbar-fixed-bottom .dropdown { + // Reverse the caret + .caret { + border-top: 0; + border-bottom: $caret-width-base dashed; + border-bottom: $caret-width-base solid \9; // IE8 + content: ""; + } + // Different positioning for bottom up menu + .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; + } +} + + +// Component alignment +// +// Reiterate per navbar.less and the modified component alignment there. + +@media (min-width: $grid-float-breakpoint) { + .navbar-right { + .dropdown-menu { + right: 0; left: auto; + } + // Necessary for overrides of the default right aligned menu. + // Will remove come v4 in all likelihood. + .dropdown-menu-left { + left: 0; right: auto; + } + } +} diff --git a/static/bootstrap/stylesheets/bootstrap/_forms.scss b/static/bootstrap/stylesheets/bootstrap/_forms.scss new file mode 100644 index 0000000..ac26a6a --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_forms.scss @@ -0,0 +1,617 @@ +// +// Forms +// -------------------------------------------------- + + +// Normalize non-controls +// +// Restyle and baseline non-control form elements. + +fieldset { + padding: 0; + margin: 0; + border: 0; + // Chrome and Firefox set a `min-width: min-content;` on fieldsets, + // so we reset that to ensure it behaves more like a standard block element. + // See https://github.com/twbs/bootstrap/issues/12359. + min-width: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: $line-height-computed; + font-size: ($font-size-base * 1.5); + line-height: inherit; + color: $legend-color; + border: 0; + border-bottom: 1px solid $legend-border-color; +} + +label { + display: inline-block; + max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141) + margin-bottom: 5px; + font-weight: bold; +} + + +// Normalize form controls +// +// While most of our form styles require extra classes, some basic normalization +// is required to ensure optimum display with or without those classes to better +// address browser inconsistencies. + +// Override content-box in Normalize (* isn't specific enough) +input[type="search"] { + @include box-sizing(border-box); +} + +// Position radios and checkboxes better +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; // IE8-9 + line-height: normal; +} + +input[type="file"] { + display: block; +} + +// Make range inputs behave like textual form controls +input[type="range"] { + display: block; + width: 100%; +} + +// Make multiple select elements height not fixed +select[multiple], +select[size] { + height: auto; +} + +// Focus for file, radio, and checkbox +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + @include tab-focus; +} + +// Adjust output element +output { + display: block; + padding-top: ($padding-base-vertical + 1); + font-size: $font-size-base; + line-height: $line-height-base; + color: $input-color; +} + + +// Common form controls +// +// Shared size and type resets for form controls. Apply `.form-control` to any +// of the following form controls: +// +// select +// textarea +// input[type="text"] +// input[type="password"] +// input[type="datetime"] +// input[type="datetime-local"] +// input[type="date"] +// input[type="month"] +// input[type="time"] +// input[type="week"] +// input[type="number"] +// input[type="email"] +// input[type="url"] +// input[type="search"] +// input[type="tel"] +// input[type="color"] + +.form-control { + display: block; + width: 100%; + height: $input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border) + padding: $padding-base-vertical $padding-base-horizontal; + font-size: $font-size-base; + line-height: $line-height-base; + color: $input-color; + background-color: $input-bg; + background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 + border: 1px solid $input-border; + border-radius: $input-border-radius; // Note: This has no effect on s in CSS. + @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); + @include transition(border-color ease-in-out .15s, box-shadow ease-in-out .15s); + + // Customize the `:focus` state to imitate native WebKit styles. + @include form-control-focus; + + // Placeholder + @include placeholder; + + // Unstyle the caret on `` background color +$input-bg: #fff !default; +//** `` background color +$input-bg-disabled: $gray-lighter !default; + +//** Text color for ``s +$input-color: $gray !default; +//** `` border color +$input-border: #ccc !default; + +// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4 +//** Default `.form-control` border radius +// This has no effect on ``s in CSS. +$input-border-radius: $border-radius-base !default; +//** Large `.form-control` border radius +$input-border-radius-large: $border-radius-large !default; +//** Small `.form-control` border radius +$input-border-radius-small: $border-radius-small !default; + +//** Border color for inputs on focus +$input-border-focus: #66afe9 !default; + +//** Placeholder text color +$input-color-placeholder: #999 !default; + +//** Default `.form-control` height +$input-height-base: ($line-height-computed + ($padding-base-vertical * 2) + 2) !default; +//** Large `.form-control` height +$input-height-large: (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2) !default; +//** Small `.form-control` height +$input-height-small: (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2) !default; + +//** `.form-group` margin +$form-group-margin-bottom: 15px !default; + +$legend-color: $gray-dark !default; +$legend-border-color: #e5e5e5 !default; + +//** Background color for textual input addons +$input-group-addon-bg: $gray-lighter !default; +//** Border color for textual input addons +$input-group-addon-border-color: $input-border !default; + +//** Disabled cursor for form controls and buttons. +$cursor-disabled: not-allowed !default; + + +//== Dropdowns +// +//## Dropdown menu container and contents. + +//** Background for the dropdown menu. +$dropdown-bg: #fff !default; +//** Dropdown menu `border-color`. +$dropdown-border: rgba(0,0,0,.15) !default; +//** Dropdown menu `border-color` **for IE8**. +$dropdown-fallback-border: #ccc !default; +//** Divider color for between dropdown items. +$dropdown-divider-bg: #e5e5e5 !default; + +//** Dropdown link text color. +$dropdown-link-color: $gray-dark !default; +//** Hover color for dropdown links. +$dropdown-link-hover-color: darken($gray-dark, 5%) !default; +//** Hover background for dropdown links. +$dropdown-link-hover-bg: #f5f5f5 !default; + +//** Active dropdown menu item text color. +$dropdown-link-active-color: $component-active-color !default; +//** Active dropdown menu item background color. +$dropdown-link-active-bg: $component-active-bg !default; + +//** Disabled dropdown menu item background color. +$dropdown-link-disabled-color: $gray-light !default; + +//** Text color for headers within dropdown menus. +$dropdown-header-color: $gray-light !default; + +//** Deprecated `$dropdown-caret-color` as of v3.1.0 +$dropdown-caret-color: #000 !default; + + +//-- Z-index master list +// +// Warning: Avoid customizing these values. They're used for a bird's eye view +// of components dependent on the z-axis and are designed to all work together. +// +// Note: These variables are not generated into the Customizer. + +$zindex-navbar: 1000 !default; +$zindex-dropdown: 1000 !default; +$zindex-popover: 1060 !default; +$zindex-tooltip: 1070 !default; +$zindex-navbar-fixed: 1030 !default; +$zindex-modal-background: 1040 !default; +$zindex-modal: 1050 !default; + + +//== Media queries breakpoints +// +//## Define the breakpoints at which your layout will change, adapting to different screen sizes. + +// Extra small screen / phone +//** Deprecated `$screen-xs` as of v3.0.1 +$screen-xs: 480px !default; +//** Deprecated `$screen-xs-min` as of v3.2.0 +$screen-xs-min: $screen-xs !default; +//** Deprecated `$screen-phone` as of v3.0.1 +$screen-phone: $screen-xs-min !default; + +// Small screen / tablet +//** Deprecated `$screen-sm` as of v3.0.1 +$screen-sm: 768px !default; +$screen-sm-min: $screen-sm !default; +//** Deprecated `$screen-tablet` as of v3.0.1 +$screen-tablet: $screen-sm-min !default; + +// Medium screen / desktop +//** Deprecated `$screen-md` as of v3.0.1 +$screen-md: 992px !default; +$screen-md-min: $screen-md !default; +//** Deprecated `$screen-desktop` as of v3.0.1 +$screen-desktop: $screen-md-min !default; + +// Large screen / wide desktop +//** Deprecated `$screen-lg` as of v3.0.1 +$screen-lg: 1200px !default; +$screen-lg-min: $screen-lg !default; +//** Deprecated `$screen-lg-desktop` as of v3.0.1 +$screen-lg-desktop: $screen-lg-min !default; + +// So media queries don't overlap when required, provide a maximum +$screen-xs-max: ($screen-sm-min - 1) !default; +$screen-sm-max: ($screen-md-min - 1) !default; +$screen-md-max: ($screen-lg-min - 1) !default; + + +//== Grid system +// +//## Define your custom responsive grid. + +//** Number of columns in the grid. +$grid-columns: 12 !default; +//** Padding between columns. Gets divided in half for the left and right. +$grid-gutter-width: 30px !default; +// Navbar collapse +//** Point at which the navbar becomes uncollapsed. +$grid-float-breakpoint: $screen-sm-min !default; +//** Point at which the navbar begins collapsing. +$grid-float-breakpoint-max: ($grid-float-breakpoint - 1) !default; + + +//== Container sizes +// +//## Define the maximum width of `.container` for different screen sizes. + +// Small screen / tablet +$container-tablet: (720px + $grid-gutter-width) !default; +//** For `$screen-sm-min` and up. +$container-sm: $container-tablet !default; + +// Medium screen / desktop +$container-desktop: (940px + $grid-gutter-width) !default; +//** For `$screen-md-min` and up. +$container-md: $container-desktop !default; + +// Large screen / wide desktop +$container-large-desktop: (1140px + $grid-gutter-width) !default; +//** For `$screen-lg-min` and up. +$container-lg: $container-large-desktop !default; + + +//== Navbar +// +//## + +// Basics of a navbar +$navbar-height: 50px !default; +$navbar-margin-bottom: $line-height-computed !default; +$navbar-border-radius: $border-radius-base !default; +$navbar-padding-horizontal: floor(($grid-gutter-width / 2)) !default; +$navbar-padding-vertical: (($navbar-height - $line-height-computed) / 2) !default; +$navbar-collapse-max-height: 340px !default; + +$navbar-default-color: #777 !default; +$navbar-default-bg: #f8f8f8 !default; +$navbar-default-border: darken($navbar-default-bg, 6.5%) !default; + +// Navbar links +$navbar-default-link-color: #777 !default; +$navbar-default-link-hover-color: #333 !default; +$navbar-default-link-hover-bg: transparent !default; +$navbar-default-link-active-color: #555 !default; +$navbar-default-link-active-bg: darken($navbar-default-bg, 6.5%) !default; +$navbar-default-link-disabled-color: #ccc !default; +$navbar-default-link-disabled-bg: transparent !default; + +// Navbar brand label +$navbar-default-brand-color: $navbar-default-link-color !default; +$navbar-default-brand-hover-color: darken($navbar-default-brand-color, 10%) !default; +$navbar-default-brand-hover-bg: transparent !default; + +// Navbar toggle +$navbar-default-toggle-hover-bg: #ddd !default; +$navbar-default-toggle-icon-bar-bg: #888 !default; +$navbar-default-toggle-border-color: #ddd !default; + + +//=== Inverted navbar +// Reset inverted navbar basics +$navbar-inverse-color: lighten($gray-light, 15%) !default; +$navbar-inverse-bg: #222 !default; +$navbar-inverse-border: darken($navbar-inverse-bg, 10%) !default; + +// Inverted navbar links +$navbar-inverse-link-color: lighten($gray-light, 15%) !default; +$navbar-inverse-link-hover-color: #fff !default; +$navbar-inverse-link-hover-bg: transparent !default; +$navbar-inverse-link-active-color: $navbar-inverse-link-hover-color !default; +$navbar-inverse-link-active-bg: darken($navbar-inverse-bg, 10%) !default; +$navbar-inverse-link-disabled-color: #444 !default; +$navbar-inverse-link-disabled-bg: transparent !default; + +// Inverted navbar brand label +$navbar-inverse-brand-color: $navbar-inverse-link-color !default; +$navbar-inverse-brand-hover-color: #fff !default; +$navbar-inverse-brand-hover-bg: transparent !default; + +// Inverted navbar toggle +$navbar-inverse-toggle-hover-bg: #333 !default; +$navbar-inverse-toggle-icon-bar-bg: #fff !default; +$navbar-inverse-toggle-border-color: #333 !default; + + +//== Navs +// +//## + +//=== Shared nav styles +$nav-link-padding: 10px 15px !default; +$nav-link-hover-bg: $gray-lighter !default; + +$nav-disabled-link-color: $gray-light !default; +$nav-disabled-link-hover-color: $gray-light !default; + +//== Tabs +$nav-tabs-border-color: #ddd !default; + +$nav-tabs-link-hover-border-color: $gray-lighter !default; + +$nav-tabs-active-link-hover-bg: $body-bg !default; +$nav-tabs-active-link-hover-color: $gray !default; +$nav-tabs-active-link-hover-border-color: #ddd !default; + +$nav-tabs-justified-link-border-color: #ddd !default; +$nav-tabs-justified-active-link-border-color: $body-bg !default; + +//== Pills +$nav-pills-border-radius: $border-radius-base !default; +$nav-pills-active-link-hover-bg: $component-active-bg !default; +$nav-pills-active-link-hover-color: $component-active-color !default; + + +//== Pagination +// +//## + +$pagination-color: $link-color !default; +$pagination-bg: #fff !default; +$pagination-border: #ddd !default; + +$pagination-hover-color: $link-hover-color !default; +$pagination-hover-bg: $gray-lighter !default; +$pagination-hover-border: #ddd !default; + +$pagination-active-color: #fff !default; +$pagination-active-bg: $brand-primary !default; +$pagination-active-border: $brand-primary !default; + +$pagination-disabled-color: $gray-light !default; +$pagination-disabled-bg: #fff !default; +$pagination-disabled-border: #ddd !default; + + +//== Pager +// +//## + +$pager-bg: $pagination-bg !default; +$pager-border: $pagination-border !default; +$pager-border-radius: 15px !default; + +$pager-hover-bg: $pagination-hover-bg !default; + +$pager-active-bg: $pagination-active-bg !default; +$pager-active-color: $pagination-active-color !default; + +$pager-disabled-color: $pagination-disabled-color !default; + + +//== Jumbotron +// +//## + +$jumbotron-padding: 30px !default; +$jumbotron-color: inherit !default; +$jumbotron-bg: $gray-lighter !default; +$jumbotron-heading-color: inherit !default; +$jumbotron-font-size: ceil(($font-size-base * 1.5)) !default; +$jumbotron-heading-font-size: ceil(($font-size-base * 4.5)) !default; + + +//== Form states and alerts +// +//## Define colors for form feedback states and, by default, alerts. + +$state-success-text: #3c763d !default; +$state-success-bg: #dff0d8 !default; +$state-success-border: darken(adjust-hue($state-success-bg, -10), 5%) !default; + +$state-info-text: #31708f !default; +$state-info-bg: #d9edf7 !default; +$state-info-border: darken(adjust-hue($state-info-bg, -10), 7%) !default; + +$state-warning-text: #8a6d3b !default; +$state-warning-bg: #fcf8e3 !default; +$state-warning-border: darken(adjust-hue($state-warning-bg, -10), 5%) !default; + +$state-danger-text: #a94442 !default; +$state-danger-bg: #f2dede !default; +$state-danger-border: darken(adjust-hue($state-danger-bg, -10), 5%) !default; + + +//== Tooltips +// +//## + +//** Tooltip max width +$tooltip-max-width: 200px !default; +//** Tooltip text color +$tooltip-color: #fff !default; +//** Tooltip background color +$tooltip-bg: #000 !default; +$tooltip-opacity: .9 !default; + +//** Tooltip arrow width +$tooltip-arrow-width: 5px !default; +//** Tooltip arrow color +$tooltip-arrow-color: $tooltip-bg !default; + + +//== Popovers +// +//## + +//** Popover body background color +$popover-bg: #fff !default; +//** Popover maximum width +$popover-max-width: 276px !default; +//** Popover border color +$popover-border-color: rgba(0,0,0,.2) !default; +//** Popover fallback border color +$popover-fallback-border-color: #ccc !default; + +//** Popover title background color +$popover-title-bg: darken($popover-bg, 3%) !default; + +//** Popover arrow width +$popover-arrow-width: 10px !default; +//** Popover arrow color +$popover-arrow-color: $popover-bg !default; + +//** Popover outer arrow width +$popover-arrow-outer-width: ($popover-arrow-width + 1) !default; +//** Popover outer arrow color +$popover-arrow-outer-color: fade_in($popover-border-color, 0.05) !default; +//** Popover outer arrow fallback color +$popover-arrow-outer-fallback-color: darken($popover-fallback-border-color, 20%) !default; + + +//== Labels +// +//## + +//** Default label background color +$label-default-bg: $gray-light !default; +//** Primary label background color +$label-primary-bg: $brand-primary !default; +//** Success label background color +$label-success-bg: $brand-success !default; +//** Info label background color +$label-info-bg: $brand-info !default; +//** Warning label background color +$label-warning-bg: $brand-warning !default; +//** Danger label background color +$label-danger-bg: $brand-danger !default; + +//** Default label text color +$label-color: #fff !default; +//** Default text color of a linked label +$label-link-hover-color: #fff !default; + + +//== Modals +// +//## + +//** Padding applied to the modal body +$modal-inner-padding: 15px !default; + +//** Padding applied to the modal title +$modal-title-padding: 15px !default; +//** Modal title line-height +$modal-title-line-height: $line-height-base !default; + +//** Background color of modal content area +$modal-content-bg: #fff !default; +//** Modal content border color +$modal-content-border-color: rgba(0,0,0,.2) !default; +//** Modal content border color **for IE8** +$modal-content-fallback-border-color: #999 !default; + +//** Modal backdrop background color +$modal-backdrop-bg: #000 !default; +//** Modal backdrop opacity +$modal-backdrop-opacity: .5 !default; +//** Modal header border color +$modal-header-border-color: #e5e5e5 !default; +//** Modal footer border color +$modal-footer-border-color: $modal-header-border-color !default; + +$modal-lg: 900px !default; +$modal-md: 600px !default; +$modal-sm: 300px !default; + + +//== Alerts +// +//## Define alert colors, border radius, and padding. + +$alert-padding: 15px !default; +$alert-border-radius: $border-radius-base !default; +$alert-link-font-weight: bold !default; + +$alert-success-bg: $state-success-bg !default; +$alert-success-text: $state-success-text !default; +$alert-success-border: $state-success-border !default; + +$alert-info-bg: $state-info-bg !default; +$alert-info-text: $state-info-text !default; +$alert-info-border: $state-info-border !default; + +$alert-warning-bg: $state-warning-bg !default; +$alert-warning-text: $state-warning-text !default; +$alert-warning-border: $state-warning-border !default; + +$alert-danger-bg: $state-danger-bg !default; +$alert-danger-text: $state-danger-text !default; +$alert-danger-border: $state-danger-border !default; + + +//== Progress bars +// +//## + +//** Background color of the whole progress component +$progress-bg: #f5f5f5 !default; +//** Progress bar text color +$progress-bar-color: #fff !default; +//** Variable for setting rounded corners on progress bar. +$progress-border-radius: $border-radius-base !default; + +//** Default progress bar color +$progress-bar-bg: $brand-primary !default; +//** Success progress bar color +$progress-bar-success-bg: $brand-success !default; +//** Warning progress bar color +$progress-bar-warning-bg: $brand-warning !default; +//** Danger progress bar color +$progress-bar-danger-bg: $brand-danger !default; +//** Info progress bar color +$progress-bar-info-bg: $brand-info !default; + + +//== List group +// +//## + +//** Background color on `.list-group-item` +$list-group-bg: #fff !default; +//** `.list-group-item` border color +$list-group-border: #ddd !default; +//** List group border radius +$list-group-border-radius: $border-radius-base !default; + +//** Background color of single list items on hover +$list-group-hover-bg: #f5f5f5 !default; +//** Text color of active list items +$list-group-active-color: $component-active-color !default; +//** Background color of active list items +$list-group-active-bg: $component-active-bg !default; +//** Border color of active list elements +$list-group-active-border: $list-group-active-bg !default; +//** Text color for content within active list items +$list-group-active-text-color: lighten($list-group-active-bg, 40%) !default; + +//** Text color of disabled list items +$list-group-disabled-color: $gray-light !default; +//** Background color of disabled list items +$list-group-disabled-bg: $gray-lighter !default; +//** Text color for content within disabled list items +$list-group-disabled-text-color: $list-group-disabled-color !default; + +$list-group-link-color: #555 !default; +$list-group-link-hover-color: $list-group-link-color !default; +$list-group-link-heading-color: #333 !default; + + +//== Panels +// +//## + +$panel-bg: #fff !default; +$panel-body-padding: 15px !default; +$panel-heading-padding: 10px 15px !default; +$panel-footer-padding: $panel-heading-padding !default; +$panel-border-radius: $border-radius-base !default; + +//** Border color for elements within panels +$panel-inner-border: #ddd !default; +$panel-footer-bg: #f5f5f5 !default; + +$panel-default-text: $gray-dark !default; +$panel-default-border: #ddd !default; +$panel-default-heading-bg: #f5f5f5 !default; + +$panel-primary-text: #fff !default; +$panel-primary-border: $brand-primary !default; +$panel-primary-heading-bg: $brand-primary !default; + +$panel-success-text: $state-success-text !default; +$panel-success-border: $state-success-border !default; +$panel-success-heading-bg: $state-success-bg !default; + +$panel-info-text: $state-info-text !default; +$panel-info-border: $state-info-border !default; +$panel-info-heading-bg: $state-info-bg !default; + +$panel-warning-text: $state-warning-text !default; +$panel-warning-border: $state-warning-border !default; +$panel-warning-heading-bg: $state-warning-bg !default; + +$panel-danger-text: $state-danger-text !default; +$panel-danger-border: $state-danger-border !default; +$panel-danger-heading-bg: $state-danger-bg !default; + + +//== Thumbnails +// +//## + +//** Padding around the thumbnail image +$thumbnail-padding: 4px !default; +//** Thumbnail background color +$thumbnail-bg: $body-bg !default; +//** Thumbnail border color +$thumbnail-border: #ddd !default; +//** Thumbnail border radius +$thumbnail-border-radius: $border-radius-base !default; + +//** Custom text color for thumbnail captions +$thumbnail-caption-color: $text-color !default; +//** Padding around the thumbnail caption +$thumbnail-caption-padding: 9px !default; + + +//== Wells +// +//## + +$well-bg: #f5f5f5 !default; +$well-border: darken($well-bg, 7%) !default; + + +//== Badges +// +//## + +$badge-color: #fff !default; +//** Linked badge text color on hover +$badge-link-hover-color: #fff !default; +$badge-bg: $gray-light !default; + +//** Badge text color in active nav link +$badge-active-color: $link-color !default; +//** Badge background color in active nav link +$badge-active-bg: #fff !default; + +$badge-font-weight: bold !default; +$badge-line-height: 1 !default; +$badge-border-radius: 10px !default; + + +//== Breadcrumbs +// +//## + +$breadcrumb-padding-vertical: 8px !default; +$breadcrumb-padding-horizontal: 15px !default; +//** Breadcrumb background color +$breadcrumb-bg: #f5f5f5 !default; +//** Breadcrumb text color +$breadcrumb-color: #ccc !default; +//** Text color of current page in the breadcrumb +$breadcrumb-active-color: $gray-light !default; +//** Textual separator for between breadcrumb elements +$breadcrumb-separator: "/" !default; + + +//== Carousel +// +//## + +$carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6) !default; + +$carousel-control-color: #fff !default; +$carousel-control-width: 15% !default; +$carousel-control-opacity: .5 !default; +$carousel-control-font-size: 20px !default; + +$carousel-indicator-active-bg: #fff !default; +$carousel-indicator-border-color: #fff !default; + +$carousel-caption-color: #fff !default; + + +//== Close +// +//## + +$close-font-weight: bold !default; +$close-color: #000 !default; +$close-text-shadow: 0 1px 0 #fff !default; + + +//== Code +// +//## + +$code-color: #c7254e !default; +$code-bg: #f9f2f4 !default; + +$kbd-color: #fff !default; +$kbd-bg: #333 !default; + +$pre-bg: #f5f5f5 !default; +$pre-color: $gray-dark !default; +$pre-border-color: #ccc !default; +$pre-scrollable-max-height: 340px !default; + + +//== Type +// +//## + +//** Horizontal offset for forms and lists. +$component-offset-horizontal: 180px !default; +//** Text muted color +$text-muted: $gray-light !default; +//** Abbreviations and acronyms border color +$abbr-border-color: $gray-light !default; +//** Headings small color +$headings-small-color: $gray-light !default; +//** Blockquote small color +$blockquote-small-color: $gray-light !default; +//** Blockquote font size +$blockquote-font-size: ($font-size-base * 1.25) !default; +//** Blockquote border color +$blockquote-border-color: $gray-lighter !default; +//** Page header border color +$page-header-border-color: $gray-lighter !default; +//** Width of horizontal description list titles +$dl-horizontal-offset: $component-offset-horizontal !default; +//** Point at which .dl-horizontal becomes horizontal +$dl-horizontal-breakpoint: $grid-float-breakpoint !default; +//** Horizontal line color. +$hr-border: $gray-lighter !default; diff --git a/static/bootstrap/stylesheets/bootstrap/_wells.scss b/static/bootstrap/stylesheets/bootstrap/_wells.scss new file mode 100644 index 0000000..b865711 --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/_wells.scss @@ -0,0 +1,29 @@ +// +// Wells +// -------------------------------------------------- + + +// Base class +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: $well-bg; + border: 1px solid $well-border; + border-radius: $border-radius-base; + @include box-shadow(inset 0 1px 1px rgba(0,0,0,.05)); + blockquote { + border-color: #ddd; + border-color: rgba(0,0,0,.15); + } +} + +// Sizes +.well-lg { + padding: 24px; + border-radius: $border-radius-large; +} +.well-sm { + padding: 9px; + border-radius: $border-radius-small; +} diff --git a/static/bootstrap/stylesheets/bootstrap/mixins/_alerts.scss b/static/bootstrap/stylesheets/bootstrap/mixins/_alerts.scss new file mode 100644 index 0000000..3faf0b5 --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/mixins/_alerts.scss @@ -0,0 +1,14 @@ +// Alerts + +@mixin alert-variant($background, $border, $text-color) { + background-color: $background; + border-color: $border; + color: $text-color; + + hr { + border-top-color: darken($border, 5%); + } + .alert-link { + color: darken($text-color, 10%); + } +} diff --git a/static/bootstrap/stylesheets/bootstrap/mixins/_background-variant.scss b/static/bootstrap/stylesheets/bootstrap/mixins/_background-variant.scss new file mode 100644 index 0000000..4c7769e --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/mixins/_background-variant.scss @@ -0,0 +1,12 @@ +// Contextual backgrounds + +// [converter] $parent hack +@mixin bg-variant($parent, $color) { + #{$parent} { + background-color: $color; + } + a#{$parent}:hover, + a#{$parent}:focus { + background-color: darken($color, 10%); + } +} diff --git a/static/bootstrap/stylesheets/bootstrap/mixins/_border-radius.scss b/static/bootstrap/stylesheets/bootstrap/mixins/_border-radius.scss new file mode 100644 index 0000000..ce19499 --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/mixins/_border-radius.scss @@ -0,0 +1,18 @@ +// Single side border-radius + +@mixin border-top-radius($radius) { + border-top-right-radius: $radius; + border-top-left-radius: $radius; +} +@mixin border-right-radius($radius) { + border-bottom-right-radius: $radius; + border-top-right-radius: $radius; +} +@mixin border-bottom-radius($radius) { + border-bottom-right-radius: $radius; + border-bottom-left-radius: $radius; +} +@mixin border-left-radius($radius) { + border-bottom-left-radius: $radius; + border-top-left-radius: $radius; +} diff --git a/static/bootstrap/stylesheets/bootstrap/mixins/_buttons.scss b/static/bootstrap/stylesheets/bootstrap/mixins/_buttons.scss new file mode 100644 index 0000000..b93f84b --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/mixins/_buttons.scss @@ -0,0 +1,65 @@ +// Button variants +// +// Easily pump out default styles, as well as :hover, :focus, :active, +// and disabled options for all buttons + +@mixin button-variant($color, $background, $border) { + color: $color; + background-color: $background; + border-color: $border; + + &:focus, + &.focus { + color: $color; + background-color: darken($background, 10%); + border-color: darken($border, 25%); + } + &:hover { + color: $color; + background-color: darken($background, 10%); + border-color: darken($border, 12%); + } + &:active, + &.active, + .open > &.dropdown-toggle { + color: $color; + background-color: darken($background, 10%); + border-color: darken($border, 12%); + + &:hover, + &:focus, + &.focus { + color: $color; + background-color: darken($background, 17%); + border-color: darken($border, 25%); + } + } + &:active, + &.active, + .open > &.dropdown-toggle { + background-image: none; + } + &.disabled, + &[disabled], + fieldset[disabled] & { + &:hover, + &:focus, + &.focus { + background-color: $background; + border-color: $border; + } + } + + .badge { + color: $background; + background-color: $color; + } +} + +// Button sizes +@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) { + padding: $padding-vertical $padding-horizontal; + font-size: $font-size; + line-height: $line-height; + border-radius: $border-radius; +} diff --git a/static/bootstrap/stylesheets/bootstrap/mixins/_center-block.scss b/static/bootstrap/stylesheets/bootstrap/mixins/_center-block.scss new file mode 100644 index 0000000..e06fb5e --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/mixins/_center-block.scss @@ -0,0 +1,7 @@ +// Center-align a block level element + +@mixin center-block() { + display: block; + margin-left: auto; + margin-right: auto; +} diff --git a/static/bootstrap/stylesheets/bootstrap/mixins/_clearfix.scss b/static/bootstrap/stylesheets/bootstrap/mixins/_clearfix.scss new file mode 100644 index 0000000..dc3e2ab --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/mixins/_clearfix.scss @@ -0,0 +1,22 @@ +// Clearfix +// +// For modern browsers +// 1. The space content is one way to avoid an Opera bug when the +// contenteditable attribute is included anywhere else in the document. +// Otherwise it causes space to appear at the top and bottom of elements +// that are clearfixed. +// 2. The use of `table` rather than `block` is only necessary if using +// `:before` to contain the top-margins of child elements. +// +// Source: http://nicolasgallagher.com/micro-clearfix-hack/ + +@mixin clearfix() { + &:before, + &:after { + content: " "; // 1 + display: table; // 2 + } + &:after { + clear: both; + } +} diff --git a/static/bootstrap/stylesheets/bootstrap/mixins/_forms.scss b/static/bootstrap/stylesheets/bootstrap/mixins/_forms.scss new file mode 100644 index 0000000..277aa5f --- /dev/null +++ b/static/bootstrap/stylesheets/bootstrap/mixins/_forms.scss @@ -0,0 +1,88 @@ +// Form validation states +// +// Used in forms.less to generate the form validation CSS for warnings, errors, +// and successes. + +@mixin form-control-validation($text-color: #555, $border-color: #ccc, $background-color: #f5f5f5) { + // Color the label and help text + .help-block, + .control-label, + .radio, + .checkbox, + .radio-inline, + .checkbox-inline, + &.radio label, + &.checkbox label, + &.radio-inline label, + &.checkbox-inline label { + color: $text-color; + } + // Set the border and box shadow on specific inputs to match + .form-control { + border-color: $border-color; + @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work + &:focus { + border-color: darken($border-color, 10%); + $shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($border-color, 20%); + @include box-shadow($shadow); + } + } + // Set validation states also for addons + .input-group-addon { + color: $text-color; + border-color: $border-color; + background-color: $background-color; + } + // Optional feedback icon + .form-control-feedback { + color: $text-color; + } +} + + +// Form control focus state +// +// Generate a customized focus state and for any input with the specified color, +// which defaults to the `$input-border-focus` variable. +// +// We highly encourage you to not customize the default value, but instead use +// this to tweak colors on an as-needed basis. This aesthetic change is based on +// WebKit's default styles, but applicable to a wider range of browsers. Its +// usability and accessibility should be taken into account with any change. +// +// Example usage: change the default blue border and shadow to white for better +// contrast against a dark gray background. +@mixin form-control-focus($color: $input-border-focus) { + $color-rgba: rgba(red($color), green($color), blue($color), .6); + &:focus { + border-color: $color; + outline: 0; + @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px $color-rgba); + } +} + +// Form control sizing +// +// Relative text size, padding, and border-radii changes for form controls. For +// horizontal sizing, wrap controls in the predefined grid classes. `",t.querySelectorAll("[msallowcapture^='']").length&&R.push("[*^$]="+nt+"*(?:''|\"\")"),t.querySelectorAll("[selected]").length||R.push("\\["+nt+"*(?:value|"+et+")"),t.querySelectorAll("[id~="+F+"-]").length||R.push("~="),t.querySelectorAll(":checked").length||R.push(":checked"),t.querySelectorAll("a#"+F+"+*").length||R.push(".#.+[+~]")}),o(function(t){var e=O.createElement("input");e.setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),t.querySelectorAll("[name=d]").length&&R.push("name"+nt+"*[*^$|!~]?="),t.querySelectorAll(":enabled").length||R.push(":enabled",":disabled"),t.querySelectorAll("*,:x"),R.push(",.*:")})),(w.matchesSelector=vt.test(H=I.matches||I.webkitMatchesSelector||I.mozMatchesSelector||I.oMatchesSelector||I.msMatchesSelector))&&o(function(t){w.disconnectedMatch=H.call(t,"div"),H.call(t,"[s!='']:x"),q.push("!=",rt)}),R=R.length&&new RegExp(R.join("|")),q=q.length&&new RegExp(q.join("|")),e=vt.test(I.compareDocumentPosition),P=e||vt.test(I.contains)?function(t,e){var n=9===t.nodeType?t.documentElement:t,i=e&&e.parentNode;return t===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):t.compareDocumentPosition&&16&t.compareDocumentPosition(i)))}:function(t,e){if(e)for(;e=e.parentNode;)if(e===t)return!0;return!1},V=e?function(t,e){if(t===e)return j=!0,0;var n=!t.compareDocumentPosition-!e.compareDocumentPosition;return n?n:(n=(t.ownerDocument||t)===(e.ownerDocument||e)?t.compareDocumentPosition(e):1,1&n||!w.sortDetached&&e.compareDocumentPosition(t)===n?t===O||t.ownerDocument===M&&P(M,t)?-1:e===O||e.ownerDocument===M&&P(M,e)?1:D?tt(D,t)-tt(D,e):0:4&n?-1:1)}:function(t,e){if(t===e)return j=!0,0;var n,i=0,o=t.parentNode,r=e.parentNode,a=[t],l=[e];if(!o||!r)return t===O?-1:e===O?1:o?-1:r?1:D?tt(D,t)-tt(D,e):0;if(o===r)return s(t,e);for(n=t;n=n.parentNode;)a.unshift(n);for(n=e;n=n.parentNode;)l.unshift(n);for(;a[i]===l[i];)i++;return i?s(a[i],l[i]):a[i]===M?-1:l[i]===M?1:0},O):O},e.matches=function(t,n){return e(t,null,null,n)},e.matchesSelector=function(t,n){if((t.ownerDocument||t)!==O&&A(t),n=n.replace(ct,"='$1']"), -w.matchesSelector&&L&&!z[n+" "]&&(!q||!q.test(n))&&(!R||!R.test(n)))try{var i=H.call(t,n);if(i||w.disconnectedMatch||t.document&&11!==t.document.nodeType)return i}catch(o){}return e(n,O,null,[t]).length>0},e.contains=function(t,e){return(t.ownerDocument||t)!==O&&A(t),P(t,e)},e.attr=function(t,e){(t.ownerDocument||t)!==O&&A(t);var n=T.attrHandle[e.toLowerCase()],i=n&&Q.call(T.attrHandle,e.toLowerCase())?n(t,e,!L):void 0;return void 0!==i?i:w.attributes||!L?t.getAttribute(e):(i=t.getAttributeNode(e))&&i.specified?i.value:null},e.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},e.uniqueSort=function(t){var e,n=[],i=0,o=0;if(j=!w.detectDuplicates,D=!w.sortStable&&t.slice(0),t.sort(V),j){for(;e=t[o++];)e===t[o]&&(i=n.push(o));for(;i--;)t.splice(n[i],1)}return D=null,t},C=e.getText=function(t){var e,n="",i=0,o=t.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof t.textContent)return t.textContent;for(t=t.firstChild;t;t=t.nextSibling)n+=C(t)}else if(3===o||4===o)return t.nodeValue}else for(;e=t[i++];)n+=C(e);return n},T=e.selectors={cacheLength:50,createPseudo:i,match:dt,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(xt,wt),t[3]=(t[3]||t[4]||t[5]||"").replace(xt,wt),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||e.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&e.error(t[0]),t},PSEUDO:function(t){var e,n=!t[6]&&t[2];return dt.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":n&&ft.test(n)&&(e=k(n,!0))&&(e=n.indexOf(")",n.length-e)-n.length)&&(t[0]=t[0].slice(0,e),t[2]=n.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(xt,wt).toLowerCase();return"*"===t?function(){return!0}:function(t){return t.nodeName&&t.nodeName.toLowerCase()===e}},CLASS:function(t){var e=B[t+" "];return e||(e=new RegExp("(^|"+nt+")"+t+"("+nt+"|$)"))&&B(t,function(t){return e.test("string"==typeof t.className&&t.className||"undefined"!=typeof t.getAttribute&&t.getAttribute("class")||"")})},ATTR:function(t,n,i){return function(o){var r=e.attr(o,t);return null==r?"!="===n:n?(r+="","="===n?r===i:"!="===n?r!==i:"^="===n?i&&0===r.indexOf(i):"*="===n?i&&r.indexOf(i)>-1:"$="===n?i&&r.slice(-i.length)===i:"~="===n?(" "+r.replace(st," ")+" ").indexOf(i)>-1:"|="===n?r===i||r.slice(0,i.length+1)===i+"-":!1):!0}},CHILD:function(t,e,n,i,o){var r="nth"!==t.slice(0,3),s="last"!==t.slice(-4),a="of-type"===e;return 1===i&&0===o?function(t){return!!t.parentNode}:function(e,n,l){var u,c,f,p,d,h,g=r!==s?"nextSibling":"previousSibling",v=e.parentNode,m=a&&e.nodeName.toLowerCase(),y=!l&&!a,b=!1;if(v){if(r){for(;g;){for(p=e;p=p[g];)if(a?p.nodeName.toLowerCase()===m:1===p.nodeType)return!1;h=g="only"===t&&!h&&"nextSibling"}return!0}if(h=[s?v.firstChild:v.lastChild],s&&y){for(p=v,f=p[F]||(p[F]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),u=c[t]||[],d=u[0]===W&&u[1],b=d&&u[2],p=d&&v.childNodes[d];p=++d&&p&&p[g]||(b=d=0)||h.pop();)if(1===p.nodeType&&++b&&p===e){c[t]=[W,d,b];break}}else if(y&&(p=e,f=p[F]||(p[F]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),u=c[t]||[],d=u[0]===W&&u[1],b=d),b===!1)for(;(p=++d&&p&&p[g]||(b=d=0)||h.pop())&&((a?p.nodeName.toLowerCase()!==m:1!==p.nodeType)||!++b||(y&&(f=p[F]||(p[F]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),c[t]=[W,b]),p!==e)););return b-=o,b===i||b%i===0&&b/i>=0}}},PSEUDO:function(t,n){var o,r=T.pseudos[t]||T.setFilters[t.toLowerCase()]||e.error("unsupported pseudo: "+t);return r[F]?r(n):r.length>1?(o=[t,t,"",n],T.setFilters.hasOwnProperty(t.toLowerCase())?i(function(t,e){for(var i,o=r(t,n),s=o.length;s--;)i=tt(t,o[s]),t[i]=!(e[i]=o[s])}):function(t){return r(t,0,o)}):r}},pseudos:{not:i(function(t){var e=[],n=[],o=$(t.replace(at,"$1"));return o[F]?i(function(t,e,n,i){for(var r,s=o(t,null,i,[]),a=t.length;a--;)(r=s[a])&&(t[a]=!(e[a]=r))}):function(t,i,r){return e[0]=t,o(e,null,r,n),e[0]=null,!n.pop()}}),has:i(function(t){return function(n){return e(t,n).length>0}}),contains:i(function(t){return t=t.replace(xt,wt),function(e){return(e.textContent||e.innerText||C(e)).indexOf(t)>-1}}),lang:i(function(t){return pt.test(t||"")||e.error("unsupported lang: "+t),t=t.replace(xt,wt).toLowerCase(),function(e){var n;do if(n=L?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return n=n.toLowerCase(),n===t||0===n.indexOf(t+"-");while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var n=t.location&&t.location.hash;return n&&n.slice(1)===e.id},root:function(t){return t===I},focus:function(t){return t===O.activeElement&&(!O.hasFocus||O.hasFocus())&&!!(t.type||t.href||~t.tabIndex)},enabled:function(t){return t.disabled===!1},disabled:function(t){return t.disabled===!0},checked:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&!!t.checked||"option"===e&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,t.selected===!0},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!T.pseudos.empty(t)},header:function(t){return gt.test(t.nodeName)},input:function(t){return ht.test(t.nodeName)},button:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&"button"===t.type||"button"===e},text:function(t){var e;return"input"===t.nodeName.toLowerCase()&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:u(function(){return[0]}),last:u(function(t,e){return[e-1]}),eq:u(function(t,e,n){return[0>n?n+e:n]}),even:u(function(t,e){for(var n=0;e>n;n+=2)t.push(n);return t}),odd:u(function(t,e){for(var n=1;e>n;n+=2)t.push(n);return t}),lt:u(function(t,e,n){for(var i=0>n?n+e:n;--i>=0;)t.push(i);return t}),gt:u(function(t,e,n){for(var i=0>n?n+e:n;++i2&&"ID"===(s=r[0]).type&&w.getById&&9===e.nodeType&&L&&T.relative[r[1].type]){if(e=(T.find.ID(s.matches[0].replace(xt,wt),e)||[])[0],!e)return n;u&&(e=e.parentNode),t=t.slice(r.shift().value.length)}for(o=dt.needsContext.test(t)?0:r.length;o--&&(s=r[o],!T.relative[a=s.type]);)if((l=T.find[a])&&(i=l(s.matches[0].replace(xt,wt),yt.test(r[0].type)&&c(e.parentNode)||e))){if(r.splice(o,1),t=i.length&&p(r),!t)return J.apply(n,i),n;break}}return(u||$(t,f))(i,e,!L,n,!e||yt.test(t)&&c(e.parentNode)||e),n},w.sortStable=F.split("").sort(V).join("")===F,w.detectDuplicates=!!j,A(),w.sortDetached=o(function(t){return 1&t.compareDocumentPosition(O.createElement("div"))}),o(function(t){return t.innerHTML="","#"===t.firstChild.getAttribute("href")})||r("type|href|height|width",function(t,e,n){return n?void 0:t.getAttribute(e,"type"===e.toLowerCase()?1:2)}),w.attributes&&o(function(t){return t.innerHTML="",t.firstChild.setAttribute("value",""),""===t.firstChild.getAttribute("value")})||r("value",function(t,e,n){return n||"input"!==t.nodeName.toLowerCase()?void 0:t.defaultValue}),o(function(t){return null==t.getAttribute("disabled")})||r(et,function(t,e,n){var i;return n?void 0:t[e]===!0?e.toLowerCase():(i=t.getAttributeNode(e))&&i.specified?i.value:null}),e}(t);rt.find=ct,rt.expr=ct.selectors,rt.expr[":"]=rt.expr.pseudos,rt.uniqueSort=rt.unique=ct.uniqueSort,rt.text=ct.getText,rt.isXMLDoc=ct.isXML,rt.contains=ct.contains;var ft=function(t,e,n){for(var i=[],o=void 0!==n;(t=t[e])&&9!==t.nodeType;)if(1===t.nodeType){if(o&&rt(t).is(n))break;i.push(t)}return i},pt=function(t,e){for(var n=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&n.push(t);return n},dt=rt.expr.match.needsContext,ht=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,gt=/^.[^:#\[\.,]*$/;rt.filter=function(t,e,n){var i=e[0];return n&&(t=":not("+t+")"),1===e.length&&1===i.nodeType?rt.find.matchesSelector(i,t)?[i]:[]:rt.find.matches(t,rt.grep(e,function(t){return 1===t.nodeType}))},rt.fn.extend({find:function(t){var e,n=this.length,i=[],o=this;if("string"!=typeof t)return this.pushStack(rt(t).filter(function(){for(e=0;n>e;e++)if(rt.contains(o[e],this))return!0}));for(e=0;n>e;e++)rt.find(t,o[e],i);return i=this.pushStack(n>1?rt.unique(i):i),i.selector=this.selector?this.selector+" "+t:t,i},filter:function(t){return this.pushStack(i(this,t||[],!1))},not:function(t){return this.pushStack(i(this,t||[],!0))},is:function(t){return!!i(this,"string"==typeof t&&dt.test(t)?rt(t):t||[],!1).length}});var vt,mt=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,yt=rt.fn.init=function(t,e,n){var i,o;if(!t)return this;if(n=n||vt,"string"==typeof t){if(i="<"===t[0]&&">"===t[t.length-1]&&t.length>=3?[null,t,null]:mt.exec(t),!i||!i[1]&&e)return!e||e.jquery?(e||n).find(t):this.constructor(e).find(t);if(i[1]){if(e=e instanceof rt?e[0]:e,rt.merge(this,rt.parseHTML(i[1],e&&e.nodeType?e.ownerDocument||e:Y,!0)),ht.test(i[1])&&rt.isPlainObject(e))for(i in e)rt.isFunction(this[i])?this[i](e[i]):this.attr(i,e[i]);return this}return o=Y.getElementById(i[2]),o&&o.parentNode&&(this.length=1,this[0]=o),this.context=Y,this.selector=t,this}return t.nodeType?(this.context=this[0]=t,this.length=1,this):rt.isFunction(t)?void 0!==n.ready?n.ready(t):t(rt):(void 0!==t.selector&&(this.selector=t.selector,this.context=t.context),rt.makeArray(t,this))};yt.prototype=rt.fn,vt=rt(Y);var bt=/^(?:parents|prev(?:Until|All))/,xt={children:!0,contents:!0,next:!0,prev:!0};rt.fn.extend({has:function(t){var e=rt(t,this),n=e.length;return this.filter(function(){for(var t=0;n>t;t++)if(rt.contains(this,e[t]))return!0})},closest:function(t,e){for(var n,i=0,o=this.length,r=[],s=dt.test(t)||"string"!=typeof t?rt(t,e||this.context):0;o>i;i++)for(n=this[i];n&&n!==e;n=n.parentNode)if(n.nodeType<11&&(s?s.index(n)>-1:1===n.nodeType&&rt.find.matchesSelector(n,t))){r.push(n);break}return this.pushStack(r.length>1?rt.uniqueSort(r):r)},index:function(t){return t?"string"==typeof t?Z.call(rt(t),this[0]):Z.call(this,t.jquery?t[0]:t):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(rt.uniqueSort(rt.merge(this.get(),rt(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),rt.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return ft(t,"parentNode")},parentsUntil:function(t,e,n){return ft(t,"parentNode",n)},next:function(t){return o(t,"nextSibling")},prev:function(t){return o(t,"previousSibling")},nextAll:function(t){return ft(t,"nextSibling")},prevAll:function(t){return ft(t,"previousSibling")},nextUntil:function(t,e,n){return ft(t,"nextSibling",n)},prevUntil:function(t,e,n){return ft(t,"previousSibling",n)},siblings:function(t){return pt((t.parentNode||{}).firstChild,t)},children:function(t){return pt(t.firstChild)},contents:function(t){return t.contentDocument||rt.merge([],t.childNodes)}},function(t,e){rt.fn[t]=function(n,i){var o=rt.map(this,e,n);return"Until"!==t.slice(-5)&&(i=n),i&&"string"==typeof i&&(o=rt.filter(i,o)),this.length>1&&(xt[t]||rt.uniqueSort(o),bt.test(t)&&o.reverse()),this.pushStack(o)}});var wt=/\S+/g;rt.Callbacks=function(t){t="string"==typeof t?r(t):rt.extend({},t);var e,n,i,o,s=[],a=[],l=-1,u=function(){for(o=t.once,i=e=!0;a.length;l=-1)for(n=a.shift();++l-1;)s.splice(n,1),l>=n&&l--}),this},has:function(t){return t?rt.inArray(t,s)>-1:s.length>0},empty:function(){return s&&(s=[]),this},disable:function(){return o=a=[],s=n="",this},disabled:function(){return!s},lock:function(){return o=a=[],n||(s=n=""),this},locked:function(){return!!o},fireWith:function(t,n){return o||(n=n||[],n=[t,n.slice?n.slice():n],a.push(n),e||u()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!i}};return c},rt.extend({Deferred:function(t){var e=[["resolve","done",rt.Callbacks("once memory"),"resolved"],["reject","fail",rt.Callbacks("once memory"),"rejected"],["notify","progress",rt.Callbacks("memory")]],n="pending",i={state:function(){return n},always:function(){return o.done(arguments).fail(arguments),this},then:function(){var t=arguments;return rt.Deferred(function(n){rt.each(e,function(e,r){var s=rt.isFunction(t[e])&&t[e];o[r[1]](function(){var t=s&&s.apply(this,arguments);t&&rt.isFunction(t.promise)?t.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this===i?n.promise():this,s?[t]:arguments)})}),t=null}).promise()},promise:function(t){return null!=t?rt.extend(t,i):i}},o={};return i.pipe=i.then,rt.each(e,function(t,r){var s=r[2],a=r[3];i[r[1]]=s.add,a&&s.add(function(){n=a},e[1^t][2].disable,e[2][2].lock),o[r[0]]=function(){return o[r[0]+"With"](this===o?i:this,arguments),this},o[r[0]+"With"]=s.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(t){var e,n,i,o=0,r=G.call(arguments),s=r.length,a=1!==s||t&&rt.isFunction(t.promise)?s:0,l=1===a?t:rt.Deferred(),u=function(t,n,i){return function(o){n[t]=this,i[t]=arguments.length>1?G.call(arguments):o,i===e?l.notifyWith(n,i):--a||l.resolveWith(n,i)}};if(s>1)for(e=new Array(s),n=new Array(s),i=new Array(s);s>o;o++)r[o]&&rt.isFunction(r[o].promise)?r[o].promise().progress(u(o,n,e)).done(u(o,i,r)).fail(l.reject):--a;return a||l.resolveWith(i,r),l.promise()}});var Tt;rt.fn.ready=function(t){return rt.ready.promise().done(t),this},rt.extend({isReady:!1,readyWait:1,holdReady:function(t){t?rt.readyWait++:rt.ready(!0)},ready:function(t){(t===!0?--rt.readyWait:rt.isReady)||(rt.isReady=!0,t!==!0&&--rt.readyWait>0||(Tt.resolveWith(Y,[rt]),rt.fn.triggerHandler&&(rt(Y).triggerHandler("ready"),rt(Y).off("ready"))))}}),rt.ready.promise=function(e){return Tt||(Tt=rt.Deferred(),"complete"===Y.readyState||"loading"!==Y.readyState&&!Y.documentElement.doScroll?t.setTimeout(rt.ready):(Y.addEventListener("DOMContentLoaded",s),t.addEventListener("load",s))),Tt.promise(e)},rt.ready.promise();var Ct=function(t,e,n,i,o,r,s){var a=0,l=t.length,u=null==n;if("object"===rt.type(n)){o=!0;for(a in n)Ct(t,e,a,n[a],!0,r,s)}else if(void 0!==i&&(o=!0,rt.isFunction(i)||(s=!0),u&&(s?(e.call(t,i),e=null):(u=e,e=function(t,e,n){return u.call(rt(t),n)})),e))for(;l>a;a++)e(t[a],n,s?i:i.call(t[a],a,e(t[a],n)));return o?t:u?e.call(t):l?e(t[0],n):r},Et=function(t){return 1===t.nodeType||9===t.nodeType||!+t.nodeType};a.uid=1,a.prototype={register:function(t,e){var n=e||{};return t.nodeType?t[this.expando]=n:Object.defineProperty(t,this.expando,{value:n,writable:!0,configurable:!0}),t[this.expando]},cache:function(t){if(!Et(t))return{};var e=t[this.expando];return e||(e={},Et(t)&&(t.nodeType?t[this.expando]=e:Object.defineProperty(t,this.expando,{value:e,configurable:!0}))),e},set:function(t,e,n){var i,o=this.cache(t);if("string"==typeof e)o[e]=n;else for(i in e)o[i]=e[i];return o},get:function(t,e){return void 0===e?this.cache(t):t[this.expando]&&t[this.expando][e]},access:function(t,e,n){var i;return void 0===e||e&&"string"==typeof e&&void 0===n?(i=this.get(t,e),void 0!==i?i:this.get(t,rt.camelCase(e))):(this.set(t,e,n),void 0!==n?n:e)},remove:function(t,e){var n,i,o,r=t[this.expando];if(void 0!==r){if(void 0===e)this.register(t);else{rt.isArray(e)?i=e.concat(e.map(rt.camelCase)):(o=rt.camelCase(e),e in r?i=[e,o]:(i=o,i=i in r?[i]:i.match(wt)||[])),n=i.length;for(;n--;)delete r[i[n]]}(void 0===e||rt.isEmptyObject(r))&&(t.nodeType?t[this.expando]=void 0:delete t[this.expando])}},hasData:function(t){var e=t[this.expando];return void 0!==e&&!rt.isEmptyObject(e)}};var kt=new a,$t=new a,St=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Nt=/[A-Z]/g;rt.extend({hasData:function(t){return $t.hasData(t)||kt.hasData(t)},data:function(t,e,n){return $t.access(t,e,n)},removeData:function(t,e){$t.remove(t,e)},_data:function(t,e,n){return kt.access(t,e,n)},_removeData:function(t,e){kt.remove(t,e)}}),rt.fn.extend({data:function(t,e){var n,i,o,r=this[0],s=r&&r.attributes;if(void 0===t){if(this.length&&(o=$t.get(r),1===r.nodeType&&!kt.get(r,"hasDataAttrs"))){for(n=s.length;n--;)s[n]&&(i=s[n].name,0===i.indexOf("data-")&&(i=rt.camelCase(i.slice(5)),l(r,i,o[i])));kt.set(r,"hasDataAttrs",!0)}return o}return"object"==typeof t?this.each(function(){$t.set(this,t)}):Ct(this,function(e){var n,i;if(r&&void 0===e){if(n=$t.get(r,t)||$t.get(r,t.replace(Nt,"-$&").toLowerCase()),void 0!==n)return n;if(i=rt.camelCase(t),n=$t.get(r,i),void 0!==n)return n;if(n=l(r,i,void 0),void 0!==n)return n}else i=rt.camelCase(t),this.each(function(){var n=$t.get(this,i);$t.set(this,i,e),t.indexOf("-")>-1&&void 0!==n&&$t.set(this,t,e)})},null,e,arguments.length>1,null,!0)},removeData:function(t){return this.each(function(){$t.remove(this,t)})}}),rt.extend({queue:function(t,e,n){var i;return t?(e=(e||"fx")+"queue",i=kt.get(t,e),n&&(!i||rt.isArray(n)?i=kt.access(t,e,rt.makeArray(n)):i.push(n)),i||[]):void 0},dequeue:function(t,e){e=e||"fx";var n=rt.queue(t,e),i=n.length,o=n.shift(),r=rt._queueHooks(t,e),s=function(){rt.dequeue(t,e)};"inprogress"===o&&(o=n.shift(),i--),o&&("fx"===e&&n.unshift("inprogress"),delete r.stop,o.call(t,s,r)),!i&&r&&r.empty.fire()},_queueHooks:function(t,e){var n=e+"queueHooks";return kt.get(t,n)||kt.access(t,n,{empty:rt.Callbacks("once memory").add(function(){kt.remove(t,[e+"queue",n])})})}}),rt.fn.extend({queue:function(t,e){var n=2;return"string"!=typeof t&&(e=t,t="fx",n--),arguments.length",""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};qt.optgroup=qt.option,qt.tbody=qt.tfoot=qt.colgroup=qt.caption=qt.thead,qt.th=qt.td;var Ht=/<|&#?\w+;/;!function(){var t=Y.createDocumentFragment(),e=t.appendChild(Y.createElement("div")),n=Y.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),e.appendChild(n),it.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",it.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var Pt=/^key/,Ft=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Mt=/^([^.]*)(?:\.(.+)|)/;rt.event={global:{},add:function(t,e,n,i,o){var r,s,a,l,u,c,f,p,d,h,g,v=kt.get(t);if(v)for(n.handler&&(r=n,n=r.handler,o=r.selector),n.guid||(n.guid=rt.guid++),(l=v.events)||(l=v.events={}),(s=v.handle)||(s=v.handle=function(e){return"undefined"!=typeof rt&&rt.event.triggered!==e.type?rt.event.dispatch.apply(t,arguments):void 0}),e=(e||"").match(wt)||[""],u=e.length;u--;)a=Mt.exec(e[u])||[],d=g=a[1],h=(a[2]||"").split(".").sort(),d&&(f=rt.event.special[d]||{},d=(o?f.delegateType:f.bindType)||d,f=rt.event.special[d]||{},c=rt.extend({type:d,origType:g,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&rt.expr.match.needsContext.test(o),namespace:h.join(".")},r),(p=l[d])||(p=l[d]=[],p.delegateCount=0,f.setup&&f.setup.call(t,i,h,s)!==!1||t.addEventListener&&t.addEventListener(d,s)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),o?p.splice(p.delegateCount++,0,c):p.push(c),rt.event.global[d]=!0)},remove:function(t,e,n,i,o){var r,s,a,l,u,c,f,p,d,h,g,v=kt.hasData(t)&&kt.get(t);if(v&&(l=v.events)){for(e=(e||"").match(wt)||[""],u=e.length;u--;)if(a=Mt.exec(e[u])||[],d=g=a[1],h=(a[2]||"").split(".").sort(),d){for(f=rt.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,p=l[d]||[],a=a[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=r=p.length;r--;)c=p[r],!o&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(p.splice(r,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(t,c));s&&!p.length&&(f.teardown&&f.teardown.call(t,h,v.handle)!==!1||rt.removeEvent(t,d,v.handle),delete l[d])}else for(d in l)rt.event.remove(t,d+e[u],n,i,!0);rt.isEmptyObject(l)&&kt.remove(t,"handle events")}},dispatch:function(t){t=rt.event.fix(t);var e,n,i,o,r,s=[],a=G.call(arguments),l=(kt.get(this,"events")||{})[t.type]||[],u=rt.event.special[t.type]||{};if(a[0]=t,t.delegateTarget=this,!u.preDispatch||u.preDispatch.call(this,t)!==!1){for(s=rt.event.handlers.call(this,t,l),e=0;(o=s[e++])&&!t.isPropagationStopped();)for(t.currentTarget=o.elem,n=0;(r=o.handlers[n++])&&!t.isImmediatePropagationStopped();)t.rnamespace&&!t.rnamespace.test(r.namespace)||(t.handleObj=r,t.data=r.data,i=((rt.event.special[r.origType]||{}).handle||r.handler).apply(o.elem,a),void 0!==i&&(t.result=i)===!1&&(t.preventDefault(),t.stopPropagation()));return u.postDispatch&&u.postDispatch.call(this,t),t.result}},handlers:function(t,e){var n,i,o,r,s=[],a=e.delegateCount,l=t.target;if(a&&l.nodeType&&("click"!==t.type||isNaN(t.button)||t.button<1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==t.type)){for(i=[],n=0;a>n;n++)r=e[n],o=r.selector+" ",void 0===i[o]&&(i[o]=r.needsContext?rt(o,this).index(l)>-1:rt.find(o,this,null,[l]).length),i[o]&&i.push(r);i.length&&s.push({elem:l,handlers:i})}return a]*)\/>/gi,_t=/\s*$/g;rt.extend({htmlPrefilter:function(t){return t.replace(Wt,"<$1>")},clone:function(t,e,n){var i,o,r,s,a=t.cloneNode(!0),l=rt.contains(t.ownerDocument,t);if(!(it.noCloneChecked||1!==t.nodeType&&11!==t.nodeType||rt.isXMLDoc(t)))for(s=c(a),r=c(t),i=0,o=r.length;o>i;i++)w(r[i],s[i]);if(e)if(n)for(r=r||c(t),s=s||c(a),i=0,o=r.length;o>i;i++)x(r[i],s[i]);else x(t,a);return s=c(a,"script"),s.length>0&&f(s,!l&&c(t,"script")),a},cleanData:function(t){for(var e,n,i,o=rt.event.special,r=0;void 0!==(n=t[r]);r++)if(Et(n)){if(e=n[kt.expando]){if(e.events)for(i in e.events)o[i]?rt.event.remove(n,i):rt.removeEvent(n,i,e.handle);n[kt.expando]=void 0}n[$t.expando]&&(n[$t.expando]=void 0)}}}),rt.fn.extend({domManip:T,detach:function(t){return C(this,t,!0)},remove:function(t){return C(this,t)},text:function(t){return Ct(this,function(t){return void 0===t?rt.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=t)})},null,t,arguments.length)},append:function(){return T(this,arguments,function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=m(this,t);e.appendChild(t)}})},prepend:function(){return T(this,arguments,function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=m(this,t);e.insertBefore(t,e.firstChild)}})},before:function(){return T(this,arguments,function(t){this.parentNode&&this.parentNode.insertBefore(t,this)})},after:function(){return T(this,arguments,function(t){this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling)})},empty:function(){for(var t,e=0;null!=(t=this[e]);e++)1===t.nodeType&&(rt.cleanData(c(t,!1)),t.textContent="");return this},clone:function(t,e){return t=null==t?!1:t,e=null==e?t:e,this.map(function(){return rt.clone(this,t,e)})},html:function(t){return Ct(this,function(t){var e=this[0]||{},n=0,i=this.length;if(void 0===t&&1===e.nodeType)return e.innerHTML;if("string"==typeof t&&!_t.test(t)&&!qt[(Lt.exec(t)||["",""])[1].toLowerCase()]){t=rt.htmlPrefilter(t);try{for(;i>n;n++)e=this[n]||{},1===e.nodeType&&(rt.cleanData(c(e,!1)),e.innerHTML=t);e=0}catch(o){}}e&&this.empty().append(t)},null,t,arguments.length)},replaceWith:function(){var t=[];return T(this,arguments,function(e){var n=this.parentNode;rt.inArray(this,t)<0&&(rt.cleanData(c(this)),n&&n.replaceChild(e,this))},t)}}),rt.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(t,e){rt.fn[t]=function(t){for(var n,i=[],o=rt(t),r=o.length-1,s=0;r>=s;s++)n=s===r?this:this.clone(!0),rt(o[s])[e](n),J.apply(i,n.get());return this.pushStack(i)}});var Vt,Xt={HTML:"block",BODY:"block"},Qt=/^margin/,Yt=new RegExp("^("+Dt+")(?!px)[a-z%]+$","i"),Gt=function(e){var n=e.ownerDocument.defaultView;return n&&n.opener||(n=t),n.getComputedStyle(e)},Kt=function(t,e,n,i){var o,r,s={};for(r in e)s[r]=t.style[r],t.style[r]=e[r];o=n.apply(t,i||[]);for(r in e)t.style[r]=s[r];return o},Jt=Y.documentElement;!function(){function e(){a.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",a.innerHTML="",Jt.appendChild(s);var e=t.getComputedStyle(a);n="1%"!==e.top,r="2px"===e.marginLeft,i="4px"===e.width,a.style.marginRight="50%",o="4px"===e.marginRight,Jt.removeChild(s)}var n,i,o,r,s=Y.createElement("div"),a=Y.createElement("div");a.style&&(a.style.backgroundClip="content-box",a.cloneNode(!0).style.backgroundClip="",it.clearCloneStyle="content-box"===a.style.backgroundClip,s.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",s.appendChild(a),rt.extend(it,{pixelPosition:function(){return e(),n},boxSizingReliable:function(){return null==i&&e(),i},pixelMarginRight:function(){return null==i&&e(),o},reliableMarginLeft:function(){return null==i&&e(),r},reliableMarginRight:function(){var e,n=a.appendChild(Y.createElement("div"));return n.style.cssText=a.style.cssText="-webkit-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",n.style.marginRight=n.style.width="0",a.style.width="1px",Jt.appendChild(s),e=!parseFloat(t.getComputedStyle(n).marginRight),Jt.removeChild(s),a.removeChild(n),e}}))}();var Zt=/^(none|table(?!-c[ea]).+)/,te={position:"absolute",visibility:"hidden",display:"block"},ee={letterSpacing:"0",fontWeight:"400"},ne=["Webkit","O","Moz","ms"],ie=Y.createElement("div").style;rt.extend({cssHooks:{opacity:{get:function(t,e){if(e){var n=$(t,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(t,e,n,i){if(t&&3!==t.nodeType&&8!==t.nodeType&&t.style){var o,r,s,a=rt.camelCase(e),l=t.style;return e=rt.cssProps[a]||(rt.cssProps[a]=N(a)||a),s=rt.cssHooks[e]||rt.cssHooks[a],void 0===n?s&&"get"in s&&void 0!==(o=s.get(t,!1,i))?o:l[e]:(r=typeof n,"string"===r&&(o=jt.exec(n))&&o[1]&&(n=u(t,e,o),r="number"),null!=n&&n===n&&("number"===r&&(n+=o&&o[3]||(rt.cssNumber[a]?"":"px")),it.clearCloneStyle||""!==n||0!==e.indexOf("background")||(l[e]="inherit"),s&&"set"in s&&void 0===(n=s.set(t,n,i))||(l[e]=n)), -void 0)}},css:function(t,e,n,i){var o,r,s,a=rt.camelCase(e);return e=rt.cssProps[a]||(rt.cssProps[a]=N(a)||a),s=rt.cssHooks[e]||rt.cssHooks[a],s&&"get"in s&&(o=s.get(t,!0,n)),void 0===o&&(o=$(t,e,i)),"normal"===o&&e in ee&&(o=ee[e]),""===n||n?(r=parseFloat(o),n===!0||isFinite(r)?r||0:o):o}}),rt.each(["height","width"],function(t,e){rt.cssHooks[e]={get:function(t,n,i){return n?Zt.test(rt.css(t,"display"))&&0===t.offsetWidth?Kt(t,te,function(){return A(t,e,i)}):A(t,e,i):void 0},set:function(t,n,i){var o,r=i&&Gt(t),s=i&&j(t,e,i,"border-box"===rt.css(t,"boxSizing",!1,r),r);return s&&(o=jt.exec(n))&&"px"!==(o[3]||"px")&&(t.style[e]=n,n=rt.css(t,e)),D(t,n,s)}}}),rt.cssHooks.marginLeft=S(it.reliableMarginLeft,function(t,e){return e?(parseFloat($(t,"marginLeft"))||t.getBoundingClientRect().left-Kt(t,{marginLeft:0},function(){return t.getBoundingClientRect().left}))+"px":void 0}),rt.cssHooks.marginRight=S(it.reliableMarginRight,function(t,e){return e?Kt(t,{display:"inline-block"},$,[t,"marginRight"]):void 0}),rt.each({margin:"",padding:"",border:"Width"},function(t,e){rt.cssHooks[t+e]={expand:function(n){for(var i=0,o={},r="string"==typeof n?n.split(" "):[n];4>i;i++)o[t+At[i]+e]=r[i]||r[i-2]||r[0];return o}},Qt.test(t)||(rt.cssHooks[t+e].set=D)}),rt.fn.extend({css:function(t,e){return Ct(this,function(t,e,n){var i,o,r={},s=0;if(rt.isArray(e)){for(i=Gt(t),o=e.length;o>s;s++)r[e[s]]=rt.css(t,e[s],!1,i);return r}return void 0!==n?rt.style(t,e,n):rt.css(t,e)},t,e,arguments.length>1)},show:function(){return O(this,!0)},hide:function(){return O(this)},toggle:function(t){return"boolean"==typeof t?t?this.show():this.hide():this.each(function(){Ot(this)?rt(this).show():rt(this).hide()})}}),rt.Tween=I,I.prototype={constructor:I,init:function(t,e,n,i,o,r){this.elem=t,this.prop=n,this.easing=o||rt.easing._default,this.options=e,this.start=this.now=this.cur(),this.end=i,this.unit=r||(rt.cssNumber[n]?"":"px")},cur:function(){var t=I.propHooks[this.prop];return t&&t.get?t.get(this):I.propHooks._default.get(this)},run:function(t){var e,n=I.propHooks[this.prop];return this.options.duration?this.pos=e=rt.easing[this.easing](t,this.options.duration*t,0,1,this.options.duration):this.pos=e=t,this.now=(this.end-this.start)*e+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):I.propHooks._default.set(this),this}},I.prototype.init.prototype=I.prototype,I.propHooks={_default:{get:function(t){var e;return 1!==t.elem.nodeType||null!=t.elem[t.prop]&&null==t.elem.style[t.prop]?t.elem[t.prop]:(e=rt.css(t.elem,t.prop,""),e&&"auto"!==e?e:0)},set:function(t){rt.fx.step[t.prop]?rt.fx.step[t.prop](t):1!==t.elem.nodeType||null==t.elem.style[rt.cssProps[t.prop]]&&!rt.cssHooks[t.prop]?t.elem[t.prop]=t.now:rt.style(t.elem,t.prop,t.now+t.unit)}}},I.propHooks.scrollTop=I.propHooks.scrollLeft={set:function(t){t.elem.nodeType&&t.elem.parentNode&&(t.elem[t.prop]=t.now)}},rt.easing={linear:function(t){return t},swing:function(t){return.5-Math.cos(t*Math.PI)/2},_default:"swing"},rt.fx=I.prototype.init,rt.fx.step={};var oe,re,se=/^(?:toggle|show|hide)$/,ae=/queueHooks$/;rt.Animation=rt.extend(F,{tweeners:{"*":[function(t,e){var n=this.createTween(t,e);return u(n.elem,t,jt.exec(e),n),n}]},tweener:function(t,e){rt.isFunction(t)?(e=t,t=["*"]):t=t.match(wt);for(var n,i=0,o=t.length;o>i;i++)n=t[i],F.tweeners[n]=F.tweeners[n]||[],F.tweeners[n].unshift(e)},prefilters:[H],prefilter:function(t,e){e?F.prefilters.unshift(t):F.prefilters.push(t)}}),rt.speed=function(t,e,n){var i=t&&"object"==typeof t?rt.extend({},t):{complete:n||!n&&e||rt.isFunction(t)&&t,duration:t,easing:n&&e||e&&!rt.isFunction(e)&&e};return i.duration=rt.fx.off?0:"number"==typeof i.duration?i.duration:i.duration in rt.fx.speeds?rt.fx.speeds[i.duration]:rt.fx.speeds._default,null!=i.queue&&i.queue!==!0||(i.queue="fx"),i.old=i.complete,i.complete=function(){rt.isFunction(i.old)&&i.old.call(this),i.queue&&rt.dequeue(this,i.queue)},i},rt.fn.extend({fadeTo:function(t,e,n,i){return this.filter(Ot).css("opacity",0).show().end().animate({opacity:e},t,n,i)},animate:function(t,e,n,i){var o=rt.isEmptyObject(t),r=rt.speed(e,n,i),s=function(){var e=F(this,rt.extend({},t),r);(o||kt.get(this,"finish"))&&e.stop(!0)};return s.finish=s,o||r.queue===!1?this.each(s):this.queue(r.queue,s)},stop:function(t,e,n){var i=function(t){var e=t.stop;delete t.stop,e(n)};return"string"!=typeof t&&(n=e,e=t,t=void 0),e&&t!==!1&&this.queue(t||"fx",[]),this.each(function(){var e=!0,o=null!=t&&t+"queueHooks",r=rt.timers,s=kt.get(this);if(o)s[o]&&s[o].stop&&i(s[o]);else for(o in s)s[o]&&s[o].stop&&ae.test(o)&&i(s[o]);for(o=r.length;o--;)r[o].elem!==this||null!=t&&r[o].queue!==t||(r[o].anim.stop(n),e=!1,r.splice(o,1));!e&&n||rt.dequeue(this,t)})},finish:function(t){return t!==!1&&(t=t||"fx"),this.each(function(){var e,n=kt.get(this),i=n[t+"queue"],o=n[t+"queueHooks"],r=rt.timers,s=i?i.length:0;for(n.finish=!0,rt.queue(this,t,[]),o&&o.stop&&o.stop.call(this,!0),e=r.length;e--;)r[e].elem===this&&r[e].queue===t&&(r[e].anim.stop(!0),r.splice(e,1));for(e=0;s>e;e++)i[e]&&i[e].finish&&i[e].finish.call(this);delete n.finish})}}),rt.each(["toggle","show","hide"],function(t,e){var n=rt.fn[e];rt.fn[e]=function(t,i,o){return null==t||"boolean"==typeof t?n.apply(this,arguments):this.animate(R(e,!0),t,i,o)}}),rt.each({slideDown:R("show"),slideUp:R("hide"),slideToggle:R("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(t,e){rt.fn[t]=function(t,n,i){return this.animate(e,t,n,i)}}),rt.timers=[],rt.fx.tick=function(){var t,e=0,n=rt.timers;for(oe=rt.now();e1)},removeAttr:function(t){return this.each(function(){rt.removeAttr(this,t)})}}),rt.extend({attr:function(t,e,n){var i,o,r=t.nodeType;if(3!==r&&8!==r&&2!==r)return"undefined"==typeof t.getAttribute?rt.prop(t,e,n):(1===r&&rt.isXMLDoc(t)||(e=e.toLowerCase(),o=rt.attrHooks[e]||(rt.expr.match.bool.test(e)?le:void 0)),void 0!==n?null===n?void rt.removeAttr(t,e):o&&"set"in o&&void 0!==(i=o.set(t,n,e))?i:(t.setAttribute(e,n+""),n):o&&"get"in o&&null!==(i=o.get(t,e))?i:(i=rt.find.attr(t,e),null==i?void 0:i))},attrHooks:{type:{set:function(t,e){if(!it.radioValue&&"radio"===e&&rt.nodeName(t,"input")){var n=t.value;return t.setAttribute("type",e),n&&(t.value=n),e}}}},removeAttr:function(t,e){var n,i,o=0,r=e&&e.match(wt);if(r&&1===t.nodeType)for(;n=r[o++];)i=rt.propFix[n]||n,rt.expr.match.bool.test(n)&&(t[i]=!1),t.removeAttribute(n)}}),le={set:function(t,e,n){return e===!1?rt.removeAttr(t,n):t.setAttribute(n,n),n}},rt.each(rt.expr.match.bool.source.match(/\w+/g),function(t,e){var n=ue[e]||rt.find.attr;ue[e]=function(t,e,i){var o,r;return i||(r=ue[e],ue[e]=o,o=null!=n(t,e,i)?e.toLowerCase():null,ue[e]=r),o}});var ce=/^(?:input|select|textarea|button)$/i,fe=/^(?:a|area)$/i;rt.fn.extend({prop:function(t,e){return Ct(this,rt.prop,t,e,arguments.length>1)},removeProp:function(t){return this.each(function(){delete this[rt.propFix[t]||t]})}}),rt.extend({prop:function(t,e,n){var i,o,r=t.nodeType;if(3!==r&&8!==r&&2!==r)return 1===r&&rt.isXMLDoc(t)||(e=rt.propFix[e]||e,o=rt.propHooks[e]),void 0!==n?o&&"set"in o&&void 0!==(i=o.set(t,n,e))?i:t[e]=n:o&&"get"in o&&null!==(i=o.get(t,e))?i:t[e]},propHooks:{tabIndex:{get:function(t){var e=rt.find.attr(t,"tabindex");return e?parseInt(e,10):ce.test(t.nodeName)||fe.test(t.nodeName)&&t.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),it.optSelected||(rt.propHooks.selected={get:function(t){var e=t.parentNode;return e&&e.parentNode&&e.parentNode.selectedIndex,null}}),rt.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){rt.propFix[this.toLowerCase()]=this});var pe=/[\t\r\n\f]/g;rt.fn.extend({addClass:function(t){var e,n,i,o,r,s,a,l=0;if(rt.isFunction(t))return this.each(function(e){rt(this).addClass(t.call(this,e,M(this)))});if("string"==typeof t&&t)for(e=t.match(wt)||[];n=this[l++];)if(o=M(n),i=1===n.nodeType&&(" "+o+" ").replace(pe," ")){for(s=0;r=e[s++];)i.indexOf(" "+r+" ")<0&&(i+=r+" ");a=rt.trim(i),o!==a&&n.setAttribute("class",a)}return this},removeClass:function(t){var e,n,i,o,r,s,a,l=0;if(rt.isFunction(t))return this.each(function(e){rt(this).removeClass(t.call(this,e,M(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof t&&t)for(e=t.match(wt)||[];n=this[l++];)if(o=M(n),i=1===n.nodeType&&(" "+o+" ").replace(pe," ")){for(s=0;r=e[s++];)for(;i.indexOf(" "+r+" ")>-1;)i=i.replace(" "+r+" "," ");a=rt.trim(i),o!==a&&n.setAttribute("class",a)}return this},toggleClass:function(t,e){var n=typeof t;return"boolean"==typeof e&&"string"===n?e?this.addClass(t):this.removeClass(t):rt.isFunction(t)?this.each(function(n){rt(this).toggleClass(t.call(this,n,M(this),e),e)}):this.each(function(){var e,i,o,r;if("string"===n)for(i=0,o=rt(this),r=t.match(wt)||[];e=r[i++];)o.hasClass(e)?o.removeClass(e):o.addClass(e);else void 0!==t&&"boolean"!==n||(e=M(this),e&&kt.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||t===!1?"":kt.get(this,"__className__")||""))})},hasClass:function(t){var e,n,i=0;for(e=" "+t+" ";n=this[i++];)if(1===n.nodeType&&(" "+M(n)+" ").replace(pe," ").indexOf(e)>-1)return!0;return!1}});var de=/\r/g;rt.fn.extend({val:function(t){var e,n,i,o=this[0];{if(arguments.length)return i=rt.isFunction(t),this.each(function(n){var o;1===this.nodeType&&(o=i?t.call(this,n,rt(this).val()):t,null==o?o="":"number"==typeof o?o+="":rt.isArray(o)&&(o=rt.map(o,function(t){return null==t?"":t+""})),e=rt.valHooks[this.type]||rt.valHooks[this.nodeName.toLowerCase()],e&&"set"in e&&void 0!==e.set(this,o,"value")||(this.value=o))});if(o)return e=rt.valHooks[o.type]||rt.valHooks[o.nodeName.toLowerCase()],e&&"get"in e&&void 0!==(n=e.get(o,"value"))?n:(n=o.value,"string"==typeof n?n.replace(de,""):null==n?"":n)}}}),rt.extend({valHooks:{option:{get:function(t){return rt.trim(t.value)}},select:{get:function(t){for(var e,n,i=t.options,o=t.selectedIndex,r="select-one"===t.type||0>o,s=r?null:[],a=r?o+1:i.length,l=0>o?a:r?o:0;a>l;l++)if(n=i[l],(n.selected||l===o)&&(it.optDisabled?!n.disabled:null===n.getAttribute("disabled"))&&(!n.parentNode.disabled||!rt.nodeName(n.parentNode,"optgroup"))){if(e=rt(n).val(),r)return e;s.push(e)}return s},set:function(t,e){for(var n,i,o=t.options,r=rt.makeArray(e),s=o.length;s--;)i=o[s],(i.selected=rt.inArray(rt.valHooks.option.get(i),r)>-1)&&(n=!0);return n||(t.selectedIndex=-1),r}}}}),rt.each(["radio","checkbox"],function(){rt.valHooks[this]={set:function(t,e){return rt.isArray(e)?t.checked=rt.inArray(rt(t).val(),e)>-1:void 0}},it.checkOn||(rt.valHooks[this].get=function(t){return null===t.getAttribute("value")?"on":t.value})});var he=/^(?:focusinfocus|focusoutblur)$/;rt.extend(rt.event,{trigger:function(e,n,i,o){var r,s,a,l,u,c,f,p=[i||Y],d=nt.call(e,"type")?e.type:e,h=nt.call(e,"namespace")?e.namespace.split("."):[];if(s=a=i=i||Y,3!==i.nodeType&&8!==i.nodeType&&!he.test(d+rt.event.triggered)&&(d.indexOf(".")>-1&&(h=d.split("."),d=h.shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,e=e[rt.expando]?e:new rt.Event(d,"object"==typeof e&&e),e.isTrigger=o?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=i),n=null==n?[e]:rt.makeArray(n,[e]),f=rt.event.special[d]||{},o||!f.trigger||f.trigger.apply(i,n)!==!1)){if(!o&&!f.noBubble&&!rt.isWindow(i)){for(l=f.delegateType||d,he.test(l+d)||(s=s.parentNode);s;s=s.parentNode)p.push(s),a=s;a===(i.ownerDocument||Y)&&p.push(a.defaultView||a.parentWindow||t)}for(r=0;(s=p[r++])&&!e.isPropagationStopped();)e.type=r>1?l:f.bindType||d,c=(kt.get(s,"events")||{})[e.type]&&kt.get(s,"handle"),c&&c.apply(s,n),c=u&&s[u],c&&c.apply&&Et(s)&&(e.result=c.apply(s,n),e.result===!1&&e.preventDefault());return e.type=d,o||e.isDefaultPrevented()||f._default&&f._default.apply(p.pop(),n)!==!1||!Et(i)||u&&rt.isFunction(i[d])&&!rt.isWindow(i)&&(a=i[u],a&&(i[u]=null),rt.event.triggered=d,i[d](),rt.event.triggered=void 0,a&&(i[u]=a)),e.result}},simulate:function(t,e,n){var i=rt.extend(new rt.Event,n,{type:t,isSimulated:!0});rt.event.trigger(i,null,e),i.isDefaultPrevented()&&n.preventDefault()}}),rt.fn.extend({trigger:function(t,e){return this.each(function(){rt.event.trigger(t,e,this)})},triggerHandler:function(t,e){var n=this[0];return n?rt.event.trigger(t,e,n,!0):void 0}}),rt.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(t,e){rt.fn[e]=function(t,n){return arguments.length>0?this.on(e,null,t,n):this.trigger(e)}}),rt.fn.extend({hover:function(t,e){return this.mouseenter(t).mouseleave(e||t)}}),it.focusin="onfocusin"in t,it.focusin||rt.each({focus:"focusin",blur:"focusout"},function(t,e){var n=function(t){rt.event.simulate(e,t.target,rt.event.fix(t))};rt.event.special[e]={setup:function(){var i=this.ownerDocument||this,o=kt.access(i,e);o||i.addEventListener(t,n,!0),kt.access(i,e,(o||0)+1)},teardown:function(){var i=this.ownerDocument||this,o=kt.access(i,e)-1;o?kt.access(i,e,o):(i.removeEventListener(t,n,!0),kt.remove(i,e))}}});var ge=t.location,ve=rt.now(),me=/\?/;rt.parseJSON=function(t){return JSON.parse(t+"")},rt.parseXML=function(e){var n;if(!e||"string"!=typeof e)return null;try{n=(new t.DOMParser).parseFromString(e,"text/xml")}catch(i){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||rt.error("Invalid XML: "+e),n};var ye=/#.*$/,be=/([?&])_=[^&]*/,xe=/^(.*?):[ \t]*([^\r\n]*)$/gm,we=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Te=/^(?:GET|HEAD)$/,Ce=/^\/\//,Ee={},ke={},$e="*/".concat("*"),Se=Y.createElement("a");Se.href=ge.href,rt.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:ge.href,type:"GET",isLocal:we.test(ge.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$e,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":rt.parseJSON,"text xml":rt.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(t,e){return e?B(B(t,rt.ajaxSettings),e):B(rt.ajaxSettings,t)},ajaxPrefilter:W(Ee),ajaxTransport:W(ke),ajax:function(e,n){function i(e,n,i,a){var u,f,y,b,w,C=n;2!==x&&(x=2,l&&t.clearTimeout(l),o=void 0,s=a||"",T.readyState=e>0?4:0,u=e>=200&&300>e||304===e,i&&(b=U(p,T,i)),b=z(p,b,T,u),u?(p.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(rt.lastModified[r]=w),w=T.getResponseHeader("etag"),w&&(rt.etag[r]=w)),204===e||"HEAD"===p.type?C="nocontent":304===e?C="notmodified":(C=b.state,f=b.data,y=b.error,u=!y)):(y=C,!e&&C||(C="error",0>e&&(e=0))),T.status=e,T.statusText=(n||C)+"",u?g.resolveWith(d,[f,C,T]):g.rejectWith(d,[T,C,y]),T.statusCode(m),m=void 0,c&&h.trigger(u?"ajaxSuccess":"ajaxError",[T,p,u?f:y]),v.fireWith(d,[T,C]),c&&(h.trigger("ajaxComplete",[T,p]),--rt.active||rt.event.trigger("ajaxStop")))}"object"==typeof e&&(n=e,e=void 0),n=n||{};var o,r,s,a,l,u,c,f,p=rt.ajaxSetup({},n),d=p.context||p,h=p.context&&(d.nodeType||d.jquery)?rt(d):rt.event,g=rt.Deferred(),v=rt.Callbacks("once memory"),m=p.statusCode||{},y={},b={},x=0,w="canceled",T={readyState:0,getResponseHeader:function(t){var e;if(2===x){if(!a)for(a={};e=xe.exec(s);)a[e[1].toLowerCase()]=e[2];e=a[t.toLowerCase()]}return null==e?null:e},getAllResponseHeaders:function(){return 2===x?s:null},setRequestHeader:function(t,e){var n=t.toLowerCase();return x||(t=b[n]=b[n]||t,y[t]=e),this},overrideMimeType:function(t){return x||(p.mimeType=t),this},statusCode:function(t){var e;if(t)if(2>x)for(e in t)m[e]=[m[e],t[e]];else T.always(t[T.status]);return this},abort:function(t){var e=t||w;return o&&o.abort(e),i(0,e),this}};if(g.promise(T).complete=v.add,T.success=T.done,T.error=T.fail,p.url=((e||p.url||ge.href)+"").replace(ye,"").replace(Ce,ge.protocol+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=rt.trim(p.dataType||"*").toLowerCase().match(wt)||[""],null==p.crossDomain){u=Y.createElement("a");try{u.href=p.url,u.href=u.href,p.crossDomain=Se.protocol+"//"+Se.host!=u.protocol+"//"+u.host}catch(C){p.crossDomain=!0}}if(p.data&&p.processData&&"string"!=typeof p.data&&(p.data=rt.param(p.data,p.traditional)),_(Ee,p,n,T),2===x)return T;c=rt.event&&p.global,c&&0===rt.active++&&rt.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Te.test(p.type),r=p.url,p.hasContent||(p.data&&(r=p.url+=(me.test(r)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=be.test(r)?r.replace(be,"$1_="+ve++):r+(me.test(r)?"&":"?")+"_="+ve++)),p.ifModified&&(rt.lastModified[r]&&T.setRequestHeader("If-Modified-Since",rt.lastModified[r]),rt.etag[r]&&T.setRequestHeader("If-None-Match",rt.etag[r])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&T.setRequestHeader("Content-Type",p.contentType),T.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+$e+"; q=0.01":""):p.accepts["*"]);for(f in p.headers)T.setRequestHeader(f,p.headers[f]);if(p.beforeSend&&(p.beforeSend.call(d,T,p)===!1||2===x))return T.abort();w="abort";for(f in{success:1,error:1,complete:1})T[f](p[f]);if(o=_(ke,p,n,T)){if(T.readyState=1,c&&h.trigger("ajaxSend",[T,p]),2===x)return T;p.async&&p.timeout>0&&(l=t.setTimeout(function(){T.abort("timeout")},p.timeout));try{x=1,o.send(y,i)}catch(C){if(!(2>x))throw C;i(-1,C)}}else i(-1,"No Transport");return T},getJSON:function(t,e,n){return rt.get(t,e,n,"json")},getScript:function(t,e){return rt.get(t,void 0,e,"script")}}),rt.each(["get","post"],function(t,e){rt[e]=function(t,n,i,o){return rt.isFunction(n)&&(o=o||i,i=n,n=void 0),rt.ajax(rt.extend({url:t,type:e,dataType:o,data:n,success:i},rt.isPlainObject(t)&&t))}}),rt._evalUrl=function(t){return rt.ajax({url:t,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},rt.fn.extend({wrapAll:function(t){var e;return rt.isFunction(t)?this.each(function(e){rt(this).wrapAll(t.call(this,e))}):(this[0]&&(e=rt(t,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&e.insertBefore(this[0]),e.map(function(){for(var t=this;t.firstElementChild;)t=t.firstElementChild;return t}).append(this)),this)},wrapInner:function(t){return rt.isFunction(t)?this.each(function(e){rt(this).wrapInner(t.call(this,e))}):this.each(function(){var e=rt(this),n=e.contents();n.length?n.wrapAll(t):e.append(t)})},wrap:function(t){var e=rt.isFunction(t);return this.each(function(n){rt(this).wrapAll(e?t.call(this,n):t)})},unwrap:function(){return this.parent().each(function(){rt.nodeName(this,"body")||rt(this).replaceWith(this.childNodes)}).end()}}),rt.expr.filters.hidden=function(t){return!rt.expr.filters.visible(t)},rt.expr.filters.visible=function(t){return t.offsetWidth>0||t.offsetHeight>0||t.getClientRects().length>0};var Ne=/%20/g,De=/\[\]$/,je=/\r?\n/g,Ae=/^(?:submit|button|image|reset|file)$/i,Oe=/^(?:input|select|textarea|keygen)/i;rt.param=function(t,e){var n,i=[],o=function(t,e){e=rt.isFunction(e)?e():null==e?"":e,i[i.length]=encodeURIComponent(t)+"="+encodeURIComponent(e)};if(void 0===e&&(e=rt.ajaxSettings&&rt.ajaxSettings.traditional),rt.isArray(t)||t.jquery&&!rt.isPlainObject(t))rt.each(t,function(){o(this.name,this.value)});else for(n in t)V(n,t[n],e,o);return i.join("&").replace(Ne,"+")},rt.fn.extend({serialize:function(){return rt.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var t=rt.prop(this,"elements");return t?rt.makeArray(t):this}).filter(function(){var t=this.type;return this.name&&!rt(this).is(":disabled")&&Oe.test(this.nodeName)&&!Ae.test(t)&&(this.checked||!It.test(t))}).map(function(t,e){var n=rt(this).val();return null==n?null:rt.isArray(n)?rt.map(n,function(t){return{name:e.name,value:t.replace(je,"\r\n")}}):{name:e.name,value:n.replace(je,"\r\n")}}).get()}}),rt.ajaxSettings.xhr=function(){try{return new t.XMLHttpRequest}catch(e){}};var Ie={0:200,1223:204},Le=rt.ajaxSettings.xhr();it.cors=!!Le&&"withCredentials"in Le,it.ajax=Le=!!Le,rt.ajaxTransport(function(e){var n,i;return it.cors||Le&&!e.crossDomain?{send:function(o,r){var s,a=e.xhr();if(a.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(s in e.xhrFields)a[s]=e.xhrFields[s];e.mimeType&&a.overrideMimeType&&a.overrideMimeType(e.mimeType),e.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest");for(s in o)a.setRequestHeader(s,o[s]);n=function(t){return function(){n&&(n=i=a.onload=a.onerror=a.onabort=a.onreadystatechange=null,"abort"===t?a.abort():"error"===t?"number"!=typeof a.status?r(0,"error"):r(a.status,a.statusText):r(Ie[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=n(),i=a.onerror=n("error"),void 0!==a.onabort?a.onabort=i:a.onreadystatechange=function(){4===a.readyState&&t.setTimeout(function(){n&&i()})},n=n("abort");try{a.send(e.hasContent&&e.data||null)}catch(l){if(n)throw l}},abort:function(){n&&n()}}:void 0}),rt.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(t){return rt.globalEval(t),t}}}),rt.ajaxPrefilter("script",function(t){void 0===t.cache&&(t.cache=!1),t.crossDomain&&(t.type="GET")}),rt.ajaxTransport("script",function(t){if(t.crossDomain){var e,n;return{send:function(i,o){e=rt(" diff --git a/static/src/hbs/_styles.hbs b/static/src/hbs/_styles.hbs deleted file mode 100644 index c5371d0..0000000 --- a/static/src/hbs/_styles.hbs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/static/src/less/site.less b/static/src/less/site.less deleted file mode 100644 index da96c55..0000000 --- a/static/src/less/site.less +++ /dev/null @@ -1,15 +0,0 @@ -@import "bootstrap"; -@import "font-awesome"; - -@import "variables.less"; - -// Account -@import "account.less"; - -// Symposion UI components -@import "editor.less"; -@import "symposion-components.less"; -@import "symposion-schedule.less"; - -// Site overrides -@import "custom.less"; diff --git a/static/src/less/variables.less b/static/src/less/variables.less deleted file mode 100644 index 822d64f..0000000 --- a/static/src/less/variables.less +++ /dev/null @@ -1,3 +0,0 @@ -@font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif; -@font-family-serif: Georgia, "Times New Roman", Times, serif; -@font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace; diff --git a/symposion_templates b/symposion_templates new file mode 120000 index 0000000..2168e40 --- /dev/null +++ b/symposion_templates @@ -0,0 +1 @@ +../symposion-bootstrap-templates/symposion_templates \ No newline at end of file