Repository: mozilla/nunjucks
Branch: master
Commit: 2025c933fba3
Files: 301
Total size: 2.4 MB
Directory structure:
gitextract_d6mkhpa4/
├── .babelrc
├── .gitattributes
├── .github/
│ ├── PULL_REQUEST_TEMPLATE.md
│ └── workflows/
│ └── tests.yml
├── .gitignore
├── .npmignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── MAINTENANCE.md
├── README.md
├── bench/
│ ├── case.html
│ ├── index.html
│ ├── jinja/
│ │ ├── index.html
│ │ └── jinja.py
│ └── run.js
├── bin/
│ ├── precompile
│ └── precompile.cmd
├── bower.json
├── codecov.yml
├── contribute.json
├── docs/
│ ├── .gitignore
│ ├── Makefile
│ ├── README.md
│ ├── _config-prod.yml
│ ├── _config.yml
│ ├── _layouts/
│ │ ├── page.html
│ │ └── subpage.html
│ ├── _plugins/
│ │ ├── api.rb
│ │ ├── cleanup.rb
│ │ ├── locale.rb
│ │ └── page_toc.rb
│ ├── api.md
│ ├── bower_components/
│ │ ├── bootstrap/
│ │ │ ├── .bower.json
│ │ │ ├── CNAME
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── Gruntfile.js
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── _config.yml
│ │ │ ├── _includes/
│ │ │ │ ├── ads.html
│ │ │ │ ├── footer.html
│ │ │ │ ├── header.html
│ │ │ │ ├── nav-components.html
│ │ │ │ ├── nav-css.html
│ │ │ │ ├── nav-customize.html
│ │ │ │ ├── nav-getting-started.html
│ │ │ │ ├── nav-javascript.html
│ │ │ │ ├── nav-main.html
│ │ │ │ ├── old-bs-docs.html
│ │ │ │ └── social-buttons.html
│ │ │ ├── _layouts/
│ │ │ │ ├── default.html
│ │ │ │ └── home.html
│ │ │ ├── assets/
│ │ │ │ ├── css/
│ │ │ │ │ ├── docs.css
│ │ │ │ │ └── pygments-manni.css
│ │ │ │ └── js/
│ │ │ │ ├── application.js
│ │ │ │ ├── customizer.js
│ │ │ │ ├── filesaver.js
│ │ │ │ ├── holder.js
│ │ │ │ ├── html5shiv.js
│ │ │ │ ├── jquery.js
│ │ │ │ ├── jszip.js
│ │ │ │ ├── less.js
│ │ │ │ ├── raw-files.js
│ │ │ │ └── uglify.js
│ │ │ ├── bower.json
│ │ │ ├── browserstack.json
│ │ │ ├── composer.json
│ │ │ ├── dist/
│ │ │ │ ├── css/
│ │ │ │ │ ├── bootstrap-theme.css
│ │ │ │ │ └── bootstrap.css
│ │ │ │ └── js/
│ │ │ │ └── bootstrap.js
│ │ │ ├── examples/
│ │ │ │ ├── carousel/
│ │ │ │ │ ├── carousel.css
│ │ │ │ │ └── index.html
│ │ │ │ ├── grid/
│ │ │ │ │ ├── grid.css
│ │ │ │ │ └── index.html
│ │ │ │ ├── jumbotron/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── jumbotron.css
│ │ │ │ ├── jumbotron-narrow/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── jumbotron-narrow.css
│ │ │ │ ├── justified-nav/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── justified-nav.css
│ │ │ │ ├── navbar/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── navbar.css
│ │ │ │ ├── navbar-fixed-top/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── navbar-fixed-top.css
│ │ │ │ ├── navbar-static-top/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── navbar-static-top.css
│ │ │ │ ├── non-responsive/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── non-responsive.css
│ │ │ │ ├── offcanvas/
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── offcanvas.css
│ │ │ │ │ └── offcanvas.js
│ │ │ │ ├── signin/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── signin.css
│ │ │ │ ├── starter-template/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── starter-template.css
│ │ │ │ ├── sticky-footer/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── sticky-footer.css
│ │ │ │ ├── sticky-footer-navbar/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── sticky-footer-navbar.css
│ │ │ │ └── theme/
│ │ │ │ ├── index.html
│ │ │ │ └── theme.css
│ │ │ ├── js/
│ │ │ │ ├── .jshintrc
│ │ │ │ ├── affix.js
│ │ │ │ ├── alert.js
│ │ │ │ ├── button.js
│ │ │ │ ├── carousel.js
│ │ │ │ ├── collapse.js
│ │ │ │ ├── dropdown.js
│ │ │ │ ├── modal.js
│ │ │ │ ├── popover.js
│ │ │ │ ├── scrollspy.js
│ │ │ │ ├── tab.js
│ │ │ │ ├── tests/
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── phantom.js
│ │ │ │ │ ├── server.js
│ │ │ │ │ ├── unit/
│ │ │ │ │ │ ├── affix.js
│ │ │ │ │ │ ├── alert.js
│ │ │ │ │ │ ├── button.js
│ │ │ │ │ │ ├── carousel.js
│ │ │ │ │ │ ├── collapse.js
│ │ │ │ │ │ ├── dropdown.js
│ │ │ │ │ │ ├── modal.js
│ │ │ │ │ │ ├── phantom.js
│ │ │ │ │ │ ├── popover.js
│ │ │ │ │ │ ├── scrollspy.js
│ │ │ │ │ │ ├── tab.js
│ │ │ │ │ │ ├── tooltip.js
│ │ │ │ │ │ └── transition.js
│ │ │ │ │ └── vendor/
│ │ │ │ │ ├── jquery.js
│ │ │ │ │ ├── qunit.css
│ │ │ │ │ └── qunit.js
│ │ │ │ ├── tooltip.js
│ │ │ │ └── transition.js
│ │ │ ├── less/
│ │ │ │ ├── alerts.less
│ │ │ │ ├── badges.less
│ │ │ │ ├── bootstrap.less
│ │ │ │ ├── breadcrumbs.less
│ │ │ │ ├── button-groups.less
│ │ │ │ ├── buttons.less
│ │ │ │ ├── carousel.less
│ │ │ │ ├── close.less
│ │ │ │ ├── code.less
│ │ │ │ ├── component-animations.less
│ │ │ │ ├── dropdowns.less
│ │ │ │ ├── forms.less
│ │ │ │ ├── glyphicons.less
│ │ │ │ ├── grid.less
│ │ │ │ ├── input-groups.less
│ │ │ │ ├── jumbotron.less
│ │ │ │ ├── labels.less
│ │ │ │ ├── list-group.less
│ │ │ │ ├── media.less
│ │ │ │ ├── mixins.less
│ │ │ │ ├── modals.less
│ │ │ │ ├── navbar.less
│ │ │ │ ├── navs.less
│ │ │ │ ├── normalize.less
│ │ │ │ ├── pager.less
│ │ │ │ ├── pagination.less
│ │ │ │ ├── panels.less
│ │ │ │ ├── popovers.less
│ │ │ │ ├── print.less
│ │ │ │ ├── progress-bars.less
│ │ │ │ ├── responsive-utilities.less
│ │ │ │ ├── scaffolding.less
│ │ │ │ ├── tables.less
│ │ │ │ ├── theme.less
│ │ │ │ ├── thumbnails.less
│ │ │ │ ├── tooltip.less
│ │ │ │ ├── type.less
│ │ │ │ ├── utilities.less
│ │ │ │ ├── variables.less
│ │ │ │ └── wells.less
│ │ │ └── package.json
│ │ └── jquery/
│ │ ├── .bower.json
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── bower.json
│ │ ├── component.json
│ │ ├── composer.json
│ │ ├── jquery-migrate.js
│ │ ├── jquery.js
│ │ └── package.json
│ ├── cn/
│ │ ├── api.md
│ │ ├── faq.md
│ │ ├── getting-started.md
│ │ └── templating.md
│ ├── css/
│ │ ├── app.css
│ │ └── highlight.css
│ ├── faq.md
│ ├── fr/
│ │ ├── api.md
│ │ ├── faq.md
│ │ ├── getting-started.md
│ │ └── templating.md
│ ├── getting-started.md
│ ├── index.html
│ ├── js/
│ │ ├── app.js
│ │ └── subpage.js
│ └── templating.md
├── eslint.config.js
├── nunjucks/
│ ├── index.js
│ └── src/
│ ├── compiler.js
│ ├── environment.js
│ ├── express-app.js
│ ├── filters.js
│ ├── globals.js
│ ├── jinja-compat.js
│ ├── lexer.js
│ ├── lib.js
│ ├── loader.js
│ ├── loaders.js
│ ├── node-loaders.js
│ ├── nodes.js
│ ├── object.js
│ ├── parser.js
│ ├── precompile-global.js
│ ├── precompile.js
│ ├── precompiled-loader.js
│ ├── runtime.js
│ ├── tests.js
│ ├── transformer.js
│ └── web-loaders.js
├── package.json
├── samples/
│ └── express/
│ ├── js/
│ │ ├── app.js
│ │ └── extensions.js
│ ├── main.js
│ ├── pre.js
│ └── views/
│ ├── about.html
│ ├── base.html
│ ├── import-context-set.html
│ ├── index.html
│ ├── item-base.html
│ ├── item.html
│ └── set.html
├── scripts/
│ ├── bundle.js
│ ├── lib/
│ │ ├── is-main-module.js
│ │ ├── mocha-phantomjs.js
│ │ ├── precompile.js
│ │ ├── runtests.js
│ │ ├── static-server.js
│ │ └── utils.js
│ └── testrunner.js
└── tests/
├── api.js
├── browser/
│ ├── index.html
│ └── slim.html
├── cli.js
├── compiler.js
├── core.js
├── eslint.config.js
├── express.js
├── filters.js
├── globals.js
├── jinja-compat.js
├── lexer.js
├── loader.js
├── parser.js
├── precompile.js
├── runtime.js
├── setup.js
├── templates/
│ ├── async.njk
│ ├── base-inherit.njk
│ ├── base-set-and-show.njk
│ ├── base-set-inside-block.njk
│ ├── base-set-wraps-block.njk
│ ├── base-set.njk
│ ├── base-show.njk
│ ├── base.njk
│ ├── base2.njk
│ ├── base3.njk
│ ├── broken-conditional-include.njk
│ ├── broken-import.njk
│ ├── filter-block.html
│ ├── for-async-content.njk
│ ├── import-context-set.njk
│ ├── import-context.njk
│ ├── import-macro-call-undefined-macro.njk
│ ├── import.njk
│ ├── include-in-loop.njk
│ ├── include-set.njk
│ ├── include.njk
│ ├── includeMany.njk
│ ├── item.njk
│ ├── macro-call-undefined-macro.njk
│ ├── relative/
│ │ ├── dir1/
│ │ │ ├── index.njk
│ │ │ └── macros.njk
│ │ ├── dir2/
│ │ │ ├── index.njk
│ │ │ └── macros.njk
│ │ ├── test-cache.njk
│ │ ├── test1.njk
│ │ └── test2.njk
│ ├── set.njk
│ ├── simple-base.njk
│ ├── throws.njk
│ └── undefined-macro.njk
├── test-node-pkgs/
│ └── dummy-pkg/
│ ├── index.js
│ ├── package.json
│ └── simple-template.html
├── tests.js
└── util.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .babelrc
================================================
{
"presets": [
["@babel/env", {
"loose": true,
"targets": {
"browsers": ["last 2 versions", "safari >= 7", "ie 9"],
"node": "6"
}
}]
],
"env": {
"test": {
"plugins": ["istanbul"]
}
},
"ignore": [
"scripts/lib/arrow-function-coverage-fix.js"
]
}
================================================
FILE: .gitattributes
================================================
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Checkout example and test fixtures with linux line ending
# to guarantee test successes
tests/** text eol=lf
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
## Summary
Proposed change:
Closes # .
## Checklist
I've completed the checklist below to ensure I didn't forget anything. This makes reviewing this PR as easy as possible for the maintainers. And it gets this change released as soon as possible.
* [ ] Proposed change helps towards [*purpose of this project*](https://github.com/mozilla/nunjucks/blob/master/CONTRIBUTING.md#purpose).
* [ ] [*Documentation*](https://github.com/mozilla/nunjucks/tree/master/docs/) is added / updated to describe proposed change.
* [ ] [*Tests*](https://github.com/mozilla/nunjucks/tree/master/tests) are added / updated to cover proposed change.
* [ ] [*Changelog*](https://github.com/mozilla/nunjucks/blob/master/CHANGELOG.md) has an entry for proposed change (if user-facing fix or feature).
================================================
FILE: .github/workflows/tests.yml
================================================
name: Tests
on:
push:
pull_request:
workflow_dispatch:
permissions:
contents: read
jobs:
tests:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- node: 16
os: windows-2022
- node: 16
os: windows-2025
- node: 18
os: ubuntu-22.04
- node: 18.20.1 # TODO: spawn node18+/win: github.com/nodejs/nodejs.org/pull/6660
os: windows-2022
- node: 20
os: macos-14
- node: 20
os: ubuntu-latest
- node: 20.12.1 # TODO: spawn node18+/win: github.com/nodejs/nodejs.org/pull/6660
os: windows-2025
- node: 22
os: macos-15-intel
- node: 22
os: ubuntu-24.04
- node: 24
os: ubuntu-latest
- node: 24
os: macos-latest
- node: 25
os: macos-26
name: Test (node-${{ matrix.node }}/${{ matrix.os }})
steps:
- if: runner.os == 'Linux' # PhantomJS OpenSSL 1.1.1 vs 3.x Ubuntu 22+ compat
run: echo "OPENSSL_CONF=/dev/null" >> "$GITHUB_ENV"
- if: runner.os == 'Windows' # Tests would fail LF vs CRLF linebreak-style
run: git config --global core.autocrlf false && git config --global core.eol lf
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: npm
- run: npm ci
- run: npm test
- if: success()
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
================================================
FILE: .gitignore
================================================
node_modules
coverage
.#*
docs/_site
docs/files
/src/
/index.js
/index.js.map
/tests/browser/nunjucks*
.nyc_output
/browser
/tests/browser/precompiled-templates.js
/samples/express/js/nunjucks.js
/samples/express/js/templates.js
================================================
FILE: .npmignore
================================================
node_modules
coverage
.nyc_output
docs
tests
bench
nunjucks
scripts
================================================
FILE: CHANGELOG.md
================================================
Changelog
=========
3.2.4 (Apr 13 2023)
------------------
* HTML encode backslashes when expressions are passed through the escape
filter (including when this is done automatically with autoescape). Merge
of [#1437](https://github.com/mozilla/nunjucks/pull/1437).
3.2.3 (Feb 15 2021)
-------------------
* Add support for nested attributes on
[`sort` filter](https://mozilla.github.io/nunjucks/templating.html#sort-arr-reverse-casesens-attr);
respect `throwOnUndefined` if sort attribute is undefined.
* Add `base` arg to
[`int` filter](https://mozilla.github.io/nunjucks/templating.html#int).
* Move `chokidar` to `peerDependencies` and mark it `optional` in `peerDependenciesMeta`.
* Fix prototype pollution issue for template variables. Merge of
[#1330](https://github.com/mozilla/nunjucks/pull/1330); fixes
[#1331](https://github.com/mozilla/nunjucks/issues/1331). Thanks
[ChenKS12138](https://github.com/ChenKS12138)!
3.2.2 (Jul 20 2020)
-------------------
* Add [`select`](https://mozilla.github.io/nunjucks/templating.html#select) and
[`reject`](https://mozilla.github.io/nunjucks/templating.html#reject) filters.
Merge of [#1278](https://github.com/mozilla/nunjucks/pull/1278) and
[#1279](https://github.com/mozilla/nunjucks/pull/1279); fixes
[#282](https://github.com/mozilla/nunjucks/issues/282). Thanks
[ogonkov](https://github.com/ogonkovv)!
* Fix precompile binary script `TypeError: name.replace is not a function`.
Fixes [#1295](https://github.com/mozilla/nunjucks/issues/1295).
* Add support for nested attributes on
[`groupby` filter](https://mozilla.github.io/nunjucks/templating.html#groupby);
respect `throwOnUndefined` option, if the groupby attribute is undefined.
Merge of [#1276](https://github.com/mozilla/nunjucks/pull/1276); fixes
[#1198](https://github.com/mozilla/nunjucks/issues/1198). Thanks
[ogonkov](https://github.com/ogonkovv)!
* Fix bug that prevented errors in included templates from being raised when
rendering templates synchronously. Fixes
[#1272](https://github.com/mozilla/nunjucks/issues/1272).
* The `indent` filter no longer appends an additional newline. Fixes
[#1231](https://github.com/mozilla/nunjucks/issues/1231).
3.2.1 (Mar 17 2020)
-------------------
* Replace yargs with commander to reduce number of dependencies. Merge of
[#1253](https://github.com/mozilla/nunjucks/pull/1253). Thanks
[AlynxZhou](@AlynxZhou).
* Update optional dependency chokidar from `^2.0.0` to `^3.3.0`. Merge of
[#1254](https://github.com/mozilla/nunjucks/pull/1254). Thanks
[eklingen](@eklingen).
* Prevent optional dependency Chokidar from loading when not watching. Merge
of [#1250](https://github.com/mozilla/nunjucks/pull/1250). Thanks
[eklingen](@eklingen).
3.2.0 (Mar 5 2019)
------------------
* Adds [`NodeResolveLoader`](http://mozilla.github.io/nunjucks/api.html#noderesolveloader),
a Loader that loads templates using node's
[`require.resolve`](https://nodejs.org/api/modules.html#modules_all_together).
Fixes [#1175](https://github.com/mozilla/nunjucks/issues/1175).
* Emit 'load' events on `Environment` instances, to allow runtime dependency
tracking. Fixes [#1153](https://github.com/mozilla/nunjucks/issues/1153).
3.1.7 (Jan 12 2019)
------------------
* Fix bug where exceptions were silently swallowed with synchronous render.
Fixes [#678](https://github.com/mozilla/nunjucks/issues/678),
[#1116](https://github.com/mozilla/nunjucks/issues/1116),
[#1127](https://github.com/mozilla/nunjucks/issues/1127), and
[#1164](https://github.com/mozilla/nunjucks/issues/1164)
* Removes deprecated postinstall-build package in favor of
[npm prepare](https://docs.npmjs.com/misc/scripts#prepublish-and-prepare).
Merge of [#1172](https://github.com/mozilla/nunjucks/pull/1172).
Fixes [#1167](https://github.com/mozilla/nunjucks/issues/1167).
- Note: this means that npm@5 or later is required to install nunjucks
directly from github.
3.1.6 (Dec 13 2018)
-------------------
No code changes; fixed npm packaging issue.
3.1.5 (Dec 13 2018)
-------------------
* Fix engine dependency version for Node versions > 11.1.0;
Fixes [#1168](https://github.com/mozilla/nunjucks/issues/1168).
3.1.4 (Nov 9 2018)
------------------
* Fix engine version for Node v11.1.0
* Fix "Unexpected token" error for U+2028 unicode newline. Fixes [#126](https://github.com/mozilla/nunjucks/issues/126) and [#736](https://github.com/mozilla/nunjucks/issues/736)
3.1.3 (May 19 2018)
-------------------
* Add `forceescape` filter. Fixes [#782](https://github.com/mozilla/nunjucks/issues/782)
* Fix regression that prevented template errors from reporting line and column number.
Fixes [#1087](https://github.com/mozilla/nunjucks/issues/1087) and
[#1095](https://github.com/mozilla/nunjucks/issues/1095).
* Fix "Invalid type: Is" error for `{% if value is defined %}`. Fixes
[#1110](https://github.com/mozilla/nunjucks/issues/1110)
* Formally drop support for node v4 (the upgrade to babel 7 in 3.1.0 made the
build process incompatible with node < 6.9.0).
3.1.2 (Feb 23 2018)
-------------------
* Fix regression to make `chokidar` an optional dependency again. Fixes
[#1073](https://github.com/mozilla/nunjucks/issues/1073)
* Fix issue when running `npm install nunjucks` with the `--no-bin-links` flag
* Fix regression that broke template caching. Fixes
[#1074](https://github.com/mozilla/nunjucks/issues/1074)
3.1.0 (Feb 19 2018)
-------------------
* Support nunjucks.installJinjaCompat() with slim build. Fixes
[#1019](https://github.com/mozilla/nunjucks/issues/1019)
* Fix calling render callback twice when a conditional import throws an error.
Solves [#1029](https://github.com/mozilla/nunjucks/issues/1029)
* Support objects created with Object.create(null). fixes [#468](https://github.com/mozilla/nunjucks/issues/468)
* Support ESNext iterators, using Array.from. Merge of
[#1058](https://github.com/mozilla/nunjucks/pull/1058)
3.0.1 (May 24 2017)
-------------------
* Fix handling methods and attributes of static arrays, objects and primitives.
Solves the issue [#937](https://github.com/mozilla/nunjucks/issues/937)
* Add support for python-style array slices with Jinja compat enabled.
Fixes [#188](https://github.com/mozilla/nunjucks/issues/188); merge of
[#976](https://github.com/mozilla/nunjucks/pull/976).
* Fix call blocks having access to their parent scope. Fixes
[#906](https://github.com/mozilla/nunjucks/issues/906); merge of
[#994](https://github.com/mozilla/nunjucks/pull/994).
* Fix a bug that caused capturing block tags (e.g. set/endset,
filter/endfilter) to write to the global buffer rather than capturing
their contents. Fixes
[#914](https://github.com/mozilla/nunjucks/issues/914) and
[#972](https://github.com/mozilla/nunjucks/issues/972); merge of
[#990](https://github.com/mozilla/nunjucks/pull/990). Thanks [Noah
Lange](@noahlange).
3.0.0 (Nov 5 2016)
----------------
* Allow including many templates without reaching recursion limits. Merge of
[#787](https://github.com/mozilla/nunjucks/pull/787). Thanks Gleb Khudyakov.
* Allow explicitly setting `null` (aka `none`) as the value of a variable;
don't ignore that value and look on up the frame stack or context. Fixes
[#478](https://github.com/mozilla/nunjucks/issues/478). Thanks Jonny Gerig
Meyer for the report.
* Execute blocks in a child frame that can't write to its parent. This means
that vars set inside blocks will not leak outside of the block, base
templates can no longer see vars set in templates that inherit them, and
`super()` can no longer set vars in its calling scope. Fixes the inheritance
portion of [#561](https://github.com/mozilla/nunjucks/issues/561), which
fully closes that issue. Thanks legutierr for the report.
* Prevent macros from seeing or affecting their calling scope. Merge of
[#667](https://github.com/mozilla/nunjucks/pull/667).
* Fix handling of macro arg with default value which shares a name with another
macro. Merge of [#791](https://github.com/mozilla/nunjucks/pull/791).
* Add support for the spaces parameter in the dump template filter.
Merge of [#868](https://github.com/mozilla/nunjucks/pull/868).
Thanks Jesse Eikema
* Add `verbatim` as an alias of `raw` for compatibility with Twig.
Merge of [#874](https://github.com/mozilla/nunjucks/pull/874).
* Add new `nl2br` filter. Thanks Marc-Aurèle Darche
* Add support for python's `list.append` with Jinja compat enabled. Thanks
Conor Flannigan.
* Add variables whitespace control.
2.5.2 (Sep 14 2016)
----------------
* Call `.toString` in safe filter.
Merge of [#849](https://github.com/mozilla/nunjucks/pull/849).
2.5.1 (Sep 13 2016)
----------------
* Fix `undefined` and `null` behavior in escape and safe filter.
Merge of [#843](https://github.com/mozilla/nunjucks/pull/843).
2.5.0 (Sep 7 2016)
----------------
* Add `elseif` as an alias of `elif` for parity with Twig. Thanks kswedberg.
Merge of [#826](https://github.com/mozilla/nunjucks/pull/826).
* Add nunjucks env to express app settings as `nunjucksEnv`.
Merge of [#829](https://github.com/mozilla/nunjucks/pull/829).
* Add support for finding an object's "length" in length filter.
Merge of [#813](https://github.com/mozilla/nunjucks/pull/813).
* Ensure that precompiling on Windows still outputs POSIX-style path
separators. Merge of [#761](https://github.com/mozilla/nunjucks/pull/761).
* Add support for strict type check comparisons (=== and !==). Thanks
oughter. Merge of [#746](https://github.com/mozilla/nunjucks/pull/746).
* Allow full expressions (incl. filters) in import and from tags. Thanks legutierr.
Merge of [#710](https://github.com/mozilla/nunjucks/pull/710).
* OS agnostic file paths in precompile. Merge of [#825](https://github.com/mozilla/nunjucks/pull/825).
2.4.3 (Sep 7 2016)
----------------
* Fix potential cast-related XSS vulnerability in autoescape mode, and with `escape` filter.
Thanks Matt Austin for the report and Thomas Hunkapiller for the fix.
[#836](https://github.com/mozilla/nunjucks/pull/836)
2.4.2 (Apr 15 2016)
-------------------
* Fix use of `in` operator with strings. Fixes
[#714](https://github.com/mozilla/nunjucks/issues/714). Thanks Zubrik for the
report.
* Support ES2015 Map and Set in `length` filter. Merge of
[#705](https://github.com/mozilla/nunjucks/pull/705). Thanks ricordisamoa.
* Remove truncation of long function names in error messages. Thanks Daniel
Bendavid. Merge of [#702](https://github.com/mozilla/nunjucks/pull/702).
2.4.1 (Mar 17 2016)
-------------------
* Don't double-escape. Thanks legutierr. Merge of
[#701](https://github.com/mozilla/nunjucks/pull/701).
* Prevent filter.escape from escaping SafeString. Thanks atian25. Merge of
[#623](https://github.com/mozilla/nunjucks/pull/623).
* Throw an error if a block is defined multiple times. Refs
[#696](https://github.com/mozilla/nunjucks/issues/696).
* Officially recommend the `.njk` extension. Thanks David Kebler. Merge of
[#691](https://github.com/mozilla/nunjucks/pull/691).
* Allow block-set to wrap an inheritance block. Unreported; fixed as a side
effect of the fix for [#576](https://github.com/mozilla/nunjucks/issues/576).
* Fix `filter` tag with non-trivial contents. Thanks Stefan Cruz and Fabien
Franzen for report and investigation, Jan Oopkaup for failing tests. Fixes
[#576](https://github.com/mozilla/nunjucks/issues/576).
2.4.0 (Mar 10 2016)
-------------------
* Allow retrieving boolean-false as a global. Thanks Marius Büscher. Merge of
[#694](https://github.com/mozilla/nunjucks/pull/694).
* Don't automatically convert any for-loop that has an include statement into
an async loop. Reverts
[7d4716f4fd](https://github.com/mozilla/nunjucks/commit/7d4716f4fd), re-opens
[#372](https://github.com/mozilla/nunjucks/issues/372), fixes
[#527](https://github.com/mozilla/nunjucks/issues/527). Thanks Tom Delmas for
the report.
* Switch from Optimist to Yargs for argument-parsing. Thanks Bogdan
Chadkin. Merge of [#672](https://github.com/mozilla/nunjucks/pull/672).
* Prevent includes from writing to their including scope. Merge of
[#667](https://github.com/mozilla/nunjucks/pull/667) (only partially
backported to 2.x; macro var visibility not backported).
* Fix handling of `dev` environment option, to get full tracebacks on errors
(including nunjucks internals). Thanks Tobias Petry and Chandrasekhar Ambula
V for the report, Aleksandr Motsjonov for draft patch.
* Support using `in` operator to search in both arrays and objects,
and it will throw an error for other data types.
Fix [#659](https://github.com/mozilla/nunjucks/pull/659).
Thanks Alex Mayfield for report and test, Ouyang Yadong for fix.
Merge of [#661](https://github.com/mozilla/nunjucks/pull/661).
* Add support for `{% set %}` block assignments as in jinja2. Thanks Daniele
Rapagnani. Merge of [#656](https://github.com/mozilla/nunjucks/pull/656)
* Fix `{% set %}` scoping within macros.
Fixes [#577](https://github.com/mozilla/nunjucks/issues/577) and
the macro portion of [#561](https://github.com/mozilla/nunjucks/issues/561).
Thanks Ouyang Yadong. Merge of [#653](https://github.com/mozilla/nunjucks/pull/653).
* Add support for named `endblock` (e.g. `{% endblock foo %}`). Thanks
ricordisamoa. Merge of [#641](https://github.com/mozilla/nunjucks/pull/641).
* Fix `range` global with zero as stop-value. Thanks Thomas Hunkapiller. Merge
of [#638](https://github.com/mozilla/nunjucks/pull/638).
* Fix a bug in urlize that collapsed whitespace. Thanks Paulo Bu. Merge of
[#637](https://github.com/mozilla/nunjucks/pull/637).
* Add `sum` filter. Thanks Pablo Matías Lazo. Merge of
[#629](https://github.com/mozilla/nunjucks/pull/629).
* Don't suppress errors inside {% if %} tags. Thanks Artemy Tregubenko for
report and test, Ouyang Yadong for fix. Merge of
[#634](https://github.com/mozilla/nunjucks/pull/634).
* Allow whitespace control on comment blocks, too. Thanks Ouyang Yadong. Merge
of [#632](https://github.com/mozilla/nunjucks/pull/632).
* Fix whitespace control around nested tags/variables/comments. Thanks Ouyang
Yadong. Merge of [#631](https://github.com/mozilla/nunjucks/pull/631).
v2.3.0 (Jan 6 2016)
-------------------
* Return `null` from `WebLoader` on missing template instead of throwing an
error, for consistency with other loaders. This allows `WebLoader` to support
the new `ignore missing` flag on the `include` tag. If `ignore missing` is
not set, a generic "template not found" error will still be thrown, just like
for any other loader. Ajax errors other than 404 will still cause `WebLoader`
to throw an error directly.
* Add preserve-linebreaks option to `striptags` filter. Thanks Ivan
Kleshnin. Merge of [#619](https://github.com/mozilla/nunjucks/pull/619).
v2.2.0 (Nov 23 2015)
--------------------
* Add `striptags` filter. Thanks Anthony Giniers. Merge of
[#589](https://github.com/mozilla/nunjucks/pull/589).
* Allow compiled templates to be imported, included and extended. Thanks Luis
Gutierrez-Sheris. Merge of
[#581](https://github.com/mozilla/nunjucks/pull/581).
* Fix issue with different nunjucks environments sharing same globals. Each
environment is now independent. Thanks Paul Pechin. Merge of
[#574](https://github.com/mozilla/nunjucks/pull/574).
* Add negative steps support for range function. Thanks Nikita Mostovoy. Merge
of [#575](https://github.com/mozilla/nunjucks/pull/575).
* Remove deprecation warning when using the `default` filter without specifying
a third argument. Merge of
[#567](https://github.com/mozilla/nunjucks/pull/567).
* Add support for chaining of addGlobal, addFilter, etc. Thanks Rob Graeber. Merge of
[#537](https://github.com/mozilla/nunjucks/pull/537)
* Fix error propagation. Thanks Tom Delmas. Merge of
[#534](https://github.com/mozilla/nunjucks/pull/534).
* trimBlocks now also trims windows style line endings. Thanks Magnus Tovslid. Merge of
[#548](https://github.com/mozilla/nunjucks/pull/548)
* `include` now supports an option to suppress errors if the template does not
exist. Thanks Mathias Nestler. Merge of
[#559](https://github.com/mozilla/nunjucks/pull/559)
v2.1.0 (Sep 21 2015)
--------------------
* Fix creating `WebLoader` without `opts`. Merge of
[#524](https://github.com/mozilla/nunjucks/pull/524).
* Add `hasExtension` and `removeExtension` methods to `Environment`. Merge of
[#512](https://github.com/mozilla/nunjucks/pull/512).
* Add support for kwargs in `sort` filter. Merge of
[#510](https://github.com/mozilla/nunjucks/pull/510).
* Add `none` as a lexed constant evaluating to `null`. Merge of
[#480](https://github.com/mozilla/nunjucks/pull/480).
* Fix rendering of multiple `raw` blocks. Thanks Aaron O'Mullan. Merge of
[#503](https://github.com/mozilla/nunjucks/pull/503).
* Avoid crashing on async loader error. Thanks Samy Pessé. Merge of
[#504](https://github.com/mozilla/nunjucks/pull/504).
* Add support for keyword arguments for sort filter. Thanks Andres Pardini. Merge of
[#510](https://github.com/mozilla/nunjucks/pull/510)
v2.0.0 (Aug 30 2015)
--------------------
Most of the changes can be summed up in the
[issues tagged 2.0](https://github.com/mozilla/nunjucks/issues?q=is%3Aissue+milestone%3A2.0+is%3Aclosed).
Or you can
[see all commits](https://github.com/mozilla/nunjucks/compare/v1.3.4...f8aabccefc31a9ffaccdc6797938b5187e07ea87).
Most important changes:
* **autoescape is now on by default.** You need to explicitly pass `{
autoescape: false }` in the options to turn it off.
* **watch is off by default.** You need to explicitly pass `{ watch: true }` to
start the watcher.
* The `default` filter has changed. It will show the default value only if the
argument is **undefined**. Any other value, even false-y values like `false`
and `null`, will be returned. You can get back the old behavior by passing
`true` as a 3rd argument to activate the loose-y behavior: `foo |
default("bar", true)`. In 2.0 if you don't pass the 3rd argument, a warning
will be displayed about this change in behavior. In 2.1 this warning will be
removed.
* [New filter tag](http://mozilla.github.io/nunjucks/templating.html#filter)
* Lots of other bug fixes and small features, view the above issue list!
v1.3.4 (Apr 27 2015)
--------------------
This is an extremely minor release that only adds an .npmignore so that the
bench, tests, and docs folders do not get published to npm. Nunjucks should
download a lot faster now.
v1.3.3 (Apr 3 2015)
-------------------
This is exactly the same as v1.3.1, just fixing a typo in the git version tag.
v1.3.2 (Apr 3 2015)
-------------------
(no notes)
v1.3.1 (Apr 3 2015)
-------------------
We added strict mode to all the files, but that broke running nunjucks in the
browser. Should work now with this small fix.
v1.3.0 (Apr 3 2015)
-------------------
* Relative templates: you can now load a template relatively by starting the
path with ., like ./foo.html
* FileSystemLoader now takes a noCache option, if true will disable caching
entirely
* Additional lstripBlocks and trimBlocks available to clean output
automatically
* New selectattr and rejectattr filters
* Small fixes to the watcher
* Several bug fixes
v1.2.0 (Feb 4 2015)
-------------------
* The special non-line-breaking space is considered whitespace now
* The in operator has a lower precedence now. This is potentially a breaking
change, thus the minor version bump. See
[#336](https://github.com/mozilla/nunjucks/pull/336)
* import with context now implemented:
[#319](https://github.com/mozilla/nunjucks/pull/319)
* async rendering doesn't throw compile errors
v1.1.0 (Sep 30 2014)
--------------------
User visible changes:
* Fix a bug in urlize that would remove periods
* custom tag syntax (like {% and %}) was made Environment-specific
internally. Previously they were global even though you set them through the
Environment.
* Remove aggressive optimization that only emitted loop variables when uses. It
introduced several bugs and didn't really improve perf.
* Support the regular expression syntax like /foo/g.
* The replace filter can take a regex as the first argument
* The call tag was implemented
* for tags can now take an else clause
* The cycler object now exposes the current item as the current property
* The chokidar library was updated and should fix various issues
Dev changes:
* Test coverage now available via istanbul. Will automatically display after
running tests.
v1.0.7 (Aug 15 2014)
--------------------
Mixed up a few things in the 1.0.6 release, so another small bump. This merges
in one thing:
* The length filter will not throw an error is used on an undefined
variable. It will return 0 if the variable is undefined.
v1.0.6 (Aug 15 2014)
--------------------
* Added the addGlobal method to the Environment object
* import/extends/include now can take an arbitrary expression
* fix bugs in set
* improve express integration (allows rendering templates without an extension)
v1.0.5 (May 1 2014)
-------------------
* Added support for browserify
* Added option to specify template output path when precompiling templates
* Keep version comment in browser minified files
* Speed up SafeString implementation
* Handle null and non-matching cases for word count filter
* Added support for node-webkit
* Other various minor bugfixes
chokidar repo fix - v1.0.4 (Apr 4 2014)
---------------------------------------
* The chokidar dependency moved repos, and though the git URL should have been
forwarded some people were having issues. This fixed the repo and
version.
(v1.0.3 is skipped because it was published with a bad URL, quickly fixed with
another version bump)
Bug fixes - v1.0.2 (Mar 25 2014)
--------------------------------
* Use chokidar for watching file changes. This should fix a lot of problems on
OS X machines.
* Always use / in paths when precompiling templates
* Fix bug where async filters hang indefinitely inside if statements
* Extensions now can override autoescaping with an autoescape property
* Other various minor bugfixes
v1.0.1 (Dec 16, 2013)
---------------------
(no notes)
We've reached 1.0! Better APIs, asynchronous control, and more (Oct 24, 2013)
-----------------------------------------------------------------------------
* An asynchronous API is now available, and async filters, extensions, and
loaders is supported. The async API is optional and if you don't do anything
async (the default), nothing changes for you. You can read more about this
[here](http://jlongster.github.io/nunjucks/api.html#asynchronous-support). (fixes
[#41](https://github.com/mozilla/nunjucks/issues/41))
* Much simpler higher-level API for initiating/configuring nunjucks is
available. Read more
[here](http://jlongster.github.io/nunjucks/api.html#simple-api).
* An official grunt plugin is available for precompiling templates:
[grunt-nunjucks](https://github.com/jlongster/grunt-nunjucks)
* **The browser files have been renamed.** nunjucks.js is now the full library
with compiler, and nunjucks-slim.js is the small version that only works with
precompiled templates
* urlencode filter has been added
* The express integration has been refactored and isn't a kludge
anymore. Should avoid some bugs and be more future-proof;
* The order in which variables are lookup up in the context and frame lookup
has been reversed. It will now look in the frame first, and then the
context. This means that if a for loop introduces a new var, like {% for name
in names %}, and if you have name in the context as well, it will properly
reference name from the for loop inside the loop. (fixes
[#122](https://github.com/mozilla/nunjucks/pull/122) and
[#119](https://github.com/mozilla/nunjucks/issues/119))
v0.1.10 (Aug 9 2013)
--------------------
(no notes)
v0.1.9 (May 30 2013)
--------------------
(no notes)
v0.1.8 - whitespace controls, unpacking, better errors, and more! (Feb 6 2013)
------------------------------------------------------------------------------
There are lots of cool new features in this release, as well as many critical
bug fixes.
Full list of changes:
* Whitespace control is implemented. Use {%- and -%} to strip whitespace before/after the block.
* `for` loops implement Python-style array unpacking. This is a really nice
feature which lets you do this:
{% for x, y, z in [[2, 2, 2], [3, 3, 3]] %}
--{{ x }} {{ y }} {{ z }}--
{% endfor %}
The above would output: --2 2 2----3 3 3--
You can pass any number of variable names to for and it will destructure each
array in the list to the variables.
This makes the syntax between arrays and objects more
consistent. Additionally, it allows us to implement the `dictsort` filter
which sorts an object by keys or values. Technically, it returns an array of
2-value arrays and the unpacking takes care of it. Example:
{% for k, v in { b: 2, a: 1 } %}
--{{ k }}: {{ v }}--
{% endfor %}
Output: `--b: 2----a: 1--` (note: the order could actually be anything
because it uses javascript’s `for k in obj` syntax to iterate, and ordering
depends on the js implementation)
{% for k, v in { b: 2, a: 1} | dictsort %}
--{{ k }}: {{ v }}--
{% endfor %}
Output: `--a: 1----b: 2--`
The above output will always be ordered that way. See the documentation for
more details.
Thanks to novocaine for this!
* Much better error handling with at runtime (shows template/line/col information for attempting to call undefined values, etc)
* Fixed a regression which broke the {% raw %} block
* Fix some edge cases with variable lookups
* Fix a regression with loading precompiled templates
* Tweaks to allow usage with YUICompressor
* Use the same error handling as normal when precompiling (shows proper errors)
* Fix template loading on Windows machines
* Fix int/float filters
* Fix regression with super()
v0.1.7 - helpful errors, many bug fixes (Dec 12 2012)
-----------------------------------------------------
The biggest change in v0.1.7 comes from devoidfury (thanks!) which implements
consistent and helpful error messages. The errors are still simply raw text,
and not pretty HTML, but they at least contain all the necessary information to
track down an error, such as template names, line and column numbers, and the
inheritance stack. So if an error happens in a child template, it will print
out all the templates that it inherits. In the future, we will most likely
display the actual line causing an error.
Full list of changes:
* Consistent and helpful error messages
* Expressions are more consistent now. Previously, there were several places
that wouldn’t accept an arbitrary expression that should. For example, you
can now do {% include templateNames['foo'] %}, whereas previously you could
only give it a simply variable name.
* app.locals is fixed with express 2.5
* Method calls on objects now have correct scope for this. Version 0.1.6 broke
this and this was referencing the global scope.
* A check was added to enforce loading of templates within the correct
path. Previously you could load a file outside of the template with something
like ../../crazyPrivateFile.txt
You can
[view all the code changes here](https://github.com/jlongster/nunjucks/compare/v0.1.6...v0.1.7). Please
[file an issue](https://github.com/jlongster/nunjucks/issues?page=1&state=open)
if something breaks!
v0.1.6 - undefined handling, bugfixes (Nov 13, 2012)
----------------------------------------------------
This is mostly a bugfix release, but there are a few small tweaks based on
feedback:
* In some cases, backslashes in the template would not appear in the
output. This has been fixed.
* An error is thrown if a filter is not found
* Old versions of express are now supported (2.5.11 was tested)
* References on undefined objects are now suppressed. For example, {{ foo }},
{{ foo.bar }}, {{ foo.bar.baz }} all output nothing if foo is
undefined. Previously only the first form would be suppressed, and a cryptic
error thrown for the latter 2 references. Note: I believe this is a departure
from jinja, which throws errors when referencing undefined objects. I feel
that this is a good and non-breaking addition though. (thanks to devoidfury)
* A bug in set where you couldn’t not reference other variables is fixed
(thanks chriso and panta)
* Other various small bugfixes
You can view
[all the code changes here](https://github.com/jlongster/nunjucks/compare/v0.1.5...v0.1.6). As
always, [file an issue](https://github.com/jlongster/nunjucks/issues) if
something breaks!
v0.1.5 - macros, keyword arguments, bugfixes (Oct 11 2012)
----------------------------------------------------------
v0.1.5 has been pushed to npm, and it’s a big one. Please file any issues you
find, and I’ll fix them as soon as possible!
* The node data structure has been completely refactored to reduce redundancy
and make it easier to add more types in the future.
* Thanks to Brent Hagany, macros now have been implemented. They should act
exactly the way jinja2 macros do.
* A calling convention which implements keyword arguments now exists. All
keyword args are converted into a hash and passed as the last
argument. Macros needed this to implement keyword/default arguments.
* Function and filter calls apply the new keyword argument calling convention
* The “set” block now appropriately only sets a variable for the current scope.
* Many other bugfixes.
I’m watching this release carefully because of the large amount of code that
has changed, so please
[file an issue](https://github.com/jlongster/nunjucks/issues) if you have a
problem with it.
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Community Participation Guidelines
This repository is governed by Mozilla's code of conduct and etiquette guidelines.
For more details, please read the
[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
## How to Report
For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
Thanks for your interest in contributing! The advice below will help you get your issue fixed / pull request merged.
## Purpose
Nunjucks has the following purpose:
* Aim for templating feature parity with Jinja2.
* Aim for templating feature parity with Twig, but only when not conflicting with Jinja2 parity.
* Works in all node releases that are
[actively maintained by the Node Foundation](https://github.com/nodejs/Release#release-schedule)
* Works in all modern browsers (with [ES5 support](http://kangax.github.io/compat-table/es5/)).
* Works in IE8 with [es5-shim](https://github.com/es-shims/es5-shim).
* Keep footprint browser files as small as possible (save on bandwidth, download time).
* Keep performance as fast as possible (see benchmarks).
* Keep maintenance as easy as possible (avoid complexity, automate what we can).
Notes:
* We don't aim for parity of all language specific syntax.
* We don't aim for parity of language specific filters like [Twig's PHP date format](http://twig.sensiolabs.org/doc/functions/date.html).
Issues and pull requests contributing to this purpose have the best chance to make it into Nunjucks.
## Questions?
Please DO NOT ask "how do I?" or usage questions via GitHub issues. Instead,
use the [mailing list](https://groups.google.com/forum/#!forum/nunjucks).
## Submitting Issues
Issues are easier to reproduce/resolve when they have:
- A pull request with a failing test demonstrating the issue
- A code example that produces the issue consistently
- A traceback (when applicable)
## Pull Requests
When creating a pull request:
- Write tests (see below).
- Note user-facing changes in the [`CHANGELOG.md`](CHANGELOG.md) file.
- Update the documentation (in [`docs/`](docs/)) as needed.
## Testing
Please add tests for any changes you submit. The tests should fail before your
code changes, and pass with your changes. Existing tests should not break. Test
coverage (output at the end of every test run) should never decrease after your
changes.
To install all the requirements for running the tests:
```bash
npm install
```
To run the tests:
```bash
npm test
```
================================================
FILE: LICENSE
================================================
Copyright (c) 2012-2015, James Long
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: MAINTENANCE.md
================================================
# Pushing a New Version
Nunjucks attempts to adhere to semantic versioning. The API is very stable, so
from here on out it will most likely be point releases.
1. Do a `pull` from github to make sure you have all the latest updates.
2. View all the changes since the last version:
```
$ git log --oneline v1.2.3..master
```
Replace `v1.2.3` with whatever the last version was, and you'll see all the
changes going out in this version. Ensure that all significant user-facing
changes (new features and bugfixes) are mentioned in `CHANGELOG.md`. Change the
"master (unreleased)" heading in `CHANGELOG.md` to the new version number and
date.
3. Update the version in `package.json`.
3. Run the command to update the ready-made files for the browser.
```
$ npm run browserfiles
```
5. Commit above changes and push to `master` (or a release branch, if using one).
6. Draft a new release on GitHub and copy the changelog to the description. The
tag and title should both be the version, in the form `v2.3.0`. Publish the
release.
7. Publish to npm:
```
npm publish
```
8. Make sure docs are up-to-date. You need to copy all the `nunjucks*.js` files
in `browser/` to the docs. This is where the "download" link points to in
the docs. You also need to copy the tests into the docs, for the online
browser tests. ``make prod`` in the ``docs/`` dir will handle these tasks
for you. Push (force push if necessary) the build out _site folder onto the
`gh-pages` branch of the `nunjucks` repo to get it live. One way to do that
is the following commands. These commands presume that you have another
nunjucks git clone inside the (git-ignored) `docs/_site` directory, checked
out to the `gh-pages` branch (and tracking `origin/gh-pages`). (To set that
up the first time, `cd docs/_site`, `rm -rf *`, `git clone
git@github.com:mozilla/nunjucks.git .`, and `git checkout gh-pages`).
```
cd docs && make prod
cd files
python -m SimpleHTTPServer
# load http://localhost:8000/tests/browser/ and verify tests pass in browser
cd ../_site && git add -A && git commit && git push
```
9. Add a new "master (unreleased)" section at the top of `CHANGELOG.md`.
10. Bump the version number in `package.json` to a development pre-release of
the next anticipated release number (e.g. "2.2.0-dev.1").
================================================
FILE: README.md
================================================
# Nunjucks
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![CI][github-actions-image]][github-actions-url]
[![Codecov][codecov-image]][codecov-url]
[Nunjucks](https://mozilla.github.io/nunjucks/) is a full featured
templating engine for javascript. It is heavily inspired by
[jinja2](https://jinja.palletsprojects.com/). View the docs
[here](https://mozilla.github.io/nunjucks/).
## Installation
`npm install nunjucks`
To use the file watcher built-in to Nunjucks, Chokidar must be installed separately.
`npm install nunjucks chokidar`
(View the [CHANGELOG](https://github.com/mozilla/nunjucks/releases))
## Documentation
Nunjucks info and documentation source is in [`/docs`](/docs) and publishes to https://mozilla.github.io/nunjucks/
## Browser Support
Supported in all modern browsers. For IE8 support, use [es5-shim](https://github.com/es-shims/es5-shim).
## Tests
Run the tests with `npm test`.
## Get in touch
If you have ideas or questions, or need help, you can reach us in the [#nunjucks:mozilla.org](https://matrix.to/#/#nunjucks:mozilla.org) room on [Matrix](https://wiki.mozilla.org/Matrix).
## Want to help?
Contributions are always welcome! Before you submit an issue or pull request, please read our [contribution guidelines](CONTRIBUTING.md).
## Contributors
[](https://github.com/mozilla/nunjucks/graphs/contributors)
[npm-image]: https://img.shields.io/npm/v/nunjucks.svg
[npm-url]: https://npmjs.org/package/nunjucks
[downloads-image]: https://img.shields.io/npm/dm/nunjucks.svg
[downloads-url]: https://npmjs.org/package/nunjucks
[github-actions-image]: https://github.com/mozilla/nunjucks/actions/workflows/tests.yml/badge.svg
[github-actions-url]: https://github.com/mozilla/nunjucks/actions
[codecov-image]: https://img.shields.io/codecov/c/gh/mozilla/nunjucks.svg
[codecov-url]: https://codecov.io/gh/mozilla/nunjucks/branch/master
================================================
FILE: bench/case.html
================================================
")
end
def block_code(code, lang)
require 'pygments'
lang = lang && lang.split.first || "text"
output = add_code_tags(Pygments.highlight(code, :lexer => lang, :options => { :encoding => 'utf-8' }),
lang) + "\n"
end
end
def render(context)
content = @nodelist.map { |token|
token.respond_to?(:render) ? token.render(context) : token
}.join.strip!
content = content.split(/\n/)
name = content[0]
sig = content[1]
desc = content[2..-1].join("\n")
desc = Redcarpet::Markdown.new(@@renderer.new,
fenced_code_blocks: true).render(desc)
'### ' + name + "\n\n
" + sig + "
\n" +
"
" + desc + "
\n"
end
end
end
Liquid::Template.register_tag('api', Jekyll::ApiTag)
================================================
FILE: docs/_plugins/cleanup.rb
================================================
module Jekyll
module Converters
class Markdown
def convert(content)
setup
content = @parser.convert(content)
names = {}
content.gsub(/toc_\d*">([^<]*)/) {
name = $1
slug = name.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
if names.has_key?(slug)
i = 1
newSlug = slug + i.to_s
while names.has_key?(newSlug)
i = i + 1
newSlug = slug + i.to_s
end
slug = newSlug
end
names[slug] = true
slug + '">' + name
}
end
end
end
end
================================================
FILE: docs/_plugins/locale.rb
================================================
# -*- coding: utf-8 -*-
module Jekyll
module LocaleFilter
def locale_buttons(url, baseurl)
if url.start_with?('/cn/')
en_url = File.join(baseurl, url.sub(/^\/cn\//, '/'))
cn_url = File.join(baseurl, url)
fr_url = File.join(baseurl, url.sub(/^\/cn\//, '/fr/'))
'English' +
'中文' +
'Français'
else
if url.start_with?('/fr/')
en_url = File.join(baseurl, url.sub(/^\/fr\//, '/'))
cn_url = File.join(baseurl, url.sub(/^\/fr\//, '/cn/'))
fr_url = File.join(baseurl, url)
'English' +
'中文' +
'Français'
else
en_url = File.join(baseurl, url)
cn_url = File.join(baseurl, url.sub(/^\//, '/cn/'))
fr_url = File.join(baseurl, url.sub(/^\//, '/fr/'))
'English' +
'中文' +
'Français'
end
end
end
end
end
Liquid::Template::register_filter(Jekyll::LocaleFilter)
================================================
FILE: docs/_plugins/page_toc.rb
================================================
require 'redcarpet';
module Jekyll
class PageTocTag < Liquid::Tag
def initialize(tag_name, args, tokens)
end
def render(context)
content = File.open(context.environments.first["page"]["path"]).read
content = content.gsub(/^---.*\n---/m, '')
content = content.gsub(/^{% api %}\n([^\n]*)/m, '### \1')
names = {}
content = Redcarpet::Markdown.new(Redcarpet::Render::HTML_TOC).render(content)
content.gsub(/toc_\d*">([^<]*)/) {
name = $1
slug = name.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
if names.has_key?(slug)
i = 1
newSlug = slug + i.to_s
while names.has_key?(newSlug)
i = i + 1
newSlug = slug + i.to_s
end
slug = newSlug
end
names[slug] = true
slug + '">' + name
}
end
end
end
Liquid::Template.register_tag('page_toc', Jekyll::PageTocTag)
================================================
FILE: docs/api.md
================================================
---
layout: subpage
title: API
---
{% raw %}
# API
The API for nunjucks covers rendering templates, adding filters and
extensions, customizing template loading, and more.
## User-Defined Templates Warning
nunjucks does not sandbox execution so **it is not safe to run
user-defined templates or inject user-defined content into template
definitions**. On the server, you can expose attack vectors for
accessing sensitive data and remote code execution. On the client,
you can expose cross-site scripting vulnerabilities even for
precompiled templates (which can be mitigated with a strong
[CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)). See
[this issue](https://github.com/mozilla/nunjucks-docs/issues/17) for
more information.
## Simple API
If you don't need deep customization of the system, you can use this simple
higher-level API for loading and rendering templates.
{% endraw %}
{% api %}
render
nunjucks.render(name, [context], [callback])
Renders the template named **name** with the **context** hash. If
**callback** is provided, it will be called when done with any
possible error as the first argument and the result as the second.
Otherwise, the result is returned from `render` and errors are thrown.
See [asynchronous support](#asynchronous-support) for more info.
See the warning about **not allowing [users to define their own
templates](#user-defined-templates-warning).**
```js
var res = nunjucks.render('foo.html');
var res = nunjucks.render('foo.html', { username: 'James' });
nunjucks.render('async.html', function(err, res) {
});
```
{% endapi %}
{% api %}
renderString
nunjucks.renderString(str, context, [callback])
Same as [`render`](#render), but renders a raw string instead of
loading a template.
The same warning about **not allowing [users to define their own
templates](#user-defined-templates-warning)** applies.
{% raw %}
```js
var res = nunjucks.renderString('Hello {{ username }}', { username: 'James' });
```
{% endraw %}
{% endapi %}
{% api %}
compile
nunjucks.compile(str, [env], [path])
Compile the given string into a reusable nunjucks Template object.
{% raw %}
```js
var template = nunjucks.compile('Hello {{ username }}');
template.render({ username: 'James' });
```
{% endraw %}
{% endapi %}
{% api %}
configure
nunjucks.configure([path], [opts]);
Tell nunjucks that your templates live at **path** and flip any
feature on or off with the **opts** hash. You can provide both
arguments or either of them. **path** defaults to the current working
directory, and the following options are available in **opts**:
* **autoescape** *(default: true)* controls if output with dangerous characters are
escaped automatically. See [Autoescaping](#autoescaping)
* **throwOnUndefined** *(default: false)* throw errors when outputting a null/undefined value
* **trimBlocks** *(default: false)* automatically remove trailing newlines from a block/tag
* **lstripBlocks** *(default: false)* automatically remove leading whitespace from a block/tag
* **watch** *(default: false)* reload templates when they are changed (server-side). To use watch, make sure optional dependency *chokidar* is installed.
* **noCache** *(default: false)* never use a cache and recompile templates each time (server-side)
* **web** an object for configuring loading templates in the browser:
* **useCache** *(default: false)* will enable cache and templates will never see updates.
* **async** *(default: false)* will load templates asynchronously instead of synchronously (requires use of the [asynchronous API](#asynchronous-support) for rendering).
* **express** an express app that nunjucks should install to
* **tags:** *(default: see nunjucks syntax)* defines the syntax for
nunjucks tags. See [Customizing Syntax](#customizing-syntax)
`configure` returns an `Environment` instance, which lets you add
filters and extensions while still using the simple API. See below for
more information on `Environment`.
**Warning**: The simple API (above; e.g. `nunjucks.render`) always uses the
configuration from the most recent call to `nunjucks.configure`. Since this
is implicit and can result in unexpected side effects, use of the simple API
is discouraged in most cases (especially if `configure` is used); instead,
explicitly create an environment using `var env = nunjucks.configure(...)`
and then call `env.render(...)` etc.
```js
nunjucks.configure('views');
// if in the browser, you probably want to use an absolute URL
nunjucks.configure('/views');
nunjucks.configure({ autoescape: true });
nunjucks.configure('views', {
autoescape: true,
express: app,
watch: true
});
var env = nunjucks.configure('views');
// do stuff with env
```
{% endapi %}
{% api %}
installJinjaCompat
nunjucks.installJinjaCompat()
This installs experimental support for more consistent Jinja
compatibility by adding Pythonic APIs to the environment. While
nunjucks does not aim for complete Jinja/Python compatibility, this
might help users seeking just that.
This adds `True` and `False` which map to the JS `true` and `false`
values, allows use of Python slice syntax, and augments arrays and
objects with Python-style methods.
[Check out the source](https://github.com/mozilla/nunjucks/blob/master/nunjucks/src/jinja-compat.js)
to see everything it adds.
{% endapi %}
{% raw %}
*That's it for the simple API! If you want total control over how
templates are loaded, and more customization, you need to manually
set up the system as seen below.*
## Environment
The `Environment` class is the central object which handles templates.
It knows how to load your templates, and internally templates depend
on it for inheritance and including templates. The simple API above
dispatches everything to an `Environment` instance that it keeps for
you.
You can manually handle it if you want, which allows you to specify
custom template loaders.
{% endraw %}
{% api %}
constructor
new Environment([loaders], [opts])
The constructor takes a list of **loaders** and a hash of
configuration parameters as **opts**. If **loaders** is null, it
defaults to loading from the current directory or URL. You can pass a
single loader or an array of loaders. If you pass an array of loaders,
nunjucks will walk through them in order until one of them finds a
template. See [`Loader`](#loader) for more info about loaders.
The available flags in **opts** is **autoescape**,
**throwOnUndefined**, **trimBlocks**, and **lstripBlocks**.
Read more about those options in [`configure`](#configure) (the
express and watch options are not applicable here and configured
elsewhere like [`env.express`](#express)).
In node, the [`FileSystemLoader`](#filesystemloader) is available to
load templates off the filesystem, and in the browser the [`WebLoader`](#webloader)
is available to load over HTTP (or use precompiled templates). If you
use the simple [`configure`](#configure) API, nunjucks automatically
creates the appropriate loader for you, depending if you're in node or
the browser. See [`Loader`](#loader) for more information.
Also only in node, [`NodeResolveLoader`](#noderesolveloader) is
provided to allow templates to be included using
[node `require` resolution](https://nodejs.org/api/modules.html#modules_all_together).
This is not enabled by default with [`configure`](#configure), it must be
explicitly passed into the `Environment` constructor.
```js
// the FileSystemLoader is available if in node
var env = new nunjucks.Environment(new nunjucks.FileSystemLoader('views'));
var env = new nunjucks.Environment(new nunjucks.FileSystemLoader('views'),
{ autoescape: false });
var env = new nunjucks.Environment([new nunjucks.FileSystemLoader('views'),
new MyCustomLoader()]);
// the WebLoader is available if in the browser
var env = new nunjucks.Environment(new nunjucks.WebLoader('/views'));
```
{% endapi %}
{% api %}
render
env.render(name, [context], [callback])
Render the template named **name** with the optional **context** hash.
If **callback** is supplied, call it when done with any errors and the
result (see [asynchronous support](#asynchronous-support)), otherwise
return the rendered string.
```js
var res = nunjucks.render('foo.html');
var res = nunjucks.render('foo.html', { username: 'James' });
nunjucks.render('async.html', function(err, res) {
});
```
{% endapi %}
{% api %}
renderString
env.renderString(src, [context], [callback])
Same as [`render`](#render1), but renders a raw string instead of
loading a template.
{% raw %}
```js
var res = nunjucks.renderString('Hello {{ username }}', { username: 'James' });
```
{% endraw %}
{% endapi %}
{% api %}
addFilter
env.addFilter(name, func, [async])
Add a custom filter named **name** which calls **func** whenever
invoked. If the filter needs to be async, **async** must be `true`
(see [asynchronous support](#asynchronous-support)). Returns `env` for further method chaining. See
[Custom Filters](#custom-filters).
{% endapi %}
{% api %}
getFilter
env.getFilter(name)
Get the filter, which is just a function, named **name**.
{% endapi %}
{% api %}
addExtension
env.addExtension(name, ext)
Add the custom extension **ext** named **name**. **ext** is an object
with a few specific methods that are called by the extension system. Returns `env` for further method chaining.
See [Custom Tags](#custom-tags).
{% endapi %}
{% api %}
removeExtension
env.removeExtension(name)
Remove a previously added custom extension named **name**.
{% endapi %}
{% api %}
getExtension
env.getExtension(name)
Get an extension named **name**.
{% endapi %}
{% api %}
hasExtension
env.hasExtension(name)
Return true if a custom extension named **name** has been added.
{% endapi %}
{% api %}
addGlobal
env.addGlobal(name, value)
Add a global value that will be available to all templates. Note: this will overwrite any existing global called `name`.
Returns `env` for further method chaining.
{% endapi %}
{% api %}
getGlobal
env.getGlobal(name)
Get a global named **name**.
{% endapi %}
{% api %}
getTemplate
env.getTemplate(name, [eagerCompile], [callback])
Retrieve the template named **name**. If **eagerCompile** is `true`,
compile it now instead of on render. If **callback** is supplied, call
it with any errors and a template (if found), otherwise return
synchronously. If using any async loaders, you must use the async API.
The builtin loaders do not require this. See
[asynchronous support](#asynchronous-support) and [loaders](#loader).
```js
var tmpl = env.getTemplate('page.html');
var tmpl = env.getTemplate('page.html', true);
env.getTemplate('from-async-loader.html', function(err, tmpl) {
});
```
{% endapi %}
{% api %}
express
env.express(app)
Install nunjucks as the rendering engine for the express **app**.
After doing this, you can use express normally. Note that you can do
this automatically with the simple API call [`configure`](#configure)
by passing in the app as the **express** option. Returns `env` for further method chaining.
```js
var app = express();
env.express(app);
app.get('/', function(req, res) {
res.render('index.html');
});
```
{% endapi %}
{% api %}
opts.autoescape
env.opts.autoescape
You can use this boolean property to see if autoescaping is turned on
globally or not. This may be helpful in creating advanced filtering
that do HTML manipulation. Normally you should simply return a
SafeString (to be documented) if one was passed in, so the output will
copy the safeness of the input, but this property is helpful in rare
circumstances.
{% endapi %}
{% api %}
'load' event
env.on('load', function(name, source, loader))
The 'load' event gets emitted whenever a Loader retrieves the source of a
template. It can be listened to in order to determine template dependencies
at runtime. The arguments emitted to the callback are:
* **name** *(String)* The template name, as passed to the loader
* **source** *(Object)* The object that gets returned from Loader.getSource
* **src** *(String)* The template source
* **path** *(String)* The full path to the template
* **noCache** *(Bool)* If `true`, the template wasn't cached.
* **loader** The Loader instance that triggered the event.
{% endapi %}
{% raw %}
## Template
A `Template` is an object that handles the compiling of template
strings and rendering them. Usually the `Environment` handles them for
you, but you can easily use it yourself. If you don't connect a
template with an environment, you can't include or inherit any other
templates.
{% endraw %}
{% api %}
constructor
new Template(src, [env], [path], [eagerCompile])
The constructor takes a template string **src**, an optional
`Environment` instance **env** to use for loading other templates, a
string **path** describing the location/path for debugging purposes,
and a boolean **eagerCompile** which, if `true`, kicks off compilation
immediately instead of waiting until the template is rendered.
{% raw %}
```js
var tmpl = new nunjucks.Template('Hello {{ username }}');
tmpl.render({ username: "James" }); // -> "Hello James"
```
{% endraw %}
{% endapi %}
{% api %}
render
tmpl.render(context, [callback])
Renders the template with the optional **context** hash. If
**callback** is supplied, call it when done with any errors and the
result (see [asynchronous support](#asynchronous-support)), otherwise
return the rendered string.
{% endapi %}
{% raw %}
## Loader
A loader is an object that takes a template name and loads it from a
source, such as the filesystem or network. The following two builtin
loaders exist, each for different contexts.
{% endraw %}
{% api %}
FileSystemLoader
new FileSystemLoader([searchPaths], [opts])
This is only available to node. It will load templates from the
filesystem, using the **searchPaths** array as paths to look for
templates. **searchPaths** can also be a single path for where
templates live, and it defaults to the current working directory.
**opts** is an object with the following optional properties:
* **watch** - if `true`, the system will automatically update templates. To use watch, make sure optional dependency *chokidar* is installed.
when they are changed on the filesystem
* **noCache** - if `true`, the system will avoid using a cache and templates
will be recompiled every single time
```js
// Loads templates from the "views" folder
var env = new nunjucks.Environment(new nunjucks.FileSystemLoader('views'));
```
{% endapi %}
{% api %}
NodeResolveLoader
new NodeResolveLoader([opts])
As the name suggests, this is also only available in node. It will load
templates from the filesystem using node's
[`require.resolve`](https://nodejs.org/api/modules.html#modules_all_together).
**opts** is an object which takes the same properties as
[`FileSystemLoader`](#filesystemloader).
{% endapi %}
{% api %}
WebLoader
new WebLoader([baseURL], [opts])
This is only available in the browser. **baseURL** is the URL to load
templates from (must be the same domain), and it defaults to the
current relative directory.
**opts** is an object with the following optional properties:
* **useCache** if `true`, templates will be forever cached and you
won't see updates to them. The cache is disabled by default
because there is no way to watch for changes and dirty the cache.
Remember, you should be precompiling your templates for production.
* **async** if `true`, templates will be loaded asynchronously instead
synchronously. You must use the asynchronous render API when using
this (pass a callback to `render`).
This loader also recognizes when precompiled templates are available
and automatically uses them instead of fetching over HTTP. In
production, this should always be the case. See
[Precompiling](#precompiling).
```js
// Load templates from /views
var env = new nunjucks.Environment(new nunjucks.WebLoader('/views'))
```
{% endapi %}
{% raw %}
### Writing a Loader
You can write loaders for more complex loading, like from a database.
If you want to do this, just create an object that has a method
`getSource(name)`, where **name** is the name of the template. That's it.
```js
function MyLoader(opts) {
// configuration
}
MyLoader.prototype.getSource = function(name) {
// load the template
// return an object with:
// - src: String. The template source.
// - path: String. Path to template.
// - noCache: Bool. Don't cache the template (optional).
}
```
It can get a little more complex. If you want to track updates to
templates and bust the internal cache so that you can see updates, you
need to extend the `Loader` class. This gives you `emit` method that
can fire events. You need to call it
```js
var MyLoader = nunjucks.Loader.extend({
init: function() {
// setup a process which watches templates here
// and call `this.emit('update', name)` when a template
// is changed
},
getSource: function(name) {
// load the template
}
});
```
#### Asynchronous
There's one last piece: asynchronous loaders. So far, all of the
loaders have been synchronous; `getSource` returns the source
immediately. The benefit of this is that the user isn't forced to use
the asynchronous API and be aware of edge cases about async templates.
You might want to load from a database, however.
Just add an `async: true` property to your loader and it will be used
asynchronously.
```js
var MyLoader = nunjucks.Loader.extend({
async: true,
getSource: function(name, callback) {
// load the template
// ...
callback(err, res);
}
});
```
Remember that you now have to use the asynchronous API. See
[asynchronous support](#asynchronous-support).
**Warning**: if you are using an asynchronous loader, you can't load
templates inside `for` loops. You need to explicitly use the
`asyncEach` tag if you need to load templates, which is exactly the
same as `for` but asynchronous. More info can be found at
[Be Careful!](#be-careful).
## Browser Usage
Using nunjucks in the browser takes a little more thought because you
care about load and compile time. On the server-side, templates are
compiled once and cached in memory and you never have to worry about
it. On the client-side however, you don't want to compile templates
even once, as it would result in slow page render time.
The solution is to precompile your templates into JavaScript, and load
them as a simple `.js` file on page load.
Maybe you do want to dynamically load templates while developing,
however, so that you can see changes immediately without recompiling.
Nunjucks tries to adapt to whatever workflow you want.
The only rule you must follow: **always precompile your templates in
production**. Why? Not only is it slow to compile all your templates
on page load, they are loaded *synchronously* over HTTP, blocking the
whole page. It is slow. It does this because nunjucks isn't async by
default.
### Recommended Setups
These are two of the most popular ways to set up nunjucks on the
client-side. Note that there are two different js files: one with the
compiler, nunjucks.js, and one without the compiler, nunjucks-slim.js.
Read [Getting Started](getting-started.html) for a brief overview of
the differences.
See [Precompiling](#precompiling) for information on precompiling
templates.
#### Setup #1: only precompile in production
This method will give you a setup that dynamically loads templates
while developing (you can see changes immediately), but uses
precompiled templates in production.
1. Load [nunjucks.js](files/nunjucks.js) with either a script tag or a module loader.
2. Render templates ([example](#simple-api))!
3. When pushing to production, [precompile](#precompiling) the templates into a js file
and load it on the page
> An optimization is to use `nunjucks-slim.js` instead of
> `nunjucks.js` in production since you are using precompiled
> templates there. It's 8K instead of 20K because it doesn't contain
> the compiler. This complicates the setup though because you are
> using different js files between dev and prod, so it may or may not
> be worth it.
#### Setup #2: always precompile
This method always uses precompiled templates while developing and in
production, which simplifies the setup. However, you're going to want
something that automatically recompiles templates while developing
unless you want to manually recompile them after every change.
1. For development, use the [grunt](https://github.com/jlongster/grunt-nunjucks) or
[gulp](https://github.com/sindresorhus/gulp-nunjucks) tasks to watch your template
directory for changes and automatically [precompile](#precompiling) them into a js file
2. Load [nunjucks-slim.js](files/nunjucks-slim.js) and `templates.js`, or whatever you named
the precompiled js file, with either a script tag or a module loader.
3. Render templates ([example](#simple-api))!
With this method, there are no differences between development and
production code. Simply commit the templates.js file and deploy the
same code to production.
## Precompiling
To precompile your templates, use the `nunjucks-precompile` script
that comes with nunjucks. You can pass it a directory or a file and it
will generate all the JavaScript for your templates.
```
// Precompiling a whole directory
$ nunjucks-precompile views > templates.js
// Precompiling individual templates
$ nunjucks-precompile views/base.html >> templates.js
$ nunjucks-precompile views/index.html >> templates.js
$ nunjucks-precompile views/about.html >> templates.js
```
All you have to do is simply load `templates.js` on the page, and the
system will automatically use the precompiled templates. There are
zero changes necessary.
There are various options available to the script. Simply invoke
`nunjucks-precompile` to see more info about them. Note that **names
of all asynchronous filters need to passed to the script** since they
need to be known at compile-time. You can pass a comma-delimited list
of async filters with `-a`, like `-a foo,bar,baz`. If you only use
normal synchronous filters, you don't need to do anything.
Extensions cannot be specified with this script. You must use the
precompile API below if you use them.
### API
There is also an API if you want to programmatically precompile
templates. You'll want to do this if you use extensions or you use
asynchronous filters, both of which need to be known at compile-time.
You can pass an `Environment` object straight into the precompiler and
it will get the extensions and filters from it. You should share the
same `Environment` object between the client and server to keep
everything in sync.
{% endraw %}
{% api %}
precompile
nunjucks.precompile(path, [opts])
Precompile a file or directory at **path**. **opts** is a hash with any of the following options:
* **name**: name of the template, when compiling a string (required)
or a file (optional, defaults to **path**). names are
auto-generated when compiling a directory.
* **asFunction**: generate a callable function
* **force**: keep compiling on error
* **env**: the Environment to use (gets extensions and async filters from it)
* **include**: array of file/folders to include (folders are auto-included, files are auto-excluded)
* **exclude**: array of file/folders to exclude (folders are auto-included, files are auto-excluded)
* **wrapper**: `function(templates, opts)` Customize the output format of the precompiled templates. This function must return a string
* **templates**: array of objects with the following properties:
* **name**: name of the template
* **template**: string source of the precompiled template in javascript
* **opts**: object of all the above options
```js
var env = new nunjucks.Environment();
// extensions must be known at compile-time
env.addExtension('MyExtension', new MyExtension());
// async filters must be known at compile-time
env.addFilter('asyncFilter', function(val, cb) {
// do something
}, true);
nunjucks.precompile('/dir/to/views', { env: env });
```
{% endapi %}
{% api %}
precompileString
nunjucks.precompileString(str, [opts])
Exactly the same as [`precompile`](#precompile), but compiles a raw string.
{% endapi %}
{% raw %}
## Asynchronous Support
You only need to read this section if you are interested in
asynchronous rendering. There is no performance benefit to this, it is
solely to allow custom filters and extensions to make async calls. If
you don't care about this, you should simply use the normal API like
`var res = env.render('foo.html');`. There's no need to force the
`callback` on you, and it's why it's optional in all the rendering
functions.
As of version 1.0, nunjucks provides a way to render templates
asynchronously. This means that custom filters and extensions can do
stuff like fetch things from the database, and template rendering is
"paused" until the callback is called.
Template loaders can be async as well, allowing you to load templates
from a database or somewhere else. See
[Writing a Loader](#writing-a-loader). If you are using an async
template loader, you must use the async API. The builtin loaders that
load from the filesystem and over HTTP are synchronous, which is not a
performance problem because they are cached from the filesystem and
you should precompile your templates and never use HTTP in production.
If you are using anything async, you need to use the async API like this:
```js
nunjucks.render('foo.html', function(err, res) {
// check err and handle result
});
```
Read more about async [`filters`](#asynchronous1), [`extensions`](#asynchronous2), and
[`loaders`](#asynchronous).
### Be Careful!
Nunjucks is synchronous by default. Because of this, you need to
follow a few rules when writing asynchronous templates:
* Always use the async API. `render` should take a function that takes
a callback.
* Async filters and extensions need to be known at compile-time, so
you need to specify them explicitly when precompiling (see
[Precompiling](#precompiling)).
* If you are using a custom template loader that is asynchronous, you
can't include templates inside a `for` loop. This is because `for`
will compile to an imperative JavaScript `for` loop. You need to
explicitly use the async `asyncEach` tag to iterate, which is
exactly the same as `for` except asynchronous.
## Autoescaping
By default, nunjucks will escape all output. It's recommended
that you do this for security reasons. If you turn off autoescaping,
nunjucks will render all output as it is by default.
To deactivate it, all you have to do is pass the `autoescape` option as
`false` to the `Environment` object.
```js
var env = nunjucks.configure('/path/to/templates', { autoescape: false });
```
## Customizing Syntax
If you want different tokens than `{{` and the rest for variables,
blocks, and comments, you can specify different tokens as the `tags`
option:
```js
var env = nunjucks.configure('/path/to/templates', {
tags: {
blockStart: '<%',
blockEnd: '%>',
variableStart: '<$',
variableEnd: '$>',
commentStart: '<#',
commentEnd: '#>'
}
});
```
Using this environment, templates will look like this:
```
<% for item in items %>
<$ item $>
<% endfor %>
```
## Custom Filters
To install a custom filter, use the `Environment` method `addFilter`.
A filter is simply a function that takes the target object as the
first argument and any arguments passed to the filter as the other
arguments, in order.
```js
var nunjucks = require('nunjucks');
var env = new nunjucks.Environment();
env.addFilter('shorten', function(str, count) {
return str.slice(0, count || 5);
});
```
This adds a filter `shorten` which returns the first `count`
characters in a string, with `count` defaulting to 5. Here is how it
is used:
```jinja
{# Show the first 5 characters #}
A message for you: {{ message|shorten }}
{# Show the first 20 characters #}
A message for you: {{ message|shorten(20) }}
```
### Keyword/Default Arguments
As described in the
[templating section](templating#keyword-arguments), nunjucks supports
keyword/default arguments. You can write a normal javascript filter
that leverages them.
All keyword arguments are passed in as a hash as the last argument.
This is a filter `foo` that uses keyword arguments:
```js
env.addFilter('foo', function(num, x, y, kwargs) {
return num + (kwargs.bar || 10);
})
```
The template can use it like this:
```jinja
{{ 5 | foo(1, 2) }} -> 15
{{ 5 | foo(1, 2, bar=3) }} -> 8
```
You *must* pass all of the positional arguments before keyword
arguments (`foo(1)` is valid but `foo(1, bar=10)` is not). Also, you
cannot set a positional argument with a keyword argument like you can
in Python (such as `foo(1, y=1)`)
### Asynchronous
Asynchronous filters receive a callback to resume rendering, and are
created by passing `true` as the third argument to `addFilter`.
```js
var env = nunjucks.configure('views');
env.addFilter('lookup', function(name, callback) {
db.getItem(name, callback);
}, true);
env.renderString('{{ item|lookup }}', function(err, res) {
// do something with res
});
```
Make sure to call the callback with two arguments: `callback(err, res)`. `err` can be null, of course.
Note: When precompiling, **you must tell the precompiler the names of
all asynchronous filters**. See
[Precompiling](#precompiling).
## Custom Tags
You can create more complicated extensions by creating custom tags.
This exposes the parser API and allows you to do anything you want
with the template.
Note: When precompiling, **you must install the extensions at
compile-time**. You have to use the [precompiling API](#api1) (or the
[grunt](https://github.com/jlongster/grunt-nunjucks) or
[gulp](https://github.com/sindresorhus/gulp-nunjucks) tasks) instead of
the script. You'll want to create an [`Environment`](#environment)
object, install your extensions, and pass it to the precompiler.
An extension is a javascript object with at least two fields: `tags`
and `parse`. Extensions basically register new tag names and take
control of the parser when they are hit.
`tags` is an array of tag names that the extension should handle.
`parse` is the method that actually parses them when the template is
compiled. Additionally, there is a special node type `CallExtension`
that you can use to call any method on your extension at runtime. This
is explained more below.
Because you have to interact directly with the parse API and construct
ASTs manually, this is a bit cumbersome. It's necessary if you want to
do really complex stuff, however. Here are a few key parser methods
you'll want to use:
* `parseSignature([throwErrors], [noParens])` - Parse a list of
arguments. By default it requires the parser to be pointing at the
left opening parenthesis, and parses up the right one. However, for
custom tags you shouldn't use parentheses, so passing `true` to the
second argument tells it to parse a list of arguments up until the
block end tag. A comma is required between arguments. Example: `{%
mytag foo, bar, baz=10 %}`
* `parseUntilBlocks(names)` - Parse content up until it hits a block
with a name in the `names` array. This is useful for parsing content
between tags.
The parser API needs to be more documented, but for now read the above
and check out the example below. You can also look at the
[source](https://github.com/mozilla/nunjucks/blob/master/nunjucks/src/parser.js).
The most common usage is to process the content within some tags at
runtime. It's like filters, but on steroids because you aren't
confined to a single expression. You basically want to lightly parse
the template and then get a callback into your extension with the
content. This is done with the `CallExtension` node, which takes an
extension instance, the method to call, list of arguments parsed from
the tag, and a list of content blocks (parsed with
`parseUntilBlocks`).
For example, here's how you would implement an extension that fetches
content from a URL and injects it into the page:
```js
function RemoteExtension() {
this.tags = ['remote'];
this.parse = function(parser, nodes, lexer) {
// get the tag token
var tok = parser.nextToken();
// parse the args and move after the block end. passing true
// as the second arg is required if there are no parentheses
var args = parser.parseSignature(null, true);
parser.advanceAfterBlockEnd(tok.value);
// parse the body and possibly the error block, which is optional
var body = parser.parseUntilBlocks('error', 'endremote');
var errorBody = null;
if(parser.skipSymbol('error')) {
parser.skip(lexer.TOKEN_BLOCK_END);
errorBody = parser.parseUntilBlocks('endremote');
}
parser.advanceAfterBlockEnd();
// See above for notes about CallExtension
return new nodes.CallExtension(this, 'run', args, [body, errorBody]);
};
this.run = function(context, url, body, errorBody) {
var id = 'el' + Math.floor(Math.random() * 10000);
var ret = new nunjucks.runtime.SafeString('
' + body() + '
');
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if(ajax.readyState == 4) {
if(ajax.status == 200) {
document.getElementById(id).innerHTML = ajax.responseText;
}
else {
document.getElementById(id).innerHTML = errorBody();
}
}
};
ajax.open('GET', url, true);
ajax.send();
return ret;
};
}
env.addExtension('RemoteExtension', new RemoteExtension());
```
Use it like this:
```jinja
{% remote "/stuff" %}
This content will be replaced with the content from /stuff
{% error %}
There was an error fetching /stuff
{% endremote %}
```
### Asynchronous
Another available node is `CallExtensionAsync` which is an
asynchronous version of `CallExtension`. It calls back into your
extension at runtime, with an additional parameter: a callback.
Template rendering is paused until you call the callback to resume.
The `run` function from the above example would now look like:
```js
this.run = function(context, url, body, errorBody, callback) {
// do async stuff and then call callback(err, res)
};
```
If you create anything interesting, make sure to
[add it to the wiki!](https://github.com/mozilla/nunjucks/wiki/Custom-Tags)
{% endraw %}
================================================
FILE: docs/bower_components/bootstrap/.bower.json
================================================
{
"name": "bootstrap",
"version": "3.0.0",
"main": [
"./dist/js/bootstrap.js",
"./dist/css/bootstrap.css"
],
"ignore": [
"**/.*"
],
"dependencies": {
"jquery": ">= 1.9.0"
},
"homepage": "https://github.com/twbs/bootstrap",
"_release": "3.0.0",
"_resolution": {
"type": "version",
"tag": "v3.0.0",
"commit": "e8a1df5f060bf7e6631554648e0abde150aedbe4"
},
"_source": "git://github.com/twbs/bootstrap.git",
"_target": "~3.0.0",
"_originalSource": "bootstrap",
"_direct": true
}
================================================
FILE: docs/bower_components/bootstrap/CNAME
================================================
getbootstrap.com
================================================
FILE: docs/bower_components/bootstrap/CONTRIBUTING.md
================================================
# Contributing to Bootstrap
Looking to contribute something to Bootstrap? **Here's how you can help.**
## Reporting issues
We only accept issues that are bug reports or feature requests. Bugs must be isolated and reproducible problems that we can fix within the Bootstrap core. Please read the following guidelines before opening any issue.
1. **Search for existing issues.** We get a lot of duplicate issues, and you'd help us out a lot by first checking if someone else has reported the same issue. Moreover, the issue may have already been resolved with a fix available.
2. **Create an isolated and reproducible test case.** Be sure the problem exists in Bootstrap's code with a [reduced test case](http://css-tricks.com/reduced-test-cases/) that should be included in each bug report.
3. **Include a live example.** Make use of jsFiddle or jsBin to share your isolated test cases.
4. **Share as much information as possible.** Include operating system and version, browser and version, version of Bootstrap, customized or vanilla build, etc. where appropriate. Also include steps to reproduce the bug.
## Key branches
- `master` is the latest, deployed version.
- `gh-pages` is the hosted docs (not to be used for pull requests).
- `*-wip` is the official work in progress branch for the next release.
## Pull requests
- Try to submit pull requests against the latest `*-wip` branch for easier merging
- CSS changes must be done in .less files first, never just the compiled files
- If modifying the .less files, always recompile and commit the compiled files bootstrap.css and bootstrap.min.css
- Try not to pollute your pull request with unintended changes--keep them simple and small
- Try to share which browsers your code has been tested in before submitting a pull request
## Coding standards
### HTML
- Two spaces for indentation, never tabs
- Double quotes only, never single quotes
- Always use proper indentation
- Use tags and elements appropriate for an HTML5 doctype (e.g., self-closing tags)
### CSS
- Adhere to the [Recess CSS property order](http://markdotto.com/2011/11/29/css-property-order/)
- Multiple-line approach (one property and value per line)
- Always a space after a property's colon (.e.g, `display: block;` and not `display:block;`)
- End all lines with a semi-colon
- For multiple, comma-separated selectors, place each selector on its own line
- Attribute selectors, like `input[type="text"]` should always wrap the attribute's value in double quotes, for consistency and safety (see this [blog post on unquoted attribute values](http://mathiasbynens.be/notes/unquoted-attribute-values) that can lead to XSS attacks).
### JS
- No semicolons
- Comma first
- 2 spaces (no tabs)
- strict mode
- "Attractive"
## License
By contributing your code, you agree to license your contribution under the terms of the APLv2: https://github.com/twbs/bootstrap/blob/master/LICENSE
================================================
FILE: docs/bower_components/bootstrap/Gruntfile.js
================================================
/* jshint node: true */
module.exports = function(grunt) {
"use strict";
// Project configuration.
grunt.initConfig({
// Metadata.
pkg: grunt.file.readJSON('package.json'),
banner: '/**\n' +
'* <%= pkg.name %>.js v<%= pkg.version %> by @fat and @mdo\n' +
'* Copyright <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
'* <%= _.pluck(pkg.licenses, "url").join(", ") %>\n' +
'*/\n',
jqueryCheck: 'if (!jQuery) { throw new Error(\"Bootstrap requires jQuery\") }\n\n',
// Task configuration.
clean: {
dist: ['dist']
},
jshint: {
options: {
jshintrc: 'js/.jshintrc'
},
gruntfile: {
src: 'Gruntfile.js'
},
src: {
src: ['js/*.js']
},
test: {
src: ['js/tests/unit/*.js']
}
},
concat: {
options: {
banner: '<%= banner %><%= jqueryCheck %>',
stripBanners: false
},
bootstrap: {
src: [
'js/transition.js',
'js/alert.js',
'js/button.js',
'js/carousel.js',
'js/collapse.js',
'js/dropdown.js',
'js/modal.js',
'js/tooltip.js',
'js/popover.js',
'js/scrollspy.js',
'js/tab.js',
'js/affix.js'
],
dest: 'dist/js/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '<%= banner %>'
},
bootstrap: {
src: ['<%= concat.bootstrap.dest %>'],
dest: 'dist/js/<%= pkg.name %>.min.js'
}
},
recess: {
options: {
compile: true
},
bootstrap: {
src: ['less/bootstrap.less'],
dest: 'dist/css/<%= pkg.name %>.css'
},
min: {
options: {
compress: true
},
src: ['less/bootstrap.less'],
dest: 'dist/css/<%= pkg.name %>.min.css'
},
theme: {
src: ['less/theme.less'],
dest: 'dist/css/<%= pkg.name %>-theme.css'
},
theme_min: {
options: {
compress: true
},
src: ['less/theme.less'],
dest: 'dist/css/<%= pkg.name %>-theme.min.css'
}
},
copy: {
fonts: {
expand: true,
src: ["fonts/*"],
dest: 'dist/'
}
},
qunit: {
options: {
inject: 'js/tests/unit/phantom.js'
},
files: ['js/tests/*.html']
},
connect: {
server: {
options: {
port: 3000,
base: '.'
}
}
},
jekyll: {
docs: {}
},
validation: {
options: {
reset: true
},
files: {
src: ["_gh_pages/**/*.html"]
}
},
watch: {
src: {
files: '<%= jshint.src.src %>',
tasks: ['jshint:src', 'qunit']
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'qunit']
},
recess: {
files: 'less/*.less',
tasks: ['recess']
}
}
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-html-validation');
grunt.loadNpmTasks('grunt-jekyll');
grunt.loadNpmTasks('grunt-recess');
grunt.loadNpmTasks('browserstack-runner');
// Docs HTML validation task
grunt.registerTask('validate-html', ['jekyll', 'validation']);
// Test task.
var testSubtasks = ['dist-css', 'jshint', 'qunit', 'validate-html'];
// Only run BrowserStack tests under Travis
if (process.env.TRAVIS) {
// Only run BrowserStack tests if this is a mainline commit in twbs/bootstrap, or you have your own BrowserStack key
if ((process.env.TRAVIS_REPO_SLUG === 'twbs/bootstrap' && process.env.TRAVIS_PULL_REQUEST === 'false') || process.env.TWBS_HAVE_OWN_BROWSERSTACK_KEY) {
testSubtasks.push('browserstack_runner');
}
}
grunt.registerTask('test', testSubtasks);
// JS distribution task.
grunt.registerTask('dist-js', ['concat', 'uglify']);
// CSS distribution task.
grunt.registerTask('dist-css', ['recess']);
// Fonts distribution task.
grunt.registerTask('dist-fonts', ['copy']);
// Full distribution task.
grunt.registerTask('dist', ['clean', 'dist-css', 'dist-fonts', 'dist-js']);
// Default task.
grunt.registerTask('default', ['test', 'dist', 'build-customizer']);
// task for building customizer
grunt.registerTask('build-customizer', 'Add scripts/less files to customizer.', function () {
var fs = require('fs')
function getFiles(type) {
var files = {}
fs.readdirSync(type)
.filter(function (path) {
return type == 'fonts' ? true : new RegExp('\\.' + type + '$').test(path)
})
.forEach(function (path) {
return files[path] = fs.readFileSync(type + '/' + path, 'utf8')
})
return 'var __' + type + ' = ' + JSON.stringify(files) + '\n'
}
var customize = fs.readFileSync('customize.html', 'utf-8')
var files = getFiles('js') + getFiles('less') + getFiles('fonts')
fs.writeFileSync('assets/js/raw-files.js', files)
});
};
================================================
FILE: docs/bower_components/bootstrap/LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
================================================
FILE: docs/bower_components/bootstrap/README.md
================================================
# [Bootstrap v3.0.0](http://getbootstrap.com) [](http://travis-ci.org/twbs/bootstrap)
Bootstrap is a sleek, intuitive, and powerful front-end framework for faster and easier web development, created and maintained by [Mark Otto](http://twitter.com/mdo) and [Jacob Thornton](http://twitter.com/fat).
To get started, check out [http://getbootstrap.com](http://getbootstrap.com)!
## Quick start
Three quick start options are available:
* [Download the latest release](https://github.com/twbs/bootstrap/zipball/3.0.0-wip).
* Clone the repo: `git clone git://github.com/twbs/bootstrap.git`.
* Install with [Bower](http://bower.io): `bower install bootstrap`.
Read the [Getting Started page](http://getbootstrap.com/getting-started/) for information on the framework contents, templates and examples, and more.
## Bugs and feature requests
Have a bug or a feature request? [Please open a new issue](https://github.com/twbs/bootstrap/issues). Before opening any issue, please search for existing issues and read the [Issue Guidelines](https://github.com/necolas/issue-guidelines), written by [Nicolas Gallagher](https://github.com/necolas/).
You may use [this JS Bin](http://jsbin.com/aKiCIDO/1/edit) as a template for your bug reports.
## Documentation
Bootstrap's documentation, included in this repo in the root directory, is built with [Jekyll](http://jekyllrb.com) and publicly hosted on GitHub Pages at [http://getbootstrap.com](http://getbootstrap.com). The docs may also be run locally.
### Running documentation locally
1. If necessary, [install Jekyll](http://jekyllrb.com/docs/installation) (requires v1.x).
2. From the root `/bootstrap` directory, run `jekyll serve` in the command line.
- **Windows users:** run `chcp 65001` first to change the command prompt's character encoding ([code page](http://en.wikipedia.org/wiki/Windows_code_page)) to UTF-8 so Jekyll runs without errors.
3. Open [http://localhost:9001](http://localhost:9001) in your browser, and voilà.
Learn more about using Jekyll by reading their [documentation](http://jekyllrb.com/docs/home/).
### Documentation for previous releases
Documentation for v2.3.2 has been made available for the time being at [http://getbootstrap.com/2.3.2/](http://getbootstrap.com/2.3.2/) while folks transition to Bootstrap 3.
[Previous releases](https://github.com/twbs/bootstrap/releases) and their documentation are also available for download.
## Compiling CSS and JavaScript
Bootstrap uses [Grunt](http://gruntjs.com/) with convenient methods for working with the framework. It's how we compile our code, run tests, and more. To use it, install the required dependencies as directed and then run some Grunt commands.
### Install Grunt
From the command line:
1. Install `grunt-cli` globally with `npm install -g grunt-cli`.
2. Install the [necessary local dependencies](package.json) via `npm install`
When completed, you'll be able to run the various Grunt commands provided from the command line.
**Unfamiliar with `npm`? Don't have node installed?** That's a-okay. npm stands for [node packaged modules](http://npmjs.org/) and is a way to manage development dependencies through node.js. [Download and install node.js](http://nodejs.org/download/) before proceeding.
### Available Grunt commands
#### Build - `grunt`
Run `grunt` to run tests locally and compile the CSS and JavaScript into `/dist`. **Requires [recess](https://github.com/twitter/recess) and [uglify-js](https://github.com/mishoo/UglifyJS).**
#### Only compile CSS and JavaScript - `grunt dist`
`grunt dist` creates the `/dist` directory with compiled files. **Requires [recess](https://github.com/twitter/recess) and [uglify-js](https://github.com/mishoo/UglifyJS).**
#### Tests - `grunt test`
Runs jshint and qunit tests headlessly in [phantomjs](https://github.com/ariya/phantomjs/) (used for CI). **Requires [phantomjs](https://github.com/ariya/phantomjs/).**
#### Watch - `grunt watch`
This is a convenience method for watching just Less files and automatically building them whenever you save.
### Troubleshooting dependencies
Should you encounter problems with installing dependencies or running Grunt commands, uninstall all previous dependency versions (global and local). Then, rerun `npm install`.
## Contributing
Please read through our guidelines for contributing to Bootstrap. Included are directions for opening issues, coding standards, and notes on development.
More over, if your pull request contains JavaScript patches or features, you must include relevant unit tests. All HTML and CSS should conform to the [Code Guide](http://github.com/mdo/code-guide), maintained by [Mark Otto](http://github.com/mdo).
Editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at [http://editorconfig.org](http://editorconfig.org).
## Community
Keep track of development and community news.
* Follow [@twbootstrap on Twitter](http://twitter.com/twbootstrap).
* Read and subscribe to the [The Official Bootstrap Blog](http://blog.getbootstrap.com).
* Have a question that's not a feature request or bug report? [Ask on the mailing list.](http://groups.google.com/group/twitter-bootstrap)
* Chat with fellow Bootstrappers in IRC. On the `irc.freenode.net` server, in the `##twitter-bootstrap` channel.
## Versioning
For transparency and insight into our release cycle, and for striving to maintain backward compatibility, Bootstrap will be maintained under the Semantic Versioning guidelines as much as possible.
Releases will be numbered with the following format:
`..`
And constructed with the following guidelines:
* Breaking backward compatibility bumps the major (and resets the minor and patch)
* New additions without breaking backward compatibility bumps the minor (and resets the patch)
* Bug fixes and misc changes bumps the patch
For more information on SemVer, please visit [http://semver.org/](http://semver.org/).
## Authors
**Mark Otto**
+ [http://twitter.com/mdo](http://twitter.com/mdo)
+ [http://github.com/mdo](http://github.com/mdo)
**Jacob Thornton**
+ [http://twitter.com/fat](http://twitter.com/fat)
+ [http://github.com/fat](http://github.com/fat)
## Copyright and license
Copyright 2012 Twitter, Inc under [the Apache 2.0 license](LICENSE).
================================================
FILE: docs/bower_components/bootstrap/_config.yml
================================================
# Dependencies
markdown: rdiscount
pygments: true
# Permalinks
permalink: pretty
# Server
destination: ./_gh_pages
exclude: [".editorconfig", ".gitignore", ".ruby-version", "bower.json", "composer.json", "CONTRIBUTING.md", "CNAME", "LICENSE", "Gruntfile.js", "package.json", "node_modules", "README.md", "less"]
port: 9001
# Custom vars
repo: https://github.com/twbs/bootstrap
download: https://github.com/twbs/bootstrap/archive/v3.0.0.zip
download_dist: https://github.com/twbs/bootstrap/releases/download/v3.0.0/bootstrap-3.0.0-dist.zip
blog: http://blog.getbootstrap.com
expo: http://expo.getbootstrap.com
cdn_css: //netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css
cdn_theme_css: //netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css
cdn_js: //netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js
================================================
FILE: docs/bower_components/bootstrap/_includes/ads.html
================================================
').appendTo('body').alert()
throw err
}
function showCallout(msg, showUpTop) {
var callout = $('
\
Attention!
\
' + msg + '
\
')
if (showUpTop) {
callout.appendTo('.bs-docs-container')
} else {
callout.insertAfter('.bs-customize-download')
}
}
function getQueryParam(key) {
key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&"); // escape RegEx meta chars
var match = location.search.match(new RegExp("[?&]"+key+"=([^&]+)(&|$)"));
return match && decodeURIComponent(match[1].replace(/\+/g, " "));
}
function createGist(configData) {
var data = {
"description": "Bootstrap Customizer Config",
"public": true,
"files": {
"config.json": {
"content": JSON.stringify(configData, null, 2)
}
}
}
$.ajax({
url: 'https://api.github.com/gists',
type: 'POST',
dataType: 'json',
data: JSON.stringify(data)
})
.success(function(result) {
history.replaceState(false, document.title, window.location.origin + window.location.pathname + '?id=' + result.id)
})
.error(function(err) {
showError('Ruh roh! Could not save gist file, configuration not saved.', err)
})
}
function getCustomizerData() {
var vars = {}
$('#less-variables-section input')
.each(function () {
$(this).val() && (vars[ $(this).prev().text() ] = $(this).val())
})
var data = {
vars: vars,
css: $('#less-section input:checked') .map(function () { return this.value }).toArray(),
js: $('#plugin-section input:checked').map(function () { return this.value }).toArray()
}
if ($.isEmptyObject(data.vars) && !data.css.length && !data.js.length) return
return data
}
function parseUrl() {
var id = getQueryParam('id')
if (!id) return
$.ajax({
url: 'https://api.github.com/gists/' + id,
type: 'GET',
dataType: 'json'
})
.success(function(result) {
var data = JSON.parse(result.files['config.json'].content)
if (data.js) {
$('#plugin-section input').each(function () {
$(this).prop('checked', ~$.inArray(this.value, data.js))
})
}
if (data.css) {
$('#less-section input').each(function () {
$(this).prop('checked', ~$.inArray(this.value, data.css))
})
}
if (data.vars) {
for (var i in data.vars) {
$('input[data-var="' + i + '"]').val(data.vars[i])
}
}
})
.error(function(err) {
showError('Error fetching bootstrap config file', err)
})
}
function generateZip(css, js, fonts, complete) {
if (!css && !js) return showError('Ruh roh! No Bootstrap files selected.', new Error('no Bootstrap'))
var zip = new JSZip()
if (css) {
var cssFolder = zip.folder('css')
for (var fileName in css) {
cssFolder.file(fileName, css[fileName])
}
}
if (js) {
var jsFolder = zip.folder('js')
for (var fileName in js) {
jsFolder.file(fileName, js[fileName])
}
}
if (fonts) {
var fontsFolder = zip.folder('fonts')
for (var fileName in fonts) {
fontsFolder.file(fileName, fonts[fileName])
}
}
var content = zip.generate({type:"blob"})
complete(content)
}
function generateCustomCSS(vars) {
var result = ''
for (var key in vars) {
result += key + ': ' + vars[key] + ';\n'
}
return result + '\n\n'
}
function generateFonts() {
var glyphicons = $('#less-section [value="glyphicons.less"]:checked')
if (glyphicons.length) {
return __fonts
}
}
function generateCSS() {
var $checked = $('#less-section input:checked')
if (!$checked.length) return false
var result = {}
var vars = {}
var css = ''
$('#less-variables-section input')
.each(function () {
$(this).val() && (vars[ $(this).prev().text() ] = $(this).val())
})
css += __less['variables.less']
if (vars) css += generateCustomCSS(vars)
css += __less['mixins.less']
css += __less['normalize.less']
css += __less['scaffolding.less']
css += $checked
.map(function () { return __less[this.value] })
.toArray()
.join('\n')
css = css.replace(/@import[^\n]*/gi, '') //strip any imports
try {
var parser = new less.Parser({
paths: ['variables.less', 'mixins.less']
, optimization: 0
, filename: 'bootstrap.css'
}).parse(css, function (err, tree) {
if (err) {
return showError('Ruh roh! Could not parse less files.', err)
}
result = {
'bootstrap.css' : cw + tree.toCSS(),
'bootstrap.min.css' : cw + tree.toCSS({ compress: true })
}
})
} catch (err) {
return showError('Ruh roh! Could not parse less files.', err)
}
return result
}
function generateJavascript() {
var $checked = $('#plugin-section input:checked')
if (!$checked.length) return false
var js = $checked
.map(function () { return __js[this.value] })
.toArray()
.join('\n')
return {
'bootstrap.js': js,
'bootstrap.min.js': cw + uglify(js)
}
}
var inputsComponent = $('#less-section input')
var inputsPlugin = $('#plugin-section input')
var inputsVariables = $('#less-variables-section input')
$('#less-section .toggle').on('click', function (e) {
e.preventDefault()
inputsComponent.prop('checked', !inputsComponent.is(':checked'))
})
$('#plugin-section .toggle').on('click', function (e) {
e.preventDefault()
inputsPlugin.prop('checked', !inputsPlugin.is(':checked'))
})
$('#less-variables-section .toggle').on('click', function (e) {
e.preventDefault()
inputsVariables.val('')
})
$('[data-dependencies]').on('click', function () {
if (!$(this).is(':checked')) return
var dependencies = this.getAttribute('data-dependencies')
if (!dependencies) return
dependencies = dependencies.split(',')
for (var i = 0; i < dependencies.length; i++) {
var dependency = $('[value="' + dependencies[i] + '"]')
dependency && dependency.prop('checked', true)
}
})
$('[data-dependents]').on('click', function () {
if ($(this).is(':checked')) return
var dependents = this.getAttribute('data-dependents')
if (!dependents) return
dependents = dependents.split(',')
for (var i = 0; i < dependents.length; i++) {
var dependent = $('[value="' + dependents[i] + '"]')
dependent && dependent.prop('checked', false)
}
})
var $compileBtn = $('#btn-compile')
var $downloadBtn = $('#btn-download')
$compileBtn.on('click', function (e) {
e.preventDefault()
$compileBtn.attr('disabled', 'disabled')
generateZip(generateCSS(), generateJavascript(), generateFonts(), function (blob) {
$compileBtn.removeAttr('disabled')
saveAs(blob, "bootstrap.zip")
createGist(getCustomizerData())
})
})
// browser support alerts
if (!window.URL && navigator.userAgent.toLowerCase().indexOf('safari') != -1) {
showCallout("Looks like you're using safari, which sadly doesn't have the best support\
for HTML5 blobs. Because of this your file will be downloaded with the name \"untitled\".\
However, if you check your downloads folder, just rename this \"untitled\" file\
to \"bootstrap.zip\" and you should be good to go!")
} else if (!window.URL && !window.webkitURL) {
$('.bs-docs-section, .bs-sidebar').css('display', 'none')
showCallout("Looks like your current browser doesn't support the Bootstrap Customizer. Please take a second\
to upgrade to a more modern browser.", true)
}
parseUrl()
}
================================================
FILE: docs/bower_components/bootstrap/assets/js/filesaver.js
================================================
/* Blob.js
* A Blob implementation.
* 2013-06-20
*
* By Eli Grey, http://eligrey.com
* By Devin Samarin, https://github.com/eboyjr
* License: X11/MIT
* See LICENSE.md
*/
/*global self, unescape */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
if (typeof Blob !== "function" || typeof URL === "undefined")
if (typeof Blob === "function" && typeof webkitURL !== "undefined") self.URL = webkitURL;
else var Blob = (function (view) {
"use strict";
var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) {
var
get_class = function(object) {
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
}
, FakeBlobBuilder = function BlobBuilder() {
this.data = [];
}
, FakeBlob = function Blob(data, type, encoding) {
this.data = data;
this.size = data.length;
this.type = type;
this.encoding = encoding;
}
, FBB_proto = FakeBlobBuilder.prototype
, FB_proto = FakeBlob.prototype
, FileReaderSync = view.FileReaderSync
, FileException = function(type) {
this.code = this[this.name = type];
}
, file_ex_codes = (
"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
).split(" ")
, file_ex_code = file_ex_codes.length
, real_URL = view.URL || view.webkitURL || view
, real_create_object_URL = real_URL.createObjectURL
, real_revoke_object_URL = real_URL.revokeObjectURL
, URL = real_URL
, btoa = view.btoa
, atob = view.atob
, ArrayBuffer = view.ArrayBuffer
, Uint8Array = view.Uint8Array
;
FakeBlob.fake = FB_proto.fake = true;
while (file_ex_code--) {
FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
}
if (!real_URL.createObjectURL) {
URL = view.URL = {};
}
URL.createObjectURL = function(blob) {
var
type = blob.type
, data_URI_header
;
if (type === null) {
type = "application/octet-stream";
}
if (blob instanceof FakeBlob) {
data_URI_header = "data:" + type;
if (blob.encoding === "base64") {
return data_URI_header + ";base64," + blob.data;
} else if (blob.encoding === "URI") {
return data_URI_header + "," + decodeURIComponent(blob.data);
} if (btoa) {
return data_URI_header + ";base64," + btoa(blob.data);
} else {
return data_URI_header + "," + encodeURIComponent(blob.data);
}
} else if (real_create_object_URL) {
return real_create_object_URL.call(real_URL, blob);
}
};
URL.revokeObjectURL = function(object_URL) {
if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
real_revoke_object_URL.call(real_URL, object_URL);
}
};
FBB_proto.append = function(data/*, endings*/) {
var bb = this.data;
// decode data to a binary string
if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
var
str = ""
, buf = new Uint8Array(data)
, i = 0
, buf_len = buf.length
;
for (; i < buf_len; i++) {
str += String.fromCharCode(buf[i]);
}
bb.push(str);
} else if (get_class(data) === "Blob" || get_class(data) === "File") {
if (FileReaderSync) {
var fr = new FileReaderSync;
bb.push(fr.readAsBinaryString(data));
} else {
// async FileReader won't work as BlobBuilder is sync
throw new FileException("NOT_READABLE_ERR");
}
} else if (data instanceof FakeBlob) {
if (data.encoding === "base64" && atob) {
bb.push(atob(data.data));
} else if (data.encoding === "URI") {
bb.push(decodeURIComponent(data.data));
} else if (data.encoding === "raw") {
bb.push(data.data);
}
} else {
if (typeof data !== "string") {
data += ""; // convert unsupported types to strings
}
// decode UTF-16 to binary string
bb.push(unescape(encodeURIComponent(data)));
}
};
FBB_proto.getBlob = function(type) {
if (!arguments.length) {
type = null;
}
return new FakeBlob(this.data.join(""), type, "raw");
};
FBB_proto.toString = function() {
return "[object BlobBuilder]";
};
FB_proto.slice = function(start, end, type) {
var args = arguments.length;
if (args < 3) {
type = null;
}
return new FakeBlob(
this.data.slice(start, args > 1 ? end : this.data.length)
, type
, this.encoding
);
};
FB_proto.toString = function() {
return "[object Blob]";
};
return FakeBlobBuilder;
}(view));
return function Blob(blobParts, options) {
var type = options ? (options.type || "") : "";
var builder = new BlobBuilder();
if (blobParts) {
for (var i = 0, len = blobParts.length; i < len; i++) {
builder.append(blobParts[i]);
}
}
return builder.getBlob(type);
};
}(self));
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
var saveAs=saveAs||(navigator.msSaveOrOpenBlob&&navigator.msSaveOrOpenBlob.bind(navigator))||(function(h){"use strict";var r=h.document,l=function(){return h.URL||h.webkitURL||h},e=h.URL||h.webkitURL||h,n=r.createElementNS("http://www.w3.org/1999/xhtml","a"),g=!h.externalHost&&"download" in n,j=function(t){var s=r.createEvent("MouseEvents");s.initMouseEvent("click",true,false,h,0,0,0,0,0,false,false,false,false,0,null);t.dispatchEvent(s)},o=h.webkitRequestFileSystem,p=h.requestFileSystem||o||h.mozRequestFileSystem,m=function(s){(h.setImmediate||h.setTimeout)(function(){throw s},0)},c="application/octet-stream",k=0,b=[],i=function(){var t=b.length;while(t--){var s=b[t];if(typeof s==="string"){e.revokeObjectURL(s)}else{s.remove()}}b.length=0},q=function(t,s,w){s=[].concat(s);var v=s.length;while(v--){var x=t["on"+s[v]];if(typeof x==="function"){try{x.call(t,w||t)}catch(u){m(u)}}}},f=function(t,u){var v=this,B=t.type,E=false,x,w,s=function(){var F=l().createObjectURL(t);b.push(F);return F},A=function(){q(v,"writestart progress write writeend".split(" "))},D=function(){if(E||!x){x=s(t)}if(w){w.location.href=x}else{window.open(x,"_blank")}v.readyState=v.DONE;A()},z=function(F){return function(){if(v.readyState!==v.DONE){return F.apply(this,arguments)}}},y={create:true,exclusive:false},C;v.readyState=v.INIT;if(!u){u="download"}if(g){x=s(t);n.href=x;n.download=u;j(n);v.readyState=v.DONE;A();return}if(h.chrome&&B&&B!==c){C=t.slice||t.webkitSlice;t=C.call(t,0,t.size,c);E=true}if(o&&u!=="download"){u+=".download"}if(B===c||o){w=h}if(!p){D();return}k+=t.size;p(h.TEMPORARY,k,z(function(F){F.root.getDirectory("saved",y,z(function(G){var H=function(){G.getFile(u,y,z(function(I){I.createWriter(z(function(J){J.onwriteend=function(K){w.location.href=I.toURL();b.push(I);v.readyState=v.DONE;q(v,"writeend",K)};J.onerror=function(){var K=J.error;if(K.code!==K.ABORT_ERR){D()}};"writestart progress write abort".split(" ").forEach(function(K){J["on"+K]=v["on"+K]});J.write(t);v.abort=function(){J.abort();v.readyState=v.DONE};v.readyState=v.WRITING}),D)}),D)};G.getFile(u,{create:false},z(function(I){I.remove();H()}),z(function(I){if(I.code===I.NOT_FOUND_ERR){H()}else{D()}}))}),D)}),D)},d=f.prototype,a=function(s,t){return new f(s,t)};d.abort=function(){var s=this;s.readyState=s.DONE;q(s,"abort")};d.readyState=d.INIT=0;d.WRITING=1;d.DONE=2;d.error=d.onwritestart=d.onprogress=d.onwrite=d.onabort=d.onerror=d.onwriteend=null;h.addEventListener("unload",i,false);return a}(self));
================================================
FILE: docs/bower_components/bootstrap/assets/js/holder.js
================================================
/*
Holder - 2.0 - client side image placeholders
(c) 2012-2013 Ivan Malopinsky / http://imsky.co
Provided under the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
Commercial use requires attribution.
*/
var Holder = Holder || {};
(function (app, win) {
var preempted = false,
fallback = false,
canvas = document.createElement('canvas');
//getElementsByClassName polyfill
document.getElementsByClassName||(document.getElementsByClassName=function(e){var t=document,n,r,i,s=[];if(t.querySelectorAll)return t.querySelectorAll("."+e);if(t.evaluate){r=".//*[contains(concat(' ', @class, ' '), ' "+e+" ')]",n=t.evaluate(r,t,null,0,null);while(i=n.iterateNext())s.push(i)}else{n=t.getElementsByTagName("*"),r=new RegExp("(^|\\s)"+e+"(\\s|$)");for(i=0;i= 0.75) {
text_height = Math.floor(text_height * 0.75 * (width/text_width));
}
//Resetting font size if necessary
ctx.font = "bold " + (text_height * ratio) + "px " + font;
ctx.fillText(text, (width / 2), (height / 2), width);
return canvas.toDataURL("image/png");
}
function render(mode, el, holder, src) {
var dimensions = holder.dimensions,
theme = holder.theme,
text = holder.text ? decodeURIComponent(holder.text) : holder.text;
var dimensions_caption = dimensions.width + "x" + dimensions.height;
theme = (text ? extend(theme, {
text: text
}) : theme);
theme = (holder.font ? extend(theme, {
font: holder.font
}) : theme);
if (mode == "image") {
el.setAttribute("data-src", src);
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if (fallback || !holder.auto) {
el.style.width = dimensions.width + "px";
el.style.height = dimensions.height + "px";
}
if (fallback) {
el.style.backgroundColor = theme.background;
} else {
el.setAttribute("src", draw(ctx, dimensions, theme, ratio));
}
} else if (mode == "background") {
if (!fallback) {
el.style.backgroundImage = "url(" + draw(ctx, dimensions, theme, ratio) + ")";
el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px";
}
} else if (mode == "fluid") {
el.setAttribute("data-src", src);
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if (dimensions.height.substr(-1) == "%") {
el.style.height = dimensions.height
} else {
el.style.height = dimensions.height + "px"
}
if (dimensions.width.substr(-1) == "%") {
el.style.width = dimensions.width
} else {
el.style.width = dimensions.width + "px"
}
if (el.style.display == "inline" || el.style.display == "") {
el.style.display = "block";
}
if (fallback) {
el.style.backgroundColor = theme.background;
} else {
el.holderData = holder;
fluid_images.push(el);
fluid_update(el);
}
}
};
function fluid_update(element) {
var images;
if (element.nodeType == null) {
images = fluid_images;
} else {
images = [element]
}
for (i in images) {
var el = images[i]
if (el.holderData) {
var holder = el.holderData;
el.setAttribute("src", draw(ctx, {
height: el.clientHeight,
width: el.clientWidth
}, holder.theme, ratio));
}
}
}
function parse_flags(flags, options) {
var ret = {
theme: settings.themes.gray
}, render = false;
for (sl = flags.length, j = 0; j < sl; j++) {
var flag = flags[j];
if (app.flags.dimensions.match(flag)) {
render = true;
ret.dimensions = app.flags.dimensions.output(flag);
} else if (app.flags.fluid.match(flag)) {
render = true;
ret.dimensions = app.flags.fluid.output(flag);
ret.fluid = true;
} else if (app.flags.colors.match(flag)) {
ret.theme = app.flags.colors.output(flag);
} else if (options.themes[flag]) {
//If a theme is specified, it will override custom colors
ret.theme = options.themes[flag];
} else if (app.flags.text.match(flag)) {
ret.text = app.flags.text.output(flag);
} else if (app.flags.font.match(flag)) {
ret.font = app.flags.font.output(flag);
} else if (app.flags.auto.match(flag)) {
ret.auto = true;
}
}
return render ? ret : false;
};
if (!canvas.getContext) {
fallback = true;
} else {
if (canvas.toDataURL("image/png")
.indexOf("data:image/png") < 0) {
//Android doesn't support data URI
fallback = true;
} else {
var ctx = canvas.getContext("2d");
}
}
var dpr = 1, bsr = 1;
if(!fallback){
dpr = window.devicePixelRatio || 1,
bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
}
var ratio = dpr / bsr;
var fluid_images = [];
var settings = {
domain: "holder.js",
images: "img",
bgnodes: ".holderjs",
themes: {
"gray": {
background: "#eee",
foreground: "#aaa",
size: 12
},
"social": {
background: "#3a5a97",
foreground: "#fff",
size: 12
},
"industrial": {
background: "#434A52",
foreground: "#C2F200",
size: 12
}
},
stylesheet: ".holderjs-fluid {font-size:16px;font-weight:bold;text-align:center;font-family:sans-serif;margin:0}"
};
app.flags = {
dimensions: {
regex: /^(\d+)x(\d+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: +exec[1],
height: +exec[2]
}
}
},
fluid: {
regex: /^([0-9%]+)x([0-9%]+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: exec[1],
height: exec[2]
}
}
},
colors: {
regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i,
output: function (val) {
var exec = this.regex.exec(val);
return {
size: settings.themes.gray.size,
foreground: "#" + exec[2],
background: "#" + exec[1]
}
}
},
text: {
regex: /text\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
font: {
regex: /font\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
auto: {
regex: /^auto$/
}
}
for (var flag in app.flags) {
if (!app.flags.hasOwnProperty(flag)) continue;
app.flags[flag].match = function (val) {
return val.match(this.regex)
}
}
app.add_theme = function (name, theme) {
name != null && theme != null && (settings.themes[name] = theme);
return app;
};
app.add_image = function (src, el) {
var node = selector(el);
if (node.length) {
for (var i = 0, l = node.length; i < l; i++) {
var img = document.createElement("img")
img.setAttribute("data-src", src);
node[i].appendChild(img);
}
}
return app;
};
app.run = function (o) {
var options = extend(settings, o),
images = [], imageNodes = [], bgnodes = [];
if(typeof(options.images) == "string"){
imageNodes = selector(options.images);
}
else if (window.NodeList && options.images instanceof window.NodeList) {
imageNodes = options.images;
} else if (window.Node && options.images instanceof window.Node) {
imageNodes = [options.images];
}
if(typeof(options.bgnodes) == "string"){
bgnodes = selector(options.bgnodes);
} else if (window.NodeList && options.elements instanceof window.NodeList) {
bgnodes = options.bgnodes;
} else if (window.Node && options.bgnodes instanceof window.Node) {
bgnodes = [options.bgnodes];
}
preempted = true;
for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]);
var holdercss = document.getElementById("holderjs-style");
if (!holdercss) {
holdercss = document.createElement("style");
holdercss.setAttribute("id", "holderjs-style");
holdercss.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(holdercss);
}
if (!options.nocss) {
if (holdercss.styleSheet) {
holdercss.styleSheet.cssText += options.stylesheet;
} else {
holdercss.appendChild(document.createTextNode(options.stylesheet));
}
}
var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)");
for (var l = bgnodes.length, i = 0; i < l; i++) {
var src = window.getComputedStyle(bgnodes[i], null)
.getPropertyValue("background-image");
var flags = src.match(cssregex);
var bgsrc = bgnodes[i].getAttribute("data-background-src");
if (flags) {
var holder = parse_flags(flags[1].split("/"), options);
if (holder) {
render("background", bgnodes[i], holder, src);
}
}
else if(bgsrc != null){
var holder = parse_flags(bgsrc.substr(bgsrc.lastIndexOf(options.domain) + options.domain.length + 1)
.split("/"), options);
if(holder){
render("background", bgnodes[i], holder, src);
}
}
}
for (l = images.length, i = 0; i < l; i++) {
var attr_src = attr_data_src = src = null;
try{
attr_src = images[i].getAttribute("src");
attr_datasrc = images[i].getAttribute("data-src");
}catch(e){}
if (attr_datasrc == null && !! attr_src && attr_src.indexOf(options.domain) >= 0) {
src = attr_src;
} else if ( !! attr_datasrc && attr_datasrc.indexOf(options.domain) >= 0) {
src = attr_datasrc;
}
if (src) {
var holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1)
.split("/"), options);
if (holder) {
if (holder.fluid) {
render("fluid", images[i], holder, src)
} else {
render("image", images[i], holder, src);
}
}
}
}
return app;
};
contentLoaded(win, function () {
if (window.addEventListener) {
window.addEventListener("resize", fluid_update, false);
window.addEventListener("orientationchange", fluid_update, false);
} else {
window.attachEvent("onresize", fluid_update)
}
preempted || app.run();
});
if (typeof define === "function" && define.amd) {
define("Holder", [], function () {
return app;
});
}
})(Holder, window);
================================================
FILE: docs/bower_components/bootstrap/assets/js/html5shiv.js
================================================
/*
HTML5 Shiv v3.6.2pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x";
c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",version:"3.6.2pre",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment();
for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
a",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="
").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window);
================================================
FILE: docs/bower_components/bootstrap/assets/js/jszip.js
================================================
/**
JSZip - A Javascript class for generating and reading zip files
(c) 2009-2012 Stuart Knightley
Dual licenced under the MIT license or GPLv3. See LICENSE.markdown.
Usage:
zip = new JSZip();
zip.file("hello.txt", "Hello, World!").file("tempfile", "nothing");
zip.folder("images").file("smile.gif", base64Data, {base64: true});
zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")});
zip.remove("tempfile");
base64zip = zip.generate();
**/
"use strict";
/**
* Representation a of zip file in js
* @constructor
* @param {String=|ArrayBuffer=|Uint8Array=|Buffer=} data the data to load, if any (optional).
* @param {Object=} options the options for creating this objects (optional).
*/
var JSZip = function(data, options) {
// object containing the files :
// {
// "folder/" : {...},
// "folder/data.txt" : {...}
// }
this.files = {};
// Where we are in the hierarchy
this.root = "";
if (data) {
this.load(data, options);
}
};
JSZip.signature = {
LOCAL_FILE_HEADER : "\x50\x4b\x03\x04",
CENTRAL_FILE_HEADER : "\x50\x4b\x01\x02",
CENTRAL_DIRECTORY_END : "\x50\x4b\x05\x06",
ZIP64_CENTRAL_DIRECTORY_LOCATOR : "\x50\x4b\x06\x07",
ZIP64_CENTRAL_DIRECTORY_END : "\x50\x4b\x06\x06",
DATA_DESCRIPTOR : "\x50\x4b\x07\x08"
};
// Default properties for a new file
JSZip.defaults = {
base64: false,
binary: false,
dir: false,
date: null,
compression: null
};
JSZip.prototype = (function () {
/**
* Returns the raw data of a ZipObject, decompress the content if necessary.
* @param {ZipObject} file the file to use.
* @return {String|ArrayBuffer|Uint8Array|Buffer} the data.
*/
var getRawData = function (file) {
if (file._data instanceof JSZip.CompressedObject) {
file._data = file._data.getContent();
file.options.binary = true;
file.options.base64 = false;
if (JSZip.utils.getTypeOf(file._data) === "uint8array") {
var copy = file._data;
// when reading an arraybuffer, the CompressedObject mechanism will keep it and subarray() a Uint8Array.
// if we request a file in the same format, we might get the same Uint8Array or its ArrayBuffer (the original zip file).
file._data = new Uint8Array(copy.length);
// with an empty Uint8Array, Opera fails with a "Offset larger than array size"
if (copy.length !== 0) {
file._data.set(copy, 0);
}
}
}
return file._data;
};
/**
* Returns the data of a ZipObject in a binary form. If the content is an unicode string, encode it.
* @param {ZipObject} file the file to use.
* @return {String|ArrayBuffer|Uint8Array|Buffer} the data.
*/
var getBinaryData = function (file) {
var result = getRawData(file), type = JSZip.utils.getTypeOf(result);
if (type === "string") {
if (!file.options.binary) {
// unicode text !
// unicode string => binary string is a painful process, check if we can avoid it.
if (JSZip.support.uint8array && typeof TextEncoder === "function") {
return TextEncoder("utf-8").encode(result);
}
if (JSZip.support.nodebuffer) {
return new Buffer(result, "utf-8");
}
}
return file.asBinary();
}
return result;
}
/**
* Transform this._data into a string.
* @param {function} filter a function String -> String, applied if not null on the result.
* @return {String} the string representing this._data.
*/
var dataToString = function (asUTF8) {
var result = getRawData(this);
if (result === null || typeof result === "undefined") {
return "";
}
// if the data is a base64 string, we decode it before checking the encoding !
if (this.options.base64) {
result = JSZip.base64.decode(result);
}
if (asUTF8 && this.options.binary) {
// JSZip.prototype.utf8decode supports arrays as input
// skip to array => string step, utf8decode will do it.
result = JSZip.prototype.utf8decode(result);
} else {
// no utf8 transformation, do the array => string step.
result = JSZip.utils.transformTo("string", result);
}
if (!asUTF8 && !this.options.binary) {
result = JSZip.prototype.utf8encode(result);
}
return result;
};
/**
* A simple object representing a file in the zip file.
* @constructor
* @param {string} name the name of the file
* @param {String|ArrayBuffer|Uint8Array|Buffer} data the data
* @param {Object} options the options of the file
*/
var ZipObject = function (name, data, options) {
this.name = name;
this._data = data;
this.options = options;
};
ZipObject.prototype = {
/**
* Return the content as UTF8 string.
* @return {string} the UTF8 string.
*/
asText : function () {
return dataToString.call(this, true);
},
/**
* Returns the binary content.
* @return {string} the content as binary.
*/
asBinary : function () {
return dataToString.call(this, false);
},
/**
* Returns the content as a nodejs Buffer.
* @return {Buffer} the content as a Buffer.
*/
asNodeBuffer : function () {
var result = getBinaryData(this);
return JSZip.utils.transformTo("nodebuffer", result);
},
/**
* Returns the content as an Uint8Array.
* @return {Uint8Array} the content as an Uint8Array.
*/
asUint8Array : function () {
var result = getBinaryData(this);
return JSZip.utils.transformTo("uint8array", result);
},
/**
* Returns the content as an ArrayBuffer.
* @return {ArrayBuffer} the content as an ArrayBufer.
*/
asArrayBuffer : function () {
return this.asUint8Array().buffer;
}
};
/**
* Transform an integer into a string in hexadecimal.
* @private
* @param {number} dec the number to convert.
* @param {number} bytes the number of bytes to generate.
* @returns {string} the result.
*/
var decToHex = function(dec, bytes) {
var hex = "", i;
for(i = 0; i < bytes; i++) {
hex += String.fromCharCode(dec&0xff);
dec=dec>>>8;
}
return hex;
};
/**
* Merge the objects passed as parameters into a new one.
* @private
* @param {...Object} var_args All objects to merge.
* @return {Object} a new object with the data of the others.
*/
var extend = function () {
var result = {}, i, attr;
for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers
for (attr in arguments[i]) {
if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") {
result[attr] = arguments[i][attr];
}
}
}
return result;
};
/**
* Transforms the (incomplete) options from the user into the complete
* set of options to create a file.
* @private
* @param {Object} o the options from the user.
* @return {Object} the complete set of options.
*/
var prepareFileAttrs = function (o) {
o = o || {};
if (o.base64 === true && o.binary == null) {
o.binary = true;
}
o = extend(o, JSZip.defaults);
o.date = o.date || new Date();
if (o.compression !== null) o.compression = o.compression.toUpperCase();
return o;
};
/**
* Add a file in the current folder.
* @private
* @param {string} name the name of the file
* @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file
* @param {Object} o the options of the file
* @return {Object} the new file.
*/
var fileAdd = function (name, data, o) {
// be sure sub folders exist
var parent = parentFolder(name), dataType = JSZip.utils.getTypeOf(data);
if (parent) {
folderAdd.call(this, parent);
}
o = prepareFileAttrs(o);
if (o.dir || data === null || typeof data === "undefined") {
o.base64 = false;
o.binary = false;
data = null;
} else if (dataType === "string") {
if (o.binary && !o.base64) {
// optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask
if (o.optimizedBinaryString !== true) {
// this is a string, not in a base64 format.
// Be sure that this is a correct "binary string"
data = JSZip.utils.string2binary(data);
}
}
} else { // arraybuffer, uint8array, ...
o.base64 = false;
o.binary = true;
if (!dataType && !(data instanceof JSZip.CompressedObject)) {
throw new Error("The data of '" + name + "' is in an unsupported format !");
}
// special case : it's way easier to work with Uint8Array than with ArrayBuffer
if (dataType === "arraybuffer") {
data = JSZip.utils.transformTo("uint8array", data);
}
}
return this.files[name] = new ZipObject(name, data, o);
};
/**
* Find the parent folder of the path.
* @private
* @param {string} path the path to use
* @return {string} the parent folder, or ""
*/
var parentFolder = function (path) {
if (path.slice(-1) == '/') {
path = path.substring(0, path.length - 1);
}
var lastSlash = path.lastIndexOf('/');
return (lastSlash > 0) ? path.substring(0, lastSlash) : "";
};
/**
* Add a (sub) folder in the current folder.
* @private
* @param {string} name the folder's name
* @return {Object} the new folder.
*/
var folderAdd = function (name) {
// Check the name ends with a /
if (name.slice(-1) != "/") {
name += "/"; // IE doesn't like substr(-1)
}
// Does this folder already exist?
if (!this.files[name]) {
fileAdd.call(this, name, null, {dir:true});
}
return this.files[name];
};
/**
* Generate a JSZip.CompressedObject for a given zipOject.
* @param {ZipObject} file the object to read.
* @param {JSZip.compression} compression the compression to use.
* @return {JSZip.CompressedObject} the compressed result.
*/
var generateCompressedObjectFrom = function (file, compression) {
var result = new JSZip.CompressedObject(), content;
// the data has not been decompressed, we might reuse things !
if (file._data instanceof JSZip.CompressedObject) {
result.uncompressedSize = file._data.uncompressedSize;
result.crc32 = file._data.crc32;
if (result.uncompressedSize === 0 || file.options.dir) {
compression = JSZip.compressions['STORE'];
result.compressedContent = "";
result.crc32 = 0;
} else if (file._data.compressionMethod === compression.magic) {
result.compressedContent = file._data.getCompressedContent();
} else {
content = file._data.getContent()
// need to decompress / recompress
result.compressedContent = compression.compress(JSZip.utils.transformTo(compression.compressInputType, content));
}
} else {
// have uncompressed data
content = getBinaryData(file);
if (!content || content.length === 0 || file.options.dir) {
compression = JSZip.compressions['STORE'];
content = "";
}
result.uncompressedSize = content.length;
result.crc32 = this.crc32(content);
result.compressedContent = compression.compress(JSZip.utils.transformTo(compression.compressInputType, content));
}
result.compressedSize = result.compressedContent.length;
result.compressionMethod = compression.magic;
return result;
};
/**
* Generate the various parts used in the construction of the final zip file.
* @param {string} name the file name.
* @param {ZipObject} file the file content.
* @param {JSZip.CompressedObject} compressedObject the compressed object.
* @param {number} offset the current offset from the start of the zip file.
* @return {object} the zip parts.
*/
var generateZipParts = function(name, file, compressedObject, offset) {
var data = compressedObject.compressedContent,
utfEncodedFileName = this.utf8encode(file.name),
useUTF8 = utfEncodedFileName !== file.name,
o = file.options,
dosTime,
dosDate;
// date
// @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html
// @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html
// @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html
dosTime = o.date.getHours();
dosTime = dosTime << 6;
dosTime = dosTime | o.date.getMinutes();
dosTime = dosTime << 5;
dosTime = dosTime | o.date.getSeconds() / 2;
dosDate = o.date.getFullYear() - 1980;
dosDate = dosDate << 4;
dosDate = dosDate | (o.date.getMonth() + 1);
dosDate = dosDate << 5;
dosDate = dosDate | o.date.getDate();
var header = "";
// version needed to extract
header += "\x0A\x00";
// general purpose bit flag
// set bit 11 if utf8
header += useUTF8 ? "\x00\x08" : "\x00\x00";
// compression method
header += compressedObject.compressionMethod;
// last mod file time
header += decToHex(dosTime, 2);
// last mod file date
header += decToHex(dosDate, 2);
// crc-32
header += decToHex(compressedObject.crc32, 4);
// compressed size
header += decToHex(compressedObject.compressedSize, 4);
// uncompressed size
header += decToHex(compressedObject.uncompressedSize, 4);
// file name length
header += decToHex(utfEncodedFileName.length, 2);
// extra field length
header += "\x00\x00";
var fileRecord = JSZip.signature.LOCAL_FILE_HEADER + header + utfEncodedFileName;
var dirRecord = JSZip.signature.CENTRAL_FILE_HEADER +
// version made by (00: DOS)
"\x14\x00" +
// file header (common to file and central directory)
header +
// file comment length
"\x00\x00" +
// disk number start
"\x00\x00" +
// internal file attributes TODO
"\x00\x00" +
// external file attributes
(file.options.dir===true?"\x10\x00\x00\x00":"\x00\x00\x00\x00")+
// relative offset of local header
decToHex(offset, 4) +
// file name
utfEncodedFileName;
return {
fileRecord : fileRecord,
dirRecord : dirRecord,
compressedObject : compressedObject
};
};
/**
* An object to write any content to a string.
* @constructor
*/
var StringWriter = function () {
this.data = [];
};
StringWriter.prototype = {
/**
* Append any content to the current string.
* @param {Object} input the content to add.
*/
append : function (input) {
input = JSZip.utils.transformTo("string", input);
this.data.push(input);
},
/**
* Finalize the construction an return the result.
* @return {string} the generated string.
*/
finalize : function () {
return this.data.join("");
}
};
/**
* An object to write any content to an Uint8Array.
* @constructor
* @param {number} length The length of the array.
*/
var Uint8ArrayWriter = function (length) {
this.data = new Uint8Array(length);
this.index = 0;
};
Uint8ArrayWriter.prototype = {
/**
* Append any content to the current array.
* @param {Object} input the content to add.
*/
append : function (input) {
if (input.length !== 0) {
// with an empty Uint8Array, Opera fails with a "Offset larger than array size"
input = JSZip.utils.transformTo("uint8array", input);
this.data.set(input, this.index);
this.index += input.length;
}
},
/**
* Finalize the construction an return the result.
* @return {Uint8Array} the generated array.
*/
finalize : function () {
return this.data;
}
};
// return the actual prototype of JSZip
return {
/**
* Read an existing zip and merge the data in the current JSZip object.
* The implementation is in jszip-load.js, don't forget to include it.
* @param {String|ArrayBuffer|Uint8Array|Buffer} stream The stream to load
* @param {Object} options Options for loading the stream.
* options.base64 : is the stream in base64 ? default : false
* @return {JSZip} the current JSZip object
*/
load : function (stream, options) {
throw new Error("Load method is not defined. Is the file jszip-load.js included ?");
},
/**
* Filter nested files/folders with the specified function.
* @param {Function} search the predicate to use :
* function (relativePath, file) {...}
* It takes 2 arguments : the relative path and the file.
* @return {Array} An array of matching elements.
*/
filter : function (search) {
var result = [], filename, relativePath, file, fileClone;
for (filename in this.files) {
if ( !this.files.hasOwnProperty(filename) ) { continue; }
file = this.files[filename];
// return a new object, don't let the user mess with our internal objects :)
fileClone = new ZipObject(file.name, file._data, extend(file.options));
relativePath = filename.slice(this.root.length, filename.length);
if (filename.slice(0, this.root.length) === this.root && // the file is in the current root
search(relativePath, fileClone)) { // and the file matches the function
result.push(fileClone);
}
}
return result;
},
/**
* Add a file to the zip file, or search a file.
* @param {string|RegExp} name The name of the file to add (if data is defined),
* the name of the file to find (if no data) or a regex to match files.
* @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded
* @param {Object} o File options
* @return {JSZip|Object|Array} this JSZip object (when adding a file),
* a file (when searching by string) or an array of files (when searching by regex).
*/
file : function(name, data, o) {
if (arguments.length === 1) {
if (name instanceof RegExp) {
var regexp = name;
return this.filter(function(relativePath, file) {
return !file.options.dir && regexp.test(relativePath);
});
} else { // text
return this.filter(function (relativePath, file) {
return !file.options.dir && relativePath === name;
})[0]||null;
}
} else { // more than one argument : we have data !
name = this.root+name;
fileAdd.call(this, name, data, o);
}
return this;
},
/**
* Add a directory to the zip file, or search.
* @param {String|RegExp} arg The name of the directory to add, or a regex to search folders.
* @return {JSZip} an object with the new directory as the root, or an array containing matching folders.
*/
folder : function(arg) {
if (!arg) {
return this;
}
if (arg instanceof RegExp) {
return this.filter(function(relativePath, file) {
return file.options.dir && arg.test(relativePath);
});
}
// else, name is a new folder
var name = this.root + arg;
var newFolder = folderAdd.call(this, name);
// Allow chaining by returning a new object with this folder as the root
var ret = this.clone();
ret.root = newFolder.name;
return ret;
},
/**
* Delete a file, or a directory and all sub-files, from the zip
* @param {string} name the name of the file to delete
* @return {JSZip} this JSZip object
*/
remove : function(name) {
name = this.root + name;
var file = this.files[name];
if (!file) {
// Look for any folders
if (name.slice(-1) != "/") {
name += "/";
}
file = this.files[name];
}
if (file) {
if (!file.options.dir) {
// file
delete this.files[name];
} else {
// folder
var kids = this.filter(function (relativePath, file) {
return file.name.slice(0, name.length) === name;
});
for (var i = 0; i < kids.length; i++) {
delete this.files[kids[i].name];
}
}
}
return this;
},
/**
* Generate the complete zip file
* @param {Object} options the options to generate the zip file :
* - base64, (deprecated, use type instead) true to generate base64.
* - compression, "STORE" by default.
* - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
* @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file
*/
generate : function(options) {
options = extend(options || {}, {
base64 : true,
compression : "STORE",
type : "base64"
});
JSZip.utils.checkSupport(options.type);
var zipData = [], localDirLength = 0, centralDirLength = 0, writer, i;
// first, generate all the zip parts.
for (var name in this.files) {
if ( !this.files.hasOwnProperty(name) ) { continue; }
var file = this.files[name];
var compressionName = file.compression || options.compression.toUpperCase();
var compression = JSZip.compressions[compressionName];
if (!compression) {
throw new Error(compressionName + " is not a valid compression method !");
}
var compressedObject = generateCompressedObjectFrom.call(this, file, compression);
var zipPart = generateZipParts.call(this, name, file, compressedObject, localDirLength);
localDirLength += zipPart.fileRecord.length + compressedObject.compressedSize;
centralDirLength += zipPart.dirRecord.length;
zipData.push(zipPart);
}
var dirEnd = "";
// end of central dir signature
dirEnd = JSZip.signature.CENTRAL_DIRECTORY_END +
// number of this disk
"\x00\x00" +
// number of the disk with the start of the central directory
"\x00\x00" +
// total number of entries in the central directory on this disk
decToHex(zipData.length, 2) +
// total number of entries in the central directory
decToHex(zipData.length, 2) +
// size of the central directory 4 bytes
decToHex(centralDirLength, 4) +
// offset of start of central directory with respect to the starting disk number
decToHex(localDirLength, 4) +
// .ZIP file comment length
"\x00\x00";
// we have all the parts (and the total length)
// time to create a writer !
switch(options.type.toLowerCase()) {
case "uint8array" :
case "arraybuffer" :
case "blob" :
case "nodebuffer" :
writer = new Uint8ArrayWriter(localDirLength + centralDirLength + dirEnd.length);
break;
case "base64" :
default : // case "string" :
writer = new StringWriter(localDirLength + centralDirLength + dirEnd.length);
break;
}
for (i = 0; i < zipData.length; i++) {
writer.append(zipData[i].fileRecord);
writer.append(zipData[i].compressedObject.compressedContent);
}
for (i = 0; i < zipData.length; i++) {
writer.append(zipData[i].dirRecord);
}
writer.append(dirEnd);
var zip = writer.finalize();
switch(options.type.toLowerCase()) {
// case "zip is an Uint8Array"
case "uint8array" :
case "arraybuffer" :
case "nodebuffer" :
return JSZip.utils.transformTo(options.type.toLowerCase(), zip);
case "blob" :
return JSZip.utils.arrayBuffer2Blob(JSZip.utils.transformTo("arraybuffer", zip));
// case "zip is a string"
case "base64" :
return (options.base64) ? JSZip.base64.encode(zip) : zip;
default : // case "string" :
return zip;
}
},
/**
*
* Javascript crc32
* http://www.webtoolkit.info/
*
*/
crc32 : function crc32(input, crc) {
if (typeof input === "undefined" || !input.length) {
return 0;
}
var isArray = JSZip.utils.getTypeOf(input) !== "string";
var table = [
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
];
if (typeof(crc) == "undefined") { crc = 0; }
var x = 0;
var y = 0;
var byte = 0;
crc = crc ^ (-1);
for( var i = 0, iTop = input.length; i < iTop; i++ ) {
byte = isArray ? input[i] : input.charCodeAt(i);
y = ( crc ^ byte ) & 0xFF;
x = table[y];
crc = ( crc >>> 8 ) ^ x;
}
return crc ^ (-1);
},
// Inspired by http://my.opera.com/GreyWyvern/blog/show.dml/1725165
clone : function() {
var newObj = new JSZip();
for (var i in this) {
if (typeof this[i] !== "function") {
newObj[i] = this[i];
}
}
return newObj;
},
/**
* http://www.webtoolkit.info/javascript-utf8.html
*/
utf8encode : function (string) {
// TextEncoder + Uint8Array to binary string is faster than checking every bytes on long strings.
// http://jsperf.com/utf8encode-vs-textencoder
// On short strings (file names for example), the TextEncoder API is (currently) slower.
if (JSZip.support.uint8array && typeof TextEncoder === "function") {
var u8 = TextEncoder("utf-8").encode(string);
return JSZip.utils.transformTo("string", u8);
}
if (JSZip.support.nodebuffer) {
return JSZip.utils.transformTo("string", new Buffer(string, "utf-8"));
}
// array.join may be slower than string concatenation but generates less objects (less time spent garbage collecting).
// See also http://jsperf.com/array-direct-assignment-vs-push/31
var result = [], resIndex = 0;
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
result[resIndex++] = String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
result[resIndex++] = String.fromCharCode((c >> 6) | 192);
result[resIndex++] = String.fromCharCode((c & 63) | 128);
} else {
result[resIndex++] = String.fromCharCode((c >> 12) | 224);
result[resIndex++] = String.fromCharCode(((c >> 6) & 63) | 128);
result[resIndex++] = String.fromCharCode((c & 63) | 128);
}
}
return result.join("");
},
/**
* http://www.webtoolkit.info/javascript-utf8.html
*/
utf8decode : function (input) {
var result = [], resIndex = 0;
var type = JSZip.utils.getTypeOf(input);
var isArray = type !== "string";
var i = 0;
var c = 0, c1 = 0, c2 = 0, c3 = 0;
// check if we can use the TextDecoder API
// see http://encoding.spec.whatwg.org/#api
if (JSZip.support.uint8array && typeof TextDecoder === "function") {
return TextDecoder("utf-8").decode(
JSZip.utils.transformTo("uint8array", input)
);
}
if (JSZip.support.nodebuffer) {
return JSZip.utils.transformTo("nodebuffer", input).toString("utf-8");
}
while ( i < input.length ) {
c = isArray ? input[i] : input.charCodeAt(i);
if (c < 128) {
result[resIndex++] = String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = isArray ? input[i+1] : input.charCodeAt(i+1);
result[resIndex++] = String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = isArray ? input[i+1] : input.charCodeAt(i+1);
c3 = isArray ? input[i+2] : input.charCodeAt(i+2);
result[resIndex++] = String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return result.join("");
}
};
}());
/*
* Compression methods
* This object is filled in as follow :
* name : {
* magic // the 2 bytes indentifying the compression method
* compress // function, take the uncompressed content and return it compressed.
* uncompress // function, take the compressed content and return it uncompressed.
* compressInputType // string, the type accepted by the compress method. null to accept everything.
* uncompressInputType // string, the type accepted by the uncompress method. null to accept everything.
* }
*
* STORE is the default compression method, so it's included in this file.
* Other methods should go to separated files : the user wants modularity.
*/
JSZip.compressions = {
"STORE" : {
magic : "\x00\x00",
compress : function (content) {
return content; // no compression
},
uncompress : function (content) {
return content; // no compression
},
compressInputType : null,
uncompressInputType : null
}
};
/*
* List features that require a modern browser, and if the current browser support them.
*/
JSZip.support = {
// contains true if JSZip can read/generate ArrayBuffer, false otherwise.
arraybuffer : (function(){
return typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined";
})(),
// contains true if JSZip can read/generate nodejs Buffer, false otherwise.
nodebuffer : (function(){
return typeof Buffer !== "undefined";
})(),
// contains true if JSZip can read/generate Uint8Array, false otherwise.
uint8array : (function(){
return typeof Uint8Array !== "undefined";
})(),
// contains true if JSZip can read/generate Blob, false otherwise.
blob : (function(){
// the spec started with BlobBuilder then replaced it with a construtor for Blob.
// Result : we have browsers that :
// * know the BlobBuilder (but with prefix)
// * know the Blob constructor
// * know about Blob but not about how to build them
// About the "=== 0" test : if given the wrong type, it may be converted to a string.
// Instead of an empty content, we will get "[object Uint8Array]" for example.
if (typeof ArrayBuffer === "undefined") {
return false;
}
var buffer = new ArrayBuffer(0);
try {
return new Blob([buffer], { type: "application/zip" }).size === 0;
}
catch(e) {}
try {
var builder = new (window.BlobBuilder || window.WebKitBlobBuilder ||
window.MozBlobBuilder || window.MSBlobBuilder)();
builder.append(buffer);
return builder.getBlob('application/zip').size === 0;
}
catch(e) {}
return false;
})()
};
(function () {
JSZip.utils = {
/**
* Convert a string to a "binary string" : a string containing only char codes between 0 and 255.
* @param {string} str the string to transform.
* @return {String} the binary string.
*/
string2binary : function (str) {
var result = "";
for (var i = 0; i < str.length; i++) {
result += String.fromCharCode(str.charCodeAt(i) & 0xff);
}
return result;
},
/**
* Create a Uint8Array from the string.
* @param {string} str the string to transform.
* @return {Uint8Array} the typed array.
* @throws {Error} an Error if the browser doesn't support the requested feature.
* @deprecated : use JSZip.utils.transformTo instead.
*/
string2Uint8Array : function (str) {
return JSZip.utils.transformTo("uint8array", str);
},
/**
* Create a string from the Uint8Array.
* @param {Uint8Array} array the array to transform.
* @return {string} the string.
* @throws {Error} an Error if the browser doesn't support the requested feature.
* @deprecated : use JSZip.utils.transformTo instead.
*/
uint8Array2String : function (array) {
return JSZip.utils.transformTo("string", array);
},
/**
* Create a blob from the given ArrayBuffer.
* @param {ArrayBuffer} buffer the buffer to transform.
* @return {Blob} the result.
* @throws {Error} an Error if the browser doesn't support the requested feature.
*/
arrayBuffer2Blob : function (buffer) {
JSZip.utils.checkSupport("blob");
try {
// Blob constructor
return new Blob([buffer], { type: "application/zip" });
}
catch(e) {}
try {
// deprecated, browser only, old way
var builder = new (window.BlobBuilder || window.WebKitBlobBuilder ||
window.MozBlobBuilder || window.MSBlobBuilder)();
builder.append(buffer);
return builder.getBlob('application/zip');
}
catch(e) {}
// well, fuck ?!
throw new Error("Bug : can't construct the Blob.");
},
/**
* Create a blob from the given string.
* @param {string} str the string to transform.
* @return {Blob} the result.
* @throws {Error} an Error if the browser doesn't support the requested feature.
*/
string2Blob : function (str) {
var buffer = JSZip.utils.transformTo("arraybuffer", str);
return JSZip.utils.arrayBuffer2Blob(buffer);
}
};
/**
* The identity function.
* @param {Object} input the input.
* @return {Object} the same input.
*/
function identity(input) {
return input;
};
/**
* Fill in an array with a string.
* @param {String} str the string to use.
* @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated).
* @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array.
*/
function stringToArrayLike(str, array) {
for (var i = 0; i < str.length; ++i) {
array[i] = str.charCodeAt(i) & 0xFF;
}
return array;
};
/**
* Transform an array-like object to a string.
* @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform.
* @return {String} the result.
*/
function arrayLikeToString(array) {
// Performances notes :
// --------------------
// String.fromCharCode.apply(null, array) is the fastest, see
// see http://jsperf.com/converting-a-uint8array-to-a-string/2
// but the stack is limited (and we can get huge arrays !).
//
// result += String.fromCharCode(array[i]); generate too many strings !
//
// This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2
var chunk = 65536;
var result = [], len = array.length, type = JSZip.utils.getTypeOf(array), k = 0;
while (k < len && chunk > 1) {
try {
if (type === "array" || type === "nodebuffer") {
result.push(String.fromCharCode.apply(null, array.slice(k, Math.max(k + chunk, len))));
} else {
result.push(String.fromCharCode.apply(null, array.subarray(k, k + chunk)));
}
k += chunk;
} catch (e) {
chunk = Math.floor(chunk / 2);
}
}
return result.join("");
};
/**
* Copy the data from an array-like to an other array-like.
* @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array.
* @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated.
* @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array.
*/
function arrayLikeToArrayLike(arrayFrom, arrayTo) {
for(var i = 0; i < arrayFrom.length; i++) {
arrayTo[i] = arrayFrom[i];
}
return arrayTo;
};
// a matrix containing functions to transform everything into everything.
var transform = {};
// string to ?
transform["string"] = {
"string" : identity,
"array" : function (input) {
return stringToArrayLike(input, new Array(input.length));
},
"arraybuffer" : function (input) {
return transform["string"]["uint8array"](input).buffer;
},
"uint8array" : function (input) {
return stringToArrayLike(input, new Uint8Array(input.length));
},
"nodebuffer" : function (input) {
return stringToArrayLike(input, new Buffer(input.length));
}
};
// array to ?
transform["array"] = {
"string" : arrayLikeToString,
"array" : identity,
"arraybuffer" : function (input) {
return (new Uint8Array(input)).buffer;
},
"uint8array" : function (input) {
return new Uint8Array(input);
},
"nodebuffer" : function (input) {
return new Buffer(input);
}
};
// arraybuffer to ?
transform["arraybuffer"] = {
"string" : function (input) {
return arrayLikeToString(new Uint8Array(input));
},
"array" : function (input) {
return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength));
},
"arraybuffer" : identity,
"uint8array" : function (input) {
return new Uint8Array(input);
},
"nodebuffer" : function (input) {
return new Buffer(new Uint8Array(input));
}
};
// uint8array to ?
transform["uint8array"] = {
"string" : arrayLikeToString,
"array" : function (input) {
return arrayLikeToArrayLike(input, new Array(input.length));
},
"arraybuffer" : function (input) {
return input.buffer;
},
"uint8array" : identity,
"nodebuffer" : function(input) {
return new Buffer(input);
}
};
// nodebuffer to ?
transform["nodebuffer"] = {
"string" : arrayLikeToString,
"array" : function (input) {
return arrayLikeToArrayLike(input, new Array(input.length));
},
"arraybuffer" : function (input) {
return transform["nodebuffer"]["uint8array"](input).buffer;
},
"uint8array" : function (input) {
return arrayLikeToArrayLike(input, new Uint8Array(input.length));
},
"nodebuffer" : identity
};
/**
* Transform an input into any type.
* The supported output type are : string, array, uint8array, arraybuffer, nodebuffer.
* If no output type is specified, the unmodified input will be returned.
* @param {String} outputType the output type.
* @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert.
* @throws {Error} an Error if the browser doesn't support the requested output type.
*/
JSZip.utils.transformTo = function (outputType, input) {
if (!input) {
// undefined, null, etc
// an empty string won't harm.
input = "";
}
if (!outputType) {
return input;
}
JSZip.utils.checkSupport(outputType);
var inputType = JSZip.utils.getTypeOf(input);
var result = transform[inputType][outputType](input);
return result;
};
/**
* Return the type of the input.
* The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer.
* @param {Object} input the input to identify.
* @return {String} the (lowercase) type of the input.
*/
JSZip.utils.getTypeOf = function (input) {
if (typeof input === "string") {
return "string";
}
if (input instanceof Array) {
return "array";
}
if (JSZip.support.nodebuffer && Buffer.isBuffer(input)) {
return "nodebuffer";
}
if (JSZip.support.uint8array && input instanceof Uint8Array) {
return "uint8array";
}
if (JSZip.support.arraybuffer && input instanceof ArrayBuffer) {
return "arraybuffer";
}
};
/**
* Throw an exception if the type is not supported.
* @param {String} type the type to check.
* @throws {Error} an Error if the browser doesn't support the requested type.
*/
JSZip.utils.checkSupport = function (type) {
var supported = true;
switch (type.toLowerCase()) {
case "uint8array":
supported = JSZip.support.uint8array;
break;
case "arraybuffer":
supported = JSZip.support.arraybuffer;
break;
case "nodebuffer":
supported = JSZip.support.nodebuffer;
break;
case "blob":
supported = JSZip.support.blob;
break;
}
if (!supported) {
throw new Error(type + " is not supported by this browser");
}
};
})();
(function (){
/**
* Represents an entry in the zip.
* The content may or may not be compressed.
* @constructor
*/
JSZip.CompressedObject = function () {
this.compressedSize = 0;
this.uncompressedSize = 0;
this.crc32 = 0;
this.compressionMethod = null;
this.compressedContent = null;
};
JSZip.CompressedObject.prototype = {
/**
* Return the decompressed content in an unspecified format.
* The format will depend on the decompressor.
* @return {Object} the decompressed content.
*/
getContent : function () {
return null; // see implementation
},
/**
* Return the compressed content in an unspecified format.
* The format will depend on the compressed conten source.
* @return {Object} the compressed content.
*/
getCompressedContent : function () {
return null; // see implementation
}
};
})();
/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
* Hacked so that it doesn't utf8 en/decode everything
**/
JSZip.base64 = (function() {
// private property
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
return {
// public method for encoding
encode : function(input, utf8) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function(input, utf8) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
return output;
}
};
}());
// enforcing Stuk's coding style
// vim: set shiftwidth=3 softtabstop=3:
================================================
FILE: docs/bower_components/bootstrap/assets/js/less.js
================================================
//
// LESS - Leaner CSS v1.3.3
// http://lesscss.org
//
// Copyright (c) 2009-2013, Alexis Sellier
// Licensed under the Apache 2.0 License.
//
(function(e,t){function n(t){return e.less[t.split("/")[1]]}function f(){r.env==="development"?(r.optimization=0,r.watchTimer=setInterval(function(){r.watchMode&&g(function(e,t,n,r,i){t&&S(t.toCSS(),r,i.lastModified)})},r.poll)):r.optimization=3}function m(){var e=document.getElementsByTagName("style");for(var t=0;t0&&(s.splice(o-1,2),o-=2)}return i.hostPart=r[1],i.directories=s,i.path=r[1]+s.join("/"),i.fileUrl=i.path+(r[4]||""),i.url=i.fileUrl+(r[5]||""),i}function w(t,n,i,s){var o=t.contents||{},u=t.files||{},a=b(t.href,e.location.href),f=a.url,c=l&&l.getItem(f),h=l&&l.getItem(f+":timestamp"),p={css:c,timestamp:h},d;r.relativeUrls?r.rootpath?t.entryPath?d=b(r.rootpath+y(a.path,t.entryPath)).path:d=r.rootpath:d=a.path:r.rootpath?d=r.rootpath:t.entryPath?d=t.entryPath:d=a.path,x(f,t.type,function(e,l){v+=e.replace(/@import .+?;/ig,"");if(!i&&p&&l&&(new Date(l)).valueOf()===(new Date(p.timestamp)).valueOf())S(p.css,t),n(null,null,e,t,{local:!0,remaining:s},f);else try{o[f]=e,(new r.Parser({optimization:r.optimization,paths:[a.path],entryPath:t.entryPath||a.path,mime:t.type,filename:f,rootpath:d,relativeUrls:t.relativeUrls,contents:o,files:u,dumpLineNumbers:r.dumpLineNumbers})).parse(e,function(r,i){if(r)return k(r,f);try{n(r,i,e,t,{local:!1,lastModified:l,remaining:s},f),N(document.getElementById("less-error-message:"+E(f)))}catch(r){k(r,f)}})}catch(c){k(c,f)}},function(e,t){throw new Error("Couldn't load "+t+" ("+e+")")})}function E(e){return e.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\.[a-zA-Z]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function S(e,t,n){var r,i=t.href||"",s="less:"+(t.title||E(i));if((r=document.getElementById(s))===null){r=document.createElement("style"),r.type="text/css",t.media&&(r.media=t.media),r.id=s;var o=t&&t.nextSibling||null;(o||document.getElementsByTagName("head")[0]).parentNode.insertBefore(r,o)}if(r.styleSheet)try{r.styleSheet.cssText=e}catch(u){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(e){r.childNodes.length>0?r.firstChild.nodeValue!==e.nodeValue&&r.replaceChild(e,r.firstChild):r.appendChild(e)})(document.createTextNode(e));if(n&&l){C("saving "+i+" to cache.");try{l.setItem(i,e),l.setItem(i+":timestamp",n)}catch(u){C("failed to save")}}}function x(e,t,n,i){function a(t,n,r){t.status>=200&&t.status<300?n(t.responseText,t.getResponseHeader("Last-Modified")):typeof r=="function"&&r(t.status,e)}var s=T(),u=o?r.fileAsync:r.async;typeof s.overrideMimeType=="function"&&s.overrideMimeType("text/css"),s.open("GET",e,u),s.setRequestHeader("Accept",t||"text/x-less, text/css; q=0.9, */*; q=0.5"),s.send(null),o&&!r.fileAsync?s.status===0||s.status>=200&&s.status<300?n(s.responseText):i(s.status,e):u?s.onreadystatechange=function(){s.readyState==4&&a(s,n,i)}:a(s,n,i)}function T(){if(e.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(t){return C("browser doesn't support AJAX."),null}}function N(e){return e&&e.parentNode.removeChild(e)}function C(e){r.env=="development"&&typeof console!="undefined"&&console.log("less: "+e)}function k(e,t){var n="less-error-message:"+E(t),i='
"+(e.message||"There is an error in your .less file")+"
"+'
in '+l+" ";var c=function(e,t,n){e.extract[t]&&a.push(i.replace(/\{line\}/,parseInt(e.line)+(t-1)).replace(/\{class\}/,n).replace(/\{content\}/,e.extract[t]))};e.stack?u+=" "+e.stack.split("\n").slice(1).join(" "):e.extract&&(c(e,0,""),c(e,1,"line"),c(e,2,""),u+="on line "+e.line+", column "+(e.column+1)+":
"+"
"+a.join("")+"
"),s.innerHTML=u,S([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),s.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),r.env=="development"&&(o=setInterval(function(){document.body&&(document.getElementById(n)?document.body.replaceChild(s,document.getElementById(n)):document.body.insertBefore(s,document.body.firstChild),clearInterval(o))},10))}Array.isArray||(Array.isArray=function(e){return Object.prototype.toString.call(e)==="[object Array]"||e instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(e,t){var n=this.length>>>0;for(var r=0;r>>0,n=new Array(t),r=arguments[1];for(var i=0;i>>0,n=0;if(t===0&&arguments.length===1)throw new TypeError;if(arguments.length>=2)var r=arguments[1];else do{if(n in this){r=this[n++];break}if(++n>=t)throw new TypeError}while(!0);for(;n=t)return-1;n<0&&(n+=t);for(;nh&&(c[u]=c[u].slice(o-h),h=o)}function w(e){var t=e.charCodeAt(0);return t===32||t===10||t===9}function E(e){var t,n,r,i,a;if(e instanceof Function)return e.call(p.parsers);if(typeof e=="string")t=s.charAt(o)===e?e:null,r=1,b();else{b();if(!(t=e.exec(c[u])))return null;r=t[0].length}if(t)return S(r),typeof t=="string"?t:t.length===1?t[0]:t}function S(e){var t=o,n=u,r=o+c[u].length,i=o+=e;while(o=0&&t.charAt(n)!=="\n";n--)r++;return{line:typeof e=="number"?(t.slice(0,e).match(/\n/g)||"").length:null,column:r}}function L(e){return r.mode==="browser"||r.mode==="rhino"?e.filename:n("path").resolve(e.filename)}function A(e,t,n){return{lineNumber:k(e,t).line+1,fileName:L(n)}}function O(e,t){var n=C(e,t),r=k(e.index,n),i=r.line,s=r.column,o=n.split("\n");this.type=e.type||"Syntax",this.message=e.message,this.filename=e.filename||t.filename,this.index=e.index,this.line=typeof i=="number"?i+1:null,this.callLine=e.call&&k(e.call,n).line+1,this.callExtract=o[k(e.call,n).line],this.stack=e.stack,this.column=s,this.extract=[o[i-1],o[i],o[i+1]]}var s,o,u,a,f,l,c,h,p,d=this,t=t||{};t.contents||(t.contents={}),t.rootpath=t.rootpath||"",t.files||(t.files={});var v=function(){},m=this.imports={paths:t.paths||[],queue:[],files:t.files,contents:t.contents,mime:t.mime,error:null,push:function(e,n){var i=this;this.queue.push(e),r.Parser.importer(e,this.paths,function(t,r,s){i.queue.splice(i.queue.indexOf(e),1);var o=s in i.files;i.files[s]=r,t&&!i.error&&(i.error=t),n(t,r,o),i.queue.length===0&&v(i.error)},t)}};return this.env=t=t||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.filename=this.env.filename||null,p={imports:m,parse:function(e,a){var f,d,m,g,y,b,w=[],S,x=null;o=u=h=l=0,s=e.replace(/\r\n/g,"\n"),s=s.replace(/^\uFEFF/,""),c=function(e){var n=0,r=/(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,i=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,o=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,u=0,a,f=e[0],l;for(var c=0,h,p;c0?"missing closing `}`":"missing opening `{`",filename:t.filename},t)),e.map(function(e){return e.join("")})}([[]]);if(x)return a(x,t);try{f=new i.Ruleset([],E(this.parsers.primary)),f.root=!0}catch(T){return a(new O(T,t))}f.toCSS=function(e){var s,o,u;return function(s,o){var u=[],a;s=s||{},typeof o=="object"&&!Array.isArray(o)&&(o=Object.keys(o).map(function(e){var t=o[e];return t instanceof i.Value||(t instanceof i.Expression||(t=new i.Expression([t])),t=new i.Value([t])),new i.Rule("@"+e,t,!1,0)}),u=[new i.Ruleset(null,o)]);try{var f=e.call(this,{frames:u}).toCSS([],{compress:s.compress||!1,dumpLineNumbers:t.dumpLineNumbers})}catch(l){throw new O(l,t)}if(a=p.imports.error)throw a instanceof O?a:new O(a,t);return s.yuicompress&&r.mode==="node"?n("ycssmin").cssmin(f):s.compress?f.replace(/(\s)+/g,"$1"):f}}(f.eval);if(o=0&&s.charAt(N)!=="\n";N--)C++;x={type:"Parse",message:"Syntax Error on line "+y,index:o,filename:t.filename,line:y,column:C,extract:[b[y-2],b[y-1],b[y]]}}this.imports.queue.length>0?v=function(e){e=x||e,e?a(e):a(null,f)}:a(x,f)},parsers:{primary:function(){var e,t=[];while((e=E(this.mixin.definition)||E(this.rule)||E(this.ruleset)||E(this.mixin.call)||E(this.comment)||E(this.directive))||E(/^[\s\n]+/)||E(/^;+/))e&&t.push(e);return t},comment:function(){var e;if(s.charAt(o)!=="/")return;if(s.charAt(o+1)==="/")return new i.Comment(E(/^\/\/.*/),!0);if(e=E(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new i.Comment(e)},entities:{quoted:function(){var e,t=o,n;s.charAt(t)==="~"&&(t++,n=!0);if(s.charAt(t)!=='"'&&s.charAt(t)!=="'")return;n&&E("~");if(e=E(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new i.Quoted(e[0],e[1]||e[2],n)},keyword:function(){var e;if(e=E(/^[_A-Za-z-][_A-Za-z0-9-]*/))return i.colors.hasOwnProperty(e)?new i.Color(i.colors[e].slice(1)):new i.Keyword(e)},call:function(){var e,n,r,s,a=o;if(!(e=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(c[u])))return;e=e[1],n=e.toLowerCase();if(n==="url")return null;o+=e.length;if(n==="alpha"){s=E(this.alpha);if(typeof s!="undefined")return s}E("("),r=E(this.entities.arguments);if(!E(")"))return;if(e)return new i.Call(e,r,a,t.filename)},arguments:function(){var e=[],t;while(t=E(this.entities.assignment)||E(this.expression)){e.push(t);if(!E(","))break}return e},literal:function(){return E(this.entities.ratio)||E(this.entities.dimension)||E(this.entities.color)||E(this.entities.quoted)||E(this.entities.unicodeDescriptor)},assignment:function(){var e,t;if((e=E(/^\w+(?=\s?=)/i))&&E("=")&&(t=E(this.entity)))return new i.Assignment(e,t)},url:function(){var e;if(s.charAt(o)!=="u"||!E(/^url\(/))return;return e=E(this.entities.quoted)||E(this.entities.variable)||E(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/)||"",x(")"),new i.URL(e.value!=null||e instanceof i.Variable?e:new i.Anonymous(e),t.rootpath)},variable:function(){var e,n=o;if(s.charAt(o)==="@"&&(e=E(/^@@?[\w-]+/)))return new i.Variable(e,n,t.filename)},variableCurly:function(){var e,n,r=o;if(s.charAt(o)==="@"&&(n=E(/^@\{([\w-]+)\}/)))return new i.Variable("@"+n[1],r,t.filename)},color:function(){var e;if(s.charAt(o)==="#"&&(e=E(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/)))return new i.Color(e[1])},dimension:function(){var e,t=s.charCodeAt(o);if(t>57||t<43||t===47||t==44)return;if(e=E(/^([+-]?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn|dpi|dpcm|dppx|rem|vw|vh|vmin|vm|ch)?/))return new i.Dimension(e[1],e[2])},ratio:function(){var e,t=s.charCodeAt(o);if(t>57||t<48)return;if(e=E(/^(\d+\/\d+)/))return new i.Ratio(e[1])},unicodeDescriptor:function(){var e;if(e=E(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/))return new i.UnicodeDescriptor(e[0])},javascript:function(){var e,t=o,n;s.charAt(t)==="~"&&(t++,n=!0);if(s.charAt(t)!=="`")return;n&&E("~");if(e=E(/^`([^`]*)`/))return new i.JavaScript(e[1],o,n)}},variable:function(){var e;if(s.charAt(o)==="@"&&(e=E(/^(@[\w-]+)\s*:/)))return e[1]},shorthand:function(){var e,t;if(!N(/^[@\w.%-]+\/[@\w.-]+/))return;g();if((e=E(this.entity))&&E("/")&&(t=E(this.entity)))return new i.Shorthand(e,t);y()},mixin:{call:function(){var e=[],n,r,u=[],a=[],f,l,c,h,p,d,v,m=o,b=s.charAt(o),w,S,C=!1;if(b!=="."&&b!=="#")return;g();while(n=E(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/))e.push(new i.Element(r,n,o)),r=E(">");if(E("(")){p=[];while(c=E(this.expression)){h=null,S=c;if(c.value.length==1){var k=c.value[0];k instanceof i.Variable&&E(":")&&(p.length>0&&(d&&T("Cannot mix ; and , as delimiter types"),v=!0),S=x(this.expression),h=w=k.name)}p.push(S),a.push({name:h,value:S});if(E(","))continue;if(E(";")||d)v&&T("Cannot mix ; and , as delimiter types"),d=!0,p.length>1&&(S=new i.Value(p)),u.push({name:w,value:S}),w=null,p=[],v=!1}x(")")}f=d?u:a,E(this.important)&&(C=!0);if(e.length>0&&(E(";")||N("}")))return new i.mixin.Call(e,f,m,t.filename,C);y()},definition:function(){var e,t=[],n,r,u,a,f,c=!1;if(s.charAt(o)!=="."&&s.charAt(o)!=="#"||N(/^[^{]*\}/))return;g();if(n=E(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)){e=n[1];do{E(this.comment);if(s.charAt(o)==="."&&E(/^\.{3}/)){c=!0,t.push({variadic:!0});break}if(!(u=E(this.entities.variable)||E(this.entities.literal)||E(this.entities.keyword)))break;if(u instanceof i.Variable)if(E(":"))a=x(this.expression,"expected expression"),t.push({name:u.name,value:a});else{if(E(/^\.{3}/)){t.push({name:u.name,variadic:!0}),c=!0;break}t.push({name:u.name})}else t.push({value:u})}while(E(",")||E(";"));E(")")||(l=o,y()),E(this.comment),E(/^when/)&&(f=x(this.conditions,"expected condition")),r=E(this.block);if(r)return new i.mixin.Definition(e,t,r,f,c);y()}}},entity:function(){return E(this.entities.literal)||E(this.entities.variable)||E(this.entities.url)||E(this.entities.call)||E(this.entities.keyword)||E(this.entities.javascript)||E(this.comment)},end:function(){return E(";")||N("}")},alpha:function(){var e;if(!E(/^\(opacity=/i))return;if(e=E(/^\d+/)||E(this.entities.variable))return x(")"),new i.Alpha(e)},element:function(){var e,t,n,r;n=E(this.combinator),e=E(/^(?:\d+\.\d+|\d+)%/)||E(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)||E("*")||E("&")||E(this.attribute)||E(/^\([^()@]+\)/)||E(/^[\.#](?=@)/)||E(this.entities.variableCurly),e||E("(")&&(r=E(this.entities.variableCurly)||E(this.entities.variable)||E(this.selector))&&E(")")&&(e=new i.Paren(r));if(e)return new i.Element(n,e,o)},combinator:function(){var e,t=s.charAt(o);if(t===">"||t==="+"||t==="~"||t==="|"){o++;while(s.charAt(o).match(/\s/))o++;return new i.Combinator(t)}return s.charAt(o-1).match(/\s/)?new i.Combinator(" "):new i.Combinator(null)},selector:function(){var e,t,n=[],r,u;if(E("("))return e=E(this.entity),E(")")?new i.Selector([new i.Element("",e,o)]):null;while(t=E(this.element)){r=s.charAt(o),n.push(t);if(r==="{"||r==="}"||r===";"||r===","||r===")")break}if(n.length>0)return new i.Selector(n)},attribute:function(){var e="",t,n,r;if(!E("["))return;if(t=E(/^(?:[_A-Za-z0-9-]|\\.)+/)||E(this.entities.quoted))(r=E(/^[|~*$^]?=/))&&(n=E(this.entities.quoted)||E(/^[\w-]+/))?e=[t,r,n.toCSS?n.toCSS():n].join(""):e=t;if(!E("]"))return;if(e)return"["+e+"]"},block:function(){var e;if(E("{")&&(e=E(this.primary))&&E("}"))return e},ruleset:function(){var e=[],n,r,u,a;g(),t.dumpLineNumbers&&(a=A(o,s,t));while(n=E(this.selector)){e.push(n),E(this.comment);if(!E(","))break;E(this.comment)}if(e.length>0&&(r=E(this.block))){var f=new i.Ruleset(e,r,t.strictImports);return t.dumpLineNumbers&&(f.debugInfo=a),f}l=o,y()},rule:function(){var e,t,n=s.charAt(o),r,a;g();if(n==="."||n==="#"||n==="&")return;if(e=E(this.variable)||E(this.property)){e.charAt(0)!="@"&&(a=/^([^@+\/'"*`(;{}-]*);/.exec(c[u]))?(o+=a[0].length-1,t=new i.Anonymous(a[1])):e==="font"?t=E(this.font):t=E(this.value),r=E(this.important);if(t&&E(this.end))return new i.Rule(e,t,r,f);l=o,y()}},"import":function(){var e,n,r=o;g();var s=E(/^@import(?:-(once))?\s+/);if(s&&(e=E(this.entities.quoted)||E(this.entities.url))){n=E(this.mediaFeatures);if(E(";"))return new i.Import(e,m,n,s[1]==="once",r,t.rootpath)}y()},mediaFeature:function(){var e,t,n=[];do if(e=E(this.entities.keyword))n.push(e);else if(E("(")){t=E(this.property),e=E(this.entity);if(!E(")"))return null;if(t&&e)n.push(new i.Paren(new i.Rule(t,e,null,o,!0)));else{if(!e)return null;n.push(new i.Paren(e))}}while(e);if(n.length>0)return new i.Expression(n)},mediaFeatures:function(){var e,t=[];do if(e=E(this.mediaFeature)){t.push(e);if(!E(","))break}else if(e=E(this.entities.variable)){t.push(e);if(!E(","))break}while(e);return t.length>0?t:null},media:function(){var e,n,r,u;t.dumpLineNumbers&&(u=A(o,s,t));if(E(/^@media/)){e=E(this.mediaFeatures);if(n=E(this.block))return r=new i.Media(n,e),t.dumpLineNumbers&&(r.debugInfo=u),r}},directive:function(){var e,n,r,u,a,f,l,c,h,p;if(s.charAt(o)!=="@")return;if(n=E(this["import"])||E(this.media))return n;g(),e=E(/^@[a-z-]+/);if(!e)return;l=e,e.charAt(1)=="-"&&e.indexOf("-",2)>0&&(l="@"+e.slice(e.indexOf("-",2)+1));switch(l){case"@font-face":c=!0;break;case"@viewport":case"@top-left":case"@top-left-corner":case"@top-center":case"@top-right":case"@top-right-corner":case"@bottom-left":case"@bottom-left-corner":case"@bottom-center":case"@bottom-right":case"@bottom-right-corner":case"@left-top":case"@left-middle":case"@left-bottom":case"@right-top":case"@right-middle":case"@right-bottom":c=!0;break;case"@page":case"@document":case"@supports":case"@keyframes":c=!0,h=!0;break;case"@namespace":p=!0}h&&(e+=" "+(E(/^[^{]+/)||"").trim());if(c){if(r=E(this.block))return new i.Directive(e,r)}else if((n=p?E(this.expression):E(this.entity))&&E(";")){var d=new i.Directive(e,n);return t.dumpLineNumbers&&(d.debugInfo=A(o,s,t)),d}y()},font:function(){var e=[],t=[],n,r,s,o;while(o=E(this.shorthand)||E(this.entity))t.push(o);e.push(new i.Expression(t));if(E(","))while(o=E(this.expression)){e.push(o);if(!E(","))break}return new i.Value(e)},value:function(){var e,t=[],n;while(e=E(this.expression)){t.push(e);if(!E(","))break}if(t.length>0)return new i.Value(t)},important:function(){if(s.charAt(o)==="!")return E(/^! *important/)},sub:function(){var e;if(E("(")&&(e=E(this.expression))&&E(")"))return e},multiplication:function(){var e,t,n,r;if(e=E(this.operand)){while(!N(/^\/[*\/]/)&&(n=E("/")||E("*"))&&(t=E(this.operand)))r=new i.Operation(n,[r||e,t]);return r||e}},addition:function(){var e,t,n,r;if(e=E(this.multiplication)){while((n=E(/^[-+]\s+/)||!w(s.charAt(o-1))&&(E("+")||E("-")))&&(t=E(this.multiplication)))r=new i.Operation(n,[r||e,t]);return r||e}},conditions:function(){var e,t,n=o,r;if(e=E(this.condition)){while(E(",")&&(t=E(this.condition)))r=new i.Condition("or",r||e,t,n);return r||e}},condition:function(){var e,t,n,r,s=o,u=!1;E(/^not/)&&(u=!0),x("(");if(e=E(this.addition)||E(this.entities.keyword)||E(this.entities.quoted))return(r=E(/^(?:>=|=<|[<=>])/))?(t=E(this.addition)||E(this.entities.keyword)||E(this.entities.quoted))?n=new i.Condition(r,e,t,s,u):T("expected expression"):n=new i.Condition("=",e,new i.Keyword("true"),s,u),x(")"),E(/^and/)?new i.Condition("and",n,E(this.condition)):n},operand:function(){var e,t=s.charAt(o+1);s.charAt(o)==="-"&&(t==="@"||t==="(")&&(e=E("-"));var n=E(this.sub)||E(this.entities.dimension)||E(this.entities.color)||E(this.entities.variable)||E(this.entities.call);return e?new i.Operation("*",[new i.Dimension(-1),n]):n},expression:function(){var e,t,n=[],r;while(e=E(this.addition)||E(this.entity))n.push(e);if(n.length>0)return new i.Expression(n)},property:function(){var e;if(e=E(/^(\*?-?[_a-z0-9-]+)\s*:/))return e[1]}}}};if(r.mode==="browser"||r.mode==="rhino")r.Parser.importer=function(e,t,n,r){!/^([a-z-]+:)?\//.test(e)&&t.length>0&&(e=t[0]+e),w({href:e,title:e,type:r.mime,contents:r.contents,files:r.files,rootpath:r.rootpath,entryPath:r.entryPath,relativeUrls:r.relativeUrls},function(e,i,s,o,u,a){e&&typeof r.errback=="function"?r.errback.call(null,a,t,n,r):n.call(null,e,i,a)},!0)};(function(e){function t(t){return e.functions.hsla(t.h,t.s,t.l,t.a)}function n(t,n){return t instanceof e.Dimension&&t.unit=="%"?parseFloat(t.value*n/100):r(t)}function r(t){if(t instanceof e.Dimension)return parseFloat(t.unit=="%"?t.value/100:t.value);if(typeof t=="number")return t;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function i(e){return Math.min(1,Math.max(0,e))}e.functions={rgb:function(e,t,n){return this.rgba(e,t,n,1)},rgba:function(t,i,s,o){var u=[t,i,s].map(function(e){return n(e,256)});return o=r(o),new e.Color(u,o)},hsl:function(e,t,n){return this.hsla(e,t,n,1)},hsla:function(e,t,n,i){function u(e){return e=e<0?e+1:e>1?e-1:e,e*6<1?o+(s-o)*e*6:e*2<1?s:e*3<2?o+(s-o)*(2/3-e)*6:o}e=r(e)%360/360,t=r(t),n=r(n),i=r(i);var s=n<=.5?n*(t+1):n+t-n*t,o=n*2-s;return this.rgba(u(e+1/3)*255,u(e)*255,u(e-1/3)*255,i)},hsv:function(e,t,n){return this.hsva(e,t,n,1)},hsva:function(e,t,n,i){e=r(e)%360/360*360,t=r(t),n=r(n),i=r(i);var s,o;s=Math.floor(e/60%6),o=e/60-s;var u=[n,n*(1-t),n*(1-o*t),n*(1-(1-o)*t)],a=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]];return this.rgba(u[a[s][0]]*255,u[a[s][1]]*255,u[a[s][2]]*255,i)},hue:function(t){return new e.Dimension(Math.round(t.toHSL().h))},saturation:function(t){return new e.Dimension(Math.round(t.toHSL().s*100),"%")},lightness:function(t){return new e.Dimension(Math.round(t.toHSL().l*100),"%")},red:function(t){return new e.Dimension(t.rgb[0])},green:function(t){return new e.Dimension(t.rgb[1])},blue:function(t){return new e.Dimension(t.rgb[2])},alpha:function(t){return new e.Dimension(t.toHSL().a)},luma:function(t){return new e.Dimension(Math.round((.2126*(t.rgb[0]/255)+.7152*(t.rgb[1]/255)+.0722*(t.rgb[2]/255))*t.alpha*100),"%")},saturate:function(e,n){var r=e.toHSL();return r.s+=n.value/100,r.s=i(r.s),t(r)},desaturate:function(e,n){var r=e.toHSL();return r.s-=n.value/100,r.s=i(r.s),t(r)},lighten:function(e,n){var r=e.toHSL();return r.l+=n.value/100,r.l=i(r.l),t(r)},darken:function(e,n){var r=e.toHSL();return r.l-=n.value/100,r.l=i(r.l),t(r)},fadein:function(e,n){var r=e.toHSL();return r.a+=n.value/100,r.a=i(r.a),t(r)},fadeout:function(e,n){var r=e.toHSL();return r.a-=n.value/100,r.a=i(r.a),t(r)},fade:function(e,n){var r=e.toHSL();return r.a=n.value/100,r.a=i(r.a),t(r)},spin:function(e,n){var r=e.toHSL(),i=(r.h+n.value)%360;return r.h=i<0?360+i:i,t(r)},mix:function(t,n,r){r||(r=new e.Dimension(50));var i=r.value/100,s=i*2-1,o=t.toHSL().a-n.toHSL().a,u=((s*o==-1?s:(s+o)/(1+s*o))+1)/2,a=1-u,f=[t.rgb[0]*u+n.rgb[0]*a,t.rgb[1]*u+n.rgb[1]*a,t.rgb[2]*u+n.rgb[2]*a],l=t.alpha*i+n.alpha*(1-i);return new e.Color(f,l)},greyscale:function(t){return this.desaturate(t,new e.Dimension(100))},contrast:function(e,t,n,r){return e.rgb?(typeof n=="undefined"&&(n=this.rgba(255,255,255,1)),typeof t=="undefined"&&(t=this.rgba(0,0,0,1)),typeof r=="undefined"?r=.43:r=r.value,(.2126*(e.rgb[0]/255)+.7152*(e.rgb[1]/255)+.0722*(e.rgb[2]/255))*e.alpha255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("")},operate:function(t,n){var r=[];n instanceof e.Color||(n=n.toColor());for(var i=0;i<3;i++)r[i]=e.operate(t,this.rgb[i],n.rgb[i]);return new e.Color(r,this.alpha+n.alpha)},toHSL:function(){var e=this.rgb[0]/255,t=this.rgb[1]/255,n=this.rgb[2]/255,r=this.alpha,i=Math.max(e,t,n),s=Math.min(e,t,n),o,u,a=(i+s)/2,f=i-s;if(i===s)o=u=0;else{u=a>.5?f/(2-i-s):f/(i+s);switch(i){case e:o=(t-n)/f+(t255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("")},compare:function(e){return e.rgb?e.rgb[0]===this.rgb[0]&&e.rgb[1]===this.rgb[1]&&e.rgb[2]===this.rgb[2]&&e.alpha===this.alpha?0:-1:-1}}}(n("../tree")),function(e){e.Comment=function(e,t){this.value=e,this.silent=!!t},e.Comment.prototype={toCSS:function(e){return e.compress?"":this.value},eval:function(){return this}}}(n("../tree")),function(e){e.Condition=function(e,t,n,r,i){this.op=e.trim(),this.lvalue=t,this.rvalue=n,this.index=r,this.negate=i},e.Condition.prototype.eval=function(e){var t=this.lvalue.eval(e),n=this.rvalue.eval(e),r=this.index,i,i=function(e){switch(e){case"and":return t&&n;case"or":return t||n;default:if(t.compare)i=t.compare(n);else{if(!n.compare)throw{type:"Type",message:"Unable to perform comparison",index:r};i=n.compare(t)}switch(i){case-1:return e==="<"||e==="=<";case 0:return e==="="||e===">="||e==="=<";case 1:return e===">"||e===">="}}}(this.op);return this.negate?!i:i}}(n("../tree")),function(e){e.Dimension=function(e,t){this.value=parseFloat(e),this.unit=t||null},e.Dimension.prototype={eval:function(){return this},toColor:function(){return new e.Color([this.value,this.value,this.value])},toCSS:function(){var e=this.value+this.unit;return e},operate:function(t,n){return new e.Dimension(e.operate(t,this.value,n.value),this.unit||n.unit)},compare:function(t){return t instanceof e.Dimension?t.value>this.value?-1:t.value":e.compress?">":" > ","|":e.compress?"|":" | "}[this.value]}}(n("../tree")),function(e){e.Expression=function(e){this.value=e},e.Expression.prototype={eval:function(t){return this.value.length>1?new e.Expression(this.value.map(function(e){return e.eval(t)})):this.value.length===1?this.value[0].eval(t):this},toCSS:function(e){return this.value.map(function(t){return t.toCSS?t.toCSS(e):""}).join(" ")}}}(n("../tree")),function(e){e.Import=function(t,n,r,i,s,o){var u=this;this.once=i,this.index=s,this._path=t,this.features=r&&new e.Value(r),this.rootpath=o,t instanceof e.Quoted?this.path=/(\.[a-z]*$)|([\?;].*)$/.test(t.value)?t.value:t.value+".less":this.path=t.value.value||t.value,this.css=/css([\?;].*)?$/.test(this.path),this.css||n.push(this.path,function(t,n,r){t&&(t.index=s),r&&u.once&&(u.skip=r),u.root=n||new e.Ruleset([],[])})},e.Import.prototype={toCSS:function(e){var t=this.features?" "+this.features.toCSS(e):"";return this.css?(typeof this._path.value=="string"&&!/^(?:[a-z-]+:|\/)/.test(this._path.value)&&(this._path.value=this.rootpath+this._path.value),"@import "+this._path.toCSS()+t+";\n"):""},eval:function(t){var n,r=this.features&&this.features.eval(t);return this.skip?[]:this.css?this:(n=new e.Ruleset([],this.root.rules.slice(0)),n.evalImports(t),this.features?new e.Media(n.rules,this.features.value):n.rules)}}}(n("../tree")),function(e){e.JavaScript=function(e,t,n){this.escaped=n,this.expression=e,this.index=t},e.JavaScript.prototype={eval:function(t){var n,r=this,i={},s=this.expression.replace(/@\{([\w-]+)\}/g,function(n,i){return e.jsify((new e.Variable("@"+i,r.index)).eval(t))});try{s=new Function("return ("+s+")")}catch(o){throw{message:"JavaScript evaluation error: `"+s+"`",index:this.index}}for(var u in t.frames[0].variables())i[u.slice(1)]={value:t.frames[0].variables()[u].value,toJS:function(){return this.value.eval(t).toCSS()}};try{n=s.call(i)}catch(o){throw{message:"JavaScript evaluation error: '"+o.name+": "+o.message+"'",index:this.index}}return typeof n=="string"?new e.Quoted('"'+n+'"',n,this.escaped,this.index):Array.isArray(n)?new e.Anonymous(n.join(", ")):new e.Anonymous(n)}}}(n("../tree")),function(e){e.Keyword=function(e){this.value=e},e.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value},compare:function(t){return t instanceof e.Keyword?t.value===this.value?0:1:-1}},e.True=new e.Keyword("true"),e.False=new e.Keyword("false")}(n("../tree")),function(e){e.Media=function(t,n){var r=this.emptySelectors();this.features=new e.Value(n),this.ruleset=new e.Ruleset(r,t),this.ruleset.allowImports=!0},e.Media.prototype={toCSS:function(e,t){var n=this.features.toCSS(t);return this.ruleset.root=e.length===0||e[0].multiMedia,"@media "+n+(t.compress?"{":" {\n ")+this.ruleset.toCSS(e,t).trim().replace(/\n/g,"\n ")+(t.compress?"}":"\n}\n")},eval:function(t){t.mediaBlocks||(t.mediaBlocks=[],t.mediaPath=[]);var n=new e.Media([],[]);return this.debugInfo&&(this.ruleset.debugInfo=this.debugInfo,n.debugInfo=this.debugInfo),n.features=this.features.eval(t),t.mediaPath.push(n),t.mediaBlocks.push(n),t.frames.unshift(this.ruleset),n.ruleset=this.ruleset.eval(t),t.frames.shift(),t.mediaPath.pop(),t.mediaPath.length===0?n.evalTop(t):n.evalNested(t)},variable:function(t){return e.Ruleset.prototype.variable.call(this.ruleset,t)},find:function(){return e.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return e.Ruleset.prototype.rulesets.apply(this.ruleset)},emptySelectors:function(){var t=new e.Element("","&",0);return[new e.Selector([t])]},evalTop:function(t){var n=this;if(t.mediaBlocks.length>1){var r=this.emptySelectors();n=new e.Ruleset(r,t.mediaBlocks),n.multiMedia=!0}return delete t.mediaBlocks,delete t.mediaPath,n},evalNested:function(t){var n,r,i=t.mediaPath.concat([this]);for(n=0;n0;n--)t.splice(n,0,new e.Anonymous("and"));return new e.Expression(t)})),new e.Ruleset([],[])},permute:function(e){if(e.length===0)return[];if(e.length===1)return e[0];var t=[],n=this.permute(e.slice(1));for(var r=0;r0){c=!0;for(a=0;athis.params.length)return!1;if(this.required>0&&n>this.params.length)return!1}r=Math.min(n,this.arity);for(var s=0;si.selectors[o].elements.length?Array.prototype.push.apply(r,i.find(new e.Selector(t.elements.slice(1)),n)):r.push(i);break}}),this._lookups[o]=r)},toCSS:function(t,n){var r=[],i=[],s=[],o=[],u=[],a,f,l;this.root||this.joinSelectors(u,t,this.selectors);for(var c=0;c0){f=e.debugInfo(n,this),a=u.map(function(e){return e.map(function(e){return e.toCSS(n)}).join("").trim()}).join(n.compress?",":",\n");for(var c=i.length-1;c>=0;c--)s.indexOf(i[c])===-1&&s.unshift(i[c]);i=s,r.push(f+a+(n.compress?"{":" {\n ")+i.join(n.compress?"":"\n ")+(n.compress?"}":"\n}\n"))}return r.push(o),r.join("")+(n.compress?"\n":"")},joinSelectors:function(e,t,n){for(var r=0;r0)for(i=0;i0&&this.mergeElementsOnToSelectors(g,a);for(s=0;s0&&(l[0].elements=l[0].elements.slice(0),l[0].elements.push(new e.Element(f.combinator,"",0))),y.push(l);else for(o=0;o0?(h=l.slice(0),m=h.pop(),d=new e.Selector(m.elements.slice(0)),v=!1):d=new e.Selector([]),c.length>1&&(p=p.concat(c.slice(1))),c.length>0&&(v=!1,d.elements.push(new e.Element(f.combinator,c[0].elements[0].value,0)),d.elements=d.elements.concat(c[0].elements.slice(1))),v||h.push(d),h=h.concat(p),y.push(h)}a=y,g=[]}}g.length>0&&this.mergeElementsOnToSelectors(g,a);for(i=0;i0?i[i.length-1]=new e.Selector(i[i.length-1].elements.concat(t)):i.push(new e.Selector(t))}}}(n("../tree")),function(e){e.Selector=function(e){this.elements=e},e.Selector.prototype.match=function(e){var t=this.elements,n=t.length,r,i,s,o;r=e.elements.slice(e.elements.length&&e.elements[0].value==="&"?1:0),i=r.length,s=Math.min(n,i);if(i===0||n1?"["+e.value.map(function(e){return e.toCSS(!1)}).join(", ")+"]":e.toCSS(!1)}}(n("./tree"));var o=/^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);r.env=r.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||o?"development":"production"),r.async=r.async||!1,r.fileAsync=r.fileAsync||!1,r.poll=r.poll||(o?1e3:1500);if(r.functions)for(var u in r.functions)r.tree.functions[u]=r.functions[u];var a=/!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);a&&(r.dumpLineNumbers=a[1]),r.watch=function(){return r.watchMode||(r.env="development",f()),this.watchMode=!0},r.unwatch=function(){return clearInterval(r.watchTimer),this.watchMode=!1},/!watch/.test(location.hash)&&r.watch();var l=null;if(r.env!="development")try{l=typeof e.localStorage=="undefined"?null:e.localStorage}catch(c){}var h=document.getElementsByTagName("link"),p=/^text\/(x-)?less$/;r.sheets=[];for(var d=0;d= scrollHeight - offsetBottom) ? 'bottom' :\n offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false\n\n if (this.affixed === affix) return\n if (this.unpin) this.$element.css('top', '')\n\n this.affixed = affix\n this.unpin = affix == 'bottom' ? position.top - scrollTop : null\n\n this.$element.removeClass(Affix.RESET).addClass('affix' + (affix ? '-' + affix : ''))\n\n if (affix == 'bottom') {\n this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })\n }\n }\n\n\n // AFFIX PLUGIN DEFINITION\n // =======================\n\n var old = $.fn.affix\n\n $.fn.affix = function (option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.affix')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n $.fn.affix.Constructor = Affix\n\n\n // AFFIX NO CONFLICT\n // =================\n\n $.fn.affix.noConflict = function () {\n $.fn.affix = old\n return this\n }\n\n\n // AFFIX DATA-API\n // ==============\n\n $(window).on('load', function () {\n $('[data-spy=\"affix\"]').each(function () {\n var $spy = $(this)\n var data = $spy.data()\n\n data.offset = data.offset || {}\n\n if (data.offsetBottom) data.offset.bottom = data.offsetBottom\n if (data.offsetTop) data.offset.top = data.offsetTop\n\n $spy.affix(data)\n })\n })\n\n}(window.jQuery);\n","alert.js":"/* ========================================================================\n * Bootstrap: alert.js v3.0.0\n * http://twbs.github.com/bootstrap/javascript.html#alerts\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n // ALERT CLASS DEFINITION\n // ======================\n\n var dismiss = '[data-dismiss=\"alert\"]'\n var Alert = function (el) {\n $(el).on('click', dismiss, this.close)\n }\n\n Alert.prototype.close = function (e) {\n var $this = $(this)\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n var $parent = $(selector)\n\n if (e) e.preventDefault()\n\n if (!$parent.length) {\n $parent = $this.hasClass('alert') ? $this : $this.parent()\n }\n\n $parent.trigger(e = $.Event('close.bs.alert'))\n\n if (e.isDefaultPrevented()) return\n\n $parent.removeClass('in')\n\n function removeElement() {\n $parent.trigger('closed.bs.alert').remove()\n }\n\n $.support.transition && $parent.hasClass('fade') ?\n $parent\n .one($.support.transition.end, removeElement)\n .emulateTransitionEnd(150) :\n removeElement()\n }\n\n\n // ALERT PLUGIN DEFINITION\n // =======================\n\n var old = $.fn.alert\n\n $.fn.alert = function (option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.alert')\n\n if (!data) $this.data('bs.alert', (data = new Alert(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n $.fn.alert.Constructor = Alert\n\n\n // ALERT NO CONFLICT\n // =================\n\n $.fn.alert.noConflict = function () {\n $.fn.alert = old\n return this\n }\n\n\n // ALERT DATA-API\n // ==============\n\n $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(window.jQuery);\n","button.js":"/* ========================================================================\n * Bootstrap: button.js v3.0.0\n * http://twbs.github.com/bootstrap/javascript.html#buttons\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n // BUTTON PUBLIC CLASS DEFINITION\n // ==============================\n\n var Button = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Button.DEFAULTS, options)\n }\n\n Button.DEFAULTS = {\n loadingText: 'loading...'\n }\n\n Button.prototype.setState = function (state) {\n var d = 'disabled'\n var $el = this.$element\n var val = $el.is('input') ? 'val' : 'html'\n var data = $el.data()\n\n state = state + 'Text'\n\n if (!data.resetText) $el.data('resetText', $el[val]())\n\n $el[val](data[state] || this.options[state])\n\n // push to event loop to allow forms to submit\n setTimeout(function () {\n state == 'loadingText' ?\n $el.addClass(d).attr(d, d) :\n $el.removeClass(d).removeAttr(d);\n }, 0)\n }\n\n Button.prototype.toggle = function () {\n var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n if ($parent.length) {\n var $input = this.$element.find('input')\n .prop('checked', !this.$element.hasClass('active'))\n .trigger('change')\n if ($input.prop('type') === 'radio') $parent.find('.active').removeClass('active')\n }\n\n this.$element.toggleClass('active')\n }\n\n\n // BUTTON PLUGIN DEFINITION\n // ========================\n\n var old = $.fn.button\n\n $.fn.button = function (option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.button')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n if (option == 'toggle') data.toggle()\n else if (option) data.setState(option)\n })\n }\n\n $.fn.button.Constructor = Button\n\n\n // BUTTON NO CONFLICT\n // ==================\n\n $.fn.button.noConflict = function () {\n $.fn.button = old\n return this\n }\n\n\n // BUTTON DATA-API\n // ===============\n\n $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {\n var $btn = $(e.target)\n if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n $btn.button('toggle')\n e.preventDefault()\n })\n\n}(window.jQuery);\n","carousel.js":"/* ========================================================================\n * Bootstrap: carousel.js v3.0.0\n * http://twbs.github.com/bootstrap/javascript.html#carousel\n * ========================================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n // CAROUSEL CLASS DEFINITION\n // =========================\n\n var Carousel = function (element, options) {\n this.$element = $(element)\n this.$indicators = this.$element.find('.carousel-indicators')\n this.options = options\n this.paused =\n this.sliding =\n this.interval =\n this.$active =\n this.$items = null\n\n this.options.pause == 'hover' && this.$element\n .on('mouseenter', $.proxy(this.pause, this))\n .on('mouseleave', $.proxy(this.cycle, this))\n }\n\n Carousel.DEFAULTS = {\n interval: 5000\n , pause: 'hover'\n , wrap: true\n }\n\n Carousel.prototype.cycle = function (e) {\n e || (this.paused = false)\n\n this.interval && clearInterval(this.interval)\n\n this.options.interval\n && !this.paused\n && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n return this\n }\n\n Carousel.prototype.getActiveIndex = function () {\n this.$active = this.$element.find('.item.active')\n this.$items = this.$active.parent().children()\n\n return this.$items.index(this.$active)\n }\n\n Carousel.prototype.to = function (pos) {\n var that = this\n var activeIndex = this.getActiveIndex()\n\n if (pos > (this.$items.length - 1) || pos < 0) return\n\n if (this.sliding) return this.$element.one('slid', function () { that.to(pos) })\n if (activeIndex == pos) return this.pause().cycle()\n\n return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))\n }\n\n Carousel.prototype.pause = function (e) {\n e || (this.paused = true)\n\n if (this.$element.find('.next, .prev').length && $.support.transition.end) {\n this.$element.trigger($.support.transition.end)\n this.cycle(true)\n }\n\n this.interval = clearInterval(this.interval)\n\n return this\n }\n\n Carousel.prototype.next = function () {\n if (this.sliding) return\n return this.slide('next')\n }\n\n Carousel.prototype.prev = function () {\n if (this.sliding) return\n return this.slide('prev')\n }\n\n Carousel.prototype.slide = function (type, next) {\n var $active = this.$element.find('.item.active')\n var $next = next || $active[type]()\n var isCycling = this.interval\n var direction = type == 'next' ? 'left' : 'right'\n var fallback = type == 'next' ? 'first' : 'last'\n var that = this\n\n if (!$next.length) {\n if (!this.options.wrap) return\n $next = this.$element.find('.item')[fallback]()\n }\n\n this.sliding = true\n\n isCycling && this.pause()\n\n var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction })\n\n if ($next.hasClass('active')) return\n\n if (this.$indicators.length) {\n this.$indicators.find('.active').removeClass('active')\n this.$element.one('slid', function () {\n var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])\n $nextIndicator && $nextIndicator.addClass('active')\n })\n }\n\n if ($.support.transition && this.$element.hasClass('slide')) {\n this.$element.trigger(e)\n if (e.isDefaultPrevented()) return\n $next.addClass(type)\n $next[0].offsetWidth // force reflow\n $active.addClass(direction)\n $next.addClass(direction)\n $active\n .one($.support.transition.end, function () {\n $next.removeClass([type, direction].join(' ')).addClass('active')\n $active.removeClass(['active', direction].join(' '))\n that.sliding = false\n setTimeout(function () { that.$element.trigger('slid') }, 0)\n })\n .emulateTransitionEnd(600)\n } else {\n this.$element.trigger(e)\n if (e.isDefaultPrevented()) return\n $active.removeClass('active')\n $next.addClass('active')\n this.sliding = false\n this.$element.trigger('slid')\n }\n\n isCycling && this.cycle()\n\n return this\n }\n\n\n // CAROUSEL PLUGIN DEFINITION\n // ==========================\n\n var old = $.fn.carousel\n\n $.fn.carousel = function (option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.carousel')\n var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n var action = typeof option == 'string' ? option : options.slide\n\n if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n if (typeof option == 'number') data.to(option)\n else if (action) data[action]()\n else if (options.interval) data.pause().cycle()\n })\n }\n\n $.fn.carousel.Constructor = Carousel\n\n\n // CAROUSEL NO CONFLICT\n // ====================\n\n $.fn.carousel.noConflict = function () {\n $.fn.carousel = old\n return this\n }\n\n\n // CAROUSEL DATA-API\n // =================\n\n $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {\n var $this = $(this), href\n var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) //strip for ie7\n var options = $.extend({}, $target.data(), $this.data())\n var slideIndex = $this.attr('data-slide-to')\n if (slideIndex) options.interval = false\n\n $target.carousel(options)\n\n if (slideIndex = $this.attr('data-slide-to')) {\n $target.data('bs.carousel').to(slideIndex)\n }\n\n e.preventDefault()\n })\n\n $(window).on('load', function () {\n $('[data-ride=\"carousel\"]').each(function () {\n var $carousel = $(this)\n $carousel.carousel($carousel.data())\n })\n })\n\n}(window.jQuery);\n","collapse.js":"/* ========================================================================\n * Bootstrap: collapse.js v3.0.0\n * http://twbs.github.com/bootstrap/javascript.html#collapse\n * ========================================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n // COLLAPSE PUBLIC CLASS DEFINITION\n // ================================\n\n var Collapse = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Collapse.DEFAULTS, options)\n this.transitioning = null\n\n if (this.options.parent) this.$parent = $(this.options.parent)\n if (this.options.toggle) this.toggle()\n }\n\n Collapse.DEFAULTS = {\n toggle: true\n }\n\n Collapse.prototype.dimension = function () {\n var hasWidth = this.$element.hasClass('width')\n return hasWidth ? 'width' : 'height'\n }\n\n Collapse.prototype.show = function () {\n if (this.transitioning || this.$element.hasClass('in')) return\n\n var startEvent = $.Event('show.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n var actives = this.$parent && this.$parent.find('> .panel > .in')\n\n if (actives && actives.length) {\n var hasData = actives.data('bs.collapse')\n if (hasData && hasData.transitioning) return\n actives.collapse('hide')\n hasData || actives.data('bs.collapse', null)\n }\n\n var dimension = this.dimension()\n\n this.$element\n .removeClass('collapse')\n .addClass('collapsing')\n [dimension](0)\n\n this.transitioning = 1\n\n var complete = function () {\n this.$element\n .removeClass('collapsing')\n .addClass('in')\n [dimension]('auto')\n this.transitioning = 0\n this.$element.trigger('shown.bs.collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n this.$element\n .one($.support.transition.end, $.proxy(complete, this))\n .emulateTransitionEnd(350)\n [dimension](this.$element[0][scrollSize])\n }\n\n Collapse.prototype.hide = function () {\n if (this.transitioning || !this.$element.hasClass('in')) return\n\n var startEvent = $.Event('hide.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n var dimension = this.dimension()\n\n this.$element\n [dimension](this.$element[dimension]())\n [0].offsetHeight\n\n this.$element\n .addClass('collapsing')\n .removeClass('collapse')\n .removeClass('in')\n\n this.transitioning = 1\n\n var complete = function () {\n this.transitioning = 0\n this.$element\n .trigger('hidden.bs.collapse')\n .removeClass('collapsing')\n .addClass('collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n this.$element\n [dimension](0)\n .one($.support.transition.end, $.proxy(complete, this))\n .emulateTransitionEnd(350)\n }\n\n Collapse.prototype.toggle = function () {\n this[this.$element.hasClass('in') ? 'hide' : 'show']()\n }\n\n\n // COLLAPSE PLUGIN DEFINITION\n // ==========================\n\n var old = $.fn.collapse\n\n $.fn.collapse = function (option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.collapse')\n var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n $.fn.collapse.Constructor = Collapse\n\n\n // COLLAPSE NO CONFLICT\n // ====================\n\n $.fn.collapse.noConflict = function () {\n $.fn.collapse = old\n return this\n }\n\n\n // COLLAPSE DATA-API\n // =================\n\n $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {\n var $this = $(this), href\n var target = $this.attr('data-target')\n || e.preventDefault()\n || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') //strip for ie7\n var $target = $(target)\n var data = $target.data('bs.collapse')\n var option = data ? 'toggle' : $this.data()\n var parent = $this.attr('data-parent')\n var $parent = parent && $(parent)\n\n if (!data || !data.transitioning) {\n if ($parent) $parent.find('[data-toggle=collapse][data-parent=\"' + parent + '\"]').not($this).addClass('collapsed')\n $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')\n }\n\n $target.collapse(option)\n })\n\n}(window.jQuery);\n","dropdown.js":"/* ========================================================================\n * Bootstrap: dropdown.js v3.0.0\n * http://twbs.github.com/bootstrap/javascript.html#dropdowns\n * ========================================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n // DROPDOWN CLASS DEFINITION\n // =========================\n\n var backdrop = '.dropdown-backdrop'\n var toggle = '[data-toggle=dropdown]'\n var Dropdown = function (element) {\n var $el = $(element).on('click.bs.dropdown', this.toggle)\n }\n\n Dropdown.prototype.toggle = function (e) {\n var $this = $(this)\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n clearMenus()\n\n if (!isActive) {\n if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n // if mobile we we use a backdrop because click events don't delegate\n $('
').insertAfter($(this)).on('click', clearMenus)\n }\n\n $parent.trigger(e = $.Event('show.bs.dropdown'))\n\n if (e.isDefaultPrevented()) return\n\n $parent\n .toggleClass('open')\n .trigger('shown.bs.dropdown')\n\n $this.focus()\n }\n\n return false\n }\n\n Dropdown.prototype.keydown = function (e) {\n if (!/(38|40|27)/.test(e.keyCode)) return\n\n var $this = $(this)\n\n e.preventDefault()\n e.stopPropagation()\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n if (!isActive || (isActive && e.keyCode == 27)) {\n if (e.which == 27) $parent.find(toggle).focus()\n return $this.click()\n }\n\n var $items = $('[role=menu] li:not(.divider):visible a', $parent)\n\n if (!$items.length) return\n\n var index = $items.index($items.filter(':focus'))\n\n if (e.keyCode == 38 && index > 0) index-- // up\n if (e.keyCode == 40 && index < $items.length - 1) index++ // down\n if (!~index) index=0\n\n $items.eq(index).focus()\n }\n\n function clearMenus() {\n $(backdrop).remove()\n $(toggle).each(function (e) {\n var $parent = getParent($(this))\n if (!$parent.hasClass('open')) return\n $parent.trigger(e = $.Event('hide.bs.dropdown'))\n if (e.isDefaultPrevented()) return\n $parent.removeClass('open').trigger('hidden.bs.dropdown')\n })\n }\n\n function getParent($this) {\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n }\n\n var $parent = selector && $(selector)\n\n return $parent && $parent.length ? $parent : $this.parent()\n }\n\n\n // DROPDOWN PLUGIN DEFINITION\n // ==========================\n\n var old = $.fn.dropdown\n\n $.fn.dropdown = function (option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('dropdown')\n\n if (!data) $this.data('dropdown', (data = new Dropdown(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n $.fn.dropdown.Constructor = Dropdown\n\n\n // DROPDOWN NO CONFLICT\n // ====================\n\n $.fn.dropdown.noConflict = function () {\n $.fn.dropdown = old\n return this\n }\n\n\n // APPLY TO STANDARD DROPDOWN ELEMENTS\n // ===================================\n\n $(document)\n .on('click.bs.dropdown.data-api', clearMenus)\n .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n .on('click.bs.dropdown.data-api' , toggle, Dropdown.prototype.toggle)\n .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)\n\n}(window.jQuery);\n","modal.js":"/* ========================================================================\n * Bootstrap: modal.js v3.0.0\n * http://twbs.github.com/bootstrap/javascript.html#modals\n * ========================================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n // MODAL CLASS DEFINITION\n // ======================\n\n var Modal = function (element, options) {\n this.options = options\n this.$element = $(element)\n this.$backdrop =\n this.isShown = null\n\n if (this.options.remote) this.$element.load(this.options.remote)\n }\n\n Modal.DEFAULTS = {\n backdrop: true\n , keyboard: true\n , show: true\n }\n\n Modal.prototype.toggle = function (_relatedTarget) {\n return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)\n }\n\n Modal.prototype.show = function (_relatedTarget) {\n var that = this\n var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n this.$element.trigger(e)\n\n if (this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = true\n\n this.escape()\n\n this.$element.on('click.dismiss.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n this.backdrop(function () {\n var transition = $.support.transition && that.$element.hasClass('fade')\n\n if (!that.$element.parent().length) {\n that.$element.appendTo(document.body) // don't move modals dom position\n }\n\n that.$element.show()\n\n if (transition) {\n that.$element[0].offsetWidth // force reflow\n }\n\n that.$element\n .addClass('in')\n .attr('aria-hidden', false)\n\n that.enforceFocus()\n\n var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n transition ?\n that.$element.find('.modal-dialog') // wait for modal to slide in\n .one($.support.transition.end, function () {\n that.$element.focus().trigger(e)\n })\n .emulateTransitionEnd(300) :\n that.$element.focus().trigger(e)\n })\n }\n\n Modal.prototype.hide = function (e) {\n if (e) e.preventDefault()\n\n e = $.Event('hide.bs.modal')\n\n this.$element.trigger(e)\n\n if (!this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = false\n\n this.escape()\n\n $(document).off('focusin.bs.modal')\n\n this.$element\n .removeClass('in')\n .attr('aria-hidden', true)\n .off('click.dismiss.modal')\n\n $.support.transition && this.$element.hasClass('fade') ?\n this.$element\n .one($.support.transition.end, $.proxy(this.hideModal, this))\n .emulateTransitionEnd(300) :\n this.hideModal()\n }\n\n Modal.prototype.enforceFocus = function () {\n $(document)\n .off('focusin.bs.modal') // guard against infinite focus loop\n .on('focusin.bs.modal', $.proxy(function (e) {\n if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {\n this.$element.focus()\n }\n }, this))\n }\n\n Modal.prototype.escape = function () {\n if (this.isShown && this.options.keyboard) {\n this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {\n e.which == 27 && this.hide()\n }, this))\n } else if (!this.isShown) {\n this.$element.off('keyup.dismiss.bs.modal')\n }\n }\n\n Modal.prototype.hideModal = function () {\n var that = this\n this.$element.hide()\n this.backdrop(function () {\n that.removeBackdrop()\n that.$element.trigger('hidden.bs.modal')\n })\n }\n\n Modal.prototype.removeBackdrop = function () {\n this.$backdrop && this.$backdrop.remove()\n this.$backdrop = null\n }\n\n Modal.prototype.backdrop = function (callback) {\n var that = this\n var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n if (this.isShown && this.options.backdrop) {\n var doAnimate = $.support.transition && animate\n\n this.$backdrop = $('')\n .appendTo(document.body)\n\n this.$element.on('click.dismiss.modal', $.proxy(function (e) {\n if (e.target !== e.currentTarget) return\n this.options.backdrop == 'static'\n ? this.$element[0].focus.call(this.$element[0])\n : this.hide.call(this)\n }, this))\n\n if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n this.$backdrop.addClass('in')\n\n if (!callback) return\n\n doAnimate ?\n this.$backdrop\n .one($.support.transition.end, callback)\n .emulateTransitionEnd(150) :\n callback()\n\n } else if (!this.isShown && this.$backdrop) {\n this.$backdrop.removeClass('in')\n\n $.support.transition && this.$element.hasClass('fade')?\n this.$backdrop\n .one($.support.transition.end, callback)\n .emulateTransitionEnd(150) :\n callback()\n\n } else if (callback) {\n callback()\n }\n }\n\n\n // MODAL PLUGIN DEFINITION\n // =======================\n\n var old = $.fn.modal\n\n $.fn.modal = function (option, _relatedTarget) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.modal')\n var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n if (typeof option == 'string') data[option](_relatedTarget)\n else if (options.show) data.show(_relatedTarget)\n })\n }\n\n $.fn.modal.Constructor = Modal\n\n\n // MODAL NO CONFLICT\n // =================\n\n $.fn.modal.noConflict = function () {\n $.fn.modal = old\n return this\n }\n\n\n // MODAL DATA-API\n // ==============\n\n $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n var $this = $(this)\n var href = $this.attr('href')\n var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) //strip for ie7\n var option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n e.preventDefault()\n\n $target\n .modal(option, this)\n .one('hide', function () {\n $this.is(':visible') && $this.focus()\n })\n })\n\n $(document)\n .on('show.bs.modal', '.modal', function () { $(document.body).addClass('modal-open') })\n .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })\n\n}(window.jQuery);\n","popover.js":"/* ========================================================================\n * Bootstrap: popover.js v3.0.0\n * http://twbs.github.com/bootstrap/javascript.html#popovers\n * ========================================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n // POPOVER PUBLIC CLASS DEFINITION\n // ===============================\n\n var Popover = function (element, options) {\n this.init('popover', element, options)\n }\n\n if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n Popover.DEFAULTS = $.extend({} , $.fn.tooltip.Constructor.DEFAULTS, {\n placement: 'right'\n , trigger: 'click'\n , content: ''\n , template: '
'\n })\n\n\n // NOTE: POPOVER EXTENDS tooltip.js\n // ================================\n\n Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n Popover.prototype.constructor = Popover\n\n Popover.prototype.getDefaults = function () {\n return Popover.DEFAULTS\n }\n\n Popover.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n var content = this.getContent()\n\n $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)\n\n $tip.removeClass('fade top bottom left right in')\n\n // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n // this manually by checking the contents.\n if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n }\n\n Popover.prototype.hasContent = function () {\n return this.getTitle() || this.getContent()\n }\n\n Popover.prototype.getContent = function () {\n var $e = this.$element\n var o = this.options\n\n return $e.attr('data-content')\n || (typeof o.content == 'function' ?\n o.content.call($e[0]) :\n o.content)\n }\n\n Popover.prototype.arrow = function () {\n return this.$arrow = this.$arrow || this.tip().find('.arrow')\n }\n\n Popover.prototype.tip = function () {\n if (!this.$tip) this.$tip = $(this.options.template)\n return this.$tip\n }\n\n\n // POPOVER PLUGIN DEFINITION\n // =========================\n\n var old = $.fn.popover\n\n $.fn.popover = function (option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.popover')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n $.fn.popover.Constructor = Popover\n\n\n // POPOVER NO CONFLICT\n // ===================\n\n $.fn.popover.noConflict = function () {\n $.fn.popover = old\n return this\n }\n\n}(window.jQuery);\n","scrollspy.js":"/* ========================================================================\n * Bootstrap: scrollspy.js v3.0.0\n * http://twbs.github.com/bootstrap/javascript.html#scrollspy\n * ========================================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n // SCROLLSPY CLASS DEFINITION\n // ==========================\n\n function ScrollSpy(element, options) {\n var href\n var process = $.proxy(this.process, this)\n\n this.$element = $(element).is('body') ? $(window) : $(element)\n this.$body = $('body')\n this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)\n this.options = $.extend({}, ScrollSpy.DEFAULTS, options)\n this.selector = (this.options.target\n || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) //strip for ie7\n || '') + ' .nav li > a'\n this.offsets = $([])\n this.targets = $([])\n this.activeTarget = null\n\n this.refresh()\n this.process()\n }\n\n ScrollSpy.DEFAULTS = {\n offset: 10\n }\n\n ScrollSpy.prototype.refresh = function () {\n var offsetMethod = this.$element[0] == window ? 'offset' : 'position'\n\n this.offsets = $([])\n this.targets = $([])\n\n var self = this\n var $targets = this.$body\n .find(this.selector)\n .map(function () {\n var $el = $(this)\n var href = $el.data('target') || $el.attr('href')\n var $href = /^#\\w/.test(href) && $(href)\n\n return ($href\n && $href.length\n && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null\n })\n .sort(function (a, b) { return a[0] - b[0] })\n .each(function () {\n self.offsets.push(this[0])\n self.targets.push(this[1])\n })\n }\n\n ScrollSpy.prototype.process = function () {\n var scrollTop = this.$scrollElement.scrollTop() + this.options.offset\n var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight\n var maxScroll = scrollHeight - this.$scrollElement.height()\n var offsets = this.offsets\n var targets = this.targets\n var activeTarget = this.activeTarget\n var i\n\n if (scrollTop >= maxScroll) {\n return activeTarget != (i = targets.last()[0]) && this.activate(i)\n }\n\n for (i = offsets.length; i--;) {\n activeTarget != targets[i]\n && scrollTop >= offsets[i]\n && (!offsets[i + 1] || scrollTop <= offsets[i + 1])\n && this.activate( targets[i] )\n }\n }\n\n ScrollSpy.prototype.activate = function (target) {\n this.activeTarget = target\n\n $(this.selector)\n .parents('.active')\n .removeClass('active')\n\n var selector = this.selector\n + '[data-target=\"' + target + '\"],'\n + this.selector + '[href=\"' + target + '\"]'\n\n var active = $(selector)\n .parents('li')\n .addClass('active')\n\n if (active.parent('.dropdown-menu').length) {\n active = active\n .closest('li.dropdown')\n .addClass('active')\n }\n\n active.trigger('activate')\n }\n\n\n // SCROLLSPY PLUGIN DEFINITION\n // ===========================\n\n var old = $.fn.scrollspy\n\n $.fn.scrollspy = function (option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.scrollspy')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n $.fn.scrollspy.Constructor = ScrollSpy\n\n\n // SCROLLSPY NO CONFLICT\n // =====================\n\n $.fn.scrollspy.noConflict = function () {\n $.fn.scrollspy = old\n return this\n }\n\n\n // SCROLLSPY DATA-API\n // ==================\n\n $(window).on('load', function () {\n $('[data-spy=\"scroll\"]').each(function () {\n var $spy = $(this)\n $spy.scrollspy($spy.data())\n })\n })\n\n}(window.jQuery);\n","tab.js":"/* ========================================================================\n * Bootstrap: tab.js v3.0.0\n * http://twbs.github.com/bootstrap/javascript.html#tabs\n * ========================================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n // TAB CLASS DEFINITION\n // ====================\n\n var Tab = function (element) {\n this.element = $(element)\n }\n\n Tab.prototype.show = function () {\n var $this = this.element\n var $ul = $this.closest('ul:not(.dropdown-menu)')\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n }\n\n if ($this.parent('li').hasClass('active')) return\n\n var previous = $ul.find('.active:last a')[0]\n var e = $.Event('show.bs.tab', {\n relatedTarget: previous\n })\n\n $this.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n var $target = $(selector)\n\n this.activate($this.parent('li'), $ul)\n this.activate($target, $target.parent(), function () {\n $this.trigger({\n type: 'shown.bs.tab'\n , relatedTarget: previous\n })\n })\n }\n\n Tab.prototype.activate = function (element, container, callback) {\n var $active = container.find('> .active')\n var transition = callback\n && $.support.transition\n && $active.hasClass('fade')\n\n function next() {\n $active\n .removeClass('active')\n .find('> .dropdown-menu > .active')\n .removeClass('active')\n\n element.addClass('active')\n\n if (transition) {\n element[0].offsetWidth // reflow for transition\n element.addClass('in')\n } else {\n element.removeClass('fade')\n }\n\n if (element.parent('.dropdown-menu')) {\n element.closest('li.dropdown').addClass('active')\n }\n\n callback && callback()\n }\n\n transition ?\n $active\n .one($.support.transition.end, next)\n .emulateTransitionEnd(150) :\n next()\n\n $active.removeClass('in')\n }\n\n\n // TAB PLUGIN DEFINITION\n // =====================\n\n var old = $.fn.tab\n\n $.fn.tab = function ( option ) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tab')\n\n if (!data) $this.data('bs.tab', (data = new Tab(this)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n $.fn.tab.Constructor = Tab\n\n\n // TAB NO CONFLICT\n // ===============\n\n $.fn.tab.noConflict = function () {\n $.fn.tab = old\n return this\n }\n\n\n // TAB DATA-API\n // ============\n\n $(document).on('click.bs.tab.data-api', '[data-toggle=\"tab\"], [data-toggle=\"pill\"]', function (e) {\n e.preventDefault()\n $(this).tab('show')\n })\n\n}(window.jQuery);\n","tooltip.js":"/* ========================================================================\n * Bootstrap: tooltip.js v3.0.0\n * http://twbs.github.com/bootstrap/javascript.html#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n // TOOLTIP PUBLIC CLASS DEFINITION\n // ===============================\n\n var Tooltip = function (element, options) {\n this.type =\n this.options =\n this.enabled =\n this.timeout =\n this.hoverState =\n this.$element = null\n\n this.init('tooltip', element, options)\n }\n\n Tooltip.DEFAULTS = {\n animation: true\n , placement: 'top'\n , selector: false\n , template: '
'\n , trigger: 'hover focus'\n , title: ''\n , delay: 0\n , html: false\n , container: false\n }\n\n Tooltip.prototype.init = function (type, element, options) {\n this.enabled = true\n this.type = type\n this.$element = $(element)\n this.options = this.getOptions(options)\n\n var triggers = this.options.trigger.split(' ')\n\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i]\n\n if (trigger == 'click') {\n this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n } else if (trigger != 'manual') {\n var eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'\n var eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'\n\n this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n }\n }\n\n this.options.selector ?\n (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n this.fixTitle()\n }\n\n Tooltip.prototype.getDefaults = function () {\n return Tooltip.DEFAULTS\n }\n\n Tooltip.prototype.getOptions = function (options) {\n options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n if (options.delay && typeof options.delay == 'number') {\n options.delay = {\n show: options.delay\n , hide: options.delay\n }\n }\n\n return options\n }\n\n Tooltip.prototype.getDelegateOptions = function () {\n var options = {}\n var defaults = this.getDefaults()\n\n this._options && $.each(this._options, function (key, value) {\n if (defaults[key] != value) options[key] = value\n })\n\n return options\n }\n\n Tooltip.prototype.enter = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'in'\n\n if (!self.options.delay || !self.options.delay.show) return self.show()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'in') self.show()\n }, self.options.delay.show)\n }\n\n Tooltip.prototype.leave = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'out'\n\n if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'out') self.hide()\n }, self.options.delay.hide)\n }\n\n Tooltip.prototype.show = function () {\n var e = $.Event('show.bs.'+ this.type)\n\n if (this.hasContent() && this.enabled) {\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n var $tip = this.tip()\n\n this.setContent()\n\n if (this.options.animation) $tip.addClass('fade')\n\n var placement = typeof this.options.placement == 'function' ?\n this.options.placement.call(this, $tip[0], this.$element[0]) :\n this.options.placement\n\n var autoToken = /\\s?auto?\\s?/i\n var autoPlace = autoToken.test(placement)\n if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n $tip\n .detach()\n .css({ top: 0, left: 0, display: 'block' })\n .addClass(placement)\n\n this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n\n var pos = this.getPosition()\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (autoPlace) {\n var $parent = this.$element.parent()\n\n var orgPlacement = placement\n var docScroll = document.documentElement.scrollTop || document.body.scrollTop\n var parentWidth = this.options.container == 'body' ? window.innerWidth : $parent.outerWidth()\n var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()\n var parentLeft = this.options.container == 'body' ? 0 : $parent.offset().left\n\n placement = placement == 'bottom' && pos.top + pos.height + actualHeight - docScroll > parentHeight ? 'top' :\n placement == 'top' && pos.top - docScroll - actualHeight < 0 ? 'bottom' :\n placement == 'right' && pos.right + actualWidth > parentWidth ? 'left' :\n placement == 'left' && pos.left - actualWidth < parentLeft ? 'right' :\n placement\n\n $tip\n .removeClass(orgPlacement)\n .addClass(placement)\n }\n\n var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n this.applyPlacement(calculatedOffset, placement)\n this.$element.trigger('shown.bs.' + this.type)\n }\n }\n\n Tooltip.prototype.applyPlacement = function(offset, placement) {\n var replace\n var $tip = this.tip()\n var width = $tip[0].offsetWidth\n var height = $tip[0].offsetHeight\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt($tip.css('margin-top'), 10)\n var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0\n if (isNaN(marginLeft)) marginLeft = 0\n\n offset.top = offset.top + marginTop\n offset.left = offset.left + marginLeft\n\n $tip\n .offset(offset)\n .addClass('in')\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (placement == 'top' && actualHeight != height) {\n replace = true\n offset.top = offset.top + height - actualHeight\n }\n\n if (/bottom|top/.test(placement)) {\n var delta = 0\n\n if (offset.left < 0) {\n delta = offset.left * -2\n offset.left = 0\n\n $tip.offset(offset)\n\n actualWidth = $tip[0].offsetWidth\n actualHeight = $tip[0].offsetHeight\n }\n\n this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')\n } else {\n this.replaceArrow(actualHeight - height, actualHeight, 'top')\n }\n\n if (replace) $tip.offset(offset)\n }\n\n Tooltip.prototype.replaceArrow = function(delta, dimension, position) {\n this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + \"%\") : '')\n }\n\n Tooltip.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n\n $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n $tip.removeClass('fade in top bottom left right')\n }\n\n Tooltip.prototype.hide = function () {\n var that = this\n var $tip = this.tip()\n var e = $.Event('hide.bs.' + this.type)\n\n function complete() {\n if (that.hoverState != 'in') $tip.detach()\n }\n\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n $tip.removeClass('in')\n\n $.support.transition && this.$tip.hasClass('fade') ?\n $tip\n .one($.support.transition.end, complete)\n .emulateTransitionEnd(150) :\n complete()\n\n this.$element.trigger('hidden.bs.' + this.type)\n\n return this\n }\n\n Tooltip.prototype.fixTitle = function () {\n var $e = this.$element\n if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {\n $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n }\n }\n\n Tooltip.prototype.hasContent = function () {\n return this.getTitle()\n }\n\n Tooltip.prototype.getPosition = function () {\n var el = this.$element[0]\n return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {\n width: el.offsetWidth\n , height: el.offsetHeight\n }, this.$element.offset())\n }\n\n Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n }\n\n Tooltip.prototype.getTitle = function () {\n var title\n var $e = this.$element\n var o = this.options\n\n title = $e.attr('data-original-title')\n || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)\n\n return title\n }\n\n Tooltip.prototype.tip = function () {\n return this.$tip = this.$tip || $(this.options.template)\n }\n\n Tooltip.prototype.arrow = function () {\n return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')\n }\n\n Tooltip.prototype.validate = function () {\n if (!this.$element[0].parentNode) {\n this.hide()\n this.$element = null\n this.options = null\n }\n }\n\n Tooltip.prototype.enable = function () {\n this.enabled = true\n }\n\n Tooltip.prototype.disable = function () {\n this.enabled = false\n }\n\n Tooltip.prototype.toggleEnabled = function () {\n this.enabled = !this.enabled\n }\n\n Tooltip.prototype.toggle = function (e) {\n var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this\n self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n }\n\n Tooltip.prototype.destroy = function () {\n this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)\n }\n\n\n // TOOLTIP PLUGIN DEFINITION\n // =========================\n\n var old = $.fn.tooltip\n\n $.fn.tooltip = function (option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tooltip')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n $.fn.tooltip.Constructor = Tooltip\n\n\n // TOOLTIP NO CONFLICT\n // ===================\n\n $.fn.tooltip.noConflict = function () {\n $.fn.tooltip = old\n return this\n }\n\n}(window.jQuery);\n","transition.js":"/* ========================================================================\n * Bootstrap: transition.js v3.0.0\n * http://twbs.github.com/bootstrap/javascript.html#transitions\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)\n // ============================================================\n\n function transitionEnd() {\n var el = document.createElement('bootstrap')\n\n var transEndEventNames = {\n 'WebkitTransition' : 'webkitTransitionEnd'\n , 'MozTransition' : 'transitionend'\n , 'OTransition' : 'oTransitionEnd otransitionend'\n , 'transition' : 'transitionend'\n }\n\n for (var name in transEndEventNames) {\n if (el.style[name] !== undefined) {\n return { end: transEndEventNames[name] }\n }\n }\n }\n\n // http://blog.alexmaccaw.com/css-transitions\n $.fn.emulateTransitionEnd = function (duration) {\n var called = false, $el = this\n $(this).one($.support.transition.end, function () { called = true })\n var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n setTimeout(callback, duration)\n return this\n }\n\n $(function () {\n $.support.transition = transitionEnd()\n })\n\n}(window.jQuery);\n"}
var __less = {"alerts.less":"//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headingsColor\n color: inherit;\n }\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissable alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","badges.less":"//\n// Badges\n// --------------------------------------------------\n\n\n// Base classes\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: baseline;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n}\n\n// Hover state, but only for links\na.badge {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n}\n\n// Quick fix for labels/badges in buttons\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n// Account for counters in navs\na.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n","bootstrap.less":"/*!\n * Bootstrap v3.0.0\n *\n * Copyright 2013 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Designed and built with all the love in the world by @mdo and @fat.\n */\n\n// Core variables and mixins\n@import \"variables.less\";\n@import \"mixins.less\";\n\n// Reset\n@import \"normalize.less\";\n@import \"print.less\";\n\n// Core CSS\n@import \"scaffolding.less\";\n@import \"type.less\";\n@import \"code.less\";\n@import \"grid.less\";\n@import \"tables.less\";\n@import \"forms.less\";\n@import \"buttons.less\";\n\n// Components\n@import \"component-animations.less\";\n@import \"glyphicons.less\";\n@import \"dropdowns.less\";\n@import \"button-groups.less\";\n@import \"input-groups.less\";\n@import \"navs.less\";\n@import \"navbar.less\";\n@import \"breadcrumbs.less\";\n@import \"pagination.less\";\n@import \"pager.less\";\n@import \"labels.less\";\n@import \"badges.less\";\n@import \"jumbotron.less\";\n@import \"thumbnails.less\";\n@import \"alerts.less\";\n@import \"progress-bars.less\";\n@import \"media.less\";\n@import \"list-group.less\";\n@import \"panels.less\";\n@import \"wells.less\";\n@import \"close.less\";\n\n// Components w/ JavaScript\n@import \"modals.less\";\n@import \"tooltip.less\";\n@import \"popovers.less\";\n@import \"carousel.less\";\n\n// Utility classes\n@import \"utilities.less\";\n@import \"responsive-utilities.less\";\n","breadcrumbs.less":"//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n > li {\n display: inline-block;\n &+li:before {\n content: \"/\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","button-groups.less":"//\n// Button groups\n// --------------------------------------------------\n\n// Button carets\n//\n// Match the button text color to the arrow/caret for indicating dropdown-ness.\n\n.caret {\n .btn-default & {\n border-top-color: @btn-default-color;\n }\n .btn-primary &,\n .btn-success &,\n .btn-warning &,\n .btn-danger &,\n .btn-info & {\n border-top-color: #fff;\n }\n}\n.dropup {\n & .btn-default .caret {\n border-bottom-color: @btn-default-color;\n }\n .btn-primary,\n .btn-success,\n .btn-warning,\n .btn-danger,\n .btn-info {\n .caret {\n border-bottom-color: #fff;\n }\n }\n}\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n &:focus {\n // Remove focus outline when dropdown JS adds it after closing the menu\n outline: none;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n .clearfix();\n\n .btn-group {\n float: left;\n }\n // Space out series of button groups\n > .btn,\n > .btn-group {\n + .btn,\n + .btn-group {\n margin-left: 5px;\n }\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// 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\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { .btn-xs(); }\n.btn-group-sm > .btn { .btn-sm(); }\n.btn-group-lg > .btn { .btn-lg(); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n .clearfix();\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n border-top-right-radius: @border-radius-base;\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n border-bottom-left-radius: @border-radius-base;\n .border-top-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n .btn {\n float: none;\n display: table-cell;\n width: 1%;\n }\n}\n\n\n// Checkbox and radio options\n[data-toggle=\"buttons\"] > .btn > input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn > input[type=\"checkbox\"] {\n display: none;\n}\n","buttons.less":"//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n// Core styles\n.btn {\n display: inline-block;\n padding: @padding-base-vertical @padding-base-horizontal;\n margin-bottom: 0; // For input.btn\n font-size: @font-size-base;\n font-weight: @btn-font-weight;\n line-height: @line-height-base;\n text-align: center;\n vertical-align: middle;\n cursor: pointer;\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n white-space: nowrap;\n .user-select(none);\n\n &:focus {\n .tab-focus();\n }\n\n &:hover,\n &:focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: not-allowed;\n pointer-events: none; // Future-proof disabling of clicks\n .opacity(.65);\n .box-shadow(none);\n }\n\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n cursor: pointer;\n border-radius: 0;\n\n &,\n &:active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: underline;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n.btn-sm,\n.btn-xs {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n.btn-xs {\n padding: 1px 5px;\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n padding-left: 0;\n padding-right: 0;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","carousel.less":"//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n\n > .item {\n display: none;\n position: relative;\n .transition(.6s ease-in-out left);\n\n // Account for jankitude on images\n > img,\n > a > img {\n .img-responsive();\n line-height: 1;\n }\n }\n\n > .active,\n > .next,\n > .prev { display: block; }\n\n > .active {\n left: 0;\n }\n\n > .next,\n > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n }\n\n > .next {\n left: 100%;\n }\n > .prev {\n left: -100%;\n }\n > .next.left,\n > .prev.right {\n left: 0;\n }\n\n > .active.left {\n left: -100%;\n }\n > .active.right {\n left: 100%;\n }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: @carousel-control-width;\n .opacity(@carousel-control-opacity);\n font-size: @carousel-control-font-size;\n color: @carousel-control-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n // We can't have this transition here because webkit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Set gradients for backgrounds\n &.left {\n #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n }\n &.right {\n left: auto;\n right: 0;\n #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n }\n\n // Hover/focus state\n &:hover,\n &:focus {\n color: @carousel-control-color;\n text-decoration: none;\n .opacity(.9);\n }\n\n // Toggles\n .icon-prev,\n .icon-next,\n .glyphicon-chevron-left,\n .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n left: 50%;\n z-index: 5;\n display: inline-block;\n }\n .icon-prev,\n .icon-next {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n margin-left: -10px;\n font-family: serif;\n }\n\n .icon-prev {\n &:before {\n content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n }\n }\n .icon-next {\n &:before {\n content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n }\n }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n\n li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid @carousel-indicator-border-color;\n border-radius: 10px;\n cursor: pointer;\n }\n .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: @carousel-indicator-active-bg;\n }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: @carousel-caption-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n & .btn {\n text-shadow: none; // No shadow for button elements in carousel-caption\n }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-tablet) {\n\n // Scale up the controls a smidge\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n margin-left: -15px;\n font-size: 30px;\n }\n\n // Show and left align the captions\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n\n // Move up the indicators\n .carousel-indicators {\n bottom: 20px;\n }\n}\n","close.less":"//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","code.less":"//\n// Code (inline and blocK)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\npre {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n white-space: nowrap;\n border-radius: @border-radius-base;\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Make prettyprint styles more spaced out for readability\n &.prettyprint {\n margin-bottom: @line-height-computed;\n }\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","component-animations.less":"//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twitter/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n &.in {\n display: block;\n }\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition(height .35s ease);\n}\n","dropdowns.less":"//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base solid @dropdown-caret-color;\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n // Firefox fix for https://github.com/twbs/bootstrap/issues/9538. Once fixed,\n // we can just straight up remove this.\n border-bottom: 0 dotted;\n content: \"\";\n}\n\n// The dropdown wrapper (div)\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n}\n// Nuke hover/focus effects\n.dropdown-menu > .disabled > a {\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: not-allowed;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: @zindex-dropdown - 10;\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n // Firefox fix for https://github.com/twbs/bootstrap/issues/9538. Once this\n // gets fixed, restore `border-top: 0;`.\n border-top: 0 dotted;\n border-bottom: 4px solid @dropdown-caret-color;\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 1px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .pull-right > .dropdown-menu();\n }\n }\n}\n\n","forms.less":"//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; /* IE8-9 */\n line-height: normal;\n}\n\n// Set the height of select and file controls to match text inputs\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Fix optgroup Firefox bug per https://github.com/twbs/bootstrap/issues/7611\nselect optgroup {\n font-size: inherit;\n font-style: inherit;\n font-family: inherit;\n}\n\n// Focus for select, file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Fix for Chrome number input\n// Setting certain font-sizes causes the `I` bar to appear on hover of the bottom increment button.\n// See https://github.com/twbs/bootstrap/issues/8350 for more.\ninput[type=\"number\"] {\n &::-webkit-outer-spin-button,\n &::-webkit-inner-spin-button {\n height: auto;\n }\n}\n\n\n// Placeholder\n//\n// Placeholder text gets special styles because when browsers invalidate entire\n// lines if it doesn't understand a selector/\n.form-control {\n .placeholder();\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n vertical-align: middle;\n background-color: @input-bg;\n border: 1px solid @input-border;\n border-radius: @input-border-radius;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Disabled and read-only inputs\n // Note: HTML5 says that controls under a fieldset > legend:first-child won't\n // be disabled if the fieldset is disabled. Due to implementation difficulty,\n // we don't honor that edge case; we style them as disabled anyway.\n &[disabled],\n &[readonly],\n fieldset[disabled] & {\n cursor: not-allowed;\n background-color: @input-bg-disabled;\n }\n\n // Reset height for `textarea`s\n textarea& {\n height: auto;\n }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: 15px;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n display: block;\n min-height: @line-height-computed; // clear the floating input if there is no label text\n margin-top: 10px;\n margin-bottom: 10px;\n padding-left: 20px;\n vertical-align: middle;\n label {\n display: inline;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n float: left;\n margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"],\n.radio,\n.radio-inline,\n.checkbox,\n.checkbox-inline {\n &[disabled],\n fieldset[disabled] & {\n cursor: not-allowed;\n }\n}\n\n// Form control sizing\n.input-sm {\n .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n.input-lg {\n .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n// Warning\n.has-warning {\n .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n// Error\n.has-error {\n .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n// Success\n.has-success {\n .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n margin-bottom: 0; // Remove default margin from `p`\n padding-top: (@padding-base-vertical + 1);\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n display: block; // account for any element using help-block\n margin-top: 5px;\n margin-bottom: 10px;\n color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n // Kick in the inline\n @media (min-width: @screen-tablet) {\n // Inline-block all the things for \"inline\"\n .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // In navbar-form, allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match (which also avoids\n // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).\n .radio,\n .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n }\n .radio input[type=\"radio\"],\n .checkbox input[type=\"checkbox\"] {\n float: none;\n margin-left: 0;\n }\n }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n // Consistent vertical alignment of labels, radios, and checkboxes\n .control-label,\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n\n // Make form groups behave like rows\n .form-group {\n .make-row();\n }\n\n // Only right align form labels here when the columns stop stacking\n @media (min-width: @screen-tablet) {\n .control-label {\n text-align: right;\n }\n }\n}\n","glyphicons.less":"//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#glyphicons-halflingsregular') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\2a\"; } }\n.glyphicon-plus { &:before { content: \"\\2b\"; } }\n.glyphicon-euro { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-briefcase { &:before { content: \"\\1f4bc\"; } }\n.glyphicon-calendar { &:before { content: \"\\1f4c5\"; } }\n.glyphicon-pushpin { &:before { content: \"\\1f4cc\"; } }\n.glyphicon-paperclip { &:before { content: \"\\1f4ce\"; } }\n.glyphicon-camera { &:before { content: \"\\1f4f7\"; } }\n.glyphicon-lock { &:before { content: \"\\1f512\"; } }\n.glyphicon-bell { &:before { content: \"\\1f514\"; } }\n.glyphicon-bookmark { &:before { content: \"\\1f516\"; } }\n.glyphicon-fire { &:before { content: \"\\1f525\"; } }\n.glyphicon-wrench { &:before { content: \"\\1f527\"; } }\n","grid.less":"//\n// Grid system\n// --------------------------------------------------\n\n\n// Set the container width, and override it for fixed navbars in media queries\n.container {\n .container-fixed();\n}\n\n// mobile first defaults\n.row {\n .make-row();\n}\n\n// Common styles for small and large grid columns\n.col-xs-1,\n.col-xs-2,\n.col-xs-3,\n.col-xs-4,\n.col-xs-5,\n.col-xs-6,\n.col-xs-7,\n.col-xs-8,\n.col-xs-9,\n.col-xs-10,\n.col-xs-11,\n.col-xs-12,\n.col-sm-1,\n.col-sm-2,\n.col-sm-3,\n.col-sm-4,\n.col-sm-5,\n.col-sm-6,\n.col-sm-7,\n.col-sm-8,\n.col-sm-9,\n.col-sm-10,\n.col-sm-11,\n.col-sm-12,\n.col-md-1,\n.col-md-2,\n.col-md-3,\n.col-md-4,\n.col-md-5,\n.col-md-6,\n.col-md-7,\n.col-md-8,\n.col-md-9,\n.col-md-10,\n.col-md-11,\n.col-md-12,\n.col-lg-1,\n.col-lg-2,\n.col-lg-3,\n.col-lg-4,\n.col-lg-5,\n.col-lg-6,\n.col-lg-7,\n.col-lg-8,\n.col-lg-9,\n.col-lg-10,\n.col-lg-11,\n.col-lg-12 {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n}\n\n\n// Extra small grid\n//\n// Grid classes for extra small devices like smartphones. No offset, push, or\n// pull classes are present here due to the size of the target.\n//\n// Note that `.col-xs-12` doesn't get floated on purpose—there's no need since\n// it's full-width.\n\n.col-xs-1,\n.col-xs-2,\n.col-xs-3,\n.col-xs-4,\n.col-xs-5,\n.col-xs-6,\n.col-xs-7,\n.col-xs-8,\n.col-xs-9,\n.col-xs-10,\n.col-xs-11 {\n float: left;\n}\n.col-xs-1 { width: percentage((1 / @grid-columns)); }\n.col-xs-2 { width: percentage((2 / @grid-columns)); }\n.col-xs-3 { width: percentage((3 / @grid-columns)); }\n.col-xs-4 { width: percentage((4 / @grid-columns)); }\n.col-xs-5 { width: percentage((5 / @grid-columns)); }\n.col-xs-6 { width: percentage((6 / @grid-columns)); }\n.col-xs-7 { width: percentage((7 / @grid-columns)); }\n.col-xs-8 { width: percentage((8 / @grid-columns)); }\n.col-xs-9 { width: percentage((9 / @grid-columns)); }\n.col-xs-10 { width: percentage((10/ @grid-columns)); }\n.col-xs-11 { width: percentage((11/ @grid-columns)); }\n.col-xs-12 { width: 100%; }\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n//\n// Note that `.col-sm-12` doesn't get floated on purpose—there's no need since\n// it's full-width.\n\n@media (min-width: @screen-tablet) {\n .container {\n max-width: @container-tablet;\n }\n\n .col-sm-1,\n .col-sm-2,\n .col-sm-3,\n .col-sm-4,\n .col-sm-5,\n .col-sm-6,\n .col-sm-7,\n .col-sm-8,\n .col-sm-9,\n .col-sm-10,\n .col-sm-11 {\n float: left;\n }\n .col-sm-1 { width: percentage((1 / @grid-columns)); }\n .col-sm-2 { width: percentage((2 / @grid-columns)); }\n .col-sm-3 { width: percentage((3 / @grid-columns)); }\n .col-sm-4 { width: percentage((4 / @grid-columns)); }\n .col-sm-5 { width: percentage((5 / @grid-columns)); }\n .col-sm-6 { width: percentage((6 / @grid-columns)); }\n .col-sm-7 { width: percentage((7 / @grid-columns)); }\n .col-sm-8 { width: percentage((8 / @grid-columns)); }\n .col-sm-9 { width: percentage((9 / @grid-columns)); }\n .col-sm-10 { width: percentage((10/ @grid-columns)); }\n .col-sm-11 { width: percentage((11/ @grid-columns)); }\n .col-sm-12 { width: 100%; }\n\n // Push and pull columns for source order changes\n .col-sm-push-1 { left: percentage((1 / @grid-columns)); }\n .col-sm-push-2 { left: percentage((2 / @grid-columns)); }\n .col-sm-push-3 { left: percentage((3 / @grid-columns)); }\n .col-sm-push-4 { left: percentage((4 / @grid-columns)); }\n .col-sm-push-5 { left: percentage((5 / @grid-columns)); }\n .col-sm-push-6 { left: percentage((6 / @grid-columns)); }\n .col-sm-push-7 { left: percentage((7 / @grid-columns)); }\n .col-sm-push-8 { left: percentage((8 / @grid-columns)); }\n .col-sm-push-9 { left: percentage((9 / @grid-columns)); }\n .col-sm-push-10 { left: percentage((10/ @grid-columns)); }\n .col-sm-push-11 { left: percentage((11/ @grid-columns)); }\n\n .col-sm-pull-1 { right: percentage((1 / @grid-columns)); }\n .col-sm-pull-2 { right: percentage((2 / @grid-columns)); }\n .col-sm-pull-3 { right: percentage((3 / @grid-columns)); }\n .col-sm-pull-4 { right: percentage((4 / @grid-columns)); }\n .col-sm-pull-5 { right: percentage((5 / @grid-columns)); }\n .col-sm-pull-6 { right: percentage((6 / @grid-columns)); }\n .col-sm-pull-7 { right: percentage((7 / @grid-columns)); }\n .col-sm-pull-8 { right: percentage((8 / @grid-columns)); }\n .col-sm-pull-9 { right: percentage((9 / @grid-columns)); }\n .col-sm-pull-10 { right: percentage((10/ @grid-columns)); }\n .col-sm-pull-11 { right: percentage((11/ @grid-columns)); }\n\n // Offsets\n .col-sm-offset-1 { margin-left: percentage((1 / @grid-columns)); }\n .col-sm-offset-2 { margin-left: percentage((2 / @grid-columns)); }\n .col-sm-offset-3 { margin-left: percentage((3 / @grid-columns)); }\n .col-sm-offset-4 { margin-left: percentage((4 / @grid-columns)); }\n .col-sm-offset-5 { margin-left: percentage((5 / @grid-columns)); }\n .col-sm-offset-6 { margin-left: percentage((6 / @grid-columns)); }\n .col-sm-offset-7 { margin-left: percentage((7 / @grid-columns)); }\n .col-sm-offset-8 { margin-left: percentage((8 / @grid-columns)); }\n .col-sm-offset-9 { margin-left: percentage((9 / @grid-columns)); }\n .col-sm-offset-10 { margin-left: percentage((10/ @grid-columns)); }\n .col-sm-offset-11 { margin-left: percentage((11/ @grid-columns)); }\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n//\n// Note that `.col-md-12` doesn't get floated on purpose—there's no need since\n// it's full-width.\n\n@media (min-width: @screen-desktop) {\n .container {\n max-width: @container-desktop;\n }\n .col-md-1,\n .col-md-2,\n .col-md-3,\n .col-md-4,\n .col-md-5,\n .col-md-6,\n .col-md-7,\n .col-md-8,\n .col-md-9,\n .col-md-10,\n .col-md-11 {\n float: left;\n }\n .col-md-1 { width: percentage((1 / @grid-columns)); }\n .col-md-2 { width: percentage((2 / @grid-columns)); }\n .col-md-3 { width: percentage((3 / @grid-columns)); }\n .col-md-4 { width: percentage((4 / @grid-columns)); }\n .col-md-5 { width: percentage((5 / @grid-columns)); }\n .col-md-6 { width: percentage((6 / @grid-columns)); }\n .col-md-7 { width: percentage((7 / @grid-columns)); }\n .col-md-8 { width: percentage((8 / @grid-columns)); }\n .col-md-9 { width: percentage((9 / @grid-columns)); }\n .col-md-10 { width: percentage((10/ @grid-columns)); }\n .col-md-11 { width: percentage((11/ @grid-columns)); }\n .col-md-12 { width: 100%; }\n\n // Push and pull columns for source order changes\n .col-md-push-0 { left: auto; }\n .col-md-push-1 { left: percentage((1 / @grid-columns)); }\n .col-md-push-2 { left: percentage((2 / @grid-columns)); }\n .col-md-push-3 { left: percentage((3 / @grid-columns)); }\n .col-md-push-4 { left: percentage((4 / @grid-columns)); }\n .col-md-push-5 { left: percentage((5 / @grid-columns)); }\n .col-md-push-6 { left: percentage((6 / @grid-columns)); }\n .col-md-push-7 { left: percentage((7 / @grid-columns)); }\n .col-md-push-8 { left: percentage((8 / @grid-columns)); }\n .col-md-push-9 { left: percentage((9 / @grid-columns)); }\n .col-md-push-10 { left: percentage((10/ @grid-columns)); }\n .col-md-push-11 { left: percentage((11/ @grid-columns)); }\n\n .col-md-pull-0 { right: auto; }\n .col-md-pull-1 { right: percentage((1 / @grid-columns)); }\n .col-md-pull-2 { right: percentage((2 / @grid-columns)); }\n .col-md-pull-3 { right: percentage((3 / @grid-columns)); }\n .col-md-pull-4 { right: percentage((4 / @grid-columns)); }\n .col-md-pull-5 { right: percentage((5 / @grid-columns)); }\n .col-md-pull-6 { right: percentage((6 / @grid-columns)); }\n .col-md-pull-7 { right: percentage((7 / @grid-columns)); }\n .col-md-pull-8 { right: percentage((8 / @grid-columns)); }\n .col-md-pull-9 { right: percentage((9 / @grid-columns)); }\n .col-md-pull-10 { right: percentage((10/ @grid-columns)); }\n .col-md-pull-11 { right: percentage((11/ @grid-columns)); }\n\n // Offsets\n .col-md-offset-0 { margin-left: 0; }\n .col-md-offset-1 { margin-left: percentage((1 / @grid-columns)); }\n .col-md-offset-2 { margin-left: percentage((2 / @grid-columns)); }\n .col-md-offset-3 { margin-left: percentage((3 / @grid-columns)); }\n .col-md-offset-4 { margin-left: percentage((4 / @grid-columns)); }\n .col-md-offset-5 { margin-left: percentage((5 / @grid-columns)); }\n .col-md-offset-6 { margin-left: percentage((6 / @grid-columns)); }\n .col-md-offset-7 { margin-left: percentage((7 / @grid-columns)); }\n .col-md-offset-8 { margin-left: percentage((8 / @grid-columns)); }\n .col-md-offset-9 { margin-left: percentage((9 / @grid-columns)); }\n .col-md-offset-10 { margin-left: percentage((10/ @grid-columns)); }\n .col-md-offset-11 { margin-left: percentage((11/ @grid-columns)); }\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n//\n// Note that `.col-lg-12` doesn't get floated on purpose—there's no need since\n// it's full-width.\n\n@media (min-width: @screen-lg-desktop) {\n .container {\n max-width: @container-lg-desktop;\n }\n\n .col-lg-1,\n .col-lg-2,\n .col-lg-3,\n .col-lg-4,\n .col-lg-5,\n .col-lg-6,\n .col-lg-7,\n .col-lg-8,\n .col-lg-9,\n .col-lg-10,\n .col-lg-11 {\n float: left;\n }\n .col-lg-1 { width: percentage((1 / @grid-columns)); }\n .col-lg-2 { width: percentage((2 / @grid-columns)); }\n .col-lg-3 { width: percentage((3 / @grid-columns)); }\n .col-lg-4 { width: percentage((4 / @grid-columns)); }\n .col-lg-5 { width: percentage((5 / @grid-columns)); }\n .col-lg-6 { width: percentage((6 / @grid-columns)); }\n .col-lg-7 { width: percentage((7 / @grid-columns)); }\n .col-lg-8 { width: percentage((8 / @grid-columns)); }\n .col-lg-9 { width: percentage((9 / @grid-columns)); }\n .col-lg-10 { width: percentage((10/ @grid-columns)); }\n .col-lg-11 { width: percentage((11/ @grid-columns)); }\n .col-lg-12 { width: 100%; }\n\n // Push and pull columns for source order changes\n .col-lg-push-0 { left: auto; }\n .col-lg-push-1 { left: percentage((1 / @grid-columns)); }\n .col-lg-push-2 { left: percentage((2 / @grid-columns)); }\n .col-lg-push-3 { left: percentage((3 / @grid-columns)); }\n .col-lg-push-4 { left: percentage((4 / @grid-columns)); }\n .col-lg-push-5 { left: percentage((5 / @grid-columns)); }\n .col-lg-push-6 { left: percentage((6 / @grid-columns)); }\n .col-lg-push-7 { left: percentage((7 / @grid-columns)); }\n .col-lg-push-8 { left: percentage((8 / @grid-columns)); }\n .col-lg-push-9 { left: percentage((9 / @grid-columns)); }\n .col-lg-push-10 { left: percentage((10/ @grid-columns)); }\n .col-lg-push-11 { left: percentage((11/ @grid-columns)); }\n\n .col-lg-pull-0 { right: auto; }\n .col-lg-pull-1 { right: percentage((1 / @grid-columns)); }\n .col-lg-pull-2 { right: percentage((2 / @grid-columns)); }\n .col-lg-pull-3 { right: percentage((3 / @grid-columns)); }\n .col-lg-pull-4 { right: percentage((4 / @grid-columns)); }\n .col-lg-pull-5 { right: percentage((5 / @grid-columns)); }\n .col-lg-pull-6 { right: percentage((6 / @grid-columns)); }\n .col-lg-pull-7 { right: percentage((7 / @grid-columns)); }\n .col-lg-pull-8 { right: percentage((8 / @grid-columns)); }\n .col-lg-pull-9 { right: percentage((9 / @grid-columns)); }\n .col-lg-pull-10 { right: percentage((10/ @grid-columns)); }\n .col-lg-pull-11 { right: percentage((11/ @grid-columns)); }\n\n // Offsets\n .col-lg-offset-0 { margin-left: 0; }\n .col-lg-offset-1 { margin-left: percentage((1 / @grid-columns)); }\n .col-lg-offset-2 { margin-left: percentage((2 / @grid-columns)); }\n .col-lg-offset-3 { margin-left: percentage((3 / @grid-columns)); }\n .col-lg-offset-4 { margin-left: percentage((4 / @grid-columns)); }\n .col-lg-offset-5 { margin-left: percentage((5 / @grid-columns)); }\n .col-lg-offset-6 { margin-left: percentage((6 / @grid-columns)); }\n .col-lg-offset-7 { margin-left: percentage((7 / @grid-columns)); }\n .col-lg-offset-8 { margin-left: percentage((8 / @grid-columns)); }\n .col-lg-offset-9 { margin-left: percentage((9 / @grid-columns)); }\n .col-lg-offset-10 { margin-left: percentage((10/ @grid-columns)); }\n .col-lg-offset-11 { margin-left: percentage((11/ @grid-columns)); }\n}\n","input-groups.less":"//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &.col {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n width: 100%;\n margin-bottom: 0;\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn { .input-lg(); }\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn { .input-sm(); }\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @border-radius-base;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child) {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n // Jankily prevent input button groups from wrapping\n + .btn {\n margin-left: -4px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:active {\n z-index: 2;\n }\n}\n","jumbotron.less":"//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding: @jumbotron-padding;\n margin-bottom: @jumbotron-padding;\n font-size: (@font-size-base * 1.5);\n font-weight: 200;\n line-height: (@line-height-base * 1.5);\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1 {\n line-height: 1;\n color: @jumbotron-heading-color;\n }\n p {\n line-height: 1.4;\n }\n\n .container & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n }\n\n @media screen and (min-width: @screen-tablet) {\n padding-top: (@jumbotron-padding * 1.6);\n padding-bottom: (@jumbotron-padding * 1.6);\n\n .container & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1 {\n font-size: (@font-size-base * 4.5);\n }\n }\n}\n","labels.less":"//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n &[href] {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","list-group.less":"//\n// List groups\n// --------------------------------------------------\n\n// Base class\n//\n// Easily usable on
, , or
.\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n// Individual list items\n// -------------------------\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n\n // Align badges within list items\n > .badge {\n float: right;\n }\n > .badge + .badge {\n margin-right: 5px;\n }\n\n // Linked list items\n a& {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @list-group-hover-bg;\n }\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: lighten(@list-group-active-bg, 40%);\n }\n }\n}\n\n// Custom content options\n// -------------------------\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","media.less":"// Media objects\n// Source: http://stubbornella.org/content/?p=497\n// --------------------------------------------------\n\n\n// Common styles\n// -------------------------\n\n// Clear the floats\n.media,\n.media-body {\n overflow: hidden;\n zoom: 1;\n}\n\n// Proper spacing between instances of .media\n.media,\n.media .media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n\n// For images and videos, set to block\n.media-object {\n display: block;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin: 0 0 5px;\n}\n\n\n// Media image alignment\n// -------------------------\n\n.media {\n > .pull-left {\n margin-right: 10px;\n }\n > .pull-right {\n margin-left: 10px;\n }\n}\n\n\n// Media list variation\n// -------------------------\n\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","mixins.less":"//\n// Mixins\n// --------------------------------------------------\n\n\n// Utilities\n// -------------------------\n\n// Clearfix\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; /* 1 */\n display: table; /* 2 */\n }\n &:after {\n clear: both;\n }\n}\n\n// Webkit-style focus\n.tab-focus() {\n // Default\n outline: thin dotted #333;\n // Webkit\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n\n// Center-align a block level element\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n\n// Sizing shortcuts\n.size(@width; @height) {\n width: @width;\n height: @height;\n}\n.square(@size) {\n .size(@size; @size);\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n &:-moz-placeholder { color: @color; } // Firefox 4-18\n &::-moz-placeholder { color: @color; } // Firefox 19+\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Text overflow\n// Requires inline-block or block for proper styling\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n// CSS image replacement\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n\n\n// CSS3 PROPERTIES\n// --------------------------------------------------\n\n// Single side border-radius\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n\n// Drop shadows\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Transitions\n.transition(@transition) {\n -webkit-transition: @transition;\n transition: @transition;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n// Transformations\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9+\n transform: rotate(@degrees);\n}\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9+\n transform: scale(@ratio);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9+\n transform: translate(@x, @y);\n}\n.skew(@x; @y) {\n -webkit-transform: skew(@x, @y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n transform: skew(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n// See git pull https://github.com/dannykeane/bootstrap.git backface-visibility for examples\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// User select\n// For selecting text on the page\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n -o-user-select: @select;\n user-select: @select;\n}\n\n// Resize anything\n.resizable(@direction) {\n resize: @direction; // Options: horizontal, vertical, both\n overflow: auto; // Safari fix\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Opacity\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n\n\n\n// GRADIENTS\n// --------------------------------------------------\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-gradient(linear, @start-percent top, @end-percent top, from(@start-color), to(@end-color)); // Safari 4+, Chrome 2+\n background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1+, Chrome 10+\n background-image: -moz-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // FF 3.6+\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-gradient(linear, left @start-percent, left @end-percent, from(@start-color), to(@end-color)); // Safari 4+, Chrome 2+\n background-image: -webkit-linear-gradient(top, @start-color, @start-percent, @end-color, @end-percent); // Safari 5.1+, Chrome 10+\n background-image: -moz-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // FF 3.6+\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1+, Chrome 10+\n background-image: -moz-linear-gradient(@deg, @start-color, @end-color); // FF 3.6+\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-gradient(left, linear, 0 0, 0 100%, from(@start-color), color-stop(@color-stop, @mid-color), to(@end-color));\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -moz-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@start-color), color-stop(@color-stop, @mid-color), to(@end-color));\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -moz-linear-gradient(top, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(@inner-color), to(@outer-color));\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: -moz-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: #555; @angle: 45deg) {\n background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent));\n background-image: -webkit-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);\n background-image: -moz-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);\n }\n}\n\n// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n\n\n\n// Retina images\n//\n// Short retina mixin for setting background-image and -size\n\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n.img-responsive(@display: block;) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// COMPONENT MIXINS\n// --------------------------------------------------\n\n// Horizontal dividers\n// -------------------------\n// Dividers (basically an hr) within dropdowns and nav lists\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n\n// Panels\n// -------------------------\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border;) {\n border-color: @border;\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n + .panel-collapse .panel-body {\n border-top-color: @border;\n }\n }\n & > .panel-footer {\n + .panel-collapse .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n\n// Alerts\n// -------------------------\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n\n// Tables\n// -------------------------\n.table-row-variant(@state; @background; @border) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n border-color: @border;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td {\n background-color: darken(@background, 5%);\n border-color: darken(@border, 5%);\n }\n }\n}\n\n// Button variants\n// -------------------------\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:hover,\n &:focus,\n &:active,\n &.active,\n .open .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 8%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &:active,\n &.active {\n background-color: @background;\n border-color: @border\n }\n }\n}\n\n// Button sizes\n// -------------------------\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n\n// Pagination\n// -------------------------\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n\n// Labels\n// -------------------------\n.label-variant(@color) {\n background-color: @color;\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n\n// Navbar vertical align\n// -------------------------\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n\n// Progress bars\n// -------------------------\n.progress-bar-variant(@color) {\n background-color: @color;\n .progress-striped & {\n #gradient > .striped(@color);\n }\n}\n\n// Responsive utilities\n// -------------------------\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n tr& { display: none !important; }\n th&,\n td& { display: none !important; }\n}\n\n// Grid System\n// -----------\n\n// Centered container element\n.container-fixed() {\n margin-right: auto;\n margin-left: auto;\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n .clearfix();\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: (@gutter / -2);\n margin-right: (@gutter / -2);\n .clearfix();\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n // Calculate width based on number of columns available\n @media (min-width: @screen-sm) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the small column offsets\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n // Calculate width based on number of columns available\n @media (min-width: @screen-md) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large column offsets\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n // Calculate width based on number of columns available\n @media (min-width: @screen-lg) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large column offsets\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n\n// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n // Color the label and help text\n .help-block,\n .control-label {\n color: @text-color;\n }\n // Set the border and box shadow on specific inputs to match\n .form-control {\n border-color: @border-color;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n &:focus {\n border-color: darken(@border-color, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n .box-shadow(@shadow);\n }\n }\n // Set validation states also for addons\n .input-group-addon {\n color: @text-color;\n border-color: @border-color;\n background-color: @background-color;\n }\n}\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-focus-border` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n\n.form-control-focus(@color: @input-border-focus) {\n @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n &:focus {\n border-color: @color;\n outline: 0;\n .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `