summaryrefslogtreecommitdiff
path: root/templates/assets/bootstrap
diff options
context:
space:
mode:
Diffstat (limited to 'templates/assets/bootstrap')
-rw-r--r--templates/assets/bootstrap/.bower.json44
-rw-r--r--templates/assets/bootstrap/CHANGELOG.md5
-rw-r--r--templates/assets/bootstrap/Gemfile8
-rw-r--r--templates/assets/bootstrap/Gemfile.lock58
-rw-r--r--templates/assets/bootstrap/Gruntfile.js321
-rw-r--r--templates/assets/bootstrap/ISSUE_TEMPLATE.md22
-rw-r--r--templates/assets/bootstrap/LICENSE22
-rw-r--r--templates/assets/bootstrap/README.md149
-rw-r--r--templates/assets/bootstrap/bower.json35
-rwxr-xr-xtemplates/assets/bootstrap/grunt/change-version.js110
-rw-r--r--templates/assets/bootstrap/grunt/gcp-key.json.encbin0 -> 2304 bytes
-rw-r--r--templates/assets/bootstrap/grunt/npm-shrinkwrap.json4164
-rw-r--r--templates/assets/bootstrap/grunt/postcss.config.js41
-rw-r--r--templates/assets/bootstrap/grunt/sauce_browsers.yml84
-rwxr-xr-xtemplates/assets/bootstrap/grunt/upload-preview.sh27
-rw-r--r--templates/assets/bootstrap/js/.eslintrc.json240
-rw-r--r--templates/assets/bootstrap/js/src/alert.js193
-rw-r--r--templates/assets/bootstrap/js/src/button.js176
-rw-r--r--templates/assets/bootstrap/js/src/carousel.js497
-rw-r--r--templates/assets/bootstrap/js/src/collapse.js393
-rw-r--r--templates/assets/bootstrap/js/src/dropdown.js307
-rw-r--r--templates/assets/bootstrap/js/src/modal.js545
-rw-r--r--templates/assets/bootstrap/js/src/popover.js179
-rw-r--r--templates/assets/bootstrap/js/src/scrollspy.js335
-rw-r--r--templates/assets/bootstrap/js/src/tab.js284
-rw-r--r--templates/assets/bootstrap/js/src/tooltip.js675
-rw-r--r--templates/assets/bootstrap/js/src/util.js164
-rw-r--r--templates/assets/bootstrap/nuget/MyGet.ps118
-rw-r--r--templates/assets/bootstrap/nuget/bootstrap.nuspec27
-rw-r--r--templates/assets/bootstrap/nuget/bootstrap.sass.nuspec27
-rw-r--r--templates/assets/bootstrap/package.js19
-rw-r--r--templates/assets/bootstrap/package.json114
-rw-r--r--templates/assets/bootstrap/sache.json5
-rw-r--r--templates/assets/bootstrap/scss/.scss-lint.yml536
-rw-r--r--templates/assets/bootstrap/scss/_alert.scss55
-rw-r--r--templates/assets/bootstrap/scss/_badge.scss76
-rw-r--r--templates/assets/bootstrap/scss/_breadcrumb.scss38
-rw-r--r--templates/assets/bootstrap/scss/_button-group.scss204
-rw-r--r--templates/assets/bootstrap/scss/_buttons.scss170
-rw-r--r--templates/assets/bootstrap/scss/_card.scss276
-rw-r--r--templates/assets/bootstrap/scss/_carousel.scss177
-rw-r--r--templates/assets/bootstrap/scss/_close.scss29
-rw-r--r--templates/assets/bootstrap/scss/_code.scss64
-rw-r--r--templates/assets/bootstrap/scss/_custom-forms.scss258
-rw-r--r--templates/assets/bootstrap/scss/_custom.scss4
-rw-r--r--templates/assets/bootstrap/scss/_dropdown.scss156
-rw-r--r--templates/assets/bootstrap/scss/_forms.scss387
-rw-r--r--templates/assets/bootstrap/scss/_grid.scss52
-rw-r--r--templates/assets/bootstrap/scss/_images.scss43
-rw-r--r--templates/assets/bootstrap/scss/_input-group.scss175
-rw-r--r--templates/assets/bootstrap/scss/_jumbotron.scss20
-rw-r--r--templates/assets/bootstrap/scss/_list-group.scss116
-rw-r--r--templates/assets/bootstrap/scss/_media.scss8
-rw-r--r--templates/assets/bootstrap/scss/_mixins.scss43
-rw-r--r--templates/assets/bootstrap/scss/_modal.scss142
-rw-r--r--templates/assets/bootstrap/scss/_nav.scss120
-rw-r--r--templates/assets/bootstrap/scss/_navbar.scss276
-rw-r--r--templates/assets/bootstrap/scss/_pagination.scss67
-rw-r--r--templates/assets/bootstrap/scss/_popover.scss171
-rw-r--r--templates/assets/bootstrap/scss/_print.scss119
-rw-r--r--templates/assets/bootstrap/scss/_progress.scss30
-rw-r--r--templates/assets/bootstrap/scss/_reboot.scss484
-rw-r--r--templates/assets/bootstrap/scss/_responsive-embed.scss52
-rw-r--r--templates/assets/bootstrap/scss/_tables.scss169
-rw-r--r--templates/assets/bootstrap/scss/_tooltip.scss90
-rw-r--r--templates/assets/bootstrap/scss/_transitions.scss34
-rw-r--r--templates/assets/bootstrap/scss/_type.scss143
-rw-r--r--templates/assets/bootstrap/scss/_utilities.scss13
-rw-r--r--templates/assets/bootstrap/scss/_variables.scss921
-rw-r--r--templates/assets/bootstrap/scss/bootstrap-grid.scss37
-rw-r--r--templates/assets/bootstrap/scss/bootstrap-reboot.scss9
-rw-r--r--templates/assets/bootstrap/scss/bootstrap.scss52
-rw-r--r--templates/assets/bootstrap/scss/mixins/_alert.scss14
-rw-r--r--templates/assets/bootstrap/scss/mixins/_background-variant.scss12
-rw-r--r--templates/assets/bootstrap/scss/mixins/_badge.scss11
-rw-r--r--templates/assets/bootstrap/scss/mixins/_border-radius.scss35
-rw-r--r--templates/assets/bootstrap/scss/mixins/_box-shadow.scss5
-rw-r--r--templates/assets/bootstrap/scss/mixins/_breakpoints.scss95
-rw-r--r--templates/assets/bootstrap/scss/mixins/_buttons.scss86
-rw-r--r--templates/assets/bootstrap/scss/mixins/_cards.scss47
-rw-r--r--templates/assets/bootstrap/scss/mixins/_clearfix.scss7
-rw-r--r--templates/assets/bootstrap/scss/mixins/_float.scss9
-rw-r--r--templates/assets/bootstrap/scss/mixins/_forms.scss55
-rw-r--r--templates/assets/bootstrap/scss/mixins/_gradients.scss37
-rw-r--r--templates/assets/bootstrap/scss/mixins/_grid-framework.scss65
-rw-r--r--templates/assets/bootstrap/scss/mixins/_grid.scss100
-rw-r--r--templates/assets/bootstrap/scss/mixins/_hover.scss60
-rw-r--r--templates/assets/bootstrap/scss/mixins/_image.scss36
-rw-r--r--templates/assets/bootstrap/scss/mixins/_list-group.scss26
-rw-r--r--templates/assets/bootstrap/scss/mixins/_lists.scss7
-rw-r--r--templates/assets/bootstrap/scss/mixins/_nav-divider.scss10
-rw-r--r--templates/assets/bootstrap/scss/mixins/_navbar-align.scss9
-rw-r--r--templates/assets/bootstrap/scss/mixins/_pagination.scss21
-rw-r--r--templates/assets/bootstrap/scss/mixins/_reset-text.scss18
-rw-r--r--templates/assets/bootstrap/scss/mixins/_resize.scss6
-rw-r--r--templates/assets/bootstrap/scss/mixins/_screen-reader.scss35
-rw-r--r--templates/assets/bootstrap/scss/mixins/_size.scss6
-rw-r--r--templates/assets/bootstrap/scss/mixins/_table-row.scss30
-rw-r--r--templates/assets/bootstrap/scss/mixins/_text-emphasis.scss12
-rw-r--r--templates/assets/bootstrap/scss/mixins/_text-hide.scss8
-rw-r--r--templates/assets/bootstrap/scss/mixins/_text-truncate.scss8
-rw-r--r--templates/assets/bootstrap/scss/mixins/_transforms.scss14
-rw-r--r--templates/assets/bootstrap/scss/mixins/_transition.scss9
-rw-r--r--templates/assets/bootstrap/scss/mixins/_visibility.scss5
-rw-r--r--templates/assets/bootstrap/scss/utilities/_align.scss6
-rw-r--r--templates/assets/bootstrap/scss/utilities/_background.scss19
-rw-r--r--templates/assets/bootstrap/scss/utilities/_borders.scss37
-rw-r--r--templates/assets/bootstrap/scss/utilities/_clearfix.scss3
-rw-r--r--templates/assets/bootstrap/scss/utilities/_display.scss53
-rw-r--r--templates/assets/bootstrap/scss/utilities/_flex.scss48
-rw-r--r--templates/assets/bootstrap/scss/utilities/_float.scss9
-rw-r--r--templates/assets/bootstrap/scss/utilities/_position.scss23
-rw-r--r--templates/assets/bootstrap/scss/utilities/_screenreaders.scss11
-rw-r--r--templates/assets/bootstrap/scss/utilities/_sizing.scss10
-rw-r--r--templates/assets/bootstrap/scss/utilities/_spacing.scss41
-rw-r--r--templates/assets/bootstrap/scss/utilities/_text.scss61
-rw-r--r--templates/assets/bootstrap/scss/utilities/_visibility.scss11
117 files changed, 16334 insertions, 0 deletions
diff --git a/templates/assets/bootstrap/.bower.json b/templates/assets/bootstrap/.bower.json
new file mode 100644
index 0000000..06b071c
--- /dev/null
+++ b/templates/assets/bootstrap/.bower.json
@@ -0,0 +1,44 @@
+{
+ "name": "bootstrap",
+ "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
+ "keywords": [
+ "css",
+ "js",
+ "sass",
+ "mobile-first",
+ "responsive",
+ "front-end",
+ "framework",
+ "web"
+ ],
+ "homepage": "https://getbootstrap.com",
+ "license": "MIT",
+ "moduleType": "globals",
+ "main": [
+ "scss/bootstrap.scss",
+ "dist/js/bootstrap.js"
+ ],
+ "ignore": [
+ "/.*",
+ "_config.yml",
+ "CNAME",
+ "composer.json",
+ "CONTRIBUTING.md",
+ "docs",
+ "js/tests",
+ "test-infra"
+ ],
+ "dependencies": {
+ "jquery": ">=1.9.1",
+ "tether": "^1.4.0"
+ },
+ "_release": "78fc4d23fc",
+ "_resolution": {
+ "type": "branch",
+ "branch": "v4-dev",
+ "commit": "78fc4d23fcefe31397444b75f43728c38e13c590"
+ },
+ "_source": "https://github.com/twbs/bootstrap.git",
+ "_target": "v4-dev",
+ "_originalSource": "bootstrap"
+} \ No newline at end of file
diff --git a/templates/assets/bootstrap/CHANGELOG.md b/templates/assets/bootstrap/CHANGELOG.md
new file mode 100644
index 0000000..7b60d7c
--- /dev/null
+++ b/templates/assets/bootstrap/CHANGELOG.md
@@ -0,0 +1,5 @@
+Bootstrap uses [GitHub's Releases feature](https://github.com/blog/1547-release-your-software) for its changelogs.
+
+See [the Releases section of our GitHub project](https://github.com/twbs/bootstrap/releases) for changelogs for each release version of Bootstrap.
+
+Release announcement posts on [the official Bootstrap blog](https://blog.getbootstrap.com) contain summaries of the most noteworthy changes made in each release.
diff --git a/templates/assets/bootstrap/Gemfile b/templates/assets/bootstrap/Gemfile
new file mode 100644
index 0000000..958c7a9
--- /dev/null
+++ b/templates/assets/bootstrap/Gemfile
@@ -0,0 +1,8 @@
+source 'https://rubygems.org'
+
+group :development, :test do
+ gem 'jekyll', '~> 3.4.2'
+ gem 'jekyll-redirect-from', '~> 0.12.1'
+ gem 'jekyll-sitemap', '~> 1.0.0'
+ gem 'scss_lint', '~> 0.52.0'
+end
diff --git a/templates/assets/bootstrap/Gemfile.lock b/templates/assets/bootstrap/Gemfile.lock
new file mode 100644
index 0000000..242ec49
--- /dev/null
+++ b/templates/assets/bootstrap/Gemfile.lock
@@ -0,0 +1,58 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ addressable (2.5.0)
+ public_suffix (~> 2.0, >= 2.0.2)
+ colorator (1.1.0)
+ ffi (1.9.18)
+ forwardable-extended (2.6.0)
+ jekyll (3.4.2)
+ addressable (~> 2.4)
+ colorator (~> 1.0)
+ jekyll-sass-converter (~> 1.0)
+ jekyll-watch (~> 1.1)
+ kramdown (~> 1.3)
+ liquid (~> 3.0)
+ mercenary (~> 0.3.3)
+ pathutil (~> 0.9)
+ rouge (~> 1.7)
+ safe_yaml (~> 1.0)
+ jekyll-redirect-from (0.12.1)
+ jekyll (~> 3.3)
+ jekyll-sass-converter (1.5.0)
+ sass (~> 3.4)
+ jekyll-sitemap (1.0.0)
+ jekyll (~> 3.3)
+ jekyll-watch (1.5.0)
+ listen (~> 3.0, < 3.1)
+ kramdown (1.13.2)
+ liquid (3.0.6)
+ listen (3.0.8)
+ rb-fsevent (~> 0.9, >= 0.9.4)
+ rb-inotify (~> 0.9, >= 0.9.7)
+ mercenary (0.3.6)
+ pathutil (0.14.0)
+ forwardable-extended (~> 2.6)
+ public_suffix (2.0.5)
+ rake (12.0.0)
+ rb-fsevent (0.9.8)
+ rb-inotify (0.9.8)
+ ffi (>= 0.5.0)
+ rouge (1.11.1)
+ safe_yaml (1.0.4)
+ sass (3.4.23)
+ scss_lint (0.52.0)
+ rake (>= 0.9, < 13)
+ sass (~> 3.4.20)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ jekyll (~> 3.4.2)
+ jekyll-redirect-from (~> 0.12.1)
+ jekyll-sitemap (~> 1.0.0)
+ scss_lint (~> 0.52.0)
+
+BUNDLED WITH
+ 1.14.6
diff --git a/templates/assets/bootstrap/Gruntfile.js b/templates/assets/bootstrap/Gruntfile.js
new file mode 100644
index 0000000..7675e2f
--- /dev/null
+++ b/templates/assets/bootstrap/Gruntfile.js
@@ -0,0 +1,321 @@
+/*!
+ * Bootstrap's Gruntfile
+ * https://getbootstrap.com
+ * Copyright 2013-2017 The Bootstrap Authors
+ * Copyright 2013-2017 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+module.exports = function (grunt) {
+ 'use strict'
+
+ // Force use of Unix newlines
+ grunt.util.linefeed = '\n'
+
+ RegExp.quote = function (string) {
+ return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&')
+ }
+
+ var isTravis = require('is-travis')
+
+ // Project configuration.
+ grunt.initConfig({
+
+ // Metadata.
+ pkg: grunt.file.readJSON('package.json'),
+ banner: '/*!\n' +
+ ' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
+ ' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
+ ' * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n' +
+ ' */\n',
+ jqueryCheck: 'if (typeof jQuery === \'undefined\') {\n' +
+ ' throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\\'s JavaScript.\')\n' +
+ '}\n',
+ jqueryVersionCheck: '+function ($) {\n' +
+ ' var version = $.fn.jquery.split(\' \')[0].split(\'.\')\n' +
+ ' if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] >= 4)) {\n' +
+ ' throw new Error(\'Bootstrap\\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0\')\n' +
+ ' }\n' +
+ '}(jQuery);\n\n',
+
+ // Task configuration.
+ clean: {
+ dist: 'dist',
+ docs: 'docs/dist'
+ },
+
+ // JS build configuration
+ babel: {
+ dev: {
+ options: {
+ sourceMap: true
+ },
+ files: {
+ 'js/dist/util.js' : 'js/src/util.js',
+ 'js/dist/alert.js' : 'js/src/alert.js',
+ 'js/dist/button.js' : 'js/src/button.js',
+ 'js/dist/carousel.js' : 'js/src/carousel.js',
+ 'js/dist/collapse.js' : 'js/src/collapse.js',
+ 'js/dist/dropdown.js' : 'js/src/dropdown.js',
+ 'js/dist/modal.js' : 'js/src/modal.js',
+ 'js/dist/scrollspy.js' : 'js/src/scrollspy.js',
+ 'js/dist/tab.js' : 'js/src/tab.js',
+ 'js/dist/tooltip.js' : 'js/src/tooltip.js',
+ 'js/dist/popover.js' : 'js/src/popover.js'
+ }
+ },
+ dist: {
+ options: {
+ extends: '../../.babelrc'
+ },
+ files: {
+ '<%= concat.bootstrap.dest %>' : '<%= concat.bootstrap.dest %>'
+ }
+ }
+ },
+
+ stamp: {
+ options: {
+ banner: '<%= banner %>\n<%= jqueryCheck %>\n<%= jqueryVersionCheck %>\n+function () {\n',
+ footer: '\n}();'
+ },
+ bootstrap: {
+ files: {
+ src: '<%= concat.bootstrap.dest %>'
+ }
+ }
+ },
+
+ concat: {
+ options: {
+ // Custom function to remove all export and import statements
+ process: function (src) {
+ return src.replace(/^(export|import).*/gm, '')
+ }
+ },
+ bootstrap: {
+ src: [
+ 'js/src/util.js',
+ 'js/src/alert.js',
+ 'js/src/button.js',
+ 'js/src/carousel.js',
+ 'js/src/collapse.js',
+ 'js/src/dropdown.js',
+ 'js/src/modal.js',
+ 'js/src/scrollspy.js',
+ 'js/src/tab.js',
+ 'js/src/tooltip.js',
+ 'js/src/popover.js'
+ ],
+ dest: 'dist/js/<%= pkg.name %>.js'
+ }
+ },
+
+ qunit: {
+ options: {
+ inject: 'js/tests/unit/phantom.js'
+ },
+ files: 'js/tests/index.html'
+ },
+
+ // CSS build configuration
+ copy: {
+ docs: {
+ expand: true,
+ cwd: 'dist/',
+ src: [
+ '**/*'
+ ],
+ dest: 'docs/dist/'
+ }
+ },
+
+ connect: {
+ server: {
+ options: {
+ port: 3000,
+ base: '.'
+ }
+ }
+ },
+
+ watch: {
+ src: {
+ files: '<%= concat.bootstrap.src %>',
+ tasks: ['babel:dev']
+ },
+ sass: {
+ files: 'scss/**/*.scss',
+ tasks: ['dist-css', 'docs']
+ },
+ docs: {
+ files: 'docs/assets/scss/**/*.scss',
+ tasks: ['dist-css', 'docs']
+ }
+ },
+
+ 'saucelabs-qunit': {
+ all: {
+ options: {
+ build: process.env.TRAVIS_JOB_ID,
+ concurrency: 10,
+ maxRetries: 3,
+ maxPollRetries: 4,
+ urls: ['http://127.0.0.1:3000/js/tests/index.html?hidepassed'],
+ browsers: grunt.file.readYAML('grunt/sauce_browsers.yml')
+ }
+ }
+ },
+
+ exec: {
+ 'clean-css': {
+ command: 'npm run clean-css'
+ },
+ 'clean-css-docs': {
+ command: 'npm run clean-css-docs'
+ },
+ postcss: {
+ command: 'npm run postcss'
+ },
+ 'postcss-docs': {
+ command: 'npm run postcss-docs'
+ },
+ htmlhint: {
+ command: 'npm run htmlhint'
+ },
+ htmllint: {
+ command: 'npm run htmllint'
+ },
+ jekyll: {
+ command: 'npm run jekyll'
+ },
+ 'jekyll-github': {
+ command: 'npm run jekyll-github'
+ },
+ sass: {
+ command: 'npm run sass'
+ },
+ 'sass-docs': {
+ command: 'npm run sass-docs'
+ },
+ 'scss-lint': {
+ command: 'npm run scss-lint'
+ },
+ 'scss-lint-docs': {
+ command: 'npm run scss-lint-docs'
+ },
+ uglify: {
+ command: 'npm run uglify'
+ },
+ 'uglify-docs': {
+ command: 'npm run uglify-docs'
+ }
+ },
+
+ buildcontrol: {
+ options: {
+ dir: '_gh_pages',
+ commit: true,
+ push: true,
+ message: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%'
+ },
+ pages: {
+ options: {
+ remote: 'git@github.com:twbs/derpstrap.git',
+ branch: 'gh-pages'
+ }
+ }
+ },
+
+ compress: {
+ main: {
+ options: {
+ archive: 'bootstrap-<%= pkg.version %>-dist.zip',
+ mode: 'zip',
+ level: 9,
+ pretty: true
+ },
+ files: [
+ {
+ expand: true,
+ cwd: 'dist/',
+ src: ['**'],
+ dest: 'bootstrap-<%= pkg.version %>-dist'
+ }
+ ]
+ }
+ }
+
+ })
+
+
+ // These plugins provide necessary tasks.
+ require('load-grunt-tasks')(grunt)
+ require('time-grunt')(grunt)
+
+ // Docs HTML validation task
+ grunt.registerTask('validate-html', ['exec:jekyll', 'exec:htmllint', 'exec:htmlhint'])
+
+ var runSubset = function (subset) {
+ return !process.env.TWBS_TEST || process.env.TWBS_TEST === subset
+ }
+ var isUndefOrNonZero = function (val) {
+ return val === undefined || val !== '0'
+ }
+
+ // Test task.
+ var testSubtasks = []
+ // Skip core tests if running a different subset of the test suite
+ if (runSubset('core') &&
+ // Skip core tests if this is a Savage build
+ process.env.TRAVIS_REPO_SLUG !== 'twbs-savage/bootstrap') {
+ testSubtasks = testSubtasks.concat(['dist-css', 'dist-js', 'test-scss', 'qunit', 'docs'])
+ }
+ // Skip HTML validation if running a different subset of the test suite
+ if (runSubset('validate-html') &&
+ isTravis &&
+ // Skip HTML5 validator when [skip validator] is in the commit message
+ isUndefOrNonZero(process.env.TWBS_DO_VALIDATOR)) {
+ testSubtasks.push('validate-html')
+ }
+ // Only run Sauce Labs tests if there's a Sauce access key
+ if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
+ // Skip Sauce if running a different subset of the test suite
+ runSubset('sauce-js-unit')) {
+ testSubtasks = testSubtasks.concat(['dist', 'docs-css', 'docs-js', 'clean:docs', 'copy:docs'])
+ // Skip Sauce on Travis when [skip sauce] is in the commit message
+ if (isUndefOrNonZero(process.env.TWBS_DO_SAUCE)) {
+ testSubtasks.push('connect')
+ testSubtasks.push('saucelabs-qunit')
+ }
+ }
+ grunt.registerTask('test', testSubtasks)
+
+ // JS distribution task.
+ grunt.registerTask('dist-js', ['babel:dev', 'concat', 'babel:dist', 'stamp', 'exec:uglify'])
+
+ grunt.registerTask('test-scss', ['exec:scss-lint'])
+
+ // CSS distribution task.
+ grunt.registerTask('sass-compile', ['exec:sass', 'exec:sass-docs'])
+
+ grunt.registerTask('dist-css', ['sass-compile', 'exec:postcss', 'exec:clean-css', 'exec:clean-css-docs'])
+
+ // Full distribution task.
+ grunt.registerTask('dist', ['clean:dist', 'dist-css', 'dist-js'])
+
+ // Default task.
+ grunt.registerTask('default', ['clean:dist', 'test'])
+
+ // Docs task.
+ grunt.registerTask('docs-css', ['exec:clean-css-docs', 'exec:postcss-docs'])
+ grunt.registerTask('lint-docs-css', ['exec:scss-lint-docs'])
+ grunt.registerTask('docs-js', ['exec:uglify-docs'])
+ grunt.registerTask('docs', ['lint-docs-css', 'docs-css', 'docs-js', 'clean:docs', 'copy:docs'])
+ grunt.registerTask('docs-github', ['exec:jekyll-github'])
+
+ grunt.registerTask('prep-release', ['dist', 'docs', 'docs-github', 'compress'])
+
+ // Publish to GitHub
+ grunt.registerTask('publish', ['buildcontrol:pages'])
+}
diff --git a/templates/assets/bootstrap/ISSUE_TEMPLATE.md b/templates/assets/bootstrap/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..d2a406f
--- /dev/null
+++ b/templates/assets/bootstrap/ISSUE_TEMPLATE.md
@@ -0,0 +1,22 @@
+Before opening an issue:
+
+- [Search for duplicate or closed issues](https://github.com/twbs/bootstrap/issues?utf8=%E2%9C%93&q=is%3Aissue)
+- [Validate](https://validator.w3.org/nu/) and [lint](https://github.com/twbs/bootlint#in-the-browser) any HTML to avoid common problems
+- Prepare a [reduced test case](https://css-tricks.com/reduced-test-cases/) for any bugs
+- Read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md)
+
+When asking general "how to" questions:
+
+- Please do not open an issue here
+- Instead, ask for help on [StackOverflow, IRC, or Slack](https://github.com/twbs/bootstrap/blob/master/README.md#community)
+
+When reporting a bug, include:
+
+- Operating system and version (Windows, Mac OS X, Android, iOS, Win10 Mobile)
+- Browser and version (Chrome, Firefox, Safari, IE, MS Edge, Opera 15+, Android Browser)
+- Reduced test cases and potential fixes using [JS Bin](https://jsbin.com)
+
+When suggesting a feature, include:
+
+- As much detail as possible for what we should add and why it's important to Bootstrap
+- Relevant links to prior art, screenshots, or live demos whenever possible
diff --git a/templates/assets/bootstrap/LICENSE b/templates/assets/bootstrap/LICENSE
new file mode 100644
index 0000000..1381cb2
--- /dev/null
+++ b/templates/assets/bootstrap/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2011-2017 Twitter, Inc.
+Copyright (c) 2011-2017 The Bootstrap Authors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/templates/assets/bootstrap/README.md b/templates/assets/bootstrap/README.md
new file mode 100644
index 0000000..7028798
--- /dev/null
+++ b/templates/assets/bootstrap/README.md
@@ -0,0 +1,149 @@
+<p align="center">
+ <a href="https://v4-alpha.getbootstrap.com">
+ <img src="http://v4-alpha.getbootstrap.com/assets/brand/bootstrap-solid.svg" width=72 height=72>
+ </a>
+
+ <h3 align="center">Bootstrap</h3>
+
+ <p align="center">
+ Sleek, intuitive, and powerful front-end framework for faster and easier web development.
+ <br>
+ <a href="https://v4-alpha.getbootstrap.com"><strong>Visit Bootstrap &raquo;</strong></a>
+ </p>
+</p>
+
+<br>
+
+## Table of contents
+
+- [Quick start](#quick-start)
+- [Status](#status)
+- [What's included](#whats-included)
+- [Bugs and feature requests](#bugs-and-feature-requests)
+- [Documentation](#documentation)
+- [Contributing](#contributing)
+- [Community](#community)
+- [Versioning](#versioning)
+- [Creators](#creators)
+- [Copyright and license](#copyright-and-license)
+
+## Quick start
+
+Several quick start options are available:
+
+- [Download the latest release.](https://github.com/twbs/bootstrap/archive/v4.0.0-alpha.6.zip)
+- Clone the repo: `git clone https://github.com/twbs/bootstrap.git`
+- Install with [npm](https://www.npmjs.com): `npm install bootstrap@4.0.0-alpha.6`
+- Install with [yarn](https://github.com/yarnpkg/yarn): `yarn add bootstrap@4.0.0-alpha.6`
+- Install with [Composer](https://getcomposer.org): `composer require twbs/bootstrap:4.0.0-alpha.6`
+- Install with [Bower](https://bower.io): `bower install bootstrap#v4.0.0-alpha.6`
+- Install with [NuGet](https://www.nuget.org): CSS: `Install-Package bootstrap -Pre` Sass: `Install-Package bootstrap.sass -Pre` (`-Pre` is only required until Bootstrap v4 has a stable release).
+
+Read the [Getting started page](https://getbootstrap.com/getting-started/) for information on the framework contents, templates and examples, and more.
+
+## Status
+
+[![Slack](https://bootstrap-slack.herokuapp.com/badge.svg)](https://bootstrap-slack.herokuapp.com)
+![Bower version](https://img.shields.io/bower/v/bootstrap.svg)
+[![npm version](https://img.shields.io/npm/v/bootstrap.svg)](https://www.npmjs.com/package/bootstrap)
+[![Gem version](https://img.shields.io/gem/v/bootstrap.svg)](https://rubygems.org/gems/bootstrap)
+[![Build Status](https://img.shields.io/travis/twbs/bootstrap/v4-dev.svg)](https://travis-ci.org/twbs/bootstrap)
+[![devDependency Status](https://img.shields.io/david/dev/twbs/bootstrap.svg)](https://david-dm.org/twbs/bootstrap?type=dev)
+[![Meteor Atmosphere](https://img.shields.io/badge/meteor-twbs%3Abootstrap-blue.svg)](https://atmospherejs.com/twbs/bootstrap)
+[![Packagist Prerelease](https://img.shields.io/packagist/vpre/twbs/bootstrap.svg)](https://packagist.org/packages/twbs/bootstrap)
+[![NuGet](https://img.shields.io/nuget/vpre/bootstrap.svg)](https://www.nuget.org/packages/bootstrap/4.0.0-alpha5)
+
+[![Selenium Test Status](https://saucelabs.com/browser-matrix/bootstrap.svg)](https://saucelabs.com/u/bootstrap)
+
+## What's included
+
+Within the download you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations. You'll see something like this:
+
+```
+bootstrap/
+├── css/
+│ ├── bootstrap.css
+│ ├── bootstrap.css.map
+│ ├── bootstrap.min.css
+│ └── bootstrap.min.css.map
+└── js/
+ ├── bootstrap.js
+ └── bootstrap.min.js
+```
+
+We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). CSS [source maps](https://developers.google.com/web/tools/chrome-devtools/debug/readability/source-maps) (`bootstrap.*.map`) are available for use with certain browsers' developer tools.
+
+
+## Bugs and feature requests
+
+Have a bug or a feature request? Please first read the [issue guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md#using-the-issue-tracker) and search for existing and closed issues. If your problem or idea is not addressed yet, [please open a new issue](https://github.com/twbs/bootstrap/issues/new).
+
+
+## Documentation
+
+Bootstrap's documentation, included in this repo in the root directory, is built with [Jekyll](https://jekyllrb.com) and publicly hosted on GitHub Pages at <https://getbootstrap.com>. The docs may also be run locally.
+
+### Running documentation locally
+
+1. Run through the [tooling setup](https://github.com/twbs/bootstrap/blob/v4-dev/docs/getting-started/build-tools.md#tooling-setup) to install Jekyll (the site builder) and other Ruby dependencies with `bundle install`.
+2. Run `grunt` (or a specific set of Grunt tasks) to rebuild distributed CSS and JavaScript files, as well as our docs assets.
+3. From the root `/bootstrap` directory, run `bundle exec jekyll serve` in the command line.
+4. Open <http://localhost:9001> in your browser, and voilà.
+
+Learn more about using Jekyll by reading its [documentation](https://jekyllrb.com/docs/home/).
+
+### Documentation for previous releases
+
+Documentation for v2.3.2 has been made available for the time being at <https://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.
+
+
+
+## Contributing
+
+Please read through our [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development.
+
+Moreover, if your pull request contains JavaScript patches or features, you must include [relevant unit tests](https://github.com/twbs/bootstrap/tree/master/js/tests). All HTML and CSS should conform to the [Code Guide](https://github.com/mdo/code-guide), maintained by [Mark Otto](https://github.com/mdo).
+
+Editor preferences are available in the [editor config](https://github.com/twbs/bootstrap/blob/master/.editorconfig) for easy use in common text editors. Read more and download plugins at <http://editorconfig.org>.
+
+
+
+## Community
+
+Get updates on Bootstrap's development and chat with the project maintainers and community members.
+
+- Follow [@getbootstrap on Twitter](https://twitter.com/getbootstrap).
+- Read and subscribe to [The Official Bootstrap Blog](https://blog.getbootstrap.com).
+- Join [the official Slack room](https://bootstrap-slack.herokuapp.com).
+- Chat with fellow Bootstrappers in IRC. On the `irc.freenode.net` server, in the `##bootstrap` channel.
+- Implementation help may be found at Stack Overflow (tagged [`bootstrap-4`](https://stackoverflow.com/questions/tagged/bootstrap-4)).
+- Developers should use the keyword `bootstrap` on packages which modify or add to the functionality of Bootstrap when distributing through [npm](https://www.npmjs.com/browse/keyword/bootstrap) or similar delivery mechanisms for maximum discoverability.
+
+
+
+## Versioning
+
+For transparency into our release cycle and in striving to maintain backward compatibility, Bootstrap is maintained under [the Semantic Versioning guidelines](http://semver.org/). Sometimes we screw up, but we'll adhere to those rules whenever possible.
+
+See [the Releases section of our GitHub project](https://github.com/twbs/bootstrap/releases) for changelogs for each release version of Bootstrap. Release announcement posts on [the official Bootstrap blog](https://blog.getbootstrap.com) contain summaries of the most noteworthy changes made in each release.
+
+
+## Creators
+
+**Mark Otto**
+
+- <https://twitter.com/mdo>
+- <https://github.com/mdo>
+
+**Jacob Thornton**
+
+- <https://twitter.com/fat>
+- <https://github.com/fat>
+
+
+
+## Copyright and license
+
+Code and documentation copyright 2011-2017 the [Bootstrap Authors](https://github.com/twbs/bootstrap/graphs/contributors) and [Twitter, Inc.](https://twitter.com) Code released under the [MIT License](https://github.com/twbs/bootstrap/blob/master/LICENSE). Docs released under [Creative Commons](https://github.com/twbs/bootstrap/blob/master/docs/LICENSE).
diff --git a/templates/assets/bootstrap/bower.json b/templates/assets/bootstrap/bower.json
new file mode 100644
index 0000000..5107709
--- /dev/null
+++ b/templates/assets/bootstrap/bower.json
@@ -0,0 +1,35 @@
+{
+ "name": "bootstrap",
+ "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
+ "keywords": [
+ "css",
+ "js",
+ "sass",
+ "mobile-first",
+ "responsive",
+ "front-end",
+ "framework",
+ "web"
+ ],
+ "homepage": "https://getbootstrap.com",
+ "license": "MIT",
+ "moduleType": "globals",
+ "main": [
+ "scss/bootstrap.scss",
+ "dist/js/bootstrap.js"
+ ],
+ "ignore": [
+ "/.*",
+ "_config.yml",
+ "CNAME",
+ "composer.json",
+ "CONTRIBUTING.md",
+ "docs",
+ "js/tests",
+ "test-infra"
+ ],
+ "dependencies": {
+ "jquery": ">=1.9.1",
+ "tether": "^1.4.0"
+ }
+}
diff --git a/templates/assets/bootstrap/grunt/change-version.js b/templates/assets/bootstrap/grunt/change-version.js
new file mode 100755
index 0000000..5ea5918
--- /dev/null
+++ b/templates/assets/bootstrap/grunt/change-version.js
@@ -0,0 +1,110 @@
+#!/usr/bin/env node
+
+'use strict'
+
+/*!
+ * Script to update version number references in the project.
+ * Copyright 2017 The Bootstrap Authors
+ * Copyright 2017 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+/* global Set */
+
+var fs = require('fs')
+var path = require('path')
+var sh = require('shelljs')
+sh.config.fatal = true
+var sed = sh.sed
+
+// Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37
+RegExp.quote = function (string) {
+ return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&')
+}
+RegExp.quoteReplacement = function (string) {
+ return string.replace(/[$]/g, '$$')
+}
+
+var DRY_RUN = false
+
+function walkAsync(directory, excludedDirectories, fileCallback, errback) {
+ if (excludedDirectories.has(path.parse(directory).base)) {
+ return
+ }
+ fs.readdir(directory, function (err, names) {
+ if (err) {
+ errback(err)
+ return
+ }
+ names.forEach(function (name) {
+ var filepath = path.join(directory, name)
+ fs.lstat(filepath, function (err, stats) {
+ if (err) {
+ process.nextTick(errback, err)
+ return
+ }
+ if (stats.isSymbolicLink()) {
+ return
+ }
+ else if (stats.isDirectory()) {
+ process.nextTick(walkAsync, filepath, excludedDirectories, fileCallback, errback)
+ }
+ else if (stats.isFile()) {
+ process.nextTick(fileCallback, filepath)
+ }
+ })
+ })
+ })
+}
+
+function replaceRecursively(directory, excludedDirectories, allowedExtensions, original, replacement) {
+ original = new RegExp(RegExp.quote(original), 'g')
+ replacement = RegExp.quoteReplacement(replacement)
+ var updateFile = !DRY_RUN ? function (filepath) {
+ if (allowedExtensions.has(path.parse(filepath).ext)) {
+ sed('-i', original, replacement, filepath)
+ }
+ } : function (filepath) {
+ if (allowedExtensions.has(path.parse(filepath).ext)) {
+ console.log('FILE: ' + filepath)
+ }
+ else {
+ console.log('EXCLUDED:' + filepath)
+ }
+ }
+ walkAsync(directory, excludedDirectories, updateFile, function (err) {
+ console.error('ERROR while traversing directory!:')
+ console.error(err)
+ process.exit(1)
+ })
+}
+
+function main(args) {
+ if (args.length !== 2) {
+ console.error('USAGE: change-version old_version new_version')
+ console.error('Got arguments:', args)
+ process.exit(1)
+ }
+ var oldVersion = args[0]
+ var newVersion = args[1]
+ var EXCLUDED_DIRS = new Set([
+ '.git',
+ 'node_modules',
+ 'vendor'
+ ])
+ var INCLUDED_EXTENSIONS = new Set([
+ // This extension whitelist is how we avoid modifying binary files
+ '',
+ '.css',
+ '.html',
+ '.js',
+ '.json',
+ '.md',
+ '.scss',
+ '.txt',
+ '.yml'
+ ])
+ replaceRecursively('.', EXCLUDED_DIRS, INCLUDED_EXTENSIONS, oldVersion, newVersion)
+}
+
+main(process.argv.slice(2))
diff --git a/templates/assets/bootstrap/grunt/gcp-key.json.enc b/templates/assets/bootstrap/grunt/gcp-key.json.enc
new file mode 100644
index 0000000..6e1856a
--- /dev/null
+++ b/templates/assets/bootstrap/grunt/gcp-key.json.enc
Binary files differ
diff --git a/templates/assets/bootstrap/grunt/npm-shrinkwrap.json b/templates/assets/bootstrap/grunt/npm-shrinkwrap.json
new file mode 100644
index 0000000..f35e330
--- /dev/null
+++ b/templates/assets/bootstrap/grunt/npm-shrinkwrap.json
@@ -0,0 +1,4164 @@
+{
+ "name": "bootstrap",
+ "version": "4.0.0-alpha.6",
+ "dependencies": {
+ "abbrev": {
+ "version": "1.1.0",
+ "from": "abbrev@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
+ "dev": true
+ },
+ "accepts": {
+ "version": "1.3.3",
+ "from": "accepts@>=1.3.3 <1.4.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
+ "dev": true
+ },
+ "acorn": {
+ "version": "4.0.4",
+ "from": "acorn@4.0.4",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.4.tgz",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "3.0.1",
+ "from": "acorn-jsx@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+ "dev": true,
+ "dependencies": {
+ "acorn": {
+ "version": "3.3.0",
+ "from": "acorn@>=3.0.4 <4.0.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "agent-base": {
+ "version": "2.0.1",
+ "from": "agent-base@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz",
+ "dev": true,
+ "dependencies": {
+ "semver": {
+ "version": "5.0.3",
+ "from": "semver@>=5.0.1 <5.1.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
+ "dev": true
+ }
+ }
+ },
+ "ajv": {
+ "version": "4.11.5",
+ "from": "ajv@>=4.7.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.5.tgz",
+ "dev": true
+ },
+ "ajv-keywords": {
+ "version": "1.5.1",
+ "from": "ajv-keywords@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
+ "dev": true
+ },
+ "align-text": {
+ "version": "0.1.4",
+ "from": "align-text@>=0.1.3 <0.2.0",
+ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "1.4.0",
+ "from": "ansi-escapes@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "from": "ansi-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "from": "ansi-styles@>=2.2.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "dev": true
+ },
+ "any-promise": {
+ "version": "1.3.0",
+ "from": "any-promise@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "dev": true
+ },
+ "anymatch": {
+ "version": "1.3.0",
+ "from": "anymatch@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz",
+ "dev": true
+ },
+ "aproba": {
+ "version": "1.1.1",
+ "from": "aproba@>=1.0.3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz",
+ "dev": true
+ },
+ "archiver": {
+ "version": "1.3.0",
+ "from": "archiver@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "async": {
+ "version": "2.1.5",
+ "from": "async@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz",
+ "dev": true
+ }
+ }
+ },
+ "archiver-utils": {
+ "version": "1.3.0",
+ "from": "archiver-utils@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz",
+ "dev": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.2",
+ "from": "are-we-there-yet@>=1.1.2 <1.2.0",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz",
+ "dev": true
+ },
+ "argparse": {
+ "version": "1.0.9",
+ "from": "argparse@>=1.0.7 <2.0.0",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
+ "dev": true
+ },
+ "arr-diff": {
+ "version": "2.0.0",
+ "from": "arr-diff@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+ "dev": true
+ },
+ "arr-flatten": {
+ "version": "1.0.1",
+ "from": "arr-flatten@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.1.tgz",
+ "dev": true
+ },
+ "array-differ": {
+ "version": "1.0.0",
+ "from": "array-differ@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
+ "dev": true
+ },
+ "array-find-index": {
+ "version": "1.0.2",
+ "from": "array-find-index@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "dev": true
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "from": "array-union@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "dev": true
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "from": "array-uniq@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.2.1",
+ "from": "array-unique@>=0.2.1 <0.3.0",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+ "dev": true
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "from": "arrify@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "dev": true
+ },
+ "asap": {
+ "version": "2.0.5",
+ "from": "asap@>=2.0.3 <2.1.0",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.5.tgz",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "from": "asn1@>=0.2.3 <0.3.0",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "dev": true
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "from": "assert-plus@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "dev": true
+ },
+ "async": {
+ "version": "1.5.2",
+ "from": "async@>=1.5.2 <1.6.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "dev": true
+ },
+ "async-each": {
+ "version": "1.0.1",
+ "from": "async-each@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+ "dev": true
+ },
+ "async-foreach": {
+ "version": "0.1.3",
+ "from": "async-foreach@>=0.1.3 <0.2.0",
+ "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "from": "asynckit@>=0.4.0 <0.5.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "dev": true
+ },
+ "autoprefixer": {
+ "version": "6.7.7",
+ "from": "autoprefixer@>=6.7.7 <7.0.0",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "from": "aws-sign2@>=0.6.0 <0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.6.0",
+ "from": "aws4@>=1.2.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "dev": true
+ },
+ "babel-code-frame": {
+ "version": "6.22.0",
+ "from": "babel-code-frame@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-core": {
+ "version": "6.24.0",
+ "from": "babel-core@>=6.0.12 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.24.0.tgz",
+ "dev": true
+ },
+ "babel-eslint": {
+ "version": "7.1.1",
+ "from": "babel-eslint@>=7.1.1 <8.0.0",
+ "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.1.1.tgz",
+ "dev": true
+ },
+ "babel-generator": {
+ "version": "6.24.0",
+ "from": "babel-generator@>=6.24.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.24.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "jsesc": {
+ "version": "1.3.0",
+ "from": "jsesc@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "babel-helper-call-delegate": {
+ "version": "6.22.0",
+ "from": "babel-helper-call-delegate@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-helper-define-map": {
+ "version": "6.23.0",
+ "from": "babel-helper-define-map@>=6.23.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-helper-function-name": {
+ "version": "6.23.0",
+ "from": "babel-helper-function-name@>=6.23.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-helper-get-function-arity": {
+ "version": "6.22.0",
+ "from": "babel-helper-get-function-arity@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-helper-hoist-variables": {
+ "version": "6.22.0",
+ "from": "babel-helper-hoist-variables@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-helper-optimise-call-expression": {
+ "version": "6.23.0",
+ "from": "babel-helper-optimise-call-expression@>=6.23.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-helper-regex": {
+ "version": "6.22.0",
+ "from": "babel-helper-regex@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-helper-replace-supers": {
+ "version": "6.23.0",
+ "from": "babel-helper-replace-supers@>=6.23.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-helpers": {
+ "version": "6.23.0",
+ "from": "babel-helpers@>=6.23.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-messages": {
+ "version": "6.23.0",
+ "from": "babel-messages@>=6.23.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-check-es2015-constants": {
+ "version": "6.22.0",
+ "from": "babel-plugin-check-es2015-constants@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-arrow-functions": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-arrow-functions@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-block-scoped-functions": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-block-scoped-functions@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-block-scoping": {
+ "version": "6.23.0",
+ "from": "babel-plugin-transform-es2015-block-scoping@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-classes": {
+ "version": "6.23.0",
+ "from": "babel-plugin-transform-es2015-classes@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-computed-properties": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-computed-properties@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-destructuring": {
+ "version": "6.23.0",
+ "from": "babel-plugin-transform-es2015-destructuring@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-duplicate-keys": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-duplicate-keys@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-for-of": {
+ "version": "6.23.0",
+ "from": "babel-plugin-transform-es2015-for-of@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-function-name": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-function-name@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-literals": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-literals@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-modules-amd": {
+ "version": "6.24.0",
+ "from": "babel-plugin-transform-es2015-modules-amd@>=6.24.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-modules-commonjs": {
+ "version": "6.24.0",
+ "from": "babel-plugin-transform-es2015-modules-commonjs@>=6.24.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-modules-strip": {
+ "version": "0.1.0",
+ "from": "babel-plugin-transform-es2015-modules-strip@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-strip/-/babel-plugin-transform-es2015-modules-strip-0.1.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-modules-systemjs": {
+ "version": "6.23.0",
+ "from": "babel-plugin-transform-es2015-modules-systemjs@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-modules-umd": {
+ "version": "6.24.0",
+ "from": "babel-plugin-transform-es2015-modules-umd@>=6.24.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-object-super": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-object-super@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-parameters": {
+ "version": "6.23.0",
+ "from": "babel-plugin-transform-es2015-parameters@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-shorthand-properties": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-shorthand-properties@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-spread": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-spread@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-sticky-regex": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-sticky-regex@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-template-literals": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-template-literals@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-typeof-symbol": {
+ "version": "6.23.0",
+ "from": "babel-plugin-transform-es2015-typeof-symbol@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-unicode-regex": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-es2015-unicode-regex@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-regenerator": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-regenerator@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-plugin-transform-strict-mode": {
+ "version": "6.22.0",
+ "from": "babel-plugin-transform-strict-mode@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.22.0.tgz",
+ "dev": true
+ },
+ "babel-preset-es2015": {
+ "version": "6.24.0",
+ "from": "babel-preset-es2015@>=6.24.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.0.tgz",
+ "dev": true
+ },
+ "babel-register": {
+ "version": "6.24.0",
+ "from": "babel-register@>=6.24.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.0.tgz",
+ "dev": true
+ },
+ "babel-runtime": {
+ "version": "6.23.0",
+ "from": "babel-runtime@>=6.22.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-template": {
+ "version": "6.23.0",
+ "from": "babel-template@>=6.23.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.23.0.tgz",
+ "dev": true
+ },
+ "babel-traverse": {
+ "version": "6.23.1",
+ "from": "babel-traverse@>=6.15.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.23.1.tgz",
+ "dev": true
+ },
+ "babel-types": {
+ "version": "6.23.0",
+ "from": "babel-types@>=6.15.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.23.0.tgz",
+ "dev": true
+ },
+ "babylon": {
+ "version": "6.16.1",
+ "from": "babylon@>=6.13.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.16.1.tgz",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "0.4.2",
+ "from": "balanced-match@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "dev": true
+ },
+ "basic-auth": {
+ "version": "1.1.0",
+ "from": "basic-auth@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz",
+ "dev": true
+ },
+ "batch": {
+ "version": "0.5.3",
+ "from": "batch@0.5.3",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.5.3.tgz",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "from": "bcrypt-pbkdf@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "dev": true,
+ "optional": true
+ },
+ "binary-extensions": {
+ "version": "1.8.0",
+ "from": "binary-extensions@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.8.0.tgz",
+ "dev": true
+ },
+ "bl": {
+ "version": "1.2.0",
+ "from": "bl@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.0.tgz",
+ "dev": true
+ },
+ "block-stream": {
+ "version": "0.0.9",
+ "from": "block-stream@*",
+ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+ "dev": true
+ },
+ "bluebird": {
+ "version": "3.5.0",
+ "from": "bluebird@>=3.0.6 <4.0.0",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
+ "dev": true
+ },
+ "body-parser": {
+ "version": "1.14.2",
+ "from": "body-parser@>=1.14.0 <1.15.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz",
+ "dev": true,
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.2.0 <2.3.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.3.1",
+ "from": "http-errors@>=1.3.1 <1.4.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.13",
+ "from": "iconv-lite@0.4.13",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
+ "dev": true
+ },
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+ "dev": true
+ },
+ "qs": {
+ "version": "5.2.0",
+ "from": "qs@5.2.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "boom": {
+ "version": "2.10.1",
+ "from": "boom@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.6",
+ "from": "brace-expansion@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz",
+ "dev": true
+ },
+ "braces": {
+ "version": "1.8.5",
+ "from": "braces@>=1.8.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+ "dev": true
+ },
+ "browserslist": {
+ "version": "1.7.6",
+ "from": "browserslist@>=1.7.6 <2.0.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.6.tgz",
+ "dev": true
+ },
+ "buffer-crc32": {
+ "version": "0.2.13",
+ "from": "buffer-crc32@>=0.2.1 <0.3.0",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "dev": true
+ },
+ "buffer-shims": {
+ "version": "1.0.0",
+ "from": "buffer-shims@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
+ "dev": true
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "from": "builtin-modules@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "dev": true
+ },
+ "bulk-require": {
+ "version": "1.0.0",
+ "from": "bulk-require@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/bulk-require/-/bulk-require-1.0.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "glob": {
+ "version": "3.2.11",
+ "from": "glob@>=3.2.7 <3.3.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "0.3.0",
+ "from": "minimatch@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "bytes": {
+ "version": "2.2.0",
+ "from": "bytes@2.2.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz",
+ "dev": true
+ },
+ "caller-path": {
+ "version": "0.1.0",
+ "from": "caller-path@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+ "dev": true
+ },
+ "callsites": {
+ "version": "0.2.0",
+ "from": "callsites@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "2.1.1",
+ "from": "camelcase@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "2.1.0",
+ "from": "camelcase-keys@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "dev": true
+ },
+ "caniuse-db": {
+ "version": "1.0.30000637",
+ "from": "caniuse-db@>=1.0.30000634 <2.0.0",
+ "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000637.tgz",
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "from": "caseless@>=0.11.0 <0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+ "dev": true
+ },
+ "center-align": {
+ "version": "0.1.3",
+ "from": "center-align@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "from": "chalk@>=1.1.3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "dev": true,
+ "dependencies": {
+ "supports-color": {
+ "version": "2.0.0",
+ "from": "supports-color@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "chokidar": {
+ "version": "1.6.1",
+ "from": "chokidar@>=1.6.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz",
+ "dev": true
+ },
+ "circular-json": {
+ "version": "0.3.1",
+ "from": "circular-json@>=0.3.1 <0.4.0",
+ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz",
+ "dev": true
+ },
+ "cjson": {
+ "version": "0.5.0",
+ "from": "cjson@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.5.0.tgz",
+ "dev": true
+ },
+ "clean-css": {
+ "version": "4.0.9",
+ "from": "clean-css@>=4.0.9 <5.0.0",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.0.9.tgz",
+ "dev": true
+ },
+ "clean-css-cli": {
+ "version": "4.0.9",
+ "from": "clean-css-cli@>=4.0.9 <5.0.0",
+ "resolved": "https://registry.npmjs.org/clean-css-cli/-/clean-css-cli-4.0.9.tgz",
+ "dev": true
+ },
+ "cli": {
+ "version": "0.6.6",
+ "from": "cli@>=0.6.0 <0.7.0",
+ "resolved": "https://registry.npmjs.org/cli/-/cli-0.6.6.tgz",
+ "dev": true,
+ "dependencies": {
+ "glob": {
+ "version": "3.2.11",
+ "from": "glob@>=3.2.1 <3.3.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "0.3.0",
+ "from": "minimatch@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "cli-cursor": {
+ "version": "1.0.2",
+ "from": "cli-cursor@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+ "dev": true
+ },
+ "cli-spinners": {
+ "version": "1.0.0",
+ "from": "cli-spinners@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.0.0.tgz",
+ "dev": true
+ },
+ "cli-width": {
+ "version": "2.1.0",
+ "from": "cli-width@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz",
+ "dev": true
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "from": "cliui@>=3.2.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "dev": true
+ },
+ "co": {
+ "version": "4.6.0",
+ "from": "co@>=4.6.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "dev": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "from": "code-point-at@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "dev": true
+ },
+ "coffee-script": {
+ "version": "1.10.0",
+ "from": "coffee-script@>=1.10.0 <1.11.0",
+ "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.10.0.tgz",
+ "dev": true
+ },
+ "colors": {
+ "version": "1.1.2",
+ "from": "colors@>=1.1.2 <1.2.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "from": "combined-stream@>=1.0.5 <1.1.0",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.9.0",
+ "from": "commander@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
+ "dev": true
+ },
+ "compress-commons": {
+ "version": "1.2.0",
+ "from": "compress-commons@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.0.tgz",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "from": "concat-map@0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.0",
+ "from": "concat-stream@>=1.5.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
+ "dev": true
+ },
+ "connect": {
+ "version": "3.6.0",
+ "from": "connect@>=3.4.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "debug": {
+ "version": "2.6.1",
+ "from": "debug@2.6.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz",
+ "dev": true
+ }
+ }
+ },
+ "connect-livereload": {
+ "version": "0.5.4",
+ "from": "connect-livereload@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.5.4.tgz",
+ "dev": true
+ },
+ "console-browserify": {
+ "version": "1.1.0",
+ "from": "console-browserify@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+ "dev": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "from": "console-control-strings@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "dev": true
+ },
+ "content-type": {
+ "version": "1.0.2",
+ "from": "content-type@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.4.0",
+ "from": "convert-source-map@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.4.0.tgz",
+ "dev": true
+ },
+ "core-js": {
+ "version": "2.4.1",
+ "from": "core-js@>=2.4.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "from": "core-util-is@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "dev": true
+ },
+ "cosmiconfig": {
+ "version": "2.1.1",
+ "from": "cosmiconfig@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.1.1.tgz",
+ "dev": true,
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "from": "minimist@>=1.2.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "crc": {
+ "version": "3.4.4",
+ "from": "crc@>=3.4.4 <4.0.0",
+ "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz",
+ "dev": true
+ },
+ "crc32-stream": {
+ "version": "2.0.0",
+ "from": "crc32-stream@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "3.0.1",
+ "from": "cross-spawn@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": {
+ "version": "4.0.2",
+ "from": "lru-cache@>=4.0.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz",
+ "dev": true
+ }
+ }
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "from": "cryptiles@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "dev": true
+ },
+ "csslint": {
+ "version": "0.10.0",
+ "from": "csslint@0.10.0",
+ "resolved": "https://registry.npmjs.org/csslint/-/csslint-0.10.0.tgz",
+ "dev": true
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "from": "currently-unhandled@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "dev": true
+ },
+ "d": {
+ "version": "1.0.0",
+ "from": "d@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+ "dev": true
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "from": "dashdash@>=1.12.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "dev": true,
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "from": "assert-plus@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "date-now": {
+ "version": "0.1.4",
+ "from": "date-now@>=0.1.4 <0.2.0",
+ "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+ "dev": true
+ },
+ "date-time": {
+ "version": "1.1.0",
+ "from": "date-time@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/date-time/-/date-time-1.1.0.tgz",
+ "dev": true
+ },
+ "dateformat": {
+ "version": "1.0.12",
+ "from": "dateformat@>=1.0.12 <1.1.0",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.3",
+ "from": "debug@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.3.tgz",
+ "dev": true
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "from": "decamelize@>=1.1.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "dev": true
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "from": "deep-is@>=0.1.3 <0.2.0",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "dev": true
+ },
+ "del": {
+ "version": "2.2.2",
+ "from": "del@>=2.0.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+ "dev": true
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "from": "delayed-stream@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "dev": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "from": "delegates@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "dev": true
+ },
+ "depd": {
+ "version": "1.1.0",
+ "from": "depd@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
+ "dev": true
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "from": "destroy@>=1.0.4 <1.1.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "dev": true
+ },
+ "detect-file": {
+ "version": "0.1.0",
+ "from": "detect-file@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz",
+ "dev": true
+ },
+ "detect-indent": {
+ "version": "4.0.0",
+ "from": "detect-indent@>=4.0.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+ "dev": true
+ },
+ "doctrine": {
+ "version": "2.0.0",
+ "from": "doctrine@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz",
+ "dev": true
+ },
+ "dom-serializer": {
+ "version": "0.1.0",
+ "from": "dom-serializer@>=0.0.0 <1.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": {
+ "version": "1.1.3",
+ "from": "domelementtype@>=1.1.1 <1.2.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+ "dev": true
+ },
+ "entities": {
+ "version": "1.1.1",
+ "from": "entities@>=1.1.1 <1.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
+ "dev": true
+ }
+ }
+ },
+ "domelementtype": {
+ "version": "1.3.0",
+ "from": "domelementtype@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
+ "dev": true
+ },
+ "domhandler": {
+ "version": "2.3.0",
+ "from": "domhandler@>=2.3.0 <2.4.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+ "dev": true
+ },
+ "domutils": {
+ "version": "1.5.1",
+ "from": "domutils@>=1.5.0 <1.6.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+ "dev": true
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "from": "ecc-jsbn@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "dev": true,
+ "optional": true
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "from": "ee-first@1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "dev": true
+ },
+ "electron-to-chromium": {
+ "version": "1.2.7",
+ "from": "electron-to-chromium@>=1.2.5 <2.0.0",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.2.7.tgz",
+ "dev": true
+ },
+ "encodeurl": {
+ "version": "1.0.1",
+ "from": "encodeurl@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+ "dev": true
+ },
+ "end-of-stream": {
+ "version": "1.4.0",
+ "from": "end-of-stream@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz",
+ "dev": true
+ },
+ "entities": {
+ "version": "1.0.0",
+ "from": "entities@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+ "dev": true
+ },
+ "error-ex": {
+ "version": "1.3.1",
+ "from": "error-ex@>=1.2.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+ "dev": true
+ },
+ "es5-ext": {
+ "version": "0.10.14",
+ "from": "es5-ext@>=0.10.14 <0.11.0",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.14.tgz",
+ "dev": true
+ },
+ "es6-iterator": {
+ "version": "2.0.1",
+ "from": "es6-iterator@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
+ "dev": true
+ },
+ "es6-map": {
+ "version": "0.1.5",
+ "from": "es6-map@>=0.1.3 <0.2.0",
+ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+ "dev": true
+ },
+ "es6-object-assign": {
+ "version": "1.1.0",
+ "from": "es6-object-assign@>=1.0.3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
+ "dev": true
+ },
+ "es6-promise": {
+ "version": "4.0.5",
+ "from": "es6-promise@>=4.0.3 <4.1.0",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz",
+ "dev": true
+ },
+ "es6-set": {
+ "version": "0.1.5",
+ "from": "es6-set@>=0.1.5 <0.2.0",
+ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
+ "dev": true
+ },
+ "es6-symbol": {
+ "version": "3.1.1",
+ "from": "es6-symbol@>=3.1.1 <3.2.0",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+ "dev": true
+ },
+ "es6-weak-map": {
+ "version": "2.0.2",
+ "from": "es6-weak-map@>=2.0.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+ "dev": true
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "from": "escape-html@>=1.0.3 <1.1.0",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "from": "escape-string-regexp@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "dev": true
+ },
+ "escope": {
+ "version": "3.6.0",
+ "from": "escope@>=3.6.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
+ "dev": true
+ },
+ "eslint": {
+ "version": "3.18.0",
+ "from": "eslint@>=3.18.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.18.0.tgz",
+ "dev": true
+ },
+ "espree": {
+ "version": "3.4.0",
+ "from": "espree@>=3.4.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.4.0.tgz",
+ "dev": true
+ },
+ "esprima": {
+ "version": "3.1.3",
+ "from": "esprima@>=3.1.1 <4.0.0",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.0.0",
+ "from": "esquery@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
+ "dev": true
+ },
+ "esrecurse": {
+ "version": "4.1.0",
+ "from": "esrecurse@>=4.1.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "estraverse": {
+ "version": "4.1.1",
+ "from": "estraverse@>=4.1.0 <4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz",
+ "dev": true
+ }
+ }
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "from": "estraverse@>=4.2.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "from": "esutils@>=2.0.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "dev": true
+ },
+ "etag": {
+ "version": "1.8.0",
+ "from": "etag@>=1.8.0 <1.9.0",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz",
+ "dev": true
+ },
+ "event-emitter": {
+ "version": "0.3.5",
+ "from": "event-emitter@>=0.3.5 <0.4.0",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "dev": true
+ },
+ "eventemitter2": {
+ "version": "0.4.14",
+ "from": "eventemitter2@>=0.4.13 <0.5.0",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+ "dev": true
+ },
+ "exit": {
+ "version": "0.1.2",
+ "from": "exit@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "dev": true
+ },
+ "exit-hook": {
+ "version": "1.1.1",
+ "from": "exit-hook@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
+ "dev": true
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "from": "expand-brackets@>=0.1.4 <0.2.0",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+ "dev": true
+ },
+ "expand-range": {
+ "version": "1.8.2",
+ "from": "expand-range@>=1.8.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+ "dev": true
+ },
+ "expand-tilde": {
+ "version": "1.2.2",
+ "from": "expand-tilde@>=1.2.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
+ "dev": true
+ },
+ "extend": {
+ "version": "3.0.0",
+ "from": "extend@>=3.0.0 <3.1.0",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz",
+ "dev": true
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "from": "extglob@>=0.3.1 <0.4.0",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+ "dev": true
+ },
+ "extract-zip": {
+ "version": "1.5.0",
+ "from": "extract-zip@>=1.5.0 <1.6.0",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.5.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "concat-stream": {
+ "version": "1.5.0",
+ "from": "concat-stream@1.5.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.0.tgz",
+ "dev": true
+ },
+ "debug": {
+ "version": "0.7.4",
+ "from": "debug@0.7.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.0",
+ "from": "mkdirp@0.5.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.0.6",
+ "from": "readable-stream@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
+ "dev": true
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.0.2",
+ "from": "extsprintf@1.0.2",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "from": "fast-levenshtein@>=2.0.4 <2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "dev": true
+ },
+ "faye-websocket": {
+ "version": "0.10.0",
+ "from": "faye-websocket@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
+ "dev": true
+ },
+ "fd-slicer": {
+ "version": "1.0.1",
+ "from": "fd-slicer@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+ "dev": true
+ },
+ "fg-lodash": {
+ "version": "0.0.2",
+ "from": "fg-lodash@0.0.2",
+ "resolved": "https://registry.npmjs.org/fg-lodash/-/fg-lodash-0.0.2.tgz",
+ "dev": true,
+ "dependencies": {
+ "lodash": {
+ "version": "2.4.2",
+ "from": "lodash@>=2.4.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
+ "dev": true
+ },
+ "underscore.string": {
+ "version": "2.3.3",
+ "from": "underscore.string@>=2.3.3 <2.4.0",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
+ "dev": true
+ }
+ }
+ },
+ "figures": {
+ "version": "1.7.0",
+ "from": "figures@>=1.3.5 <2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "dev": true
+ },
+ "file-entry-cache": {
+ "version": "2.0.0",
+ "from": "file-entry-cache@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+ "dev": true
+ },
+ "file-sync-cmp": {
+ "version": "0.1.1",
+ "from": "file-sync-cmp@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz",
+ "dev": true
+ },
+ "filename-regex": {
+ "version": "2.0.0",
+ "from": "filename-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.0.tgz",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "2.2.3",
+ "from": "fill-range@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
+ "dev": true
+ },
+ "finalhandler": {
+ "version": "1.0.0",
+ "from": "finalhandler@1.0.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "debug": {
+ "version": "2.6.1",
+ "from": "debug@2.6.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz",
+ "dev": true
+ }
+ }
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "from": "find-up@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "dev": true
+ },
+ "findup-sync": {
+ "version": "0.3.0",
+ "from": "findup-sync@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "glob": {
+ "version": "5.0.15",
+ "from": "glob@>=5.0.0 <5.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "dev": true
+ }
+ }
+ },
+ "fined": {
+ "version": "1.0.2",
+ "from": "fined@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-1.0.2.tgz",
+ "dev": true
+ },
+ "flagged-respawn": {
+ "version": "0.3.2",
+ "from": "flagged-respawn@>=0.3.2 <0.4.0",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz",
+ "dev": true
+ },
+ "flat-cache": {
+ "version": "1.2.2",
+ "from": "flat-cache@>=1.2.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz",
+ "dev": true
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "from": "for-in@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "dev": true
+ },
+ "for-own": {
+ "version": "0.1.5",
+ "from": "for-own@>=0.1.4 <0.2.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "from": "forever-agent@>=0.6.1 <0.7.0",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.1.2",
+ "from": "form-data@>=2.1.1 <2.2.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz",
+ "dev": true
+ },
+ "fresh": {
+ "version": "0.5.0",
+ "from": "fresh@0.5.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz",
+ "dev": true
+ },
+ "fs-exists-sync": {
+ "version": "0.1.0",
+ "from": "fs-exists-sync@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz",
+ "dev": true
+ },
+ "fs-extra": {
+ "version": "1.0.0",
+ "from": "fs-extra@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+ "dev": true
+ },
+ "fs-promise": {
+ "version": "1.0.0",
+ "from": "fs-promise@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-1.0.0.tgz",
+ "dev": true
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "from": "fs.realpath@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "dev": true
+ },
+ "fstream": {
+ "version": "1.0.11",
+ "from": "fstream@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+ "dev": true
+ },
+ "gauge": {
+ "version": "2.7.3",
+ "from": "gauge@>=2.7.1 <2.8.0",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.3.tgz",
+ "dev": true
+ },
+ "gaze": {
+ "version": "1.1.2",
+ "from": "gaze@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz",
+ "dev": true
+ },
+ "generate-function": {
+ "version": "2.0.0",
+ "from": "generate-function@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
+ "dev": true
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "from": "generate-object-property@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "1.0.2",
+ "from": "get-caller-file@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "4.0.1",
+ "from": "get-stdin@>=4.0.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+ "dev": true
+ },
+ "getobject": {
+ "version": "0.1.0",
+ "from": "getobject@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.6",
+ "from": "getpass@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz",
+ "dev": true,
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "from": "assert-plus@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "glob": {
+ "version": "7.1.1",
+ "from": "glob@>=7.0.3 <8.0.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
+ "dev": true
+ },
+ "glob-base": {
+ "version": "0.3.0",
+ "from": "glob-base@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+ "dev": true
+ },
+ "glob-parent": {
+ "version": "2.0.0",
+ "from": "glob-parent@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+ "dev": true
+ },
+ "global-modules": {
+ "version": "0.2.3",
+ "from": "global-modules@>=0.2.3 <0.3.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz",
+ "dev": true
+ },
+ "global-prefix": {
+ "version": "0.1.5",
+ "from": "global-prefix@>=0.1.4 <0.2.0",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz",
+ "dev": true
+ },
+ "globals": {
+ "version": "9.16.0",
+ "from": "globals@>=9.0.0 <10.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.16.0.tgz",
+ "dev": true
+ },
+ "globby": {
+ "version": "5.0.0",
+ "from": "globby@>=5.0.0 <6.0.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+ "dev": true
+ },
+ "globule": {
+ "version": "1.1.0",
+ "from": "globule@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/globule/-/globule-1.1.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "lodash": {
+ "version": "4.16.6",
+ "from": "lodash@>=4.16.4 <4.17.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.16.6.tgz",
+ "dev": true
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "from": "graceful-fs@>=4.1.2 <5.0.0",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "dev": true
+ },
+ "graceful-readlink": {
+ "version": "1.0.1",
+ "from": "graceful-readlink@>=1.0.0",
+ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
+ "dev": true
+ },
+ "grunt": {
+ "version": "1.0.1",
+ "from": "grunt@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.1.tgz",
+ "dev": true,
+ "dependencies": {
+ "esprima": {
+ "version": "2.7.3",
+ "from": "esprima@>=2.6.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.0.6",
+ "from": "glob@>=7.0.0 <7.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
+ "dev": true
+ },
+ "grunt-cli": {
+ "version": "1.2.0",
+ "from": "grunt-cli@>=1.2.0 <1.3.0",
+ "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.5.5",
+ "from": "js-yaml@>=3.5.2 <3.6.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.1.7",
+ "from": "resolve@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.2.8",
+ "from": "rimraf@>=2.2.8 <2.3.0",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
+ "dev": true
+ }
+ }
+ },
+ "grunt-babel": {
+ "version": "6.0.0",
+ "from": "grunt-babel@>=6.0.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-babel/-/grunt-babel-6.0.0.tgz",
+ "dev": true
+ },
+ "grunt-build-control": {
+ "version": "0.7.1",
+ "from": "grunt-build-control@>=0.7.1 <0.8.0",
+ "resolved": "https://registry.npmjs.org/grunt-build-control/-/grunt-build-control-0.7.1.tgz",
+ "dev": true,
+ "dependencies": {
+ "semver": {
+ "version": "4.3.6",
+ "from": "semver@>=4.3.3 <4.4.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
+ "dev": true
+ },
+ "shelljs": {
+ "version": "0.2.6",
+ "from": "shelljs@>=0.2.6 <0.3.0",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.2.6.tgz",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-clean": {
+ "version": "1.0.0",
+ "from": "grunt-contrib-clean@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-1.0.0.tgz",
+ "dev": true
+ },
+ "grunt-contrib-compress": {
+ "version": "1.4.1",
+ "from": "grunt-contrib-compress@>=1.4.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-compress/-/grunt-contrib-compress-1.4.1.tgz",
+ "dev": true
+ },
+ "grunt-contrib-concat": {
+ "version": "1.0.1",
+ "from": "grunt-contrib-concat@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-1.0.1.tgz",
+ "dev": true
+ },
+ "grunt-contrib-connect": {
+ "version": "1.0.2",
+ "from": "grunt-contrib-connect@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-connect/-/grunt-contrib-connect-1.0.2.tgz",
+ "dev": true
+ },
+ "grunt-contrib-copy": {
+ "version": "1.0.0",
+ "from": "grunt-contrib-copy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz",
+ "dev": true
+ },
+ "grunt-contrib-qunit": {
+ "version": "1.3.0",
+ "from": "grunt-contrib-qunit@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-1.3.0.tgz",
+ "dev": true
+ },
+ "grunt-contrib-watch": {
+ "version": "1.0.0",
+ "from": "grunt-contrib-watch@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.0.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "lodash": {
+ "version": "3.10.1",
+ "from": "lodash@>=3.10.1 <4.0.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "dev": true
+ }
+ }
+ },
+ "grunt-exec": {
+ "version": "2.0.0",
+ "from": "grunt-exec@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-2.0.0.tgz",
+ "dev": true
+ },
+ "grunt-known-options": {
+ "version": "1.1.0",
+ "from": "grunt-known-options@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.0.tgz",
+ "dev": true
+ },
+ "grunt-legacy-log": {
+ "version": "1.0.0",
+ "from": "grunt-legacy-log@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-1.0.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "lodash": {
+ "version": "3.10.1",
+ "from": "lodash@>=3.10.1 <3.11.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "dev": true
+ }
+ }
+ },
+ "grunt-legacy-log-utils": {
+ "version": "1.0.0",
+ "from": "grunt-legacy-log-utils@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "lodash": {
+ "version": "4.3.0",
+ "from": "lodash@>=4.3.0 <4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "grunt-legacy-util": {
+ "version": "1.0.0",
+ "from": "grunt-legacy-util@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "lodash": {
+ "version": "4.3.0",
+ "from": "lodash@>=4.3.0 <4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "grunt-lib-phantomjs": {
+ "version": "1.1.0",
+ "from": "grunt-lib-phantomjs@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-lib-phantomjs/-/grunt-lib-phantomjs-1.1.0.tgz",
+ "dev": true
+ },
+ "grunt-saucelabs": {
+ "version": "9.0.0",
+ "from": "grunt-saucelabs@>=9.0.0 <10.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-saucelabs/-/grunt-saucelabs-9.0.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "lodash": {
+ "version": "4.13.1",
+ "from": "lodash@>=4.13.1 <4.14.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz",
+ "dev": true
+ }
+ }
+ },
+ "grunt-stamp": {
+ "version": "0.3.0",
+ "from": "grunt-stamp@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/grunt-stamp/-/grunt-stamp-0.3.0.tgz",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "from": "har-validator@>=2.0.6 <2.1.0",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "dev": true
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "from": "has-ansi@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "from": "has-flag@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "dev": true
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "from": "has-unicode@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "dev": true
+ },
+ "hasha": {
+ "version": "2.2.0",
+ "from": "hasha@>=2.2.0 <2.3.0",
+ "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
+ "dev": true
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "from": "hawk@>=3.1.3 <3.2.0",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "dev": true
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "from": "hoek@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "dev": true
+ },
+ "home-or-tmp": {
+ "version": "2.0.0",
+ "from": "home-or-tmp@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+ "dev": true
+ },
+ "homedir-polyfill": {
+ "version": "1.0.1",
+ "from": "homedir-polyfill@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
+ "dev": true
+ },
+ "hooker": {
+ "version": "0.2.3",
+ "from": "hooker@>=0.2.3 <0.3.0",
+ "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "2.3.1",
+ "from": "hosted-git-info@>=2.1.4 <3.0.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.3.1.tgz",
+ "dev": true
+ },
+ "htmlhint": {
+ "version": "0.9.13",
+ "from": "htmlhint@>=0.9.13 <0.10.0",
+ "resolved": "https://registry.npmjs.org/htmlhint/-/htmlhint-0.9.13.tgz",
+ "dev": true,
+ "dependencies": {
+ "async": {
+ "version": "1.4.2",
+ "from": "async@1.4.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.4.2.tgz",
+ "dev": true
+ },
+ "colors": {
+ "version": "1.0.3",
+ "from": "colors@1.0.3",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.6.0",
+ "from": "commander@2.6.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz",
+ "dev": true
+ },
+ "glob": {
+ "version": "5.0.15",
+ "from": "glob@5.0.15",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "1.0.4",
+ "from": "strip-json-comments@1.0.4",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+ "dev": true
+ }
+ }
+ },
+ "htmllint": {
+ "version": "0.6.0",
+ "from": "htmllint@>=0.6.0 <0.7.0",
+ "resolved": "https://registry.npmjs.org/htmllint/-/htmllint-0.6.0.tgz",
+ "dev": true
+ },
+ "htmllint-cli": {
+ "version": "0.0.6",
+ "from": "htmllint-cli@>=0.0.6 <0.0.7",
+ "resolved": "https://registry.npmjs.org/htmllint-cli/-/htmllint-cli-0.0.6.tgz",
+ "dev": true
+ },
+ "htmlparser2": {
+ "version": "3.8.3",
+ "from": "htmlparser2@>=3.8.0 <3.9.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
+ "dev": true,
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "from": "isarray@0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "from": "readable-stream@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "dev": true
+ }
+ }
+ },
+ "http-errors": {
+ "version": "1.5.1",
+ "from": "http-errors@>=1.5.0 <1.6.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz",
+ "dev": true
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "from": "http-signature@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "dev": true
+ },
+ "http2": {
+ "version": "3.3.6",
+ "from": "http2@>=3.3.4 <4.0.0",
+ "resolved": "https://registry.npmjs.org/http2/-/http2-3.3.6.tgz",
+ "dev": true
+ },
+ "https-proxy-agent": {
+ "version": "1.0.0",
+ "from": "https-proxy-agent@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.15",
+ "from": "iconv-lite@>=0.4.13 <0.5.0",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
+ "dev": true
+ },
+ "ignore": {
+ "version": "3.2.6",
+ "from": "ignore@>=3.2.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.2.6.tgz",
+ "dev": true
+ },
+ "iltorb": {
+ "version": "1.0.13",
+ "from": "iltorb@>=1.0.13 <2.0.0",
+ "resolved": "https://registry.npmjs.org/iltorb/-/iltorb-1.0.13.tgz",
+ "dev": true,
+ "optional": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "from": "imurmurhash@>=0.1.4 <0.2.0",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "dev": true
+ },
+ "in-publish": {
+ "version": "2.0.0",
+ "from": "in-publish@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "2.1.0",
+ "from": "indent-string@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "from": "inflight@>=1.0.4 <2.0.0",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "dev": true
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "from": "inherits@>=2.0.3 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.4",
+ "from": "ini@>=1.3.4 <2.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+ "dev": true
+ },
+ "inquirer": {
+ "version": "0.12.0",
+ "from": "inquirer@>=0.12.0 <0.13.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
+ "dev": true
+ },
+ "interpret": {
+ "version": "1.0.1",
+ "from": "interpret@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.1.tgz",
+ "dev": true
+ },
+ "invariant": {
+ "version": "2.2.2",
+ "from": "invariant@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
+ "dev": true
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "from": "invert-kv@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "dev": true
+ },
+ "is-absolute": {
+ "version": "0.2.6",
+ "from": "is-absolute@>=0.2.3 <0.3.0",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz",
+ "dev": true
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "from": "is-arrayish@>=0.2.1 <0.3.0",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "from": "is-binary-path@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "dev": true
+ },
+ "is-buffer": {
+ "version": "1.1.5",
+ "from": "is-buffer@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
+ "dev": true
+ },
+ "is-builtin-module": {
+ "version": "1.0.0",
+ "from": "is-builtin-module@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "dev": true
+ },
+ "is-dotfile": {
+ "version": "1.0.2",
+ "from": "is-dotfile@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz",
+ "dev": true
+ },
+ "is-equal-shallow": {
+ "version": "0.1.3",
+ "from": "is-equal-shallow@>=0.1.3 <0.2.0",
+ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+ "dev": true
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "from": "is-extendable@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "1.0.0",
+ "from": "is-extglob@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "dev": true
+ },
+ "is-finite": {
+ "version": "1.0.2",
+ "from": "is-finite@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "from": "is-fullwidth-code-point@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "from": "is-glob@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "dev": true
+ },
+ "is-my-json-valid": {
+ "version": "2.16.0",
+ "from": "is-my-json-valid@>=2.10.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz",
+ "dev": true
+ },
+ "is-number": {
+ "version": "2.1.0",
+ "from": "is-number@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+ "dev": true
+ },
+ "is-path-cwd": {
+ "version": "1.0.0",
+ "from": "is-path-cwd@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+ "dev": true
+ },
+ "is-path-in-cwd": {
+ "version": "1.0.0",
+ "from": "is-path-in-cwd@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
+ "dev": true
+ },
+ "is-path-inside": {
+ "version": "1.0.0",
+ "from": "is-path-inside@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
+ "dev": true
+ },
+ "is-posix-bracket": {
+ "version": "0.1.1",
+ "from": "is-posix-bracket@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+ "dev": true
+ },
+ "is-primitive": {
+ "version": "2.0.0",
+ "from": "is-primitive@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+ "dev": true
+ },
+ "is-property": {
+ "version": "1.0.2",
+ "from": "is-property@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "dev": true
+ },
+ "is-relative": {
+ "version": "0.2.1",
+ "from": "is-relative@>=0.2.1 <0.3.0",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz",
+ "dev": true
+ },
+ "is-resolvable": {
+ "version": "1.0.0",
+ "from": "is-resolvable@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "from": "is-stream@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "dev": true
+ },
+ "is-travis": {
+ "version": "1.0.0",
+ "from": "is-travis@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-travis/-/is-travis-1.0.0.tgz",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "from": "is-typedarray@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "dev": true
+ },
+ "is-unc-path": {
+ "version": "0.1.2",
+ "from": "is-unc-path@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz",
+ "dev": true
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "from": "is-utf8@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "0.2.0",
+ "from": "is-windows@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "from": "isarray@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "dev": true
+ },
+ "isexe": {
+ "version": "1.1.2",
+ "from": "isexe@>=1.1.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz",
+ "dev": true
+ },
+ "isobject": {
+ "version": "2.1.0",
+ "from": "isobject@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "from": "isstream@>=0.1.2 <0.2.0",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "dev": true
+ },
+ "jju": {
+ "version": "1.3.0",
+ "from": "jju@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/jju/-/jju-1.3.0.tgz",
+ "dev": true
+ },
+ "jodid25519": {
+ "version": "1.0.2",
+ "from": "jodid25519@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz",
+ "dev": true,
+ "optional": true
+ },
+ "jquery": {
+ "version": "3.2.0",
+ "from": "jquery@>=1.9.1",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.0.tgz"
+ },
+ "js-base64": {
+ "version": "2.1.9",
+ "from": "js-base64@>=2.1.9 <3.0.0",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "3.0.1",
+ "from": "js-tokens@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.8.2",
+ "from": "js-yaml@>=3.5.1 <4.0.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.2.tgz",
+ "dev": true
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "from": "jsbn@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "dev": true,
+ "optional": true
+ },
+ "jsesc": {
+ "version": "0.5.0",
+ "from": "jsesc@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "dev": true
+ },
+ "jshint": {
+ "version": "2.8.0",
+ "from": "jshint@2.8.0",
+ "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.8.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "lodash": {
+ "version": "3.7.0",
+ "from": "lodash@>=3.7.0 <3.8.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "2.0.10",
+ "from": "minimatch@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
+ "dev": true
+ },
+ "shelljs": {
+ "version": "0.3.0",
+ "from": "shelljs@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "1.0.4",
+ "from": "strip-json-comments@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+ "dev": true
+ }
+ }
+ },
+ "json-parse-helpfulerror": {
+ "version": "1.0.3",
+ "from": "json-parse-helpfulerror@>=1.0.3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz",
+ "dev": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "from": "json-schema@0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "from": "json-stable-stringify@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+ "dev": true
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "from": "json-stringify-safe@>=5.0.1 <5.1.0",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "dev": true
+ },
+ "json5": {
+ "version": "0.5.1",
+ "from": "json5@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "2.4.0",
+ "from": "jsonfile@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "dev": true
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "from": "jsonify@>=0.0.0 <0.1.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "dev": true
+ },
+ "jsonpointer": {
+ "version": "4.0.1",
+ "from": "jsonpointer@>=4.0.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.0",
+ "from": "jsprim@>=1.2.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "from": "assert-plus@1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "kew": {
+ "version": "0.7.0",
+ "from": "kew@>=0.7.0 <0.8.0",
+ "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.1.0",
+ "from": "kind-of@>=3.0.2 <4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.1.0.tgz",
+ "dev": true
+ },
+ "klaw": {
+ "version": "1.3.1",
+ "from": "klaw@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "dev": true
+ },
+ "lazy-cache": {
+ "version": "1.0.4",
+ "from": "lazy-cache@>=1.0.3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+ "dev": true
+ },
+ "lazystream": {
+ "version": "1.0.0",
+ "from": "lazystream@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+ "dev": true
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "from": "lcid@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "from": "levn@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "dev": true
+ },
+ "liftoff": {
+ "version": "2.3.0",
+ "from": "liftoff@>=2.3.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "findup-sync": {
+ "version": "0.4.3",
+ "from": "findup-sync@>=0.4.2 <0.5.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz",
+ "dev": true
+ }
+ }
+ },
+ "livereload-js": {
+ "version": "2.2.2",
+ "from": "livereload-js@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.2.2.tgz",
+ "dev": true
+ },
+ "load-grunt-tasks": {
+ "version": "3.5.2",
+ "from": "load-grunt-tasks@>=3.5.2 <4.0.0",
+ "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz",
+ "dev": true
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "from": "load-json-file@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "strip-bom": {
+ "version": "2.0.0",
+ "from": "strip-bom@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "lodash": {
+ "version": "4.17.4",
+ "from": "lodash@>=4.2.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
+ "dev": true
+ },
+ "lodash.assign": {
+ "version": "4.2.0",
+ "from": "lodash.assign@>=4.2.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+ "dev": true
+ },
+ "lodash.assignwith": {
+ "version": "4.2.0",
+ "from": "lodash.assignwith@>=4.0.7 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz",
+ "dev": true
+ },
+ "lodash.clonedeep": {
+ "version": "4.5.0",
+ "from": "lodash.clonedeep@>=4.3.2 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "dev": true
+ },
+ "lodash.isempty": {
+ "version": "4.4.0",
+ "from": "lodash.isempty@>=4.2.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz",
+ "dev": true
+ },
+ "lodash.isplainobject": {
+ "version": "4.0.6",
+ "from": "lodash.isplainobject@>=4.0.4 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "dev": true
+ },
+ "lodash.isstring": {
+ "version": "4.0.1",
+ "from": "lodash.isstring@>=4.0.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "dev": true
+ },
+ "lodash.mapvalues": {
+ "version": "4.6.0",
+ "from": "lodash.mapvalues@>=4.4.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz",
+ "dev": true
+ },
+ "lodash.mergewith": {
+ "version": "4.6.0",
+ "from": "lodash.mergewith@>=4.6.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz",
+ "dev": true
+ },
+ "lodash.pick": {
+ "version": "4.4.0",
+ "from": "lodash.pick@>=4.2.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
+ "dev": true
+ },
+ "lodash.pickby": {
+ "version": "4.6.0",
+ "from": "lodash.pickby@>=4.6.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "1.0.2",
+ "from": "log-symbols@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
+ "dev": true
+ },
+ "longest": {
+ "version": "1.0.1",
+ "from": "longest@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "dev": true
+ },
+ "loose-envify": {
+ "version": "1.3.1",
+ "from": "loose-envify@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
+ "dev": true
+ },
+ "loud-rejection": {
+ "version": "1.6.0",
+ "from": "loud-rejection@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "2.7.3",
+ "from": "lru-cache@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
+ "dev": true
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "from": "map-cache@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "dev": true
+ },
+ "map-obj": {
+ "version": "1.0.1",
+ "from": "map-obj@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "dev": true
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "from": "media-typer@0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "dev": true
+ },
+ "meow": {
+ "version": "3.7.0",
+ "from": "meow@>=3.3.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "from": "minimist@>=1.1.3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "micromatch": {
+ "version": "2.3.11",
+ "from": "micromatch@>=2.3.7 <3.0.0",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+ "dev": true
+ },
+ "mime": {
+ "version": "1.3.4",
+ "from": "mime@1.3.4",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.26.0",
+ "from": "mime-db@>=1.26.0 <1.27.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.14",
+ "from": "mime-types@>=2.1.11 <2.2.0",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.14.tgz",
+ "dev": true
+ },
+ "mimic-fn": {
+ "version": "1.1.0",
+ "from": "mimic-fn@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.3",
+ "from": "minimatch@>=3.0.2 <4.0.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
+ "dev": true
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "from": "minimist@0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "from": "mkdirp@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "dev": true
+ },
+ "morgan": {
+ "version": "1.8.1",
+ "from": "morgan@>=1.6.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.8.1.tgz",
+ "dev": true,
+ "dependencies": {
+ "debug": {
+ "version": "2.6.1",
+ "from": "debug@2.6.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz",
+ "dev": true
+ }
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "from": "ms@0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "dev": true
+ },
+ "multimatch": {
+ "version": "2.1.0",
+ "from": "multimatch@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.5",
+ "from": "mute-stream@0.0.5",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
+ "dev": true
+ },
+ "mz": {
+ "version": "2.6.0",
+ "from": "mz@>=2.3.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.6.0.tgz",
+ "dev": true
+ },
+ "nan": {
+ "version": "2.5.1",
+ "from": "nan@>=2.4.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.5.1.tgz",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "from": "natural-compare@>=1.4.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "dev": true
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "from": "negotiator@0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "dev": true
+ },
+ "node-gyp": {
+ "version": "3.6.0",
+ "from": "node-gyp@>=3.3.1 <4.0.0",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.0.tgz",
+ "dev": true
+ },
+ "node-sass": {
+ "version": "4.5.0",
+ "from": "node-sass@>=4.5.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.5.0.tgz",
+ "dev": true
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "from": "nopt@>=3.0.6 <3.1.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "dev": true
+ },
+ "normalize-package-data": {
+ "version": "2.3.6",
+ "from": "normalize-package-data@>=2.3.4 <3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.6.tgz",
+ "dev": true
+ },
+ "normalize-path": {
+ "version": "2.0.1",
+ "from": "normalize-path@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.0.1.tgz",
+ "dev": true
+ },
+ "normalize-range": {
+ "version": "0.1.2",
+ "from": "normalize-range@>=0.1.2 <0.2.0",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "dev": true
+ },
+ "npmlog": {
+ "version": "4.0.2",
+ "from": "npmlog@>=4.0.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.0.2.tgz",
+ "dev": true
+ },
+ "num2fraction": {
+ "version": "1.2.2",
+ "from": "num2fraction@>=1.2.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+ "dev": true
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "from": "number-is-nan@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "from": "oauth-sign@>=0.8.1 <0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "from": "object-assign@>=4.0.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "dev": true
+ },
+ "object.omit": {
+ "version": "2.0.1",
+ "from": "object.omit@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+ "dev": true
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "from": "on-finished@>=2.3.0 <2.4.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "dev": true
+ },
+ "on-headers": {
+ "version": "1.0.1",
+ "from": "on-headers@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "from": "once@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "dev": true
+ },
+ "onetime": {
+ "version": "1.1.0",
+ "from": "onetime@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+ "dev": true
+ },
+ "opn": {
+ "version": "4.0.2",
+ "from": "opn@>=4.0.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz",
+ "dev": true
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "from": "optionator@>=0.8.2 <0.9.0",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "dev": true
+ },
+ "ora": {
+ "version": "1.1.0",
+ "from": "ora@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-1.1.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "cli-cursor": {
+ "version": "2.1.0",
+ "from": "cli-cursor@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "dev": true
+ },
+ "onetime": {
+ "version": "2.0.0",
+ "from": "onetime@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.0.tgz",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "from": "restore-cursor@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "from": "os-homedir@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "dev": true
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "from": "os-locale@>=1.4.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "dev": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "from": "os-tmpdir@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "dev": true
+ },
+ "osenv": {
+ "version": "0.1.4",
+ "from": "osenv@>=0.0.0 <1.0.0",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
+ "dev": true
+ },
+ "package": {
+ "version": "1.0.1",
+ "from": "package@>=1.0.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/package/-/package-1.0.1.tgz",
+ "dev": true
+ },
+ "parse-filepath": {
+ "version": "1.0.1",
+ "from": "parse-filepath@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz",
+ "dev": true
+ },
+ "parse-glob": {
+ "version": "3.0.4",
+ "from": "parse-glob@3.0.4",
+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+ "dev": true
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "from": "parse-json@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "dev": true
+ },
+ "parse-ms": {
+ "version": "1.0.1",
+ "from": "parse-ms@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz",
+ "dev": true
+ },
+ "parse-passwd": {
+ "version": "1.0.0",
+ "from": "parse-passwd@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "dev": true
+ },
+ "parserlib": {
+ "version": "0.2.5",
+ "from": "parserlib@>=0.2.2 <0.3.0",
+ "resolved": "https://registry.npmjs.org/parserlib/-/parserlib-0.2.5.tgz",
+ "dev": true
+ },
+ "parseurl": {
+ "version": "1.3.1",
+ "from": "parseurl@>=1.3.1 <1.4.0",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "from": "path-exists@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "from": "path-is-absolute@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "from": "path-is-inside@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.5",
+ "from": "path-parse@>=1.0.5 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
+ "dev": true
+ },
+ "path-root": {
+ "version": "0.1.1",
+ "from": "path-root@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "dev": true
+ },
+ "path-root-regex": {
+ "version": "0.1.2",
+ "from": "path-root-regex@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "dev": true
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "from": "path-type@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "dev": true
+ },
+ "pend": {
+ "version": "1.2.0",
+ "from": "pend@>=1.2.0 <1.3.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "dev": true
+ },
+ "phantomjs-prebuilt": {
+ "version": "2.1.14",
+ "from": "phantomjs-prebuilt@>=2.1.3 <3.0.0",
+ "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.14.tgz",
+ "dev": true
+ },
+ "pify": {
+ "version": "2.3.0",
+ "from": "pify@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "from": "pinkie@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "from": "pinkie-promise@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "dev": true
+ },
+ "pkg-up": {
+ "version": "1.0.0",
+ "from": "pkg-up@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz",
+ "dev": true
+ },
+ "plur": {
+ "version": "1.0.0",
+ "from": "plur@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz",
+ "dev": true
+ },
+ "pluralize": {
+ "version": "1.2.1",
+ "from": "pluralize@>=1.2.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
+ "dev": true
+ },
+ "portscanner": {
+ "version": "1.2.0",
+ "from": "portscanner@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-1.2.0.tgz",
+ "dev": true
+ },
+ "postcss": {
+ "version": "5.2.16",
+ "from": "postcss@>=5.2.16 <6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.16.tgz",
+ "dev": true
+ },
+ "postcss-cli": {
+ "version": "3.0.0",
+ "from": "postcss-cli@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-3.0.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "from": "camelcase@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "5.0.1",
+ "from": "get-stdin@>=5.0.1 <6.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
+ "dev": true
+ },
+ "globby": {
+ "version": "6.1.0",
+ "from": "globby@>=6.1.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "dev": true
+ },
+ "yargs": {
+ "version": "7.0.2",
+ "from": "yargs@>=7.0.2 <8.0.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.0.2.tgz",
+ "dev": true
+ },
+ "yargs-parser": {
+ "version": "5.0.0",
+ "from": "yargs-parser@>=5.0.0 <6.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "postcss-flexbugs-fixes": {
+ "version": "2.1.0",
+ "from": "postcss-flexbugs-fixes@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-2.1.0.tgz",
+ "dev": true
+ },
+ "postcss-load-config": {
+ "version": "1.2.0",
+ "from": "postcss-load-config@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz",
+ "dev": true
+ },
+ "postcss-load-options": {
+ "version": "1.2.0",
+ "from": "postcss-load-options@>=1.2.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz",
+ "dev": true
+ },
+ "postcss-load-plugins": {
+ "version": "2.3.0",
+ "from": "postcss-load-plugins@>=2.3.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz",
+ "dev": true
+ },
+ "postcss-reporter": {
+ "version": "3.0.0",
+ "from": "postcss-reporter@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-3.0.0.tgz",
+ "dev": true
+ },
+ "postcss-value-parser": {
+ "version": "3.3.0",
+ "from": "postcss-value-parser@>=3.2.3 <4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "from": "prelude-ls@>=1.1.2 <1.2.0",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "dev": true
+ },
+ "preserve": {
+ "version": "0.2.0",
+ "from": "preserve@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+ "dev": true
+ },
+ "pretty-bytes": {
+ "version": "3.0.1",
+ "from": "pretty-bytes@>=3.0.1 <4.0.0",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz",
+ "dev": true
+ },
+ "pretty-ms": {
+ "version": "2.1.0",
+ "from": "pretty-ms@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz",
+ "dev": true
+ },
+ "private": {
+ "version": "0.1.7",
+ "from": "private@>=0.1.6 <0.2.0",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "from": "process-nextick-args@>=1.0.6 <1.1.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "dev": true
+ },
+ "progress": {
+ "version": "1.1.8",
+ "from": "progress@>=1.1.8 <2.0.0",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "dev": true
+ },
+ "promise": {
+ "version": "7.1.1",
+ "from": "promise@>=7.1.1 <8.0.0",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.1.1.tgz",
+ "dev": true
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "from": "pseudomap@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "dev": true
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "from": "punycode@>=1.4.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "dev": true
+ },
+ "q": {
+ "version": "1.4.1",
+ "from": "q@>=1.4.1 <1.5.0",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.3.2",
+ "from": "qs@>=6.3.0 <6.4.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+ "dev": true
+ },
+ "randomatic": {
+ "version": "1.1.6",
+ "from": "randomatic@>=1.1.3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.6.tgz",
+ "dev": true
+ },
+ "range-parser": {
+ "version": "1.2.0",
+ "from": "range-parser@>=1.2.0 <1.3.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "dev": true
+ },
+ "raw-body": {
+ "version": "2.1.7",
+ "from": "raw-body@>=2.1.5 <2.2.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz",
+ "dev": true,
+ "dependencies": {
+ "bytes": {
+ "version": "2.4.0",
+ "from": "bytes@2.4.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.13",
+ "from": "iconv-lite@0.4.13",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
+ "dev": true
+ }
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "from": "read-pkg@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "dev": true
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "from": "read-pkg-up@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.2.6",
+ "from": "readable-stream@>=2.2.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.6.tgz",
+ "dev": true
+ },
+ "readdirp": {
+ "version": "2.1.0",
+ "from": "readdirp@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+ "dev": true
+ },
+ "readline2": {
+ "version": "1.0.1",
+ "from": "readline2@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
+ "dev": true
+ },
+ "rechoir": {
+ "version": "0.6.2",
+ "from": "rechoir@>=0.6.2 <0.7.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "dev": true
+ },
+ "redent": {
+ "version": "1.0.0",
+ "from": "redent@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+ "dev": true
+ },
+ "regenerate": {
+ "version": "1.3.2",
+ "from": "regenerate@>=1.2.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz",
+ "dev": true
+ },
+ "regenerator-runtime": {
+ "version": "0.10.3",
+ "from": "regenerator-runtime@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz",
+ "dev": true
+ },
+ "regenerator-transform": {
+ "version": "0.9.8",
+ "from": "regenerator-transform@0.9.8",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.8.tgz",
+ "dev": true
+ },
+ "regex-cache": {
+ "version": "0.4.3",
+ "from": "regex-cache@>=0.4.2 <0.5.0",
+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz",
+ "dev": true
+ },
+ "regexpu-core": {
+ "version": "2.0.0",
+ "from": "regexpu-core@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
+ "dev": true
+ },
+ "regjsgen": {
+ "version": "0.2.0",
+ "from": "regjsgen@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+ "dev": true
+ },
+ "regjsparser": {
+ "version": "0.1.5",
+ "from": "regjsparser@>=0.1.4 <0.2.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+ "dev": true
+ },
+ "repeat-element": {
+ "version": "1.1.2",
+ "from": "repeat-element@>=1.1.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "from": "repeat-string@>=1.5.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "dev": true
+ },
+ "repeating": {
+ "version": "2.0.1",
+ "from": "repeating@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+ "dev": true
+ },
+ "request": {
+ "version": "2.79.0",
+ "from": "request@>=2.79.0 <2.80.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
+ "dev": true
+ },
+ "request-progress": {
+ "version": "2.0.1",
+ "from": "request-progress@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
+ "dev": true
+ },
+ "requestretry": {
+ "version": "1.9.1",
+ "from": "requestretry@>=1.9.0 <1.10.0",
+ "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.9.1.tgz",
+ "dev": true
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "from": "require-directory@>=2.1.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "dev": true
+ },
+ "require-from-string": {
+ "version": "1.2.1",
+ "from": "require-from-string@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "from": "require-main-filename@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "dev": true
+ },
+ "require-uncached": {
+ "version": "1.0.3",
+ "from": "require-uncached@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.3.2",
+ "from": "resolve@>=1.1.6 <2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.2.tgz",
+ "dev": true
+ },
+ "resolve-dir": {
+ "version": "0.1.1",
+ "from": "resolve-dir@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
+ "dev": true
+ },
+ "resolve-from": {
+ "version": "1.0.1",
+ "from": "resolve-from@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+ "dev": true
+ },
+ "resolve-pkg": {
+ "version": "0.1.0",
+ "from": "resolve-pkg@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-0.1.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "resolve-from": {
+ "version": "2.0.0",
+ "from": "resolve-from@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "restore-cursor": {
+ "version": "1.0.1",
+ "from": "restore-cursor@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+ "dev": true
+ },
+ "right-align": {
+ "version": "0.1.3",
+ "from": "right-align@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.6.1",
+ "from": "rimraf@>=2.2.8 <3.0.0",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
+ "dev": true
+ },
+ "run-async": {
+ "version": "0.1.0",
+ "from": "run-async@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
+ "dev": true
+ },
+ "rx-lite": {
+ "version": "3.1.2",
+ "from": "rx-lite@>=3.1.2 <4.0.0",
+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
+ "dev": true
+ },
+ "sass-graph": {
+ "version": "2.1.2",
+ "from": "sass-graph@>=2.1.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.1.2.tgz",
+ "dev": true,
+ "dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "from": "camelcase@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "dev": true
+ },
+ "yargs": {
+ "version": "4.8.1",
+ "from": "yargs@>=4.7.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
+ "dev": true
+ },
+ "yargs-parser": {
+ "version": "2.4.1",
+ "from": "yargs-parser@>=2.4.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
+ "dev": true
+ }
+ }
+ },
+ "sauce-tunnel": {
+ "version": "2.5.0",
+ "from": "sauce-tunnel@>=2.5.0 <2.6.0",
+ "resolved": "https://registry.npmjs.org/sauce-tunnel/-/sauce-tunnel-2.5.0.tgz",
+ "dev": true
+ },
+ "saucelabs": {
+ "version": "1.2.0",
+ "from": "saucelabs@>=1.2.0 <1.3.0",
+ "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.2.0.tgz",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.3.0",
+ "from": "semver@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0||>=4.0.0 <5.0.0||>=5.0.0 <6.0.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+ "dev": true
+ },
+ "send": {
+ "version": "0.15.1",
+ "from": "send@0.15.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.15.1.tgz",
+ "dev": true,
+ "dependencies": {
+ "debug": {
+ "version": "2.6.1",
+ "from": "debug@2.6.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.6.1",
+ "from": "http-errors@>=1.6.1 <1.7.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.1.tgz",
+ "dev": true
+ },
+ "setprototypeof": {
+ "version": "1.0.3",
+ "from": "setprototypeof@1.0.3",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "dev": true
+ }
+ }
+ },
+ "serve-index": {
+ "version": "1.8.0",
+ "from": "serve-index@>=1.7.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.8.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.2.0 <2.3.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dev": true
+ },
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+ "dev": true
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.12.1",
+ "from": "serve-static@>=1.10.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.1.tgz",
+ "dev": true
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "from": "set-blocking@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "dev": true
+ },
+ "set-immediate-shim": {
+ "version": "1.0.1",
+ "from": "set-immediate-shim@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+ "dev": true
+ },
+ "setprototypeof": {
+ "version": "1.0.2",
+ "from": "setprototypeof@1.0.2",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz",
+ "dev": true
+ },
+ "shelljs": {
+ "version": "0.7.7",
+ "from": "shelljs@>=0.7.7 <0.8.0",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.7.tgz",
+ "dev": true
+ },
+ "shx": {
+ "version": "0.2.2",
+ "from": "shx@>=0.2.2 <0.3.0",
+ "resolved": "https://registry.npmjs.org/shx/-/shx-0.2.2.tgz",
+ "dev": true,
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "from": "minimist@>=1.2.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "from": "sigmund@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "from": "signal-exit@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "dev": true
+ },
+ "slash": {
+ "version": "1.0.0",
+ "from": "slash@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "0.0.4",
+ "from": "slice-ansi@0.0.4",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+ "dev": true
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "from": "sntp@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.5.6",
+ "from": "source-map@>=0.5.6 <0.6.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
+ "dev": true
+ },
+ "source-map-support": {
+ "version": "0.4.14",
+ "from": "source-map-support@>=0.4.2 <0.5.0",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.14.tgz",
+ "dev": true
+ },
+ "spdx-correct": {
+ "version": "1.0.2",
+ "from": "spdx-correct@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "1.0.4",
+ "from": "spdx-expression-parse@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
+ "dev": true
+ },
+ "spdx-license-ids": {
+ "version": "1.2.2",
+ "from": "spdx-license-ids@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
+ "dev": true
+ },
+ "split": {
+ "version": "1.0.0",
+ "from": "split@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/split/-/split-1.0.0.tgz",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "from": "sprintf-js@>=1.0.2 <1.1.0",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.11.0",
+ "from": "sshpk@>=1.7.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.11.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "from": "assert-plus@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "statuses": {
+ "version": "1.3.1",
+ "from": "statuses@>=1.3.1 <1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "dev": true
+ },
+ "stdout-stream": {
+ "version": "1.4.0",
+ "from": "stdout-stream@>=1.4.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz",
+ "dev": true
+ },
+ "stream-buffers": {
+ "version": "2.2.0",
+ "from": "stream-buffers@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "from": "string_decoder@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "dev": true
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "from": "string-width@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "dev": true
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "from": "stringstream@>=0.0.4 <0.1.0",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "from": "strip-ansi@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "dev": true
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "from": "strip-bom@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "dev": true
+ },
+ "strip-indent": {
+ "version": "1.0.1",
+ "from": "strip-indent@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "from": "strip-json-comments@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "from": "supports-color@>=3.2.3 <4.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "dev": true
+ },
+ "table": {
+ "version": "3.8.3",
+ "from": "table@>=3.7.8 <4.0.0",
+ "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
+ "dev": true,
+ "dependencies": {
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "from": "is-fullwidth-code-point@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.0.0",
+ "from": "string-width@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "tar": {
+ "version": "2.2.1",
+ "from": "tar@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+ "dev": true
+ },
+ "tar-stream": {
+ "version": "1.5.2",
+ "from": "tar-stream@>=1.5.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.2.tgz",
+ "dev": true
+ },
+ "temporary": {
+ "version": "0.0.8",
+ "from": "temporary@>=0.0.8 <0.0.9",
+ "resolved": "https://registry.npmjs.org/temporary/-/temporary-0.0.8.tgz",
+ "dev": true
+ },
+ "tether": {
+ "version": "1.4.0",
+ "from": "tether@>=1.4.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/tether/-/tether-1.4.0.tgz"
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "from": "text-table@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "dev": true
+ },
+ "thenify": {
+ "version": "3.2.1",
+ "from": "thenify@>=3.1.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.2.1.tgz",
+ "dev": true
+ },
+ "thenify-all": {
+ "version": "1.6.0",
+ "from": "thenify-all@>=1.6.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "dev": true
+ },
+ "throttleit": {
+ "version": "1.0.0",
+ "from": "throttleit@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "from": "through@>=2.3.6 <3.0.0",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "dev": true
+ },
+ "time-grunt": {
+ "version": "1.4.0",
+ "from": "time-grunt@>=1.4.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/time-grunt/-/time-grunt-1.4.0.tgz",
+ "dev": true
+ },
+ "time-zone": {
+ "version": "0.1.0",
+ "from": "time-zone@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-0.1.0.tgz",
+ "dev": true
+ },
+ "tiny-lr": {
+ "version": "0.2.1",
+ "from": "tiny-lr@>=0.2.1 <0.3.0",
+ "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.2.1.tgz",
+ "dev": true,
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.2.0 <2.3.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dev": true
+ },
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+ "dev": true
+ },
+ "qs": {
+ "version": "5.1.0",
+ "from": "qs@>=5.1.0 <5.2.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "to-fast-properties": {
+ "version": "1.0.2",
+ "from": "to-fast-properties@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.2.tgz",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "2.3.2",
+ "from": "tough-cookie@>=2.3.0 <2.4.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
+ "dev": true
+ },
+ "trim-newlines": {
+ "version": "1.0.0",
+ "from": "trim-newlines@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+ "dev": true
+ },
+ "trim-right": {
+ "version": "1.0.1",
+ "from": "trim-right@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+ "dev": true
+ },
+ "tryit": {
+ "version": "1.0.3",
+ "from": "tryit@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "from": "tunnel-agent@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "dev": true
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "from": "tweetnacl@>=0.14.0 <0.15.0",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "dev": true,
+ "optional": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "from": "type-check@>=0.3.2 <0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "dev": true
+ },
+ "type-is": {
+ "version": "1.6.14",
+ "from": "type-is@>=1.6.10 <1.7.0",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.14.tgz",
+ "dev": true
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "from": "typedarray@>=0.0.6 <0.0.7",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "2.8.14",
+ "from": "uglify-js@>=2.8.14 <3.0.0",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.14.tgz",
+ "dev": true,
+ "dependencies": {
+ "camelcase": {
+ "version": "1.2.1",
+ "from": "camelcase@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "dev": true
+ },
+ "cliui": {
+ "version": "2.1.0",
+ "from": "cliui@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+ "dev": true
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "from": "window-size@0.1.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+ "dev": true
+ },
+ "wordwrap": {
+ "version": "0.0.2",
+ "from": "wordwrap@0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+ "dev": true
+ },
+ "yargs": {
+ "version": "3.10.0",
+ "from": "yargs@>=3.10.0 <3.11.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "from": "uglify-to-browserify@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "dev": true
+ },
+ "unc-path-regex": {
+ "version": "0.1.2",
+ "from": "unc-path-regex@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "dev": true
+ },
+ "underscore.string": {
+ "version": "3.2.3",
+ "from": "underscore.string@>=3.2.3 <3.3.0",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "from": "unpipe@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "dev": true
+ },
+ "user-home": {
+ "version": "2.0.0",
+ "from": "user-home@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
+ "dev": true
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "from": "util-deprecate@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "dev": true
+ },
+ "utils-merge": {
+ "version": "1.0.0",
+ "from": "utils-merge@1.0.0",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.0.1",
+ "from": "uuid@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz",
+ "dev": true
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.1",
+ "from": "validate-npm-package-license@>=3.0.1 <4.0.0",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
+ "dev": true
+ },
+ "verror": {
+ "version": "1.3.6",
+ "from": "verror@1.3.6",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz",
+ "dev": true
+ },
+ "walkdir": {
+ "version": "0.0.11",
+ "from": "walkdir@>=0.0.11 <0.0.12",
+ "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz",
+ "dev": true
+ },
+ "websocket-driver": {
+ "version": "0.6.5",
+ "from": "websocket-driver@>=0.5.1",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz",
+ "dev": true
+ },
+ "websocket-extensions": {
+ "version": "0.1.1",
+ "from": "websocket-extensions@>=0.1.1",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz",
+ "dev": true
+ },
+ "when": {
+ "version": "3.7.8",
+ "from": "when@>=3.7.5 <3.8.0",
+ "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz",
+ "dev": true
+ },
+ "which": {
+ "version": "1.2.12",
+ "from": "which@>=1.2.1 <1.3.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.2.12.tgz",
+ "dev": true
+ },
+ "which-module": {
+ "version": "1.0.0",
+ "from": "which-module@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "dev": true
+ },
+ "wide-align": {
+ "version": "1.1.0",
+ "from": "wide-align@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.0.tgz",
+ "dev": true
+ },
+ "window-size": {
+ "version": "0.2.0",
+ "from": "window-size@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
+ "dev": true
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "from": "wordwrap@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "from": "wrap-ansi@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "dev": true
+ },
+ "write": {
+ "version": "0.2.1",
+ "from": "write@>=0.2.1 <0.3.0",
+ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+ "dev": true
+ },
+ "xml": {
+ "version": "1.0.0",
+ "from": "xml@1.0.0",
+ "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.0.tgz",
+ "dev": true
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "from": "xtend@>=4.0.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "dev": true
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "from": "y18n@>=3.2.1 <4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "from": "yallist@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "dev": true
+ },
+ "yargs": {
+ "version": "6.6.0",
+ "from": "yargs@>=6.6.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
+ "dev": true,
+ "dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "from": "camelcase@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "4.2.1",
+ "from": "yargs-parser@>=4.2.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz",
+ "dev": true,
+ "dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "from": "camelcase@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "dev": true
+ }
+ }
+ },
+ "yauzl": {
+ "version": "2.4.1",
+ "from": "yauzl@2.4.1",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+ "dev": true
+ },
+ "zip-stream": {
+ "version": "1.1.1",
+ "from": "zip-stream@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.1.1.tgz",
+ "dev": true
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/grunt/postcss.config.js b/templates/assets/bootstrap/grunt/postcss.config.js
new file mode 100644
index 0000000..803078a
--- /dev/null
+++ b/templates/assets/bootstrap/grunt/postcss.config.js
@@ -0,0 +1,41 @@
+module.exports = (ctx) => ({
+ map: ctx.file.dirname.startsWith('docs') ? false : {
+ inline: false,
+ annotation: true,
+ sourcesContent: true
+ },
+ plugins: {
+ autoprefixer: {
+ browsers: [
+ //
+ // Official browser support policy:
+ // https://v4-alpha.getbootstrap.com/getting-started/browsers-devices/#supported-browsers
+ //
+ 'Chrome >= 35', // Exact version number here is kinda arbitrary
+ // Rather than using Autoprefixer's native "Firefox ESR" version specifier string,
+ // we deliberately hardcode the number. This is to avoid unwittingly severely breaking the previous ESR in the event that:
+ // (a) we happen to ship a new Bootstrap release soon after the release of a new ESR,
+ // such that folks haven't yet had a reasonable amount of time to upgrade; and
+ // (b) the new ESR has unprefixed CSS properties/values whose absence would severely break webpages
+ // (e.g. `box-sizing`, as opposed to `background: linear-gradient(...)`).
+ // Since they've been unprefixed, Autoprefixer will stop prefixing them,
+ // thus causing them to not work in the previous ESR (where the prefixes were required).
+ 'Firefox >= 38', // Current Firefox Extended Support Release (ESR); https://www.mozilla.org/en-US/firefox/organizations/faq/
+ // Note: Edge versions in Autoprefixer & Can I Use refer to the EdgeHTML rendering engine version,
+ // NOT the Edge app version shown in Edge's "About" screen.
+ // For example, at the time of writing, Edge 20 on an up-to-date system uses EdgeHTML 12.
+ // See also https://github.com/Fyrd/caniuse/issues/1928
+ 'Edge >= 12',
+ 'Explorer >= 10',
+ // Out of leniency, we prefix these 1 version further back than the official policy.
+ 'iOS >= 8',
+ 'Safari >= 8',
+ // The following remain NOT officially supported, but we're lenient and include their prefixes to avoid severely breaking in them.
+ 'Android 2.3',
+ 'Android >= 4',
+ 'Opera >= 12'
+ ]
+ },
+ 'postcss-flexbugs-fixes': {}
+ }
+})
diff --git a/templates/assets/bootstrap/grunt/sauce_browsers.yml b/templates/assets/bootstrap/grunt/sauce_browsers.yml
new file mode 100644
index 0000000..4d5041b
--- /dev/null
+++ b/templates/assets/bootstrap/grunt/sauce_browsers.yml
@@ -0,0 +1,84 @@
+[
+ # Docs: https://wiki.saucelabs.com/display/DOCS/Platform+Configurator
+
+ {
+ browserName: "safari",
+ platform: "OS X 10.11"
+ },
+ {
+ browserName: "chrome",
+ platform: "OS X 10.11",
+ version: "latest"
+ },
+ {
+ browserName: "firefox",
+ platform: "OS X 10.11",
+ version: "latest"
+ },
+
+ # Mac Opera not currently supported by Sauce Labs
+
+ {
+ browserName: "MicrosoftEdge",
+ platform: "Windows 10",
+ version: "latest"
+ },
+ {
+ browserName: "internet explorer",
+ version: "11",
+ platform: "Windows 8.1"
+ },
+ {
+ browserName: "internet explorer",
+ version: "10",
+ platform: "Windows 8"
+ },
+ {
+ browserName: "internet explorer",
+ version: "9",
+ platform: "Windows 7"
+ },
+
+ {
+ browserName: "chrome",
+ platform: "Windows 10",
+ version: "latest"
+ },
+ {
+ browserName: "firefox",
+ platform: "Windows 10",
+ version: "latest"
+ },
+
+ # Win Opera 15+ not currently supported by Sauce Labs
+
+ {
+ browserName: "Safari",
+ deviceName: "iPhone Simulator",
+ platformVersion: "9.3",
+ platformName: "iOS"
+ },
+
+ # iOS Chrome not currently supported by Sauce Labs
+
+ # Linux (unofficial)
+ {
+ browserName: "chrome",
+ platform: "Linux",
+ version: "latest"
+ },
+ {
+ browserName: "firefox",
+ platform: "Linux",
+ version: "latest"
+ },
+
+ # Android
+ {
+ platform: "Linux",
+ browserName: "android",
+ deviceName: "Android Emulator",
+ version: "latest",
+ deviceType: "phone"
+ }
+]
diff --git a/templates/assets/bootstrap/grunt/upload-preview.sh b/templates/assets/bootstrap/grunt/upload-preview.sh
new file mode 100755
index 0000000..08e7fa2
--- /dev/null
+++ b/templates/assets/bootstrap/grunt/upload-preview.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Upload built docs to preview.twbsapps.com
+
+if [ "$TRAVIS_REPO_SLUG" != twbs-savage/bootstrap ]; then exit 0; fi
+
+# Add build metadata to version
+sed -i "/^current_version:/ s/\$/+pr.${TRAVIS_COMMIT}/" _config.yml
+# Fix URLs since the site's root is now a subdirectory
+bundle exec jekyll build --destination "$TRAVIS_COMMIT" --baseurl "/c/${TRAVIS_COMMIT}"
+
+# Install gcloud & gsutil
+GSUTIL_VERSION=$(gsutil version | cut -d ' ' -f 3)
+if [ ! -d "${HOME}/google-cloud-sdk" ] || [ "${GSUTIL_VERSION}" != '4.19' ]; then
+ rm -rf "${HOME}/google-cloud-sdk" # Kill Travis' outdated non-updateable preinstalled version
+ echo 'Installing google-cloud-sdk...'
+ export CLOUDSDK_CORE_DISABLE_PROMPTS=1
+ time (curl -S -s https://sdk.cloud.google.com | bash &>/dev/null)
+ echo 'Done.'
+fi
+source "${HOME}/google-cloud-sdk/path.bash.inc"
+
+openssl aes-256-cbc -K $encrypted_2b749c8e6327_key -iv $encrypted_2b749c8e6327_iv -in grunt/gcp-key.json.enc -out grunt/gcp-key.json -d
+gcloud auth activate-service-account "$GCP_SERVICE_ACCOUNT" --key-file grunt/gcp-key.json &> /dev/null || (echo 'GCP login failed!'; exit 1)
+
+echo "Uploading to http://preview.twbsapps.com/c/${TRAVIS_COMMIT} ..."
+time gsutil -q -m cp -z html,css,js,svg -r "./${TRAVIS_COMMIT}" gs://preview.twbsapps.com/c/
+echo 'Done.'
diff --git a/templates/assets/bootstrap/js/.eslintrc.json b/templates/assets/bootstrap/js/.eslintrc.json
new file mode 100644
index 0000000..07a307a
--- /dev/null
+++ b/templates/assets/bootstrap/js/.eslintrc.json
@@ -0,0 +1,240 @@
+{
+ "root": true,
+ "parser": "babel-eslint",
+ "env": {
+ "browser": true,
+ "es6": true,
+ "jquery": true
+ },
+ "extends": "eslint:recommended",
+ "parserOptions": {
+ "ecmaVersion": 8,
+ "sourceType": "module"
+ },
+ "rules": {
+ // Possible Errors
+ "no-await-in-loop": "error",
+ "no-compare-neg-zero": "error",
+ "no-extra-parens": "error",
+ "no-prototype-builtins": "off",
+ "no-template-curly-in-string": "error",
+ "no-unsafe-negation": "error",
+ "valid-jsdoc": "error",
+
+ // Best Practices
+ "accessor-pairs": "error",
+ "array-callback-return": "error",
+ "block-scoped-var": "error",
+ "class-methods-use-this": "off",
+ "complexity": "error",
+ "consistent-return": "error",
+ "curly": "error",
+ "default-case": "error",
+ "dot-location": ["error", "property"],
+ "dot-notation": "error",
+ "eqeqeq": "error",
+ "guard-for-in": "error",
+ "no-alert": "error",
+ "no-caller": "error",
+ "no-div-regex": "error",
+ "no-else-return": "error",
+ "no-empty-function": "error",
+ "no-eq-null": "error",
+ "no-eval": "error",
+ "no-extend-native": "error",
+ "no-extra-bind": "error",
+ "no-extra-label": "error",
+ "no-floating-decimal": "error",
+ "no-global-assign": "error",
+ "no-implicit-coercion": "error",
+ "no-implicit-globals": "error",
+ "no-implied-eval": "error",
+ "no-invalid-this": "off",
+ "no-iterator": "error",
+ "no-labels": "error",
+ "no-lone-blocks": "error",
+ "no-loop-func": "error",
+ "no-magic-numbers": ["error", {
+ "ignore": [-1, 0, 1],
+ "ignoreArrayIndexes": true
+ }
+ ],
+ "no-multi-spaces": ["error", {
+ "exceptions": {
+ "AssignmentExpression": true,
+ "ArrowFunctionExpression": true,
+ "CallExpression": true,
+ "VariableDeclarator": true
+ }
+ }
+ ],
+ "no-multi-str": "error",
+ "no-new": "error",
+ "no-new-func": "off",
+ "no-new-wrappers": "error",
+ "no-new": "error",
+ "no-octal-escape": "error",
+ "no-param-reassign": "off",
+ "no-proto": "error",
+ "no-restricted-properties": "error",
+ "no-return-assign": "off",
+ "no-return-await": "error",
+ "no-script-url": "error",
+ "no-self-compare": "error",
+ "no-sequences": "error",
+ "no-throw-literal": "error",
+ "no-unmodified-loop-condition": "error",
+ "no-unused-expressions": "error",
+ "no-useless-call": "error",
+ "no-useless-concat": "error",
+ "no-useless-escape": "error",
+ "no-useless-return": "off",
+ "no-void": "error",
+ "no-warning-comments": "off",
+ "no-with": "error",
+ "prefer-promise-reject-errors": "error",
+ "radix": "error",
+ "vars-on-top": "error",
+ "wrap-iife": "error",
+ "yoda": "error",
+
+ // Strict Mode
+ "strict": "error",
+
+ // Variables
+ "init-declarations": "off",
+ "no-catch-shadow": "error",
+ "no-label-var": "error",
+ "no-restricted-globals": "error",
+ "no-shadow": "off",
+ "no-shadow-restricted-names": "error",
+ "no-undef-init": "error",
+ "no-undefined": "off",
+ "no-use-before-define": "off",
+
+ // Node.js and CommonJS
+ "callback-return": "off",
+ "global-require": "error",
+ "handle-callback-err": "error",
+ "no-mixed-requires": "error",
+ "no-new-require": "error",
+ "no-path-concat": "error",
+ "no-process-env": "error",
+ "no-process-exit": "error",
+ "no-restricted-modules": "error",
+ "no-sync": "error",
+
+ // Stylistic Issues
+ "array-bracket-spacing": "error",
+ "block-spacing": "error",
+ "brace-style": "error",
+ "capitalized-comments": "off",
+ "camelcase": "error",
+ "comma-dangle": "error",
+ "comma-spacing": "error",
+ "comma-style": "error",
+ "computed-property-spacing": "error",
+ "consistent-this": "error",
+ "eol-last": "error",
+ "func-call-spacing": "error",
+ "func-name-matching": "error",
+ "func-names": "off",
+ "func-style": ["error", "declaration"],
+ "id-blacklist": "error",
+ "id-length": "off",
+ "id-match": "error",
+ "indent": ["error", 2, { "SwitchCase": 1 }],
+ "jsx-quotes": "error",
+ "key-spacing": "off",
+ "keyword-spacing": "error",
+ "line-comment-position": "off",
+ "linebreak-style": ["error", "unix"],
+ "lines-around-comment": "off",
+ "lines-around-directive": "error",
+ "max-depth": ["error", 10],
+ "max-len": "off",
+ "max-lines": "off",
+ "max-nested-callbacks": "error",
+ "max-params": "off",
+ "max-statements": "off",
+ "max-statements-per-line": "error",
+ "multiline-ternary": "off",
+ "new-cap": ["error", { "capIsNewExceptionPattern": "$.*" }],
+ "new-parens": "error",
+ "newline-after-var": "off",
+ "newline-before-return": "off",
+ "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 5 }],
+ "no-array-constructor": "error",
+ "no-bitwise": "error",
+ "no-continue": "off",
+ "no-inline-comments": "off",
+ "no-lonely-if": "error",
+ "no-mixed-operators": "off",
+ "no-multi-assign": "error",
+ "no-multiple-empty-lines": "error",
+ "no-negated-condition": "off",
+ "no-nested-ternary": "error",
+ "no-new-object": "error",
+ "no-plusplus": "off",
+ "no-restricted-syntax": "error",
+ "no-tabs": "error",
+ "no-ternary": "off",
+ "no-trailing-spaces": "error",
+ "no-underscore-dangle": "off",
+ "no-unneeded-ternary": "error",
+ "no-whitespace-before-property": "error",
+ "nonblock-statement-body-position": "error",
+ "object-curly-newline": ["error", { "minProperties": 1 }],
+ "object-curly-spacing": ["error", "always"],
+ "object-property-newline": "error",
+ "one-var": ["error", "never"],
+ "one-var-declaration-per-line": "error",
+ "operator-assignment": "error",
+ "operator-linebreak": "off",
+ "padded-blocks": "off",
+ "quote-props": ["error", "as-needed"],
+ "quotes": ["error", "single"],
+ "require-jsdoc": "off",
+ "semi": ["error", "never"],
+ "semi-spacing": "error",
+ "sort-keys": "off",
+ "sort-vars": "error",
+ "space-before-blocks": "error",
+ "space-before-function-paren": ["error", {
+ "anonymous": "always",
+ "named": "never"
+ }],
+ "space-in-parens": "error",
+ "space-infix-ops": "error",
+ "space-unary-ops": "error",
+ "spaced-comment": "error",
+ "template-tag-spacing": "error",
+ "unicode-bom": "error",
+ "wrap-regex": "off",
+
+ // ECMAScript 6
+ "arrow-body-style": "off",
+ "arrow-parens": "error",
+ "arrow-spacing": "error",
+ "generator-star-spacing": "error",
+ "no-confusing-arrow": "error",
+ "no-duplicate-imports": "error",
+ "no-restricted-imports": "error",
+ "no-useless-computed-key": "error",
+ "no-useless-constructor": "error",
+ "no-useless-rename": "error",
+ "no-var": "error",
+ "object-shorthand": "error",
+ "prefer-arrow-callback": "error",
+ "prefer-const": "error",
+ "prefer-numeric-literals": "error",
+ "prefer-rest-params": "error",
+ "prefer-spread": "error",
+ "prefer-template": "error",
+ "rest-spread-spacing": "error",
+ "sort-imports": "error",
+ "symbol-description": "error",
+ "template-curly-spacing": "error",
+ "yield-star-spacing": "error"
+ }
+}
diff --git a/templates/assets/bootstrap/js/src/alert.js b/templates/assets/bootstrap/js/src/alert.js
new file mode 100644
index 0000000..b30d0d3
--- /dev/null
+++ b/templates/assets/bootstrap/js/src/alert.js
@@ -0,0 +1,193 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): alert.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Alert = (($) => {
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+ const NAME = 'alert'
+ const VERSION = '4.0.0-alpha.6'
+ const DATA_KEY = 'bs.alert'
+ const EVENT_KEY = `.${DATA_KEY}`
+ const DATA_API_KEY = '.data-api'
+ const JQUERY_NO_CONFLICT = $.fn[NAME]
+ const TRANSITION_DURATION = 150
+
+ const Selector = {
+ DISMISS : '[data-dismiss="alert"]'
+ }
+
+ const Event = {
+ CLOSE : `close${EVENT_KEY}`,
+ CLOSED : `closed${EVENT_KEY}`,
+ CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
+ }
+
+ const ClassName = {
+ ALERT : 'alert',
+ FADE : 'fade',
+ SHOW : 'show'
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ class Alert {
+
+ constructor(element) {
+ this._element = element
+ }
+
+
+ // getters
+
+ static get VERSION() {
+ return VERSION
+ }
+
+
+ // public
+
+ close(element) {
+ element = element || this._element
+
+ const rootElement = this._getRootElement(element)
+ const customEvent = this._triggerCloseEvent(rootElement)
+
+ if (customEvent.isDefaultPrevented()) {
+ return
+ }
+
+ this._removeElement(rootElement)
+ }
+
+ dispose() {
+ $.removeData(this._element, DATA_KEY)
+ this._element = null
+ }
+
+
+ // private
+
+ _getRootElement(element) {
+ const selector = Util.getSelectorFromElement(element)
+ let parent = false
+
+ if (selector) {
+ parent = $(selector)[0]
+ }
+
+ if (!parent) {
+ parent = $(element).closest(`.${ClassName.ALERT}`)[0]
+ }
+
+ return parent
+ }
+
+ _triggerCloseEvent(element) {
+ const closeEvent = $.Event(Event.CLOSE)
+
+ $(element).trigger(closeEvent)
+ return closeEvent
+ }
+
+ _removeElement(element) {
+ $(element).removeClass(ClassName.SHOW)
+
+ if (!Util.supportsTransitionEnd() ||
+ !$(element).hasClass(ClassName.FADE)) {
+ this._destroyElement(element)
+ return
+ }
+
+ $(element)
+ .one(Util.TRANSITION_END, (event) => this._destroyElement(element, event))
+ .emulateTransitionEnd(TRANSITION_DURATION)
+ }
+
+ _destroyElement(element) {
+ $(element)
+ .detach()
+ .trigger(Event.CLOSED)
+ .remove()
+ }
+
+
+ // static
+
+ static _jQueryInterface(config) {
+ return this.each(function () {
+ const $element = $(this)
+ let data = $element.data(DATA_KEY)
+
+ if (!data) {
+ data = new Alert(this)
+ $element.data(DATA_KEY, data)
+ }
+
+ if (config === 'close') {
+ data[config](this)
+ }
+ })
+ }
+
+ static _handleDismiss(alertInstance) {
+ return function (event) {
+ if (event) {
+ event.preventDefault()
+ }
+
+ alertInstance.close(this)
+ }
+ }
+
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+ $(document).on(
+ Event.CLICK_DATA_API,
+ Selector.DISMISS,
+ Alert._handleDismiss(new Alert())
+ )
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME] = Alert._jQueryInterface
+ $.fn[NAME].Constructor = Alert
+ $.fn[NAME].noConflict = function () {
+ $.fn[NAME] = JQUERY_NO_CONFLICT
+ return Alert._jQueryInterface
+ }
+
+ return Alert
+
+})(jQuery)
+
+export default Alert
diff --git a/templates/assets/bootstrap/js/src/button.js b/templates/assets/bootstrap/js/src/button.js
new file mode 100644
index 0000000..76c5cdd
--- /dev/null
+++ b/templates/assets/bootstrap/js/src/button.js
@@ -0,0 +1,176 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): button.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Button = (($) => {
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+ const NAME = 'button'
+ const VERSION = '4.0.0-alpha.6'
+ const DATA_KEY = 'bs.button'
+ const EVENT_KEY = `.${DATA_KEY}`
+ const DATA_API_KEY = '.data-api'
+ const JQUERY_NO_CONFLICT = $.fn[NAME]
+
+ const ClassName = {
+ ACTIVE : 'active',
+ BUTTON : 'btn',
+ FOCUS : 'focus'
+ }
+
+ const Selector = {
+ DATA_TOGGLE_CARROT : '[data-toggle^="button"]',
+ DATA_TOGGLE : '[data-toggle="buttons"]',
+ INPUT : 'input',
+ ACTIVE : '.active',
+ BUTTON : '.btn'
+ }
+
+ const Event = {
+ CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,
+ FOCUS_BLUR_DATA_API : `focus${EVENT_KEY}${DATA_API_KEY} `
+ + `blur${EVENT_KEY}${DATA_API_KEY}`
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ class Button {
+
+ constructor(element) {
+ this._element = element
+ }
+
+
+ // getters
+
+ static get VERSION() {
+ return VERSION
+ }
+
+
+ // public
+
+ toggle() {
+ let triggerChangeEvent = true
+ const rootElement = $(this._element).closest(
+ Selector.DATA_TOGGLE
+ )[0]
+
+ if (rootElement) {
+ const input = $(this._element).find(Selector.INPUT)[0]
+
+ if (input) {
+ if (input.type === 'radio') {
+ if (input.checked &&
+ $(this._element).hasClass(ClassName.ACTIVE)) {
+ triggerChangeEvent = false
+
+ } else {
+ const activeElement = $(rootElement).find(Selector.ACTIVE)[0]
+
+ if (activeElement) {
+ $(activeElement).removeClass(ClassName.ACTIVE)
+ }
+ }
+ }
+
+ if (triggerChangeEvent) {
+ input.checked = !$(this._element).hasClass(ClassName.ACTIVE)
+ $(input).trigger('change')
+ }
+
+ input.focus()
+ }
+
+ }
+
+ this._element.setAttribute('aria-pressed',
+ !$(this._element).hasClass(ClassName.ACTIVE))
+
+ if (triggerChangeEvent) {
+ $(this._element).toggleClass(ClassName.ACTIVE)
+ }
+ }
+
+ dispose() {
+ $.removeData(this._element, DATA_KEY)
+ this._element = null
+ }
+
+
+ // static
+
+ static _jQueryInterface(config) {
+ return this.each(function () {
+ let data = $(this).data(DATA_KEY)
+
+ if (!data) {
+ data = new Button(this)
+ $(this).data(DATA_KEY, data)
+ }
+
+ if (config === 'toggle') {
+ data[config]()
+ }
+ })
+ }
+
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+ $(document)
+ .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
+ event.preventDefault()
+
+ let button = event.target
+
+ if (!$(button).hasClass(ClassName.BUTTON)) {
+ button = $(button).closest(Selector.BUTTON)
+ }
+
+ Button._jQueryInterface.call($(button), 'toggle')
+ })
+ .on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
+ const button = $(event.target).closest(Selector.BUTTON)[0]
+ $(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type))
+ })
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME] = Button._jQueryInterface
+ $.fn[NAME].Constructor = Button
+ $.fn[NAME].noConflict = function () {
+ $.fn[NAME] = JQUERY_NO_CONFLICT
+ return Button._jQueryInterface
+ }
+
+ return Button
+
+})(jQuery)
+
+export default Button
diff --git a/templates/assets/bootstrap/js/src/carousel.js b/templates/assets/bootstrap/js/src/carousel.js
new file mode 100644
index 0000000..8a75cb2
--- /dev/null
+++ b/templates/assets/bootstrap/js/src/carousel.js
@@ -0,0 +1,497 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): carousel.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Carousel = (($) => {
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+ const NAME = 'carousel'
+ const VERSION = '4.0.0-alpha.6'
+ const DATA_KEY = 'bs.carousel'
+ const EVENT_KEY = `.${DATA_KEY}`
+ const DATA_API_KEY = '.data-api'
+ const JQUERY_NO_CONFLICT = $.fn[NAME]
+ const TRANSITION_DURATION = 600
+ const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key
+ const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key
+
+ const Default = {
+ interval : 5000,
+ keyboard : true,
+ slide : false,
+ pause : 'hover',
+ wrap : true
+ }
+
+ const DefaultType = {
+ interval : '(number|boolean)',
+ keyboard : 'boolean',
+ slide : '(boolean|string)',
+ pause : '(string|boolean)',
+ wrap : 'boolean'
+ }
+
+ const Direction = {
+ NEXT : 'next',
+ PREV : 'prev',
+ LEFT : 'left',
+ RIGHT : 'right'
+ }
+
+ const Event = {
+ SLIDE : `slide${EVENT_KEY}`,
+ SLID : `slid${EVENT_KEY}`,
+ KEYDOWN : `keydown${EVENT_KEY}`,
+ MOUSEENTER : `mouseenter${EVENT_KEY}`,
+ MOUSELEAVE : `mouseleave${EVENT_KEY}`,
+ LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`,
+ CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
+ }
+
+ const ClassName = {
+ CAROUSEL : 'carousel',
+ ACTIVE : 'active',
+ SLIDE : 'slide',
+ RIGHT : 'carousel-item-right',
+ LEFT : 'carousel-item-left',
+ NEXT : 'carousel-item-next',
+ PREV : 'carousel-item-prev',
+ ITEM : 'carousel-item'
+ }
+
+ const Selector = {
+ ACTIVE : '.active',
+ ACTIVE_ITEM : '.active.carousel-item',
+ ITEM : '.carousel-item',
+ NEXT_PREV : '.carousel-item-next, .carousel-item-prev',
+ INDICATORS : '.carousel-indicators',
+ DATA_SLIDE : '[data-slide], [data-slide-to]',
+ DATA_RIDE : '[data-ride="carousel"]'
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ class Carousel {
+
+ constructor(element, config) {
+ this._items = null
+ this._interval = null
+ this._activeElement = null
+
+ this._isPaused = false
+ this._isSliding = false
+
+ this._config = this._getConfig(config)
+ this._element = $(element)[0]
+ this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0]
+
+ this._addEventListeners()
+ }
+
+
+ // getters
+
+ static get VERSION() {
+ return VERSION
+ }
+
+ static get Default() {
+ return Default
+ }
+
+
+ // public
+
+ next() {
+ if (this._isSliding) {
+ throw new Error('Carousel is sliding')
+ }
+ this._slide(Direction.NEXT)
+ }
+
+ nextWhenVisible() {
+ // Don't call next when the page isn't visible
+ if (!document.hidden) {
+ this.next()
+ }
+ }
+
+ prev() {
+ if (this._isSliding) {
+ throw new Error('Carousel is sliding')
+ }
+ this._slide(Direction.PREV)
+ }
+
+ pause(event) {
+ if (!event) {
+ this._isPaused = true
+ }
+
+ if ($(this._element).find(Selector.NEXT_PREV)[0] &&
+ Util.supportsTransitionEnd()) {
+ Util.triggerTransitionEnd(this._element)
+ this.cycle(true)
+ }
+
+ clearInterval(this._interval)
+ this._interval = null
+ }
+
+ cycle(event) {
+ if (!event) {
+ this._isPaused = false
+ }
+
+ if (this._interval) {
+ clearInterval(this._interval)
+ this._interval = null
+ }
+
+ if (this._config.interval && !this._isPaused) {
+ this._interval = setInterval(
+ (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),
+ this._config.interval
+ )
+ }
+ }
+
+ to(index) {
+ this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]
+
+ const activeIndex = this._getItemIndex(this._activeElement)
+
+ if (index > this._items.length - 1 || index < 0) {
+ return
+ }
+
+ if (this._isSliding) {
+ $(this._element).one(Event.SLID, () => this.to(index))
+ return
+ }
+
+ if (activeIndex === index) {
+ this.pause()
+ this.cycle()
+ return
+ }
+
+ const direction = index > activeIndex ?
+ Direction.NEXT :
+ Direction.PREV
+
+ this._slide(direction, this._items[index])
+ }
+
+ dispose() {
+ $(this._element).off(EVENT_KEY)
+ $.removeData(this._element, DATA_KEY)
+
+ this._items = null
+ this._config = null
+ this._element = null
+ this._interval = null
+ this._isPaused = null
+ this._isSliding = null
+ this._activeElement = null
+ this._indicatorsElement = null
+ }
+
+
+ // private
+
+ _getConfig(config) {
+ config = $.extend({}, Default, config)
+ Util.typeCheckConfig(NAME, config, DefaultType)
+ return config
+ }
+
+ _addEventListeners() {
+ if (this._config.keyboard) {
+ $(this._element)
+ .on(Event.KEYDOWN, (event) => this._keydown(event))
+ }
+
+ if (this._config.pause === 'hover' &&
+ !('ontouchstart' in document.documentElement)) {
+ $(this._element)
+ .on(Event.MOUSEENTER, (event) => this.pause(event))
+ .on(Event.MOUSELEAVE, (event) => this.cycle(event))
+ }
+ }
+
+ _keydown(event) {
+ if (/input|textarea/i.test(event.target.tagName)) {
+ return
+ }
+
+ switch (event.which) {
+ case ARROW_LEFT_KEYCODE:
+ event.preventDefault()
+ this.prev()
+ break
+ case ARROW_RIGHT_KEYCODE:
+ event.preventDefault()
+ this.next()
+ break
+ default:
+ return
+ }
+ }
+
+ _getItemIndex(element) {
+ this._items = $.makeArray($(element).parent().find(Selector.ITEM))
+ return this._items.indexOf(element)
+ }
+
+ _getItemByDirection(direction, activeElement) {
+ const isNextDirection = direction === Direction.NEXT
+ const isPrevDirection = direction === Direction.PREV
+ const activeIndex = this._getItemIndex(activeElement)
+ const lastItemIndex = this._items.length - 1
+ const isGoingToWrap = isPrevDirection && activeIndex === 0 ||
+ isNextDirection && activeIndex === lastItemIndex
+
+ if (isGoingToWrap && !this._config.wrap) {
+ return activeElement
+ }
+
+ const delta = direction === Direction.PREV ? -1 : 1
+ const itemIndex = (activeIndex + delta) % this._items.length
+
+ return itemIndex === -1 ?
+ this._items[this._items.length - 1] : this._items[itemIndex]
+ }
+
+
+ _triggerSlideEvent(relatedTarget, eventDirectionName) {
+ const slideEvent = $.Event(Event.SLIDE, {
+ relatedTarget,
+ direction: eventDirectionName
+ })
+
+ $(this._element).trigger(slideEvent)
+
+ return slideEvent
+ }
+
+ _setActiveIndicatorElement(element) {
+ if (this._indicatorsElement) {
+ $(this._indicatorsElement)
+ .find(Selector.ACTIVE)
+ .removeClass(ClassName.ACTIVE)
+
+ const nextIndicator = this._indicatorsElement.children[
+ this._getItemIndex(element)
+ ]
+
+ if (nextIndicator) {
+ $(nextIndicator).addClass(ClassName.ACTIVE)
+ }
+ }
+ }
+
+ _slide(direction, element) {
+ const activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]
+ const nextElement = element || activeElement &&
+ this._getItemByDirection(direction, activeElement)
+
+ const isCycling = Boolean(this._interval)
+
+ let directionalClassName
+ let orderClassName
+ let eventDirectionName
+
+ if (direction === Direction.NEXT) {
+ directionalClassName = ClassName.LEFT
+ orderClassName = ClassName.NEXT
+ eventDirectionName = Direction.LEFT
+ } else {
+ directionalClassName = ClassName.RIGHT
+ orderClassName = ClassName.PREV
+ eventDirectionName = Direction.RIGHT
+ }
+
+ if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {
+ this._isSliding = false
+ return
+ }
+
+ const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)
+ if (slideEvent.isDefaultPrevented()) {
+ return
+ }
+
+ if (!activeElement || !nextElement) {
+ // some weirdness is happening, so we bail
+ return
+ }
+
+ this._isSliding = true
+
+ if (isCycling) {
+ this.pause()
+ }
+
+ this._setActiveIndicatorElement(nextElement)
+
+ const slidEvent = $.Event(Event.SLID, {
+ relatedTarget: nextElement,
+ direction: eventDirectionName
+ })
+
+ if (Util.supportsTransitionEnd() &&
+ $(this._element).hasClass(ClassName.SLIDE)) {
+
+ $(nextElement).addClass(orderClassName)
+
+ Util.reflow(nextElement)
+
+ $(activeElement).addClass(directionalClassName)
+ $(nextElement).addClass(directionalClassName)
+
+ $(activeElement)
+ .one(Util.TRANSITION_END, () => {
+ $(nextElement)
+ .removeClass(`${directionalClassName} ${orderClassName}`)
+ .addClass(ClassName.ACTIVE)
+
+ $(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`)
+
+ this._isSliding = false
+
+ setTimeout(() => $(this._element).trigger(slidEvent), 0)
+
+ })
+ .emulateTransitionEnd(TRANSITION_DURATION)
+
+ } else {
+ $(activeElement).removeClass(ClassName.ACTIVE)
+ $(nextElement).addClass(ClassName.ACTIVE)
+
+ this._isSliding = false
+ $(this._element).trigger(slidEvent)
+ }
+
+ if (isCycling) {
+ this.cycle()
+ }
+ }
+
+
+ // static
+
+ static _jQueryInterface(config) {
+ return this.each(function () {
+ let data = $(this).data(DATA_KEY)
+ const _config = $.extend({}, Default, $(this).data())
+
+ if (typeof config === 'object') {
+ $.extend(_config, config)
+ }
+
+ const action = typeof config === 'string' ? config : _config.slide
+
+ if (!data) {
+ data = new Carousel(this, _config)
+ $(this).data(DATA_KEY, data)
+ }
+
+ if (typeof config === 'number') {
+ data.to(config)
+ } else if (typeof action === 'string') {
+ if (data[action] === undefined) {
+ throw new Error(`No method named "${action}"`)
+ }
+ data[action]()
+ } else if (_config.interval) {
+ data.pause()
+ data.cycle()
+ }
+ })
+ }
+
+ static _dataApiClickHandler(event) {
+ const selector = Util.getSelectorFromElement(this)
+
+ if (!selector) {
+ return
+ }
+
+ const target = $(selector)[0]
+
+ if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {
+ return
+ }
+
+ const config = $.extend({}, $(target).data(), $(this).data())
+ const slideIndex = this.getAttribute('data-slide-to')
+
+ if (slideIndex) {
+ config.interval = false
+ }
+
+ Carousel._jQueryInterface.call($(target), config)
+
+ if (slideIndex) {
+ $(target).data(DATA_KEY).to(slideIndex)
+ }
+
+ event.preventDefault()
+ }
+
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+ $(document)
+ .on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler)
+
+ $(window).on(Event.LOAD_DATA_API, () => {
+ $(Selector.DATA_RIDE).each(function () {
+ const $carousel = $(this)
+ Carousel._jQueryInterface.call($carousel, $carousel.data())
+ })
+ })
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME] = Carousel._jQueryInterface
+ $.fn[NAME].Constructor = Carousel
+ $.fn[NAME].noConflict = function () {
+ $.fn[NAME] = JQUERY_NO_CONFLICT
+ return Carousel._jQueryInterface
+ }
+
+ return Carousel
+
+})(jQuery)
+
+export default Carousel
diff --git a/templates/assets/bootstrap/js/src/collapse.js b/templates/assets/bootstrap/js/src/collapse.js
new file mode 100644
index 0000000..13c4450
--- /dev/null
+++ b/templates/assets/bootstrap/js/src/collapse.js
@@ -0,0 +1,393 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): collapse.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Collapse = (($) => {
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+ const NAME = 'collapse'
+ const VERSION = '4.0.0-alpha.6'
+ const DATA_KEY = 'bs.collapse'
+ const EVENT_KEY = `.${DATA_KEY}`
+ const DATA_API_KEY = '.data-api'
+ const JQUERY_NO_CONFLICT = $.fn[NAME]
+ const TRANSITION_DURATION = 600
+
+ const Default = {
+ toggle : true,
+ parent : ''
+ }
+
+ const DefaultType = {
+ toggle : 'boolean',
+ parent : 'string'
+ }
+
+ const Event = {
+ SHOW : `show${EVENT_KEY}`,
+ SHOWN : `shown${EVENT_KEY}`,
+ HIDE : `hide${EVENT_KEY}`,
+ HIDDEN : `hidden${EVENT_KEY}`,
+ CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
+ }
+
+ const ClassName = {
+ SHOW : 'show',
+ COLLAPSE : 'collapse',
+ COLLAPSING : 'collapsing',
+ COLLAPSED : 'collapsed'
+ }
+
+ const Dimension = {
+ WIDTH : 'width',
+ HEIGHT : 'height'
+ }
+
+ const Selector = {
+ ACTIVES : '.card > .show, .card > .collapsing',
+ DATA_TOGGLE : '[data-toggle="collapse"]',
+ DATA_CHILDREN : 'data-children'
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ class Collapse {
+
+ constructor(element, config) {
+ this._isTransitioning = false
+ this._element = element
+ this._config = this._getConfig(config)
+ this._triggerArray = $.makeArray($(
+ `[data-toggle="collapse"][href="#${element.id}"],` +
+ `[data-toggle="collapse"][data-target="#${element.id}"]`
+ ))
+ this._parent = this._config.parent ? this._getParent() : null
+
+ if (!this._config.parent) {
+ this._addAriaAndCollapsedClass(this._element, this._triggerArray)
+ }
+
+ this._selectorActives = Selector.ACTIVES
+ if (this._parent) {
+ const childrenSelector = this._parent.hasAttribute(Selector.DATA_CHILDREN) ? this._parent.getAttribute(Selector.DATA_CHILDREN) : null
+ if (childrenSelector !== null) {
+ this._selectorActives = `${childrenSelector} > .show, ${childrenSelector} > .collapsing`
+ }
+ }
+
+ if (this._config.toggle) {
+ this.toggle()
+ }
+ }
+
+
+ // getters
+
+ static get VERSION() {
+ return VERSION
+ }
+
+ static get Default() {
+ return Default
+ }
+
+
+ // public
+
+ toggle() {
+ if ($(this._element).hasClass(ClassName.SHOW)) {
+ this.hide()
+ } else {
+ this.show()
+ }
+ }
+
+ show() {
+ if (this._isTransitioning) {
+ throw new Error('Collapse is transitioning')
+ }
+
+ if ($(this._element).hasClass(ClassName.SHOW)) {
+ return
+ }
+
+ let actives
+ let activesData
+
+ if (this._parent) {
+ actives = $.makeArray($(this._parent).find(this._selectorActives))
+ if (!actives.length) {
+ actives = null
+ }
+ }
+
+ if (actives) {
+ activesData = $(actives).data(DATA_KEY)
+ if (activesData && activesData._isTransitioning) {
+ return
+ }
+ }
+
+ const startEvent = $.Event(Event.SHOW)
+ $(this._element).trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) {
+ return
+ }
+
+ if (actives) {
+ Collapse._jQueryInterface.call($(actives), 'hide')
+ if (!activesData) {
+ $(actives).data(DATA_KEY, null)
+ }
+ }
+
+ const dimension = this._getDimension()
+
+ $(this._element)
+ .removeClass(ClassName.COLLAPSE)
+ .addClass(ClassName.COLLAPSING)
+
+ this._element.style[dimension] = 0
+ this._element.setAttribute('aria-expanded', true)
+
+ if (this._triggerArray.length) {
+ $(this._triggerArray)
+ .removeClass(ClassName.COLLAPSED)
+ .attr('aria-expanded', true)
+ }
+
+ this.setTransitioning(true)
+
+ const complete = () => {
+ $(this._element)
+ .removeClass(ClassName.COLLAPSING)
+ .addClass(ClassName.COLLAPSE)
+ .addClass(ClassName.SHOW)
+
+ this._element.style[dimension] = ''
+
+ this.setTransitioning(false)
+
+ $(this._element).trigger(Event.SHOWN)
+ }
+
+ if (!Util.supportsTransitionEnd()) {
+ complete()
+ return
+ }
+
+ const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
+ const scrollSize = `scroll${capitalizedDimension}`
+
+ $(this._element)
+ .one(Util.TRANSITION_END, complete)
+ .emulateTransitionEnd(TRANSITION_DURATION)
+
+ this._element.style[dimension] = `${this._element[scrollSize]}px`
+ }
+
+ hide() {
+ if (this._isTransitioning) {
+ throw new Error('Collapse is transitioning')
+ }
+
+ if (!$(this._element).hasClass(ClassName.SHOW)) {
+ return
+ }
+
+ const startEvent = $.Event(Event.HIDE)
+ $(this._element).trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) {
+ return
+ }
+
+ const dimension = this._getDimension()
+
+ this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`
+
+ Util.reflow(this._element)
+
+ $(this._element)
+ .addClass(ClassName.COLLAPSING)
+ .removeClass(ClassName.COLLAPSE)
+ .removeClass(ClassName.SHOW)
+
+ this._element.setAttribute('aria-expanded', false)
+
+ if (this._triggerArray.length) {
+ $(this._triggerArray)
+ .addClass(ClassName.COLLAPSED)
+ .attr('aria-expanded', false)
+ }
+
+ this.setTransitioning(true)
+
+ const complete = () => {
+ this.setTransitioning(false)
+ $(this._element)
+ .removeClass(ClassName.COLLAPSING)
+ .addClass(ClassName.COLLAPSE)
+ .trigger(Event.HIDDEN)
+ }
+
+ this._element.style[dimension] = ''
+
+ if (!Util.supportsTransitionEnd()) {
+ complete()
+ return
+ }
+
+ $(this._element)
+ .one(Util.TRANSITION_END, complete)
+ .emulateTransitionEnd(TRANSITION_DURATION)
+ }
+
+ setTransitioning(isTransitioning) {
+ this._isTransitioning = isTransitioning
+ }
+
+ dispose() {
+ $.removeData(this._element, DATA_KEY)
+
+ this._config = null
+ this._parent = null
+ this._element = null
+ this._triggerArray = null
+ this._isTransitioning = null
+ }
+
+
+ // private
+
+ _getConfig(config) {
+ config = $.extend({}, Default, config)
+ config.toggle = Boolean(config.toggle) // coerce string values
+ Util.typeCheckConfig(NAME, config, DefaultType)
+ return config
+ }
+
+ _getDimension() {
+ const hasWidth = $(this._element).hasClass(Dimension.WIDTH)
+ return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT
+ }
+
+ _getParent() {
+ const parent = $(this._config.parent)[0]
+ const selector =
+ `[data-toggle="collapse"][data-parent="${this._config.parent}"]`
+
+ $(parent).find(selector).each((i, element) => {
+ this._addAriaAndCollapsedClass(
+ Collapse._getTargetFromElement(element),
+ [element]
+ )
+ })
+
+ return parent
+ }
+
+ _addAriaAndCollapsedClass(element, triggerArray) {
+ if (element) {
+ const isOpen = $(element).hasClass(ClassName.SHOW)
+ element.setAttribute('aria-expanded', isOpen)
+
+ if (triggerArray.length) {
+ $(triggerArray)
+ .toggleClass(ClassName.COLLAPSED, !isOpen)
+ .attr('aria-expanded', isOpen)
+ }
+ }
+ }
+
+
+ // static
+
+ static _getTargetFromElement(element) {
+ const selector = Util.getSelectorFromElement(element)
+ return selector ? $(selector)[0] : null
+ }
+
+ static _jQueryInterface(config) {
+ return this.each(function () {
+ const $this = $(this)
+ let data = $this.data(DATA_KEY)
+ const _config = $.extend(
+ {},
+ Default,
+ $this.data(),
+ typeof config === 'object' && config
+ )
+
+ if (!data && _config.toggle && /show|hide/.test(config)) {
+ _config.toggle = false
+ }
+
+ if (!data) {
+ data = new Collapse(this, _config)
+ $this.data(DATA_KEY, data)
+ }
+
+ if (typeof config === 'string') {
+ if (data[config] === undefined) {
+ throw new Error(`No method named "${config}"`)
+ }
+ data[config]()
+ }
+ })
+ }
+
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+ $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+ event.preventDefault()
+
+ const target = Collapse._getTargetFromElement(this)
+ const data = $(target).data(DATA_KEY)
+ const config = data ? 'toggle' : $(this).data()
+
+ Collapse._jQueryInterface.call($(target), config)
+ })
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME] = Collapse._jQueryInterface
+ $.fn[NAME].Constructor = Collapse
+ $.fn[NAME].noConflict = function () {
+ $.fn[NAME] = JQUERY_NO_CONFLICT
+ return Collapse._jQueryInterface
+ }
+
+ return Collapse
+
+})(jQuery)
+
+export default Collapse
diff --git a/templates/assets/bootstrap/js/src/dropdown.js b/templates/assets/bootstrap/js/src/dropdown.js
new file mode 100644
index 0000000..644273a
--- /dev/null
+++ b/templates/assets/bootstrap/js/src/dropdown.js
@@ -0,0 +1,307 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): dropdown.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Dropdown = (($) => {
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+ const NAME = 'dropdown'
+ const VERSION = '4.0.0-alpha.6'
+ const DATA_KEY = 'bs.dropdown'
+ const EVENT_KEY = `.${DATA_KEY}`
+ const DATA_API_KEY = '.data-api'
+ const JQUERY_NO_CONFLICT = $.fn[NAME]
+ const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
+ const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key
+ const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key
+ const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key
+ const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)
+ const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}|${SPACE_KEYCODE}`)
+
+ const Event = {
+ HIDE : `hide${EVENT_KEY}`,
+ HIDDEN : `hidden${EVENT_KEY}`,
+ SHOW : `show${EVENT_KEY}`,
+ SHOWN : `shown${EVENT_KEY}`,
+ CLICK : `click${EVENT_KEY}`,
+ CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,
+ FOCUSIN_DATA_API : `focusin${EVENT_KEY}${DATA_API_KEY}`,
+ KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`
+ }
+
+ const ClassName = {
+ BACKDROP : 'dropdown-backdrop',
+ DISABLED : 'disabled',
+ SHOW : 'show'
+ }
+
+ const Selector = {
+ BACKDROP : '.dropdown-backdrop',
+ DATA_TOGGLE : '[data-toggle="dropdown"]',
+ FORM_CHILD : '.dropdown form',
+ ROLE_MENU : '[role="menu"]',
+ ROLE_LISTBOX : '[role="listbox"]',
+ NAVBAR_NAV : '.navbar-nav',
+ VISIBLE_ITEMS : '[role="menu"] li:not(.disabled) a, '
+ + '[role="listbox"] li:not(.disabled) a'
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ class Dropdown {
+
+ constructor(element) {
+ this._element = element
+
+ this._addEventListeners()
+ }
+
+
+ // getters
+
+ static get VERSION() {
+ return VERSION
+ }
+
+
+ // public
+
+ toggle() {
+ if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+ return false
+ }
+
+ const parent = Dropdown._getParentFromElement(this)
+ const isActive = $(parent).hasClass(ClassName.SHOW)
+
+ Dropdown._clearMenus()
+
+ if (isActive) {
+ return false
+ }
+
+ const relatedTarget = {
+ relatedTarget : this
+ }
+ const showEvent = $.Event(Event.SHOW, relatedTarget)
+
+ $(parent).trigger(showEvent)
+
+ if (showEvent.isDefaultPrevented()) {
+ return false
+ }
+
+ // set the backdrop only if the dropdown menu will be opened
+ if ('ontouchstart' in document.documentElement &&
+ !$(parent).closest(Selector.NAVBAR_NAV).length) {
+
+ // if mobile we use a backdrop because click events don't delegate
+ const dropdown = document.createElement('div')
+ dropdown.className = ClassName.BACKDROP
+ $(dropdown).insertBefore(this)
+ $(dropdown).on('click', Dropdown._clearMenus)
+ }
+
+ this.focus()
+ this.setAttribute('aria-expanded', true)
+
+ $(parent).toggleClass(ClassName.SHOW)
+ $(parent).trigger($.Event(Event.SHOWN, relatedTarget))
+
+ return false
+ }
+
+ dispose() {
+ $.removeData(this._element, DATA_KEY)
+ $(this._element).off(EVENT_KEY)
+ this._element = null
+ }
+
+
+ // private
+
+ _addEventListeners() {
+ $(this._element).on(Event.CLICK, this.toggle)
+ }
+
+
+ // static
+
+ static _jQueryInterface(config) {
+ return this.each(function () {
+ let data = $(this).data(DATA_KEY)
+
+ if (!data) {
+ data = new Dropdown(this)
+ $(this).data(DATA_KEY, data)
+ }
+
+ if (typeof config === 'string') {
+ if (data[config] === undefined) {
+ throw new Error(`No method named "${config}"`)
+ }
+ data[config].call(this)
+ }
+ })
+ }
+
+ static _clearMenus(event) {
+ if (event && event.which === RIGHT_MOUSE_BUTTON_WHICH) {
+ return
+ }
+
+ const toggles = $.makeArray($(Selector.DATA_TOGGLE))
+
+ for (let i = 0; i < toggles.length; i++) {
+ const parent = Dropdown._getParentFromElement(toggles[i])
+ const relatedTarget = {
+ relatedTarget : toggles[i]
+ }
+
+ if (!$(parent).hasClass(ClassName.SHOW)) {
+ continue
+ }
+
+ if (event && (event.type === 'click' &&
+ /input|textarea/i.test(event.target.tagName) || event.type === 'focusin')
+ && $.contains(parent, event.target)) {
+ continue
+ }
+
+ const hideEvent = $.Event(Event.HIDE, relatedTarget)
+ $(parent).trigger(hideEvent)
+ if (hideEvent.isDefaultPrevented()) {
+ continue
+ }
+
+ // remove backdrop only if the dropdown menu will be hidden
+ const backdrop = $(parent).find(Selector.BACKDROP)[0]
+ if (backdrop) {
+ backdrop.parentNode.removeChild(backdrop)
+ }
+
+ toggles[i].setAttribute('aria-expanded', 'false')
+
+ $(parent)
+ .removeClass(ClassName.SHOW)
+ .trigger($.Event(Event.HIDDEN, relatedTarget))
+ }
+ }
+
+ static _getParentFromElement(element) {
+ let parent
+ const selector = Util.getSelectorFromElement(element)
+
+ if (selector) {
+ parent = $(selector)[0]
+ }
+
+ return parent || element.parentNode
+ }
+
+ static _dataApiKeydownHandler(event) {
+ if (!REGEXP_KEYDOWN.test(event.which) ||
+ /input|textarea/i.test(event.target.tagName)) {
+ return
+ }
+
+ event.preventDefault()
+ event.stopPropagation()
+
+ if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+ return
+ }
+
+ const parent = Dropdown._getParentFromElement(this)
+ const isActive = $(parent).hasClass(ClassName.SHOW)
+
+ if (!isActive && event.which !== ESCAPE_KEYCODE ||
+ isActive && event.which === ESCAPE_KEYCODE) {
+
+ if (event.which === ESCAPE_KEYCODE) {
+ const toggle = $(parent).find(Selector.DATA_TOGGLE)[0]
+ $(toggle).trigger('focus')
+ }
+
+ $(this).trigger('click')
+ return
+ }
+
+ const items = $(parent).find(Selector.VISIBLE_ITEMS).get()
+
+ if (!items.length) {
+ return
+ }
+
+ let index = items.indexOf(event.target)
+
+ if (event.which === ARROW_UP_KEYCODE && index > 0) { // up
+ index--
+ }
+
+ if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // down
+ index++
+ }
+
+ if (index < 0) {
+ index = 0
+ }
+
+ items[index].focus()
+ }
+
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+ $(document)
+ .on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler)
+ .on(Event.KEYDOWN_DATA_API, Selector.ROLE_MENU, Dropdown._dataApiKeydownHandler)
+ .on(Event.KEYDOWN_DATA_API, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler)
+ .on(`${Event.CLICK_DATA_API} ${Event.FOCUSIN_DATA_API}`, Dropdown._clearMenus)
+ .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle)
+ .on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => {
+ e.stopPropagation()
+ })
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME] = Dropdown._jQueryInterface
+ $.fn[NAME].Constructor = Dropdown
+ $.fn[NAME].noConflict = function () {
+ $.fn[NAME] = JQUERY_NO_CONFLICT
+ return Dropdown._jQueryInterface
+ }
+
+ return Dropdown
+
+})(jQuery)
+
+export default Dropdown
diff --git a/templates/assets/bootstrap/js/src/modal.js b/templates/assets/bootstrap/js/src/modal.js
new file mode 100644
index 0000000..9263efd
--- /dev/null
+++ b/templates/assets/bootstrap/js/src/modal.js
@@ -0,0 +1,545 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): modal.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Modal = (($) => {
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+ const NAME = 'modal'
+ const VERSION = '4.0.0-alpha.6'
+ const DATA_KEY = 'bs.modal'
+ const EVENT_KEY = `.${DATA_KEY}`
+ const DATA_API_KEY = '.data-api'
+ const JQUERY_NO_CONFLICT = $.fn[NAME]
+ const TRANSITION_DURATION = 300
+ const BACKDROP_TRANSITION_DURATION = 150
+ const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
+
+ const Default = {
+ backdrop : true,
+ keyboard : true,
+ focus : true,
+ show : true
+ }
+
+ const DefaultType = {
+ backdrop : '(boolean|string)',
+ keyboard : 'boolean',
+ focus : 'boolean',
+ show : 'boolean'
+ }
+
+ const Event = {
+ HIDE : `hide${EVENT_KEY}`,
+ HIDDEN : `hidden${EVENT_KEY}`,
+ SHOW : `show${EVENT_KEY}`,
+ SHOWN : `shown${EVENT_KEY}`,
+ FOCUSIN : `focusin${EVENT_KEY}`,
+ RESIZE : `resize${EVENT_KEY}`,
+ CLICK_DISMISS : `click.dismiss${EVENT_KEY}`,
+ KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`,
+ MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`,
+ MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`,
+ CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
+ }
+
+ const ClassName = {
+ SCROLLBAR_MEASURER : 'modal-scrollbar-measure',
+ BACKDROP : 'modal-backdrop',
+ OPEN : 'modal-open',
+ FADE : 'fade',
+ SHOW : 'show'
+ }
+
+ const Selector = {
+ DIALOG : '.modal-dialog',
+ DATA_TOGGLE : '[data-toggle="modal"]',
+ DATA_DISMISS : '[data-dismiss="modal"]',
+ FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ class Modal {
+
+ constructor(element, config) {
+ this._config = this._getConfig(config)
+ this._element = element
+ this._dialog = $(element).find(Selector.DIALOG)[0]
+ this._backdrop = null
+ this._isShown = false
+ this._isBodyOverflowing = false
+ this._ignoreBackdropClick = false
+ this._isTransitioning = false
+ this._originalBodyPadding = 0
+ this._scrollbarWidth = 0
+ }
+
+
+ // getters
+
+ static get VERSION() {
+ return VERSION
+ }
+
+ static get Default() {
+ return Default
+ }
+
+
+ // public
+
+ toggle(relatedTarget) {
+ return this._isShown ? this.hide() : this.show(relatedTarget)
+ }
+
+ show(relatedTarget) {
+ if (this._isTransitioning) {
+ throw new Error('Modal is transitioning')
+ }
+
+ if (Util.supportsTransitionEnd() &&
+ $(this._element).hasClass(ClassName.FADE)) {
+ this._isTransitioning = true
+ }
+ const showEvent = $.Event(Event.SHOW, {
+ relatedTarget
+ })
+
+ $(this._element).trigger(showEvent)
+
+ if (this._isShown || showEvent.isDefaultPrevented()) {
+ return
+ }
+
+ this._isShown = true
+
+ this._checkScrollbar()
+ this._setScrollbar()
+
+ $(document.body).addClass(ClassName.OPEN)
+
+ this._setEscapeEvent()
+ this._setResizeEvent()
+
+ $(this._element).on(
+ Event.CLICK_DISMISS,
+ Selector.DATA_DISMISS,
+ (event) => this.hide(event)
+ )
+
+ $(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => {
+ $(this._element).one(Event.MOUSEUP_DISMISS, (event) => {
+ if ($(event.target).is(this._element)) {
+ this._ignoreBackdropClick = true
+ }
+ })
+ })
+
+ this._showBackdrop(() => this._showElement(relatedTarget))
+ }
+
+ hide(event) {
+ if (event) {
+ event.preventDefault()
+ }
+
+ if (this._isTransitioning) {
+ throw new Error('Modal is transitioning')
+ }
+
+ const transition = Util.supportsTransitionEnd() &&
+ $(this._element).hasClass(ClassName.FADE)
+ if (transition) {
+ this._isTransitioning = true
+ }
+
+ const hideEvent = $.Event(Event.HIDE)
+ $(this._element).trigger(hideEvent)
+
+ if (!this._isShown || hideEvent.isDefaultPrevented()) {
+ return
+ }
+
+ this._isShown = false
+
+ this._setEscapeEvent()
+ this._setResizeEvent()
+
+ $(document).off(Event.FOCUSIN)
+
+ $(this._element).removeClass(ClassName.SHOW)
+
+ $(this._element).off(Event.CLICK_DISMISS)
+ $(this._dialog).off(Event.MOUSEDOWN_DISMISS)
+
+ if (transition) {
+ $(this._element)
+ .one(Util.TRANSITION_END, (event) => this._hideModal(event))
+ .emulateTransitionEnd(TRANSITION_DURATION)
+ } else {
+ this._hideModal()
+ }
+ }
+
+ dispose() {
+ $.removeData(this._element, DATA_KEY)
+
+ $(window, document, this._element, this._backdrop).off(EVENT_KEY)
+
+ this._config = null
+ this._element = null
+ this._dialog = null
+ this._backdrop = null
+ this._isShown = null
+ this._isBodyOverflowing = null
+ this._ignoreBackdropClick = null
+ this._originalBodyPadding = null
+ this._scrollbarWidth = null
+ }
+
+
+ // private
+
+ _getConfig(config) {
+ config = $.extend({}, Default, config)
+ Util.typeCheckConfig(NAME, config, DefaultType)
+ return config
+ }
+
+ _showElement(relatedTarget) {
+ const transition = Util.supportsTransitionEnd() &&
+ $(this._element).hasClass(ClassName.FADE)
+
+ if (!this._element.parentNode ||
+ this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
+ // don't move modals dom position
+ document.body.appendChild(this._element)
+ }
+
+ this._element.style.display = 'block'
+ this._element.removeAttribute('aria-hidden')
+ this._element.scrollTop = 0
+
+ if (transition) {
+ Util.reflow(this._element)
+ }
+
+ $(this._element).addClass(ClassName.SHOW)
+
+ if (this._config.focus) {
+ this._enforceFocus()
+ }
+
+ const shownEvent = $.Event(Event.SHOWN, {
+ relatedTarget
+ })
+
+ const transitionComplete = () => {
+ if (this._config.focus) {
+ this._element.focus()
+ }
+ this._isTransitioning = false
+ $(this._element).trigger(shownEvent)
+ }
+
+ if (transition) {
+ $(this._dialog)
+ .one(Util.TRANSITION_END, transitionComplete)
+ .emulateTransitionEnd(TRANSITION_DURATION)
+ } else {
+ transitionComplete()
+ }
+ }
+
+ _enforceFocus() {
+ $(document)
+ .off(Event.FOCUSIN) // guard against infinite focus loop
+ .on(Event.FOCUSIN, (event) => {
+ if (document !== event.target &&
+ this._element !== event.target &&
+ !$(this._element).has(event.target).length) {
+ this._element.focus()
+ }
+ })
+ }
+
+ _setEscapeEvent() {
+ if (this._isShown && this._config.keyboard) {
+ $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {
+ if (event.which === ESCAPE_KEYCODE) {
+ this.hide()
+ }
+ })
+
+ } else if (!this._isShown) {
+ $(this._element).off(Event.KEYDOWN_DISMISS)
+ }
+ }
+
+ _setResizeEvent() {
+ if (this._isShown) {
+ $(window).on(Event.RESIZE, (event) => this._handleUpdate(event))
+ } else {
+ $(window).off(Event.RESIZE)
+ }
+ }
+
+ _hideModal() {
+ this._element.style.display = 'none'
+ this._element.setAttribute('aria-hidden', 'true')
+ this._isTransitioning = false
+ this._showBackdrop(() => {
+ $(document.body).removeClass(ClassName.OPEN)
+ this._resetAdjustments()
+ this._resetScrollbar()
+ $(this._element).trigger(Event.HIDDEN)
+ })
+ }
+
+ _removeBackdrop() {
+ if (this._backdrop) {
+ $(this._backdrop).remove()
+ this._backdrop = null
+ }
+ }
+
+ _showBackdrop(callback) {
+ const animate = $(this._element).hasClass(ClassName.FADE) ?
+ ClassName.FADE : ''
+
+ if (this._isShown && this._config.backdrop) {
+ const doAnimate = Util.supportsTransitionEnd() && animate
+
+ this._backdrop = document.createElement('div')
+ this._backdrop.className = ClassName.BACKDROP
+
+ if (animate) {
+ $(this._backdrop).addClass(animate)
+ }
+
+ $(this._backdrop).appendTo(document.body)
+
+ $(this._element).on(Event.CLICK_DISMISS, (event) => {
+ if (this._ignoreBackdropClick) {
+ this._ignoreBackdropClick = false
+ return
+ }
+ if (event.target !== event.currentTarget) {
+ return
+ }
+ if (this._config.backdrop === 'static') {
+ this._element.focus()
+ } else {
+ this.hide()
+ }
+ })
+
+ if (doAnimate) {
+ Util.reflow(this._backdrop)
+ }
+
+ $(this._backdrop).addClass(ClassName.SHOW)
+
+ if (!callback) {
+ return
+ }
+
+ if (!doAnimate) {
+ callback()
+ return
+ }
+
+ $(this._backdrop)
+ .one(Util.TRANSITION_END, callback)
+ .emulateTransitionEnd(BACKDROP_TRANSITION_DURATION)
+
+ } else if (!this._isShown && this._backdrop) {
+ $(this._backdrop).removeClass(ClassName.SHOW)
+
+ const callbackRemove = () => {
+ this._removeBackdrop()
+ if (callback) {
+ callback()
+ }
+ }
+
+ if (Util.supportsTransitionEnd() &&
+ $(this._element).hasClass(ClassName.FADE)) {
+ $(this._backdrop)
+ .one(Util.TRANSITION_END, callbackRemove)
+ .emulateTransitionEnd(BACKDROP_TRANSITION_DURATION)
+ } else {
+ callbackRemove()
+ }
+
+ } else if (callback) {
+ callback()
+ }
+ }
+
+
+ // ----------------------------------------------------------------------
+ // the following methods are used to handle overflowing modals
+ // todo (fat): these should probably be refactored out of modal.js
+ // ----------------------------------------------------------------------
+
+ _handleUpdate() {
+ this._adjustDialog()
+ }
+
+ _adjustDialog() {
+ const isModalOverflowing =
+ this._element.scrollHeight > document.documentElement.clientHeight
+
+ if (!this._isBodyOverflowing && isModalOverflowing) {
+ this._element.style.paddingLeft = `${this._scrollbarWidth}px`
+ }
+
+ if (this._isBodyOverflowing && !isModalOverflowing) {
+ this._element.style.paddingRight = `${this._scrollbarWidth}px`
+ }
+ }
+
+ _resetAdjustments() {
+ this._element.style.paddingLeft = ''
+ this._element.style.paddingRight = ''
+ }
+
+ _checkScrollbar() {
+ this._isBodyOverflowing = document.body.clientWidth < window.innerWidth
+ this._scrollbarWidth = this._getScrollbarWidth()
+ }
+
+ _setScrollbar() {
+ const bodyPadding = parseInt(
+ $(Selector.FIXED_CONTENT).css('padding-right') || 0,
+ 10
+ )
+
+ this._originalBodyPadding = document.body.style.paddingRight || ''
+
+ if (this._isBodyOverflowing) {
+ document.body.style.paddingRight =
+ `${bodyPadding + this._scrollbarWidth}px`
+ }
+ }
+
+ _resetScrollbar() {
+ document.body.style.paddingRight = this._originalBodyPadding
+ }
+
+ _getScrollbarWidth() { // thx d.walsh
+ const scrollDiv = document.createElement('div')
+ scrollDiv.className = ClassName.SCROLLBAR_MEASURER
+ document.body.appendChild(scrollDiv)
+ const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth
+ document.body.removeChild(scrollDiv)
+ return scrollbarWidth
+ }
+
+
+ // static
+
+ static _jQueryInterface(config, relatedTarget) {
+ return this.each(function () {
+ let data = $(this).data(DATA_KEY)
+ const _config = $.extend(
+ {},
+ Modal.Default,
+ $(this).data(),
+ typeof config === 'object' && config
+ )
+
+ if (!data) {
+ data = new Modal(this, _config)
+ $(this).data(DATA_KEY, data)
+ }
+
+ if (typeof config === 'string') {
+ if (data[config] === undefined) {
+ throw new Error(`No method named "${config}"`)
+ }
+ data[config](relatedTarget)
+ } else if (_config.show) {
+ data.show(relatedTarget)
+ }
+ })
+ }
+
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+ $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+ let target
+ const selector = Util.getSelectorFromElement(this)
+
+ if (selector) {
+ target = $(selector)[0]
+ }
+
+ const config = $(target).data(DATA_KEY) ?
+ 'toggle' : $.extend({}, $(target).data(), $(this).data())
+
+ if (this.tagName === 'A' || this.tagName === 'AREA') {
+ event.preventDefault()
+ }
+
+ const $target = $(target).one(Event.SHOW, (showEvent) => {
+ if (showEvent.isDefaultPrevented()) {
+ // only register focus restorer if modal will actually get shown
+ return
+ }
+
+ $target.one(Event.HIDDEN, () => {
+ if ($(this).is(':visible')) {
+ this.focus()
+ }
+ })
+ })
+
+ Modal._jQueryInterface.call($(target), config, this)
+ })
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME] = Modal._jQueryInterface
+ $.fn[NAME].Constructor = Modal
+ $.fn[NAME].noConflict = function () {
+ $.fn[NAME] = JQUERY_NO_CONFLICT
+ return Modal._jQueryInterface
+ }
+
+ return Modal
+
+})(jQuery)
+
+export default Modal
diff --git a/templates/assets/bootstrap/js/src/popover.js b/templates/assets/bootstrap/js/src/popover.js
new file mode 100644
index 0000000..b68b479
--- /dev/null
+++ b/templates/assets/bootstrap/js/src/popover.js
@@ -0,0 +1,179 @@
+import Tooltip from './tooltip'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): popover.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Popover = (($) => {
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+ const NAME = 'popover'
+ const VERSION = '4.0.0-alpha.6'
+ const DATA_KEY = 'bs.popover'
+ const EVENT_KEY = `.${DATA_KEY}`
+ const JQUERY_NO_CONFLICT = $.fn[NAME]
+
+ const Default = $.extend({}, Tooltip.Default, {
+ placement : 'right',
+ trigger : 'click',
+ content : '',
+ template : '<div class="popover" role="tooltip">'
+ + '<h3 class="popover-title"></h3>'
+ + '<div class="popover-content"></div></div>'
+ })
+
+ const DefaultType = $.extend({}, Tooltip.DefaultType, {
+ content : '(string|element|function)'
+ })
+
+ const ClassName = {
+ FADE : 'fade',
+ SHOW : 'show'
+ }
+
+ const Selector = {
+ TITLE : '.popover-title',
+ CONTENT : '.popover-content'
+ }
+
+ const Event = {
+ HIDE : `hide${EVENT_KEY}`,
+ HIDDEN : `hidden${EVENT_KEY}`,
+ SHOW : `show${EVENT_KEY}`,
+ SHOWN : `shown${EVENT_KEY}`,
+ INSERTED : `inserted${EVENT_KEY}`,
+ CLICK : `click${EVENT_KEY}`,
+ FOCUSIN : `focusin${EVENT_KEY}`,
+ FOCUSOUT : `focusout${EVENT_KEY}`,
+ MOUSEENTER : `mouseenter${EVENT_KEY}`,
+ MOUSELEAVE : `mouseleave${EVENT_KEY}`
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ class Popover extends Tooltip {
+
+
+ // getters
+
+ static get VERSION() {
+ return VERSION
+ }
+
+ static get Default() {
+ return Default
+ }
+
+ static get NAME() {
+ return NAME
+ }
+
+ static get DATA_KEY() {
+ return DATA_KEY
+ }
+
+ static get Event() {
+ return Event
+ }
+
+ static get EVENT_KEY() {
+ return EVENT_KEY
+ }
+
+ static get DefaultType() {
+ return DefaultType
+ }
+
+
+ // overrides
+
+ isWithContent() {
+ return this.getTitle() || this._getContent()
+ }
+
+ getTipElement() {
+ return this.tip = this.tip || $(this.config.template)[0]
+ }
+
+ setContent() {
+ const $tip = $(this.getTipElement())
+
+ // we use append for html objects to maintain js events
+ this.setElementContent($tip.find(Selector.TITLE), this.getTitle())
+ this.setElementContent($tip.find(Selector.CONTENT), this._getContent())
+
+ $tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)
+
+ this.cleanupTether()
+ }
+
+ // private
+
+ _getContent() {
+ return this.element.getAttribute('data-content')
+ || (typeof this.config.content === 'function' ?
+ this.config.content.call(this.element) :
+ this.config.content)
+ }
+
+
+ // static
+
+ static _jQueryInterface(config) {
+ return this.each(function () {
+ let data = $(this).data(DATA_KEY)
+ const _config = typeof config === 'object' ? config : null
+
+ if (!data && /destroy|hide/.test(config)) {
+ return
+ }
+
+ if (!data) {
+ data = new Popover(this, _config)
+ $(this).data(DATA_KEY, data)
+ }
+
+ if (typeof config === 'string') {
+ if (data[config] === undefined) {
+ throw new Error(`No method named "${config}"`)
+ }
+ data[config]()
+ }
+ })
+ }
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME] = Popover._jQueryInterface
+ $.fn[NAME].Constructor = Popover
+ $.fn[NAME].noConflict = function () {
+ $.fn[NAME] = JQUERY_NO_CONFLICT
+ return Popover._jQueryInterface
+ }
+
+ return Popover
+
+})(jQuery)
+
+export default Popover
diff --git a/templates/assets/bootstrap/js/src/scrollspy.js b/templates/assets/bootstrap/js/src/scrollspy.js
new file mode 100644
index 0000000..15541b8
--- /dev/null
+++ b/templates/assets/bootstrap/js/src/scrollspy.js
@@ -0,0 +1,335 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): scrollspy.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const ScrollSpy = (($) => {
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+ const NAME = 'scrollspy'
+ const VERSION = '4.0.0-alpha.6'
+ const DATA_KEY = 'bs.scrollspy'
+ const EVENT_KEY = `.${DATA_KEY}`
+ const DATA_API_KEY = '.data-api'
+ const JQUERY_NO_CONFLICT = $.fn[NAME]
+
+ const Default = {
+ offset : 10,
+ method : 'auto',
+ target : ''
+ }
+
+ const DefaultType = {
+ offset : 'number',
+ method : 'string',
+ target : '(string|element)'
+ }
+
+ const Event = {
+ ACTIVATE : `activate${EVENT_KEY}`,
+ SCROLL : `scroll${EVENT_KEY}`,
+ LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`
+ }
+
+ const ClassName = {
+ DROPDOWN_ITEM : 'dropdown-item',
+ DROPDOWN_MENU : 'dropdown-menu',
+ NAV_LINK : 'nav-link',
+ NAV : 'nav',
+ ACTIVE : 'active'
+ }
+
+ const Selector = {
+ DATA_SPY : '[data-spy="scroll"]',
+ ACTIVE : '.active',
+ LIST_ITEM : '.list-item',
+ LI : 'li',
+ LI_DROPDOWN : 'li.dropdown',
+ NAV_LINKS : '.nav-link',
+ DROPDOWN : '.dropdown',
+ DROPDOWN_ITEMS : '.dropdown-item',
+ DROPDOWN_TOGGLE : '.dropdown-toggle'
+ }
+
+ const OffsetMethod = {
+ OFFSET : 'offset',
+ POSITION : 'position'
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ class ScrollSpy {
+
+ constructor(element, config) {
+ this._element = element
+ this._scrollElement = element.tagName === 'BODY' ? window : element
+ this._config = this._getConfig(config)
+ this._selector = `${this._config.target} ${Selector.NAV_LINKS},`
+ + `${this._config.target} ${Selector.DROPDOWN_ITEMS}`
+ this._offsets = []
+ this._targets = []
+ this._activeTarget = null
+ this._scrollHeight = 0
+
+ $(this._scrollElement).on(Event.SCROLL, (event) => this._process(event))
+
+ this.refresh()
+ this._process()
+ }
+
+
+ // getters
+
+ static get VERSION() {
+ return VERSION
+ }
+
+ static get Default() {
+ return Default
+ }
+
+
+ // public
+
+ refresh() {
+ const autoMethod = this._scrollElement !== this._scrollElement.window ?
+ OffsetMethod.POSITION : OffsetMethod.OFFSET
+
+ const offsetMethod = this._config.method === 'auto' ?
+ autoMethod : this._config.method
+
+ const offsetBase = offsetMethod === OffsetMethod.POSITION ?
+ this._getScrollTop() : 0
+
+ this._offsets = []
+ this._targets = []
+
+ this._scrollHeight = this._getScrollHeight()
+
+ const targets = $.makeArray($(this._selector))
+
+ targets
+ .map((element) => {
+ let target
+ const targetSelector = Util.getSelectorFromElement(element)
+
+ if (targetSelector) {
+ target = $(targetSelector)[0]
+ }
+
+ if (target) {
+ const targetBCR = target.getBoundingClientRect()
+ if (targetBCR.width || targetBCR.height) {
+ // todo (fat): remove sketch reliance on jQuery position/offset
+ return [
+ $(target)[offsetMethod]().top + offsetBase,
+ targetSelector
+ ]
+ }
+ }
+ return null
+ })
+ .filter((item) => item)
+ .sort((a, b) => a[0] - b[0])
+ .forEach((item) => {
+ this._offsets.push(item[0])
+ this._targets.push(item[1])
+ })
+ }
+
+ dispose() {
+ $.removeData(this._element, DATA_KEY)
+ $(this._scrollElement).off(EVENT_KEY)
+
+ this._element = null
+ this._scrollElement = null
+ this._config = null
+ this._selector = null
+ this._offsets = null
+ this._targets = null
+ this._activeTarget = null
+ this._scrollHeight = null
+ }
+
+
+ // private
+
+ _getConfig(config) {
+ config = $.extend({}, Default, config)
+
+ if (typeof config.target !== 'string') {
+ let id = $(config.target).attr('id')
+ if (!id) {
+ id = Util.getUID(NAME)
+ $(config.target).attr('id', id)
+ }
+ config.target = `#${id}`
+ }
+
+ Util.typeCheckConfig(NAME, config, DefaultType)
+
+ return config
+ }
+
+ _getScrollTop() {
+ return this._scrollElement === window ?
+ this._scrollElement.pageYOffset : this._scrollElement.scrollTop
+ }
+
+ _getScrollHeight() {
+ return this._scrollElement.scrollHeight || Math.max(
+ document.body.scrollHeight,
+ document.documentElement.scrollHeight
+ )
+ }
+
+ _getOffsetHeight() {
+ return this._scrollElement === window ?
+ window.innerHeight : this._scrollElement.getBoundingClientRect().height
+ }
+
+ _process() {
+ const scrollTop = this._getScrollTop() + this._config.offset
+ const scrollHeight = this._getScrollHeight()
+ const maxScroll = this._config.offset
+ + scrollHeight
+ - this._getOffsetHeight()
+
+ if (this._scrollHeight !== scrollHeight) {
+ this.refresh()
+ }
+
+ if (scrollTop >= maxScroll) {
+ const target = this._targets[this._targets.length - 1]
+
+ if (this._activeTarget !== target) {
+ this._activate(target)
+ }
+ return
+ }
+
+ if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
+ this._activeTarget = null
+ this._clear()
+ return
+ }
+
+ for (let i = this._offsets.length; i--;) {
+ const isActiveTarget = this._activeTarget !== this._targets[i]
+ && scrollTop >= this._offsets[i]
+ && (this._offsets[i + 1] === undefined ||
+ scrollTop < this._offsets[i + 1])
+
+ if (isActiveTarget) {
+ this._activate(this._targets[i])
+ }
+ }
+ }
+
+ _activate(target) {
+ this._activeTarget = target
+
+ this._clear()
+
+ let queries = this._selector.split(',')
+ queries = queries.map((selector) => {
+ return `${selector}[data-target="${target}"],` +
+ `${selector}[href="${target}"]`
+ })
+
+ const $link = $(queries.join(','))
+
+ if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {
+ $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)
+ $link.addClass(ClassName.ACTIVE)
+ } else {
+ // todo (fat) this is kinda sus...
+ // recursively add actives to tested nav-links
+ $link.parents(Selector.LI).find(`> ${Selector.NAV_LINKS}`).addClass(ClassName.ACTIVE)
+ }
+
+ $(this._scrollElement).trigger(Event.ACTIVATE, {
+ relatedTarget: target
+ })
+ }
+
+ _clear() {
+ $(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE)
+ }
+
+
+ // static
+
+ static _jQueryInterface(config) {
+ return this.each(function () {
+ let data = $(this).data(DATA_KEY)
+ const _config = typeof config === 'object' && config
+
+ if (!data) {
+ data = new ScrollSpy(this, _config)
+ $(this).data(DATA_KEY, data)
+ }
+
+ if (typeof config === 'string') {
+ if (data[config] === undefined) {
+ throw new Error(`No method named "${config}"`)
+ }
+ data[config]()
+ }
+ })
+ }
+
+
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+ $(window).on(Event.LOAD_DATA_API, () => {
+ const scrollSpys = $.makeArray($(Selector.DATA_SPY))
+
+ for (let i = scrollSpys.length; i--;) {
+ const $spy = $(scrollSpys[i])
+ ScrollSpy._jQueryInterface.call($spy, $spy.data())
+ }
+ })
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME] = ScrollSpy._jQueryInterface
+ $.fn[NAME].Constructor = ScrollSpy
+ $.fn[NAME].noConflict = function () {
+ $.fn[NAME] = JQUERY_NO_CONFLICT
+ return ScrollSpy._jQueryInterface
+ }
+
+ return ScrollSpy
+
+})(jQuery)
+
+export default ScrollSpy
diff --git a/templates/assets/bootstrap/js/src/tab.js b/templates/assets/bootstrap/js/src/tab.js
new file mode 100644
index 0000000..d5669b7
--- /dev/null
+++ b/templates/assets/bootstrap/js/src/tab.js
@@ -0,0 +1,284 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): tab.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Tab = (($) => {
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+ const NAME = 'tab'
+ const VERSION = '4.0.0-alpha.6'
+ const DATA_KEY = 'bs.tab'
+ const EVENT_KEY = `.${DATA_KEY}`
+ const DATA_API_KEY = '.data-api'
+ const JQUERY_NO_CONFLICT = $.fn[NAME]
+ const TRANSITION_DURATION = 150
+
+ const Event = {
+ HIDE : `hide${EVENT_KEY}`,
+ HIDDEN : `hidden${EVENT_KEY}`,
+ SHOW : `show${EVENT_KEY}`,
+ SHOWN : `shown${EVENT_KEY}`,
+ CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
+ }
+
+ const ClassName = {
+ DROPDOWN_MENU : 'dropdown-menu',
+ ACTIVE : 'active',
+ DISABLED : 'disabled',
+ FADE : 'fade',
+ SHOW : 'show'
+ }
+
+ const Selector = {
+ A : 'a',
+ LI : 'li',
+ DROPDOWN : '.dropdown',
+ LIST : 'ul:not(.dropdown-menu), ol:not(.dropdown-menu), nav:not(.dropdown-menu), .list-group:not(.dropdown-menu)',
+ FADE_CHILD : '> .nav-item .fade, > .list-group-item .fade, > .fade',
+ ACTIVE : '.active',
+ ACTIVE_CHILD : '> .nav-item > .active, > .list-group-item > .active, > .active',
+ DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"]',
+ DROPDOWN_TOGGLE : '.dropdown-toggle',
+ DROPDOWN_ACTIVE_CHILD : '> .dropdown-menu .active'
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ class Tab {
+
+ constructor(element) {
+ this._element = element
+ }
+
+
+ // getters
+
+ static get VERSION() {
+ return VERSION
+ }
+
+
+ // public
+
+ show() {
+ if (this._element.parentNode &&
+ this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
+ $(this._element).hasClass(ClassName.ACTIVE) ||
+ $(this._element).hasClass(ClassName.DISABLED)) {
+ return
+ }
+
+ let target
+ let previous
+ const listElement = $(this._element).closest(Selector.LIST)[0]
+ const selector = Util.getSelectorFromElement(this._element)
+
+ if (listElement) {
+ previous = $.makeArray($(listElement).find(Selector.ACTIVE))
+ previous = previous[previous.length - 1]
+ }
+
+ const hideEvent = $.Event(Event.HIDE, {
+ relatedTarget: this._element
+ })
+
+ const showEvent = $.Event(Event.SHOW, {
+ relatedTarget: previous
+ })
+
+ if (previous) {
+ $(previous).trigger(hideEvent)
+ }
+
+ $(this._element).trigger(showEvent)
+
+ if (showEvent.isDefaultPrevented() ||
+ hideEvent.isDefaultPrevented()) {
+ return
+ }
+
+ if (selector) {
+ target = $(selector)[0]
+ }
+
+ this._activate(
+ this._element,
+ listElement
+ )
+
+ const complete = () => {
+ const hiddenEvent = $.Event(Event.HIDDEN, {
+ relatedTarget: this._element
+ })
+
+ const shownEvent = $.Event(Event.SHOWN, {
+ relatedTarget: previous
+ })
+
+ $(previous).trigger(hiddenEvent)
+ $(this._element).trigger(shownEvent)
+ }
+
+ if (target) {
+ this._activate(target, target.parentNode, complete)
+ } else {
+ complete()
+ }
+ }
+
+ dispose() {
+ $.removeClass(this._element, DATA_KEY)
+ this._element = null
+ }
+
+
+ // private
+
+ _activate(element, container, callback) {
+ const active = $(container).find(Selector.ACTIVE_CHILD)[0]
+ const isTransitioning = callback
+ && Util.supportsTransitionEnd()
+ && (active && $(active).hasClass(ClassName.FADE)
+ || Boolean($(container).find(Selector.FADE_CHILD)[0]))
+
+ const complete = () => this._transitionComplete(
+ element,
+ active,
+ isTransitioning,
+ callback
+ )
+
+ if (active && isTransitioning) {
+ $(active)
+ .one(Util.TRANSITION_END, complete)
+ .emulateTransitionEnd(TRANSITION_DURATION)
+
+ } else {
+ complete()
+ }
+
+ if (active) {
+ $(active).removeClass(ClassName.SHOW)
+ }
+ }
+
+ _transitionComplete(element, active, isTransitioning, callback) {
+ if (active) {
+ $(active).removeClass(ClassName.ACTIVE)
+ if ($(active).hasClass('list-group-item')) {
+ $(active).find('a.nav-link').removeClass(ClassName.ACTIVE)
+ }
+
+ const dropdownChild = $(active.parentNode).find(
+ Selector.DROPDOWN_ACTIVE_CHILD
+ )[0]
+
+ if (dropdownChild) {
+ $(dropdownChild).removeClass(ClassName.ACTIVE)
+ }
+
+ active.setAttribute('aria-expanded', false)
+ }
+
+ $(element).addClass(ClassName.ACTIVE)
+ if ($(element.parentNode).hasClass('list-group-item')) {
+ $(element.parentNode).addClass(ClassName.ACTIVE)
+ }
+ element.setAttribute('aria-expanded', true)
+
+ if (isTransitioning) {
+ Util.reflow(element)
+ $(element).addClass(ClassName.SHOW)
+ } else {
+ $(element).removeClass(ClassName.FADE)
+ }
+
+ if (element.parentNode &&
+ $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
+
+ const dropdownElement = $(element).closest(Selector.DROPDOWN)[0]
+ if (dropdownElement) {
+ $(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)
+ }
+
+ element.setAttribute('aria-expanded', true)
+ }
+
+ if (callback) {
+ callback()
+ }
+ }
+
+
+ // static
+
+ static _jQueryInterface(config) {
+ return this.each(function () {
+ const $this = $(this)
+ let data = $this.data(DATA_KEY)
+
+ if (!data) {
+ data = new Tab(this)
+ $this.data(DATA_KEY, data)
+ }
+
+ if (typeof config === 'string') {
+ if (data[config] === undefined) {
+ throw new Error(`No method named "${config}"`)
+ }
+ data[config]()
+ }
+ })
+ }
+
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+ $(document)
+ .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+ event.preventDefault()
+ Tab._jQueryInterface.call($(this), 'show')
+ })
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME] = Tab._jQueryInterface
+ $.fn[NAME].Constructor = Tab
+ $.fn[NAME].noConflict = function () {
+ $.fn[NAME] = JQUERY_NO_CONFLICT
+ return Tab._jQueryInterface
+ }
+
+ return Tab
+
+})(jQuery)
+
+export default Tab
diff --git a/templates/assets/bootstrap/js/src/tooltip.js b/templates/assets/bootstrap/js/src/tooltip.js
new file mode 100644
index 0000000..e750dce
--- /dev/null
+++ b/templates/assets/bootstrap/js/src/tooltip.js
@@ -0,0 +1,675 @@
+/* global Tether */
+
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): tooltip.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Tooltip = (($) => {
+
+ /**
+ * Check for Tether dependency
+ * Tether - http://tether.io/
+ */
+ if (typeof Tether === 'undefined') {
+ throw new Error('Bootstrap tooltips require Tether (http://tether.io/)')
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+ const NAME = 'tooltip'
+ const VERSION = '4.0.0-alpha.6'
+ const DATA_KEY = 'bs.tooltip'
+ const EVENT_KEY = `.${DATA_KEY}`
+ const JQUERY_NO_CONFLICT = $.fn[NAME]
+ const TRANSITION_DURATION = 150
+ const CLASS_PREFIX = 'bs-tether'
+
+ const Default = {
+ animation : true,
+ template : '<div class="tooltip" role="tooltip">'
+ + '<div class="tooltip-inner"></div></div>',
+ trigger : 'hover focus',
+ title : '',
+ delay : 0,
+ html : false,
+ selector : false,
+ placement : 'top',
+ offset : '0 0',
+ constraints : [],
+ container : false
+ }
+
+ const DefaultType = {
+ animation : 'boolean',
+ template : 'string',
+ title : '(string|element|function)',
+ trigger : 'string',
+ delay : '(number|object)',
+ html : 'boolean',
+ selector : '(string|boolean)',
+ placement : '(string|function)',
+ offset : 'string',
+ constraints : 'array',
+ container : '(string|element|boolean)'
+ }
+
+ const AttachmentMap = {
+ TOP : 'bottom center',
+ RIGHT : 'middle left',
+ BOTTOM : 'top center',
+ LEFT : 'middle right'
+ }
+
+ const HoverState = {
+ SHOW : 'show',
+ OUT : 'out'
+ }
+
+ const Event = {
+ HIDE : `hide${EVENT_KEY}`,
+ HIDDEN : `hidden${EVENT_KEY}`,
+ SHOW : `show${EVENT_KEY}`,
+ SHOWN : `shown${EVENT_KEY}`,
+ INSERTED : `inserted${EVENT_KEY}`,
+ CLICK : `click${EVENT_KEY}`,
+ FOCUSIN : `focusin${EVENT_KEY}`,
+ FOCUSOUT : `focusout${EVENT_KEY}`,
+ MOUSEENTER : `mouseenter${EVENT_KEY}`,
+ MOUSELEAVE : `mouseleave${EVENT_KEY}`
+ }
+
+ const ClassName = {
+ FADE : 'fade',
+ SHOW : 'show'
+ }
+
+ const Selector = {
+ TOOLTIP : '.tooltip',
+ TOOLTIP_INNER : '.tooltip-inner'
+ }
+
+ const TetherClass = {
+ element : false,
+ enabled : false
+ }
+
+ const Trigger = {
+ HOVER : 'hover',
+ FOCUS : 'focus',
+ CLICK : 'click',
+ MANUAL : 'manual'
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ class Tooltip {
+
+ constructor(element, config) {
+
+ // private
+ this._isEnabled = true
+ this._timeout = 0
+ this._hoverState = ''
+ this._activeTrigger = {}
+ this._isTransitioning = false
+ this._tether = null
+
+ // protected
+ this.element = element
+ this.config = this._getConfig(config)
+ this.tip = null
+
+ this._setListeners()
+
+ }
+
+
+ // getters
+
+ static get VERSION() {
+ return VERSION
+ }
+
+ static get Default() {
+ return Default
+ }
+
+ static get NAME() {
+ return NAME
+ }
+
+ static get DATA_KEY() {
+ return DATA_KEY
+ }
+
+ static get Event() {
+ return Event
+ }
+
+ static get EVENT_KEY() {
+ return EVENT_KEY
+ }
+
+ static get DefaultType() {
+ return DefaultType
+ }
+
+
+ // public
+
+ enable() {
+ this._isEnabled = true
+ }
+
+ disable() {
+ this._isEnabled = false
+ }
+
+ toggleEnabled() {
+ this._isEnabled = !this._isEnabled
+ }
+
+ toggle(event) {
+ if (event) {
+ const dataKey = this.constructor.DATA_KEY
+ let context = $(event.currentTarget).data(dataKey)
+
+ if (!context) {
+ context = new this.constructor(
+ event.currentTarget,
+ this._getDelegateConfig()
+ )
+ $(event.currentTarget).data(dataKey, context)
+ }
+
+ context._activeTrigger.click = !context._activeTrigger.click
+
+ if (context._isWithActiveTrigger()) {
+ context._enter(null, context)
+ } else {
+ context._leave(null, context)
+ }
+
+ } else {
+
+ if ($(this.getTipElement()).hasClass(ClassName.SHOW)) {
+ this._leave(null, this)
+ return
+ }
+
+ this._enter(null, this)
+ }
+ }
+
+ dispose() {
+ clearTimeout(this._timeout)
+
+ this.cleanupTether()
+
+ $.removeData(this.element, this.constructor.DATA_KEY)
+
+ $(this.element).off(this.constructor.EVENT_KEY)
+ $(this.element).closest('.modal').off('hide.bs.modal')
+
+ if (this.tip) {
+ $(this.tip).remove()
+ }
+
+ this._isEnabled = null
+ this._timeout = null
+ this._hoverState = null
+ this._activeTrigger = null
+ this._tether = null
+
+ this.element = null
+ this.config = null
+ this.tip = null
+ }
+
+ show() {
+ if ($(this.element).css('display') === 'none') {
+ throw new Error('Please use show on visible elements')
+ }
+
+ const showEvent = $.Event(this.constructor.Event.SHOW)
+ if (this.isWithContent() && this._isEnabled) {
+ if (this._isTransitioning) {
+ throw new Error('Tooltip is transitioning')
+ }
+ $(this.element).trigger(showEvent)
+
+ const isInTheDom = $.contains(
+ this.element.ownerDocument.documentElement,
+ this.element
+ )
+
+ if (showEvent.isDefaultPrevented() || !isInTheDom) {
+ return
+ }
+
+ const tip = this.getTipElement()
+ const tipId = Util.getUID(this.constructor.NAME)
+
+ tip.setAttribute('id', tipId)
+ this.element.setAttribute('aria-describedby', tipId)
+
+ this.setContent()
+
+ if (this.config.animation) {
+ $(tip).addClass(ClassName.FADE)
+ }
+
+ const placement = typeof this.config.placement === 'function' ?
+ this.config.placement.call(this, tip, this.element) :
+ this.config.placement
+
+ const attachment = this._getAttachment(placement)
+
+ const container = this.config.container === false ? document.body : $(this.config.container)
+
+ $(tip)
+ .data(this.constructor.DATA_KEY, this)
+ .appendTo(container)
+
+ $(this.element).trigger(this.constructor.Event.INSERTED)
+
+ this._tether = new Tether({
+ attachment,
+ element : tip,
+ target : this.element,
+ classes : TetherClass,
+ classPrefix : CLASS_PREFIX,
+ offset : this.config.offset,
+ constraints : this.config.constraints,
+ addTargetClasses: false
+ })
+
+ Util.reflow(tip)
+ this._tether.position()
+
+ $(tip).addClass(ClassName.SHOW)
+
+ const complete = () => {
+ const prevHoverState = this._hoverState
+ this._hoverState = null
+ this._isTransitioning = false
+
+ $(this.element).trigger(this.constructor.Event.SHOWN)
+
+ if (prevHoverState === HoverState.OUT) {
+ this._leave(null, this)
+ }
+ }
+
+ if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
+ this._isTransitioning = true
+ $(this.tip)
+ .one(Util.TRANSITION_END, complete)
+ .emulateTransitionEnd(Tooltip._TRANSITION_DURATION)
+ return
+ }
+
+ complete()
+ }
+ }
+
+ hide(callback) {
+ const tip = this.getTipElement()
+ const hideEvent = $.Event(this.constructor.Event.HIDE)
+ if (this._isTransitioning) {
+ throw new Error('Tooltip is transitioning')
+ }
+ const complete = () => {
+ if (this._hoverState !== HoverState.SHOW && tip.parentNode) {
+ tip.parentNode.removeChild(tip)
+ }
+
+ this.element.removeAttribute('aria-describedby')
+ $(this.element).trigger(this.constructor.Event.HIDDEN)
+ this._isTransitioning = false
+ this.cleanupTether()
+
+ if (callback) {
+ callback()
+ }
+ }
+
+ $(this.element).trigger(hideEvent)
+
+ if (hideEvent.isDefaultPrevented()) {
+ return
+ }
+
+ $(tip).removeClass(ClassName.SHOW)
+
+ this._activeTrigger[Trigger.CLICK] = false
+ this._activeTrigger[Trigger.FOCUS] = false
+ this._activeTrigger[Trigger.HOVER] = false
+
+ if (Util.supportsTransitionEnd() &&
+ $(this.tip).hasClass(ClassName.FADE)) {
+ this._isTransitioning = true
+ $(tip)
+ .one(Util.TRANSITION_END, complete)
+ .emulateTransitionEnd(TRANSITION_DURATION)
+
+ } else {
+ complete()
+ }
+
+ this._hoverState = ''
+ }
+
+
+ // protected
+
+ isWithContent() {
+ return Boolean(this.getTitle())
+ }
+
+ getTipElement() {
+ return this.tip = this.tip || $(this.config.template)[0]
+ }
+
+ setContent() {
+ const $tip = $(this.getTipElement())
+
+ this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle())
+
+ $tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)
+
+ this.cleanupTether()
+ }
+
+ setElementContent($element, content) {
+ const html = this.config.html
+ if (typeof content === 'object' && (content.nodeType || content.jquery)) {
+ // content is a DOM node or a jQuery
+ if (html) {
+ if (!$(content).parent().is($element)) {
+ $element.empty().append(content)
+ }
+ } else {
+ $element.text($(content).text())
+ }
+ } else {
+ $element[html ? 'html' : 'text'](content)
+ }
+ }
+
+ getTitle() {
+ let title = this.element.getAttribute('data-original-title')
+
+ if (!title) {
+ title = typeof this.config.title === 'function' ?
+ this.config.title.call(this.element) :
+ this.config.title
+ }
+
+ return title
+ }
+
+ cleanupTether() {
+ if (this._tether) {
+ this._tether.destroy()
+ }
+ }
+
+
+ // private
+
+ _getAttachment(placement) {
+ return AttachmentMap[placement.toUpperCase()]
+ }
+
+ _setListeners() {
+ const triggers = this.config.trigger.split(' ')
+
+ triggers.forEach((trigger) => {
+ if (trigger === 'click') {
+ $(this.element).on(
+ this.constructor.Event.CLICK,
+ this.config.selector,
+ (event) => this.toggle(event)
+ )
+
+ } else if (trigger !== Trigger.MANUAL) {
+ const eventIn = trigger === Trigger.HOVER ?
+ this.constructor.Event.MOUSEENTER :
+ this.constructor.Event.FOCUSIN
+ const eventOut = trigger === Trigger.HOVER ?
+ this.constructor.Event.MOUSELEAVE :
+ this.constructor.Event.FOCUSOUT
+
+ $(this.element)
+ .on(
+ eventIn,
+ this.config.selector,
+ (event) => this._enter(event)
+ )
+ .on(
+ eventOut,
+ this.config.selector,
+ (event) => this._leave(event)
+ )
+ }
+
+ $(this.element).closest('.modal').on(
+ 'hide.bs.modal',
+ () => this.hide()
+ )
+ })
+
+ if (this.config.selector) {
+ this.config = $.extend({}, this.config, {
+ trigger : 'manual',
+ selector : ''
+ })
+ } else {
+ this._fixTitle()
+ }
+ }
+
+ _fixTitle() {
+ const titleType = typeof this.element.getAttribute('data-original-title')
+ if (this.element.getAttribute('title') ||
+ titleType !== 'string') {
+ this.element.setAttribute(
+ 'data-original-title',
+ this.element.getAttribute('title') || ''
+ )
+ this.element.setAttribute('title', '')
+ }
+ }
+
+ _enter(event, context) {
+ const dataKey = this.constructor.DATA_KEY
+
+ context = context || $(event.currentTarget).data(dataKey)
+
+ if (!context) {
+ context = new this.constructor(
+ event.currentTarget,
+ this._getDelegateConfig()
+ )
+ $(event.currentTarget).data(dataKey, context)
+ }
+
+ if (event) {
+ context._activeTrigger[
+ event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER
+ ] = true
+ }
+
+ if ($(context.getTipElement()).hasClass(ClassName.SHOW) ||
+ context._hoverState === HoverState.SHOW) {
+ context._hoverState = HoverState.SHOW
+ return
+ }
+
+ clearTimeout(context._timeout)
+
+ context._hoverState = HoverState.SHOW
+
+ if (!context.config.delay || !context.config.delay.show) {
+ context.show()
+ return
+ }
+
+ context._timeout = setTimeout(() => {
+ if (context._hoverState === HoverState.SHOW) {
+ context.show()
+ }
+ }, context.config.delay.show)
+ }
+
+ _leave(event, context) {
+ const dataKey = this.constructor.DATA_KEY
+
+ context = context || $(event.currentTarget).data(dataKey)
+
+ if (!context) {
+ context = new this.constructor(
+ event.currentTarget,
+ this._getDelegateConfig()
+ )
+ $(event.currentTarget).data(dataKey, context)
+ }
+
+ if (event) {
+ context._activeTrigger[
+ event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER
+ ] = false
+ }
+
+ if (context._isWithActiveTrigger()) {
+ return
+ }
+
+ clearTimeout(context._timeout)
+
+ context._hoverState = HoverState.OUT
+
+ if (!context.config.delay || !context.config.delay.hide) {
+ context.hide()
+ return
+ }
+
+ context._timeout = setTimeout(() => {
+ if (context._hoverState === HoverState.OUT) {
+ context.hide()
+ }
+ }, context.config.delay.hide)
+ }
+
+ _isWithActiveTrigger() {
+ for (const trigger in this._activeTrigger) {
+ if (this._activeTrigger[trigger]) {
+ return true
+ }
+ }
+
+ return false
+ }
+
+ _getConfig(config) {
+ config = $.extend(
+ {},
+ this.constructor.Default,
+ $(this.element).data(),
+ config
+ )
+
+ if (config.delay && typeof config.delay === 'number') {
+ config.delay = {
+ show : config.delay,
+ hide : config.delay
+ }
+ }
+
+ Util.typeCheckConfig(
+ NAME,
+ config,
+ this.constructor.DefaultType
+ )
+
+ return config
+ }
+
+ _getDelegateConfig() {
+ const config = {}
+
+ if (this.config) {
+ for (const key in this.config) {
+ if (this.constructor.Default[key] !== this.config[key]) {
+ config[key] = this.config[key]
+ }
+ }
+ }
+
+ return config
+ }
+
+
+ // static
+
+ static _jQueryInterface(config) {
+ return this.each(function () {
+ let data = $(this).data(DATA_KEY)
+ const _config = typeof config === 'object' && config
+
+ if (!data && /dispose|hide/.test(config)) {
+ return
+ }
+
+ if (!data) {
+ data = new Tooltip(this, _config)
+ $(this).data(DATA_KEY, data)
+ }
+
+ if (typeof config === 'string') {
+ if (data[config] === undefined) {
+ throw new Error(`No method named "${config}"`)
+ }
+ data[config]()
+ }
+ })
+ }
+
+ }
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME] = Tooltip._jQueryInterface
+ $.fn[NAME].Constructor = Tooltip
+ $.fn[NAME].noConflict = function () {
+ $.fn[NAME] = JQUERY_NO_CONFLICT
+ return Tooltip._jQueryInterface
+ }
+
+ return Tooltip
+
+})(jQuery)
+
+export default Tooltip
diff --git a/templates/assets/bootstrap/js/src/util.js b/templates/assets/bootstrap/js/src/util.js
new file mode 100644
index 0000000..3c0d022
--- /dev/null
+++ b/templates/assets/bootstrap/js/src/util.js
@@ -0,0 +1,164 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): util.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Util = (($) => {
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * Private TransitionEnd Helpers
+ * ------------------------------------------------------------------------
+ */
+
+ let transition = false
+
+ const MAX_UID = 1000000
+
+ const TransitionEndEvent = {
+ WebkitTransition : 'webkitTransitionEnd',
+ MozTransition : 'transitionend',
+ OTransition : 'oTransitionEnd otransitionend',
+ transition : 'transitionend'
+ }
+
+ // shoutout AngusCroll (https://goo.gl/pxwQGp)
+ function toType(obj) {
+ return {}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
+ }
+
+ function isElement(obj) {
+ return (obj[0] || obj).nodeType
+ }
+
+ function getSpecialTransitionEndEvent() {
+ return {
+ bindType: transition.end,
+ delegateType: transition.end,
+ handle(event) {
+ if ($(event.target).is(this)) {
+ return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params
+ }
+ return undefined
+ }
+ }
+ }
+
+ function transitionEndTest() {
+ if (window.QUnit) {
+ return false
+ }
+
+ const el = document.createElement('bootstrap')
+
+ for (const name in TransitionEndEvent) {
+ if (el.style[name] !== undefined) {
+ return {
+ end: TransitionEndEvent[name]
+ }
+ }
+ }
+
+ return false
+ }
+
+ function transitionEndEmulator(duration) {
+ let called = false
+
+ $(this).one(Util.TRANSITION_END, () => {
+ called = true
+ })
+
+ setTimeout(() => {
+ if (!called) {
+ Util.triggerTransitionEnd(this)
+ }
+ }, duration)
+
+ return this
+ }
+
+ function setTransitionEndSupport() {
+ transition = transitionEndTest()
+
+ $.fn.emulateTransitionEnd = transitionEndEmulator
+
+ if (Util.supportsTransitionEnd()) {
+ $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()
+ }
+ }
+
+
+ /**
+ * --------------------------------------------------------------------------
+ * Public Util Api
+ * --------------------------------------------------------------------------
+ */
+
+ const Util = {
+
+ TRANSITION_END: 'bsTransitionEnd',
+
+ getUID(prefix) {
+ do {
+ // eslint-disable-next-line no-bitwise
+ prefix += ~~(Math.random() * MAX_UID) // "~~" acts like a faster Math.floor() here
+ } while (document.getElementById(prefix))
+ return prefix
+ },
+
+ getSelectorFromElement(element) {
+ let selector = element.getAttribute('data-target')
+ if (!selector || selector === '#') {
+ selector = element.getAttribute('href') || ''
+ }
+
+ try {
+ const $selector = $(selector)
+ return $selector.length > 0 ? selector : null
+ } catch (error) {
+ return null
+ }
+ },
+
+ reflow(element) {
+ return element.offsetHeight
+ },
+
+ triggerTransitionEnd(element) {
+ $(element).trigger(transition.end)
+ },
+
+ supportsTransitionEnd() {
+ return Boolean(transition)
+ },
+
+ typeCheckConfig(componentName, config, configTypes) {
+ for (const property in configTypes) {
+ if (configTypes.hasOwnProperty(property)) {
+ const expectedTypes = configTypes[property]
+ const value = config[property]
+ const valueType = value && isElement(value) ?
+ 'element' : toType(value)
+
+ if (!new RegExp(expectedTypes).test(valueType)) {
+ throw new Error(
+ `${componentName.toUpperCase()}: ` +
+ `Option "${property}" provided type "${valueType}" ` +
+ `but expected type "${expectedTypes}".`)
+ }
+ }
+ }
+ }
+ }
+
+ setTransitionEndSupport()
+
+ return Util
+
+})(jQuery)
+
+export default Util
diff --git a/templates/assets/bootstrap/nuget/MyGet.ps1 b/templates/assets/bootstrap/nuget/MyGet.ps1
new file mode 100644
index 0000000..71110b5
--- /dev/null
+++ b/templates/assets/bootstrap/nuget/MyGet.ps1
@@ -0,0 +1,18 @@
+# set env vars usually set by MyGet (enable for local testing)
+#$env:SourcesPath = '..'
+#$env:NuGet = "./nuget.exe" #https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
+
+$nuget = $env:NuGet
+
+# parse the version number out of package.json
+$bsversionParts = ((Get-Content $env:SourcesPath\package.json) -join "`n" | ConvertFrom-Json).version.split('-', 2) # split the version on the '-'
+$bsversion = $bsversionParts[0]
+
+if ($bsversionParts.Length -gt 1)
+{
+ $bsversion += '-' + $bsversionParts[1].replace('.', '').replace('-', '_') # strip out invalid chars from the PreRelease part
+}
+
+# create packages
+& $nuget pack "$env:SourcesPath\nuget\bootstrap.nuspec" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion
+& $nuget pack "$env:SourcesPath\nuget\bootstrap.sass.nuspec" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion
diff --git a/templates/assets/bootstrap/nuget/bootstrap.nuspec b/templates/assets/bootstrap/nuget/bootstrap.nuspec
new file mode 100644
index 0000000..bbb4582
--- /dev/null
+++ b/templates/assets/bootstrap/nuget/bootstrap.nuspec
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
+ <metadata>
+ <id>bootstrap</id>
+ <version>4.0.0</version>
+ <title>Bootstrap CSS</title>
+ <authors>The Bootstrap Authors, Twitter Inc.</authors>
+ <owners>bootstrap</owners>
+ <description>The most popular front-end framework for developing responsive, mobile first projects on the web.</description>
+ <releaseNotes>https://blog.getbootstrap.com</releaseNotes>
+ <summary>Bootstrap framework in CSS. Includes fonts and JavaScript</summary>
+ <language>en-us</language>
+ <projectUrl>https://getbootstrap.com</projectUrl>
+ <iconUrl>https://getbootstrap.com/apple-touch-icon.png</iconUrl>
+ <licenseUrl>https://github.com/twbs/bootstrap/blob/master/LICENSE</licenseUrl>
+ <copyright>Copyright 2017</copyright>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <dependencies>
+ <dependency id="jQuery" version="[1.9.1,4)" />
+ </dependencies>
+ <tags>css mobile-first responsive front-end framework web</tags>
+ </metadata>
+ <files>
+ <file src="dist\css\*.*" target="content\Content" />
+ <file src="dist\js\bootstrap*.js" target="content\Scripts" />
+ </files>
+</package>
diff --git a/templates/assets/bootstrap/nuget/bootstrap.sass.nuspec b/templates/assets/bootstrap/nuget/bootstrap.sass.nuspec
new file mode 100644
index 0000000..aba443c
--- /dev/null
+++ b/templates/assets/bootstrap/nuget/bootstrap.sass.nuspec
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
+ <metadata>
+ <id>bootstrap.sass</id>
+ <version>4.0.0</version>
+ <title>Bootstrap Sass</title>
+ <authors>The Bootstrap Authors, Twitter Inc.</authors>
+ <owners>bootstrap</owners>
+ <description>The most popular front-end framework for developing responsive, mobile first projects on the web.</description>
+ <releaseNotes>https://blog.getbootstrap.com</releaseNotes>
+ <summary>Bootstrap framework in Sass. Includes fonts and JavaScript</summary>
+ <language>en-us</language>
+ <projectUrl>https://getbootstrap.com</projectUrl>
+ <iconUrl>https://getbootstrap.com/apple-touch-icon.png</iconUrl>
+ <licenseUrl>https://github.com/twbs/bootstrap/blob/master/LICENSE</licenseUrl>
+ <copyright>Copyright 2017</copyright>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <dependencies>
+ <dependency id="jQuery" version="[1.9.1,4)" />
+ </dependencies>
+ <tags>css sass mobile-first responsive front-end framework web</tags>
+ </metadata>
+ <files>
+ <file src="scss\**\*.scss" target="content\Content\bootstrap" />
+ <file src="dist\js\bootstrap*.js" target="content\Scripts" />
+ </files>
+</package>
diff --git a/templates/assets/bootstrap/package.js b/templates/assets/bootstrap/package.js
new file mode 100644
index 0000000..ce21bad
--- /dev/null
+++ b/templates/assets/bootstrap/package.js
@@ -0,0 +1,19 @@
+// package metadata file for Meteor.js
+
+/* global Package:true */
+
+Package.describe({
+ name: 'twbs:bootstrap', // https://atmospherejs.com/twbs/bootstrap
+ summary: 'The most popular front-end framework for developing responsive, mobile first projects on the web.',
+ version: '4.0.0-alpha.6',
+ git: 'https://github.com/twbs/bootstrap.git'
+});
+
+Package.onUse(function (api) {
+ api.versionsFrom('METEOR@1.0');
+ api.use('jquery', 'client');
+ api.addFiles([
+ 'dist/css/bootstrap.css',
+ 'dist/js/bootstrap.js'
+ ], 'client');
+});
diff --git a/templates/assets/bootstrap/package.json b/templates/assets/bootstrap/package.json
new file mode 100644
index 0000000..d11ffbf
--- /dev/null
+++ b/templates/assets/bootstrap/package.json
@@ -0,0 +1,114 @@
+{
+ "name": "bootstrap",
+ "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
+ "version": "4.0.0-alpha.6",
+ "keywords": [
+ "css",
+ "sass",
+ "mobile-first",
+ "responsive",
+ "front-end",
+ "framework",
+ "web"
+ ],
+ "homepage": "https://getbootstrap.com",
+ "author": "The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)",
+ "contributors": [
+ "Twitter, Inc."
+ ],
+ "scripts": {
+ "change-version": "node grunt/change-version.js",
+ "clean-css": "cleancss --level 1 --source-map --output dist/css/bootstrap.min.css dist/css/bootstrap.css && cleancss --level 1 --source-map --output dist/css/bootstrap-grid.min.css dist/css/bootstrap-grid.css && cleancss --level 1 --source-map --output dist/css/bootstrap-reboot.min.css dist/css/bootstrap-reboot.css",
+ "clean-css-docs": "cleancss --level 1 --source-map --output docs/assets/css/docs.min.css docs/assets/css/docs.min.css",
+ "eslint": "eslint --ignore-path .eslintignore js && eslint --config js/tests/.eslintrc.json --env node grunt Gruntfile.js && eslint --config js/tests/.eslintrc.json docs/assets/js/src docs/assets/js/ie-emulation-modes-warning.js docs/assets/js/ie10-viewport-bug-workaround.js",
+ "htmlhint": "htmlhint --config docs/.htmlhintrc _gh_pages/",
+ "htmllint": "htmllint --rc docs/.htmllintrc _gh_pages/**/*.html js/tests/visual/*.html",
+ "jekyll": "bundle exec jekyll build",
+ "jekyll-github": "shx echo 'github: true' > $npm_config_tmp/twbsjekyll.yml && npm run jekyll -- --config _config.yml,$npm_config_tmp/twbsjekyll.yml && shx rm $npm_config_tmp/twbsjekyll.yml",
+ "postcss": "postcss --config grunt/ --replace dist/css/*.css",
+ "postcss-docs": "postcss --config grunt/ --replace docs/assets/css/docs.min.css && postcss --config grunt/ --replace docs/examples/**/*.css",
+ "sass": "node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap.scss dist/css/bootstrap.css && node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap-grid.scss dist/css/bootstrap-grid.css && node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap-reboot.scss dist/css/bootstrap-reboot.css",
+ "sass-docs": "node-sass --output-style expanded --source-map true --precision 6 docs/assets/scss/docs.scss docs/assets/css/docs.min.css",
+ "scss-lint": "bundle exec scss-lint --config scss/.scss-lint.yml scss/*.scss",
+ "scss-lint-docs": "bundle exec scss-lint --config scss/.scss-lint.yml --exclude docs/assets/scss/docs.scss docs/assets/scss/*.scss",
+ "uglify": "uglifyjs --compress warnings=false --mangle --comments '/^!/' --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
+ "uglify-docs": "uglifyjs --compress warnings=false --mangle --comments '/^!/' --output docs/assets/js/docs.min.js docs/assets/js/vendor/anchor.min.js docs/assets/js/vendor/clipboard.min.js docs/assets/js/vendor/holder.min.js docs/assets/js/src/application.js",
+ "update-shrinkwrap": "npm shrinkwrap --dev && shx mv ./npm-shrinkwrap.json ./grunt/npm-shrinkwrap.json",
+ "test": "npm run eslint && grunt test"
+ },
+ "style": "dist/css/bootstrap.css",
+ "sass": "scss/bootstrap.scss",
+ "main": "dist/js/bootstrap",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/twbs/bootstrap.git"
+ },
+ "bugs": {
+ "url": "https://github.com/twbs/bootstrap/issues"
+ },
+ "license": "MIT",
+ "dependencies": {
+ "jquery": ">=1.9.1",
+ "tether": "^1.4.0"
+ },
+ "devDependencies": {
+ "autoprefixer": "^6.7.7",
+ "babel-eslint": "^7.1.1",
+ "babel-plugin-transform-es2015-modules-strip": "^0.1.0",
+ "babel-preset-es2015": "^6.24.0",
+ "clean-css-cli": "^4.0.9",
+ "eslint": "^3.18.0",
+ "grunt": "^1.0.1",
+ "grunt-babel": "^6.0.0",
+ "grunt-build-control": "^0.7.1",
+ "grunt-contrib-clean": "^1.0.0",
+ "grunt-contrib-compress": "^1.4.1",
+ "grunt-contrib-concat": "^1.0.1",
+ "grunt-contrib-connect": "^1.0.2",
+ "grunt-contrib-copy": "^1.0.0",
+ "grunt-contrib-qunit": "^1.3.0",
+ "grunt-contrib-watch": "^1.0.0",
+ "grunt-exec": "^2.0.0",
+ "grunt-saucelabs": "^9.0.0",
+ "grunt-stamp": "^0.3.0",
+ "htmlhint": "^0.9.13",
+ "htmllint-cli": "^0.0.6",
+ "is-travis": "^1.0.0",
+ "load-grunt-tasks": "^3.5.2",
+ "node-sass": "^4.5.0",
+ "postcss-cli": "^3.0.0",
+ "postcss-flexbugs-fixes": "^2.1.0",
+ "shelljs": "^0.7.7",
+ "shx": "^0.2.2",
+ "time-grunt": "^1.4.0",
+ "uglify-js": "^2.8.14"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "files": [
+ "dist",
+ "grunt",
+ "js/**/*.js",
+ "scss/**/*.scss",
+ "Gruntfile.js",
+ "LICENSE"
+ ],
+ "jspm": {
+ "main": "js/bootstrap",
+ "directories": {
+ "lib": "dist"
+ },
+ "shim": {
+ "js/bootstrap": {
+ "deps": [
+ "jquery"
+ ],
+ "exports": "$"
+ }
+ },
+ "dependencies": {
+ "jquery": "3"
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/sache.json b/templates/assets/bootstrap/sache.json
new file mode 100644
index 0000000..cd1a8c4
--- /dev/null
+++ b/templates/assets/bootstrap/sache.json
@@ -0,0 +1,5 @@
+{
+ "name": "bootstrap",
+ "description": "The most popular HTML, CSS, and JavaScript framework for developing responsive, mobile first projects on the web.",
+ "tags": ["bootstrap", "grid", "typography", "buttons", "ui", "responsive-web-design"]
+}
diff --git a/templates/assets/bootstrap/scss/.scss-lint.yml b/templates/assets/bootstrap/scss/.scss-lint.yml
new file mode 100644
index 0000000..845001e
--- /dev/null
+++ b/templates/assets/bootstrap/scss/.scss-lint.yml
@@ -0,0 +1,536 @@
+# Default application configuration that all configurations inherit from.
+scss_files:
+ - "**/*.scss"
+ - "docs/assets/scss/**/*.scss"
+
+plugin_directories: ['.scss-linters']
+
+# List of gem names to load custom linters from (make sure they are already
+# installed)
+plugin_gems: []
+
+# Default severity of all linters.
+severity: warning
+
+linters:
+ BangFormat:
+ enabled: true
+ space_before_bang: true
+ space_after_bang: false
+
+ BemDepth:
+ enabled: false
+ max_elements: 1
+
+ BorderZero:
+ enabled: true
+ convention: zero # or `none`
+
+ ChainedClasses:
+ enabled: false
+
+ ColorKeyword:
+ enabled: true
+
+ ColorVariable:
+ enabled: false
+
+ Comment:
+ enabled: true
+ exclude:
+ - bootstrap.scss
+ style: silent
+
+ DebugStatement:
+ enabled: true
+
+ DeclarationOrder:
+ enabled: false
+
+ DisableLinterReason:
+ enabled: false
+
+ DuplicateProperty:
+ enabled: true
+
+ ElsePlacement:
+ enabled: true
+ style: same_line # or 'new_line'
+
+ EmptyLineBetweenBlocks:
+ enabled: false
+ ignore_single_line_blocks: true
+
+ EmptyRule:
+ enabled: true
+
+ ExtendDirective:
+ enabled: false
+
+ FinalNewline:
+ enabled: true
+ present: true
+
+ HexLength:
+ enabled: true
+ style: short # or 'long'
+
+ HexNotation:
+ enabled: true
+ style: lowercase # or 'uppercase'
+
+ HexValidation:
+ enabled: true
+
+ IdSelector:
+ enabled: true
+
+ ImportantRule:
+ enabled: false
+
+ ImportPath:
+ enabled: true
+ leading_underscore: false
+ filename_extension: false
+
+ Indentation:
+ enabled: true
+ allow_non_nested_indentation: false
+ character: space # or 'tab'
+ width: 2
+
+ LeadingZero:
+ enabled: true
+ style: exclude_zero # or 'include_zero'
+
+ MergeableSelector:
+ enabled: false
+ force_nesting: true
+
+ NameFormat:
+ enabled: true
+ allow_leading_underscore: true
+ convention: hyphenated_lowercase # or 'camel_case', or 'snake_case', or a regex pattern
+
+ NestingDepth:
+ enabled: true
+ max_depth: 4
+ ignore_parent_selectors: false
+
+ PlaceholderInExtend:
+ enabled: false
+
+ PropertyCount:
+ enabled: false
+ include_nested: false
+ max_properties: 10
+
+ PropertySortOrder:
+ enabled: true
+ ignore_unspecified: false
+ min_properties: 2
+ separate_groups: false
+ order:
+ - position
+ - top
+ - right
+ - bottom
+ - left
+ - z-index
+ - -webkit-box-sizing
+ - -moz-box-sizing
+ - box-sizing
+ - display
+ - flex
+ - flex-align
+ - flex-basis
+ - flex-direction
+ - flex-wrap
+ - flex-flow
+ - flex-grow
+ - flex-order
+ - flex-pack
+ - align-items
+ - align-self
+ - justify-content
+ - float
+ - width
+ - min-width
+ - max-width
+ - height
+ - min-height
+ - max-height
+ - padding
+ - padding-top
+ - padding-right
+ - padding-bottom
+ - padding-left
+ - margin
+ - margin-top
+ - margin-right
+ - margin-bottom
+ - margin-left
+ - overflow
+ - overflow-x
+ - overflow-y
+ - -webkit-overflow-scrolling
+ - -ms-overflow-x
+ - -ms-overflow-y
+ - -ms-overflow-style
+ - clip
+ - clear
+ - font
+ - font-family
+ - font-size
+ - font-style
+ - font-weight
+ - font-variant
+ - font-size-adjust
+ - font-stretch
+ - font-effect
+ - font-emphasize
+ - font-emphasize-position
+ - font-emphasize-style
+ - font-smooth
+ - -webkit-hyphens
+ - -moz-hyphens
+ - hyphens
+ - line-height
+ - color
+ - text-align
+ - -webkit-text-align-last
+ - -moz-text-align-last
+ - -ms-text-align-last
+ - text-align-last
+ - text-emphasis
+ - text-emphasis-color
+ - text-emphasis-style
+ - text-emphasis-position
+ - text-decoration
+ - text-indent
+ - text-justify
+ - text-outline
+ - -ms-text-overflow
+ - text-overflow
+ - text-overflow-ellipsis
+ - text-overflow-mode
+ - text-shadow
+ - text-transform
+ - text-wrap
+ - -webkit-text-size-adjust
+ - -ms-text-size-adjust
+ - letter-spacing
+ - -ms-word-break
+ - word-break
+ - word-spacing
+ - -ms-word-wrap
+ - word-wrap
+ - overflow-wrap
+ - -moz-tab-size
+ - -o-tab-size
+ - tab-size
+ - white-space
+ - vertical-align
+ - list-style
+ - list-style-position
+ - list-style-type
+ - list-style-image
+ - pointer-events
+ - -ms-touch-action
+ - touch-action
+ - cursor
+ - visibility
+ - zoom
+ - table-layout
+ - empty-cells
+ - caption-side
+ - border-spacing
+ - border-collapse
+ - content
+ - quotes
+ - counter-reset
+ - counter-increment
+ - resize
+ - -webkit-user-select
+ - -moz-user-select
+ - -ms-user-select
+ - -o-user-select
+ - user-select
+ - nav-index
+ - nav-up
+ - nav-right
+ - nav-down
+ - nav-left
+ - background
+ - background-color
+ - background-image
+ - -ms-filter:\\'progid:DXImageTransform.Microsoft.gradient
+ - filter:progid:DXImageTransform.Microsoft.gradient
+ - filter:progid:DXImageTransform.Microsoft.AlphaImageLoader
+ - filter
+ - background-repeat
+ - background-attachment
+ - background-position
+ - background-position-x
+ - background-position-y
+ - -webkit-background-clip
+ - -moz-background-clip
+ - background-clip
+ - background-origin
+ - -webkit-background-size
+ - -moz-background-size
+ - -o-background-size
+ - background-size
+ - border
+ - border-color
+ - border-style
+ - border-width
+ - border-top
+ - border-top-color
+ - border-top-style
+ - border-top-width
+ - border-right
+ - border-right-color
+ - border-right-style
+ - border-right-width
+ - border-bottom
+ - border-bottom-color
+ - border-bottom-style
+ - border-bottom-width
+ - border-left
+ - border-left-color
+ - border-left-style
+ - border-left-width
+ - border-radius
+ - border-top-left-radius
+ - border-top-right-radius
+ - border-bottom-right-radius
+ - border-bottom-left-radius
+ - -webkit-border-image
+ - -moz-border-image
+ - -o-border-image
+ - border-image
+ - -webkit-border-image-source
+ - -moz-border-image-source
+ - -o-border-image-source
+ - border-image-source
+ - -webkit-border-image-slice
+ - -moz-border-image-slice
+ - -o-border-image-slice
+ - border-image-slice
+ - -webkit-border-image-width
+ - -moz-border-image-width
+ - -o-border-image-width
+ - border-image-width
+ - -webkit-border-image-outset
+ - -moz-border-image-outset
+ - -o-border-image-outset
+ - border-image-outset
+ - -webkit-border-image-repeat
+ - -moz-border-image-repeat
+ - -o-border-image-repeat
+ - border-image-repeat
+ - outline
+ - outline-width
+ - outline-style
+ - outline-color
+ - outline-offset
+ - -webkit-box-shadow
+ - -moz-box-shadow
+ - box-shadow
+ - filter:progid:DXImageTransform.Microsoft.Alpha(Opacity
+ - -ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha
+ - opacity
+ - -ms-interpolation-mode
+ - -webkit-transition
+ - -moz-transition
+ - -ms-transition
+ - -o-transition
+ - transition
+ - -webkit-transition-delay
+ - -moz-transition-delay
+ - -ms-transition-delay
+ - -o-transition-delay
+ - transition-delay
+ - -webkit-transition-timing-function
+ - -moz-transition-timing-function
+ - -ms-transition-timing-function
+ - -o-transition-timing-function
+ - transition-timing-function
+ - -webkit-transition-duration
+ - -moz-transition-duration
+ - -ms-transition-duration
+ - -o-transition-duration
+ - transition-duration
+ - -webkit-transition-property
+ - -moz-transition-property
+ - -ms-transition-property
+ - -o-transition-property
+ - transition-property
+ - -webkit-transform
+ - -moz-transform
+ - -ms-transform
+ - -o-transform
+ - transform
+ - -webkit-transform-origin
+ - -moz-transform-origin
+ - -ms-transform-origin
+ - -o-transform-origin
+ - transform-origin
+ - -webkit-animation
+ - -moz-animation
+ - -ms-animation
+ - -o-animation
+ - animation
+ - -webkit-animation-name
+ - -moz-animation-name
+ - -ms-animation-name
+ - -o-animation-name
+ - animation-name
+ - -webkit-animation-duration
+ - -moz-animation-duration
+ - -ms-animation-duration
+ - -o-animation-duration
+ - animation-duration
+ - -webkit-animation-play-state
+ - -moz-animation-play-state
+ - -ms-animation-play-state
+ - -o-animation-play-state
+ - animation-play-state
+ - -webkit-animation-timing-function
+ - -moz-animation-timing-function
+ - -ms-animation-timing-function
+ - -o-animation-timing-function
+ - animation-timing-function
+ - -webkit-animation-delay
+ - -moz-animation-delay
+ - -ms-animation-delay
+ - -o-animation-delay
+ - animation-delay
+ - -webkit-animation-iteration-count
+ - -moz-animation-iteration-count
+ - -ms-animation-iteration-count
+ - -o-animation-iteration-count
+ - animation-iteration-count
+ - -webkit-animation-direction
+ - -moz-animation-direction
+ - -ms-animation-direction
+ - -o-animation-direction
+
+
+ PropertySpelling:
+ enabled: true
+ extra_properties: []
+ disabled_properties: []
+
+ PropertyUnits:
+ enabled: true
+ global: [
+ 'ch', 'em', 'ex', 'rem', # Font-relative lengths
+ 'cm', 'in', 'mm', 'pc', 'pt', 'px', 'q', # Absolute lengths
+ 'vh', 'vw', 'vmin', 'vmax', # Viewport-percentage lengths
+ 'deg', 'grad', 'rad', 'turn', # Angle
+ 'ms', 's', # Duration
+ 'Hz', 'kHz', # Frequency
+ 'dpi', 'dpcm', 'dppx', # Resolution
+ '%'] # Other
+ properties: {}
+
+ PseudoElement:
+ enabled: true
+
+ QualifyingElement:
+ enabled: true
+ allow_element_with_attribute: false
+ allow_element_with_class: false
+ allow_element_with_id: false
+
+ SelectorDepth:
+ enabled: true
+ max_depth: 4
+
+ SelectorFormat:
+ enabled: false
+ convention: hyphenated_lowercase # or 'strict_BEM', or 'hyphenated_BEM', or 'snake_case', or 'camel_case', or a regex pattern
+
+ Shorthand:
+ enabled: true
+ allowed_shorthands: [1, 2, 3, 4]
+
+ SingleLinePerProperty:
+ enabled: false
+ allow_single_line_rule_sets: true
+
+ SingleLinePerSelector:
+ enabled: false
+
+ SpaceAfterComma:
+ enabled: false
+ style: one_space # or 'no_space', or 'at_least_one_space'
+
+ SpaceAfterPropertyColon:
+ enabled: true
+ style: at_least_one_space # or 'no_space', or 'at_least_one_space', or 'aligned'
+
+ SpaceAfterPropertyName:
+ enabled: true
+
+ SpaceAfterVariableName:
+ enabled: true
+
+ SpaceAroundOperator:
+ enabled: true
+ style: one_space # or 'at_least_one_space', or 'no_space'
+
+ SpaceBeforeBrace:
+ enabled: true
+ style: space # or 'new_line'
+ allow_single_line_padding: true
+
+ SpaceBetweenParens:
+ enabled: true
+ spaces: 0
+
+ StringQuotes:
+ enabled: true
+ style: double_quotes # or double_quotes
+
+ TrailingSemicolon:
+ enabled: true
+
+ TrailingWhitespace:
+ enabled: true
+
+ TrailingZero:
+ enabled: false
+
+ TransitionAll:
+ enabled: false
+
+ UnnecessaryMantissa:
+ enabled: true
+
+ UnnecessaryParentReference:
+ enabled: true
+
+ UrlFormat:
+ enabled: true
+
+ UrlQuotes:
+ enabled: true
+
+ VariableForProperty:
+ enabled: false
+ properties: []
+
+ VendorPrefix:
+ enabled: true
+ identifier_list: base
+ additional_identifiers: []
+ excluded_identifiers: []
+
+ ZeroUnit:
+ enabled: true
+
+ Compass::*:
+ enabled: false
diff --git a/templates/assets/bootstrap/scss/_alert.scss b/templates/assets/bootstrap/scss/_alert.scss
new file mode 100644
index 0000000..d9b4e9b
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_alert.scss
@@ -0,0 +1,55 @@
+//
+// Base styles
+//
+
+.alert {
+ padding: $alert-padding-y $alert-padding-x;
+ margin-bottom: $alert-margin-bottom;
+ border: $alert-border-width solid transparent;
+ @include border-radius($alert-border-radius);
+}
+
+// Headings for larger alerts
+.alert-heading {
+ // Specified to prevent conflicts of changing $headings-color
+ color: inherit;
+}
+
+// Provide class for links that match alerts
+.alert-link {
+ font-weight: $alert-link-font-weight;
+}
+
+
+// Dismissible alerts
+//
+// Expand the right padding and account for the close button's positioning.
+
+.alert-dismissible {
+ // Adjust close link position
+ .close {
+ position: relative;
+ top: -$alert-padding-y;
+ right: -$alert-padding-x;
+ padding: $alert-padding-y $alert-padding-x;
+ color: inherit;
+ }
+}
+
+
+// Alternate styles
+//
+// Generate contextual modifier classes for colorizing the alert.
+
+.alert-success {
+ @include alert-variant($alert-success-bg, $alert-success-border, $alert-success-text);
+}
+.alert-info {
+ @include alert-variant($alert-info-bg, $alert-info-border, $alert-info-text);
+}
+.alert-warning {
+ @include alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text);
+}
+.alert-danger {
+ @include alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text);
+}
diff --git a/templates/assets/bootstrap/scss/_badge.scss b/templates/assets/bootstrap/scss/_badge.scss
new file mode 100644
index 0000000..175b19d
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_badge.scss
@@ -0,0 +1,76 @@
+// Base class
+//
+// Requires one of the contextual, color modifier classes for `color` and
+// `background-color`.
+
+.badge {
+ display: inline-block;
+ padding: $badge-padding-y $badge-padding-x;
+ font-size: $badge-font-size;
+ font-weight: $badge-font-weight;
+ line-height: 1;
+ color: $badge-color;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ @include border-radius();
+
+ // Empty badges collapse automatically
+ &:empty {
+ display: none;
+ }
+}
+
+// Quick fix for badges in buttons
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+
+// scss-lint:disable QualifyingElement
+// Add hover effects, but only for links
+a.badge {
+ @include hover-focus {
+ color: $badge-link-hover-color;
+ text-decoration: none;
+ }
+}
+// scss-lint:enable QualifyingElement
+
+// Pill badges
+//
+// Make them extra rounded with a modifier to replace v3's badges.
+
+.badge-pill {
+ padding-right: $badge-pill-padding-x;
+ padding-left: $badge-pill-padding-x;
+ @include border-radius($badge-pill-border-radius);
+}
+
+// Colors
+//
+// Contextual variations (linked badges get darker on :hover).
+
+.badge-default {
+ @include badge-variant($badge-default-bg);
+}
+
+.badge-primary {
+ @include badge-variant($badge-primary-bg);
+}
+
+.badge-success {
+ @include badge-variant($badge-success-bg);
+}
+
+.badge-info {
+ @include badge-variant($badge-info-bg);
+}
+
+.badge-warning {
+ @include badge-variant($badge-warning-bg);
+}
+
+.badge-danger {
+ @include badge-variant($badge-danger-bg);
+}
diff --git a/templates/assets/bootstrap/scss/_breadcrumb.scss b/templates/assets/bootstrap/scss/_breadcrumb.scss
new file mode 100644
index 0000000..2bc0e20
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_breadcrumb.scss
@@ -0,0 +1,38 @@
+.breadcrumb {
+ padding: $breadcrumb-padding-y $breadcrumb-padding-x;
+ margin-bottom: 1rem;
+ list-style: none;
+ background-color: $breadcrumb-bg;
+ @include border-radius($border-radius);
+ @include clearfix;
+}
+
+.breadcrumb-item {
+ float: left;
+
+ // The separator between breadcrumbs (by default, a forward-slash: "/")
+ + .breadcrumb-item::before {
+ display: inline-block; // Suppress underlining of the separator in modern browsers
+ padding-right: $breadcrumb-item-padding;
+ padding-left: $breadcrumb-item-padding;
+ color: $breadcrumb-divider-color;
+ content: "#{$breadcrumb-divider}";
+ }
+
+ // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
+ // without `<ul>`s. The `::before` pseudo-element generates an element
+ // *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
+ //
+ // To trick IE into suppressing the underline, we give the pseudo-element an
+ // underline and then immediately remove it.
+ + .breadcrumb-item:hover::before {
+ text-decoration: underline;
+ }
+ + .breadcrumb-item:hover::before {
+ text-decoration: none;
+ }
+
+ &.active {
+ color: $breadcrumb-active-color;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_button-group.scss b/templates/assets/bootstrap/scss/_button-group.scss
new file mode 100644
index 0000000..facecd3
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_button-group.scss
@@ -0,0 +1,204 @@
+// scss-lint:disable QualifyingElement
+
+// Make the div behave like a button
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-flex;
+ vertical-align: middle; // match .btn alignment given font-size hack above
+
+ > .btn {
+ position: relative;
+ flex: 0 1 auto;
+ margin-bottom: 0;
+
+ // Bring the hover, focused, and "active" buttons to the fron to overlay
+ // the borders properly
+ @include hover {
+ z-index: 2;
+ }
+ &:focus,
+ &:active,
+ &.active {
+ z-index: 2;
+ }
+ }
+
+ // Prevent double borders when buttons are next to each other
+ .btn + .btn,
+ .btn + .btn-group,
+ .btn-group + .btn,
+ .btn-group + .btn-group {
+ margin-left: -$input-btn-border-width;
+ }
+}
+
+// Optional: Group multiple button groups together for a toolbar
+.btn-toolbar {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+
+ .input-group {
+ width: auto;
+ }
+}
+
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0;
+}
+
+// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match
+.btn-group > .btn:first-child {
+ margin-left: 0;
+
+ &:not(:last-child):not(.dropdown-toggle) {
+ @include border-right-radius(0);
+ }
+}
+// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+ @include border-left-radius(0);
+}
+
+// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)
+.btn-group > .btn-group {
+ float: left;
+}
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group > .btn-group:first-child:not(:last-child) {
+ > .btn:last-child,
+ > .dropdown-toggle {
+ @include border-right-radius(0);
+ }
+}
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ @include border-left-radius(0);
+}
+
+// On active and open, don't show outline
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+
+
+// Sizing
+//
+// Remix the default button sizing classes into new ones for easier manipulation.
+
+.btn-group-sm > .btn { @extend .btn-sm; }
+.btn-group-lg > .btn { @extend .btn-lg; }
+
+
+//
+// Split button dropdowns
+//
+
+.btn + .dropdown-toggle-split {
+ padding-right: $btn-padding-x * .75;
+ padding-left: $btn-padding-x * .75;
+
+ &::after {
+ margin-left: 0;
+ }
+}
+
+.btn-sm + .dropdown-toggle-split {
+ padding-right: $btn-padding-x-sm * .75;
+ padding-left: $btn-padding-x-sm * .75;
+}
+
+.btn-lg + .dropdown-toggle-split {
+ padding-right: $btn-padding-x-lg * .75;
+ padding-left: $btn-padding-x-lg * .75;
+}
+
+
+// The clickable button for toggling the menu
+// Remove the gradient and set the same inset shadow as the :active state
+.btn-group.open .dropdown-toggle {
+ @include box-shadow($btn-active-box-shadow);
+
+ // Show no shadow for `.btn-link` since it has no other button styles.
+ &.btn-link {
+ @include box-shadow(none);
+ }
+}
+
+
+//
+// Vertical button groups
+//
+
+.btn-group-vertical {
+ display: inline-flex;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: center;
+
+ .btn,
+ .btn-group {
+ width: 100%;
+ }
+
+ > .btn + .btn,
+ > .btn + .btn-group,
+ > .btn-group + .btn,
+ > .btn-group + .btn-group {
+ margin-top: -$input-btn-border-width;
+ margin-left: 0;
+ }
+}
+
+.btn-group-vertical > .btn {
+ &:not(:first-child):not(:last-child) {
+ border-radius: 0;
+ }
+ &:first-child:not(:last-child) {
+ @include border-bottom-radius(0);
+ }
+ &:last-child:not(:first-child) {
+ @include border-top-radius(0);
+ }
+}
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn-group:first-child:not(:last-child) {
+ > .btn:last-child,
+ > .dropdown-toggle {
+ @include border-bottom-radius(0);
+ }
+}
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ @include border-top-radius(0);
+}
+
+
+// Checkbox and radio options
+//
+// In order to support the browser's form validation feedback, powered by the
+// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
+// `display: none;` or `visibility: hidden;` as that also hides the popover.
+// Simply visually hiding the inputs via `opacity` would leave them clickable in
+// certain cases which is prevented by using `clip` and `pointer-events`.
+// This way, we ensure a DOM element is visible to position the popover from.
+//
+// See https://github.com/twbs/bootstrap/pull/12794 and
+// https://github.com/twbs/bootstrap/pull/14559 for more information.
+
+[data-toggle="buttons"] {
+ > .btn,
+ > .btn-group > .btn {
+ input[type="radio"],
+ input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0,0,0,0);
+ pointer-events: none;
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_buttons.scss b/templates/assets/bootstrap/scss/_buttons.scss
new file mode 100644
index 0000000..2964a52
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_buttons.scss
@@ -0,0 +1,170 @@
+// scss-lint:disable QualifyingElement
+
+//
+// Base styles
+//
+
+.btn {
+ display: inline-block;
+ font-weight: $btn-font-weight;
+ line-height: $btn-line-height;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ user-select: none;
+ border: $input-btn-border-width solid transparent;
+ @include button-size($btn-padding-y, $btn-padding-x, $font-size-base, $btn-border-radius);
+ @include transition($btn-transition);
+
+ // Share hover and focus styles
+ @include hover-focus {
+ text-decoration: none;
+ }
+ &:focus,
+ &.focus {
+ outline: 0;
+ box-shadow: $btn-focus-box-shadow;
+ }
+
+ // Disabled comes first so active can properly restyle
+ &.disabled,
+ &:disabled {
+ cursor: $cursor-disabled;
+ opacity: .65;
+ @include box-shadow(none);
+ }
+
+ &:active,
+ &.active {
+ background-image: none;
+ @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
+ }
+}
+
+// Future-proof disabling of clicks on `<a>` elements
+a.btn.disabled,
+fieldset[disabled] a.btn {
+ pointer-events: none;
+}
+
+
+//
+// Alternate buttons
+//
+
+.btn-primary {
+ @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border);
+}
+.btn-secondary {
+ @include button-variant($btn-secondary-color, $btn-secondary-bg, $btn-secondary-border);
+}
+.btn-info {
+ @include button-variant($btn-info-color, $btn-info-bg, $btn-info-border);
+}
+.btn-success {
+ @include button-variant($btn-success-color, $btn-success-bg, $btn-success-border);
+}
+.btn-warning {
+ @include button-variant($btn-warning-color, $btn-warning-bg, $btn-warning-border);
+}
+.btn-danger {
+ @include button-variant($btn-danger-color, $btn-danger-bg, $btn-danger-border);
+}
+
+// Remove all backgrounds
+.btn-outline-primary {
+ @include button-outline-variant($btn-primary-bg, $btn-primary-color);
+}
+.btn-outline-secondary {
+ @include button-outline-variant($btn-secondary-border, $btn-secondary-color);
+}
+.btn-outline-info {
+ @include button-outline-variant($btn-info-bg, $btn-info-color);
+}
+.btn-outline-success {
+ @include button-outline-variant($btn-success-bg, $btn-success-color);
+}
+.btn-outline-warning {
+ @include button-outline-variant($btn-warning-bg, $btn-warning-color);
+}
+.btn-outline-danger {
+ @include button-outline-variant($btn-danger-bg, $btn-danger-color);
+}
+
+
+//
+// Link buttons
+//
+
+// Make a button look and behave like a link
+.btn-link {
+ font-weight: $font-weight-normal;
+ color: $link-color;
+ border-radius: 0;
+
+ &,
+ &:active,
+ &.active,
+ &:disabled {
+ background-color: transparent;
+ @include box-shadow(none);
+ }
+ &,
+ &:focus,
+ &:active {
+ border-color: transparent;
+ }
+ @include hover {
+ border-color: transparent;
+ }
+ @include hover-focus {
+ color: $link-hover-color;
+ text-decoration: $link-hover-decoration;
+ background-color: transparent;
+ }
+ &:disabled {
+ color: $btn-link-disabled-color;
+
+ @include hover-focus {
+ text-decoration: none;
+ }
+ }
+}
+
+
+//
+// Button Sizes
+//
+
+.btn-lg {
+ // line-height: ensure even-numbered height of button next to large input
+ @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $font-size-lg, $btn-border-radius-lg);
+}
+.btn-sm {
+ // line-height: ensure proper height of button next to small input
+ @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $font-size-sm, $btn-border-radius-sm);
+}
+
+
+//
+// Block button
+//
+
+.btn-block {
+ display: block;
+ width: 100%;
+}
+
+// Vertically space out multiple block buttons
+.btn-block + .btn-block {
+ margin-top: $btn-block-spacing-y;
+}
+
+// Specificity overrides
+input[type="submit"],
+input[type="reset"],
+input[type="button"] {
+ &.btn-block {
+ width: 100%;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_card.scss b/templates/assets/bootstrap/scss/_card.scss
new file mode 100644
index 0000000..9fe70e8
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_card.scss
@@ -0,0 +1,276 @@
+//
+// Base styles
+//
+
+.card {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ background-color: $card-bg;
+ border: $card-border-width solid $card-border-color;
+ @include border-radius($card-border-radius);
+}
+
+.card-block {
+ // Enable `flex-grow: 1` for decks and groups so that card blocks take up
+ // as much space as possible, ensuring footers are aligned to the bottom.
+ flex: 1 1 auto;
+ padding: $card-spacer-x;
+}
+
+.card-title {
+ margin-bottom: $card-spacer-y;
+}
+
+.card-subtitle {
+ margin-top: -($card-spacer-y / 2);
+ margin-bottom: 0;
+}
+
+.card-text:last-child {
+ margin-bottom: 0;
+}
+
+.card-link {
+ @include hover {
+ text-decoration: none;
+ }
+
+ + .card-link {
+ margin-left: $card-spacer-x;
+ }
+}
+
+.card {
+ > .list-group:first-child {
+ .list-group-item:first-child {
+ @include border-top-radius($card-border-radius);
+ }
+ }
+
+ > .list-group:last-child {
+ .list-group-item:last-child {
+ @include border-bottom-radius($card-border-radius);
+ }
+ }
+}
+
+
+//
+// Optional textual caps
+//
+
+.card-header {
+ padding: $card-spacer-y $card-spacer-x;
+ margin-bottom: 0; // Removes the default margin-bottom of <hN>
+ background-color: $card-cap-bg;
+ border-bottom: $card-border-width solid $card-border-color;
+
+ &:first-child {
+ @include border-radius($card-border-radius-inner $card-border-radius-inner 0 0);
+ }
+}
+
+.card-footer {
+ padding: $card-spacer-y $card-spacer-x;
+ background-color: $card-cap-bg;
+ border-top: $card-border-width solid $card-border-color;
+
+ &:last-child {
+ @include border-radius(0 0 $card-border-radius-inner $card-border-radius-inner);
+ }
+}
+
+
+//
+// Header navs
+//
+
+.card-header-tabs {
+ margin-right: -($card-spacer-x / 2);
+ margin-bottom: -$card-spacer-y;
+ margin-left: -($card-spacer-x / 2);
+ border-bottom: 0;
+}
+
+.card-header-pills {
+ margin-right: -($card-spacer-x / 2);
+ margin-left: -($card-spacer-x / 2);
+}
+
+
+//
+// Background variations
+//
+
+.card-primary {
+ @include card-variant($brand-primary, $brand-primary);
+}
+.card-success {
+ @include card-variant($brand-success, $brand-success);
+}
+.card-info {
+ @include card-variant($brand-info, $brand-info);
+}
+.card-warning {
+ @include card-variant($brand-warning, $brand-warning);
+}
+.card-danger {
+ @include card-variant($brand-danger, $brand-danger);
+}
+
+// Remove all backgrounds
+.card-outline-primary {
+ @include card-outline-variant($btn-primary-bg);
+}
+.card-outline-secondary {
+ @include card-outline-variant($btn-secondary-border);
+}
+.card-outline-info {
+ @include card-outline-variant($btn-info-bg);
+}
+.card-outline-success {
+ @include card-outline-variant($btn-success-bg);
+}
+.card-outline-warning {
+ @include card-outline-variant($btn-warning-bg);
+}
+.card-outline-danger {
+ @include card-outline-variant($btn-danger-bg);
+}
+
+//
+// Inverse text within a card for use with dark backgrounds
+//
+
+.card-inverse {
+ @include card-inverse;
+}
+
+//
+// Blockquote
+//
+
+.card-blockquote {
+ padding: 0;
+ margin-bottom: 0;
+ border-left: 0;
+}
+
+// Card image
+.card-img {
+ // margin: -1.325rem;
+ @include border-radius($card-border-radius-inner);
+}
+.card-img-overlay {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ padding: $card-img-overlay-padding;
+}
+
+
+
+// Card image caps
+.card-img-top {
+ @include border-top-radius($card-border-radius-inner);
+}
+.card-img-bottom {
+ @include border-bottom-radius($card-border-radius-inner);
+}
+
+
+// Card deck
+
+@include media-breakpoint-up(sm) {
+ .card-deck {
+ display: flex;
+ flex-flow: row wrap;
+
+ .card {
+ display: flex;
+ flex: 1 0 0;
+ flex-direction: column;
+
+ // Selectively apply horizontal margins to cards to avoid doing the
+ // negative margin dance like our grid. This differs from the grid
+ // due to the use of margins as gutters instead of padding.
+ &:not(:first-child) { margin-left: $card-deck-margin; }
+ &:not(:last-child) { margin-right: $card-deck-margin; }
+ }
+ }
+}
+
+
+//
+// Card groups
+//
+
+@include media-breakpoint-up(sm) {
+ .card-group {
+ display: flex;
+ flex-flow: row wrap;
+
+ .card {
+ flex: 1 0 0;
+
+ + .card {
+ margin-left: 0;
+ border-left: 0;
+ }
+
+ // Handle rounded corners
+ @if $enable-rounded {
+ &:first-child {
+ @include border-right-radius(0);
+
+ .card-img-top {
+ border-top-right-radius: 0;
+ }
+ .card-img-bottom {
+ border-bottom-right-radius: 0;
+ }
+ }
+ &:last-child {
+ @include border-left-radius(0);
+
+ .card-img-top {
+ border-top-left-radius: 0;
+ }
+ .card-img-bottom {
+ border-bottom-left-radius: 0;
+ }
+ }
+
+ &:not(:first-child):not(:last-child) {
+ border-radius: 0;
+
+ .card-img-top,
+ .card-img-bottom {
+ border-radius: 0;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+//
+// Columns
+//
+
+@include media-breakpoint-up(sm) {
+ .card-columns {
+ column-count: $card-columns-count;
+ column-gap: $card-columns-gap;
+
+ .card {
+ display: inline-block; // Don't let them vertically span multiple columns
+ width: 100%; // Don't let their width change
+ margin-bottom: $card-columns-margin;
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_carousel.scss b/templates/assets/bootstrap/scss/_carousel.scss
new file mode 100644
index 0000000..1b6e450
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_carousel.scss
@@ -0,0 +1,177 @@
+// Wrapper for the slide container and indicators
+.carousel {
+ position: relative;
+}
+
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+
+.carousel-item {
+ position: relative;
+ display: none;
+ width: 100%;
+
+ @include if-supports-3d-transforms() {
+ @include transition($carousel-transition);
+ backface-visibility: hidden;
+ perspective: 1000px;
+ }
+}
+
+.carousel-item.active,
+.carousel-item-next,
+.carousel-item-prev {
+ display: flex;
+}
+
+.carousel-item-next,
+.carousel-item-prev {
+ position: absolute;
+ top: 0;
+}
+
+// CSS3 transforms when supported by the browser
+@include if-supports-3d-transforms() {
+ .carousel-item-next.carousel-item-left,
+ .carousel-item-prev.carousel-item-right {
+ transform: translate3d(0, 0, 0);
+ }
+
+ .carousel-item-next,
+ .active.carousel-item-right {
+ transform: translate3d(100%, 0, 0);
+ }
+
+ .carousel-item-prev,
+ .active.carousel-item-left {
+ transform: translate3d(-100%, 0, 0);
+ }
+}
+
+
+//
+// Left/right controls for nav
+//
+
+.carousel-control-prev,
+.carousel-control-next {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ // Use flex for alignment (1-3)
+ display: flex; // 1. allow flex styles
+ align-items: center; // 2. vertically center contents
+ justify-content: center; // 3. horizontally center contents
+ width: $carousel-control-width;
+ color: $carousel-control-color;
+ text-align: center;
+ opacity: $carousel-control-opacity;
+ // We can't have a transition here because WebKit cancels the carousel
+ // animation if you trip this while in the middle of another animation.
+
+ // Hover/focus state
+ @include hover-focus {
+ color: $carousel-control-color;
+ text-decoration: none;
+ outline: 0;
+ opacity: .9;
+ }
+}
+.carousel-control-prev {
+ left: 0;
+}
+.carousel-control-next {
+ right: 0;
+}
+
+// Icons for within
+.carousel-control-prev-icon,
+.carousel-control-next-icon {
+ display: inline-block;
+ width: $carousel-control-icon-width;
+ height: $carousel-control-icon-width;
+ background: transparent no-repeat center center;
+ background-size: 100% 100%;
+}
+.carousel-control-prev-icon {
+ background-image: $carousel-control-prev-icon-bg;
+}
+.carousel-control-next-icon {
+ background-image: $carousel-control-next-icon-bg;
+}
+
+
+// Optional indicator pips
+//
+// Add an ordered list with the following class and add a list item for each
+// slide your carousel holds.
+
+.carousel-indicators {
+ position: absolute;
+ right: 0;
+ bottom: 10px;
+ left: 0;
+ z-index: 15;
+ display: flex;
+ justify-content: center;
+ padding-left: 0; // override <ol> default
+ // Use the .carousel-control's width as margin so we don't overlay those
+ margin-right: $carousel-control-width;
+ margin-left: $carousel-control-width;
+ list-style: none;
+
+ li {
+ position: relative;
+ flex: 1 0 auto;
+ max-width: $carousel-indicator-width;
+ height: $carousel-indicator-height;
+ margin-right: $carousel-indicator-spacer;
+ margin-left: $carousel-indicator-spacer;
+ text-indent: -999px;
+ background-color: rgba($carousel-indicator-active-bg, .5);
+
+ // Use pseudo classes to increase the hit area by 10px on top and bottom.
+ &::before {
+ position: absolute;
+ top: -10px;
+ left: 0;
+ display: inline-block;
+ width: 100%;
+ height: 10px;
+ content: "";
+ }
+ &::after {
+ position: absolute;
+ bottom: -10px;
+ left: 0;
+ display: inline-block;
+ width: 100%;
+ height: 10px;
+ content: "";
+ }
+ }
+
+ .active {
+ background-color: $carousel-indicator-active-bg;
+ }
+}
+
+
+// Optional captions
+//
+//
+
+.carousel-caption {
+ position: absolute;
+ right: ((100% - $carousel-caption-width) / 2);
+ bottom: 20px;
+ left: ((100% - $carousel-caption-width) / 2);
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: $carousel-caption-color;
+ text-align: center;
+}
diff --git a/templates/assets/bootstrap/scss/_close.scss b/templates/assets/bootstrap/scss/_close.scss
new file mode 100644
index 0000000..f181490
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_close.scss
@@ -0,0 +1,29 @@
+.close {
+ float: right;
+ font-size: $close-font-size;
+ font-weight: $close-font-weight;
+ line-height: 1;
+ color: $close-color;
+ text-shadow: $close-text-shadow;
+ opacity: .5;
+
+ @include hover-focus {
+ color: $close-color;
+ text-decoration: none;
+ opacity: .75;
+ }
+}
+
+// Additional properties for button version
+// iOS requires the button element instead of an anchor tag.
+// If you want the anchor version, it requires `href="#"`.
+// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
+
+// scss-lint:disable QualifyingElement
+button.close {
+ padding: 0;
+ background: transparent;
+ border: 0;
+ -webkit-appearance: none;
+}
+// scss-lint:enable QualifyingElement
diff --git a/templates/assets/bootstrap/scss/_code.scss b/templates/assets/bootstrap/scss/_code.scss
new file mode 100644
index 0000000..759da15
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_code.scss
@@ -0,0 +1,64 @@
+// Inline and block code styles
+code,
+kbd,
+pre,
+samp {
+ font-family: $font-family-monospace;
+}
+
+// Inline code
+code {
+ padding: $code-padding-y $code-padding-x;
+ font-size: $code-font-size;
+ color: $code-color;
+ background-color: $code-bg;
+ @include border-radius($border-radius);
+
+ // Streamline the style when inside anchors to avoid broken underline and more
+ a > & {
+ padding: 0;
+ color: inherit;
+ background-color: inherit;
+ }
+}
+
+// User input typically entered via keyboard
+kbd {
+ padding: $code-padding-y $code-padding-x;
+ font-size: $code-font-size;
+ color: $kbd-color;
+ background-color: $kbd-bg;
+ @include border-radius($border-radius-sm);
+ @include box-shadow($kbd-box-shadow);
+
+ kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: $nested-kbd-font-weight;
+ @include box-shadow(none);
+ }
+}
+
+// Blocks of code
+pre {
+ display: block;
+ margin-top: 0;
+ margin-bottom: 1rem;
+ font-size: $code-font-size;
+ color: $pre-color;
+
+ // Account for some code outputs that place code tags in pre tags
+ code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ background-color: transparent;
+ border-radius: 0;
+ }
+}
+
+// Enable scrollable blocks of code
+.pre-scrollable {
+ max-height: $pre-scrollable-max-height;
+ overflow-y: scroll;
+}
diff --git a/templates/assets/bootstrap/scss/_custom-forms.scss b/templates/assets/bootstrap/scss/_custom-forms.scss
new file mode 100644
index 0000000..d303c48
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_custom-forms.scss
@@ -0,0 +1,258 @@
+// scss-lint:disable PropertyCount, VendorPrefix
+
+// Embedded icons from Open Iconic.
+// Released under MIT and copyright 2014 Waybury.
+// https://useiconic.com/open
+
+
+// Checkboxes and radios
+//
+// Base class takes care of all the key behavioral aspects.
+
+.custom-control {
+ position: relative;
+ display: inline-flex;
+ min-height: (1rem * $line-height-base);
+ padding-left: $custom-control-gutter;
+ margin-right: $custom-control-spacer-x;
+}
+
+.custom-control-input {
+ position: absolute;
+ z-index: -1; // Put the input behind the label so it doesn't overlay text
+ opacity: 0;
+
+ &:checked ~ .custom-control-indicator {
+ color: $custom-control-checked-indicator-color;
+ background-color: $custom-control-checked-indicator-bg;
+ @include box-shadow($custom-control-checked-indicator-box-shadow);
+ }
+
+ &:focus ~ .custom-control-indicator {
+ // the mixin is not used here to make sure there is feedback
+ box-shadow: $custom-control-focus-indicator-box-shadow;
+ }
+
+ &:active ~ .custom-control-indicator {
+ color: $custom-control-active-indicator-color;
+ background-color: $custom-control-active-indicator-bg;
+ @include box-shadow($custom-control-active-indicator-box-shadow);
+ }
+
+ &:disabled {
+ ~ .custom-control-indicator {
+ cursor: $custom-control-disabled-cursor;
+ background-color: $custom-control-disabled-indicator-bg;
+ }
+
+ ~ .custom-control-description {
+ color: $custom-control-disabled-description-color;
+ cursor: $custom-control-disabled-cursor;
+ }
+ }
+}
+
+// Custom indicator
+//
+// Generates a shadow element to create our makeshift checkbox/radio background.
+
+.custom-control-indicator {
+ position: absolute;
+ top: (($line-height-base - $custom-control-indicator-size) / 2);
+ left: 0;
+ display: block;
+ width: $custom-control-indicator-size;
+ height: $custom-control-indicator-size;
+ pointer-events: none;
+ user-select: none;
+ background-color: $custom-control-indicator-bg;
+ background-repeat: no-repeat;
+ background-position: center center;
+ background-size: $custom-control-indicator-bg-size;
+ @include box-shadow($custom-control-indicator-box-shadow);
+}
+
+// Checkboxes
+//
+// Tweak just a few things for checkboxes.
+
+.custom-checkbox {
+ .custom-control-indicator {
+ @include border-radius($custom-checkbox-radius);
+ }
+
+ .custom-control-input:checked ~ .custom-control-indicator {
+ background-image: $custom-checkbox-checked-icon;
+ }
+
+ .custom-control-input:indeterminate ~ .custom-control-indicator {
+ background-color: $custom-checkbox-indeterminate-bg;
+ background-image: $custom-checkbox-indeterminate-icon;
+ @include box-shadow($custom-checkbox-indeterminate-box-shadow);
+ }
+}
+
+// Radios
+//
+// Tweak just a few things for radios.
+
+.custom-radio {
+ .custom-control-indicator {
+ border-radius: $custom-radio-radius;
+ }
+
+ .custom-control-input:checked ~ .custom-control-indicator {
+ background-image: $custom-radio-checked-icon;
+ }
+}
+
+
+// Layout options
+//
+// By default radios and checkboxes are `inline-block` with no additional spacing
+// set. Use these optional classes to tweak the layout.
+
+.custom-controls-stacked {
+ display: flex;
+ flex-direction: column;
+
+ .custom-control {
+ margin-bottom: $custom-control-spacer-y;
+
+ + .custom-control {
+ margin-left: 0;
+ }
+ }
+}
+
+
+// Select
+//
+// Replaces the browser default select with a custom one, mostly pulled from
+// http://primercss.io.
+//
+
+.custom-select {
+ display: inline-block;
+ max-width: 100%;
+ $select-border-width: ($custom-select-border-width * 2);
+ height: calc(#{$input-height} + #{$select-border-width});
+ padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;
+ line-height: $custom-select-line-height;
+ color: $custom-select-color;
+ vertical-align: middle;
+ background: $custom-select-bg $custom-select-indicator no-repeat right $custom-select-padding-x center;
+ background-size: $custom-select-bg-size;
+ border: $custom-select-border-width solid $custom-select-border-color;
+ @include border-radius($custom-select-border-radius);
+ appearance: none;
+
+ &:focus {
+ border-color: $custom-select-focus-border-color;
+ outline: none;
+ @include box-shadow($custom-select-focus-box-shadow);
+
+ &::-ms-value {
+ // For visual consistency with other platforms/browsers,
+ // supress the default white text on blue background highlight given to
+ // the selected option text when the (still closed) <select> receives focus
+ // in IE and (under certain conditions) Edge.
+ // See https://github.com/twbs/bootstrap/issues/19398.
+ color: $input-color;
+ background-color: $input-bg;
+ }
+ }
+
+ &:disabled {
+ color: $custom-select-disabled-color;
+ cursor: $cursor-disabled;
+ background-color: $custom-select-disabled-bg;
+ }
+
+ // Hides the default caret in IE11
+ &::-ms-expand {
+ opacity: 0;
+ }
+}
+
+.custom-select-sm {
+ padding-top: $custom-select-padding-y;
+ padding-bottom: $custom-select-padding-y;
+ font-size: $custom-select-sm-font-size;
+
+ // &:not([multiple]) {
+ // height: 26px;
+ // min-height: 26px;
+ // }
+}
+
+
+// File
+//
+// Custom file input.
+
+.custom-file {
+ position: relative;
+ display: inline-block;
+ max-width: 100%;
+ height: $custom-file-height;
+ margin-bottom: 0;
+}
+
+.custom-file-input {
+ min-width: $custom-file-width;
+ max-width: 100%;
+ height: $custom-file-height;
+ margin: 0;
+ opacity: 0;
+
+ &:focus ~ .custom-file-control {
+ @include box-shadow($custom-file-focus-box-shadow);
+ }
+}
+
+.custom-file-control {
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ z-index: 5;
+ height: $custom-file-height;
+ padding: $custom-file-padding-x $custom-file-padding-y;
+ line-height: $custom-file-line-height;
+ color: $custom-file-color;
+ pointer-events: none;
+ user-select: none;
+ background-color: $custom-file-bg;
+ border: $custom-file-border-width solid $custom-file-border-color;
+ @include border-radius($custom-file-border-radius);
+ @include box-shadow($custom-file-box-shadow);
+
+ @each $lang, $text in map-get($custom-file-text, placeholder) {
+ &:lang(#{$lang}):empty::after {
+ content: $text;
+ }
+ }
+
+ &::before {
+ position: absolute;
+ top: -$custom-file-border-width;
+ right: -$custom-file-border-width;
+ bottom: -$custom-file-border-width;
+ z-index: 6;
+ display: block;
+ height: $custom-file-height;
+ padding: $custom-file-padding-x $custom-file-padding-y;
+ line-height: $custom-file-line-height;
+ color: $custom-file-button-color;
+ background-color: $custom-file-button-bg;
+ border: $custom-file-border-width solid $custom-file-border-color;
+ @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);
+ }
+
+ @each $lang, $text in map-get($custom-file-text, button-label) {
+ &:lang(#{$lang})::before {
+ content: $text;
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_custom.scss b/templates/assets/bootstrap/scss/_custom.scss
new file mode 100644
index 0000000..88ccf20
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_custom.scss
@@ -0,0 +1,4 @@
+// Bootstrap overrides
+//
+// Copy variables from `_variables.scss` to this file to override default values
+// without modifying source files.
diff --git a/templates/assets/bootstrap/scss/_dropdown.scss b/templates/assets/bootstrap/scss/_dropdown.scss
new file mode 100644
index 0000000..404483e
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_dropdown.scss
@@ -0,0 +1,156 @@
+// The dropdown wrapper (`<div>`)
+.dropup,
+.dropdown {
+ position: relative;
+}
+
+.dropdown-toggle {
+ // Generate the caret automatically
+ &::after {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: $caret-width;
+ vertical-align: middle;
+ content: "";
+ border-top: $caret-width solid;
+ border-right: $caret-width solid transparent;
+ border-left: $caret-width solid transparent;
+ }
+}
+
+.dropup {
+ .dropdown-toggle {
+ &::after {
+ border-top: 0;
+ border-bottom: $caret-width solid;
+ }
+ }
+}
+
+// The dropdown menu
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: $zindex-dropdown;
+ display: none; // none by default, but block on "open" of the menu
+ float: left;
+ min-width: $dropdown-min-width;
+ padding: $dropdown-padding-y 0;
+ margin: $dropdown-margin-top 0 0; // override default ul
+ font-size: $font-size-base; // Redeclare because nesting can cause inheritance issues
+ color: $body-color;
+ text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
+ list-style: none;
+ background-color: $dropdown-bg;
+ background-clip: padding-box;
+ border: $dropdown-border-width solid $dropdown-border-color;
+ @include border-radius($border-radius);
+ @include box-shadow($dropdown-box-shadow);
+}
+
+// Dividers (basically an `<hr>`) within the dropdown
+.dropdown-divider {
+ @include nav-divider($dropdown-divider-bg);
+}
+
+// Links, buttons, and more within the dropdown menu
+//
+// `<button>`-specific styles are denoted with `// For <button>s`
+.dropdown-item {
+ display: block;
+ width: 100%; // For `<button>`s
+ padding: 3px $dropdown-item-padding-x;
+ clear: both;
+ font-weight: $font-weight-normal;
+ color: $dropdown-link-color;
+ text-align: inherit; // For `<button>`s
+ white-space: nowrap; // prevent links from randomly breaking onto new lines
+ background: none; // For `<button>`s
+ border: 0; // For `<button>`s
+
+ @include hover-focus {
+ color: $dropdown-link-hover-color;
+ text-decoration: none;
+ background-color: $dropdown-link-hover-bg;
+ }
+
+ &.active,
+ &:active {
+ color: $dropdown-link-active-color;
+ text-decoration: none;
+ background-color: $dropdown-link-active-bg;
+ }
+
+ &.disabled,
+ &:disabled {
+ color: $dropdown-link-disabled-color;
+ cursor: $cursor-disabled;
+ background-color: transparent;
+ // Remove CSS gradients if they're enabled
+ @if $enable-gradients {
+ background-image: none;
+ }
+ }
+}
+
+// Open state for the dropdown
+.show {
+ // Show the menu
+ > .dropdown-menu {
+ display: block;
+ }
+
+ // Remove the outline when :focus is triggered
+ > a {
+ outline: 0;
+ }
+}
+
+// Menu positioning
+//
+// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown
+// menu with the parent.
+.dropdown-menu-right {
+ right: 0;
+ left: auto; // Reset the default from `.dropdown-menu`
+}
+
+.dropdown-menu-left {
+ right: auto;
+ left: 0;
+}
+
+// Dropdown section headers
+.dropdown-header {
+ display: block;
+ padding: $dropdown-padding-y $dropdown-item-padding-x;
+ margin-bottom: 0; // for use with heading elements
+ font-size: $font-size-sm;
+ color: $dropdown-header-color;
+ white-space: nowrap; // as with > li > a
+}
+
+// Backdrop to catch body clicks on mobile, etc.
+.dropdown-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $zindex-dropdown-backdrop;
+}
+
+// Allow for dropdowns to go bottom up (aka, dropup-menu)
+//
+// Just add .dropup after the standard .dropdown class and you're set.
+
+.dropup {
+ // Different positioning for bottom up menu
+ .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: $dropdown-margin-top;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_forms.scss b/templates/assets/bootstrap/scss/_forms.scss
new file mode 100644
index 0000000..4ec9f6e
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_forms.scss
@@ -0,0 +1,387 @@
+// scss-lint:disable QualifyingElement, VendorPrefix
+
+//
+// Textual form controls
+//
+
+.form-control {
+ display: block;
+ width: 100%;
+ // // Make inputs at least the height of their button counterpart (base line-height + padding + border)
+ // height: $input-height;
+ padding: $input-padding-y $input-padding-x;
+ font-size: $font-size-base;
+ line-height: $input-line-height;
+ color: $input-color;
+ background-color: $input-bg;
+ // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214.
+ background-image: none;
+ background-clip: padding-box;
+ border: $input-btn-border-width solid $input-border-color;
+
+ // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
+ @if $enable-rounded {
+ // Manually use the if/else instead of the mixin to account for iOS override
+ border-radius: $input-border-radius;
+ } @else {
+ // Otherwise undo the iOS default
+ border-radius: 0;
+ }
+
+ @include box-shadow($input-box-shadow);
+ @include transition($input-transition);
+
+ // Unstyle the caret on `<select>`s in IE10+.
+ &::-ms-expand {
+ background-color: transparent;
+ border: 0;
+ }
+
+ // Customize the `:focus` state to imitate native WebKit styles.
+ @include form-control-focus();
+
+ // Placeholder
+ &::placeholder {
+ color: $input-color-placeholder;
+ // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
+ opacity: 1;
+ }
+
+ // Disabled and read-only inputs
+ //
+ // HTML5 says that controls under a fieldset > legend:first-child won't be
+ // disabled if the fieldset is disabled. Due to implementation difficulty, we
+ // don't honor that edge case; we style them as disabled anyway.
+ &:disabled,
+ &[readonly] {
+ background-color: $input-bg-disabled;
+ // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
+ opacity: 1;
+ }
+
+ &:disabled {
+ cursor: $cursor-disabled;
+ }
+}
+
+select.form-control {
+ &:not([size]):not([multiple]) {
+ $select-border-width: ($border-width * 2);
+ height: calc(#{$input-height} + #{$select-border-width});
+ }
+
+ &:focus::-ms-value {
+ // Suppress the nested default white text on blue background highlight given to
+ // the selected option text when the (still closed) <select> receives focus
+ // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to
+ // match the appearance of the native widget.
+ // See https://github.com/twbs/bootstrap/issues/19398.
+ color: $input-color;
+ background-color: $input-bg;
+ }
+}
+
+// Make file inputs better match text inputs by forcing them to new lines.
+.form-control-file,
+.form-control-range {
+ display: block;
+}
+
+
+//
+// Labels
+//
+
+// For use with horizontal and inline forms, when you need the label text to
+// align with the form controls.
+.col-form-label {
+ padding-top: calc(#{$input-padding-y} - #{$input-btn-border-width} * 2);
+ padding-bottom: calc(#{$input-padding-y} - #{$input-btn-border-width} * 2);
+ margin-bottom: 0; // Override the `<label>` default
+}
+
+.col-form-label-lg {
+ padding-top: calc(#{$input-padding-y-lg} - #{$input-btn-border-width} * 2);
+ padding-bottom: calc(#{$input-padding-y-lg} - #{$input-btn-border-width} * 2);
+ font-size: $font-size-lg;
+}
+
+.col-form-label-sm {
+ padding-top: calc(#{$input-padding-y-sm} - #{$input-btn-border-width} * 2);
+ padding-bottom: calc(#{$input-padding-y-sm} - #{$input-btn-border-width} * 2);
+ font-size: $font-size-sm;
+}
+
+
+//
+// Legends
+//
+
+// For use with horizontal and inline forms, when you need the legend text to
+// be the same size as regular labels, and to align with the form controls.
+.col-form-legend {
+ padding-top: $input-padding-y;
+ padding-bottom: $input-padding-y;
+ margin-bottom: 0;
+ font-size: $font-size-base;
+}
+
+
+// Static form control text
+//
+// Apply class to an element to make any string of text align with labels in a
+// horizontal form layout.
+
+.form-control-static {
+ padding-top: $input-padding-y;
+ padding-bottom: $input-padding-y;
+ margin-bottom: 0; // match inputs if this class comes on inputs with default margins
+ line-height: $input-line-height;
+ border: solid transparent;
+ border-width: $input-btn-border-width 0;
+
+ &.form-control-sm,
+ &.form-control-lg {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+
+
+// Form control sizing
+//
+// Build on `.form-control` with modifier classes to decrease or increase the
+// height and font-size of form controls.
+//
+// The `.form-group-* form-control` variations are sadly duplicated to avoid the
+// issue documented in https://github.com/twbs/bootstrap/issues/15074.
+
+.form-control-sm {
+ padding: $input-padding-y-sm $input-padding-x-sm;
+ font-size: $font-size-sm;
+ @include border-radius($input-border-radius-sm);
+}
+
+select.form-control-sm {
+ &:not([size]):not([multiple]) {
+ height: $input-height-sm;
+ }
+}
+
+.form-control-lg {
+ padding: $input-padding-y-lg $input-padding-x-lg;
+ font-size: $font-size-lg;
+ @include border-radius($input-border-radius-lg);
+}
+
+select.form-control-lg {
+ &:not([size]):not([multiple]) {
+ height: $input-height-lg;
+ }
+}
+
+
+// Form groups
+//
+// Designed to help with the organization and spacing of vertical forms. For
+// horizontal forms, use the predefined grid classes.
+
+.form-group {
+ margin-bottom: $form-group-margin-bottom;
+}
+
+.form-text {
+ display: block;
+ margin-top: $form-text-margin-top;
+}
+
+
+// Checkboxes and radios
+//
+// Indent the labels to position radios/checkboxes as hanging controls.
+
+.form-check {
+ position: relative;
+ display: block;
+ margin-bottom: $form-check-margin-bottom;
+
+ &.disabled {
+ .form-check-label {
+ color: $text-muted;
+ cursor: $cursor-disabled;
+ }
+ }
+}
+
+.form-check-label {
+ padding-left: $form-check-input-gutter;
+ margin-bottom: 0; // Override default `<label>` bottom margin
+}
+
+.form-check-input {
+ position: absolute;
+ margin-top: $form-check-input-margin-y;
+ margin-left: -$form-check-input-gutter;
+
+ &:only-child {
+ position: static;
+ }
+}
+
+// Radios and checkboxes on same line
+.form-check-inline {
+ display: inline-block;
+
+ .form-check-label {
+ vertical-align: middle;
+ }
+
+ + .form-check-inline {
+ margin-left: $form-check-inline-margin-x;
+ }
+}
+
+
+// Form control feedback states
+//
+// Apply contextual and semantic states to individual form controls.
+
+.form-control-feedback {
+ margin-top: $form-feedback-margin-top;
+}
+
+.form-control-success,
+.form-control-warning,
+.form-control-danger {
+ padding-right: ($input-padding-x * 3);
+ background-repeat: no-repeat;
+ background-position: center right ($input-height / 4);
+ background-size: ($input-height / 2) ($input-height / 2);
+}
+
+// Form validation states
+.has-success {
+ @include form-control-validation($brand-success);
+
+ .form-control-success {
+ background-image: $form-icon-success;
+ }
+}
+
+.has-warning {
+ @include form-control-validation($brand-warning);
+
+ .form-control-warning {
+ background-image: $form-icon-warning;
+ }
+}
+
+.has-danger {
+ @include form-control-validation($brand-danger);
+
+ .form-control-danger {
+ background-image: $form-icon-danger;
+ }
+}
+
+
+// Inline forms
+//
+// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
+// forms begin stacked on extra small (mobile) devices and then go inline when
+// viewports reach <768px.
+//
+// Requires wrapping inputs and labels with `.form-group` for proper display of
+// default HTML form controls and our custom form controls (e.g., input groups).
+
+.form-inline {
+ display: flex;
+ flex-flow: row wrap;
+ align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)
+
+ // Because we use flex, the initial sizing of checkboxes is collapsed and
+ // doesn't occupy the full-width (which is what we want for xs grid tier),
+ // so we force that here.
+ .form-check {
+ width: 100%;
+ }
+
+ // Kick in the inline
+ @include media-breakpoint-up(sm) {
+ label {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 0;
+ }
+
+ // Inline-block all the things for "inline"
+ .form-group {
+ display: flex;
+ flex: 0 0 auto;
+ flex-flow: row wrap;
+ align-items: center;
+ margin-bottom: 0;
+ }
+
+ // Allow folks to *not* use `.form-group`
+ .form-control {
+ display: inline-block;
+ width: auto; // Prevent labels from stacking above inputs in `.form-group`
+ vertical-align: middle;
+ }
+
+ // Make static controls behave like regular ones
+ .form-control-static {
+ display: inline-block;
+ }
+
+ .input-group {
+ width: auto;
+ }
+
+ .form-control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ // Remove default margin on radios/checkboxes that were used for stacking, and
+ // then undo the floating of radios and checkboxes to match.
+ .form-check {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: auto;
+ margin-top: 0;
+ margin-bottom: 0;
+ }
+ .form-check-label {
+ padding-left: 0;
+ }
+ .form-check-input {
+ position: relative;
+ margin-top: 0;
+ margin-right: $form-check-input-margin-x;
+ margin-left: 0;
+ }
+
+ // Custom form controls
+ .custom-control {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding-left: 0;
+ }
+ .custom-control-indicator {
+ position: static;
+ display: inline-block;
+ margin-right: $form-check-input-margin-x; // Flexbox alignment means we lose our HTML space here, so we compensate.
+ vertical-align: text-bottom;
+ }
+
+ // Re-override the feedback icon.
+ .has-feedback .form-control-feedback {
+ top: 0;
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_grid.scss b/templates/assets/bootstrap/scss/_grid.scss
new file mode 100644
index 0000000..8c7a9ee
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_grid.scss
@@ -0,0 +1,52 @@
+// Container widths
+//
+// Set the container width, and override it for fixed navbars in media queries.
+
+@if $enable-grid-classes {
+ .container {
+ @include make-container();
+ @include make-container-max-widths();
+ }
+}
+
+// Fluid container
+//
+// Utilizes the mixin meant for fixed width containers, but without any defined
+// width for fluid, full width layouts.
+
+@if $enable-grid-classes {
+ .container-fluid {
+ @include make-container();
+ }
+}
+
+// Row
+//
+// Rows contain and clear the floats of your columns.
+
+@if $enable-grid-classes {
+ .row {
+ @include make-row();
+ }
+
+ // Remove the negative margin from default .row, then the horizontal padding
+ // from all immediate children columns (to prevent runaway style inheritance).
+ .no-gutters {
+ margin-right: 0;
+ margin-left: 0;
+
+ > .col,
+ > [class*="col-"] {
+ padding-right: 0;
+ padding-left: 0;
+ }
+ }
+}
+
+// Columns
+//
+// Common styles for small and large grid columns
+
+@if $enable-grid-classes {
+ @include make-grid-columns();
+}
diff --git a/templates/assets/bootstrap/scss/_images.scss b/templates/assets/bootstrap/scss/_images.scss
new file mode 100644
index 0000000..50c5610
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_images.scss
@@ -0,0 +1,43 @@
+// Responsive images (ensure images don't scale beyond their parents)
+//
+// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
+// We previously tried the "images are responsive by default" approach in Bootstrap v2,
+// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
+// which weren't expecting the images within themselves to be involuntarily resized.
+// See also https://github.com/twbs/bootstrap/issues/18178
+.img-fluid {
+ @include img-fluid;
+}
+
+
+// Image thumbnails
+.img-thumbnail {
+ padding: $thumbnail-padding;
+ background-color: $thumbnail-bg;
+ border: $thumbnail-border-width solid $thumbnail-border-color;
+ @include border-radius($thumbnail-border-radius);
+ @include transition($thumbnail-transition);
+ @include box-shadow($thumbnail-box-shadow);
+
+ // Keep them at most 100% wide
+ @include img-fluid;
+}
+
+//
+// Figures
+//
+
+.figure {
+ // Ensures the caption's text aligns with the image.
+ display: inline-block;
+}
+
+.figure-img {
+ margin-bottom: ($spacer / 2);
+ line-height: 1;
+}
+
+.figure-caption {
+ font-size: $figure-caption-font-size;
+ color: $figure-caption-color;
+}
diff --git a/templates/assets/bootstrap/scss/_input-group.scss b/templates/assets/bootstrap/scss/_input-group.scss
new file mode 100644
index 0000000..49cdf28
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_input-group.scss
@@ -0,0 +1,175 @@
+//
+// Base styles
+//
+
+.input-group {
+ position: relative;
+ display: flex;
+ width: 100%;
+
+ .form-control {
+ // Ensure that the input is always above the *appended* addon button for
+ // proper border colors.
+ position: relative;
+ z-index: 2;
+ flex: 1 1 auto;
+ // Add width 1% and flex-basis auto to ensure that button will not wrap out
+ // the column. Applies to IE Edge+ and Firefox. Chrome does not require this.
+ width: 1%;
+ margin-bottom: 0;
+
+ // Bring the "active" form control to the front
+ @include hover-focus-active {
+ z-index: 3;
+ }
+ }
+}
+
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+ // Vertically centers the content of the addons within the input group
+ display: flex;
+ align-items: center;
+
+ &:not(:first-child):not(:last-child) {
+ @include border-radius(0);
+ }
+}
+
+.input-group-addon,
+.input-group-btn {
+ white-space: nowrap;
+ vertical-align: middle; // Match the inputs
+}
+
+
+// Sizing options
+//
+// Remix the default form control sizing classes into new ones for easier
+// manipulation.
+
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+ @extend .form-control-lg;
+}
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+ @extend .form-control-sm;
+}
+
+
+//
+// Text input groups
+//
+
+.input-group-addon {
+ padding: $input-padding-y $input-padding-x;
+ margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom
+ font-size: $font-size-base; // Match inputs
+ font-weight: $font-weight-normal;
+ line-height: $input-line-height;
+ color: $input-color;
+ text-align: center;
+ background-color: $input-group-addon-bg;
+ border: $input-btn-border-width solid $input-group-addon-border-color;
+ @include border-radius($input-border-radius);
+
+ // Sizing
+ &.form-control-sm {
+ padding: $input-padding-y-sm $input-padding-x-sm;
+ font-size: $font-size-sm;
+ @include border-radius($input-border-radius-sm);
+ }
+ &.form-control-lg {
+ padding: $input-padding-y-lg $input-padding-x-lg;
+ font-size: $font-size-lg;
+ @include border-radius($input-border-radius-lg);
+ }
+
+ // scss-lint:disable QualifyingElement
+ // Nuke default margins from checkboxes and radios to vertically center within.
+ input[type="radio"],
+ input[type="checkbox"] {
+ margin-top: 0;
+ }
+ // scss-lint:enable QualifyingElement
+}
+
+
+//
+// Reset rounded corners
+//
+
+.input-group .form-control:not(:last-child),
+.input-group-addon:not(:last-child),
+.input-group-btn:not(:last-child) > .btn,
+.input-group-btn:not(:last-child) > .btn-group > .btn,
+.input-group-btn:not(:last-child) > .dropdown-toggle,
+.input-group-btn:not(:first-child) > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:not(:first-child) > .btn-group:not(:last-child) > .btn {
+ @include border-right-radius(0);
+}
+.input-group-addon:not(:last-child) {
+ border-right: 0;
+}
+.input-group .form-control:not(:first-child),
+.input-group-addon:not(:first-child),
+.input-group-btn:not(:first-child) > .btn,
+.input-group-btn:not(:first-child) > .btn-group > .btn,
+.input-group-btn:not(:first-child) > .dropdown-toggle,
+.input-group-btn:not(:last-child) > .btn:not(:first-child),
+.input-group-btn:not(:last-child) > .btn-group:not(:first-child) > .btn {
+ @include border-left-radius(0);
+}
+.form-control + .input-group-addon:not(:first-child) {
+ border-left: 0;
+}
+
+//
+// Button input groups
+//
+
+.input-group-btn {
+ position: relative;
+ // Jankily prevent input button groups from wrapping with `white-space` and
+ // `font-size` in combination with `inline-block` on buttons.
+ font-size: 0;
+ white-space: nowrap;
+
+ // Negative margin for spacing, position for bringing hovered/focused/actived
+ // element above the siblings.
+ > .btn {
+ position: relative;
+
+ + .btn {
+ margin-left: (-$input-btn-border-width);
+ }
+
+ // Bring the "active" button to the front
+ @include hover-focus-active {
+ z-index: 3;
+ }
+ }
+
+ // Negative margin to only have a single, shared border between the two
+ &:not(:last-child) {
+ > .btn,
+ > .btn-group {
+ margin-right: (-$input-btn-border-width);
+ }
+ }
+ &:not(:first-child) {
+ > .btn,
+ > .btn-group {
+ z-index: 2;
+ margin-left: (-$input-btn-border-width);
+ // Because specificity
+ @include hover-focus-active {
+ z-index: 3;
+ }
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_jumbotron.scss b/templates/assets/bootstrap/scss/_jumbotron.scss
new file mode 100644
index 0000000..b12d465
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_jumbotron.scss
@@ -0,0 +1,20 @@
+.jumbotron {
+ padding: $jumbotron-padding ($jumbotron-padding / 2);
+ margin-bottom: $jumbotron-padding;
+ background-color: $jumbotron-bg;
+ @include border-radius($border-radius-lg);
+
+ @include media-breakpoint-up(sm) {
+ padding: ($jumbotron-padding * 2) $jumbotron-padding;
+ }
+}
+
+.jumbotron-hr {
+ border-top-color: darken($jumbotron-bg, 10%);
+}
+
+.jumbotron-fluid {
+ padding-right: 0;
+ padding-left: 0;
+ @include border-radius(0);
+}
diff --git a/templates/assets/bootstrap/scss/_list-group.scss b/templates/assets/bootstrap/scss/_list-group.scss
new file mode 100644
index 0000000..c4b5e2f
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_list-group.scss
@@ -0,0 +1,116 @@
+// Base class
+//
+// Easily usable on <ul>, <ol>, or <div>.
+
+.list-group {
+ display: flex;
+ flex-direction: column;
+
+ // No need to set list-style: none; since .list-group-item is block level
+ padding-left: 0; // reset padding because ul and ol
+ margin-bottom: 0;
+}
+
+
+// Interactive list items
+//
+// Use anchor or button elements instead of `li`s or `div`s to create interactive
+// list items. Includes an extra `.active` modifier class for selected items.
+
+.list-group-item-action {
+ width: 100%; // For `<button>`s (anchors become 100% by default though)
+ color: $list-group-link-color;
+ text-align: inherit; // For `<button>`s (anchors inherit)
+
+ // Hover state
+ @include hover-focus {
+ color: $list-group-link-hover-color;
+ text-decoration: none;
+ background-color: $list-group-hover-bg;
+ }
+
+ &:active {
+ color: $list-group-link-active-color;
+ background-color: $list-group-link-active-bg;
+ }
+}
+
+
+// Individual list items
+//
+// Use on `li`s or `div`s within the `.list-group` parent.
+
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: $list-group-item-padding-y $list-group-item-padding-x;
+ // Place the border on the list items and negative margin up for better styling
+ margin-bottom: -$list-group-border-width;
+ background-color: $list-group-bg;
+ border: $list-group-border-width solid $list-group-border-color;
+
+ &:first-child {
+ @include border-top-radius($list-group-border-radius);
+ }
+
+ &:last-child {
+ margin-bottom: 0;
+ @include border-bottom-radius($list-group-border-radius);
+ }
+
+ @include hover-focus {
+ text-decoration: none;
+ }
+
+ &.disabled,
+ &:disabled {
+ color: $list-group-disabled-color;
+ cursor: $cursor-disabled;
+ background-color: $list-group-disabled-bg;
+ }
+
+ // Include both here for `<a>`s and `<button>`s
+ &.active {
+ z-index: 2; // Place active items above their siblings for proper border styling
+ color: $list-group-active-color;
+ background-color: $list-group-active-bg;
+ border-color: $list-group-active-border;
+ }
+}
+
+
+// Flush list items
+//
+// Remove borders and border-radius to keep list group items edge-to-edge. Most
+// useful within other components (e.g., cards).
+
+.list-group-flush {
+ .list-group-item {
+ border-right: 0;
+ border-left: 0;
+ border-radius: 0;
+ }
+
+ &:first-child {
+ .list-group-item:first-child {
+ border-top: 0;
+ }
+ }
+
+ &:last-child {
+ .list-group-item:last-child {
+ border-bottom: 0;
+ }
+ }
+}
+
+
+// Contextual variants
+//
+// Add modifier classes to change text and background color on individual items.
+// Organizationally, this must come after the `:hover` states.
+
+@include list-group-item-variant(success, $state-success-bg, $state-success-text);
+@include list-group-item-variant(info, $state-info-bg, $state-info-text);
+@include list-group-item-variant(warning, $state-warning-bg, $state-warning-text);
+@include list-group-item-variant(danger, $state-danger-bg, $state-danger-text);
diff --git a/templates/assets/bootstrap/scss/_media.scss b/templates/assets/bootstrap/scss/_media.scss
new file mode 100644
index 0000000..b573052
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_media.scss
@@ -0,0 +1,8 @@
+.media {
+ display: flex;
+ align-items: flex-start;
+}
+
+.media-body {
+ flex: 1;
+}
diff --git a/templates/assets/bootstrap/scss/_mixins.scss b/templates/assets/bootstrap/scss/_mixins.scss
new file mode 100644
index 0000000..13aad24
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_mixins.scss
@@ -0,0 +1,43 @@
+// Toggles
+//
+// Used in conjunction with global variables to enable certain theme features.
+
+// Utilities
+@import "mixins/breakpoints";
+@import "mixins/hover";
+@import "mixins/image";
+@import "mixins/badge";
+@import "mixins/resize";
+@import "mixins/screen-reader";
+@import "mixins/size";
+@import "mixins/reset-text";
+@import "mixins/text-emphasis";
+@import "mixins/text-hide";
+@import "mixins/text-truncate";
+@import "mixins/transforms";
+@import "mixins/visibility";
+
+// // Components
+@import "mixins/alert";
+@import "mixins/buttons";
+@import "mixins/cards";
+@import "mixins/pagination";
+@import "mixins/lists";
+@import "mixins/list-group";
+@import "mixins/nav-divider";
+@import "mixins/forms";
+@import "mixins/table-row";
+
+// // Skins
+@import "mixins/background-variant";
+@import "mixins/border-radius";
+@import "mixins/box-shadow";
+@import "mixins/gradients";
+@import "mixins/transition";
+
+// // Layout
+@import "mixins/clearfix";
+// @import "mixins/navbar-align";
+@import "mixins/grid-framework";
+@import "mixins/grid";
+@import "mixins/float";
diff --git a/templates/assets/bootstrap/scss/_modal.scss b/templates/assets/bootstrap/scss/_modal.scss
new file mode 100644
index 0000000..9d2a867
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_modal.scss
@@ -0,0 +1,142 @@
+// .modal-open - body class for killing the scroll
+// .modal - container to scroll within
+// .modal-dialog - positioning shell for the actual modal
+// .modal-content - actual modal w/ bg and corners and stuff
+
+
+// Kill the scroll on the body
+.modal-open {
+ overflow: hidden;
+}
+
+// Container that the modal scrolls within
+.modal {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $zindex-modal;
+ display: none;
+ overflow: hidden;
+ // Prevent Chrome on Windows from adding a focus outline. For details, see
+ // https://github.com/twbs/bootstrap/pull/10951.
+ outline: 0;
+ // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
+ // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
+ // See also https://github.com/twbs/bootstrap/issues/17695
+
+ // When fading in the modal, animate it to slide down
+ &.fade .modal-dialog {
+ @include transition($modal-transition);
+ transform: translate(0, -25%);
+ }
+ &.show .modal-dialog { transform: translate(0, 0); }
+}
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+// Shell div to position the modal with bottom padding
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: $modal-dialog-margin;
+}
+
+// Actual modal
+.modal-content {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ background-color: $modal-content-bg;
+ background-clip: padding-box;
+ border: $modal-content-border-width solid $modal-content-border-color;
+ @include border-radius($border-radius-lg);
+ @include box-shadow($modal-content-xs-box-shadow);
+ // Remove focus outline from opened modal
+ outline: 0;
+}
+
+// Modal background
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $zindex-modal-backdrop;
+ background-color: $modal-backdrop-bg;
+
+ // Fade for backdrop
+ &.fade { opacity: 0; }
+ &.show { opacity: $modal-backdrop-opacity; }
+}
+
+// Modal header
+// Top section of the modal w/ title and dismiss
+.modal-header {
+ display: flex;
+ align-items: center; // vertically center it
+ justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends
+ padding: $modal-header-padding;
+ border-bottom: $modal-header-border-width solid $modal-header-border-color;
+}
+
+// Title text within header
+.modal-title {
+ margin-bottom: 0;
+ line-height: $modal-title-line-height;
+}
+
+// Modal body
+// Where all modal content resides (sibling of .modal-header and .modal-footer)
+.modal-body {
+ position: relative;
+ // Enable `flex-grow: 1` so that the body take up as much space as possible
+ // when should there be a fixed height on `.modal-dialog`.
+ flex: 1 1 auto;
+ padding: $modal-inner-padding;
+}
+
+// Footer (for actions)
+.modal-footer {
+ display: flex;
+ align-items: center; // vertically center
+ justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
+ padding: $modal-inner-padding;
+ border-top: $modal-footer-border-width solid $modal-footer-border-color;
+
+ // Easily place margin between footer elements
+ > :not(:first-child) { margin-left: .25rem; }
+ > :not(:last-child) { margin-right: .25rem; }
+}
+
+// Measure scrollbar width for padding body during modal show/hide
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+
+// Scale up the modal
+@include media-breakpoint-up(sm) {
+ // Automatically set modal's width for larger viewports
+ .modal-dialog {
+ max-width: $modal-md;
+ margin: $modal-dialog-sm-up-margin-y auto;
+ }
+
+ .modal-content {
+ @include box-shadow($modal-content-sm-up-box-shadow);
+ }
+
+ .modal-sm { max-width: $modal-sm; }
+}
+
+@include media-breakpoint-up(lg) {
+ .modal-lg { max-width: $modal-lg; }
+}
diff --git a/templates/assets/bootstrap/scss/_nav.scss b/templates/assets/bootstrap/scss/_nav.scss
new file mode 100644
index 0000000..731f1b7
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_nav.scss
@@ -0,0 +1,120 @@
+// Base class
+//
+// Kickstart any navigation component with a set of style resets. Works with
+// `<nav>`s or `<ul>`s.
+
+.nav {
+ display: flex;
+ flex-wrap: wrap;
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+
+.nav-link {
+ display: block;
+ padding: $nav-link-padding;
+
+ @include hover-focus {
+ text-decoration: none;
+ }
+
+ // Disabled state lightens text and removes hover/tab effects
+ &.disabled {
+ color: $nav-disabled-link-color;
+ cursor: $cursor-disabled;
+ }
+}
+
+
+//
+// Tabs
+//
+
+.nav-tabs {
+ border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
+
+ .nav-item {
+ margin-bottom: -$nav-tabs-border-width;
+ }
+
+ .nav-link {
+ border: $nav-tabs-border-width solid transparent;
+ @include border-top-radius($nav-tabs-border-radius);
+
+ @include hover-focus {
+ border-color: $nav-tabs-link-hover-border-color $nav-tabs-link-hover-border-color $nav-tabs-border-color;
+ }
+
+ &.disabled {
+ color: $nav-disabled-link-color;
+ background-color: transparent;
+ border-color: transparent;
+ }
+ }
+
+ .nav-link.active,
+ .nav-item.show .nav-link {
+ color: $nav-tabs-active-link-color;
+ background-color: $nav-tabs-active-link-bg;
+ border-color: $nav-tabs-active-link-border-color $nav-tabs-active-link-border-color $nav-tabs-active-link-bg;
+ }
+
+ .dropdown-menu {
+ // Make dropdown border overlap tab border
+ margin-top: -$nav-tabs-border-width;
+ // Remove the top rounded corners here since there is a hard edge above the menu
+ @include border-top-radius(0);
+ }
+}
+
+
+//
+// Pills
+//
+
+.nav-pills {
+ .nav-link {
+ @include border-radius($nav-pills-border-radius);
+ }
+
+ .nav-link.active,
+ .nav-item.show .nav-link {
+ color: $nav-pills-active-link-color;
+ background-color: $nav-pills-active-link-bg;
+ }
+}
+
+
+//
+// Justified variants
+//
+
+.nav-fill {
+ .nav-item {
+ flex: 1 1 auto;
+ text-align: center;
+ }
+}
+
+.nav-justified {
+ .nav-item {
+ flex-basis: 0;
+ flex-grow: 1;
+ text-align: center;
+ }
+}
+
+
+// Tabbable tabs
+//
+// Hide tabbable panes to start, show them when `.active`
+
+.tab-content {
+ > .tab-pane {
+ display: none;
+ }
+ > .active {
+ display: block;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_navbar.scss b/templates/assets/bootstrap/scss/_navbar.scss
new file mode 100644
index 0000000..6c31017
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_navbar.scss
@@ -0,0 +1,276 @@
+// Contents
+//
+// Navbar
+// Navbar brand
+// Navbar nav
+// Navbar text
+// Navbar divider
+// Responsive navbar
+// Navbar position
+// Navbar themes
+
+
+// Navbar
+//
+// Provide a static navbar from which we expand to create full-width, fixed, and
+// other navbar variations.
+
+.navbar {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ padding: $navbar-padding-y $navbar-padding-x;
+
+ @include media-breakpoint-down(nth(map-keys($grid-breakpoints), 1)) {
+ > .container {
+ margin-right: 0;
+ margin-left: 0;
+ }
+ }
+}
+
+
+// Navbar brand
+//
+// Used for brand, project, or site names.
+
+.navbar-brand {
+ display: inline-block;
+ align-self: flex-start;
+ padding-top: .25rem;
+ padding-bottom: .25rem;
+ margin-right: $navbar-padding-x;
+ font-size: $font-size-lg;
+ line-height: inherit;
+ white-space: nowrap;
+
+ @include hover-focus {
+ text-decoration: none;
+ }
+}
+
+
+// Navbar nav
+//
+// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).
+
+.navbar-nav {
+ display: flex;
+ flex-direction: column; // cannot use `inherit` to get the `.navbar`s value
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+
+ .nav-link {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+
+
+// Navbar text
+//
+//
+
+.navbar-text {
+ display: inline-block;
+ padding-top: .425rem;
+ padding-bottom: .425rem;
+}
+
+
+// Responsive navbar
+//
+// Custom styles for responsive collapsing and toggling of navbar contents.
+// Powered by the collapse Bootstrap JavaScript plugin.
+
+// Button for toggling the navbar when in its collapsed state
+.navbar-toggler {
+ align-self: flex-start; // Prevent toggler from growing to full width when it's the only visible navbar child
+ padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;
+ font-size: $navbar-toggler-font-size;
+ line-height: 1;
+ background: transparent; // remove default button style
+ border: $border-width solid transparent; // remove default button style
+ @include border-radius($navbar-toggler-border-radius);
+
+ @include hover-focus {
+ text-decoration: none;
+ }
+}
+
+// Keep as a separate element so folks can easily override it with another icon
+// or image file as needed.
+.navbar-toggler-icon {
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ vertical-align: middle;
+ content: "";
+ background: no-repeat center center;
+ background-size: 100% 100%;
+}
+
+// Use `position` on the toggler to prevent it from being auto placed as a flex
+// item and allow easy placement.
+.navbar-toggler-left {
+ position: absolute;
+ left: $navbar-padding-x;
+}
+.navbar-toggler-right {
+ position: absolute;
+ right: $navbar-padding-x;
+}
+
+// Generate series of `.navbar-toggleable-*` responsive classes for configuring
+// where your navbar collapses.
+.navbar-toggleable {
+ @each $breakpoint in map-keys($grid-breakpoints) {
+ $next: breakpoint-next($breakpoint, $grid-breakpoints);
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ &#{$infix} {
+ @include media-breakpoint-down($breakpoint) {
+ .navbar-nav {
+ .dropdown-menu {
+ position: static;
+ float: none;
+ }
+ }
+
+ > .container {
+ padding-right: 0;
+ padding-left: 0;
+ }
+ }
+
+ @include media-breakpoint-up($next) {
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: center;
+
+ .navbar-nav {
+ flex-direction: row;
+
+ .nav-link {
+ padding-right: .5rem;
+ padding-left: .5rem;
+ }
+ }
+
+ // For nesting containers, have to redeclare for alignment purposes
+ > .container {
+ display: flex;
+ flex-wrap: nowrap;
+ align-items: center;
+ }
+
+ // scss-lint:disable ImportantRule
+ .navbar-collapse {
+ display: flex !important;
+ width: 100%;
+ }
+ // scss-lint:enable ImportantRule
+
+ .navbar-toggler {
+ display: none;
+ }
+ }
+ }
+ }
+}
+
+
+// Navbar themes
+//
+// Styles for switching between navbars with light or dark background.
+
+// Dark links against a light background
+.navbar-light {
+ .navbar-brand,
+ .navbar-toggler {
+ color: $navbar-light-active-color;
+
+ @include hover-focus {
+ color: $navbar-light-active-color;
+ }
+ }
+
+ .navbar-nav {
+ .nav-link {
+ color: $navbar-light-color;
+
+ @include hover-focus {
+ color: $navbar-light-hover-color;
+ }
+
+ &.disabled {
+ color: $navbar-light-disabled-color;
+ }
+ }
+
+ .open > .nav-link,
+ .active > .nav-link,
+ .nav-link.open,
+ .nav-link.active {
+ color: $navbar-light-active-color;
+ }
+ }
+
+ .navbar-toggler {
+ border-color: $navbar-light-toggler-border;
+ }
+
+ .navbar-toggler-icon {
+ background-image: $navbar-light-toggler-bg;
+ }
+
+ .navbar-text {
+ color: $navbar-light-color;
+ }
+}
+
+// White links against a dark background
+.navbar-inverse {
+ .navbar-brand,
+ .navbar-toggler {
+ color: $navbar-inverse-active-color;
+
+ @include hover-focus {
+ color: $navbar-inverse-active-color;
+ }
+ }
+
+ .navbar-nav {
+ .nav-link {
+ color: $navbar-inverse-color;
+
+ @include hover-focus {
+ color: $navbar-inverse-hover-color;
+ }
+
+ &.disabled {
+ color: $navbar-inverse-disabled-color;
+ }
+ }
+
+ .open > .nav-link,
+ .active > .nav-link,
+ .nav-link.open,
+ .nav-link.active {
+ color: $navbar-inverse-active-color;
+ }
+ }
+
+ .navbar-toggler {
+ border-color: $navbar-inverse-toggler-border;
+ }
+
+ .navbar-toggler-icon {
+ background-image: $navbar-inverse-toggler-bg;
+ }
+
+ .navbar-text {
+ color: $navbar-inverse-color;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_pagination.scss b/templates/assets/bootstrap/scss/_pagination.scss
new file mode 100644
index 0000000..24aa028
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_pagination.scss
@@ -0,0 +1,67 @@
+.pagination {
+ display: flex;
+ // 1-2: Disable browser default list styles
+ padding-left: 0; // 1
+ list-style: none; // 2
+ @include border-radius();
+}
+
+.page-item {
+ &:first-child {
+ .page-link {
+ margin-left: 0;
+ @include border-left-radius($border-radius);
+ }
+ }
+ &:last-child {
+ .page-link {
+ @include border-right-radius($border-radius);
+ }
+ }
+
+ &.active .page-link {
+ z-index: 2;
+ color: $pagination-active-color;
+ background-color: $pagination-active-bg;
+ border-color: $pagination-active-border;
+ }
+
+ &.disabled .page-link {
+ color: $pagination-disabled-color;
+ pointer-events: none;
+ cursor: $cursor-disabled; // While `pointer-events: none` removes the cursor in modern browsers, we provide a disabled cursor as a fallback.
+ background-color: $pagination-disabled-bg;
+ border-color: $pagination-disabled-border;
+ }
+}
+
+.page-link {
+ position: relative;
+ display: block;
+ padding: $pagination-padding-y $pagination-padding-x;
+ margin-left: -1px;
+ line-height: $pagination-line-height;
+ color: $pagination-color;
+ background-color: $pagination-bg;
+ border: $pagination-border-width solid $pagination-border-color;
+
+ @include hover-focus {
+ color: $pagination-hover-color;
+ text-decoration: none;
+ background-color: $pagination-hover-bg;
+ border-color: $pagination-hover-border;
+ }
+}
+
+
+//
+// Sizing
+//
+
+.pagination-lg {
+ @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);
+}
+
+.pagination-sm {
+ @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);
+}
diff --git a/templates/assets/bootstrap/scss/_popover.scss b/templates/assets/bootstrap/scss/_popover.scss
new file mode 100644
index 0000000..1b63634
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_popover.scss
@@ -0,0 +1,171 @@
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: $zindex-popover;
+ display: block;
+ max-width: $popover-max-width;
+ padding: $popover-inner-padding;
+ // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
+ // So reset our font and text properties to avoid inheriting weird values.
+ @include reset-text();
+ font-size: $font-size-sm;
+ // Allow breaking very long words so they don't overflow the popover's bounds
+ word-wrap: break-word;
+ background-color: $popover-bg;
+ background-clip: padding-box;
+ border: $popover-border-width solid $popover-border-color;
+ @include border-radius($border-radius-lg);
+ @include box-shadow($popover-box-shadow);
+
+
+ // Popover directions
+
+ &.popover-top,
+ &.bs-tether-element-attached-bottom {
+ margin-top: -$popover-arrow-width;
+
+ &::before,
+ &::after {
+ left: 50%;
+ border-bottom-width: 0;
+ }
+
+ &::before {
+ bottom: -$popover-arrow-outer-width;
+ margin-left: -$popover-arrow-outer-width;
+ border-top-color: $popover-arrow-outer-color;
+ }
+
+ &::after {
+ bottom: -($popover-arrow-outer-width - 1);
+ margin-left: -$popover-arrow-width;
+ border-top-color: $popover-arrow-color;
+ }
+ }
+
+ &.popover-right,
+ &.bs-tether-element-attached-left {
+ margin-left: $popover-arrow-width;
+
+ &::before,
+ &::after {
+ top: 50%;
+ border-left-width: 0;
+ }
+
+ &::before {
+ left: -$popover-arrow-outer-width;
+ margin-top: -$popover-arrow-outer-width;
+ border-right-color: $popover-arrow-outer-color;
+ }
+
+ &::after {
+ left: -($popover-arrow-outer-width - 1);
+ margin-top: -($popover-arrow-outer-width - 1);
+ border-right-color: $popover-arrow-color;
+ }
+ }
+
+ &.popover-bottom,
+ &.bs-tether-element-attached-top {
+ margin-top: $popover-arrow-width;
+
+ &::before,
+ &::after {
+ left: 50%;
+ border-top-width: 0;
+ }
+
+ &::before {
+ top: -$popover-arrow-outer-width;
+ margin-left: -$popover-arrow-outer-width;
+ border-bottom-color: $popover-arrow-outer-color;
+ }
+
+ &::after {
+ top: -($popover-arrow-outer-width - 1);
+ margin-left: -$popover-arrow-width;
+ border-bottom-color: $popover-title-bg;
+ }
+
+ // This will remove the popover-title's border just below the arrow
+ .popover-title::before {
+ position: absolute;
+ top: 0;
+ left: 50%;
+ display: block;
+ width: 20px;
+ margin-left: -10px;
+ content: "";
+ border-bottom: 1px solid $popover-title-bg;
+ }
+ }
+
+ &.popover-left,
+ &.bs-tether-element-attached-right {
+ margin-left: -$popover-arrow-width;
+
+ &::before,
+ &::after {
+ top: 50%;
+ border-right-width: 0;
+ }
+
+ &::before {
+ right: -$popover-arrow-outer-width;
+ margin-top: -$popover-arrow-outer-width;
+ border-left-color: $popover-arrow-outer-color;
+ }
+
+ &::after {
+ right: -($popover-arrow-outer-width - 1);
+ margin-top: -($popover-arrow-outer-width - 1);
+ border-left-color: $popover-arrow-color;
+ }
+ }
+}
+
+
+// Offset the popover to account for the popover arrow
+.popover-title {
+ padding: $popover-title-padding-y $popover-title-padding-x;
+ margin-bottom: 0; // Reset the default from Reboot
+ font-size: $font-size-base;
+ background-color: $popover-title-bg;
+ border-bottom: $popover-border-width solid darken($popover-title-bg, 5%);
+ $offset-border-width: calc(#{$border-radius-lg} - #{$popover-border-width});
+ @include border-top-radius($offset-border-width);
+
+ &:empty {
+ display: none;
+ }
+}
+
+.popover-content {
+ padding: $popover-content-padding-y $popover-content-padding-x;
+}
+
+
+// Arrows
+//
+// .popover-arrow is outer, .popover-arrow::after is inner
+
+.popover::before,
+.popover::after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.popover::before {
+ content: "";
+ border-width: $popover-arrow-outer-width;
+}
+.popover::after {
+ content: "";
+ border-width: $popover-arrow-width;
+}
diff --git a/templates/assets/bootstrap/scss/_print.scss b/templates/assets/bootstrap/scss/_print.scss
new file mode 100644
index 0000000..e20219a
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_print.scss
@@ -0,0 +1,119 @@
+// scss-lint:disable QualifyingElement
+
+// Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css
+
+// ==========================================================================
+// Print styles.
+// Inlined to avoid the additional HTTP request:
+// http://www.phpied.com/delay-loading-your-print-css/
+// ==========================================================================
+
+@if $enable-print-styles {
+ @media print {
+ *,
+ *::before,
+ *::after,
+ p::first-letter,
+ div::first-letter,
+ blockquote::first-letter,
+ li::first-letter,
+ p::first-line,
+ div::first-line,
+ blockquote::first-line,
+ li::first-line {
+ // Bootstrap specific; comment out `color` and `background`
+ //color: #000 !important; // Black prints faster:
+ // http://www.sanbeiji.com/archives/953
+ text-shadow: none !important;
+ //background: transparent !important;
+ box-shadow: none !important;
+ }
+
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+
+ // Bootstrap specific; comment the following selector out
+ //a[href]::after {
+ // content: " (" attr(href) ")";
+ //}
+
+ abbr[title]::after {
+ content: " (" attr(title) ")";
+ }
+
+ // Bootstrap specific; comment the following selector out
+ //
+ // Don't show links that are fragment identifiers,
+ // or use the `javascript:` pseudo protocol
+ //
+
+ //a[href^="#"]::after,
+ //a[href^="javascript:"]::after {
+ // content: "";
+ //}
+
+ pre {
+ white-space: pre-wrap !important;
+ }
+ pre,
+ blockquote {
+ border: $border-width solid #999; // Bootstrap custom code; using `$border-width` instead of 1px
+ page-break-inside: avoid;
+ }
+
+ //
+ // Printing Tables:
+ // http://css-discuss.incutio.com/wiki/Printing_Tables
+ //
+
+ thead {
+ display: table-header-group;
+ }
+
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+
+ // Bootstrap specific changes start
+
+ // Bootstrap components
+ .navbar {
+ display: none;
+ }
+ .badge {
+ border: $border-width solid #000;
+ }
+
+ .table {
+ border-collapse: collapse !important;
+
+ td,
+ th {
+ background-color: #fff !important;
+ }
+ }
+ .table-bordered {
+ th,
+ td {
+ border: 1px solid #ddd !important;
+ }
+ }
+
+ // Bootstrap specific changes end
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_progress.scss b/templates/assets/bootstrap/scss/_progress.scss
new file mode 100644
index 0000000..ccca51e
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_progress.scss
@@ -0,0 +1,30 @@
+@keyframes progress-bar-stripes {
+ from { background-position: $progress-height 0; }
+ to { background-position: 0 0; }
+}
+
+.progress {
+ display: flex;
+ overflow: hidden; // force rounded corners by cropping it
+ font-size: $progress-font-size;
+ line-height: $progress-height;
+ text-align: center;
+ background-color: $progress-bg;
+ @include border-radius($progress-border-radius);
+}
+
+.progress-bar {
+ height: $progress-height;
+ line-height: $progress-height;
+ color: $progress-bar-color;
+ background-color: $progress-bar-bg;
+}
+
+.progress-bar-striped {
+ @include gradient-striped();
+ background-size: $progress-height $progress-height;
+}
+
+.progress-bar-animated {
+ animation: progress-bar-stripes $progress-bar-animation-timing;
+}
diff --git a/templates/assets/bootstrap/scss/_reboot.scss b/templates/assets/bootstrap/scss/_reboot.scss
new file mode 100644
index 0000000..c52e6f8
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_reboot.scss
@@ -0,0 +1,484 @@
+// scss-lint:disable QualifyingElement, DuplicateProperty, VendorPrefix
+
+// Reboot
+//
+// Normalization of HTML elements, manually forked from Normalize.css to remove
+// styles targeting irrelevant browsers while applying new styles.
+//
+// Normalize is licensed MIT. https://github.com/necolas/normalize.css
+
+
+// Document
+//
+// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
+// 2. Change the default font family in all browsers.
+// 3. Correct the line height in all browsers.
+// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.
+// 5. Setting @viewport causes scrollbars to overlap content in IE11 and Edge, so
+// we force a non-overlapping, non-auto-hiding scrollbar to counteract.
+// 6. Change the default tap highlight to be completely transparent in iOS.
+
+html {
+ box-sizing: border-box; // 1
+ font-family: sans-serif; // 2
+ line-height: 1.15; // 3
+ -webkit-text-size-adjust: 100%; // 4
+ -ms-text-size-adjust: 100%; // 4
+ -ms-overflow-style: scrollbar; // 5
+ -webkit-tap-highlight-color: rgba(0,0,0,0); // 6
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: inherit; // 1
+}
+
+// IE10+ doesn't honor `<meta name="viewport">` in some cases.
+@at-root {
+ @-ms-viewport { width: device-width; }
+}
+
+
+// Body
+//
+// 1. Remove the margin in all browsers.
+// 2. As a best practice, apply a default `background-color`.
+
+body {
+ margin: 0; // 1
+ font-family: $font-family-base;
+ font-size: $font-size-base;
+ font-weight: $font-weight-base;
+ line-height: $line-height-base;
+ color: $body-color;
+ background-color: $body-bg; // 2
+}
+
+// Suppress the focus outline on elements that cannot be accessed via keyboard.
+// This prevents an unwanted focus outline from appearing around elements that
+// might still respond to pointer events.
+//
+// Credit: https://github.com/suitcss/base
+[tabindex="-1"]:focus {
+ outline: none !important;
+}
+
+
+// Content grouping
+//
+// 1. Add the correct box sizing in Firefox.
+// 2. Show the overflow in Edge and IE.
+
+hr {
+ box-sizing: content-box; // 1
+ height: 0; // 1
+ overflow: visible; // 2
+}
+
+
+//
+// Typography
+//
+
+// Remove top margins from headings
+//
+// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top
+// margin for easier control within type scales as it avoids margin collapsing.
+h1, h2, h3, h4, h5, h6 {
+ margin-top: 0;
+ margin-bottom: .5rem;
+}
+
+// Reset margins on paragraphs
+//
+// Similarly, the top margin on `<p>`s get reset. However, we also reset the
+// bottom margin to use `rem` units instead of `em`.
+p {
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+
+// Abbreviations
+//
+// 1. Remove the bottom border in Firefox 39-.
+// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+// 3. Add explicit cursor to indicate changed behavior.
+// 4. Duplicate behavior to the data-* attribute for our tooltip plugin
+
+abbr[title],
+abbr[data-original-title] { // 4
+ text-decoration: underline; // 2
+ text-decoration: underline dotted; // 2
+ cursor: help; // 3
+ border-bottom: 0; // 1
+}
+
+address {
+ margin-bottom: 1rem;
+ font-style: normal;
+ line-height: inherit;
+}
+
+ol,
+ul,
+dl {
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+
+ol ol,
+ul ul,
+ol ul,
+ul ol {
+ margin-bottom: 0;
+}
+
+dt {
+ font-weight: $dt-font-weight;
+}
+
+dd {
+ margin-bottom: .5rem;
+ margin-left: 0; // Undo browser default
+}
+
+blockquote {
+ margin: 0 0 1rem;
+}
+
+dfn {
+ font-style: italic; // Add the correct font style in Android 4.3-
+}
+
+b,
+strong {
+ font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari
+}
+
+small {
+ font-size: 80%; // Add the correct font size in all browsers
+}
+
+//
+// Prevent `sub` and `sup` elements from affecting the line height in
+// all browsers.
+//
+
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sub { bottom: -.25em; }
+sup { top: -.5em; }
+
+
+//
+// Links
+//
+
+a {
+ color: $link-color;
+ text-decoration: $link-decoration;
+ background-color: transparent; // Remove the gray background on active links in IE 10.
+ -webkit-text-decoration-skip: objects; // Remove gaps in links underline in iOS 8+ and Safari 8+.
+
+ @include hover {
+ color: $link-hover-color;
+ text-decoration: $link-hover-decoration;
+ }
+}
+
+// And undo these styles for placeholder links/named anchors (without href)
+// which have not been made explicitly keyboard-focusable (without tabindex).
+// It would be more straightforward to just use a[href] in previous block, but that
+// causes specificity issues in many other styles that are too complex to fix.
+// See https://github.com/twbs/bootstrap/issues/19402
+
+a:not([href]):not([tabindex]) {
+ color: inherit;
+ text-decoration: none;
+
+ @include hover-focus {
+ color: inherit;
+ text-decoration: none;
+ }
+
+ &:focus {
+ outline: 0;
+ }
+}
+
+
+//
+// Code
+//
+
+pre,
+code,
+kbd,
+samp {
+ font-family: monospace, monospace; // Correct the inheritance and scaling of font size in all browsers.
+ font-size: 1em; // Correct the odd `em` font sizing in all browsers.
+}
+
+pre {
+ // Remove browser default top margin
+ margin-top: 0;
+ // Reset browser default of `1em` to use `rem`s
+ margin-bottom: 1rem;
+ // Don't allow content to break outside
+ overflow: auto;
+}
+
+
+//
+// Figures
+//
+
+figure {
+ // Apply a consistent margin strategy (matches our type styles).
+ margin: 0 0 1rem;
+}
+
+
+//
+// Images and content
+//
+
+img {
+ vertical-align: middle;
+ border-style: none; // Remove the border on images inside links in IE 10-.
+}
+
+svg:not(:root) {
+ overflow: hidden; // Hide the overflow in IE
+}
+
+
+// Avoid 300ms click delay on touch devices that support the `touch-action` CSS property.
+//
+// In particular, unlike most other browsers, IE11+Edge on Windows 10 on touch devices and IE Mobile 10-11
+// DON'T remove the click delay when `<meta name="viewport" content="width=device-width">` is present.
+// However, they DO support removing the click delay via `touch-action: manipulation`.
+// See:
+// * https://v4-alpha.getbootstrap.com/content/reboot/#click-delay-optimization-for-touch
+// * http://caniuse.com/#feat=css-touch-action
+// * https://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay
+
+a,
+area,
+button,
+[role="button"],
+input,
+label,
+select,
+summary,
+textarea {
+ touch-action: manipulation;
+}
+
+
+//
+// Tables
+//
+
+table {
+ border-collapse: collapse; // Prevent double borders
+}
+
+caption {
+ padding-top: $table-cell-padding;
+ padding-bottom: $table-cell-padding;
+ color: $text-muted;
+ text-align: left;
+ caption-side: bottom;
+}
+
+th {
+ // Matches default `<td>` alignment
+ text-align: left;
+}
+
+
+//
+// Forms
+//
+
+label {
+ // Allow labels to use `margin` for spacing.
+ display: inline-block;
+ margin-bottom: .5rem;
+}
+
+// Work around a Firefox/IE bug where the transparent `button` background
+// results in a loss of the default `button` focus styles.
+//
+// Credit: https://github.com/suitcss/base/
+button:focus {
+ outline: 1px dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+}
+
+input,
+button,
+select,
+optgroup,
+textarea {
+ margin: 0; // Remove the margin in Firefox and Safari
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+
+button,
+input {
+ overflow: visible; // Show the overflow in Edge
+}
+
+button,
+select {
+ text-transform: none; // Remove the inheritance of text transform in Firefox
+}
+
+// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
+// controls in Android 4.
+// 2. Correct the inability to style clickable types in iOS and Safari.
+button,
+html [type="button"], // 1
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button; // 2
+}
+
+// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+ padding: 0;
+ border-style: none;
+}
+
+input[type="radio"],
+input[type="checkbox"] {
+ box-sizing: border-box; // 1. Add the correct box sizing in IE 10-
+ padding: 0; // 2. Remove the padding in IE 10-
+
+ // Apply a disabled cursor for radios and checkboxes.
+ //
+ // Note: Neither radios nor checkboxes can be readonly.
+ &:disabled {
+ cursor: $cursor-disabled;
+ }
+}
+
+
+input[type="date"],
+input[type="time"],
+input[type="datetime-local"],
+input[type="month"] {
+ // Remove the default appearance of temporal inputs to avoid a Mobile Safari
+ // bug where setting a custom line-height prevents text from being vertically
+ // centered within the input.
+ // See https://bugs.webkit.org/show_bug.cgi?id=139848
+ // and https://github.com/twbs/bootstrap/issues/11266
+ -webkit-appearance: listbox;
+}
+
+textarea {
+ overflow: auto; // Remove the default vertical scrollbar in IE.
+ // Textareas should really only resize vertically so they don't break their (horizontal) containers.
+ resize: vertical;
+}
+
+fieldset {
+ // Browsers set a default `min-width: min-content;` on fieldsets,
+ // unlike e.g. `<div>`s, which have `min-width: 0;` by default.
+ // So we reset that to ensure fieldsets behave more like a standard block element.
+ // See https://github.com/twbs/bootstrap/issues/12359
+ // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
+ min-width: 0;
+ // Reset the default outline behavior of fieldsets so they don't affect page layout.
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
+// 1. Correct the text wrapping in Edge and IE.
+// 2. Correct the color inheritance from `fieldset` elements in IE.
+legend {
+ display: block;
+ width: 100%;
+ max-width: 100%; // 1
+ padding: 0;
+ margin-bottom: .5rem;
+ font-size: 1.5rem;
+ line-height: inherit;
+ color: inherit; // 2
+ white-space: normal; // 1
+}
+
+progress {
+ vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.
+}
+
+// Correct the cursor style of increment and decrement buttons in Chrome.
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+[type="search"] {
+ // This overrides the extra rounded corners on search inputs in iOS so that our
+ // `.form-control` class can properly style them. Note that this cannot simply
+ // be added to `.form-control` as it's not specific enough. For details, see
+ // https://github.com/twbs/bootstrap/issues/11586.
+ outline-offset: -2px; // 2. Correct the outline style in Safari.
+ -webkit-appearance: none;
+}
+
+//
+// Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
+//
+
+[type="search"]::-webkit-search-cancel-button,
+[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+//
+// 1. Correct the inability to style clickable types in iOS and Safari.
+// 2. Change font properties to `inherit` in Safari.
+//
+
+::-webkit-file-upload-button {
+ font: inherit; // 2
+ -webkit-appearance: button; // 1
+}
+
+//
+// Correct element displays
+//
+
+output {
+ display: inline-block;
+}
+
+summary {
+ display: list-item; // Add the correct display in all browsers
+}
+
+template {
+ display: none; // Add the correct display in IE
+}
+
+// Always hide an element with the `hidden` HTML attribute (from PureCSS).
+// Needed for proper display in IE 10-.
+[hidden] {
+ display: none !important;
+}
diff --git a/templates/assets/bootstrap/scss/_responsive-embed.scss b/templates/assets/bootstrap/scss/_responsive-embed.scss
new file mode 100644
index 0000000..d3362b6
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_responsive-embed.scss
@@ -0,0 +1,52 @@
+// Credit: Nicolas Gallagher and SUIT CSS.
+
+.embed-responsive {
+ position: relative;
+ display: block;
+ width: 100%;
+ padding: 0;
+ overflow: hidden;
+
+ &::before {
+ display: block;
+ content: "";
+ }
+
+ .embed-responsive-item,
+ iframe,
+ embed,
+ object,
+ video {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: 0;
+ }
+}
+
+.embed-responsive-21by9 {
+ &::before {
+ padding-top: percentage(9 / 21);
+ }
+}
+
+.embed-responsive-16by9 {
+ &::before {
+ padding-top: percentage(9 / 16);
+ }
+}
+
+.embed-responsive-4by3 {
+ &::before {
+ padding-top: percentage(3 / 4);
+ }
+}
+
+.embed-responsive-1by1 {
+ &::before {
+ padding-top: percentage(1 / 1);
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_tables.scss b/templates/assets/bootstrap/scss/_tables.scss
new file mode 100644
index 0000000..f041f60
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_tables.scss
@@ -0,0 +1,169 @@
+//
+// Basic Bootstrap table
+//
+
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: $spacer;
+ background-color: $table-bg; // Reset for nesting within parents with `background-color`.
+
+ th,
+ td {
+ padding: $table-cell-padding;
+ vertical-align: top;
+ border-top: $table-border-width solid $table-border-color;
+ }
+
+ thead th {
+ vertical-align: bottom;
+ border-bottom: (2 * $table-border-width) solid $table-border-color;
+ }
+
+ tbody + tbody {
+ border-top: (2 * $table-border-width) solid $table-border-color;
+ }
+
+ .table {
+ background-color: $body-bg;
+ }
+}
+
+
+//
+// Condensed table w/ half padding
+//
+
+.table-sm {
+ th,
+ td {
+ padding: $table-sm-cell-padding;
+ }
+}
+
+
+// Bordered version
+//
+// Add borders all around the table and between all the columns.
+
+.table-bordered {
+ border: $table-border-width solid $table-border-color;
+
+ th,
+ td {
+ border: $table-border-width solid $table-border-color;
+ }
+
+ thead {
+ th,
+ td {
+ border-bottom-width: (2 * $table-border-width);
+ }
+ }
+}
+
+
+// Zebra-striping
+//
+// Default zebra-stripe styles (alternating gray and transparent backgrounds)
+
+.table-striped {
+ tbody tr:nth-of-type(odd) {
+ background-color: $table-bg-accent;
+ }
+}
+
+
+// Hover effect
+//
+// Placed here since it has to come after the potential zebra striping
+
+.table-hover {
+ tbody tr {
+ @include hover {
+ background-color: $table-bg-hover;
+ }
+ }
+}
+
+
+// Table backgrounds
+//
+// Exact selectors below required to override `.table-striped` and prevent
+// inheritance to nested tables.
+
+// Generate the contextual variants
+@include table-row-variant(active, $table-bg-active);
+@include table-row-variant(success, $state-success-bg);
+@include table-row-variant(info, $state-info-bg);
+@include table-row-variant(warning, $state-warning-bg);
+@include table-row-variant(danger, $state-danger-bg);
+
+
+// Inverse styles
+//
+// Same table markup, but inverted color scheme: dark background and light text.
+
+.thead-inverse {
+ th {
+ color: $table-inverse-color;
+ background-color: $table-inverse-bg;
+ }
+}
+
+.thead-default {
+ th {
+ color: $table-head-color;
+ background-color: $table-head-bg;
+ }
+}
+
+.table-inverse {
+ color: $table-inverse-color;
+ background-color: $table-inverse-bg;
+
+ th,
+ td,
+ thead th {
+ border-color: $table-inverse-border;
+ }
+
+ &.table-bordered {
+ border: 0;
+ }
+
+ &.table-striped {
+ tbody tr:nth-of-type(odd) {
+ background-color: $table-inverse-bg-accent;
+ }
+ }
+
+ &.table-hover {
+ tbody tr {
+ @include hover {
+ background-color: $table-inverse-bg-hover;
+ }
+ }
+ }
+}
+
+
+// Responsive tables
+//
+// Add `.table-responsive` to `.table`s and we'll make them mobile friendly by
+// enabling horizontal scrolling. Only applies <768px. Everything above that
+// will display normally.
+
+.table-responsive {
+ @include media-breakpoint-down(md) {
+ display: block;
+ width: 100%;
+ overflow-x: auto;
+ -ms-overflow-style: -ms-autohiding-scrollbar; // See https://github.com/twbs/bootstrap/pull/10057
+
+ // Prevent double border on horizontal scroll due to use of `display: block;`
+ &.table-bordered {
+ border: 0;
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_tooltip.scss b/templates/assets/bootstrap/scss/_tooltip.scss
new file mode 100644
index 0000000..24e198d
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_tooltip.scss
@@ -0,0 +1,90 @@
+// Base class
+.tooltip {
+ position: absolute;
+ z-index: $zindex-tooltip;
+ display: block;
+ // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
+ // So reset our font and text properties to avoid inheriting weird values.
+ @include reset-text();
+ font-size: $font-size-sm;
+ // Allow breaking very long words so they don't overflow the tooltip's bounds
+ word-wrap: break-word;
+ opacity: 0;
+
+ &.show { opacity: $tooltip-opacity; }
+
+ &.tooltip-top,
+ &.bs-tether-element-attached-bottom {
+ padding: $tooltip-arrow-width 0;
+ margin-top: -$tooltip-margin;
+
+ .tooltip-inner::before {
+ bottom: 0;
+ left: 50%;
+ margin-left: -$tooltip-arrow-width;
+ content: "";
+ border-width: $tooltip-arrow-width $tooltip-arrow-width 0;
+ border-top-color: $tooltip-arrow-color;
+ }
+ }
+ &.tooltip-right,
+ &.bs-tether-element-attached-left {
+ padding: 0 $tooltip-arrow-width;
+ margin-left: $tooltip-margin;
+
+ .tooltip-inner::before {
+ top: 50%;
+ left: 0;
+ margin-top: -$tooltip-arrow-width;
+ content: "";
+ border-width: $tooltip-arrow-width $tooltip-arrow-width $tooltip-arrow-width 0;
+ border-right-color: $tooltip-arrow-color;
+ }
+ }
+ &.tooltip-bottom,
+ &.bs-tether-element-attached-top {
+ padding: $tooltip-arrow-width 0;
+ margin-top: $tooltip-margin;
+
+ .tooltip-inner::before {
+ top: 0;
+ left: 50%;
+ margin-left: -$tooltip-arrow-width;
+ content: "";
+ border-width: 0 $tooltip-arrow-width $tooltip-arrow-width;
+ border-bottom-color: $tooltip-arrow-color;
+ }
+ }
+ &.tooltip-left,
+ &.bs-tether-element-attached-right {
+ padding: 0 $tooltip-arrow-width;
+ margin-left: -$tooltip-margin;
+
+ .tooltip-inner::before {
+ top: 50%;
+ right: 0;
+ margin-top: -$tooltip-arrow-width;
+ content: "";
+ border-width: $tooltip-arrow-width 0 $tooltip-arrow-width $tooltip-arrow-width;
+ border-left-color: $tooltip-arrow-color;
+ }
+ }
+}
+
+// Wrapper for the tooltip content
+.tooltip-inner {
+ max-width: $tooltip-max-width;
+ padding: $tooltip-padding-y $tooltip-padding-x;
+ color: $tooltip-color;
+ text-align: center;
+ background-color: $tooltip-bg;
+ @include border-radius($border-radius);
+
+ &::before {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_transitions.scss b/templates/assets/bootstrap/scss/_transitions.scss
new file mode 100644
index 0000000..86c04a5
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_transitions.scss
@@ -0,0 +1,34 @@
+.fade {
+ opacity: 0;
+ @include transition($transition-fade);
+
+ &.show {
+ opacity: 1;
+ }
+}
+
+.collapse {
+ display: none;
+ &.show {
+ display: block;
+ }
+}
+
+tr {
+ &.collapse.show {
+ display: table-row;
+ }
+}
+
+tbody {
+ &.collapse.show {
+ display: table-row-group;
+ }
+}
+
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ @include transition($transition-collapse);
+}
diff --git a/templates/assets/bootstrap/scss/_type.scss b/templates/assets/bootstrap/scss/_type.scss
new file mode 100644
index 0000000..fc9c791
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_type.scss
@@ -0,0 +1,143 @@
+//
+// Headings
+//
+
+h1, h2, h3, h4, h5, h6,
+.h1, .h2, .h3, .h4, .h5, .h6 {
+ margin-bottom: $headings-margin-bottom;
+ font-family: $headings-font-family;
+ font-weight: $headings-font-weight;
+ line-height: $headings-line-height;
+ color: $headings-color;
+}
+
+h1, .h1 { font-size: $font-size-h1; }
+h2, .h2 { font-size: $font-size-h2; }
+h3, .h3 { font-size: $font-size-h3; }
+h4, .h4 { font-size: $font-size-h4; }
+h5, .h5 { font-size: $font-size-h5; }
+h6, .h6 { font-size: $font-size-h6; }
+
+.lead {
+ font-size: $lead-font-size;
+ font-weight: $lead-font-weight;
+}
+
+// Type display classes
+.display-1 {
+ font-size: $display1-size;
+ font-weight: $display1-weight;
+ line-height: $display-line-height;
+}
+.display-2 {
+ font-size: $display2-size;
+ font-weight: $display2-weight;
+ line-height: $display-line-height;
+}
+.display-3 {
+ font-size: $display3-size;
+ font-weight: $display3-weight;
+ line-height: $display-line-height;
+}
+.display-4 {
+ font-size: $display4-size;
+ font-weight: $display4-weight;
+ line-height: $display-line-height;
+}
+
+
+//
+// Horizontal rules
+//
+
+hr {
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+ border: 0;
+ border-top: $hr-border-width solid $hr-border-color;
+}
+
+
+//
+// Emphasis
+//
+
+small,
+.small {
+ font-size: $small-font-size;
+ font-weight: $font-weight-normal;
+}
+
+mark,
+.mark {
+ padding: $mark-padding;
+ background-color: $mark-bg;
+}
+
+
+//
+// Lists
+//
+
+.list-unstyled {
+ @include list-unstyled;
+}
+
+// Inline turns list items into inline-block
+.list-inline {
+ @include list-unstyled;
+}
+.list-inline-item {
+ display: inline-block;
+
+ &:not(:last-child) {
+ margin-right: $list-inline-padding;
+ }
+}
+
+
+//
+// Misc
+//
+
+// Builds on `abbr`
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+
+// Blockquotes
+.blockquote {
+ padding: ($spacer / 2) $spacer;
+ margin-bottom: $spacer;
+ font-size: $blockquote-font-size;
+ border-left: $blockquote-border-width solid $blockquote-border-color;
+}
+
+.blockquote-footer {
+ display: block;
+ font-size: 80%; // back to default font-size
+ color: $blockquote-small-color;
+
+ &::before {
+ content: "\2014 \00A0"; // em dash, nbsp
+ }
+}
+
+// Opposite alignment of blockquote
+.blockquote-reverse {
+ padding-right: $spacer;
+ padding-left: 0;
+ text-align: right;
+ border-right: $blockquote-border-width solid $blockquote-border-color;
+ border-left: 0;
+}
+
+.blockquote-reverse .blockquote-footer {
+ &::before {
+ content: "";
+ }
+ &::after {
+ content: "\00A0 \2014"; // nbsp, em dash
+ }
+}
diff --git a/templates/assets/bootstrap/scss/_utilities.scss b/templates/assets/bootstrap/scss/_utilities.scss
new file mode 100644
index 0000000..7d08ff2
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_utilities.scss
@@ -0,0 +1,13 @@
+@import "utilities/align";
+@import "utilities/background";
+@import "utilities/borders";
+@import "utilities/clearfix";
+@import "utilities/display";
+@import "utilities/flex";
+@import "utilities/float";
+@import "utilities/position";
+@import "utilities/screenreaders";
+@import "utilities/sizing";
+@import "utilities/spacing";
+@import "utilities/text";
+@import "utilities/visibility";
diff --git a/templates/assets/bootstrap/scss/_variables.scss b/templates/assets/bootstrap/scss/_variables.scss
new file mode 100644
index 0000000..69eb401
--- /dev/null
+++ b/templates/assets/bootstrap/scss/_variables.scss
@@ -0,0 +1,921 @@
+// Variables
+//
+// Copy settings from this file into the provided `_custom.scss` to override
+// the Bootstrap defaults without modifying key, versioned files.
+
+
+// Table of Contents
+//
+// Colors
+// Options
+// Spacing
+// Body
+// Links
+// Grid breakpoints
+// Grid containers
+// Grid columns
+// Fonts
+// Components
+// Tables
+// Buttons
+// Forms
+// Dropdowns
+// Z-index master list
+// Navbar
+// Navs
+// Pagination
+// Jumbotron
+// Form states and alerts
+// Cards
+// Tooltips
+// Popovers
+// Badges
+// Modals
+// Alerts
+// Progress bars
+// List group
+// Image thumbnails
+// Figures
+// Breadcrumbs
+// Carousel
+// Close
+// Code
+
+@mixin _assert-ascending($map, $map-name) {
+ $prev-key: null;
+ $prev-num: null;
+ @each $key, $num in $map {
+ @if $prev-num == null {
+ // Do nothing
+ } @else if not comparable($prev-num, $num) {
+ @warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
+ } @else if $prev-num >= $num {
+ @warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
+ }
+ $prev-key: $key;
+ $prev-num: $num;
+ }
+}
+
+// Replace `$search` with `$replace` in `$string`
+// @author Hugo Giraudel
+// @param {String} $string - Initial string
+// @param {String} $search - Substring to replace
+// @param {String} $replace ('') - New value
+// @return {String} - Updated string
+@function str-replace($string, $search, $replace: "") {
+ $index: str-index($string, $search);
+
+ @if $index {
+ @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
+ }
+
+ @return $string;
+}
+
+@mixin _assert-starts-at-zero($map) {
+ $values: map-values($map);
+ $first-value: nth($values, 1);
+ @if $first-value != 0 {
+ @warn "First breakpoint in `$grid-breakpoints` must start at 0, but starts at #{$first-value}.";
+ }
+}
+
+
+// General variable structure
+//
+// Variable format should follow the `$component-modifier-state-property` order.
+
+
+// Colors
+//
+// Grayscale and brand colors for use across Bootstrap.
+
+// Start with assigning color names to specific hex values.
+$white: #fff !default;
+$black: #000 !default;
+$red: #d9534f !default;
+$orange: #f0ad4e !default;
+$yellow: #ffd500 !default;
+$green: #5cb85c !default;
+$blue: #0275d8 !default;
+$teal: #5bc0de !default;
+$pink: #ff5b77 !default;
+$purple: #613d7c !default;
+
+// Create grayscale
+$gray-dark: #292b2c !default;
+$gray: #464a4c !default;
+$gray-light: #636c72 !default;
+$gray-lighter: #eceeef !default;
+$gray-lightest: #f7f7f9 !default;
+
+// Reassign color vars to semantic color scheme
+$brand-primary: $blue !default;
+$brand-success: $green !default;
+$brand-info: $teal !default;
+$brand-warning: $orange !default;
+$brand-danger: $red !default;
+$brand-inverse: $gray-dark !default;
+
+
+// Options
+//
+// Quickly modify global styling by enabling or disabling optional features.
+
+$enable-rounded: true !default;
+$enable-shadows: false !default;
+$enable-gradients: false !default;
+$enable-transitions: true !default;
+$enable-hover-media-query: false !default;
+$enable-grid-classes: true !default;
+$enable-print-styles: true !default;
+
+
+// Spacing
+//
+// Control the default styling of most Bootstrap elements by modifying these
+// variables. Mostly focused on spacing.
+// You can add more entries to the $spacers map, should you need more variation.
+
+$spacer: 1rem !default;
+$spacers: (
+ 0: 0,
+ 1: ($spacer * .25),
+ 2: ($spacer * .5),
+ 3: $spacer,
+ 4: ($spacer * 1.5),
+ 5: ($spacer * 3)
+) !default;
+
+// This variable affects the `.h-*` and `.w-*` classes.
+$sizes: (
+ 25: 25%,
+ 50: 50%,
+ 75: 75%,
+ 100: 100%
+) !default;
+
+// Body
+//
+// Settings for the `<body>` element.
+
+$body-bg: $white !default;
+$body-color: $gray-dark !default;
+
+// Links
+//
+// Style anchor elements.
+
+$link-color: $brand-primary !default;
+$link-decoration: none !default;
+$link-hover-color: darken($link-color, 15%) !default;
+$link-hover-decoration: underline !default;
+
+
+// Grid breakpoints
+//
+// Define the minimum dimensions at which your layout will change,
+// adapting to different screen sizes, for use in media queries.
+
+$grid-breakpoints: (
+ xs: 0,
+ sm: 576px,
+ md: 768px,
+ lg: 992px,
+ xl: 1200px
+) !default;
+@include _assert-ascending($grid-breakpoints, "$grid-breakpoints");
+@include _assert-starts-at-zero($grid-breakpoints);
+
+
+// Grid containers
+//
+// Define the maximum width of `.container` for different screen sizes.
+
+$container-max-widths: (
+ sm: 540px,
+ md: 720px,
+ lg: 960px,
+ xl: 1140px
+) !default;
+@include _assert-ascending($container-max-widths, "$container-max-widths");
+
+
+// Grid columns
+//
+// Set the number of columns and specify the width of the gutters.
+
+$grid-columns: 12 !default;
+$grid-gutter-width-base: 30px !default;
+$grid-gutter-widths: (
+ xs: $grid-gutter-width-base,
+ sm: $grid-gutter-width-base,
+ md: $grid-gutter-width-base,
+ lg: $grid-gutter-width-base,
+ xl: $grid-gutter-width-base
+) !default;
+
+
+// Components
+//
+// Define common padding and border radius sizes and more.
+
+$line-height-lg: (4 / 3) !default;
+$line-height-sm: 1.5 !default;
+
+$border-width: 1px !default;
+
+$border-radius: .25rem !default;
+$border-radius-lg: .3rem !default;
+$border-radius-sm: .2rem !default;
+
+$component-active-color: $white !default;
+$component-active-bg: $brand-primary !default;
+
+$caret-width: .3em !default;
+
+$transition-base: all .2s ease-in-out !default;
+$transition-fade: opacity .15s linear !default;
+$transition-collapse: height .35s ease !default;
+
+
+// Fonts
+//
+// Font, line-height, and color for body text, headings, and more.
+
+$font-family-sans-serif: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !default;
+$font-family-monospace: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
+$font-family-base: $font-family-sans-serif !default;
+
+$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`
+$font-size-lg: 1.25rem !default;
+$font-size-sm: .875rem !default;
+$font-size-xs: .75rem !default;
+
+$font-weight-normal: normal !default;
+$font-weight-bold: bold !default;
+
+$font-weight-base: $font-weight-normal !default;
+$line-height-base: 1.5 !default;
+
+$font-size-h1: 2.5rem !default;
+$font-size-h2: 2rem !default;
+$font-size-h3: 1.75rem !default;
+$font-size-h4: 1.5rem !default;
+$font-size-h5: 1.25rem !default;
+$font-size-h6: 1rem !default;
+
+$headings-margin-bottom: ($spacer / 2) !default;
+$headings-font-family: inherit !default;
+$headings-font-weight: 500 !default;
+$headings-line-height: 1.1 !default;
+$headings-color: inherit !default;
+
+$display1-size: 6rem !default;
+$display2-size: 5.5rem !default;
+$display3-size: 4.5rem !default;
+$display4-size: 3.5rem !default;
+
+$display1-weight: 300 !default;
+$display2-weight: 300 !default;
+$display3-weight: 300 !default;
+$display4-weight: 300 !default;
+$display-line-height: $headings-line-height !default;
+
+$lead-font-size: 1.25rem !default;
+$lead-font-weight: 300 !default;
+
+$small-font-size: 80% !default;
+
+$text-muted: $gray-light !default;
+
+$blockquote-small-color: $gray-light !default;
+$blockquote-font-size: ($font-size-base * 1.25) !default;
+$blockquote-border-color: $gray-lighter !default;
+$blockquote-border-width: .25rem !default;
+
+$hr-border-color: rgba($black,.1) !default;
+$hr-border-width: $border-width !default;
+
+$mark-padding: .2em !default;
+
+$dt-font-weight: $font-weight-bold !default;
+
+$kbd-box-shadow: inset 0 -.1rem 0 rgba($black,.25) !default;
+$nested-kbd-font-weight: $font-weight-bold !default;
+
+$list-inline-padding: 5px !default;
+
+
+// Tables
+//
+// Customizes the `.table` component with basic values, each used across all table variations.
+
+$table-cell-padding: .75rem !default;
+$table-sm-cell-padding: .3rem !default;
+
+$table-bg: transparent !default;
+$table-bg-accent: rgba($black,.05) !default;
+$table-bg-hover: rgba($black,.075) !default;
+$table-bg-active: $table-bg-hover !default;
+
+$table-border-width: $border-width !default;
+$table-border-color: $gray-lighter !default;
+
+$table-head-bg: $gray-lighter !default;
+$table-head-color: $gray !default;
+
+$table-inverse-bg: $gray-dark !default;
+$table-inverse-bg-accent: rgba($white, .05) !default;
+$table-inverse-bg-hover: rgba($white, .075) !default;
+$table-inverse-bg-active: $table-inverse-bg-hover !default;
+$table-inverse-border: lighten($gray-dark, 7.5%) !default;
+$table-inverse-color: $body-bg !default;
+
+
+// Buttons
+//
+// For each of Bootstrap's buttons, define text, background and border color.
+
+$btn-padding-x: 1rem !default;
+$btn-padding-y: .5rem !default;
+$btn-line-height: 1.25 !default;
+$btn-font-weight: $font-weight-normal !default;
+$btn-box-shadow: inset 0 1px 0 rgba($white,.15), 0 1px 1px rgba($black,.075) !default;
+$btn-focus-box-shadow: 0 0 0 2px rgba($brand-primary, .25) !default;
+$btn-active-box-shadow: inset 0 3px 5px rgba($black,.125) !default;
+
+$btn-primary-color: $white !default;
+$btn-primary-bg: $brand-primary !default;
+$btn-primary-border: $btn-primary-bg !default;
+
+$btn-secondary-color: $gray-dark !default;
+$btn-secondary-bg: $white !default;
+$btn-secondary-border: #ccc !default;
+
+$btn-info-color: $white !default;
+$btn-info-bg: $brand-info !default;
+$btn-info-border: $btn-info-bg !default;
+
+$btn-success-color: $white !default;
+$btn-success-bg: $brand-success !default;
+$btn-success-border: $btn-success-bg !default;
+
+$btn-warning-color: $white !default;
+$btn-warning-bg: $brand-warning !default;
+$btn-warning-border: $btn-warning-bg !default;
+
+$btn-danger-color: $white !default;
+$btn-danger-bg: $brand-danger !default;
+$btn-danger-border: $btn-danger-bg !default;
+
+$btn-link-disabled-color: $gray-light !default;
+
+$btn-padding-x-sm: .5rem !default;
+$btn-padding-y-sm: .25rem !default;
+
+$btn-padding-x-lg: 1.5rem !default;
+$btn-padding-y-lg: .75rem !default;
+
+$btn-block-spacing-y: .5rem !default;
+
+// Allows for customizing button radius independently from global border radius
+$btn-border-radius: $border-radius !default;
+$btn-border-radius-lg: $border-radius-lg !default;
+$btn-border-radius-sm: $border-radius-sm !default;
+
+$btn-transition: all .2s ease-in-out !default;
+
+
+// Forms
+
+$input-padding-x: .75rem !default;
+$input-padding-y: .5rem !default;
+$input-line-height: 1.25 !default;
+
+$input-bg: $white !default;
+$input-bg-disabled: $gray-lighter !default;
+
+$input-color: $gray !default;
+$input-border-color: rgba($black,.15) !default;
+$input-btn-border-width: $border-width !default; // For form controls and buttons
+$input-box-shadow: inset 0 1px 1px rgba($black,.075) !default;
+
+$input-border-radius: $border-radius !default;
+$input-border-radius-lg: $border-radius-lg !default;
+$input-border-radius-sm: $border-radius-sm !default;
+
+$input-bg-focus: $input-bg !default;
+$input-border-focus: lighten($brand-primary, 25%) !default;
+$input-box-shadow-focus: $input-box-shadow, rgba($input-border-focus, .6) !default;
+$input-color-focus: $input-color !default;
+
+$input-color-placeholder: $gray-light !default;
+
+$input-padding-x-sm: .5rem !default;
+$input-padding-y-sm: .25rem !default;
+
+$input-padding-x-lg: 1.5rem !default;
+$input-padding-y-lg: .75rem !default;
+
+$input-height: (($font-size-base * $input-line-height) + ($input-padding-y * 2)) !default;
+$input-height-lg: (($font-size-lg * $line-height-lg) + ($input-padding-y-lg * 2)) !default;
+$input-height-sm: (($font-size-sm * $line-height-sm) + ($input-padding-y-sm * 2)) !default;
+
+$input-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s !default;
+
+$form-text-margin-top: .25rem !default;
+$form-feedback-margin-top: $form-text-margin-top !default;
+
+$form-check-margin-bottom: .5rem !default;
+$form-check-input-gutter: 1.25rem !default;
+$form-check-input-margin-y: .25rem !default;
+$form-check-input-margin-x: .25rem !default;
+
+$form-check-inline-margin-x: .75rem !default;
+
+$form-group-margin-bottom: 1rem !default;
+
+$input-group-addon-bg: $gray-lighter !default;
+$input-group-addon-border-color: $input-border-color !default;
+
+$cursor-disabled: not-allowed !default;
+
+$custom-control-gutter: 1.5rem !default;
+$custom-control-spacer-x: 1rem !default;
+$custom-control-spacer-y: .25rem !default;
+
+$custom-control-indicator-size: 1rem !default;
+$custom-control-indicator-bg: #ddd !default;
+$custom-control-indicator-bg-size: 50% 50% !default;
+$custom-control-indicator-box-shadow: inset 0 .25rem .25rem rgba($black,.1) !default;
+
+$custom-control-disabled-cursor: $cursor-disabled !default;
+$custom-control-disabled-indicator-bg: $gray-lighter !default;
+$custom-control-disabled-description-color: $gray-light !default;
+
+$custom-control-checked-indicator-color: $white !default;
+$custom-control-checked-indicator-bg: $brand-primary !default;
+$custom-control-checked-indicator-box-shadow: none !default;
+
+$custom-control-focus-indicator-box-shadow: 0 0 0 1px $body-bg, 0 0 0 3px $brand-primary !default;
+
+$custom-control-active-indicator-color: $white !default;
+$custom-control-active-indicator-bg: lighten($brand-primary, 35%) !default;
+$custom-control-active-indicator-box-shadow: none !default;
+
+$custom-checkbox-radius: $border-radius !default;
+$custom-checkbox-checked-icon: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$custom-control-checked-indicator-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"), "#", "%23") !default;
+
+$custom-checkbox-indeterminate-bg: $brand-primary !default;
+$custom-checkbox-indeterminate-indicator-color: $custom-control-checked-indicator-color !default;
+$custom-checkbox-indeterminate-icon: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='#{$custom-checkbox-indeterminate-indicator-color}' d='M0 2h4'/%3E%3C/svg%3E"), "#", "%23") !default;
+$custom-checkbox-indeterminate-box-shadow: none !default;
+
+$custom-radio-radius: 50% !default;
+$custom-radio-checked-icon: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='#{$custom-control-checked-indicator-color}'/%3E%3C/svg%3E"), "#", "%23") !default;
+
+$custom-select-padding-x: .75rem !default;
+$custom-select-padding-y: .375rem !default;
+$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator
+$custom-select-line-height: $input-line-height !default;
+$custom-select-color: $input-color !default;
+$custom-select-disabled-color: $gray-light !default;
+$custom-select-bg: $white !default;
+$custom-select-disabled-bg: $gray-lighter !default;
+$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions
+$custom-select-indicator-color: #333 !default;
+$custom-select-indicator: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E"), "#", "%23") !default;
+$custom-select-border-width: $input-btn-border-width !default;
+$custom-select-border-color: $input-border-color !default;
+$custom-select-border-radius: $border-radius !default;
+
+$custom-select-focus-border-color: lighten($brand-primary, 25%) !default;
+$custom-select-focus-box-shadow: inset 0 1px 2px rgba($black, .075), 0 0 5px rgba($custom-select-focus-border-color, .5) !default;
+
+$custom-select-sm-font-size: 75% !default;
+
+$custom-file-height: 2.5rem !default;
+$custom-file-width: 14rem !default;
+$custom-file-focus-box-shadow: 0 0 0 .075rem $white, 0 0 0 .2rem $brand-primary !default;
+
+$custom-file-padding-x: .5rem !default;
+$custom-file-padding-y: 1rem !default;
+$custom-file-line-height: 1.5 !default;
+$custom-file-color: $gray !default;
+$custom-file-bg: $white !default;
+$custom-file-border-width: $border-width !default;
+$custom-file-border-color: $input-border-color !default;
+$custom-file-border-radius: $border-radius !default;
+$custom-file-box-shadow: inset 0 .2rem .4rem rgba($black,.05) !default;
+$custom-file-button-color: $custom-file-color !default;
+$custom-file-button-bg: $gray-lighter !default;
+$custom-file-text: (
+ placeholder: (
+ en: "Choose file..."
+ ),
+ button-label: (
+ en: "Browse"
+ )
+) !default;
+
+
+// Form validation icons
+$form-icon-success-color: $brand-success !default;
+$form-icon-success: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$form-icon-success-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E"), "#", "%23") !default;
+
+$form-icon-warning-color: $brand-warning !default;
+$form-icon-warning: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$form-icon-warning-color}' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E"), "#", "%23") !default;
+
+$form-icon-danger-color: $brand-danger !default;
+$form-icon-danger: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$form-icon-danger-color}' viewBox='-2 -2 7 7'%3E%3Cpath stroke='#{$form-icon-danger-color}' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E"), "#", "%23") !default;
+
+
+// Dropdowns
+//
+// Dropdown menu container and contents.
+
+$dropdown-min-width: 10rem !default;
+$dropdown-padding-y: .5rem !default;
+$dropdown-margin-top: .125rem !default;
+$dropdown-bg: $white !default;
+$dropdown-border-color: rgba($black,.15) !default;
+$dropdown-border-width: $border-width !default;
+$dropdown-divider-bg: $gray-lighter !default;
+$dropdown-box-shadow: 0 .5rem 1rem rgba($black,.175) !default;
+
+$dropdown-link-color: $gray-dark !default;
+$dropdown-link-hover-color: darken($gray-dark, 5%) !default;
+$dropdown-link-hover-bg: $gray-lightest !default;
+
+$dropdown-link-active-color: $component-active-color !default;
+$dropdown-link-active-bg: $component-active-bg !default;
+
+$dropdown-link-disabled-color: $gray-light !default;
+
+$dropdown-item-padding-x: 1.5rem !default;
+
+$dropdown-header-color: $gray-light !default;
+
+
+// Z-index master list
+//
+// Warning: Avoid customizing these values. They're used for a bird's eye view
+// of components dependent on the z-axis and are designed to all work together.
+
+$zindex-dropdown-backdrop: 990 !default;
+$zindex-dropdown: 1000 !default;
+$zindex-sticky: 1020 !default;
+$zindex-fixed: 1030 !default;
+$zindex-modal-backdrop: 1040 !default;
+$zindex-modal: 1050 !default;
+$zindex-popover: 1060 !default;
+$zindex-tooltip: 1070 !default;
+
+// Navbar
+
+$navbar-padding-x: $spacer !default;
+$navbar-padding-y: ($spacer / 2) !default;
+
+$navbar-toggler-padding-x: .75rem !default;
+$navbar-toggler-padding-y: .25rem !default;
+$navbar-toggler-font-size: $font-size-lg !default;
+$navbar-toggler-border-radius: $btn-border-radius !default;
+
+$navbar-inverse-color: rgba($white,.5) !default;
+$navbar-inverse-hover-color: rgba($white,.75) !default;
+$navbar-inverse-active-color: rgba($white,1) !default;
+$navbar-inverse-disabled-color: rgba($white,.25) !default;
+$navbar-inverse-toggler-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-inverse-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"), "#", "%23") !default;
+$navbar-inverse-toggler-border: rgba($white,.1) !default;
+
+$navbar-light-color: rgba($black,.5) !default;
+$navbar-light-hover-color: rgba($black,.7) !default;
+$navbar-light-active-color: rgba($black,.9) !default;
+$navbar-light-disabled-color: rgba($black,.3) !default;
+$navbar-light-toggler-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"), "#", "%23") !default;
+$navbar-light-toggler-border: rgba($black,.1) !default;
+
+// Navs
+
+$nav-link-padding: .5em 1em !default;
+$nav-disabled-link-color: $gray-light !default;
+
+$nav-tabs-border-color: #ddd !default;
+$nav-tabs-border-width: $border-width !default;
+$nav-tabs-border-radius: $border-radius !default;
+$nav-tabs-link-hover-border-color: $gray-lighter !default;
+$nav-tabs-active-link-color: $gray !default;
+$nav-tabs-active-link-bg: $body-bg !default;
+$nav-tabs-active-link-border-color: #ddd !default;
+
+$nav-pills-border-radius: $border-radius !default;
+$nav-pills-active-link-color: $component-active-color !default;
+$nav-pills-active-link-bg: $component-active-bg !default;
+
+
+// Pagination
+
+$pagination-padding-x: .75rem !default;
+$pagination-padding-y: .5rem !default;
+$pagination-padding-x-sm: .5rem !default;
+$pagination-padding-y-sm: .25rem !default;
+$pagination-padding-x-lg: 1.5rem !default;
+$pagination-padding-y-lg: .75rem !default;
+$pagination-line-height: 1.25 !default;
+
+$pagination-color: $link-color !default;
+$pagination-bg: $white !default;
+$pagination-border-width: $border-width !default;
+$pagination-border-color: #ddd !default;
+
+$pagination-hover-color: $link-hover-color !default;
+$pagination-hover-bg: $gray-lighter !default;
+$pagination-hover-border: #ddd !default;
+
+$pagination-active-color: $white !default;
+$pagination-active-bg: $brand-primary !default;
+$pagination-active-border: $brand-primary !default;
+
+$pagination-disabled-color: $gray-light !default;
+$pagination-disabled-bg: $white !default;
+$pagination-disabled-border: #ddd !default;
+
+
+// Jumbotron
+
+$jumbotron-padding: 2rem !default;
+$jumbotron-bg: $gray-lighter !default;
+
+
+// Form states and alerts
+//
+// Define colors for form feedback states and, by default, alerts.
+
+$state-success-text: #3c763d !default;
+$state-success-bg: #dff0d8 !default;
+$state-success-border: darken($state-success-bg, 5%) !default;
+
+$state-info-text: #31708f !default;
+$state-info-bg: #d9edf7 !default;
+$state-info-border: darken($state-info-bg, 7%) !default;
+
+$state-warning-text: #8a6d3b !default;
+$state-warning-bg: #fcf8e3 !default;
+$mark-bg: $state-warning-bg !default;
+$state-warning-border: darken($state-warning-bg, 5%) !default;
+
+$state-danger-text: #a94442 !default;
+$state-danger-bg: #f2dede !default;
+$state-danger-border: darken($state-danger-bg, 5%) !default;
+
+
+// Cards
+
+$card-spacer-x: 1.25rem !default;
+$card-spacer-y: .75rem !default;
+$card-border-width: 1px !default;
+$card-border-radius: $border-radius !default;
+$card-border-color: rgba($black,.125) !default;
+$card-border-radius-inner: calc(#{$card-border-radius} - #{$card-border-width}) !default;
+$card-cap-bg: $gray-lightest !default;
+$card-bg: $white !default;
+
+$card-link-hover-color: $white !default;
+
+$card-img-overlay-padding: 1.25rem !default;
+
+$card-deck-margin: ($grid-gutter-width-base / 2) !default;
+
+$card-columns-count: 3 !default;
+$card-columns-gap: 1.25rem !default;
+$card-columns-margin: $card-spacer-y !default;
+
+
+// Tooltips
+
+$tooltip-max-width: 200px !default;
+$tooltip-color: $white !default;
+$tooltip-bg: $black !default;
+$tooltip-opacity: .9 !default;
+$tooltip-padding-y: 3px !default;
+$tooltip-padding-x: 8px !default;
+$tooltip-margin: 3px !default;
+
+$tooltip-arrow-width: 5px !default;
+$tooltip-arrow-color: $tooltip-bg !default;
+
+
+// Popovers
+
+$popover-inner-padding: 1px !default;
+$popover-bg: $white !default;
+$popover-max-width: 276px !default;
+$popover-border-width: $border-width !default;
+$popover-border-color: rgba($black,.2) !default;
+$popover-box-shadow: 0 5px 10px rgba($black,.2) !default;
+
+$popover-title-bg: darken($popover-bg, 3%) !default;
+$popover-title-padding-x: 14px !default;
+$popover-title-padding-y: 8px !default;
+
+$popover-content-padding-x: 14px !default;
+$popover-content-padding-y: 9px !default;
+
+$popover-arrow-width: 10px !default;
+$popover-arrow-color: $popover-bg !default;
+
+$popover-arrow-outer-width: ($popover-arrow-width + 1px) !default;
+$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;
+
+
+// Badges
+
+$badge-default-bg: $gray-light !default;
+$badge-primary-bg: $brand-primary !default;
+$badge-success-bg: $brand-success !default;
+$badge-info-bg: $brand-info !default;
+$badge-warning-bg: $brand-warning !default;
+$badge-danger-bg: $brand-danger !default;
+
+$badge-color: $white !default;
+$badge-link-hover-color: $white !default;
+$badge-font-size: 75% !default;
+$badge-font-weight: $font-weight-bold !default;
+$badge-padding-x: .4em !default;
+$badge-padding-y: .25em !default;
+
+$badge-pill-padding-x: .6em !default;
+// Use a higher than normal value to ensure completely rounded edges when
+// customizing padding or font-size on labels.
+$badge-pill-border-radius: 10rem !default;
+
+
+// Modals
+
+// Padding applied to the modal body
+$modal-inner-padding: 15px !default;
+
+$modal-dialog-margin: 10px !default;
+$modal-dialog-sm-up-margin-y: 30px !default;
+
+$modal-title-line-height: $line-height-base !default;
+
+$modal-content-bg: $white !default;
+$modal-content-border-color: rgba($black,.2) !default;
+$modal-content-border-width: $border-width !default;
+$modal-content-xs-box-shadow: 0 3px 9px rgba($black,.5) !default;
+$modal-content-sm-up-box-shadow: 0 5px 15px rgba($black,.5) !default;
+
+$modal-backdrop-bg: $black !default;
+$modal-backdrop-opacity: .5 !default;
+$modal-header-border-color: $gray-lighter !default;
+$modal-footer-border-color: $modal-header-border-color !default;
+$modal-header-border-width: $modal-content-border-width !default;
+$modal-footer-border-width: $modal-header-border-width !default;
+$modal-header-padding: 15px !default;
+
+$modal-lg: 800px !default;
+$modal-md: 500px !default;
+$modal-sm: 300px !default;
+
+$modal-transition: transform .3s ease-out !default;
+
+
+// Alerts
+//
+// Define alert colors, border radius, and padding.
+
+$alert-padding-x: 1.25rem !default;
+$alert-padding-y: .75rem !default;
+$alert-margin-bottom: 1rem !default;
+$alert-border-radius: $border-radius !default;
+$alert-link-font-weight: $font-weight-bold !default;
+$alert-border-width: $border-width !default;
+
+$alert-success-bg: $state-success-bg !default;
+$alert-success-text: $state-success-text !default;
+$alert-success-border: $state-success-border !default;
+
+$alert-info-bg: $state-info-bg !default;
+$alert-info-text: $state-info-text !default;
+$alert-info-border: $state-info-border !default;
+
+$alert-warning-bg: $state-warning-bg !default;
+$alert-warning-text: $state-warning-text !default;
+$alert-warning-border: $state-warning-border !default;
+
+$alert-danger-bg: $state-danger-bg !default;
+$alert-danger-text: $state-danger-text !default;
+$alert-danger-border: $state-danger-border !default;
+
+
+// Progress bars
+
+$progress-height: 1rem !default;
+$progress-font-size: .75rem !default;
+$progress-bg: $gray-lighter !default;
+$progress-border-radius: $border-radius !default;
+$progress-box-shadow: inset 0 .1rem .1rem rgba($black,.1) !default;
+$progress-bar-color: $white !default;
+$progress-bar-bg: $brand-primary !default;
+$progress-bar-animation-timing: 1s linear infinite !default;
+
+// List group
+
+$list-group-color: $body-color !default;
+$list-group-bg: $white !default;
+$list-group-border-color: rgba($black,.125) !default;
+$list-group-border-width: $border-width !default;
+$list-group-border-radius: $border-radius !default;
+
+$list-group-item-padding-x: 1.25rem !default;
+$list-group-item-padding-y: .75rem !default;
+
+$list-group-hover-bg: $gray-lightest !default;
+$list-group-active-color: $component-active-color !default;
+$list-group-active-bg: $component-active-bg !default;
+$list-group-active-border: $list-group-active-bg !default;
+
+$list-group-disabled-color: $gray-light !default;
+$list-group-disabled-bg: $list-group-bg !default;
+
+$list-group-link-color: $gray !default;
+$list-group-link-hover-color: $list-group-link-color !default;
+
+$list-group-link-active-color: $list-group-color !default;
+$list-group-link-active-bg: $gray-lighter !default;
+
+
+// Image thumbnails
+
+$thumbnail-padding: .25rem !default;
+$thumbnail-bg: $body-bg !default;
+$thumbnail-border-width: $border-width !default;
+$thumbnail-border-color: #ddd !default;
+$thumbnail-border-radius: $border-radius !default;
+$thumbnail-box-shadow: 0 1px 2px rgba($black,.075) !default;
+$thumbnail-transition: all .2s ease-in-out !default;
+
+
+// Figures
+
+$figure-caption-font-size: 90% !default;
+$figure-caption-color: $gray-light !default;
+
+
+// Breadcrumbs
+
+$breadcrumb-padding-y: .75rem !default;
+$breadcrumb-padding-x: 1rem !default;
+$breadcrumb-item-padding: .5rem !default;
+
+$breadcrumb-bg: $gray-lighter !default;
+$breadcrumb-divider-color: $gray-light !default;
+$breadcrumb-active-color: $gray-light !default;
+$breadcrumb-divider: "/" !default;
+
+
+// Carousel
+
+$carousel-control-color: $white !default;
+$carousel-control-width: 15% !default;
+$carousel-control-opacity: .5 !default;
+
+$carousel-indicator-width: 30px !default;
+$carousel-indicator-height: 3px !default;
+$carousel-indicator-spacer: 3px !default;
+$carousel-indicator-active-bg: $white !default;
+
+$carousel-caption-width: 70% !default;
+$carousel-caption-color: $white !default;
+
+$carousel-control-icon-width: 20px !default;
+
+$carousel-control-prev-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M4 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E"), "#", "%23") !default;
+$carousel-control-next-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M1.5 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E"), "#", "%23") !default;
+
+$carousel-transition: transform .6s ease-in-out !default;
+
+
+// Close
+
+$close-font-size: $font-size-base * 1.5 !default;
+$close-font-weight: $font-weight-bold !default;
+$close-color: $black !default;
+$close-text-shadow: 0 1px 0 $white !default;
+
+// Code
+
+$code-font-size: 90% !default;
+$code-padding-x: .4rem !default;
+$code-padding-y: .2rem !default;
+$code-color: #bd4147 !default;
+$code-bg: $gray-lightest !default;
+
+$kbd-color: $white !default;
+$kbd-bg: $gray-dark !default;
+
+$pre-color: $gray-dark !default;
+$pre-scrollable-max-height: 340px !default;
diff --git a/templates/assets/bootstrap/scss/bootstrap-grid.scss b/templates/assets/bootstrap/scss/bootstrap-grid.scss
new file mode 100644
index 0000000..2ba6858
--- /dev/null
+++ b/templates/assets/bootstrap/scss/bootstrap-grid.scss
@@ -0,0 +1,37 @@
+// Bootstrap Grid only
+//
+// Includes relevant variables and mixins for the flexbox grid
+// system, as well as the generated predefined classes (e.g., `.col-sm-4`).
+
+//
+// Box sizing, responsive, and more
+//
+
+@at-root {
+ @-ms-viewport { width: device-width; }
+}
+
+html {
+ box-sizing: border-box;
+ -ms-overflow-style: scrollbar;
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: inherit;
+}
+
+@import "custom";
+@import "variables";
+
+//
+// Grid mixins
+//
+
+@import "mixins/breakpoints";
+@import "mixins/grid-framework";
+@import "mixins/grid";
+
+@import "grid";
+@import "utilities/flex";
diff --git a/templates/assets/bootstrap/scss/bootstrap-reboot.scss b/templates/assets/bootstrap/scss/bootstrap-reboot.scss
new file mode 100644
index 0000000..5867f08
--- /dev/null
+++ b/templates/assets/bootstrap/scss/bootstrap-reboot.scss
@@ -0,0 +1,9 @@
+// Bootstrap Reboot only
+//
+// Includes only Normalize and our custom Reboot reset.
+
+@import "custom";
+@import "variables";
+@import "mixins";
+
+@import "reboot";
diff --git a/templates/assets/bootstrap/scss/bootstrap.scss b/templates/assets/bootstrap/scss/bootstrap.scss
new file mode 100644
index 0000000..f7577f5
--- /dev/null
+++ b/templates/assets/bootstrap/scss/bootstrap.scss
@@ -0,0 +1,52 @@
+/*!
+ * Bootstrap v4.0.0-alpha.6 (https://getbootstrap.com)
+ * Copyright 2011-2017 The Bootstrap Authors
+ * Copyright 2011-2017 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+// Core variables and mixins
+@import "custom";
+@import "variables";
+@import "mixins";
+
+@import "print";
+
+// Core CSS
+@import "reboot";
+@import "type";
+@import "images";
+@import "code";
+@import "grid";
+@import "tables";
+@import "forms";
+@import "buttons";
+
+// Components
+@import "transitions";
+@import "dropdown";
+@import "button-group";
+@import "input-group";
+@import "custom-forms";
+@import "nav";
+@import "navbar";
+@import "card";
+@import "breadcrumb";
+@import "pagination";
+@import "badge";
+@import "jumbotron";
+@import "alert";
+@import "progress";
+@import "media";
+@import "list-group";
+@import "responsive-embed";
+@import "close";
+
+// Components w/ JavaScript
+@import "modal";
+@import "tooltip";
+@import "popover";
+@import "carousel";
+
+// Utility classes
+@import "utilities";
diff --git a/templates/assets/bootstrap/scss/mixins/_alert.scss b/templates/assets/bootstrap/scss/mixins/_alert.scss
new file mode 100644
index 0000000..1e9307e
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_alert.scss
@@ -0,0 +1,14 @@
+// Alerts
+
+@mixin alert-variant($background, $border, $body-color) {
+ color: $body-color;
+ background-color: $background;
+ border-color: $border;
+
+ hr {
+ border-top-color: darken($border, 5%);
+ }
+ .alert-link {
+ color: darken($body-color, 10%);
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_background-variant.scss b/templates/assets/bootstrap/scss/mixins/_background-variant.scss
new file mode 100644
index 0000000..54a734d
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_background-variant.scss
@@ -0,0 +1,12 @@
+// Contextual backgrounds
+
+@mixin bg-variant($parent, $color) {
+ #{$parent} {
+ background-color: $color !important;
+ }
+ a#{$parent} {
+ @include hover-focus {
+ background-color: darken($color, 10%) !important;
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_badge.scss b/templates/assets/bootstrap/scss/mixins/_badge.scss
new file mode 100644
index 0000000..9fa44b6
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_badge.scss
@@ -0,0 +1,11 @@
+// Badges
+
+@mixin badge-variant($color) {
+ background-color: $color;
+
+ &[href] {
+ @include hover-focus {
+ background-color: darken($color, 10%);
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_border-radius.scss b/templates/assets/bootstrap/scss/mixins/_border-radius.scss
new file mode 100644
index 0000000..2024feb
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_border-radius.scss
@@ -0,0 +1,35 @@
+// Single side border-radius
+
+@mixin border-radius($radius: $border-radius) {
+ @if $enable-rounded {
+ border-radius: $radius;
+ }
+}
+
+@mixin border-top-radius($radius) {
+ @if $enable-rounded {
+ border-top-left-radius: $radius;
+ border-top-right-radius: $radius;
+ }
+}
+
+@mixin border-right-radius($radius) {
+ @if $enable-rounded {
+ border-top-right-radius: $radius;
+ border-bottom-right-radius: $radius;
+ }
+}
+
+@mixin border-bottom-radius($radius) {
+ @if $enable-rounded {
+ border-bottom-right-radius: $radius;
+ border-bottom-left-radius: $radius;
+ }
+}
+
+@mixin border-left-radius($radius) {
+ @if $enable-rounded {
+ border-top-left-radius: $radius;
+ border-bottom-left-radius: $radius;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_box-shadow.scss b/templates/assets/bootstrap/scss/mixins/_box-shadow.scss
new file mode 100644
index 0000000..b2410e5
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_box-shadow.scss
@@ -0,0 +1,5 @@
+@mixin box-shadow($shadow...) {
+ @if $enable-shadows {
+ box-shadow: $shadow;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_breakpoints.scss b/templates/assets/bootstrap/scss/mixins/_breakpoints.scss
new file mode 100644
index 0000000..904b60f
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_breakpoints.scss
@@ -0,0 +1,95 @@
+// Breakpoint viewport sizes and media queries.
+//
+// Breakpoints are defined as a map of (name: minimum width), order from small to large:
+//
+// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)
+//
+// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
+
+// Name of the next breakpoint, or null for the last breakpoint.
+//
+// >> breakpoint-next(sm)
+// md
+// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
+// md
+// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))
+// md
+@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
+ $n: index($breakpoint-names, $name);
+ @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
+}
+
+// Minimum breakpoint width. Null for the smallest (first) breakpoint.
+//
+// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
+// 576px
+@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
+ $min: map-get($breakpoints, $name);
+ @return if($min != 0, $min, null);
+}
+
+// Maximum breakpoint width. Null for the largest (last) breakpoint.
+// The maximum value is calculated as the minimum of the next one less 0.1.
+//
+// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
+// 767px
+@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
+ $next: breakpoint-next($name, $breakpoints);
+ @return if($next, breakpoint-min($next, $breakpoints) - 1px, null);
+}
+
+// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront.
+// Useful for making responsive utilities.
+//
+// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
+// "" (Returns a blank string)
+// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
+// "-sm"
+@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
+ @return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
+}
+
+// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
+// Makes the @content apply to the given breakpoint and wider.
+@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
+ $min: breakpoint-min($name, $breakpoints);
+ @if $min {
+ @media (min-width: $min) {
+ @content;
+ }
+ } @else {
+ @content;
+ }
+}
+
+// Media of at most the maximum breakpoint width. No query for the largest breakpoint.
+// Makes the @content apply to the given breakpoint and narrower.
+@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {
+ $max: breakpoint-max($name, $breakpoints);
+ @if $max {
+ @media (max-width: $max) {
+ @content;
+ }
+ } @else {
+ @content;
+ }
+}
+
+// Media that spans multiple breakpoint widths.
+// Makes the @content apply between the min and max breakpoints
+@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {
+ @include media-breakpoint-up($lower, $breakpoints) {
+ @include media-breakpoint-down($upper, $breakpoints) {
+ @content;
+ }
+ }
+}
+
+// Media between the breakpoint's minimum and maximum widths.
+// No minimum for the smallest breakpoint, and no maximum for the largest one.
+// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.
+@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {
+ @include media-breakpoint-between($name, $name, $breakpoints) {
+ @content;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_buttons.scss b/templates/assets/bootstrap/scss/mixins/_buttons.scss
new file mode 100644
index 0000000..91eb444
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_buttons.scss
@@ -0,0 +1,86 @@
+// Button variants
+//
+// Easily pump out default styles, as well as :hover, :focus, :active,
+// and disabled options for all buttons
+
+@mixin button-variant($color, $background, $border) {
+ $active-background: darken($background, 10%);
+ $active-border: darken($border, 12%);
+
+ color: $color;
+ background-color: $background;
+ border-color: $border;
+ @include box-shadow($btn-box-shadow);
+
+ // Hover and focus styles are shared
+ @include hover {
+ color: $color;
+ background-color: $active-background;
+ border-color: $active-border;
+ }
+ &:focus,
+ &.focus {
+ // Avoid using mixin so we can pass custom focus shadow properly
+ @if $enable-shadows {
+ box-shadow: $btn-box-shadow, 0 0 0 2px rgba($border, .5);
+ } @else {
+ box-shadow: 0 0 0 2px rgba($border, .5);
+ }
+ }
+
+ // Disabled comes first so active can properly restyle
+ &.disabled,
+ &:disabled {
+ background-color: $background;
+ border-color: $border;
+ }
+
+ &:active,
+ &.active,
+ .show > &.dropdown-toggle {
+ color: $color;
+ background-color: $active-background;
+ background-image: none; // Remove the gradient for the pressed/active state
+ border-color: $active-border;
+ @include box-shadow($btn-active-box-shadow);
+ }
+}
+
+@mixin button-outline-variant($color, $color-hover: #fff) {
+ color: $color;
+ background-color: transparent;
+ background-image: none;
+ border-color: $color;
+
+ @include hover {
+ color: $color-hover;
+ background-color: $color;
+ border-color: $color;
+ }
+
+ &:focus,
+ &.focus {
+ box-shadow: 0 0 0 2px rgba($color, .5);
+ }
+
+ &.disabled,
+ &:disabled {
+ color: $color;
+ background-color: transparent;
+ }
+
+ &:active,
+ &.active,
+ .show > &.dropdown-toggle {
+ color: $color-hover;
+ background-color: $color;
+ border-color: $color;
+ }
+}
+
+// Button sizes
+@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) {
+ padding: $padding-y $padding-x;
+ font-size: $font-size;
+ @include border-radius($border-radius);
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_cards.scss b/templates/assets/bootstrap/scss/mixins/_cards.scss
new file mode 100644
index 0000000..4b1232d
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_cards.scss
@@ -0,0 +1,47 @@
+// Card variants
+
+@mixin card-variant($background, $border) {
+ background-color: $background;
+ border-color: $border;
+
+ .card-header,
+ .card-footer {
+ background-color: transparent;
+ }
+}
+
+@mixin card-outline-variant($color) {
+ background-color: transparent;
+ border-color: $color;
+}
+
+//
+// Inverse text within a card for use with dark backgrounds
+//
+
+@mixin card-inverse {
+ color: rgba(255,255,255,.65);
+
+ .card-header,
+ .card-footer {
+ background-color: transparent;
+ border-color: rgba(255,255,255,.2);
+ }
+ .card-header,
+ .card-footer,
+ .card-title,
+ .card-blockquote {
+ color: #fff;
+ }
+ .card-link,
+ .card-text,
+ .card-subtitle,
+ .card-blockquote .blockquote-footer {
+ color: rgba(255,255,255,.65);
+ }
+ .card-link {
+ @include hover-focus {
+ color: $card-link-hover-color;
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_clearfix.scss b/templates/assets/bootstrap/scss/mixins/_clearfix.scss
new file mode 100644
index 0000000..11a977b
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_clearfix.scss
@@ -0,0 +1,7 @@
+@mixin clearfix() {
+ &::after {
+ display: block;
+ clear: both;
+ content: "";
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_float.scss b/templates/assets/bootstrap/scss/mixins/_float.scss
new file mode 100644
index 0000000..b43116f
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_float.scss
@@ -0,0 +1,9 @@
+@mixin float-left {
+ float: left !important;
+}
+@mixin float-right {
+ float: right !important;
+}
+@mixin float-none {
+ float: none !important;
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_forms.scss b/templates/assets/bootstrap/scss/mixins/_forms.scss
new file mode 100644
index 0000000..33b186a
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_forms.scss
@@ -0,0 +1,55 @@
+// Form validation states
+//
+// Used in _forms.scss to generate the form validation CSS for warnings, errors,
+// and successes.
+
+@mixin form-control-validation($color) {
+ // Color the label and help text
+ .form-control-feedback,
+ .form-control-label,
+ .col-form-label,
+ .form-check-label,
+ .custom-control {
+ color: $color;
+ }
+
+ // Set the border and box shadow on specific inputs to match
+ .form-control,
+ .custom-select,
+ .custom-file-control {
+ border-color: $color;
+
+ &:focus {
+ @include box-shadow($input-box-shadow, 0 0 6px lighten($color, 20%));
+ }
+ }
+
+ // Set validation states also for addons
+ .input-group-addon {
+ color: $color;
+ background-color: lighten($color, 40%);
+ border-color: $color;
+ }
+}
+
+// Form control focus state
+//
+// Generate a customized focus state and for any input with the specified color,
+// which defaults to the `@input-border-focus` variable.
+//
+// We highly encourage you to not customize the default value, but instead use
+// this to tweak colors on an as-needed basis. This aesthetic change is based on
+// WebKit's default styles, but applicable to a wider range of browsers. Its
+// usability and accessibility should be taken into account with any change.
+//
+// Example usage: change the default blue border and shadow to white for better
+// contrast against a dark gray background.
+@mixin form-control-focus() {
+ &:focus {
+ color: $input-color-focus;
+ background-color: $input-bg-focus;
+ border-color: $input-border-focus;
+ outline: none;
+ @include box-shadow($input-box-shadow-focus);
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_gradients.scss b/templates/assets/bootstrap/scss/mixins/_gradients.scss
new file mode 100644
index 0000000..bad79f9
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_gradients.scss
@@ -0,0 +1,37 @@
+// Gradients
+
+// Horizontal gradient, from left to right
+//
+// Creates two color stops, start and end, by specifying a color and position for each color stop.
+@mixin gradient-x($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
+ background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);
+ background-repeat: repeat-x;
+}
+
+// Vertical gradient, from top to bottom
+//
+// Creates two color stops, start and end, by specifying a color and position for each color stop.
+@mixin gradient-y($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
+ background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);
+ background-repeat: repeat-x;
+}
+
+@mixin gradient-directional($start-color: #555, $end-color: #333, $deg: 45deg) {
+ background-image: linear-gradient($deg, $start-color, $end-color);
+ background-repeat: repeat-x;
+}
+@mixin gradient-x-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
+ background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
+ background-repeat: no-repeat;
+}
+@mixin gradient-y-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
+ background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
+ background-repeat: no-repeat;
+}
+@mixin gradient-radial($inner-color: #555, $outer-color: #333) {
+ background-image: radial-gradient(circle, $inner-color, $outer-color);
+ background-repeat: no-repeat;
+}
+@mixin gradient-striped($color: rgba(255,255,255,.15), $angle: 45deg) {
+ background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_grid-framework.scss b/templates/assets/bootstrap/scss/mixins/_grid-framework.scss
new file mode 100644
index 0000000..0aa814a
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_grid-framework.scss
@@ -0,0 +1,65 @@
+// Framework grid generation
+//
+// Used only by Bootstrap to generate the correct number of grid classes given
+// any value of `$grid-columns`.
+
+@mixin make-grid-columns($columns: $grid-columns, $gutters: $grid-gutter-widths, $breakpoints: $grid-breakpoints) {
+ // Common properties for all breakpoints
+ %grid-column {
+ position: relative;
+ width: 100%;
+ min-height: 1px; // Prevent columns from collapsing when empty
+
+ @include make-gutters($gutters);
+ }
+
+ @each $breakpoint in map-keys($breakpoints) {
+ $infix: breakpoint-infix($breakpoint, $breakpoints);
+
+ // Allow columns to stretch full width below their breakpoints
+ @for $i from 1 through $columns {
+ .col#{$infix}-#{$i} {
+ @extend %grid-column;
+ }
+ }
+ .col#{$infix} {
+ @extend %grid-column;
+ }
+
+ @include media-breakpoint-up($breakpoint, $breakpoints) {
+ // Provide basic `.col-{bp}` classes for equal-width flexbox columns
+ .col#{$infix} {
+ flex-basis: 0;
+ flex-grow: 1;
+ max-width: 100%;
+ }
+ .col#{$infix}-auto {
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ @for $i from 1 through $columns {
+ .col#{$infix}-#{$i} {
+ @include make-col($i, $columns);
+ }
+ }
+
+ @each $modifier in (pull, push) {
+ @for $i from 0 through $columns {
+ .#{$modifier}#{$infix}-#{$i} {
+ @include make-col-modifier($modifier, $i, $columns)
+ }
+ }
+ }
+
+ // `$columns - 1` because offsetting by the width of an entire row isn't possible
+ @for $i from 0 through ($columns - 1) {
+ @if not ($infix == "" and $i == 0) { // Avoid emitting useless .offset-xs-0
+ .offset#{$infix}-#{$i} {
+ @include make-col-modifier(offset, $i, $columns)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_grid.scss b/templates/assets/bootstrap/scss/mixins/_grid.scss
new file mode 100644
index 0000000..eb6c012
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_grid.scss
@@ -0,0 +1,100 @@
+/// Grid system
+//
+// Generate semantic grid columns with these mixins.
+
+@mixin make-container($gutters: $grid-gutter-widths) {
+ position: relative;
+ margin-right: auto;
+ margin-left: auto;
+
+ @each $breakpoint in map-keys($gutters) {
+ @include media-breakpoint-up($breakpoint) {
+ $gutter: map-get($gutters, $breakpoint);
+ padding-right: ($gutter / 2);
+ padding-left: ($gutter / 2);
+ }
+ }
+}
+
+
+// For each breakpoint, define the maximum width of the container in a media query
+@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {
+ @each $breakpoint, $container-max-width in $max-widths {
+ @include media-breakpoint-up($breakpoint, $breakpoints) {
+ width: $container-max-width;
+ max-width: 100%;
+ }
+ }
+}
+
+@mixin make-gutters($gutters: $grid-gutter-widths) {
+ @each $breakpoint in map-keys($gutters) {
+ @include media-breakpoint-up($breakpoint) {
+ $gutter: map-get($gutters, $breakpoint);
+ padding-right: ($gutter / 2);
+ padding-left: ($gutter / 2);
+ }
+ }
+}
+
+@mixin make-row($gutters: $grid-gutter-widths) {
+ display: flex;
+ flex-wrap: wrap;
+
+ @each $breakpoint in map-keys($gutters) {
+ @include media-breakpoint-up($breakpoint) {
+ $gutter: map-get($gutters, $breakpoint);
+ margin-right: ($gutter / -2);
+ margin-left: ($gutter / -2);
+ }
+ }
+}
+
+@mixin make-col-ready($gutters: $grid-gutter-widths) {
+ position: relative;
+ // Prevent columns from becoming too narrow when at smaller grid tiers by
+ // always setting `width: 100%;`. This works because we use `flex` values
+ // later on to override this initial width.
+ width: 100%;
+ min-height: 1px; // Prevent collapsing
+
+ @each $breakpoint in map-keys($gutters) {
+ @include media-breakpoint-up($breakpoint) {
+ $gutter: map-get($gutters, $breakpoint);
+ padding-right: ($gutter / 2);
+ padding-left: ($gutter / 2);
+ }
+ }
+}
+
+@mixin make-col($size, $columns: $grid-columns) {
+ flex: 0 0 percentage($size / $columns);
+ // width: percentage($size / $columns);
+ // Add a `max-width` to ensure content within each column does not blow out
+ // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari
+ // do not appear to require this.
+ max-width: percentage($size / $columns);
+}
+
+@mixin make-col-offset($size, $columns: $grid-columns) {
+ margin-left: percentage($size / $columns);
+}
+
+@mixin make-col-push($size, $columns: $grid-columns) {
+ left: if($size > 0, percentage($size / $columns), auto);
+}
+
+@mixin make-col-pull($size, $columns: $grid-columns) {
+ right: if($size > 0, percentage($size / $columns), auto);
+}
+
+@mixin make-col-modifier($type, $size, $columns) {
+ // Work around the lack of dynamic mixin @include support (https://github.com/sass/sass/issues/626)
+ @if $type == push {
+ @include make-col-push($size, $columns);
+ } @else if $type == pull {
+ @include make-col-pull($size, $columns);
+ } @else if $type == offset {
+ @include make-col-offset($size, $columns);
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_hover.scss b/templates/assets/bootstrap/scss/mixins/_hover.scss
new file mode 100644
index 0000000..4aa4b1d
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_hover.scss
@@ -0,0 +1,60 @@
+@mixin hover {
+ // TODO: re-enable along with mq4-hover-shim
+// @if $enable-hover-media-query {
+// // See Media Queries Level 4: https://drafts.csswg.org/mediaqueries/#hover
+// // Currently shimmed by https://github.com/twbs/mq4-hover-shim
+// @media (hover: hover) {
+// &:hover { @content }
+// }
+// }
+// @else {
+// scss-lint:disable Indentation
+ &:hover { @content }
+// scss-lint:enable Indentation
+// }
+}
+
+
+@mixin hover-focus {
+ @if $enable-hover-media-query {
+ &:focus { @content }
+ @include hover { @content }
+ } @else {
+ &:focus,
+ &:hover {
+ @content
+ }
+ }
+}
+
+@mixin plain-hover-focus {
+ @if $enable-hover-media-query {
+ &,
+ &:focus {
+ @content
+ }
+ @include hover { @content }
+ } @else {
+ &,
+ &:focus,
+ &:hover {
+ @content
+ }
+ }
+}
+
+@mixin hover-focus-active {
+ @if $enable-hover-media-query {
+ &:focus,
+ &:active {
+ @content
+ }
+ @include hover { @content }
+ } @else {
+ &:focus,
+ &:active,
+ &:hover {
+ @content
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_image.scss b/templates/assets/bootstrap/scss/mixins/_image.scss
new file mode 100644
index 0000000..c2b45f2
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_image.scss
@@ -0,0 +1,36 @@
+// Image Mixins
+// - Responsive image
+// - Retina image
+
+
+// Responsive image
+//
+// Keep images from scaling beyond the width of their parents.
+
+@mixin img-fluid {
+ // Part 1: Set a maximum relative to the parent
+ max-width: 100%;
+ // Part 2: Override the height to auto, otherwise images will be stretched
+ // when setting a width and height attribute on the img element.
+ height: auto;
+}
+
+
+// Retina image
+//
+// Short retina mixin for setting background-image and -size.
+
+@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {
+ background-image: url($file-1x);
+
+ // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,
+ // but doesn't convert dppx=>dpi.
+ // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.
+ // Compatibility info: http://caniuse.com/#feat=css-media-resolution
+ @media
+ only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx
+ only screen and (min-resolution: 2dppx) { // Standardized
+ background-image: url($file-2x);
+ background-size: $width-1x $height-1x;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_list-group.scss b/templates/assets/bootstrap/scss/mixins/_list-group.scss
new file mode 100644
index 0000000..ba27b50
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_list-group.scss
@@ -0,0 +1,26 @@
+// List Groups
+
+@mixin list-group-item-variant($state, $background, $color) {
+ .list-group-item-#{$state} {
+ color: $color;
+ background-color: $background;
+ }
+
+ //scss-lint:disable QualifyingElement
+ a.list-group-item-#{$state},
+ button.list-group-item-#{$state} {
+ color: $color;
+
+ @include hover-focus {
+ color: $color;
+ background-color: darken($background, 5%);
+ }
+
+ &.active {
+ color: #fff;
+ background-color: $color;
+ border-color: $color;
+ }
+ }
+ // scss-lint:enable QualifyingElement
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_lists.scss b/templates/assets/bootstrap/scss/mixins/_lists.scss
new file mode 100644
index 0000000..2518562
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_lists.scss
@@ -0,0 +1,7 @@
+// Lists
+
+// Unstyled keeps list items block level, just removes default browser padding and list-style
+@mixin list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_nav-divider.scss b/templates/assets/bootstrap/scss/mixins/_nav-divider.scss
new file mode 100644
index 0000000..557673c
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_nav-divider.scss
@@ -0,0 +1,10 @@
+// Horizontal dividers
+//
+// Dividers (basically an hr) within dropdowns and nav lists
+
+@mixin nav-divider($color: #e5e5e5) {
+ height: 1px;
+ margin: ($spacer / 2) 0;
+ overflow: hidden;
+ background-color: $color;
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_navbar-align.scss b/templates/assets/bootstrap/scss/mixins/_navbar-align.scss
new file mode 100644
index 0000000..c454a4f
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_navbar-align.scss
@@ -0,0 +1,9 @@
+// Navbar vertical align
+//
+// Vertically center elements in the navbar.
+// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
+
+// @mixin navbar-vertical-align($element-height) {
+// margin-top: (($navbar-height - $element-height) / 2);
+// margin-bottom: (($navbar-height - $element-height) / 2);
+// }
diff --git a/templates/assets/bootstrap/scss/mixins/_pagination.scss b/templates/assets/bootstrap/scss/mixins/_pagination.scss
new file mode 100644
index 0000000..8cd9317
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_pagination.scss
@@ -0,0 +1,21 @@
+// Pagination
+
+@mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
+ .page-link {
+ padding: $padding-y $padding-x;
+ font-size: $font-size;
+ }
+
+ .page-item {
+ &:first-child {
+ .page-link {
+ @include border-left-radius($border-radius);
+ }
+ }
+ &:last-child {
+ .page-link {
+ @include border-right-radius($border-radius);
+ }
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_reset-text.scss b/templates/assets/bootstrap/scss/mixins/_reset-text.scss
new file mode 100644
index 0000000..4cf9e79
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_reset-text.scss
@@ -0,0 +1,18 @@
+// scss-lint:disable DuplicateProperty
+@mixin reset-text {
+ font-family: $font-family-base;
+ // We deliberately do NOT reset font-size or word-wrap.
+ font-style: normal;
+ font-weight: $font-weight-normal;
+ line-height: $line-height-base;
+ text-align: left; // Fallback for where `start` is not supported
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ white-space: normal;
+ line-break: auto;
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_resize.scss b/templates/assets/bootstrap/scss/mixins/_resize.scss
new file mode 100644
index 0000000..66f233a
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_resize.scss
@@ -0,0 +1,6 @@
+// Resize anything
+
+@mixin resizable($direction) {
+ overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
+ resize: $direction; // Options: horizontal, vertical, both
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_screen-reader.scss b/templates/assets/bootstrap/scss/mixins/_screen-reader.scss
new file mode 100644
index 0000000..a5fa51c
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_screen-reader.scss
@@ -0,0 +1,35 @@
+// Only display content to screen readers
+//
+// See: http://a11yproject.com/posts/how-to-hide-content
+// See: http://hugogiraudel.com/2016/10/13/css-hide-and-seek/
+
+@mixin sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ overflow: hidden;
+ clip: rect(0,0,0,0);
+ white-space: nowrap;
+ clip-path: inset(50%);
+ border: 0;
+}
+
+// Use in conjunction with .sr-only to only display content when it's focused.
+//
+// Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
+//
+// Credit: HTML5 Boilerplate
+
+@mixin sr-only-focusable {
+ &:active,
+ &:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ overflow: visible;
+ clip: auto;
+ white-space: normal;
+ clip-path: none;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_size.scss b/templates/assets/bootstrap/scss/mixins/_size.scss
new file mode 100644
index 0000000..b9dd48e
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_size.scss
@@ -0,0 +1,6 @@
+// Sizing shortcuts
+
+@mixin size($width, $height: $width) {
+ width: $width;
+ height: $height;
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_table-row.scss b/templates/assets/bootstrap/scss/mixins/_table-row.scss
new file mode 100644
index 0000000..84f1d30
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_table-row.scss
@@ -0,0 +1,30 @@
+// Tables
+
+@mixin table-row-variant($state, $background) {
+ // Exact selectors below required to override `.table-striped` and prevent
+ // inheritance to nested tables.
+ .table-#{$state} {
+ &,
+ > th,
+ > td {
+ background-color: $background;
+ }
+ }
+
+ // Hover states for `.table-hover`
+ // Note: this is not available for cells or rows within `thead` or `tfoot`.
+ .table-hover {
+ $hover-background: darken($background, 5%);
+
+ .table-#{$state} {
+ @include hover {
+ background-color: $hover-background;
+
+ > td,
+ > th {
+ background-color: $hover-background;
+ }
+ }
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_text-emphasis.scss b/templates/assets/bootstrap/scss/mixins/_text-emphasis.scss
new file mode 100644
index 0000000..9cd4b6a
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_text-emphasis.scss
@@ -0,0 +1,12 @@
+// Typography
+
+@mixin text-emphasis-variant($parent, $color) {
+ #{$parent} {
+ color: $color !important;
+ }
+ a#{$parent} {
+ @include hover-focus {
+ color: darken($color, 10%) !important;
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_text-hide.scss b/templates/assets/bootstrap/scss/mixins/_text-hide.scss
new file mode 100644
index 0000000..52a38a9
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_text-hide.scss
@@ -0,0 +1,8 @@
+// CSS image replacement
+@mixin text-hide() {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_text-truncate.scss b/templates/assets/bootstrap/scss/mixins/_text-truncate.scss
new file mode 100644
index 0000000..3504bb1
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_text-truncate.scss
@@ -0,0 +1,8 @@
+// Text truncate
+// Requires inline-block or block for proper styling
+
+@mixin text-truncate() {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_transforms.scss b/templates/assets/bootstrap/scss/mixins/_transforms.scss
new file mode 100644
index 0000000..4005c9d
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_transforms.scss
@@ -0,0 +1,14 @@
+// Applies the given styles only when the browser support CSS3 3D transforms.
+@mixin if-supports-3d-transforms() {
+ @media (-webkit-transform-3d) {
+ // Old Safari, Old Android
+ // http://caniuse.com/#feat=css-featurequeries
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/@media/-webkit-transform-3d
+ @content;
+ }
+
+ @supports (transform: translate3d(0,0,0)) {
+ // The Proper Way: Using a CSS feature query
+ @content;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_transition.scss b/templates/assets/bootstrap/scss/mixins/_transition.scss
new file mode 100644
index 0000000..7e33dee
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_transition.scss
@@ -0,0 +1,9 @@
+@mixin transition($transition...) {
+ @if $enable-transitions {
+ @if length($transition) == 0 {
+ transition: $transition-base;
+ } @else {
+ transition: $transition;
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/mixins/_visibility.scss b/templates/assets/bootstrap/scss/mixins/_visibility.scss
new file mode 100644
index 0000000..f67fc1c
--- /dev/null
+++ b/templates/assets/bootstrap/scss/mixins/_visibility.scss
@@ -0,0 +1,5 @@
+// Visibility
+
+@mixin invisible($visibility) {
+ visibility: $visibility !important;
+}
diff --git a/templates/assets/bootstrap/scss/utilities/_align.scss b/templates/assets/bootstrap/scss/utilities/_align.scss
new file mode 100644
index 0000000..4dbbbc2
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_align.scss
@@ -0,0 +1,6 @@
+.align-baseline { vertical-align: baseline !important; } // Browser default
+.align-top { vertical-align: top !important; }
+.align-middle { vertical-align: middle !important; }
+.align-bottom { vertical-align: bottom !important; }
+.align-text-bottom { vertical-align: text-bottom !important; }
+.align-text-top { vertical-align: text-top !important; }
diff --git a/templates/assets/bootstrap/scss/utilities/_background.scss b/templates/assets/bootstrap/scss/utilities/_background.scss
new file mode 100644
index 0000000..b9ac295
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_background.scss
@@ -0,0 +1,19 @@
+//
+// Contextual backgrounds
+//
+
+.bg-faded {
+ background-color: darken($body-bg, 3%);
+}
+
+@include bg-variant('.bg-primary', $brand-primary);
+
+@include bg-variant('.bg-success', $brand-success);
+
+@include bg-variant('.bg-info', $brand-info);
+
+@include bg-variant('.bg-warning', $brand-warning);
+
+@include bg-variant('.bg-danger', $brand-danger);
+
+@include bg-variant('.bg-inverse', $brand-inverse);
diff --git a/templates/assets/bootstrap/scss/utilities/_borders.scss b/templates/assets/bootstrap/scss/utilities/_borders.scss
new file mode 100644
index 0000000..b256881
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_borders.scss
@@ -0,0 +1,37 @@
+//
+// Border
+//
+
+.border-0 { border: 0 !important; }
+.border-top-0 { border-top: 0 !important; }
+.border-right-0 { border-right: 0 !important; }
+.border-bottom-0 { border-bottom: 0 !important; }
+.border-left-0 { border-left: 0 !important; }
+
+//
+// Border-radius
+//
+
+.rounded {
+ @include border-radius($border-radius);
+}
+.rounded-top {
+ @include border-top-radius($border-radius);
+}
+.rounded-right {
+ @include border-right-radius($border-radius);
+}
+.rounded-bottom {
+ @include border-bottom-radius($border-radius);
+}
+.rounded-left {
+ @include border-left-radius($border-radius);
+}
+
+.rounded-circle {
+ border-radius: 50%;
+}
+
+.rounded-0 {
+ border-radius: 0;
+}
diff --git a/templates/assets/bootstrap/scss/utilities/_clearfix.scss b/templates/assets/bootstrap/scss/utilities/_clearfix.scss
new file mode 100644
index 0000000..e92522a
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_clearfix.scss
@@ -0,0 +1,3 @@
+.clearfix {
+ @include clearfix();
+}
diff --git a/templates/assets/bootstrap/scss/utilities/_display.scss b/templates/assets/bootstrap/scss/utilities/_display.scss
new file mode 100644
index 0000000..4535362
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_display.scss
@@ -0,0 +1,53 @@
+//
+// Utilities for common `display` values
+//
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .d#{$infix}-none { display: none !important; }
+ .d#{$infix}-inline { display: inline !important; }
+ .d#{$infix}-inline-block { display: inline-block !important; }
+ .d#{$infix}-block { display: block !important; }
+ .d#{$infix}-table { display: table !important; }
+ .d#{$infix}-table-cell { display: table-cell !important; }
+ .d#{$infix}-flex { display: flex !important; }
+ .d#{$infix}-inline-flex { display: inline-flex !important; }
+ }
+}
+
+
+//
+// Utilities for toggling `display` in print
+//
+
+.d-print-block {
+ display: none !important;
+
+ @media print {
+ display: block !important;
+ }
+}
+
+.d-print-inline {
+ display: none !important;
+
+ @media print {
+ display: inline !important;
+ }
+}
+
+.d-print-inline-block {
+ display: none !important;
+
+ @media print {
+ display: inline-block !important;
+ }
+}
+
+.d-print-none {
+ @media print {
+ display: none !important;
+ }
+}
diff --git a/templates/assets/bootstrap/scss/utilities/_flex.scss b/templates/assets/bootstrap/scss/utilities/_flex.scss
new file mode 100644
index 0000000..cc69678
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_flex.scss
@@ -0,0 +1,48 @@
+// Flex variation
+//
+// Custom styles for additional flex alignment options.
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .order#{$infix}-first { order: -1; }
+ .order#{$infix}-last { order: 1; }
+ .order#{$infix}-0 { order: 0; }
+
+ .flex#{$infix}-row { flex-direction: row !important; }
+ .flex#{$infix}-column { flex-direction: column !important; }
+ .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }
+ .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }
+
+ .flex#{$infix}-wrap { flex-wrap: wrap !important; }
+ .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }
+ .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }
+
+ .justify-content#{$infix}-start { justify-content: flex-start !important; }
+ .justify-content#{$infix}-end { justify-content: flex-end !important; }
+ .justify-content#{$infix}-center { justify-content: center !important; }
+ .justify-content#{$infix}-between { justify-content: space-between !important; }
+ .justify-content#{$infix}-around { justify-content: space-around !important; }
+
+ .align-items#{$infix}-start { align-items: flex-start !important; }
+ .align-items#{$infix}-end { align-items: flex-end !important; }
+ .align-items#{$infix}-center { align-items: center !important; }
+ .align-items#{$infix}-baseline { align-items: baseline !important; }
+ .align-items#{$infix}-stretch { align-items: stretch !important; }
+
+ .align-content#{$infix}-start { align-content: flex-start !important; }
+ .align-content#{$infix}-end { align-content: flex-end !important; }
+ .align-content#{$infix}-center { align-content: center !important; }
+ .align-content#{$infix}-between { align-content: space-between !important; }
+ .align-content#{$infix}-around { align-content: space-around !important; }
+ .align-content#{$infix}-stretch { align-content: stretch !important; }
+
+ .align-self#{$infix}-auto { align-self: auto !important; }
+ .align-self#{$infix}-start { align-self: flex-start !important; }
+ .align-self#{$infix}-end { align-self: flex-end !important; }
+ .align-self#{$infix}-center { align-self: center !important; }
+ .align-self#{$infix}-baseline { align-self: baseline !important; }
+ .align-self#{$infix}-stretch { align-self: stretch !important; }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/utilities/_float.scss b/templates/assets/bootstrap/scss/utilities/_float.scss
new file mode 100644
index 0000000..01655e9
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_float.scss
@@ -0,0 +1,9 @@
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .float#{$infix}-left { @include float-left; }
+ .float#{$infix}-right { @include float-right; }
+ .float#{$infix}-none { @include float-none; }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/utilities/_position.scss b/templates/assets/bootstrap/scss/utilities/_position.scss
new file mode 100644
index 0000000..2cf08bf
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_position.scss
@@ -0,0 +1,23 @@
+// Positioning
+
+.fixed-top {
+ position: fixed;
+ top: 0;
+ right: 0;
+ left: 0;
+ z-index: $zindex-fixed;
+}
+
+.fixed-bottom {
+ position: fixed;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $zindex-fixed;
+}
+
+.sticky-top {
+ position: sticky;
+ top: 0;
+ z-index: $zindex-sticky;
+}
diff --git a/templates/assets/bootstrap/scss/utilities/_screenreaders.scss b/templates/assets/bootstrap/scss/utilities/_screenreaders.scss
new file mode 100644
index 0000000..9f26fde
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_screenreaders.scss
@@ -0,0 +1,11 @@
+//
+// Screenreaders
+//
+
+.sr-only {
+ @include sr-only();
+}
+
+.sr-only-focusable {
+ @include sr-only-focusable();
+}
diff --git a/templates/assets/bootstrap/scss/utilities/_sizing.scss b/templates/assets/bootstrap/scss/utilities/_sizing.scss
new file mode 100644
index 0000000..a7dc3e4
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_sizing.scss
@@ -0,0 +1,10 @@
+// Width and height
+
+@each $prop, $abbrev in (width: w, height: h) {
+ @each $size, $length in $sizes {
+ .#{$abbrev}-#{$size} { #{$prop}: $length !important; }
+ }
+}
+
+.mw-100 { max-width: 100% !important; }
+.mh-100 { max-height: 100% !important; }
diff --git a/templates/assets/bootstrap/scss/utilities/_spacing.scss b/templates/assets/bootstrap/scss/utilities/_spacing.scss
new file mode 100644
index 0000000..c89816b
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_spacing.scss
@@ -0,0 +1,41 @@
+// Margin and Padding
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ @each $prop, $abbrev in (margin: m, padding: p) {
+ @each $size, $length in $spacers {
+
+ .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }
+ .#{$abbrev}t#{$infix}-#{$size} { #{$prop}-top: $length !important; }
+ .#{$abbrev}r#{$infix}-#{$size} { #{$prop}-right: $length !important; }
+ .#{$abbrev}b#{$infix}-#{$size} { #{$prop}-bottom: $length !important; }
+ .#{$abbrev}l#{$infix}-#{$size} { #{$prop}-left: $length !important; }
+ .#{$abbrev}x#{$infix}-#{$size} {
+ #{$prop}-right: $length !important;
+ #{$prop}-left: $length !important;
+ }
+ .#{$abbrev}y#{$infix}-#{$size} {
+ #{$prop}-top: $length !important;
+ #{$prop}-bottom: $length !important;
+ }
+ }
+ }
+
+ // Some special margin utils
+ .m#{$infix}-auto { margin: auto !important; }
+ .mt#{$infix}-auto { margin-top: auto !important; }
+ .mr#{$infix}-auto { margin-right: auto !important; }
+ .mb#{$infix}-auto { margin-bottom: auto !important; }
+ .ml#{$infix}-auto { margin-left: auto !important; }
+ .mx#{$infix}-auto {
+ margin-right: auto !important;
+ margin-left: auto !important;
+ }
+ .my#{$infix}-auto {
+ margin-top: auto !important;
+ margin-bottom: auto !important;
+ }
+ }
+}
diff --git a/templates/assets/bootstrap/scss/utilities/_text.scss b/templates/assets/bootstrap/scss/utilities/_text.scss
new file mode 100644
index 0000000..4ac9053
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_text.scss
@@ -0,0 +1,61 @@
+//
+// Text
+//
+
+// Alignment
+
+.text-justify { text-align: justify !important; }
+.text-nowrap { white-space: nowrap !important; }
+.text-truncate { @include text-truncate; }
+
+// Responsive alignment
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .text#{$infix}-left { text-align: left !important; }
+ .text#{$infix}-right { text-align: right !important; }
+ .text#{$infix}-center { text-align: center !important; }
+ }
+}
+
+// Transformation
+
+.text-lowercase { text-transform: lowercase !important; }
+.text-uppercase { text-transform: uppercase !important; }
+.text-capitalize { text-transform: capitalize !important; }
+
+// Weight and italics
+
+.font-weight-normal { font-weight: $font-weight-normal; }
+.font-weight-bold { font-weight: $font-weight-bold; }
+.font-italic { font-style: italic; }
+
+// Contextual colors
+
+.text-white {
+ color: #fff !important;
+}
+
+@include text-emphasis-variant('.text-muted', $text-muted);
+
+@include text-emphasis-variant('.text-primary', $brand-primary);
+
+@include text-emphasis-variant('.text-success', $brand-success);
+
+@include text-emphasis-variant('.text-info', $brand-info);
+
+@include text-emphasis-variant('.text-warning', $brand-warning);
+
+@include text-emphasis-variant('.text-danger', $brand-danger);
+
+// Font color
+
+@include text-emphasis-variant('.text-gray-dark', $gray-dark);
+
+// Misc
+
+.text-hide {
+ @include text-hide();
+}
diff --git a/templates/assets/bootstrap/scss/utilities/_visibility.scss b/templates/assets/bootstrap/scss/utilities/_visibility.scss
new file mode 100644
index 0000000..823406d
--- /dev/null
+++ b/templates/assets/bootstrap/scss/utilities/_visibility.scss
@@ -0,0 +1,11 @@
+//
+// Visibility utilities
+//
+
+.visible {
+ @include invisible(visible);
+}
+
+.invisible {
+ @include invisible(hidden);
+}