diff --git a/Gruntfile.js b/Gruntfile.js
index f3c3af8f8eb7ad882326c68312cee3d83da43cd5..98cc655f9a7771d5d3502f2c3452ca2d24f47d89 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -56,27 +56,64 @@ module.exports = function (grunt) {
       docs: 'docs/dist'
     },
 
-    jshint: {
-      options: {
-        jshintrc: 'js/.jshintrc'
-      },
-      grunt: {
+    // JS build configuration
+
+    lineremover: {
+      es6Import: {
+        files: {
+          '<%= concat.bootstrap.dest %>': '<%= concat.bootstrap.dest %>'
+        },
+        options: {
+          exclusionPattern: /^(import|export)/g
+        }
+      }
+    },
+
+    babel: {
+      dev: {
         options: {
-          jshintrc: 'grunt/.jshintrc'
+          sourceMap: true,
+          modules: 'ignore'
         },
-        src: ['Gruntfile.js', 'grunt/*.js']
-      },
-      core: {
-        src: 'js/*.js'
+        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'
+        }
       },
-      test: {
+      dist: {
         options: {
-          jshintrc: 'js/tests/unit/.jshintrc'
+          modules: 'ignore'
         },
-        src: 'js/tests/unit/*.js'
+        files: {
+          '<%= concat.bootstrap.dest %>' : '<%= concat.bootstrap.dest %>'
+        }
       },
-      assets: {
-        src: ['docs/assets/js/src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js']
+      umd: {
+        options: {
+          modules: 'umd'
+        },
+        files: {
+          'dist/js/umd/util.js'      : 'js/src/util.js',
+          'dist/js/umd/alert.js'     : 'js/src/alert.js',
+          'dist/js/umd/button.js'    : 'js/src/button.js',
+          'dist/js/umd/carousel.js'  : 'js/src/carousel.js',
+          'dist/js/umd/collapse.js'  : 'js/src/collapse.js',
+          'dist/js/umd/dropdown.js'  : 'js/src/dropdown.js',
+          'dist/js/umd/modal.js'     : 'js/src/modal.js',
+          'dist/js/umd/scrollspy.js' : 'js/src/scrollspy.js',
+          'dist/js/umd/tab.js'       : 'js/src/tab.js',
+          'dist/js/umd/tooltip.js'   : 'js/src/tooltip.js',
+          'dist/js/umd/popover.js'   : 'js/src/popover.js'
+        }
       }
     },
 
@@ -85,41 +122,51 @@ module.exports = function (grunt) {
         config: 'js/.jscsrc'
       },
       grunt: {
-        src: '<%= jshint.grunt.src %>'
+        src: ['Gruntfile.js', 'grunt/*.js']
       },
       core: {
-        src: '<%= jshint.core.src %>'
+        src: 'js/src/*.js'
       },
       test: {
-        src: '<%= jshint.test.src %>'
+        src: 'js/tests/unit/*.js'
       },
       assets: {
         options: {
           requireCamelCaseOrUpperCaseIdentifiers: null
         },
-        src: '<%= jshint.assets.src %>'
+        src: ['docs/assets/js/src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js']
+      }
+    },
+
+    stamp: {
+      options: {
+        banner: '<%= banner %>\n<%= jqueryCheck %>\n<%= jqueryVersionCheck %>\n+function ($) {\n',
+        footer: '\n}(jQuery);'
+      },
+      bootstrap: {
+        files: {
+          src: '<%= concat.bootstrap.dest %>'
+        }
       }
     },
 
     concat: {
       options: {
-        banner: '<%= banner %>\n<%= jqueryCheck %>\n<%= jqueryVersionCheck %>',
         stripBanners: false
       },
       bootstrap: {
         src: [
-          'js/transition.js',
-          'js/alert.js',
-          'js/button.js',
-          'js/carousel.js',
-          'js/collapse.js',
-          'js/dropdown.js',
-          'js/modal.js',
-          'js/tooltip.js',
-          'js/popover.js',
-          'js/scrollspy.js',
-          'js/tab.js',
-          'js/affix.js'
+          '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'
       }
@@ -154,6 +201,9 @@ module.exports = function (grunt) {
       files: 'js/tests/index.html'
     },
 
+
+    // CSS build configuration
+
     scsslint: {
       scss: ['scss/*.scss', '!scss/_normalize.scss'],
       options: {
@@ -301,12 +351,12 @@ module.exports = function (grunt) {
 
     watch: {
       src: {
-        files: '<%= jshint.core.src %>',
-        tasks: ['jshint:core', 'qunit', 'concat']
+        files: '<%= jscs.core.src %>',
+        tasks: ['babel:dev']
       },
       test: {
-        files: '<%= jshint.test.src %>',
-        tasks: ['jshint:test', 'qunit']
+        files: '<%= jscs.test.src %>',
+        tasks: ['qunit']
       },
       sass: {
         files: 'scss/**/*.scss',
@@ -398,10 +448,10 @@ module.exports = function (grunt) {
     testSubtasks.push('saucelabs-qunit');
   }
   grunt.registerTask('test', testSubtasks);
-  grunt.registerTask('test-js', ['jshint:core', 'jshint:test', 'jshint:grunt', 'jscs:core', 'jscs:test', 'jscs:grunt', 'qunit']);
+  grunt.registerTask('test-js', ['jscs:core', 'jscs:test', 'jscs:grunt', 'qunit']);
 
   // JS distribution task.
-  grunt.registerTask('dist-js', ['concat', 'uglify:core', 'commonjs']);
+  grunt.registerTask('dist-js', ['concat', 'lineremover', 'babel:dist', 'stamp', 'uglify:core', 'commonjs']);
 
   grunt.registerTask('test-scss', ['scsslint:scss']);
 
@@ -425,8 +475,12 @@ module.exports = function (grunt) {
   // This can be overzealous, so its changes should always be manually reviewed!
   grunt.registerTask('change-version-number', 'sed');
 
-  grunt.registerTask('commonjs', 'Generate CommonJS entrypoint module in dist dir.', function () {
-    var srcFiles = grunt.config.get('concat.bootstrap.src');
+  grunt.registerTask('commonjs', ['babel:umd', 'npm-js']);
+
+  grunt.registerTask('npm-js', 'Generate npm-js entrypoint module in dist dir.', function () {
+    var srcFiles = Object.keys(grunt.config.get('babel.umd.files')).map(function (filename) {
+      return './' + path.join('umd', path.basename(filename))
+    })
     var destFilepath = 'dist/js/npm.js';
     generateCommonJSModule(grunt, srcFiles, destFilepath);
   });
@@ -434,7 +488,7 @@ module.exports = function (grunt) {
   // Docs task.
   grunt.registerTask('docs-css', ['autoprefixer:docs', 'autoprefixer:examples', 'csscomb:docs', 'csscomb:examples', 'cssmin:docs']);
   grunt.registerTask('docs-js', ['uglify:docsJs']);
-  grunt.registerTask('lint-docs-js', ['jshint:assets', 'jscs:assets']);
+  grunt.registerTask('lint-docs-js', ['jscs:assets']);
   grunt.registerTask('docs', ['docs-css', 'docs-js', 'lint-docs-js', 'clean:docs', 'copy:docs']);
 
   grunt.registerTask('docs-github', ['jekyll:github']);
diff --git a/dist/css/bootstrap.css b/dist/css/bootstrap.css
index acf6ed35f94b3a1718d5ed57170ebcea8c8d7153..f7cabd0e084c9d3ed1a319c94a9e71cb110eb25f 100644
--- a/dist/css/bootstrap.css
+++ b/dist/css/bootstrap.css
@@ -1,402 +1,363 @@
-/*!
- * Bootstrap v4.0.0-alpha (http://getbootstrap.com)
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-
+@charset "UTF-8";
 /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
 html {
   font-family: sans-serif;
-  -webkit-text-size-adjust: 100%; 
-      -ms-text-size-adjust: 100%;
-}
+  -ms-text-size-adjust: 100%;
+  -webkit-text-size-adjust: 100%; }
 
 body {
-  margin: 0;
-}
-
-article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary {
-  display: block;
-}
-
-audio, canvas, progress, video {
+  margin: 0; }
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+  display: block; }
+
+audio,
+canvas,
+progress,
+video {
   display: inline-block;
-  vertical-align: baseline;
-}
+  vertical-align: baseline; }
 
 audio:not([controls]) {
   display: none;
-  height: 0;
-}
+  height: 0; }
 
-[hidden], template {
-  display: none;
-}
+[hidden],
+template {
+  display: none; }
 
 a {
-  background-color: transparent;
-}
+  background-color: transparent; }
 
 a:active {
-  outline: 0;
-}
+  outline: 0; }
+
 a:hover {
-  outline: 0;
-}
+  outline: 0; }
 
 abbr[title] {
-  border-bottom: 1px dotted;
-}
+  border-bottom: 1px dotted; }
 
-b, strong {
-  font-weight: bold;
-}
+b,
+strong {
+  font-weight: bold; }
 
 dfn {
-  font-style: italic;
-}
+  font-style: italic; }
 
 h1 {
-  margin: .67em 0; 
   font-size: 2em;
-}
+  margin: 0.67em 0; }
 
 mark {
-  color: #000; 
   background: #ff0;
-}
+  color: #000; }
 
 small {
-  font-size: 80%;
-}
+  font-size: 80%; }
 
-sub, sup {
-  position: relative;
+sub,
+sup {
   font-size: 75%;
   line-height: 0;
-  vertical-align: baseline;
-}
+  position: relative;
+  vertical-align: baseline; }
 
 sup {
-  top: -.5em;
-}
+  top: -0.5em; }
 
 sub {
-  bottom: -.25em;
-}
+  bottom: -0.25em; }
 
 img {
-  border: 0;
-}
+  border: 0; }
 
 svg:not(:root) {
-  overflow: hidden;
-}
+  overflow: hidden; }
 
 figure {
-  margin: 1em 40px;
-}
+  margin: 1em 40px; }
 
 hr {
-  height: 0; 
-  -webkit-box-sizing: content-box;
-          box-sizing: content-box;
-}
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+  height: 0; }
 
 pre {
-  overflow: auto;
-}
+  overflow: auto; }
 
-code, kbd, pre, samp {
+code,
+kbd,
+pre,
+samp {
   font-family: monospace, monospace;
-  font-size: 1em;
-}
+  font-size: 1em; }
 
-button, input, optgroup, select, textarea {
-  margin: 0; 
-  font: inherit;
+button,
+input,
+optgroup,
+select,
+textarea {
   color: inherit;
-}
+  font: inherit;
+  margin: 0; }
 
 button {
-  overflow: visible;
-}
+  overflow: visible; }
 
-button, select {
-  text-transform: none;
-}
+button,
+select {
+  text-transform: none; }
 
-button, html input[type="button"], input[type="reset"], input[type="submit"] {
+button,
+html input[type="button"], input[type="reset"],
+input[type="submit"] {
   -webkit-appearance: button;
-  cursor: pointer;
-}
+  cursor: pointer; }
 
-button[disabled], html input[disabled] {
-  cursor: default;
-}
+button[disabled],
+html input[disabled] {
+  cursor: default; }
 
-button::-moz-focus-inner, input::-moz-focus-inner {
-  padding: 0; 
+button::-moz-focus-inner,
+input::-moz-focus-inner {
   border: 0;
-}
+  padding: 0; }
 
 input {
-  line-height: normal;
-}
+  line-height: normal; }
 
-input[type="checkbox"], input[type="radio"] {
-  -webkit-box-sizing: border-box;
-          box-sizing: border-box;
-  padding: 0;
-}
+input[type="checkbox"],
+input[type="radio"] {
+  box-sizing: border-box;
+  padding: 0; }
 
-input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button {
-  height: auto;
-}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+  height: auto; }
 
 input[type="search"] {
-  -webkit-box-sizing: content-box;
-          box-sizing: content-box; 
   -webkit-appearance: textfield;
-}
+  -moz-box-sizing: content-box;
+  -webkit-box-sizing: content-box;
+  box-sizing: content-box; }
 
-input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration {
-  -webkit-appearance: none;
-}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none; }
 
 fieldset {
-  padding: .35em .625em .75em; 
-  margin: 0 2px;
   border: 1px solid #c0c0c0;
-}
+  margin: 0 2px;
+  padding: 0.35em 0.625em 0.75em; }
 
 legend {
-  padding: 0; 
   border: 0;
-}
+  padding: 0; }
 
 textarea {
-  overflow: auto;
-}
+  overflow: auto; }
 
 optgroup {
-  font-weight: bold;
-}
+  font-weight: bold; }
 
 table {
-  border-spacing: 0; 
   border-collapse: collapse;
-}
+  border-spacing: 0; }
 
-td, th {
-  padding: 0;
-}
+td,
+th {
+  padding: 0; }
 
 @media print {
-  *, *:before, *:after {
+  *,
+  *:before,
+  *:after {
     text-shadow: none !important;
-    -webkit-box-shadow: none !important;
-            box-shadow: none !important;
-  }
-  a, a:visited {
-    text-decoration: underline;
-  }
+    box-shadow: none !important; }
+  a,
+  a:visited {
+    text-decoration: underline; }
   abbr[title]:after {
-    content: " (" attr(title) ")";
-  }
-  pre, blockquote {
+    content: " (" attr(title) ")"; }
+  pre,
+  blockquote {
     border: 1px solid #999;
-
-    page-break-inside: avoid;
-  }
+    page-break-inside: avoid; }
   thead {
-    display: table-header-group;
-  }
-  tr, img {
-    page-break-inside: avoid;
-  }
+    display: table-header-group; }
+  tr,
+  img {
+    page-break-inside: avoid; }
   img {
-    max-width: 100% !important;
-  }
-  p, h2, h3 {
+    max-width: 100% !important; }
+  p,
+  h2,
+  h3 {
     orphans: 3;
-    widows: 3;
-  }
-  h2, h3 {
-    page-break-after: avoid;
-  }
+    widows: 3; }
+  h2,
+  h3 {
+    page-break-after: avoid; }
   .navbar {
-    display: none;
-  }
-  .btn > .caret, .dropup > .btn > .caret {
-    border-top-color: #000 !important;
-  }
+    display: none; }
+  .btn > .caret,
+  .dropup > .btn > .caret {
+    border-top-color: #000 !important; }
   .label {
-    border: 1px solid #000;
-  }
+    border: 1px solid #000; }
   .table {
-    border-collapse: collapse !important;
-  }
-  .table td, .table th {
-    background-color: #fff !important;
-  }
-  .table-bordered th, .table-bordered td {
-    border: 1px solid #ddd !important;
-  }
-}
+    border-collapse: collapse !important; }
+    .table td,
+    .table th {
+      background-color: #fff !important; }
+  .table-bordered th,
+  .table-bordered td {
+    border: 1px solid #ddd !important; } }
 
 html {
-  -webkit-box-sizing: border-box;
-          box-sizing: border-box;
-}
+  box-sizing: border-box; }
+
+*,
+*:before,
+*:after {
+  box-sizing: inherit; }
 
-*, *:before, *:after {
-  -webkit-box-sizing: inherit;
-          box-sizing: inherit;
-}
+@-moz-viewport {
+  width: device-width; }
 
-@at-root {
-  @-moz-viewport {
-    width: device-width;
-  }
+@-ms-viewport {
+  width: device-width; }
 
-  @-ms-viewport {
-    width: device-width;
-  }
+@-o-viewport {
+  width: device-width; }
 
-  @-webkit-viewport {
-    width: device-width;
-  }
+@-webkit-viewport {
+  width: device-width; }
 
-  @viewport {
-    width: device-width;
-  }
-}
+@viewport {
+  width: device-width; }
 
 html {
   font-size: 16px;
-
-  -webkit-tap-highlight-color: transparent;
-}
+  -webkit-tap-highlight-color: transparent; }
 
 body {
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
   font-size: 1rem;
   line-height: 1.5;
   color: #373a3c;
-  background-color: #fff;
-}
+  background-color: #fff; }
 
 h1, h2, h3, h4, h5, h6 {
   margin-top: 0;
-  margin-bottom: .5rem;
-}
+  margin-bottom: .5rem; }
 
 p {
   margin-top: 0;
-  margin-bottom: 1rem;
-}
+  margin-bottom: 1rem; }
 
-abbr[title], abbr[data-original-title] {
+abbr[title],
+abbr[data-original-title] {
   cursor: help;
-  border-bottom: 1px dotted #818a91;
-}
+  border-bottom: 1px dotted #818a91; }
 
 address {
   margin-bottom: 1rem;
   font-style: normal;
-  line-height: inherit;
-}
+  line-height: inherit; }
 
-ol, ul, dl {
+ol,
+ul,
+dl {
   margin-top: 0;
-  margin-bottom: 1rem;
-}
+  margin-bottom: 1rem; }
 
-ol ol, ul ul, ol ul, ul ol {
-  margin-bottom: 0;
-}
+ol ol,
+ul ul,
+ol ul,
+ul ol {
+  margin-bottom: 0; }
 
 dt {
-  font-weight: bold;
-}
+  font-weight: bold; }
 
 dd {
-  margin-bottom: .5rem; 
   margin-left: 0;
-}
+  margin-bottom: .5rem; }
 
 blockquote {
-  margin: 0 0 1rem;
-}
+  margin: 0 0 1rem; }
 
 a {
   color: #0275d8;
-  text-decoration: none;
-}
-a:focus, a:hover {
-  color: #014c8c;
-  text-decoration: underline;
-}
-a:focus {
-  outline: thin dotted;
-  outline: 5px auto -webkit-focus-ring-color;
-  outline-offset: -2px;
-}
+  text-decoration: none; }
+  a:focus,
+  a:hover {
+    color: #014c8c;
+    text-decoration: underline; }
+  a:focus {
+    outline: thin dotted;
+    outline: 5px auto -webkit-focus-ring-color;
+    outline-offset: -2px; }
 
 pre {
   margin-top: 0;
-  margin-bottom: 1rem;
-}
+  margin-bottom: 1rem; }
 
 figure {
-  margin: 0 0 1rem;
-}
+  margin: 0 0 1rem; }
 
 img {
-  vertical-align: middle;
-}
+  vertical-align: middle; }
 
 [role="button"] {
-  cursor: pointer;
-}
+  cursor: pointer; }
 
 table {
-  background-color: transparent;
-}
+  background-color: transparent; }
 
 caption {
-  padding-top: .75rem;
-  padding-bottom: .75rem;
-  color: #818a91;
-  text-align: left; 
   caption-side: bottom;
-}
+  padding-top: 0.75rem;
+  padding-bottom: 0.75rem;
+  color: #818a91;
+  text-align: left; }
 
 th {
-  text-align: left;
-}
+  text-align: left; }
 
 label {
   display: inline-block;
-  margin-bottom: .5rem;
-}
+  margin-bottom: .5rem; }
 
-input, button, select, textarea {
+input,
+button,
+select,
+textarea {
   margin: 0;
-  line-height: inherit;
-}
+  line-height: inherit; }
 
 textarea {
-  resize: vertical;
-}
+  resize: vertical; }
 
 fieldset {
-  min-width: 0; 
   padding: 0;
   margin: 0;
   border: 0;
-}
+  min-width: 0; }
 
 legend {
   display: block;
@@ -404,206 +365,206 @@ legend {
   padding: 0;
   margin-bottom: .5rem;
   font-size: 1.5rem;
-  line-height: inherit;
-}
+  line-height: inherit; }
 
 input[type="search"] {
-  -webkit-appearance: none;
-}
+  -webkit-appearance: none; }
 
 output {
-  display: inline-block;
-}
+  display: inline-block; }
 
-h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
+h1, h2, h3, h4, h5, h6,
+.h1, .h2, .h3, .h4, .h5, .h6 {
   font-family: inherit;
   font-weight: 500;
   line-height: 1.1;
-  color: inherit;
-}
-h1 small, h1 .small, h2 small, h2 .small, h3 small, h3 .small, h4 small, h4 .small, h5 small, h5 .small, h6 small, h6 .small, .h1 small, .h1 .small, .h2 small, .h2 .small, .h3 small, .h3 .small, .h4 small, .h4 .small, .h5 small, .h5 .small, .h6 small, .h6 .small {
-  font-weight: normal;
-  line-height: 1;
-  color: #818a91;
-}
-
-h1, .h1, h2, .h2, h3, .h3 {
-  margin-bottom: .5rem;
-}
-h1 small, h1 .small, .h1 small, .h1 .small, h2 small, h2 .small, .h2 small, .h2 .small, h3 small, h3 .small, .h3 small, .h3 .small {
-  font-size: 65%;
-}
-
-h4, .h4, h5, .h5, h6, .h6 {
-  margin-bottom: .5rem;
-}
-h4 small, h4 .small, .h4 small, .h4 .small, h5 small, h5 .small, .h5 small, .h5 .small, h6 small, h6 .small, .h6 small, .h6 .small {
-  font-size: 75%;
-}
+  color: inherit; }
+  h1 small,
+  h1 .small, h2 small,
+  h2 .small, h3 small,
+  h3 .small, h4 small,
+  h4 .small, h5 small,
+  h5 .small, h6 small,
+  h6 .small,
+  .h1 small,
+  .h1 .small, .h2 small,
+  .h2 .small, .h3 small,
+  .h3 .small, .h4 small,
+  .h4 .small, .h5 small,
+  .h5 .small, .h6 small,
+  .h6 .small {
+    font-weight: normal;
+    line-height: 1;
+    color: #818a91; }
+
+h1, .h1,
+h2, .h2,
+h3, .h3 {
+  margin-bottom: 0.5rem; }
+  h1 small,
+  h1 .small, .h1 small,
+  .h1 .small,
+  h2 small,
+  h2 .small, .h2 small,
+  .h2 .small,
+  h3 small,
+  h3 .small, .h3 small,
+  .h3 .small {
+    font-size: 65%; }
+
+h4, .h4,
+h5, .h5,
+h6, .h6 {
+  margin-bottom: 0.5rem; }
+  h4 small,
+  h4 .small, .h4 small,
+  .h4 .small,
+  h5 small,
+  h5 .small, .h5 small,
+  .h5 .small,
+  h6 small,
+  h6 .small, .h6 small,
+  .h6 .small {
+    font-size: 75%; }
 
 h1, .h1 {
-  font-size: 2.75rem;
-}
+  font-size: 2.75rem; }
 
 h2, .h2 {
-  font-size: 2.25rem;
-}
+  font-size: 2.25rem; }
 
 h3, .h3 {
-  font-size: 1.75rem;
-}
+  font-size: 1.75rem; }
 
 h4, .h4 {
-  font-size: 1.5rem;
-}
+  font-size: 1.5rem; }
 
 h5, .h5 {
-  font-size: 1.25rem;
-}
+  font-size: 1.25rem; }
 
 h6, .h6 {
-  font-size: 1rem;
-}
+  font-size: 1rem; }
 
 .lead {
   font-size: 1.25rem;
-  font-weight: 300;
-}
+  font-weight: 300; }
 
 hr {
   margin-top: 1rem;
   margin-bottom: 1rem;
   border: 0;
-  border-top: .0625rem solid #eceeef;
-}
+  border-top: 0.0625rem solid #eceeef; }
 
-small, .small {
-  font-size: 85%;
-}
+small,
+.small {
+  font-size: 85%; }
 
-mark, .mark {
+mark,
+.mark {
   padding: .2em;
-  background-color: #fcf8e3;
-}
+  background-color: #fcf8e3; }
 
 .list-unstyled {
   padding-left: 0;
-  list-style: none;
-}
+  list-style: none; }
 
 .list-inline {
   padding-left: 0;
   margin-left: -5px;
-  list-style: none;
-}
-.list-inline > li {
-  display: inline-block;
-  padding-right: 5px;
-  padding-left: 5px;
-}
+  list-style: none; }
+  .list-inline > li {
+    display: inline-block;
+    padding-right: 5px;
+    padding-left: 5px; }
 
 .dl-horizontal {
   margin-right: -1.5rem;
-  margin-left: -1.5rem;
-}
-.dl-horizontal:before, .dl-horizontal:after {
-  display: table; 
-  content: " ";
-}
-.dl-horizontal:after {
-  clear: both;
-}
+  margin-left: -1.5rem; }
+  .dl-horizontal:before,
+  .dl-horizontal:after {
+    content: " ";
+    display: table; }
+  .dl-horizontal:after {
+    clear: both; }
 
 .initialism {
   font-size: 90%;
-  text-transform: uppercase;
-}
+  text-transform: uppercase; }
 
 .blockquote {
-  padding: .5rem 1rem;
+  padding: 0.5rem 1rem;
   margin-bottom: 1rem;
   font-size: 1.25rem;
-  border-left: .25rem solid #eceeef;
-}
-.blockquote p:last-child, .blockquote ul:last-child, .blockquote ol:last-child {
-  margin-bottom: 0;
-}
-.blockquote footer {
-  display: block;
-  font-size: 80%;
-  line-height: 1.5;
-  color: #818a91;
-}
-.blockquote footer:before {
-  content: "\2014 \00A0";
-}
+  border-left: 0.25rem solid #eceeef; }
+  .blockquote p:last-child,
+  .blockquote ul:last-child,
+  .blockquote ol:last-child {
+    margin-bottom: 0; }
+  .blockquote footer {
+    display: block;
+    font-size: 80%;
+    line-height: 1.5;
+    color: #818a91; }
+    .blockquote footer:before {
+      content: "\2014 \00A0"; }
 
 .blockquote-reverse {
   padding-right: 1rem;
   padding-left: 0;
   text-align: right;
-  border-right: .25rem solid #eceeef;
-  border-left: 0;
-}
-.blockquote-reverse footer:before {
-  content: "";
-}
-.blockquote-reverse footer:after {
-  content: "\00A0 \2014";
-}
-
-.img-responsive, .carousel-inner > .carousel-item > img, .carousel-inner > .carousel-item > a > img {
+  border-right: 0.25rem solid #eceeef;
+  border-left: 0; }
+  .blockquote-reverse footer:before {
+    content: ""; }
+  .blockquote-reverse footer:after {
+    content: "\00A0 \2014"; }
+
+.img-responsive, .carousel-inner > .carousel-item > img,
+.carousel-inner > .carousel-item > a > img {
   display: block;
   max-width: 100%;
-  height: auto;
-}
+  height: auto; }
 
 .img-rounded {
-  border-radius: .3rem;
-}
+  border-radius: 0.3rem; }
 
 .img-thumbnail {
-  display: inline-block;
-  max-width: 100%;
-  height: auto; 
-  padding: .25rem;
+  padding: 0.25rem;
   line-height: 1.5;
   background-color: #fff;
   border: 1px solid #ddd;
-  border-radius: .25rem;
-  -webkit-transition: all .2s ease-in-out;
-       -o-transition: all .2s ease-in-out;
-          transition: all .2s ease-in-out;
-}
+  border-radius: 0.25rem;
+  transition: all 0.2s ease-in-out;
+  display: inline-block;
+  max-width: 100%;
+  height: auto; }
 
 .img-circle {
-  border-radius: 50%;
-}
+  border-radius: 50%; }
 
-code, kbd, pre, samp {
-  font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
-}
+code,
+kbd,
+pre,
+samp {
+  font-family: Menlo, Monaco, Consolas, "Courier New", monospace; }
 
 code {
-  padding: .2rem .4rem;
+  padding: 0.2rem 0.4rem;
   font-size: 90%;
   color: #d44950;
   background-color: #f7f7f9;
-  border-radius: .25rem;
-}
+  border-radius: 0.25rem; }
 
 kbd {
-  padding: .2rem .4rem;
+  padding: 0.2rem 0.4rem;
   font-size: 90%;
   color: #fff;
   background-color: #333;
-  border-radius: .2rem;
-}
-kbd kbd {
-  padding: 0;
-  font-size: 100%;
-  font-weight: bold;
-}
+  border-radius: 0.2rem; }
+  kbd kbd {
+    padding: 0;
+    font-size: 100%;
+    font-weight: bold; }
 
 pre {
   display: block;
@@ -611,1668 +572,1039 @@ pre {
   margin-bottom: 1rem;
   font-size: 90%;
   line-height: 1.5;
-  color: #373a3c;
-}
-pre code {
-  padding: 0;
-  font-size: inherit;
-  color: inherit;
-  background-color: transparent;
-  border-radius: 0;
-}
+  color: #373a3c; }
+  pre code {
+    padding: 0;
+    font-size: inherit;
+    color: inherit;
+    background-color: transparent;
+    border-radius: 0; }
 
 .pre-scrollable {
   max-height: 340px;
-  overflow-y: scroll;
-}
+  overflow-y: scroll; }
 
 .container {
-  padding-right: .75rem; 
-  padding-left: .75rem;
   margin-right: auto;
   margin-left: auto;
-}
-.container:before, .container:after {
-  display: table; 
-  content: " ";
-}
-.container:after {
-  clear: both;
-}
-@media (min-width: 34em) {
-  .container {
-    max-width: 34rem;
-  }
-}
-@media (min-width: 48em) {
-  .container {
-    max-width: 45rem;
-  }
-}
-@media (min-width: 62em) {
-  .container {
-    max-width: 60rem;
-  }
-}
-@media (min-width: 75em) {
-  .container {
-    max-width: 72.25rem;
-  }
-}
+  padding-left: 0.75rem;
+  padding-right: 0.75rem; }
+  .container:before,
+  .container:after {
+    content: " ";
+    display: table; }
+  .container:after {
+    clear: both; }
+  @media (min-width: 34em) {
+    .container {
+      max-width: 34rem; } }
+  @media (min-width: 48em) {
+    .container {
+      max-width: 45rem; } }
+  @media (min-width: 62em) {
+    .container {
+      max-width: 60rem; } }
+  @media (min-width: 75em) {
+    .container {
+      max-width: 72.25rem; } }
 
 .container-fluid {
-  padding-right: .75rem; 
-  padding-left: .75rem;
   margin-right: auto;
   margin-left: auto;
-}
-.container-fluid:before, .container-fluid:after {
-  display: table; 
-  content: " ";
-}
-.container-fluid:after {
-  clear: both;
-}
+  padding-left: 0.75rem;
+  padding-right: 0.75rem; }
+  .container-fluid:before,
+  .container-fluid:after {
+    content: " ";
+    display: table; }
+  .container-fluid:after {
+    clear: both; }
 
 .row {
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -ms-flexbox;
-  display:         flex;
-  margin-right: -.75rem; 
-  margin-left: -.75rem;
-
-  -webkit-flex-wrap: wrap;
-      -ms-flex-wrap: wrap;
-          flex-wrap: wrap;
-}
-.row:before, .row:after {
-  display: table; 
-  content: " ";
-}
-.row:after {
-  clear: both;
-}
+  display: flex;
+  flex-wrap: wrap;
+  margin-left: -0.75rem;
+  margin-right: -0.75rem; }
+  .row:before,
+  .row:after {
+    content: " ";
+    display: table; }
+  .row:after {
+    clear: both; }
 
 .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 {
   position: relative;
   min-height: 1px;
-  padding-right: .75rem; 
-  padding-left: .75rem;
-}
+  padding-left: 0.75rem;
+  padding-right: 0.75rem; }
 
 .col-xs-1 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 8.333333%;
-      -ms-flex: 0 0 8.333333%;
-          flex: 0 0 8.333333%;
-}
+  flex: 0 0 8.333333%; }
 
 .col-xs-2 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 16.666667%;
-      -ms-flex: 0 0 16.666667%;
-          flex: 0 0 16.666667%;
-}
+  flex: 0 0 16.666667%; }
 
 .col-xs-3 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 25%;
-      -ms-flex: 0 0 25%;
-          flex: 0 0 25%;
-}
+  flex: 0 0 25%; }
 
 .col-xs-4 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 33.333333%;
-      -ms-flex: 0 0 33.333333%;
-          flex: 0 0 33.333333%;
-}
+  flex: 0 0 33.333333%; }
 
 .col-xs-5 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 41.666667%;
-      -ms-flex: 0 0 41.666667%;
-          flex: 0 0 41.666667%;
-}
+  flex: 0 0 41.666667%; }
 
 .col-xs-6 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 50%;
-      -ms-flex: 0 0 50%;
-          flex: 0 0 50%;
-}
+  flex: 0 0 50%; }
 
 .col-xs-7 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 58.333333%;
-      -ms-flex: 0 0 58.333333%;
-          flex: 0 0 58.333333%;
-}
+  flex: 0 0 58.333333%; }
 
 .col-xs-8 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 66.666667%;
-      -ms-flex: 0 0 66.666667%;
-          flex: 0 0 66.666667%;
-}
+  flex: 0 0 66.666667%; }
 
 .col-xs-9 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 75%;
-      -ms-flex: 0 0 75%;
-          flex: 0 0 75%;
-}
+  flex: 0 0 75%; }
 
 .col-xs-10 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 83.333333%;
-      -ms-flex: 0 0 83.333333%;
-          flex: 0 0 83.333333%;
-}
+  flex: 0 0 83.333333%; }
 
 .col-xs-11 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 91.666667%;
-      -ms-flex: 0 0 91.666667%;
-          flex: 0 0 91.666667%;
-}
+  flex: 0 0 91.666667%; }
 
 .col-xs-12 {
-  -webkit-box-flex: 0;
-  -webkit-flex: 0 0 100%;
-      -ms-flex: 0 0 100%;
-          flex: 0 0 100%;
-}
+  flex: 0 0 100%; }
 
 .col-xs-pull-0 {
-  right: auto;
-}
+  right: auto; }
 
 .col-xs-pull-1 {
-  right: 8.333333%;
-}
+  right: 8.333333%; }
 
 .col-xs-pull-2 {
-  right: 16.666667%;
-}
+  right: 16.666667%; }
 
 .col-xs-pull-3 {
-  right: 25%;
-}
+  right: 25%; }
 
 .col-xs-pull-4 {
-  right: 33.333333%;
-}
+  right: 33.333333%; }
 
 .col-xs-pull-5 {
-  right: 41.666667%;
-}
+  right: 41.666667%; }
 
 .col-xs-pull-6 {
-  right: 50%;
-}
+  right: 50%; }
 
 .col-xs-pull-7 {
-  right: 58.333333%;
-}
+  right: 58.333333%; }
 
 .col-xs-pull-8 {
-  right: 66.666667%;
-}
+  right: 66.666667%; }
 
 .col-xs-pull-9 {
-  right: 75%;
-}
+  right: 75%; }
 
 .col-xs-pull-10 {
-  right: 83.333333%;
-}
+  right: 83.333333%; }
 
 .col-xs-pull-11 {
-  right: 91.666667%;
-}
+  right: 91.666667%; }
 
 .col-xs-pull-12 {
-  right: 100%;
-}
+  right: 100%; }
 
 .col-xs-push-0 {
-  left: auto;
-}
+  left: auto; }
 
 .col-xs-push-1 {
-  left: 8.333333%;
-}
+  left: 8.333333%; }
 
 .col-xs-push-2 {
-  left: 16.666667%;
-}
+  left: 16.666667%; }
 
 .col-xs-push-3 {
-  left: 25%;
-}
+  left: 25%; }
 
 .col-xs-push-4 {
-  left: 33.333333%;
-}
+  left: 33.333333%; }
 
 .col-xs-push-5 {
-  left: 41.666667%;
-}
+  left: 41.666667%; }
 
 .col-xs-push-6 {
-  left: 50%;
-}
+  left: 50%; }
 
 .col-xs-push-7 {
-  left: 58.333333%;
-}
+  left: 58.333333%; }
 
 .col-xs-push-8 {
-  left: 66.666667%;
-}
+  left: 66.666667%; }
 
 .col-xs-push-9 {
-  left: 75%;
-}
+  left: 75%; }
 
 .col-xs-push-10 {
-  left: 83.333333%;
-}
+  left: 83.333333%; }
 
 .col-xs-push-11 {
-  left: 91.666667%;
-}
+  left: 91.666667%; }
 
 .col-xs-push-12 {
-  left: 100%;
-}
+  left: 100%; }
 
 .col-xs-offset-0 {
-  margin-left: 0;
-}
+  margin-left: 0%; }
 
 .col-xs-offset-1 {
-  margin-left: 8.333333%;
-}
+  margin-left: 8.333333%; }
 
 .col-xs-offset-2 {
-  margin-left: 16.666667%;
-}
+  margin-left: 16.666667%; }
 
 .col-xs-offset-3 {
-  margin-left: 25%;
-}
+  margin-left: 25%; }
 
 .col-xs-offset-4 {
-  margin-left: 33.333333%;
-}
+  margin-left: 33.333333%; }
 
 .col-xs-offset-5 {
-  margin-left: 41.666667%;
-}
+  margin-left: 41.666667%; }
 
 .col-xs-offset-6 {
-  margin-left: 50%;
-}
+  margin-left: 50%; }
 
 .col-xs-offset-7 {
-  margin-left: 58.333333%;
-}
+  margin-left: 58.333333%; }
 
 .col-xs-offset-8 {
-  margin-left: 66.666667%;
-}
+  margin-left: 66.666667%; }
 
 .col-xs-offset-9 {
-  margin-left: 75%;
-}
+  margin-left: 75%; }
 
 .col-xs-offset-10 {
-  margin-left: 83.333333%;
-}
+  margin-left: 83.333333%; }
 
 .col-xs-offset-11 {
-  margin-left: 91.666667%;
-}
+  margin-left: 91.666667%; }
 
 .col-xs-offset-12 {
-  margin-left: 100%;
-}
+  margin-left: 100%; }
 
 @media (min-width: 34em) {
   .col-sm-1 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 8.333333%;
-        -ms-flex: 0 0 8.333333%;
-            flex: 0 0 8.333333%;
-  }
+    flex: 0 0 8.333333%; }
   .col-sm-2 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 16.666667%;
-        -ms-flex: 0 0 16.666667%;
-            flex: 0 0 16.666667%;
-  }
+    flex: 0 0 16.666667%; }
   .col-sm-3 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 25%;
-        -ms-flex: 0 0 25%;
-            flex: 0 0 25%;
-  }
+    flex: 0 0 25%; }
   .col-sm-4 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 33.333333%;
-        -ms-flex: 0 0 33.333333%;
-            flex: 0 0 33.333333%;
-  }
+    flex: 0 0 33.333333%; }
   .col-sm-5 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 41.666667%;
-        -ms-flex: 0 0 41.666667%;
-            flex: 0 0 41.666667%;
-  }
+    flex: 0 0 41.666667%; }
   .col-sm-6 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 50%;
-        -ms-flex: 0 0 50%;
-            flex: 0 0 50%;
-  }
+    flex: 0 0 50%; }
   .col-sm-7 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 58.333333%;
-        -ms-flex: 0 0 58.333333%;
-            flex: 0 0 58.333333%;
-  }
+    flex: 0 0 58.333333%; }
   .col-sm-8 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 66.666667%;
-        -ms-flex: 0 0 66.666667%;
-            flex: 0 0 66.666667%;
-  }
+    flex: 0 0 66.666667%; }
   .col-sm-9 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 75%;
-        -ms-flex: 0 0 75%;
-            flex: 0 0 75%;
-  }
+    flex: 0 0 75%; }
   .col-sm-10 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 83.333333%;
-        -ms-flex: 0 0 83.333333%;
-            flex: 0 0 83.333333%;
-  }
+    flex: 0 0 83.333333%; }
   .col-sm-11 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 91.666667%;
-        -ms-flex: 0 0 91.666667%;
-            flex: 0 0 91.666667%;
-  }
+    flex: 0 0 91.666667%; }
   .col-sm-12 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 100%;
-        -ms-flex: 0 0 100%;
-            flex: 0 0 100%;
-  }
+    flex: 0 0 100%; }
   .col-sm-pull-0 {
-    right: auto;
-  }
+    right: auto; }
   .col-sm-pull-1 {
-    right: 8.333333%;
-  }
+    right: 8.333333%; }
   .col-sm-pull-2 {
-    right: 16.666667%;
-  }
+    right: 16.666667%; }
   .col-sm-pull-3 {
-    right: 25%;
-  }
+    right: 25%; }
   .col-sm-pull-4 {
-    right: 33.333333%;
-  }
+    right: 33.333333%; }
   .col-sm-pull-5 {
-    right: 41.666667%;
-  }
+    right: 41.666667%; }
   .col-sm-pull-6 {
-    right: 50%;
-  }
+    right: 50%; }
   .col-sm-pull-7 {
-    right: 58.333333%;
-  }
+    right: 58.333333%; }
   .col-sm-pull-8 {
-    right: 66.666667%;
-  }
+    right: 66.666667%; }
   .col-sm-pull-9 {
-    right: 75%;
-  }
+    right: 75%; }
   .col-sm-pull-10 {
-    right: 83.333333%;
-  }
+    right: 83.333333%; }
   .col-sm-pull-11 {
-    right: 91.666667%;
-  }
+    right: 91.666667%; }
   .col-sm-pull-12 {
-    right: 100%;
-  }
+    right: 100%; }
   .col-sm-push-0 {
-    left: auto;
-  }
+    left: auto; }
   .col-sm-push-1 {
-    left: 8.333333%;
-  }
+    left: 8.333333%; }
   .col-sm-push-2 {
-    left: 16.666667%;
-  }
+    left: 16.666667%; }
   .col-sm-push-3 {
-    left: 25%;
-  }
+    left: 25%; }
   .col-sm-push-4 {
-    left: 33.333333%;
-  }
+    left: 33.333333%; }
   .col-sm-push-5 {
-    left: 41.666667%;
-  }
+    left: 41.666667%; }
   .col-sm-push-6 {
-    left: 50%;
-  }
+    left: 50%; }
   .col-sm-push-7 {
-    left: 58.333333%;
-  }
+    left: 58.333333%; }
   .col-sm-push-8 {
-    left: 66.666667%;
-  }
+    left: 66.666667%; }
   .col-sm-push-9 {
-    left: 75%;
-  }
+    left: 75%; }
   .col-sm-push-10 {
-    left: 83.333333%;
-  }
+    left: 83.333333%; }
   .col-sm-push-11 {
-    left: 91.666667%;
-  }
+    left: 91.666667%; }
   .col-sm-push-12 {
-    left: 100%;
-  }
+    left: 100%; }
   .col-sm-offset-0 {
-    margin-left: 0;
-  }
+    margin-left: 0%; }
   .col-sm-offset-1 {
-    margin-left: 8.333333%;
-  }
+    margin-left: 8.333333%; }
   .col-sm-offset-2 {
-    margin-left: 16.666667%;
-  }
+    margin-left: 16.666667%; }
   .col-sm-offset-3 {
-    margin-left: 25%;
-  }
+    margin-left: 25%; }
   .col-sm-offset-4 {
-    margin-left: 33.333333%;
-  }
+    margin-left: 33.333333%; }
   .col-sm-offset-5 {
-    margin-left: 41.666667%;
-  }
+    margin-left: 41.666667%; }
   .col-sm-offset-6 {
-    margin-left: 50%;
-  }
+    margin-left: 50%; }
   .col-sm-offset-7 {
-    margin-left: 58.333333%;
-  }
+    margin-left: 58.333333%; }
   .col-sm-offset-8 {
-    margin-left: 66.666667%;
-  }
+    margin-left: 66.666667%; }
   .col-sm-offset-9 {
-    margin-left: 75%;
-  }
+    margin-left: 75%; }
   .col-sm-offset-10 {
-    margin-left: 83.333333%;
-  }
+    margin-left: 83.333333%; }
   .col-sm-offset-11 {
-    margin-left: 91.666667%;
-  }
+    margin-left: 91.666667%; }
   .col-sm-offset-12 {
-    margin-left: 100%;
-  }
-}
+    margin-left: 100%; } }
 
 @media (min-width: 48em) {
   .col-md-1 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 8.333333%;
-        -ms-flex: 0 0 8.333333%;
-            flex: 0 0 8.333333%;
-  }
+    flex: 0 0 8.333333%; }
   .col-md-2 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 16.666667%;
-        -ms-flex: 0 0 16.666667%;
-            flex: 0 0 16.666667%;
-  }
+    flex: 0 0 16.666667%; }
   .col-md-3 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 25%;
-        -ms-flex: 0 0 25%;
-            flex: 0 0 25%;
-  }
+    flex: 0 0 25%; }
   .col-md-4 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 33.333333%;
-        -ms-flex: 0 0 33.333333%;
-            flex: 0 0 33.333333%;
-  }
+    flex: 0 0 33.333333%; }
   .col-md-5 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 41.666667%;
-        -ms-flex: 0 0 41.666667%;
-            flex: 0 0 41.666667%;
-  }
+    flex: 0 0 41.666667%; }
   .col-md-6 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 50%;
-        -ms-flex: 0 0 50%;
-            flex: 0 0 50%;
-  }
+    flex: 0 0 50%; }
   .col-md-7 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 58.333333%;
-        -ms-flex: 0 0 58.333333%;
-            flex: 0 0 58.333333%;
-  }
+    flex: 0 0 58.333333%; }
   .col-md-8 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 66.666667%;
-        -ms-flex: 0 0 66.666667%;
-            flex: 0 0 66.666667%;
-  }
+    flex: 0 0 66.666667%; }
   .col-md-9 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 75%;
-        -ms-flex: 0 0 75%;
-            flex: 0 0 75%;
-  }
+    flex: 0 0 75%; }
   .col-md-10 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 83.333333%;
-        -ms-flex: 0 0 83.333333%;
-            flex: 0 0 83.333333%;
-  }
+    flex: 0 0 83.333333%; }
   .col-md-11 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 91.666667%;
-        -ms-flex: 0 0 91.666667%;
-            flex: 0 0 91.666667%;
-  }
+    flex: 0 0 91.666667%; }
   .col-md-12 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 100%;
-        -ms-flex: 0 0 100%;
-            flex: 0 0 100%;
-  }
+    flex: 0 0 100%; }
   .col-md-pull-0 {
-    right: auto;
-  }
+    right: auto; }
   .col-md-pull-1 {
-    right: 8.333333%;
-  }
+    right: 8.333333%; }
   .col-md-pull-2 {
-    right: 16.666667%;
-  }
+    right: 16.666667%; }
   .col-md-pull-3 {
-    right: 25%;
-  }
+    right: 25%; }
   .col-md-pull-4 {
-    right: 33.333333%;
-  }
+    right: 33.333333%; }
   .col-md-pull-5 {
-    right: 41.666667%;
-  }
+    right: 41.666667%; }
   .col-md-pull-6 {
-    right: 50%;
-  }
+    right: 50%; }
   .col-md-pull-7 {
-    right: 58.333333%;
-  }
+    right: 58.333333%; }
   .col-md-pull-8 {
-    right: 66.666667%;
-  }
+    right: 66.666667%; }
   .col-md-pull-9 {
-    right: 75%;
-  }
+    right: 75%; }
   .col-md-pull-10 {
-    right: 83.333333%;
-  }
+    right: 83.333333%; }
   .col-md-pull-11 {
-    right: 91.666667%;
-  }
+    right: 91.666667%; }
   .col-md-pull-12 {
-    right: 100%;
-  }
+    right: 100%; }
   .col-md-push-0 {
-    left: auto;
-  }
+    left: auto; }
   .col-md-push-1 {
-    left: 8.333333%;
-  }
+    left: 8.333333%; }
   .col-md-push-2 {
-    left: 16.666667%;
-  }
+    left: 16.666667%; }
   .col-md-push-3 {
-    left: 25%;
-  }
+    left: 25%; }
   .col-md-push-4 {
-    left: 33.333333%;
-  }
+    left: 33.333333%; }
   .col-md-push-5 {
-    left: 41.666667%;
-  }
+    left: 41.666667%; }
   .col-md-push-6 {
-    left: 50%;
-  }
+    left: 50%; }
   .col-md-push-7 {
-    left: 58.333333%;
-  }
+    left: 58.333333%; }
   .col-md-push-8 {
-    left: 66.666667%;
-  }
+    left: 66.666667%; }
   .col-md-push-9 {
-    left: 75%;
-  }
+    left: 75%; }
   .col-md-push-10 {
-    left: 83.333333%;
-  }
+    left: 83.333333%; }
   .col-md-push-11 {
-    left: 91.666667%;
-  }
+    left: 91.666667%; }
   .col-md-push-12 {
-    left: 100%;
-  }
+    left: 100%; }
   .col-md-offset-0 {
-    margin-left: 0;
-  }
+    margin-left: 0%; }
   .col-md-offset-1 {
-    margin-left: 8.333333%;
-  }
+    margin-left: 8.333333%; }
   .col-md-offset-2 {
-    margin-left: 16.666667%;
-  }
+    margin-left: 16.666667%; }
   .col-md-offset-3 {
-    margin-left: 25%;
-  }
+    margin-left: 25%; }
   .col-md-offset-4 {
-    margin-left: 33.333333%;
-  }
+    margin-left: 33.333333%; }
   .col-md-offset-5 {
-    margin-left: 41.666667%;
-  }
+    margin-left: 41.666667%; }
   .col-md-offset-6 {
-    margin-left: 50%;
-  }
+    margin-left: 50%; }
   .col-md-offset-7 {
-    margin-left: 58.333333%;
-  }
+    margin-left: 58.333333%; }
   .col-md-offset-8 {
-    margin-left: 66.666667%;
-  }
+    margin-left: 66.666667%; }
   .col-md-offset-9 {
-    margin-left: 75%;
-  }
+    margin-left: 75%; }
   .col-md-offset-10 {
-    margin-left: 83.333333%;
-  }
+    margin-left: 83.333333%; }
   .col-md-offset-11 {
-    margin-left: 91.666667%;
-  }
+    margin-left: 91.666667%; }
   .col-md-offset-12 {
-    margin-left: 100%;
-  }
-}
+    margin-left: 100%; } }
 
 @media (min-width: 62em) {
   .col-lg-1 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 8.333333%;
-        -ms-flex: 0 0 8.333333%;
-            flex: 0 0 8.333333%;
-  }
+    flex: 0 0 8.333333%; }
   .col-lg-2 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 16.666667%;
-        -ms-flex: 0 0 16.666667%;
-            flex: 0 0 16.666667%;
-  }
+    flex: 0 0 16.666667%; }
   .col-lg-3 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 25%;
-        -ms-flex: 0 0 25%;
-            flex: 0 0 25%;
-  }
+    flex: 0 0 25%; }
   .col-lg-4 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 33.333333%;
-        -ms-flex: 0 0 33.333333%;
-            flex: 0 0 33.333333%;
-  }
+    flex: 0 0 33.333333%; }
   .col-lg-5 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 41.666667%;
-        -ms-flex: 0 0 41.666667%;
-            flex: 0 0 41.666667%;
-  }
+    flex: 0 0 41.666667%; }
   .col-lg-6 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 50%;
-        -ms-flex: 0 0 50%;
-            flex: 0 0 50%;
-  }
+    flex: 0 0 50%; }
   .col-lg-7 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 58.333333%;
-        -ms-flex: 0 0 58.333333%;
-            flex: 0 0 58.333333%;
-  }
+    flex: 0 0 58.333333%; }
   .col-lg-8 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 66.666667%;
-        -ms-flex: 0 0 66.666667%;
-            flex: 0 0 66.666667%;
-  }
+    flex: 0 0 66.666667%; }
   .col-lg-9 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 75%;
-        -ms-flex: 0 0 75%;
-            flex: 0 0 75%;
-  }
+    flex: 0 0 75%; }
   .col-lg-10 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 83.333333%;
-        -ms-flex: 0 0 83.333333%;
-            flex: 0 0 83.333333%;
-  }
+    flex: 0 0 83.333333%; }
   .col-lg-11 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 91.666667%;
-        -ms-flex: 0 0 91.666667%;
-            flex: 0 0 91.666667%;
-  }
+    flex: 0 0 91.666667%; }
   .col-lg-12 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 100%;
-        -ms-flex: 0 0 100%;
-            flex: 0 0 100%;
-  }
+    flex: 0 0 100%; }
   .col-lg-pull-0 {
-    right: auto;
-  }
+    right: auto; }
   .col-lg-pull-1 {
-    right: 8.333333%;
-  }
+    right: 8.333333%; }
   .col-lg-pull-2 {
-    right: 16.666667%;
-  }
+    right: 16.666667%; }
   .col-lg-pull-3 {
-    right: 25%;
-  }
+    right: 25%; }
   .col-lg-pull-4 {
-    right: 33.333333%;
-  }
+    right: 33.333333%; }
   .col-lg-pull-5 {
-    right: 41.666667%;
-  }
+    right: 41.666667%; }
   .col-lg-pull-6 {
-    right: 50%;
-  }
+    right: 50%; }
   .col-lg-pull-7 {
-    right: 58.333333%;
-  }
+    right: 58.333333%; }
   .col-lg-pull-8 {
-    right: 66.666667%;
-  }
+    right: 66.666667%; }
   .col-lg-pull-9 {
-    right: 75%;
-  }
+    right: 75%; }
   .col-lg-pull-10 {
-    right: 83.333333%;
-  }
+    right: 83.333333%; }
   .col-lg-pull-11 {
-    right: 91.666667%;
-  }
+    right: 91.666667%; }
   .col-lg-pull-12 {
-    right: 100%;
-  }
+    right: 100%; }
   .col-lg-push-0 {
-    left: auto;
-  }
+    left: auto; }
   .col-lg-push-1 {
-    left: 8.333333%;
-  }
+    left: 8.333333%; }
   .col-lg-push-2 {
-    left: 16.666667%;
-  }
+    left: 16.666667%; }
   .col-lg-push-3 {
-    left: 25%;
-  }
+    left: 25%; }
   .col-lg-push-4 {
-    left: 33.333333%;
-  }
+    left: 33.333333%; }
   .col-lg-push-5 {
-    left: 41.666667%;
-  }
+    left: 41.666667%; }
   .col-lg-push-6 {
-    left: 50%;
-  }
+    left: 50%; }
   .col-lg-push-7 {
-    left: 58.333333%;
-  }
+    left: 58.333333%; }
   .col-lg-push-8 {
-    left: 66.666667%;
-  }
+    left: 66.666667%; }
   .col-lg-push-9 {
-    left: 75%;
-  }
+    left: 75%; }
   .col-lg-push-10 {
-    left: 83.333333%;
-  }
+    left: 83.333333%; }
   .col-lg-push-11 {
-    left: 91.666667%;
-  }
+    left: 91.666667%; }
   .col-lg-push-12 {
-    left: 100%;
-  }
+    left: 100%; }
   .col-lg-offset-0 {
-    margin-left: 0;
-  }
+    margin-left: 0%; }
   .col-lg-offset-1 {
-    margin-left: 8.333333%;
-  }
+    margin-left: 8.333333%; }
   .col-lg-offset-2 {
-    margin-left: 16.666667%;
-  }
+    margin-left: 16.666667%; }
   .col-lg-offset-3 {
-    margin-left: 25%;
-  }
+    margin-left: 25%; }
   .col-lg-offset-4 {
-    margin-left: 33.333333%;
-  }
+    margin-left: 33.333333%; }
   .col-lg-offset-5 {
-    margin-left: 41.666667%;
-  }
+    margin-left: 41.666667%; }
   .col-lg-offset-6 {
-    margin-left: 50%;
-  }
+    margin-left: 50%; }
   .col-lg-offset-7 {
-    margin-left: 58.333333%;
-  }
+    margin-left: 58.333333%; }
   .col-lg-offset-8 {
-    margin-left: 66.666667%;
-  }
+    margin-left: 66.666667%; }
   .col-lg-offset-9 {
-    margin-left: 75%;
-  }
+    margin-left: 75%; }
   .col-lg-offset-10 {
-    margin-left: 83.333333%;
-  }
+    margin-left: 83.333333%; }
   .col-lg-offset-11 {
-    margin-left: 91.666667%;
-  }
+    margin-left: 91.666667%; }
   .col-lg-offset-12 {
-    margin-left: 100%;
-  }
-}
+    margin-left: 100%; } }
 
 @media (min-width: 75em) {
   .col-xl-1 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 8.333333%;
-        -ms-flex: 0 0 8.333333%;
-            flex: 0 0 8.333333%;
-  }
+    flex: 0 0 8.333333%; }
   .col-xl-2 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 16.666667%;
-        -ms-flex: 0 0 16.666667%;
-            flex: 0 0 16.666667%;
-  }
+    flex: 0 0 16.666667%; }
   .col-xl-3 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 25%;
-        -ms-flex: 0 0 25%;
-            flex: 0 0 25%;
-  }
+    flex: 0 0 25%; }
   .col-xl-4 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 33.333333%;
-        -ms-flex: 0 0 33.333333%;
-            flex: 0 0 33.333333%;
-  }
+    flex: 0 0 33.333333%; }
   .col-xl-5 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 41.666667%;
-        -ms-flex: 0 0 41.666667%;
-            flex: 0 0 41.666667%;
-  }
+    flex: 0 0 41.666667%; }
   .col-xl-6 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 50%;
-        -ms-flex: 0 0 50%;
-            flex: 0 0 50%;
-  }
+    flex: 0 0 50%; }
   .col-xl-7 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 58.333333%;
-        -ms-flex: 0 0 58.333333%;
-            flex: 0 0 58.333333%;
-  }
+    flex: 0 0 58.333333%; }
   .col-xl-8 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 66.666667%;
-        -ms-flex: 0 0 66.666667%;
-            flex: 0 0 66.666667%;
-  }
+    flex: 0 0 66.666667%; }
   .col-xl-9 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 75%;
-        -ms-flex: 0 0 75%;
-            flex: 0 0 75%;
-  }
+    flex: 0 0 75%; }
   .col-xl-10 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 83.333333%;
-        -ms-flex: 0 0 83.333333%;
-            flex: 0 0 83.333333%;
-  }
+    flex: 0 0 83.333333%; }
   .col-xl-11 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 91.666667%;
-        -ms-flex: 0 0 91.666667%;
-            flex: 0 0 91.666667%;
-  }
+    flex: 0 0 91.666667%; }
   .col-xl-12 {
-    -webkit-box-flex: 0;
-    -webkit-flex: 0 0 100%;
-        -ms-flex: 0 0 100%;
-            flex: 0 0 100%;
-  }
+    flex: 0 0 100%; }
   .col-xl-pull-0 {
-    right: auto;
-  }
+    right: auto; }
   .col-xl-pull-1 {
-    right: 8.333333%;
-  }
+    right: 8.333333%; }
   .col-xl-pull-2 {
-    right: 16.666667%;
-  }
+    right: 16.666667%; }
   .col-xl-pull-3 {
-    right: 25%;
-  }
+    right: 25%; }
   .col-xl-pull-4 {
-    right: 33.333333%;
-  }
+    right: 33.333333%; }
   .col-xl-pull-5 {
-    right: 41.666667%;
-  }
+    right: 41.666667%; }
   .col-xl-pull-6 {
-    right: 50%;
-  }
+    right: 50%; }
   .col-xl-pull-7 {
-    right: 58.333333%;
-  }
+    right: 58.333333%; }
   .col-xl-pull-8 {
-    right: 66.666667%;
-  }
+    right: 66.666667%; }
   .col-xl-pull-9 {
-    right: 75%;
-  }
+    right: 75%; }
   .col-xl-pull-10 {
-    right: 83.333333%;
-  }
+    right: 83.333333%; }
   .col-xl-pull-11 {
-    right: 91.666667%;
-  }
+    right: 91.666667%; }
   .col-xl-pull-12 {
-    right: 100%;
-  }
+    right: 100%; }
   .col-xl-push-0 {
-    left: auto;
-  }
+    left: auto; }
   .col-xl-push-1 {
-    left: 8.333333%;
-  }
+    left: 8.333333%; }
   .col-xl-push-2 {
-    left: 16.666667%;
-  }
+    left: 16.666667%; }
   .col-xl-push-3 {
-    left: 25%;
-  }
+    left: 25%; }
   .col-xl-push-4 {
-    left: 33.333333%;
-  }
+    left: 33.333333%; }
   .col-xl-push-5 {
-    left: 41.666667%;
-  }
+    left: 41.666667%; }
   .col-xl-push-6 {
-    left: 50%;
-  }
+    left: 50%; }
   .col-xl-push-7 {
-    left: 58.333333%;
-  }
+    left: 58.333333%; }
   .col-xl-push-8 {
-    left: 66.666667%;
-  }
+    left: 66.666667%; }
   .col-xl-push-9 {
-    left: 75%;
-  }
+    left: 75%; }
   .col-xl-push-10 {
-    left: 83.333333%;
-  }
+    left: 83.333333%; }
   .col-xl-push-11 {
-    left: 91.666667%;
-  }
+    left: 91.666667%; }
   .col-xl-push-12 {
-    left: 100%;
-  }
+    left: 100%; }
   .col-xl-offset-0 {
-    margin-left: 0;
-  }
+    margin-left: 0%; }
   .col-xl-offset-1 {
-    margin-left: 8.333333%;
-  }
+    margin-left: 8.333333%; }
   .col-xl-offset-2 {
-    margin-left: 16.666667%;
-  }
+    margin-left: 16.666667%; }
   .col-xl-offset-3 {
-    margin-left: 25%;
-  }
+    margin-left: 25%; }
   .col-xl-offset-4 {
-    margin-left: 33.333333%;
-  }
+    margin-left: 33.333333%; }
   .col-xl-offset-5 {
-    margin-left: 41.666667%;
-  }
+    margin-left: 41.666667%; }
   .col-xl-offset-6 {
-    margin-left: 50%;
-  }
+    margin-left: 50%; }
   .col-xl-offset-7 {
-    margin-left: 58.333333%;
-  }
+    margin-left: 58.333333%; }
   .col-xl-offset-8 {
-    margin-left: 66.666667%;
-  }
+    margin-left: 66.666667%; }
   .col-xl-offset-9 {
-    margin-left: 75%;
-  }
+    margin-left: 75%; }
   .col-xl-offset-10 {
-    margin-left: 83.333333%;
-  }
+    margin-left: 83.333333%; }
   .col-xl-offset-11 {
-    margin-left: 91.666667%;
-  }
+    margin-left: 91.666667%; }
   .col-xl-offset-12 {
-    margin-left: 100%;
-  }
-}
+    margin-left: 100%; } }
 
 .col-xs-first {
-  -webkit-box-ordinal-group: 0;
-  -webkit-order: -1;
-  -ms-flex-order: -1;
-          order: -1;
-}
+  order: -1; }
 
 .col-xs-last {
-  -webkit-box-ordinal-group: 2;
-  -webkit-order: 1;
-  -ms-flex-order: 1;
-          order: 1;
-}
+  order: 1; }
 
 @media (min-width: 34em) {
   .col-sm-first {
-    -webkit-box-ordinal-group: 0;
-    -webkit-order: -1;
-    -ms-flex-order: -1;
-            order: -1;
-  }
+    order: -1; }
   .col-sm-last {
-    -webkit-box-ordinal-group: 2;
-    -webkit-order: 1;
-    -ms-flex-order: 1;
-            order: 1;
-  }
-}
+    order: 1; } }
 
 @media (min-width: 48em) {
   .col-md-first {
-    -webkit-box-ordinal-group: 0;
-    -webkit-order: -1;
-    -ms-flex-order: -1;
-            order: -1;
-  }
+    order: -1; }
   .col-md-last {
-    -webkit-box-ordinal-group: 2;
-    -webkit-order: 1;
-    -ms-flex-order: 1;
-            order: 1;
-  }
-}
+    order: 1; } }
 
 @media (min-width: 62em) {
   .col-lg-first {
-    -webkit-box-ordinal-group: 0;
-    -webkit-order: -1;
-    -ms-flex-order: -1;
-            order: -1;
-  }
+    order: -1; }
   .col-lg-last {
-    -webkit-box-ordinal-group: 2;
-    -webkit-order: 1;
-    -ms-flex-order: 1;
-            order: 1;
-  }
-}
+    order: 1; } }
 
 @media (min-width: 75em) {
   .col-xl-first {
-    -webkit-box-ordinal-group: 0;
-    -webkit-order: -1;
-    -ms-flex-order: -1;
-            order: -1;
-  }
+    order: -1; }
   .col-xl-last {
-    -webkit-box-ordinal-group: 2;
-    -webkit-order: 1;
-    -ms-flex-order: 1;
-            order: 1;
-  }
-}
+    order: 1; } }
 
 .row-xs-top {
-  -webkit-box-align: start;
-  -webkit-align-items: flex-start;
-  -ms-flex-align: start;
-          align-items: flex-start;
-}
+  align-items: flex-start; }
 
 .row-xs-center {
-  -webkit-box-align: center;
-  -webkit-align-items: center;
-  -ms-flex-align: center;
-          align-items: center;
-}
+  align-items: center; }
 
 .row-xs-bottom {
-  -webkit-box-align: end;
-  -webkit-align-items: flex-end;
-  -ms-flex-align: end;
-          align-items: flex-end;
-}
+  align-items: flex-end; }
 
 @media (min-width: 34em) {
   .row-sm-top {
-    -webkit-box-align: start;
-    -webkit-align-items: flex-start;
-    -ms-flex-align: start;
-            align-items: flex-start;
-  }
+    align-items: flex-start; }
   .row-sm-center {
-    -webkit-box-align: center;
-    -webkit-align-items: center;
-    -ms-flex-align: center;
-            align-items: center;
-  }
+    align-items: center; }
   .row-sm-bottom {
-    -webkit-box-align: end;
-    -webkit-align-items: flex-end;
-    -ms-flex-align: end;
-            align-items: flex-end;
-  }
-}
+    align-items: flex-end; } }
 
 @media (min-width: 48em) {
   .row-md-top {
-    -webkit-box-align: start;
-    -webkit-align-items: flex-start;
-    -ms-flex-align: start;
-            align-items: flex-start;
-  }
+    align-items: flex-start; }
   .row-md-center {
-    -webkit-box-align: center;
-    -webkit-align-items: center;
-    -ms-flex-align: center;
-            align-items: center;
-  }
+    align-items: center; }
   .row-md-bottom {
-    -webkit-box-align: end;
-    -webkit-align-items: flex-end;
-    -ms-flex-align: end;
-            align-items: flex-end;
-  }
-}
+    align-items: flex-end; } }
 
 @media (min-width: 62em) {
   .row-lg-top {
-    -webkit-box-align: start;
-    -webkit-align-items: flex-start;
-    -ms-flex-align: start;
-            align-items: flex-start;
-  }
+    align-items: flex-start; }
   .row-lg-center {
-    -webkit-box-align: center;
-    -webkit-align-items: center;
-    -ms-flex-align: center;
-            align-items: center;
-  }
+    align-items: center; }
   .row-lg-bottom {
-    -webkit-box-align: end;
-    -webkit-align-items: flex-end;
-    -ms-flex-align: end;
-            align-items: flex-end;
-  }
-}
+    align-items: flex-end; } }
 
 @media (min-width: 75em) {
   .row-xl-top {
-    -webkit-box-align: start;
-    -webkit-align-items: flex-start;
-    -ms-flex-align: start;
-            align-items: flex-start;
-  }
+    align-items: flex-start; }
   .row-xl-center {
-    -webkit-box-align: center;
-    -webkit-align-items: center;
-    -ms-flex-align: center;
-            align-items: center;
-  }
+    align-items: center; }
   .row-xl-bottom {
-    -webkit-box-align: end;
-    -webkit-align-items: flex-end;
-    -ms-flex-align: end;
-            align-items: flex-end;
-  }
-}
+    align-items: flex-end; } }
 
 .col-xs-top {
-  -webkit-align-self: flex-start;
-  -ms-flex-item-align: start;
-          align-self: flex-start;
-}
+  align-self: flex-start; }
 
 .col-xs-center {
-  -webkit-align-self: center;
-  -ms-flex-item-align: center;
-          align-self: center;
-}
+  align-self: center; }
 
 .col-xs-bottom {
-  -webkit-align-self: flex-end;
-  -ms-flex-item-align: end;
-          align-self: flex-end;
-}
+  align-self: flex-end; }
 
 @media (min-width: 34em) {
   .col-sm-top {
-    -webkit-align-self: flex-start;
-    -ms-flex-item-align: start;
-            align-self: flex-start;
-  }
+    align-self: flex-start; }
   .col-sm-center {
-    -webkit-align-self: center;
-    -ms-flex-item-align: center;
-            align-self: center;
-  }
+    align-self: center; }
   .col-sm-bottom {
-    -webkit-align-self: flex-end;
-    -ms-flex-item-align: end;
-            align-self: flex-end;
-  }
-}
+    align-self: flex-end; } }
 
 @media (min-width: 48em) {
   .col-md-top {
-    -webkit-align-self: flex-start;
-    -ms-flex-item-align: start;
-            align-self: flex-start;
-  }
+    align-self: flex-start; }
   .col-md-center {
-    -webkit-align-self: center;
-    -ms-flex-item-align: center;
-            align-self: center;
-  }
+    align-self: center; }
   .col-md-bottom {
-    -webkit-align-self: flex-end;
-    -ms-flex-item-align: end;
-            align-self: flex-end;
-  }
-}
+    align-self: flex-end; } }
 
 @media (min-width: 62em) {
   .col-lg-top {
-    -webkit-align-self: flex-start;
-    -ms-flex-item-align: start;
-            align-self: flex-start;
-  }
+    align-self: flex-start; }
   .col-lg-center {
-    -webkit-align-self: center;
-    -ms-flex-item-align: center;
-            align-self: center;
-  }
+    align-self: center; }
   .col-lg-bottom {
-    -webkit-align-self: flex-end;
-    -ms-flex-item-align: end;
-            align-self: flex-end;
-  }
-}
+    align-self: flex-end; } }
 
 @media (min-width: 75em) {
   .col-xl-top {
-    -webkit-align-self: flex-start;
-    -ms-flex-item-align: start;
-            align-self: flex-start;
-  }
+    align-self: flex-start; }
   .col-xl-center {
-    -webkit-align-self: center;
-    -ms-flex-item-align: center;
-            align-self: center;
-  }
+    align-self: center; }
   .col-xl-bottom {
-    -webkit-align-self: flex-end;
-    -ms-flex-item-align: end;
-            align-self: flex-end;
-  }
-}
+    align-self: flex-end; } }
 
 .table {
   width: 100%;
   max-width: 100%;
-  margin-bottom: 1rem;
-}
-.table th, .table td {
-  padding: .75rem;
-  line-height: 1.5;
-  vertical-align: top;
-  border-top: 1px solid #eceeef;
-}
-.table thead th {
-  vertical-align: bottom;
-  border-bottom: 2px solid #eceeef;
-}
-.table tbody + tbody {
-  border-top: 2px solid #eceeef;
-}
-.table .table {
-  background-color: #fff;
-}
-
-.table-sm th, .table-sm td {
-  padding: .3rem;
-}
+  margin-bottom: 1rem; }
+  .table th,
+  .table td {
+    padding: 0.75rem;
+    line-height: 1.5;
+    vertical-align: top;
+    border-top: 1px solid #eceeef; }
+  .table thead th {
+    vertical-align: bottom;
+    border-bottom: 2px solid #eceeef; }
+  .table tbody + tbody {
+    border-top: 2px solid #eceeef; }
+  .table .table {
+    background-color: #fff; }
+
+.table-sm th,
+.table-sm td {
+  padding: 0.3rem; }
 
 .table-bordered {
-  border: 1px solid #eceeef;
-}
-.table-bordered th, .table-bordered td {
-  border: 1px solid #eceeef;
-}
-.table-bordered thead th, .table-bordered thead td {
-  border-bottom-width: 2px;
-}
+  border: 1px solid #eceeef; }
+  .table-bordered th,
+  .table-bordered td {
+    border: 1px solid #eceeef; }
+  .table-bordered thead th,
+  .table-bordered thead td {
+    border-bottom-width: 2px; }
 
 .table-striped tbody tr:nth-of-type(odd) {
-  background-color: #f9f9f9;
-}
+  background-color: #f9f9f9; }
 
 .table-hover tbody tr:hover {
-  background-color: #f5f5f5;
-}
+  background-color: #f5f5f5; }
 
-.table-active, .table-active > th, .table-active > td {
-  background-color: #f5f5f5;
-}
+.table-active,
+.table-active > th,
+.table-active > td {
+  background-color: #f5f5f5; }
 
 .table-hover .table-active:hover {
-  background-color: #e8e8e8;
-}
-.table-hover .table-active:hover > td, .table-hover .table-active:hover > th {
-  background-color: #e8e8e8;
-}
+  background-color: #e8e8e8; }
+  .table-hover .table-active:hover > td,
+  .table-hover .table-active:hover > th {
+    background-color: #e8e8e8; }
 
-.table-success, .table-success > th, .table-success > td {
-  background-color: #dff0d8;
-}
+.table-success,
+.table-success > th,
+.table-success > td {
+  background-color: #dff0d8; }
 
 .table-hover .table-success:hover {
-  background-color: #d0e9c6;
-}
-.table-hover .table-success:hover > td, .table-hover .table-success:hover > th {
-  background-color: #d0e9c6;
-}
+  background-color: #d0e9c6; }
+  .table-hover .table-success:hover > td,
+  .table-hover .table-success:hover > th {
+    background-color: #d0e9c6; }
 
-.table-info, .table-info > th, .table-info > td {
-  background-color: #d9edf7;
-}
+.table-info,
+.table-info > th,
+.table-info > td {
+  background-color: #d9edf7; }
 
 .table-hover .table-info:hover {
-  background-color: #c4e3f3;
-}
-.table-hover .table-info:hover > td, .table-hover .table-info:hover > th {
-  background-color: #c4e3f3;
-}
+  background-color: #c4e3f3; }
+  .table-hover .table-info:hover > td,
+  .table-hover .table-info:hover > th {
+    background-color: #c4e3f3; }
 
-.table-warning, .table-warning > th, .table-warning > td {
-  background-color: #fcf8e3;
-}
+.table-warning,
+.table-warning > th,
+.table-warning > td {
+  background-color: #fcf8e3; }
 
 .table-hover .table-warning:hover {
-  background-color: #faf2cc;
-}
-.table-hover .table-warning:hover > td, .table-hover .table-warning:hover > th {
-  background-color: #faf2cc;
-}
+  background-color: #faf2cc; }
+  .table-hover .table-warning:hover > td,
+  .table-hover .table-warning:hover > th {
+    background-color: #faf2cc; }
 
-.table-danger, .table-danger > th, .table-danger > td {
-  background-color: #f2dede;
-}
+.table-danger,
+.table-danger > th,
+.table-danger > td {
+  background-color: #f2dede; }
 
 .table-hover .table-danger:hover {
-  background-color: #ebcccc;
-}
-.table-hover .table-danger:hover > td, .table-hover .table-danger:hover > th {
-  background-color: #ebcccc;
-}
+  background-color: #ebcccc; }
+  .table-hover .table-danger:hover > td,
+  .table-hover .table-danger:hover > th {
+    background-color: #ebcccc; }
 
 .table-responsive {
   display: block;
   width: 100%;
-  overflow-x: auto;
-}
+  overflow-x: auto; }
 
 .thead-inverse th {
   color: #fff;
-  background-color: #373a3c;
-}
+  background-color: #373a3c; }
 
 .thead-default th {
   color: #55595c;
-  background-color: #eceeef;
-}
+  background-color: #eceeef; }
 
 .table-inverse {
   color: #eceeef;
-  background-color: #373a3c;
-}
-.table-inverse.table-bordered {
-  border: 0;
-}
-.table-inverse th, .table-inverse td, .table-inverse thead th {
-  border-color: #55595c;
-}
+  background-color: #373a3c; }
+  .table-inverse.table-bordered {
+    border: 0; }
+  .table-inverse th,
+  .table-inverse td,
+  .table-inverse thead th {
+    border-color: #55595c; }
 
 .table-reflow thead {
-  float: left;
-}
+  float: left; }
+
 .table-reflow tbody {
   display: block;
-  white-space: nowrap;
-}
-.table-reflow th, .table-reflow td {
+  white-space: nowrap; }
+
+.table-reflow th,
+.table-reflow td {
   border-top: 1px solid #eceeef;
-  border-left: 1px solid #eceeef;
-}
-.table-reflow th:last-child, .table-reflow td:last-child {
-  border-right: 1px solid #eceeef;
-}
-.table-reflow thead:last-child tr:last-child th, .table-reflow thead:last-child tr:last-child td, .table-reflow tbody:last-child tr:last-child th, .table-reflow tbody:last-child tr:last-child td, .table-reflow tfoot:last-child tr:last-child th, .table-reflow tfoot:last-child tr:last-child td {
-  border-bottom: 1px solid #eceeef;
-}
+  border-left: 1px solid #eceeef; }
+  .table-reflow th:last-child,
+  .table-reflow td:last-child {
+    border-right: 1px solid #eceeef; }
+
+.table-reflow thead:last-child tr:last-child th,
+.table-reflow thead:last-child tr:last-child td,
+.table-reflow tbody:last-child tr:last-child th,
+.table-reflow tbody:last-child tr:last-child td,
+.table-reflow tfoot:last-child tr:last-child th,
+.table-reflow tfoot:last-child tr:last-child td {
+  border-bottom: 1px solid #eceeef; }
+
 .table-reflow tr {
-  float: left;
-}
-.table-reflow tr th, .table-reflow tr td {
-  display: block !important;
-  border: 1px solid #eceeef;
-}
+  float: left; }
+  .table-reflow tr th,
+  .table-reflow tr td {
+    display: block !important;
+    border: 1px solid #eceeef; }
 
 .form-control {
   display: block;
   width: 100%;
-  padding: .5rem .75rem;
+  padding: 0.5rem 0.75rem;
   font-size: 1rem;
   line-height: 1.5;
   color: #55595c;
   background-color: #fff;
   background-image: none;
   border: 1px solid #ccc;
-  border-radius: .25rem;
-  -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-       -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
-          transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
-}
-.form-control:not(textarea), .form-control:not(select[size]), .form-control:not(select[multiple]) {
-  height: 2.625rem;
-}
-.form-control:focus {
-  border-color: #66afe9;
-  outline: none;
-}
-.form-control::-webkit-input-placeholder {
-  color: #999;
-  opacity: 1;
-}
-.form-control::-moz-placeholder {
-  color: #999;
-  opacity: 1;
-}
-.form-control:-ms-input-placeholder {
-  color: #999;
-  opacity: 1;
-}
-.form-control::placeholder {
-  color: #999;
-  opacity: 1;
-}
-.form-control:disabled, .form-control[readonly], fieldset[disabled] .form-control {
-  background-color: #eceeef;
-  opacity: 1;
-}
-.form-control[disabled], fieldset[disabled] .form-control {
-  cursor: false;
-}
-
-.form-control-file, .form-control-range {
-  display: block;
-}
+  border-radius: 0.25rem;
+  transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; }
+  .form-control:not(textarea),
+  .form-control:not(select[size]),
+  .form-control:not(select[multiple]) {
+    height: 2.625rem; }
+  .form-control:focus {
+    border-color: #66afe9;
+    outline: none; }
+  .form-control::placeholder {
+    color: #999;
+    opacity: 1; }
+  .form-control:disabled,
+  .form-control[readonly],
+  fieldset[disabled] .form-control {
+    background-color: #eceeef;
+    opacity: 1; }
+  .form-control[disabled],
+  fieldset[disabled] .form-control {
+    cursor: not-allowed; }
+
+.form-control-file,
+.form-control-range {
+  display: block; }
 
 .form-control-label {
-  padding: .5625rem .75rem;
-  margin-bottom: 0;
-}
+  padding: 0.5625rem 0.75rem;
+  margin-bottom: 0; }
 
 .form-control-static {
   min-height: 2.625rem;
-  padding-top: .5625rem;
-  padding-bottom: .5625rem;
-  margin-bottom: 0;
-}
-.form-control-static.form-control-sm, .input-group-sm > .form-control-static.form-control, .input-group-sm > .form-control-static.input-group-addon, .input-group-sm > .input-group-btn > .form-control-static.btn, .form-control-static.form-control-lg, .input-group-lg > .form-control-static.form-control, .input-group-lg > .form-control-static.input-group-addon, .input-group-lg > .input-group-btn > .form-control-static.btn {
-  padding-right: 0;
-  padding-left: 0;
-}
-
-.form-control-sm, .input-group-sm > .form-control, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .btn {
+  padding-top: 0.5625rem;
+  padding-bottom: 0.5625rem;
+  margin-bottom: 0; }
+  .form-control-static.form-control-sm,
+  .input-group-sm > .form-control-static.form-control,
+  .input-group-sm > .form-control-static.input-group-addon,
+  .input-group-sm > .input-group-btn > .form-control-static.btn,
+  .form-control-static.form-control-lg, .input-group-lg > .form-control-static.form-control,
+  .input-group-lg > .form-control-static.input-group-addon,
+  .input-group-lg > .input-group-btn > .form-control-static.btn {
+    padding-right: 0;
+    padding-left: 0; }
+
+.form-control-sm, .input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
   height: 2rem;
-  padding: .3rem .75rem;
-  font-size: .85rem;
+  padding: 0.3rem 0.75rem;
+  font-size: 0.85rem;
   line-height: 1.5;
-  border-radius: .2rem;
-}
+  border-radius: 0.2rem; }
 
-.form-control-lg, .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn {
+.form-control-lg, .input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
   height: 3.291667rem;
-  padding: .75rem 1.5rem;
+  padding: 0.75rem 1.5rem;
   font-size: 1.25rem;
   line-height: 1.333333;
-  border-radius: .3rem;
-}
+  border-radius: 0.3rem; }
 
 .form-group {
-  margin-bottom: 15px;
-}
+  margin-bottom: 15px; }
 
-.radio, .checkbox {
+.radio,
+.checkbox {
   position: relative;
   display: block;
-  margin-bottom: .75rem;
-}
-.radio label, .checkbox label {
-  padding-left: 1.25rem;
-  margin-bottom: 0;
-  font-weight: normal;
-  cursor: pointer;
-}
-.radio label input:only-child, .checkbox label input:only-child {
-  position: static;
-}
-
-.radio input[type="radio"], .radio-inline input[type="radio"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] {
+  margin-bottom: 0.75rem; }
+  .radio label,
+  .checkbox label {
+    padding-left: 1.25rem;
+    margin-bottom: 0;
+    font-weight: normal;
+    cursor: pointer; }
+    .radio label input:only-child,
+    .checkbox label input:only-child {
+      position: static; }
+
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
   position: absolute;
   margin-top: .25rem;
-  margin-left: -1.25rem;
-}
+  margin-left: -1.25rem; }
 
-.radio + .radio, .checkbox + .checkbox {
-  margin-top: -.25rem;
-}
+.radio + .radio,
+.checkbox + .checkbox {
+  margin-top: -.25rem; }
 
-.radio-inline, .checkbox-inline {
+.radio-inline,
+.checkbox-inline {
   position: relative;
   display: inline-block;
   padding-left: 1.25rem;
   margin-bottom: 0;
   font-weight: normal;
   vertical-align: middle;
-  cursor: pointer;
-}
+  cursor: pointer; }
 
-.radio-inline + .radio-inline, .checkbox-inline + .checkbox-inline {
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
   margin-top: 0;
-  margin-left: .75rem;
-}
-
-input[type="radio"]:disabled, input[type="radio"].disabled, fieldset[disabled] input[type="radio"], input[type="checkbox"]:disabled, input[type="checkbox"].disabled, fieldset[disabled] input[type="checkbox"] {
-  cursor: false;
-}
-
-.radio-inline.disabled, fieldset[disabled] .radio-inline, .checkbox-inline.disabled, fieldset[disabled] .checkbox-inline {
-  cursor: false;
-}
-
-.radio.disabled label, fieldset[disabled] .radio label, .checkbox.disabled label, fieldset[disabled] .checkbox label {
-  cursor: false;
-}
+  margin-left: .75rem; }
+
+input[type="radio"]:disabled,
+input[type="radio"].disabled,
+fieldset[disabled] input[type="radio"],
+input[type="checkbox"]:disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="checkbox"] {
+  cursor: not-allowed; }
+
+.radio-inline.disabled,
+fieldset[disabled] .radio-inline,
+.checkbox-inline.disabled,
+fieldset[disabled] .checkbox-inline {
+  cursor: not-allowed; }
+
+.radio.disabled label,
+fieldset[disabled] .radio label,
+.checkbox.disabled label,
+fieldset[disabled] .checkbox label {
+  cursor: not-allowed; }
 
 .has-feedback {
-  position: relative;
-}
-.has-feedback .form-control {
-  padding-right: 3.28125rem;
-}
+  position: relative; }
+  .has-feedback .form-control {
+    padding-right: 3.28125rem; }
 
 .form-control-feedback {
   position: absolute;
@@ -2284,460 +1616,545 @@ input[type="radio"]:disabled, input[type="radio"].disabled, fieldset[disabled] i
   height: 2.625rem;
   line-height: 2.625rem;
   text-align: center;
-  pointer-events: none;
-}
+  pointer-events: none; }
 
-.input-lg + .form-control-feedback, .input-group-lg + .form-control-feedback {
+.input-lg + .form-control-feedback,
+.input-group-lg + .form-control-feedback {
   width: 3.291667rem;
   height: 3.291667rem;
-  line-height: 3.291667rem;
-}
+  line-height: 3.291667rem; }
 
-.input-sm + .form-control-feedback, .input-group-sm + .form-control-feedback {
+.input-sm + .form-control-feedback,
+.input-group-sm + .form-control-feedback {
   width: 2rem;
   height: 2rem;
-  line-height: 2rem;
-}
+  line-height: 2rem; }
+
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+  color: #3c763d; }
 
-.has-success .help-block, .has-success .control-label, .has-success .radio, .has-success .checkbox, .has-success .radio-inline, .has-success .checkbox-inline, .has-success.radio label, .has-success.checkbox label, .has-success.radio-inline label, .has-success.checkbox-inline label {
-  color: #3c763d;
-}
 .has-success .form-control {
-  border-color: #3c763d;
-}
-.has-success .form-control:focus {
-  border-color: #2b542c;
-}
+  border-color: #3c763d; }
+  .has-success .form-control:focus {
+    border-color: #2b542c; }
+
 .has-success .input-group-addon {
   color: #3c763d;
-  background-color: #dff0d8; 
   border-color: #3c763d;
-}
+  background-color: #dff0d8; }
+
 .has-success .form-control-feedback {
-  color: #3c763d;
-}
+  color: #3c763d; }
+
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+  color: #8a6d3b; }
 
-.has-warning .help-block, .has-warning .control-label, .has-warning .radio, .has-warning .checkbox, .has-warning .radio-inline, .has-warning .checkbox-inline, .has-warning.radio label, .has-warning.checkbox label, .has-warning.radio-inline label, .has-warning.checkbox-inline label {
-  color: #8a6d3b;
-}
 .has-warning .form-control {
-  border-color: #8a6d3b;
-}
-.has-warning .form-control:focus {
-  border-color: #66512c;
-}
+  border-color: #8a6d3b; }
+  .has-warning .form-control:focus {
+    border-color: #66512c; }
+
 .has-warning .input-group-addon {
   color: #8a6d3b;
-  background-color: #fcf8e3; 
   border-color: #8a6d3b;
-}
+  background-color: #fcf8e3; }
+
 .has-warning .form-control-feedback {
-  color: #8a6d3b;
-}
+  color: #8a6d3b; }
+
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+  color: #a94442; }
 
-.has-error .help-block, .has-error .control-label, .has-error .radio, .has-error .checkbox, .has-error .radio-inline, .has-error .checkbox-inline, .has-error.radio label, .has-error.checkbox label, .has-error.radio-inline label, .has-error.checkbox-inline label {
-  color: #a94442;
-}
 .has-error .form-control {
-  border-color: #a94442;
-}
-.has-error .form-control:focus {
-  border-color: #843534;
-}
+  border-color: #a94442; }
+  .has-error .form-control:focus {
+    border-color: #843534; }
+
 .has-error .input-group-addon {
   color: #a94442;
-  background-color: #f2dede; 
   border-color: #a94442;
-}
+  background-color: #f2dede; }
+
 .has-error .form-control-feedback {
-  color: #a94442;
-}
+  color: #a94442; }
 
 .has-feedback label ~ .form-control-feedback {
-  top: 6;
-}
+  top: 6; }
+
 .has-feedback label.sr-only ~ .form-control-feedback {
-  top: 0;
-}
+  top: 0; }
 
 .help-block {
   display: block;
   margin-top: .25rem;
   margin-bottom: .75rem;
-  color: #747a7f;
-}
+  color: #747a7f; }
 
 @media (min-width: 34em) {
   .form-inline .form-group {
     display: inline-block;
     margin-bottom: 0;
-    vertical-align: middle;
-  }
+    vertical-align: middle; }
   .form-inline .form-control {
     display: inline-block;
     width: auto;
-    vertical-align: middle;
-  }
+    vertical-align: middle; }
   .form-inline .form-control-static {
-    display: inline-block;
-  }
+    display: inline-block; }
   .form-inline .input-group {
     display: inline-table;
-    vertical-align: middle;
-  }
-  .form-inline .input-group .input-group-addon, .form-inline .input-group .input-group-btn, .form-inline .input-group .form-control {
-    width: auto;
-  }
+    vertical-align: middle; }
+    .form-inline .input-group .input-group-addon,
+    .form-inline .input-group .input-group-btn,
+    .form-inline .input-group .form-control {
+      width: auto; }
   .form-inline .input-group > .form-control {
-    width: 100%;
-  }
+    width: 100%; }
   .form-inline .control-label {
     margin-bottom: 0;
-    vertical-align: middle;
-  }
-  .form-inline .radio, .form-inline .checkbox {
+    vertical-align: middle; }
+  .form-inline .radio,
+  .form-inline .checkbox {
     display: inline-block;
     margin-top: 0;
     margin-bottom: 0;
-    vertical-align: middle;
-  }
-  .form-inline .radio label, .form-inline .checkbox label {
-    padding-left: 0;
-  }
-  .form-inline .radio input[type="radio"], .form-inline .checkbox input[type="checkbox"] {
+    vertical-align: middle; }
+    .form-inline .radio label,
+    .form-inline .checkbox label {
+      padding-left: 0; }
+  .form-inline .radio input[type="radio"],
+  .form-inline .checkbox input[type="checkbox"] {
     position: relative;
-    margin-left: 0;
-  }
+    margin-left: 0; }
   .form-inline .has-feedback .form-control-feedback {
-    top: 0;
-  }
-}
+    top: 0; } }
 
 .btn {
   display: inline-block;
-  padding: .5rem .75rem;
-  font-size: 1rem;
   font-weight: normal;
-  line-height: 1.5;
   text-align: center;
   white-space: nowrap;
   vertical-align: middle;
-  -ms-touch-action: manipulation;
-      touch-action: manipulation;
+  touch-action: manipulation;
   cursor: pointer;
-  -webkit-user-select: none;
-     -moz-user-select: none;
-      -ms-user-select: none;
-          user-select: none;
-  border: .0625rem solid transparent;
-  border-radius: .25rem;
-  -webkit-transition: all .2s ease-in-out;
-       -o-transition: all .2s ease-in-out;
-          transition: all .2s ease-in-out;
-}
-.btn:focus, .btn.focus, .btn:active:focus, .btn:active.focus, .btn.active:focus, .btn.active.focus {
-  outline: thin dotted;
-  outline: 5px auto -webkit-focus-ring-color;
-  outline-offset: -2px;
-}
-.btn:focus, .btn:hover {
-  text-decoration: none;
-}
-.btn.focus {
-  text-decoration: none;
-}
-.btn:active, .btn.active {
-  background-image: none;
-  outline: 0;
-}
-.btn.disabled, .btn:disabled, fieldset[disabled] .btn {
-  cursor: false;
-  opacity: .65;
-}
+  user-select: none;
+  border: 0.0625rem solid transparent;
+  padding: 0.5rem 0.75rem;
+  font-size: 1rem;
+  line-height: 1.5;
+  border-radius: 0.25rem;
+  transition: all 0.2s ease-in-out; }
+  .btn:focus,
+  .btn.focus,
+  .btn:active:focus,
+  .btn:active.focus,
+  .btn.active:focus,
+  .btn.active.focus {
+    outline: thin dotted;
+    outline: 5px auto -webkit-focus-ring-color;
+    outline-offset: -2px; }
+  .btn:focus,
+  .btn:hover {
+    text-decoration: none; }
+  .btn.focus {
+    text-decoration: none; }
+  .btn:active,
+  .btn.active {
+    background-image: none;
+    outline: 0; }
+  .btn.disabled,
+  .btn:disabled,
+  fieldset[disabled] .btn {
+    cursor: not-allowed;
+    opacity: .65; }
 
-a.btn.disaabled, fieldset[disabled] a.btn {
-  pointer-events: none;
-}
+a.btn.disaabled,
+fieldset[disabled] a.btn {
+  pointer-events: none; }
 
 .btn-primary {
   color: #fff;
   background-color: #0275d8;
-  border-color: #0267bf;
-}
-.btn-primary:focus, .btn-primary.focus, .btn-primary:active, .btn-primary.active, .open > .btn-primary.dropdown-toggle {
-  color: #fff;
-  background-color: #025aa5;
-  border-color: #014682;
-}
-.btn-primary:hover {
-  color: #fff;
-  background-color: #025aa5;
-  border-color: #014682;
-}
-.btn-primary:active, .btn-primary.active, .open > .btn-primary.dropdown-toggle {
-  background-image: none;
-}
-.btn-primary.disabled, .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary.disabled:active, .btn-primary.disabled.active, .btn-primary:disabled, .btn-primary:disabled:focus, .btn-primary:disabled.focus, .btn-primary:disabled:active, .btn-primary:disabled.active, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:active, fieldset[disabled] .btn-primary.active {
-  background-color: #0275d8;
-  border-color: #0267bf;
-}
-.btn-primary.disabled:hover, .btn-primary:disabled:hover, fieldset[disabled] .btn-primary:hover {
-  background-color: #0275d8;
-  border-color: #0267bf;
-}
-.btn-primary .badge {
-  color: #0275d8;
-  background-color: #fff;
-}
+  border-color: #0267bf; }
+  .btn-primary:focus,
+  .btn-primary.focus,
+  .btn-primary:active,
+  .btn-primary.active,
+  .open > .btn-primary.dropdown-toggle {
+    color: #fff;
+    background-color: #025aa5;
+    border-color: #014682; }
+  .btn-primary:hover {
+    color: #fff;
+    background-color: #025aa5;
+    border-color: #014682; }
+  .btn-primary:active,
+  .btn-primary.active,
+  .open > .btn-primary.dropdown-toggle {
+    background-image: none; }
+  .btn-primary.disabled,
+  .btn-primary.disabled:focus,
+  .btn-primary.disabled.focus,
+  .btn-primary.disabled:active,
+  .btn-primary.disabled.active,
+  .btn-primary:disabled,
+  .btn-primary:disabled:focus,
+  .btn-primary:disabled.focus,
+  .btn-primary:disabled:active,
+  .btn-primary:disabled.active,
+  fieldset[disabled] .btn-primary,
+  fieldset[disabled] .btn-primary:focus,
+  fieldset[disabled] .btn-primary.focus,
+  fieldset[disabled] .btn-primary:active,
+  fieldset[disabled] .btn-primary.active {
+    background-color: #0275d8;
+    border-color: #0267bf; }
+  .btn-primary.disabled:hover,
+  .btn-primary:disabled:hover,
+  fieldset[disabled] .btn-primary:hover {
+    background-color: #0275d8;
+    border-color: #0267bf; }
+  .btn-primary .badge {
+    color: #0275d8;
+    background-color: #fff; }
 
 .btn-secondary {
   color: #373a3c;
   background-color: #fff;
-  border-color: #ccc;
-}
-.btn-secondary:focus, .btn-secondary.focus, .btn-secondary:active, .btn-secondary.active, .open > .btn-secondary.dropdown-toggle {
-  color: #373a3c;
-  background-color: #e6e6e6;
-  border-color: #adadad;
-}
-.btn-secondary:hover {
-  color: #373a3c;
-  background-color: #e6e6e6;
-  border-color: #adadad;
-}
-.btn-secondary:active, .btn-secondary.active, .open > .btn-secondary.dropdown-toggle {
-  background-image: none;
-}
-.btn-secondary.disabled, .btn-secondary.disabled:focus, .btn-secondary.disabled.focus, .btn-secondary.disabled:active, .btn-secondary.disabled.active, .btn-secondary:disabled, .btn-secondary:disabled:focus, .btn-secondary:disabled.focus, .btn-secondary:disabled:active, .btn-secondary:disabled.active, fieldset[disabled] .btn-secondary, fieldset[disabled] .btn-secondary:focus, fieldset[disabled] .btn-secondary.focus, fieldset[disabled] .btn-secondary:active, fieldset[disabled] .btn-secondary.active {
-  background-color: #fff;
-  border-color: #ccc;
-}
-.btn-secondary.disabled:hover, .btn-secondary:disabled:hover, fieldset[disabled] .btn-secondary:hover {
-  background-color: #fff;
-  border-color: #ccc;
-}
-.btn-secondary .badge {
-  color: #fff;
-  background-color: #373a3c;
-}
+  border-color: #ccc; }
+  .btn-secondary:focus,
+  .btn-secondary.focus,
+  .btn-secondary:active,
+  .btn-secondary.active,
+  .open > .btn-secondary.dropdown-toggle {
+    color: #373a3c;
+    background-color: #e6e6e6;
+    border-color: #adadad; }
+  .btn-secondary:hover {
+    color: #373a3c;
+    background-color: #e6e6e6;
+    border-color: #adadad; }
+  .btn-secondary:active,
+  .btn-secondary.active,
+  .open > .btn-secondary.dropdown-toggle {
+    background-image: none; }
+  .btn-secondary.disabled,
+  .btn-secondary.disabled:focus,
+  .btn-secondary.disabled.focus,
+  .btn-secondary.disabled:active,
+  .btn-secondary.disabled.active,
+  .btn-secondary:disabled,
+  .btn-secondary:disabled:focus,
+  .btn-secondary:disabled.focus,
+  .btn-secondary:disabled:active,
+  .btn-secondary:disabled.active,
+  fieldset[disabled] .btn-secondary,
+  fieldset[disabled] .btn-secondary:focus,
+  fieldset[disabled] .btn-secondary.focus,
+  fieldset[disabled] .btn-secondary:active,
+  fieldset[disabled] .btn-secondary.active {
+    background-color: #fff;
+    border-color: #ccc; }
+  .btn-secondary.disabled:hover,
+  .btn-secondary:disabled:hover,
+  fieldset[disabled] .btn-secondary:hover {
+    background-color: #fff;
+    border-color: #ccc; }
+  .btn-secondary .badge {
+    color: #fff;
+    background-color: #373a3c; }
 
 .btn-info {
   color: #fff;
   background-color: #5bc0de;
-  border-color: #46b8da;
-}
-.btn-info:focus, .btn-info.focus, .btn-info:active, .btn-info.active, .open > .btn-info.dropdown-toggle {
-  color: #fff;
-  background-color: #31b0d5;
-  border-color: #269abc;
-}
-.btn-info:hover {
-  color: #fff;
-  background-color: #31b0d5;
-  border-color: #269abc;
-}
-.btn-info:active, .btn-info.active, .open > .btn-info.dropdown-toggle {
-  background-image: none;
-}
-.btn-info.disabled, .btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info.disabled:active, .btn-info.disabled.active, .btn-info:disabled, .btn-info:disabled:focus, .btn-info:disabled.focus, .btn-info:disabled:active, .btn-info:disabled.active, fieldset[disabled] .btn-info, fieldset[disabled] .btn-info:focus, fieldset[disabled] .btn-info.focus, fieldset[disabled] .btn-info:active, fieldset[disabled] .btn-info.active {
-  background-color: #5bc0de;
-  border-color: #46b8da;
-}
-.btn-info.disabled:hover, .btn-info:disabled:hover, fieldset[disabled] .btn-info:hover {
-  background-color: #5bc0de;
-  border-color: #46b8da;
-}
-.btn-info .badge {
-  color: #5bc0de;
-  background-color: #fff;
-}
+  border-color: #46b8da; }
+  .btn-info:focus,
+  .btn-info.focus,
+  .btn-info:active,
+  .btn-info.active,
+  .open > .btn-info.dropdown-toggle {
+    color: #fff;
+    background-color: #31b0d5;
+    border-color: #269abc; }
+  .btn-info:hover {
+    color: #fff;
+    background-color: #31b0d5;
+    border-color: #269abc; }
+  .btn-info:active,
+  .btn-info.active,
+  .open > .btn-info.dropdown-toggle {
+    background-image: none; }
+  .btn-info.disabled,
+  .btn-info.disabled:focus,
+  .btn-info.disabled.focus,
+  .btn-info.disabled:active,
+  .btn-info.disabled.active,
+  .btn-info:disabled,
+  .btn-info:disabled:focus,
+  .btn-info:disabled.focus,
+  .btn-info:disabled:active,
+  .btn-info:disabled.active,
+  fieldset[disabled] .btn-info,
+  fieldset[disabled] .btn-info:focus,
+  fieldset[disabled] .btn-info.focus,
+  fieldset[disabled] .btn-info:active,
+  fieldset[disabled] .btn-info.active {
+    background-color: #5bc0de;
+    border-color: #46b8da; }
+  .btn-info.disabled:hover,
+  .btn-info:disabled:hover,
+  fieldset[disabled] .btn-info:hover {
+    background-color: #5bc0de;
+    border-color: #46b8da; }
+  .btn-info .badge {
+    color: #5bc0de;
+    background-color: #fff; }
 
 .btn-success {
   color: #fff;
   background-color: #5cb85c;
-  border-color: #4cae4c;
-}
-.btn-success:focus, .btn-success.focus, .btn-success:active, .btn-success.active, .open > .btn-success.dropdown-toggle {
-  color: #fff;
-  background-color: #449d44;
-  border-color: #398439;
-}
-.btn-success:hover {
-  color: #fff;
-  background-color: #449d44;
-  border-color: #398439;
-}
-.btn-success:active, .btn-success.active, .open > .btn-success.dropdown-toggle {
-  background-image: none;
-}
-.btn-success.disabled, .btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success.disabled:active, .btn-success.disabled.active, .btn-success:disabled, .btn-success:disabled:focus, .btn-success:disabled.focus, .btn-success:disabled:active, .btn-success:disabled.active, fieldset[disabled] .btn-success, fieldset[disabled] .btn-success:focus, fieldset[disabled] .btn-success.focus, fieldset[disabled] .btn-success:active, fieldset[disabled] .btn-success.active {
-  background-color: #5cb85c;
-  border-color: #4cae4c;
-}
-.btn-success.disabled:hover, .btn-success:disabled:hover, fieldset[disabled] .btn-success:hover {
-  background-color: #5cb85c;
-  border-color: #4cae4c;
-}
-.btn-success .badge {
-  color: #5cb85c;
-  background-color: #fff;
-}
+  border-color: #4cae4c; }
+  .btn-success:focus,
+  .btn-success.focus,
+  .btn-success:active,
+  .btn-success.active,
+  .open > .btn-success.dropdown-toggle {
+    color: #fff;
+    background-color: #449d44;
+    border-color: #398439; }
+  .btn-success:hover {
+    color: #fff;
+    background-color: #449d44;
+    border-color: #398439; }
+  .btn-success:active,
+  .btn-success.active,
+  .open > .btn-success.dropdown-toggle {
+    background-image: none; }
+  .btn-success.disabled,
+  .btn-success.disabled:focus,
+  .btn-success.disabled.focus,
+  .btn-success.disabled:active,
+  .btn-success.disabled.active,
+  .btn-success:disabled,
+  .btn-success:disabled:focus,
+  .btn-success:disabled.focus,
+  .btn-success:disabled:active,
+  .btn-success:disabled.active,
+  fieldset[disabled] .btn-success,
+  fieldset[disabled] .btn-success:focus,
+  fieldset[disabled] .btn-success.focus,
+  fieldset[disabled] .btn-success:active,
+  fieldset[disabled] .btn-success.active {
+    background-color: #5cb85c;
+    border-color: #4cae4c; }
+  .btn-success.disabled:hover,
+  .btn-success:disabled:hover,
+  fieldset[disabled] .btn-success:hover {
+    background-color: #5cb85c;
+    border-color: #4cae4c; }
+  .btn-success .badge {
+    color: #5cb85c;
+    background-color: #fff; }
 
 .btn-warning {
   color: #fff;
   background-color: #f0ad4e;
-  border-color: #eea236;
-}
-.btn-warning:focus, .btn-warning.focus, .btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle {
-  color: #fff;
-  background-color: #ec971f;
-  border-color: #d58512;
-}
-.btn-warning:hover {
-  color: #fff;
-  background-color: #ec971f;
-  border-color: #d58512;
-}
-.btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle {
-  background-image: none;
-}
-.btn-warning.disabled, .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning.disabled:active, .btn-warning.disabled.active, .btn-warning:disabled, .btn-warning:disabled:focus, .btn-warning:disabled.focus, .btn-warning:disabled:active, .btn-warning:disabled.active, fieldset[disabled] .btn-warning, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning.focus, fieldset[disabled] .btn-warning:active, fieldset[disabled] .btn-warning.active {
-  background-color: #f0ad4e;
-  border-color: #eea236;
-}
-.btn-warning.disabled:hover, .btn-warning:disabled:hover, fieldset[disabled] .btn-warning:hover {
-  background-color: #f0ad4e;
-  border-color: #eea236;
-}
-.btn-warning .badge {
-  color: #f0ad4e;
-  background-color: #fff;
-}
+  border-color: #eea236; }
+  .btn-warning:focus,
+  .btn-warning.focus,
+  .btn-warning:active,
+  .btn-warning.active,
+  .open > .btn-warning.dropdown-toggle {
+    color: #fff;
+    background-color: #ec971f;
+    border-color: #d58512; }
+  .btn-warning:hover {
+    color: #fff;
+    background-color: #ec971f;
+    border-color: #d58512; }
+  .btn-warning:active,
+  .btn-warning.active,
+  .open > .btn-warning.dropdown-toggle {
+    background-image: none; }
+  .btn-warning.disabled,
+  .btn-warning.disabled:focus,
+  .btn-warning.disabled.focus,
+  .btn-warning.disabled:active,
+  .btn-warning.disabled.active,
+  .btn-warning:disabled,
+  .btn-warning:disabled:focus,
+  .btn-warning:disabled.focus,
+  .btn-warning:disabled:active,
+  .btn-warning:disabled.active,
+  fieldset[disabled] .btn-warning,
+  fieldset[disabled] .btn-warning:focus,
+  fieldset[disabled] .btn-warning.focus,
+  fieldset[disabled] .btn-warning:active,
+  fieldset[disabled] .btn-warning.active {
+    background-color: #f0ad4e;
+    border-color: #eea236; }
+  .btn-warning.disabled:hover,
+  .btn-warning:disabled:hover,
+  fieldset[disabled] .btn-warning:hover {
+    background-color: #f0ad4e;
+    border-color: #eea236; }
+  .btn-warning .badge {
+    color: #f0ad4e;
+    background-color: #fff; }
 
 .btn-danger {
   color: #fff;
   background-color: #d9534f;
-  border-color: #d43f3a;
-}
-.btn-danger:focus, .btn-danger.focus, .btn-danger:active, .btn-danger.active, .open > .btn-danger.dropdown-toggle {
-  color: #fff;
-  background-color: #c9302c;
-  border-color: #ac2925;
-}
-.btn-danger:hover {
-  color: #fff;
-  background-color: #c9302c;
-  border-color: #ac2925;
-}
-.btn-danger:active, .btn-danger.active, .open > .btn-danger.dropdown-toggle {
-  background-image: none;
-}
-.btn-danger.disabled, .btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger.disabled:active, .btn-danger.disabled.active, .btn-danger:disabled, .btn-danger:disabled:focus, .btn-danger:disabled.focus, .btn-danger:disabled:active, .btn-danger:disabled.active, fieldset[disabled] .btn-danger, fieldset[disabled] .btn-danger:focus, fieldset[disabled] .btn-danger.focus, fieldset[disabled] .btn-danger:active, fieldset[disabled] .btn-danger.active {
-  background-color: #d9534f;
-  border-color: #d43f3a;
-}
-.btn-danger.disabled:hover, .btn-danger:disabled:hover, fieldset[disabled] .btn-danger:hover {
-  background-color: #d9534f;
-  border-color: #d43f3a;
-}
-.btn-danger .badge {
-  color: #d9534f;
-  background-color: #fff;
-}
+  border-color: #d43f3a; }
+  .btn-danger:focus,
+  .btn-danger.focus,
+  .btn-danger:active,
+  .btn-danger.active,
+  .open > .btn-danger.dropdown-toggle {
+    color: #fff;
+    background-color: #c9302c;
+    border-color: #ac2925; }
+  .btn-danger:hover {
+    color: #fff;
+    background-color: #c9302c;
+    border-color: #ac2925; }
+  .btn-danger:active,
+  .btn-danger.active,
+  .open > .btn-danger.dropdown-toggle {
+    background-image: none; }
+  .btn-danger.disabled,
+  .btn-danger.disabled:focus,
+  .btn-danger.disabled.focus,
+  .btn-danger.disabled:active,
+  .btn-danger.disabled.active,
+  .btn-danger:disabled,
+  .btn-danger:disabled:focus,
+  .btn-danger:disabled.focus,
+  .btn-danger:disabled:active,
+  .btn-danger:disabled.active,
+  fieldset[disabled] .btn-danger,
+  fieldset[disabled] .btn-danger:focus,
+  fieldset[disabled] .btn-danger.focus,
+  fieldset[disabled] .btn-danger:active,
+  fieldset[disabled] .btn-danger.active {
+    background-color: #d9534f;
+    border-color: #d43f3a; }
+  .btn-danger.disabled:hover,
+  .btn-danger:disabled:hover,
+  fieldset[disabled] .btn-danger:hover {
+    background-color: #d9534f;
+    border-color: #d43f3a; }
+  .btn-danger .badge {
+    color: #d9534f;
+    background-color: #fff; }
 
 .btn-link {
   font-weight: normal;
   color: #0275d8;
-  border-radius: 0;
-}
-.btn-link, .btn-link:active, .btn-link.active, .btn-link:disabled, fieldset[disabled] .btn-link {
-  background-color: transparent;
-}
-.btn-link, .btn-link:focus, .btn-link:active {
-  border-color: transparent;
-}
-.btn-link:hover {
-  border-color: transparent;
-}
-.btn-link:focus, .btn-link:hover {
-  color: #014c8c;
-  text-decoration: underline;
-  background-color: transparent;
-}
-.btn-link:disabled:focus, .btn-link:disabled:hover, fieldset[disabled] .btn-link:focus, fieldset[disabled] .btn-link:hover {
-  color: #818a91;
-  text-decoration: none;
-}
+  border-radius: 0; }
+  .btn-link,
+  .btn-link:active,
+  .btn-link.active,
+  .btn-link:disabled,
+  fieldset[disabled] .btn-link {
+    background-color: transparent; }
+  .btn-link,
+  .btn-link:focus,
+  .btn-link:active {
+    border-color: transparent; }
+  .btn-link:hover {
+    border-color: transparent; }
+  .btn-link:focus,
+  .btn-link:hover {
+    color: #014c8c;
+    text-decoration: underline;
+    background-color: transparent; }
+  .btn-link:disabled:focus,
+  .btn-link:disabled:hover,
+  fieldset[disabled] .btn-link:focus,
+  fieldset[disabled] .btn-link:hover {
+    color: #818a91;
+    text-decoration: none; }
 
 .btn-lg, .btn-group-lg > .btn {
-  padding: .75rem 1.5rem;
+  padding: 0.75rem 1.5rem;
   font-size: 1.25rem;
   line-height: 1.333333;
-  border-radius: .3rem;
-}
+  border-radius: 0.3rem; }
 
 .btn-sm, .btn-group-sm > .btn {
-  padding: .3rem .75rem;
-  font-size: .85rem;
+  padding: 0.3rem 0.75rem;
+  font-size: 0.85rem;
   line-height: 1.5;
-  border-radius: .2rem;
-}
+  border-radius: 0.2rem; }
 
 .btn-xs, .btn-group-xs > .btn {
-  padding: .2rem .5rem;
-  font-size: .75rem;
+  padding: 0.2rem 0.5rem;
+  font-size: 0.75rem;
   line-height: 1.5;
-  border-radius: .2rem;
-}
+  border-radius: 0.2rem; }
 
 .btn-block {
   display: block;
-  width: 100%;
-}
+  width: 100%; }
 
 .btn-block + .btn-block {
-  margin-top: 5px;
-}
+  margin-top: 5px; }
 
-input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="button"].btn-block {
-  width: 100%;
-}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+  width: 100%; }
 
 .fade {
   opacity: 0;
-  -webkit-transition: opacity .15s linear;
-       -o-transition: opacity .15s linear;
-          transition: opacity .15s linear;
-}
-.fade.in {
-  opacity: 1;
-}
+  transition: opacity 0.15s linear; }
+  .fade.in {
+    opacity: 1; }
 
 .collapse {
-  display: none;
-}
-.collapse.in {
-  display: block;
-}
+  display: none; }
+  .collapse.in {
+    display: block; }
 
 .collapsing {
   position: relative;
   height: 0;
   overflow: hidden;
-  -webkit-transition-timing-function: ease;
-       -o-transition-timing-function: ease;
-          transition-timing-function: ease;
-  -webkit-transition-duration: .35s;
-       -o-transition-duration: .35s;
-          transition-duration: .35s;
-  -webkit-transition-property: height;
-       -o-transition-property: height;
-          transition-property: height;
-}
-
-.dropup, .dropdown {
-  position: relative;
-}
+  transition-timing-function: ease;
+  transition-duration: .35s;
+  transition-property: height; }
+
+.dropup,
+.dropdown {
+  position: relative; }
 
 .dropdown-toggle:after {
   display: inline-block;
@@ -2746,13 +2163,12 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto
   margin-left: .25rem;
   vertical-align: middle;
   content: "";
-  border-top: .3em solid;
-  border-right: .3em solid transparent;
-  border-left: .3em solid transparent;
-}
+  border-top: 0.3em solid;
+  border-right: 0.3em solid transparent;
+  border-left: 0.3em solid transparent; }
+
 .dropdown-toggle:focus {
-  outline: 0;
-}
+  outline: 0; }
 
 .dropdown-menu {
   position: absolute;
@@ -2768,76 +2184,71 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto
   text-align: left;
   list-style: none;
   background-color: #fff;
-  -webkit-background-clip: padding-box;
-          background-clip: padding-box;
-  border: 1px solid rgba(0, 0, 0, .15);
-  border-radius: .25rem;
-}
-.dropdown-menu .divider {
-  height: 1px;
-  margin: -.5 0;
-  overflow: hidden;
-  background-color: #e5e5e5;
-}
-.dropdown-menu > li > a {
-  display: block;
-  padding: 3px 20px;
-  clear: both;
-  font-weight: normal;
-  line-height: 1.5;
-  color: #373a3c;
-  white-space: nowrap;
-}
-
-.dropdown-menu > li > a:focus, .dropdown-menu > li > a:hover {
+  background-clip: padding-box;
+  border: 1px solid rgba(0, 0, 0, 0.15);
+  border-radius: 0.25rem; }
+  .dropdown-menu .divider {
+    height: 1px;
+    margin: 0.5rem 0;
+    overflow: hidden;
+    background-color: #e5e5e5; }
+  .dropdown-menu > li > a {
+    display: block;
+    padding: 3px 20px;
+    clear: both;
+    font-weight: normal;
+    line-height: 1.5;
+    color: #373a3c;
+    white-space: nowrap; }
+
+.dropdown-menu > li > a:focus,
+.dropdown-menu > li > a:hover {
   color: #2b2d2f;
   text-decoration: none;
-  background-color: #f5f5f5;
-}
+  background-color: #f5f5f5; }
 
-.dropdown-menu > .active > a, .dropdown-menu > .active > a:focus, .dropdown-menu > .active > a:hover {
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:focus,
+.dropdown-menu > .active > a:hover {
   color: #fff;
   text-decoration: none;
   background-color: #0275d8;
-  outline: 0;
-}
+  outline: 0; }
 
-.dropdown-menu > .disabled > a, .dropdown-menu > .disabled > a:focus, .dropdown-menu > .disabled > a:hover {
-  color: #818a91;
-}
-.dropdown-menu > .disabled > a:focus, .dropdown-menu > .disabled > a:hover {
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:focus,
+.dropdown-menu > .disabled > a:hover {
+  color: #818a91; }
+
+.dropdown-menu > .disabled > a:focus,
+.dropdown-menu > .disabled > a:hover {
   text-decoration: none;
-  cursor: false;
+  cursor: not-allowed;
   background-color: transparent;
   background-image: none;
-  filter: "progid:DXImageTransform.Microsoft.gradient(enabled = false)";
-}
+  filter: "progid:DXImageTransform.Microsoft.gradient(enabled = false)"; }
 
 .open > .dropdown-menu {
-  display: block;
-}
+  display: block; }
+
 .open > a {
-  outline: 0;
-}
+  outline: 0; }
 
 .dropdown-menu-right {
   right: 0;
-  left: auto;
-}
+  left: auto; }
 
 .dropdown-menu-left {
   right: auto;
-  left: 0;
-}
+  left: 0; }
 
 .dropdown-header {
   display: block;
   padding: 3px 20px;
-  font-size: .85rem;
+  font-size: 0.85rem;
   line-height: 1.5;
   color: #818a91;
-  white-space: nowrap;
-}
+  white-space: nowrap; }
 
 .dropdown-backdrop {
   position: fixed;
@@ -2845,208 +2256,197 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto
   right: 0;
   bottom: 0;
   left: 0;
-  z-index: 990;
-}
+  z-index: 990; }
 
 .pull-right > .dropdown-menu {
   right: 0;
-  left: auto;
-}
+  left: auto; }
 
-.dropup .caret, .navbar-fixed-bottom .dropdown .caret {
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
   content: "";
   border-top: 0;
-  border-bottom: .3em solid;
-}
-.dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu {
+  border-bottom: 0.3em solid; }
+
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
   top: auto;
   bottom: 100%;
-  margin-bottom: 2px;
-}
+  margin-bottom: 2px; }
 
-.btn-group, .btn-group-vertical {
+.btn-group,
+.btn-group-vertical {
   position: relative;
   display: inline-block;
-  vertical-align: middle;
-}
-.btn-group > .btn, .btn-group-vertical > .btn {
-  position: relative;
-  float: left;
-}
-.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active, .btn-group-vertical > .btn:focus, .btn-group-vertical > .btn:active, .btn-group-vertical > .btn.active {
-  z-index: 2;
-}
-.btn-group > .btn:hover, .btn-group-vertical > .btn:hover {
-  z-index: 2;
-}
-
-.btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group {
-  margin-left: -1px;
-}
+  vertical-align: middle; }
+  .btn-group > .btn,
+  .btn-group-vertical > .btn {
+    position: relative;
+    float: left; }
+    .btn-group > .btn:focus,
+    .btn-group > .btn:active,
+    .btn-group > .btn.active,
+    .btn-group-vertical > .btn:focus,
+    .btn-group-vertical > .btn:active,
+    .btn-group-vertical > .btn.active {
+      z-index: 2; }
+    .btn-group > .btn:hover,
+    .btn-group-vertical > .btn:hover {
+      z-index: 2; }
+
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+  margin-left: -1px; }
 
 .btn-toolbar {
-  margin-left: -5px;
-}
-.btn-toolbar:before, .btn-toolbar:after {
-  display: table; 
-  content: " ";
-}
-.btn-toolbar:after {
-  clear: both;
-}
-.btn-toolbar .btn-group, .btn-toolbar .input-group {
-  float: left;
-}
-.btn-toolbar > .btn, .btn-toolbar > .btn-group, .btn-toolbar > .input-group {
-  margin-left: 5px;
-}
+  margin-left: -5px; }
+  .btn-toolbar:before,
+  .btn-toolbar:after {
+    content: " ";
+    display: table; }
+  .btn-toolbar:after {
+    clear: both; }
+  .btn-toolbar .btn-group,
+  .btn-toolbar .input-group {
+    float: left; }
+  .btn-toolbar > .btn,
+  .btn-toolbar > .btn-group,
+  .btn-toolbar > .input-group {
+    margin-left: 5px; }
 
 .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
-  border-radius: 0;
-}
+  border-radius: 0; }
 
 .btn-group > .btn:first-child {
-  margin-left: 0;
-}
-.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
-  border-top-right-radius: 0; 
-  border-bottom-right-radius: 0;
-}
+  margin-left: 0; }
+  .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+    border-bottom-right-radius: 0;
+    border-top-right-radius: 0; }
 
-.btn-group > .btn:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) {
-  border-top-left-radius: 0; 
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
   border-bottom-left-radius: 0;
-}
+  border-top-left-radius: 0; }
 
 .btn-group > .btn-group {
-  float: left;
-}
+  float: left; }
 
 .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
-  border-radius: 0;
-}
+  border-radius: 0; }
 
-.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
-  border-top-right-radius: 0; 
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
   border-bottom-right-radius: 0;
-}
+  border-top-right-radius: 0; }
 
 .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
-  border-top-left-radius: 0; 
   border-bottom-left-radius: 0;
-}
+  border-top-left-radius: 0; }
 
-.btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle {
-  outline: 0;
-}
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+  outline: 0; }
 
 .btn-group > .btn + .dropdown-toggle {
   padding-right: 8px;
-  padding-left: 8px;
-}
+  padding-left: 8px; }
 
 .btn-group > .btn-lg + .dropdown-toggle, .btn-group-lg.btn-group > .btn + .dropdown-toggle {
   padding-right: 12px;
-  padding-left: 12px;
-}
+  padding-left: 12px; }
 
 .btn .caret {
-  margin-left: 0;
-}
+  margin-left: 0; }
 
 .btn-lg .caret, .btn-group-lg > .btn .caret {
-  border-width: .3em .3em 0;
-  border-bottom-width: 0;
-}
+  border-width: 0.3em 0.3em 0;
+  border-bottom-width: 0; }
 
 .dropup .btn-lg .caret, .dropup .btn-group-lg > .btn .caret {
-  border-width: 0 .3em .3em;
-}
+  border-width: 0 0.3em 0.3em; }
 
-.btn-group-vertical > .btn, .btn-group-vertical > .btn-group, .btn-group-vertical > .btn-group > .btn {
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
   display: block;
   float: none;
   width: 100%;
-  max-width: 100%;
-}
-.btn-group-vertical > .btn-group:before, .btn-group-vertical > .btn-group:after {
-  display: table; 
+  max-width: 100%; }
+
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after {
   content: " ";
-}
+  display: table; }
+
 .btn-group-vertical > .btn-group:after {
-  clear: both;
-}
+  clear: both; }
+
 .btn-group-vertical > .btn-group > .btn {
-  float: none;
-}
-.btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group {
+  float: none; }
+
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
   margin-top: -1px;
-  margin-left: 0;
-}
+  margin-left: 0; }
 
 .btn-group-vertical > .btn:not(:first-child):not(:last-child) {
-  border-radius: 0;
-}
+  border-radius: 0; }
+
 .btn-group-vertical > .btn:first-child:not(:last-child) {
-  border-top-right-radius: .25rem;
+  border-top-right-radius: 0.25rem;
   border-bottom-right-radius: 0;
-  border-bottom-left-radius: 0;
-}
+  border-bottom-left-radius: 0; }
+
 .btn-group-vertical > .btn:last-child:not(:first-child) {
-  border-top-left-radius: 0; 
+  border-bottom-left-radius: 0.25rem;
   border-top-right-radius: 0;
-  border-bottom-left-radius: .25rem;
-}
+  border-top-left-radius: 0; }
 
 .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
-  border-radius: 0;
-}
+  border-radius: 0; }
 
-.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
   border-bottom-right-radius: 0;
-  border-bottom-left-radius: 0;
-}
+  border-bottom-left-radius: 0; }
 
 .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
-  border-top-left-radius: 0; 
   border-top-right-radius: 0;
-}
+  border-top-left-radius: 0; }
 
-[data-toggle="buttons"] > .btn input[type="radio"], [data-toggle="buttons"] > .btn input[type="checkbox"], [data-toggle="buttons"] > .btn-group > .btn input[type="radio"], [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
   position: absolute;
   clip: rect(0, 0, 0, 0);
-  pointer-events: none;
-}
+  pointer-events: none; }
 
 .input-group {
   position: relative;
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -ms-flexbox;
-  display:         flex;
-}
-.input-group .form-control {
-  position: relative;
-  z-index: 2;
-  margin-bottom: 0; 
-
-  -webkit-box-flex: 1;
-  -webkit-flex: 1;
-      -ms-flex: 1;
-          flex: 1;
-}
+  display: flex; }
+  .input-group .form-control {
+    position: relative;
+    z-index: 2;
+    flex: 1;
+    margin-bottom: 0; }
 
-.input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child), .input-group .form-control:not(:first-child):not(:last-child) {
-  border-radius: 0;
-}
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+  border-radius: 0; }
 
-.input-group-addon, .input-group-btn {
+.input-group-addon,
+.input-group-btn {
   white-space: nowrap;
-  vertical-align: middle;
-}
+  vertical-align: middle; }
 
 .input-group-addon {
-  padding: .5rem .75rem;
+  padding: 0.5rem 0.75rem;
   font-size: 1rem;
   font-weight: normal;
   line-height: 1;
@@ -3054,84 +2454,84 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto
   text-align: center;
   background-color: #eceeef;
   border: 1px solid #ccc;
-  border-radius: .25rem;
-}
-.input-group-addon.form-control-sm, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .input-group-addon.btn {
-  padding: .3rem .75rem;
-  font-size: .85rem;
-  border-radius: .2rem;
-}
-.input-group-addon.form-control-lg, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .input-group-addon.btn {
-  padding: .75rem 1.5rem;
-  font-size: 1.25rem;
-  border-radius: .3rem;
-}
-.input-group-addon input[type="radio"], .input-group-addon input[type="checkbox"] {
-  margin-top: 0;
-}
-
-.input-group .form-control:first-child, .input-group-addon:first-child, .input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group > .btn, .input-group-btn:first-child > .dropdown-toggle, .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), .input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
-  border-top-right-radius: 0; 
+  border-radius: 0.25rem; }
+  .input-group-addon.form-control-sm, .input-group-sm > .input-group-addon,
+  .input-group-sm > .input-group-btn > .input-group-addon.btn {
+    padding: 0.3rem 0.75rem;
+    font-size: 0.85rem;
+    border-radius: 0.2rem; }
+  .input-group-addon.form-control-lg, .input-group-lg > .input-group-addon,
+  .input-group-lg > .input-group-btn > .input-group-addon.btn {
+    padding: 0.75rem 1.5rem;
+    font-size: 1.25rem;
+    border-radius: 0.3rem; }
+  .input-group-addon input[type="radio"],
+  .input-group-addon input[type="checkbox"] {
+    margin-top: 0; }
+
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
   border-bottom-right-radius: 0;
-}
+  border-top-right-radius: 0; }
 
 .input-group-addon:first-child {
-  border-right: 0;
-}
-
-.input-group .form-control:last-child, .input-group-addon:last-child, .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group > .btn, .input-group-btn:last-child > .dropdown-toggle, .input-group-btn:first-child > .btn:not(:first-child), .input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
-  border-top-left-radius: 0; 
+  border-right: 0; }
+
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
   border-bottom-left-radius: 0;
-}
+  border-top-left-radius: 0; }
 
 .input-group-addon:last-child {
-  border-left: 0;
-}
+  border-left: 0; }
 
 .input-group-btn {
   position: relative;
   font-size: 0;
-  white-space: nowrap;
-}
-.input-group-btn > .btn {
-  position: relative;
-}
-.input-group-btn > .btn + .btn {
-  margin-left: -1px;
-}
-.input-group-btn > .btn:focus, .input-group-btn > .btn:active, .input-group-btn > .btn:hover {
-  z-index: 2;
-}
-.input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group {
-  margin-right: -1px;
-}
-.input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group {
-  margin-left: -1px;
-}
+  white-space: nowrap; }
+  .input-group-btn > .btn {
+    position: relative; }
+    .input-group-btn > .btn + .btn {
+      margin-left: -1px; }
+    .input-group-btn > .btn:focus,
+    .input-group-btn > .btn:active,
+    .input-group-btn > .btn:hover {
+      z-index: 2; }
+  .input-group-btn:first-child > .btn,
+  .input-group-btn:first-child > .btn-group {
+    margin-right: -1px; }
+  .input-group-btn:last-child > .btn,
+  .input-group-btn:last-child > .btn-group {
+    margin-left: -1px; }
 
 .c-input {
   position: relative;
   display: inline;
   padding-left: 1.5rem;
   color: #555;
-  cursor: pointer;
-}
-.c-input > input {
-  position: absolute;
-  z-index: -1;
-  opacity: 0;
-}
-.c-input > input:checked ~ .c-indicator {
-  color: #fff;
-  background-color: #0074d9;
-}
-.c-input > input:active ~ .c-indicator {
-  color: #fff;
-  background-color: #84c6ff;
-}
-.c-input + .c-input {
-  margin-left: 1rem;
-}
+  cursor: pointer; }
+  .c-input > input {
+    position: absolute;
+    z-index: -1;
+    opacity: 0; }
+    .c-input > input:checked ~ .c-indicator {
+      color: #fff;
+      background-color: #0074d9; }
+    .c-input > input:active ~ .c-indicator {
+      color: #fff;
+      background-color: #84c6ff; }
+  .c-input + .c-input {
+    margin-left: 1rem; }
 
 .c-indicator {
   position: absolute;
@@ -3144,123 +2544,97 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto
   line-height: 1rem;
   color: #eee;
   text-align: center;
-  -webkit-user-select: none;
-     -moz-user-select: none;
-      -ms-user-select: none;
-          user-select: none;
+  user-select: none;
   background-color: #eee;
   background-repeat: no-repeat;
   background-position: center center;
-  -webkit-background-size: 50% 50%;
-          background-size: 50% 50%;
-}
+  background-size: 50% 50%; }
 
 .c-checkbox .c-indicator {
-  border-radius: .25rem;
-}
+  border-radius: .25rem; }
+
 .c-checkbox input:checked ~ .c-indicator {
-  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTYuNCwxTDUuNywxLjdMMi45LDQuNUwyLjEsMy43TDEuNCwzTDAsNC40bDAuNywwLjdsMS41LDEuNWwwLjcsMC43bDAuNy0wLjdsMy41LTMuNWwwLjctMC43TDYuNCwxTDYuNCwxeiINCgkvPg0KPC9zdmc+DQo=);
-}
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTYuNCwxTDUuNywxLjdMMi45LDQuNUwyLjEsMy43TDEuNCwzTDAsNC40bDAuNywwLjdsMS41LDEuNWwwLjcsMC43bDAuNy0wLjdsMy41LTMuNWwwLjctMC43TDYuNCwxTDYuNCwxeiINCgkvPg0KPC9zdmc+DQo=); }
+
 .c-checkbox input:indeterminate ~ .c-indicator {
   background-color: #0074d9;
-  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0wLDN2Mmg4VjNIMHoiLz4NCjwvc3ZnPg0K);
-}
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0wLDN2Mmg4VjNIMHoiLz4NCjwvc3ZnPg0K); }
 
 .c-radio .c-indicator {
-  border-radius: 50%;
-}
+  border-radius: 50%; }
+
 .c-radio input:checked ~ .c-indicator {
-  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTQsMUMyLjMsMSwxLDIuMywxLDRzMS4zLDMsMywzczMtMS4zLDMtM1M1LjcsMSw0LDF6Ii8+DQo8L3N2Zz4NCg==);
-}
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTQsMUMyLjMsMSwxLDIuMywxLDRzMS4zLDMsMywzczMtMS4zLDMtM1M1LjcsMSw0LDF6Ii8+DQo8L3N2Zz4NCg==); }
 
 .c-inputs-stacked .c-input {
-  display: inline;
-}
-.c-inputs-stacked .c-input:after {
-  display: block;
-  margin-bottom: .25rem;
-  content: "";
-}
-.c-inputs-stacked .c-input + .c-input {
-  margin-left: 0;
-}
+  display: inline; }
+  .c-inputs-stacked .c-input:after {
+    display: block;
+    margin-bottom: .25rem;
+    content: ""; }
+  .c-inputs-stacked .c-input + .c-input {
+    margin-left: 0; }
 
 .select {
   position: relative;
   display: inline-block;
-  color: #555;
-}
-.select > select {
-  display: inline-block;
-  width: 100%;
-  -webkit-appearance: none;
-  padding: .5rem 2.25rem .5rem 1rem;
-  margin: 0;
-  line-height: 1.5;
-  color: #555;
-  cursor: pointer;
-  background-color: #eee;
-  border: 0;
-  border-radius: .25rem;
-  outline: 0;
-
-          appearance: none;
-}
-.select > select:focus {
-  -webkit-box-shadow: 0 0 0 .075rem #fff, 0 0 0 .2rem #0074d9;
-          box-shadow: 0 0 0 .075rem #fff, 0 0 0 .2rem #0074d9;
-}
-.select > select:focus:-moz-focusring {
-  color: transparent;
-  text-shadow: 0 0 0 #000;
-}
-.select > select:active {
-  color: #fff;
-  background-color: #0074d9;
-}
-.select > select::-ms-expand {
-  display: none;
-}
-.select:after {
-  position: absolute;
-  top: 50%;
-  right: 1.25rem;
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-top: -.15rem;
-  pointer-events: none;
-  content: "";
-  border-top: .35rem solid;
-  border-right: .35rem solid transparent;
-  border-bottom: .35rem solid transparent;
-  border-left: .35rem solid transparent;
-}
+  color: #555; }
+  .select > select {
+    display: inline-block;
+    width: 100%;
+    padding: 0.5rem 2.25rem 0.5rem 1rem;
+    margin: 0;
+    line-height: 1.5;
+    color: #555;
+    cursor: pointer;
+    background-color: #eee;
+    border: 0;
+    border-radius: .25rem;
+    outline: 0;
+    -webkit-appearance: none;
+    appearance: none; }
+    .select > select:focus {
+      box-shadow: 0 0 0 0.075rem #fff, 0 0 0 0.2rem #0074d9; }
+      .select > select:focus:-moz-focusring {
+        color: transparent;
+        text-shadow: 0 0 0 #000; }
+    .select > select:active {
+      color: #fff;
+      background-color: #0074d9; }
+    .select > select::-ms-expand {
+      display: none; }
+  .select:after {
+    position: absolute;
+    top: 50%;
+    right: 1.25rem;
+    display: inline-block;
+    width: 0;
+    height: 0;
+    margin-top: -.15rem;
+    pointer-events: none;
+    content: "";
+    border-top: .35rem solid;
+    border-right: .35rem solid transparent;
+    border-bottom: .35rem solid transparent;
+    border-left: .35rem solid transparent; }
 
 .select select:hover {
-  background-color: #ddd;
-}
+  background-color: #ddd; }
 
 @-moz-document url-prefix() {
   .select select {
     padding-right: 1rem;
-    text-indent: .01px;
-    text-overflow: "";
-  }
-
+    text-indent: 0.01px;
+    text-overflow: ""; }
   .select option {
-    background-color: #fff;
-  }
-}
+    background-color: #fff; } }
 
-@media screen and (min-width: 0\0) {
+@media screen and (min-width: 0 \0) {
   .select select {
     z-index: 1;
-    padding: .5rem 1.5rem .5rem 1rem;
-  }
+    padding: 0.5rem 1.5rem 0.5rem 1rem; }
   .select:after {
-    z-index: 5;
-  }
+    z-index: 5; }
   .select:before {
     position: absolute;
     top: 0;
@@ -3270,27 +2644,24 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto
     display: block;
     width: 1.5rem;
     content: "";
-    background-color: #eee;
-  }
-  .select select:focus, .select select:active, .select select:hover {
+    background-color: #eee; }
+  .select select:focus,
+  .select select:active,
+  .select select:hover {
     color: #555;
-    background-color: #eee;
-  }
-}
+    background-color: #eee; } }
 
 .file {
   position: relative;
   display: inline-block;
   height: 2.5rem;
-  cursor: pointer;
-}
+  cursor: pointer; }
 
 .file input {
   min-width: 14rem;
   margin: 0;
   filter: alpha(opacity=0);
-  opacity: 0;
-}
+  opacity: 0; }
 
 .file-custom {
   position: absolute;
@@ -3299,23 +2670,17 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto
   left: 0;
   z-index: 5;
   height: 2.5rem;
-  padding: .5rem 1rem;
+  padding: 0.5rem 1rem;
   line-height: 1.5;
   color: #555;
-  -webkit-user-select: none;
-     -moz-user-select: none;
-      -ms-user-select: none;
-          user-select: none;
+  user-select: none;
   background-color: #fff;
   border: .075rem solid #ddd;
   border-radius: .25rem;
-  -webkit-box-shadow: inset 0 .2rem .4rem rgba(0, 0, 0, .05);
-          box-shadow: inset 0 .2rem .4rem rgba(0, 0, 0, .05);
-}
+  box-shadow: inset 0 0.2rem 0.4rem rgba(0, 0, 0, 0.05); }
 
 .file-custom:after {
-  content: "Choose file...";
-}
+  content: "Choose file..."; }
 
 .file-custom:before {
   position: absolute;
@@ -3325,427 +2690,417 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto
   z-index: 6;
   display: block;
   height: 2.5rem;
-  padding: .5rem 1rem;
+  padding: 0.5rem 1rem;
   line-height: 1.5;
   color: #555;
   content: "Browse";
   background-color: #eee;
   border: .075rem solid #ddd;
-  border-radius: 0 .25rem .25rem 0;
-}
+  border-radius: 0 0.25rem 0.25rem 0; }
 
 .file input:focus ~ .file-custom {
-  -webkit-box-shadow: 0 0 0 .075rem #fff, 0 0 0 .2rem #0074d9;
-          box-shadow: 0 0 0 .075rem #fff, 0 0 0 .2rem #0074d9;
-}
+  box-shadow: 0 0 0 0.075rem #fff, 0 0 0 0.2rem #0074d9; }
 
 .nav {
   padding-left: 0;
   margin-bottom: 0;
-  list-style: none;
-}
-.nav:before, .nav:after {
-  display: table; 
-  content: " ";
-}
-.nav:after {
-  clear: both;
-}
+  list-style: none; }
+  .nav:before,
+  .nav:after {
+    content: " ";
+    display: table; }
+  .nav:after {
+    clear: both; }
 
 .nav-item {
   position: relative;
-  display: inline-block;
-}
+  display: inline-block; }
 
 .nav-link {
   display: inline-block;
-  padding: .75em 1em;
-  line-height: 1;
-}
-.nav-link:focus, .nav-link:hover {
-  text-decoration: none;
-  background-color: #eceeef;
-}
-.disabled > .nav-link, .nav-link.disabled {
-  color: #818a91;
-}
-.disabled > .nav-link, .disabled > .nav-link:focus, .disabled > .nav-link:hover, .nav-link.disabled, .nav-link.disabled:focus, .nav-link.disabled:hover {
-  color: #818a91;
-  cursor: false;
-  background-color: transparent;
-}
+  padding: 0.75em 1em;
+  line-height: 1; }
+  .nav-link:focus,
+  .nav-link:hover {
+    text-decoration: none;
+    background-color: #eceeef; }
+  .disabled > .nav-link,
+  .nav-link.disabled {
+    color: #818a91; }
+    .disabled > .nav-link,
+    .disabled > .nav-link:focus,
+    .disabled > .nav-link:hover,
+    .nav-link.disabled,
+    .nav-link.disabled:focus,
+    .nav-link.disabled:hover {
+      color: #818a91;
+      cursor: not-allowed;
+      background-color: transparent; }
 
 .nav-tabs {
-  border-bottom: 1px solid #ddd;
-}
-.nav-tabs .nav-item {
-  float: left;
-  margin-bottom: -1px;
-}
-.nav-tabs .nav-item + .nav-item {
-  margin-left: .2rem;
-}
-.nav-tabs .nav-link {
-  display: block;
-  border: 1px solid transparent;
-  border-radius: .25rem .25rem 0 0;
-}
-.nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover {
-  border-color: #eceeef #eceeef #ddd;
-}
-.nav-tabs .open > .nav-link, .nav-tabs .open > .nav-link:focus, .nav-tabs .open > .nav-link:hover, .nav-tabs .active > .nav-link, .nav-tabs .active > .nav-link:focus, .nav-tabs .active > .nav-link:hover, .nav-tabs .nav-link.open, .nav-tabs .nav-link.open:focus, .nav-tabs .nav-link.open:hover, .nav-tabs .nav-link.active, .nav-tabs .nav-link.active:focus, .nav-tabs .nav-link.active:hover {
-  color: #55595c;
-  background-color: #fff;
-  border-color: #ddd #ddd transparent;
-}
-.nav-tabs .disabled > .nav-link, .nav-tabs .disabled > .nav-link:focus, .nav-tabs .disabled > .nav-link:hover, .nav-tabs .nav-link.disabled, .nav-tabs .nav-link.disabled:focus, .nav-tabs .nav-link.disabled:hover {
-  color: #818a91;
-  background-color: transparent;
-  border-color: transparent;
-}
+  border-bottom: 1px solid #ddd; }
+  .nav-tabs .nav-item {
+    float: left;
+    margin-bottom: -1px; }
+    .nav-tabs .nav-item + .nav-item {
+      margin-left: .2rem; }
+  .nav-tabs .nav-link {
+    display: block;
+    border: 1px solid transparent;
+    border-radius: 0.25rem 0.25rem 0 0; }
+    .nav-tabs .nav-link:focus,
+    .nav-tabs .nav-link:hover {
+      border-color: #eceeef #eceeef #ddd; }
+  .nav-tabs .open > .nav-link,
+  .nav-tabs .open > .nav-link:focus,
+  .nav-tabs .open > .nav-link:hover,
+  .nav-tabs .active > .nav-link,
+  .nav-tabs .active > .nav-link:focus,
+  .nav-tabs .active > .nav-link:hover,
+  .nav-tabs .nav-link.open,
+  .nav-tabs .nav-link.open:focus,
+  .nav-tabs .nav-link.open:hover,
+  .nav-tabs .nav-link.active,
+  .nav-tabs .nav-link.active:focus,
+  .nav-tabs .nav-link.active:hover {
+    color: #55595c;
+    background-color: #fff;
+    border-color: #ddd #ddd transparent; }
+  .nav-tabs .disabled > .nav-link,
+  .nav-tabs .disabled > .nav-link:focus,
+  .nav-tabs .disabled > .nav-link:hover,
+  .nav-tabs .nav-link.disabled,
+  .nav-tabs .nav-link.disabled:focus,
+  .nav-tabs .nav-link.disabled:hover {
+    color: #818a91;
+    background-color: transparent;
+    border-color: transparent; }
 
 .nav-pills .nav-item {
-  float: left;
-}
-.nav-pills .nav-item + .nav-item {
-  margin-left: .2rem;
-}
+  float: left; }
+  .nav-pills .nav-item + .nav-item {
+    margin-left: .2rem; }
+
 .nav-pills .nav-link {
   display: block;
-  border-radius: .25rem;
-}
-.nav-pills .open > .nav-link, .nav-pills .open > .nav-link:focus, .nav-pills .open > .nav-link:hover, .nav-pills .active > .nav-link, .nav-pills .active > .nav-link:focus, .nav-pills .active > .nav-link:hover, .nav-pills .nav-link.open, .nav-pills .nav-link.open:focus, .nav-pills .nav-link.open:hover, .nav-pills .nav-link.active, .nav-pills .nav-link.active:focus, .nav-pills .nav-link.active:hover {
+  border-radius: 0.25rem; }
+
+.nav-pills .open > .nav-link,
+.nav-pills .open > .nav-link:focus,
+.nav-pills .open > .nav-link:hover,
+.nav-pills .active > .nav-link,
+.nav-pills .active > .nav-link:focus,
+.nav-pills .active > .nav-link:hover,
+.nav-pills .nav-link.open,
+.nav-pills .nav-link.open:focus,
+.nav-pills .nav-link.open:hover,
+.nav-pills .nav-link.active,
+.nav-pills .nav-link.active:focus,
+.nav-pills .nav-link.active:hover {
   color: #fff;
   cursor: default;
-  background-color: #0275d8;
-}
+  background-color: #0275d8; }
 
 .nav-stacked .nav-item {
   display: block;
-  float: none;
-}
-.nav-stacked .nav-item + .nav-item {
-  margin-top: .2rem;
-  margin-left: 0;
-}
+  float: none; }
+  .nav-stacked .nav-item + .nav-item {
+    margin-top: .2rem;
+    margin-left: 0; }
 
 .tab-content > .tab-pane {
-  display: none;
-}
+  display: none; }
+
 .tab-content > .active {
-  display: block;
-}
+  display: block; }
 
 .nav-tabs .dropdown-menu {
   margin-top: -1px;
-  border-top-left-radius: 0; 
   border-top-right-radius: 0;
-}
+  border-top-left-radius: 0; }
 
 .navbar {
   position: relative;
   padding: 1rem;
-  margin-bottom: 1;
-}
-.navbar:before, .navbar:after {
-  display: table; 
-  content: " ";
-}
-.navbar:after {
-  clear: both;
-}
-@media (min-width: 34em) {
-  .navbar {
-    border-radius: .25rem;
-  }
-}
+  margin-bottom: 1; }
+  .navbar:before,
+  .navbar:after {
+    content: " ";
+    display: table; }
+  .navbar:after {
+    clear: both; }
+  @media (min-width: 34em) {
+    .navbar {
+      border-radius: 0.25rem; } }
 
 .navbar-static-top {
-  z-index: 1000;
-}
-@media (min-width: 34em) {
-  .navbar-static-top {
-    border-radius: 0;
-  }
-}
+  z-index: 1000; }
+  @media (min-width: 34em) {
+    .navbar-static-top {
+      border-radius: 0; } }
 
-.navbar-fixed-top, .navbar-fixed-bottom {
+.navbar-fixed-top,
+.navbar-fixed-bottom {
   position: fixed;
   right: 0;
   left: 0;
   z-index: 1030;
-  margin-bottom: 0;
-}
-@media (min-width: 34em) {
-  .navbar-fixed-top, .navbar-fixed-bottom {
-    border-radius: 0;
-  }
-}
+  margin-bottom: 0; }
+  @media (min-width: 34em) {
+    .navbar-fixed-top,
+    .navbar-fixed-bottom {
+      border-radius: 0; } }
 
 .navbar-fixed-top {
-  top: 0;
-}
+  top: 0; }
 
 .navbar-fixed-bottom {
-  bottom: 0;
-}
+  bottom: 0; }
 
 .navbar-sticky-top {
-  position: -webkit-sticky;
-  position:         sticky;
+  position: sticky;
   top: 0;
-  z-index: 1030; 
   width: 100%;
-}
-@media (min-width: 34em) {
-  .navbar-sticky-top {
-    border-radius: 0;
-  }
-}
+  z-index: 1030; }
+  @media (min-width: 34em) {
+    .navbar-sticky-top {
+      border-radius: 0; } }
 
 .navbar-brand {
   float: left;
-  padding: .625rem .75rem;
+  padding: 0.625rem 0.75rem;
   margin-right: 1rem;
   margin-bottom: 0;
   font-size: 1.25rem;
-  line-height: 1;
-}
-.navbar-brand > a:focus, .navbar-brand > a:hover {
-  text-decoration: none;
-}
-.navbar-brand > img {
-  display: block;
-}
+  line-height: 1; }
+  .navbar-brand > a:focus,
+  .navbar-brand > a:hover {
+    text-decoration: none; }
+  .navbar-brand > img {
+    display: block; }
 
 .navbar-toggler {
-  padding: .55rem .75rem;
+  padding: 0.55rem 0.75rem;
   margin-right: 1rem;
   margin-bottom: 0;
   font-size: 1.25rem;
   line-height: 1;
   background: none;
-  border: 0;
-}
-.navbar-toggler:focus, .navbar-toggler:hover {
-  text-decoration: none;
-}
+  border: 0; }
+  .navbar-toggler:focus,
+  .navbar-toggler:hover {
+    text-decoration: none; }
 
 @media (min-width: 34em) {
   .navbar-toggleable-xs {
-    display: block !important;
-  }
-}
+    display: block !important; } }
+
 @media (min-width: 48em) {
   .navbar-toggleable-sm {
-    display: block !important;
-  }
-}
+    display: block !important; } }
 
 .navbar-nav > li > .dropdown-menu {
   margin-top: 0;
-  border-top-left-radius: 0; 
   border-top-right-radius: 0;
-}
+  border-top-left-radius: 0; }
 
 .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
-  border-top-left-radius: .25rem;
-  border-top-right-radius: .25rem;
+  border-top-right-radius: 0.25rem;
+  border-top-left-radius: 0.25rem;
   border-bottom-right-radius: 0;
-  border-bottom-left-radius: 0;
-}
+  border-bottom-left-radius: 0; }
 
 .navbar-condensed {
   padding-top: 0;
-  padding-bottom: 0;
-}
-.navbar-condensed .navbar-brand {
-  padding-top: .95rem;
-  padding-bottom: .95rem;
-}
-.navbar-condensed .form-inline {
-  margin-top: .6rem;
-}
+  padding-bottom: 0; }
+  .navbar-condensed .navbar-brand {
+    padding-top: .95rem;
+    padding-bottom: .95rem; }
+  .navbar-condensed .form-inline {
+    margin-top: .6rem; }
 
 .navbar-nav .nav-item {
-  float: left;
-}
+  float: left; }
+
 .navbar-nav .nav-link {
   display: block;
   padding-top: .95rem;
   padding-bottom: .95rem;
-  line-height: 1.25;
-}
-.navbar-nav .open > .nav-link, .navbar-nav .open > .nav-link:focus, .navbar-nav .open > .nav-link:hover, .navbar-nav .active > .nav-link, .navbar-nav .active > .nav-link:focus, .navbar-nav .active > .nav-link:hover, .navbar-nav .nav-link.open, .navbar-nav .nav-link.open:focus, .navbar-nav .nav-link.open:hover, .navbar-nav .nav-link.active, .navbar-nav .nav-link.active:focus, .navbar-nav .nav-link.active:hover {
+  line-height: 1.25; }
+
+.navbar-nav .open > .nav-link,
+.navbar-nav .open > .nav-link:focus,
+.navbar-nav .open > .nav-link:hover,
+.navbar-nav .active > .nav-link,
+.navbar-nav .active > .nav-link:focus,
+.navbar-nav .active > .nav-link:hover,
+.navbar-nav .nav-link.open,
+.navbar-nav .nav-link.open:focus,
+.navbar-nav .nav-link.open:hover,
+.navbar-nav .nav-link.active,
+.navbar-nav .nav-link.active:focus,
+.navbar-nav .nav-link.active:hover {
   color: #555;
   cursor: default;
-  background-color: #e7e7e7;
-}
+  background-color: #e7e7e7; }
 
 .navbar-default {
   background-color: #f8f8f8;
-  border-color: #e7e7e7;
-}
-.navbar-default .navbar-brand {
-  color: #777;
-}
-.navbar-default .navbar-brand:focus, .navbar-default .navbar-brand:hover {
-  color: #5e5e5e;
-  background-color: transparent;
-}
+  border-color: #e7e7e7; }
+  .navbar-default .navbar-brand {
+    color: #777; }
+    .navbar-default .navbar-brand:focus,
+    .navbar-default .navbar-brand:hover {
+      color: #5e5e5e;
+      background-color: transparent; }
 
 .navbar-inverse {
   background-color: #373a3c;
-  border-color: #1f2021;
-}
-.navbar-inverse .navbar-toggler, .navbar-inverse .navbar-brand > a, .navbar-inverse .nav-pills > .nav-item > .nav-link {
-  color: #aab0b5;
-}
-.navbar-inverse .navbar-toggler:focus, .navbar-inverse .navbar-toggler:hover, .navbar-inverse .navbar-brand > a:focus, .navbar-inverse .navbar-brand > a:hover, .navbar-inverse .nav-pills > .nav-item > .nav-link:focus, .navbar-inverse .nav-pills > .nav-item > .nav-link:hover {
-  color: #fff;
-}
-.navbar-inverse .nav-pills > .nav-item > .nav-link:focus, .navbar-inverse .nav-pills > .nav-item > .nav-link:hover {
-  color: #fff;
-  background-color: #1f2021;
-}
-.navbar-inverse .nav-pills > .active > .nav-link, .navbar-inverse .nav-pills > .nav-link.active {
-  color: #fff;
-  background-color: #1f2021;
-}
-.navbar-inverse .navbar-brand {
-  color: #aab0b5;
-}
-.navbar-inverse .navbar-brand:focus, .navbar-inverse .navbar-brand:hover {
-  color: #fff;
-  background-color: transparent;
-}
-.navbar-inverse .navbar-text {
-  color: #a2a8ae;
-}
-.navbar-inverse .navbar-nav > li > a {
-  color: #aab0b5;
-}
-.navbar-inverse .navbar-nav > li > a:focus, .navbar-inverse .navbar-nav > li > a:hover {
-  color: #fff;
-  background-color: transparent;
-}
-.navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:focus, .navbar-inverse .navbar-nav > .active > a:hover {
-  color: #fff;
-  background-color: #1f2021;
-}
-.navbar-inverse .navbar-nav > .disabled > a, .navbar-inverse .navbar-nav > .disabled > a:focus, .navbar-inverse .navbar-nav > .disabled > a:hover {
-  color: #444;
-  background-color: transparent;
-}
-.navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form {
-  border-color: #262829;
-}
-.navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:focus, .navbar-inverse .navbar-nav > .open > a:hover {
-  color: #fff;
-  background-color: #1f2021;
-}
-.navbar-inverse .navbar-link {
-  color: #aab0b5;
-}
-.navbar-inverse .navbar-link:hover {
-  color: #fff;
-}
-.navbar-inverse .btn-link {
-  color: #aab0b5;
-}
-.navbar-inverse .btn-link:focus, .navbar-inverse .btn-link:hover {
-  color: #fff;
-}
-.navbar-inverse .btn-link:disabled:focus, .navbar-inverse .btn-link:disabled:hover, fieldset[disabled] .navbar-inverse .btn-link:focus, fieldset[disabled] .navbar-inverse .btn-link:hover {
-  color: #444;
-}
+  border-color: #1f2021; }
+  .navbar-inverse .navbar-toggler,
+  .navbar-inverse .navbar-brand > a,
+  .navbar-inverse .nav-pills > .nav-item > .nav-link {
+    color: #aab0b5; }
+    .navbar-inverse .navbar-toggler:focus,
+    .navbar-inverse .navbar-toggler:hover,
+    .navbar-inverse .navbar-brand > a:focus,
+    .navbar-inverse .navbar-brand > a:hover,
+    .navbar-inverse .nav-pills > .nav-item > .nav-link:focus,
+    .navbar-inverse .nav-pills > .nav-item > .nav-link:hover {
+      color: #fff; }
+  .navbar-inverse .nav-pills > .nav-item > .nav-link:focus,
+  .navbar-inverse .nav-pills > .nav-item > .nav-link:hover {
+    color: #fff;
+    background-color: #1f2021; }
+  .navbar-inverse .nav-pills > .active > .nav-link,
+  .navbar-inverse .nav-pills > .nav-link.active {
+    color: #fff;
+    background-color: #1f2021; }
+  .navbar-inverse .navbar-brand {
+    color: #aab0b5; }
+    .navbar-inverse .navbar-brand:focus,
+    .navbar-inverse .navbar-brand:hover {
+      color: #fff;
+      background-color: transparent; }
+  .navbar-inverse .navbar-text {
+    color: #a2a8ae; }
+  .navbar-inverse .navbar-nav > li > a {
+    color: #aab0b5; }
+    .navbar-inverse .navbar-nav > li > a:focus,
+    .navbar-inverse .navbar-nav > li > a:hover {
+      color: #fff;
+      background-color: transparent; }
+  .navbar-inverse .navbar-nav > .active > a,
+  .navbar-inverse .navbar-nav > .active > a:focus,
+  .navbar-inverse .navbar-nav > .active > a:hover {
+    color: #fff;
+    background-color: #1f2021; }
+  .navbar-inverse .navbar-nav > .disabled > a,
+  .navbar-inverse .navbar-nav > .disabled > a:focus,
+  .navbar-inverse .navbar-nav > .disabled > a:hover {
+    color: #444;
+    background-color: transparent; }
+  .navbar-inverse .navbar-collapse,
+  .navbar-inverse .navbar-form {
+    border-color: #262829; }
+  .navbar-inverse .navbar-nav > .open > a,
+  .navbar-inverse .navbar-nav > .open > a:focus,
+  .navbar-inverse .navbar-nav > .open > a:hover {
+    color: #fff;
+    background-color: #1f2021; }
+  .navbar-inverse .navbar-link {
+    color: #aab0b5; }
+    .navbar-inverse .navbar-link:hover {
+      color: #fff; }
+  .navbar-inverse .btn-link {
+    color: #aab0b5; }
+    .navbar-inverse .btn-link:focus,
+    .navbar-inverse .btn-link:hover {
+      color: #fff; }
+    .navbar-inverse .btn-link:disabled:focus,
+    .navbar-inverse .btn-link:disabled:hover,
+    fieldset[disabled] .navbar-inverse .btn-link:focus,
+    fieldset[disabled] .navbar-inverse .btn-link:hover {
+      color: #444; }
 
 .card {
   position: relative;
   padding: 1.25rem;
   margin-bottom: 1.25rem;
-  border: .075rem solid #eee;
-}
+  border: .075rem solid #eee; }
 
 .card-title {
   margin-top: 0;
-  margin-bottom: .75rem;
-}
+  margin-bottom: .75rem; }
 
 .card-text:last-child {
-  margin-bottom: 0;
-}
+  margin-bottom: 0; }
 
 .card-actions .card-link + .card-link {
-  margin-left: .75rem;
-}
+  margin-left: .75rem; }
 
 .card-link:hover {
-  text-decoration: none;
-}
+  text-decoration: none; }
 
 .card-header {
-  padding: .75rem 1.25rem;
+  padding: 0.75rem 1.25rem;
   margin: -1.25rem -1.25rem 1.25rem;
   border-bottom: .075rem solid #eee;
-  border-radius: .25rem .25rem 0 0;
-}
+  border-radius: 0.25rem 0.25rem 0 0; }
 
 .card-footer {
-  padding: .75rem 1.25rem;
+  padding: 0.75rem 1.25rem;
   margin: 1.25rem -1.25rem -1.25rem;
   border-top: .075rem solid #eee;
-  border-radius: 0 0 .25rem .25rem;
-}
+  border-radius: 0 0 0.25rem 0.25rem; }
 
 .card-primary {
   background-color: #0275d8;
-  border-color: #0275d8;
-}
+  border-color: #0275d8; }
 
 .card-success {
   background-color: #5cb85c;
-  border-color: #5cb85c;
-}
+  border-color: #5cb85c; }
 
 .card-info {
   background-color: #5bc0de;
-  border-color: #5bc0de;
-}
+  border-color: #5bc0de; }
 
 .card-warning {
   background-color: #f0ad4e;
-  border-color: #f0ad4e;
-}
+  border-color: #f0ad4e; }
 
 .card-danger {
   background-color: #d9534f;
-  border-color: #d9534f;
-}
+  border-color: #d9534f; }
 
-.card-inverse .card-header, .card-inverse .card-footer {
-  border-bottom: .075rem solid rgba(255, 255, 255, .2);
-}
-.card-inverse .card-header, .card-inverse .card-footer, .card-inverse .card-title, .card-inverse .card-blockquote {
-  color: #fff;
-}
-.card-inverse .card-link, .card-inverse .card-text, .card-inverse .card-blockquote > footer {
-  color: rgba(255, 255, 255, .65);
-}
-.card-inverse .card-link:focus, .card-inverse .card-link:hover {
-  color: #fff;
-}
+.card-inverse .card-header,
+.card-inverse .card-footer {
+  border-bottom: 0.075rem solid rgba(255, 255, 255, 0.2); }
+
+.card-inverse .card-header,
+.card-inverse .card-footer,
+.card-inverse .card-title,
+.card-inverse .card-blockquote {
+  color: #fff; }
+
+.card-inverse .card-link,
+.card-inverse .card-text,
+.card-inverse .card-blockquote > footer {
+  color: rgba(255, 255, 255, 0.65); }
+
+.card-inverse .card-link:focus,
+.card-inverse .card-link:hover {
+  color: #fff; }
 
 .card-blockquote {
   padding: 0;
   margin-bottom: 0;
-  border-left: 0;
-}
+  border-left: 0; }
 
 .card-img {
   margin: -1.325rem;
-  border-radius: .25rem;
-}
+  border-radius: 0.25rem; }
 
 .card-img-overlay {
   position: absolute;
@@ -3753,206 +3108,199 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto
   right: 0;
   bottom: 0;
   left: 0;
-  padding: 1.25rem;
-}
+  padding: 1.25rem; }
 
 .card-img-top {
   margin: -1.325rem -1.325rem 1.25rem;
-  border-radius: .25rem .25rem 0 0;
-}
+  border-radius: 0.25rem 0.25rem 0 0; }
 
 .card-img-bottom {
   margin: 1.25rem -1.325rem -1.325rem;
-  border-radius: 0 0 .25rem .25rem;
-}
+  border-radius: 0 0 0.25rem 0.25rem; }
 
 .card-set {
   display: table;
   table-layout: fixed;
-  border-spacing: 1.25rem 0;
-}
-.card-set .card {
-  display: table-cell;
-  float: none;
-  max-width: none;
-}
+  border-spacing: 1.25rem 0; }
+  .card-set .card {
+    display: table-cell;
+    float: none;
+    max-width: none; }
 
 .card-set-wrapper {
   margin-right: -1.25rem;
-  margin-left: -1.25rem;
-}
+  margin-left: -1.25rem; }
 
 .card-group {
   display: table;
   width: 100%;
-  table-layout: fixed;
-}
-.card-group .card {
-  display: table-cell;
-  float: none;
-  max-width: none;
-}
-.card-group .card + .card {
-  margin-left: 0;
-  border-left: 0;
-}
+  table-layout: fixed; }
+  .card-group .card {
+    display: table-cell;
+    float: none;
+    max-width: none; }
+    .card-group .card + .card {
+      margin-left: 0;
+      border-left: 0; }
 
 .card-columns {
-  -webkit-column-count: 3;
-     -moz-column-count: 3;
-          column-count: 3;
-  -webkit-column-gap: 1rem;
-     -moz-column-gap: 1rem;
-          column-gap: 1rem;
-}
-.card-columns .card {
-  display: inline-block;
-  width: 100%;
-}
+  column-count: 3;
+  column-gap: 1rem; }
+  .card-columns .card {
+    display: inline-block;
+    width: 100%; }
 
 .breadcrumb {
-  padding: .75rem 1rem;
+  padding: 0.75rem 1rem;
   margin-bottom: 1rem;
   list-style: none;
   background-color: #eceeef;
-  border-radius: .25rem;
-}
-.breadcrumb > li {
-  display: inline-block;
-}
-.breadcrumb > li + li:before {
-  padding-right: .5rem;
-  padding-left: .5rem;
-  color: #818a91;
-  content: "/\00a0";
-}
-.breadcrumb > .active {
-  color: #818a91;
-}
+  border-radius: 0.25rem; }
+  .breadcrumb > li {
+    display: inline-block; }
+    .breadcrumb > li + li:before {
+      padding-right: .5rem;
+      padding-left: .5rem;
+      color: #818a91;
+      content: "/ "; }
+  .breadcrumb > .active {
+    color: #818a91; }
 
 .pagination {
   display: inline-block;
   padding-left: 0;
+  margin-top: 1rem;
+  margin-bottom: 1rem;
   margin: 1 0;
-  border-radius: .25rem;
-}
-.pagination > li {
-  display: inline;
-}
-.pagination > li > a, .pagination > li > span {
-  position: relative;
-  float: left;
-  padding: .5rem .75rem;
-  margin-left: -1px;
-  line-height: 1.5;
-  color: #0275d8;
-  text-decoration: none;
-  background-color: #fff;
-  border: 1px solid #ddd;
-}
-.pagination > li:first-child > a, .pagination > li:first-child > span {
-  margin-left: 0;
-  border-top-left-radius: .25rem; 
-  border-bottom-left-radius: .25rem;
-}
-.pagination > li:last-child > a, .pagination > li:last-child > span {
-  border-top-right-radius: .25rem; 
-  border-bottom-right-radius: .25rem;
-}
-.pagination > li > a:focus, .pagination > li > a:hover, .pagination > li > span:focus, .pagination > li > span:hover {
-  color: #014c8c;
-  background-color: #eceeef;
-  border-color: #ddd;
-}
-.pagination > .active > a, .pagination > .active > a:focus, .pagination > .active > a:hover, .pagination > .active > span, .pagination > .active > span:focus, .pagination > .active > span:hover {
-  z-index: 2;
-  color: #fff;
-  cursor: default;
-  background-color: #0275d8;
-  border-color: #0275d8;
-}
-.pagination > .disabled > span, .pagination > .disabled > span:focus, .pagination > .disabled > span:hover, .pagination > .disabled > a, .pagination > .disabled > a:focus, .pagination > .disabled > a:hover {
-  color: #818a91;
-  cursor: false;
-  background-color: #fff;
-  border-color: #ddd;
-}
-
-.pagination-lg > li > a, .pagination-lg > li > span {
-  padding: .75rem 1.5rem;
-  font-size: 1.25rem;
-}
-.pagination-lg > li:first-child > a, .pagination-lg > li:first-child > span {
-  border-top-left-radius: .3rem; 
-  border-bottom-left-radius: .3rem;
-}
-.pagination-lg > li:last-child > a, .pagination-lg > li:last-child > span {
-  border-top-right-radius: .3rem; 
-  border-bottom-right-radius: .3rem;
-}
-
-.pagination-sm > li > a, .pagination-sm > li > span {
-  padding: .3rem .75rem;
-  font-size: .85rem;
-}
-.pagination-sm > li:first-child > a, .pagination-sm > li:first-child > span {
-  border-top-left-radius: .2rem; 
-  border-bottom-left-radius: .2rem;
-}
-.pagination-sm > li:last-child > a, .pagination-sm > li:last-child > span {
-  border-top-right-radius: .2rem; 
-  border-bottom-right-radius: .2rem;
-}
+  border-radius: 0.25rem; }
+  .pagination > li {
+    display: inline; }
+    .pagination > li > a,
+    .pagination > li > span {
+      position: relative;
+      float: left;
+      padding: 0.5rem 0.75rem;
+      margin-left: -1px;
+      line-height: 1.5;
+      color: #0275d8;
+      text-decoration: none;
+      background-color: #fff;
+      border: 1px solid #ddd; }
+    .pagination > li:first-child > a,
+    .pagination > li:first-child > span {
+      margin-left: 0;
+      border-bottom-left-radius: 0.25rem;
+      border-top-left-radius: 0.25rem; }
+    .pagination > li:last-child > a,
+    .pagination > li:last-child > span {
+      border-bottom-right-radius: 0.25rem;
+      border-top-right-radius: 0.25rem; }
+  .pagination > li > a:focus,
+  .pagination > li > a:hover,
+  .pagination > li > span:focus,
+  .pagination > li > span:hover {
+    color: #014c8c;
+    background-color: #eceeef;
+    border-color: #ddd; }
+  .pagination > .active > a,
+  .pagination > .active > a:focus,
+  .pagination > .active > a:hover,
+  .pagination > .active > span,
+  .pagination > .active > span:focus,
+  .pagination > .active > span:hover {
+    z-index: 2;
+    color: #fff;
+    cursor: default;
+    background-color: #0275d8;
+    border-color: #0275d8; }
+  .pagination > .disabled > span,
+  .pagination > .disabled > span:focus,
+  .pagination > .disabled > span:hover,
+  .pagination > .disabled > a,
+  .pagination > .disabled > a:focus,
+  .pagination > .disabled > a:hover {
+    color: #818a91;
+    cursor: not-allowed;
+    background-color: #fff;
+    border-color: #ddd; }
+
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+  padding: 0.75rem 1.5rem;
+  font-size: 1.25rem; }
+
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+  border-bottom-left-radius: 0.3rem;
+  border-top-left-radius: 0.3rem; }
+
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+  border-bottom-right-radius: 0.3rem;
+  border-top-right-radius: 0.3rem; }
+
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+  padding: 0.3rem 0.75rem;
+  font-size: 0.85rem; }
+
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+  border-bottom-left-radius: 0.2rem;
+  border-top-left-radius: 0.2rem; }
+
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+  border-bottom-right-radius: 0.2rem;
+  border-top-right-radius: 0.2rem; }
 
 .pager {
   padding-left: 0;
-  margin: 1 0;
+  margin-top: 1rem;
+  margin-bottom: 1rem;
   text-align: center;
-  list-style: none;
-}
-.pager:before, .pager:after {
-  display: table; 
-  content: " ";
-}
-.pager:after {
-  clear: both;
-}
-.pager li {
-  display: inline;
-}
-.pager li > a, .pager li > span {
-  display: inline-block;
-  padding: 5px 14px;
-  background-color: #fff;
-  border: 1px solid #ddd;
-  border-radius: 15px;
-}
-.pager li > a:focus, .pager li > a:hover {
-  text-decoration: none;
-  background-color: #eceeef;
-}
-.pager .disabled > a, .pager .disabled > a:focus, .pager .disabled > a:hover {
-  color: #818a91;
-  cursor: false;
-  background-color: #fff;
-}
-.pager .disabled > span {
-  color: #818a91;
-  cursor: false;
-  background-color: #fff;
-}
+  list-style: none; }
+  .pager:before,
+  .pager:after {
+    content: " ";
+    display: table; }
+  .pager:after {
+    clear: both; }
+  .pager li {
+    display: inline; }
+    .pager li > a,
+    .pager li > span {
+      display: inline-block;
+      padding: 5px 14px;
+      background-color: #fff;
+      border: 1px solid #ddd;
+      border-radius: 15px; }
+    .pager li > a:focus,
+    .pager li > a:hover {
+      text-decoration: none;
+      background-color: #eceeef; }
+  .pager .disabled > a,
+  .pager .disabled > a:focus,
+  .pager .disabled > a:hover {
+    color: #818a91;
+    cursor: not-allowed;
+    background-color: #fff; }
+  .pager .disabled > span {
+    color: #818a91;
+    cursor: not-allowed;
+    background-color: #fff; }
 
-.pager-next > a, .pager-next > span {
-  float: right;
-}
+.pager-next > a,
+.pager-next > span {
+  float: right; }
 
-.pager-prev > a, .pager-prev > span {
-  float: left;
-}
+.pager-prev > a,
+.pager-prev > span {
+  float: left; }
 
 .label {
   display: inline-block;
-  padding: .25em .4em;
+  padding: 0.25em 0.4em;
   font-size: 75%;
   font-weight: bold;
   line-height: 1;
@@ -3960,63 +3308,54 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto
   text-align: center;
   white-space: nowrap;
   vertical-align: baseline;
-  border-radius: .25rem;
-}
-.label:empty {
-  display: none;
-}
-.btn .label {
-  position: relative;
-  top: -1px;
-}
+  border-radius: 0.25rem; }
+  .label:empty {
+    display: none; }
+  .btn .label {
+    position: relative;
+    top: -1px; }
 
-a.label:focus, a.label:hover {
+a.label:focus,
+a.label:hover {
   color: #fff;
   text-decoration: none;
-  cursor: pointer;
-}
+  cursor: pointer; }
 
 .label-default {
-  background-color: #818a91;
-}
-.label-default[href]:focus, .label-default[href]:hover {
-  background-color: #687077;
-}
+  background-color: #818a91; }
+  .label-default[href]:focus,
+  .label-default[href]:hover {
+    background-color: #687077; }
 
 .label-primary {
-  background-color: #0275d8;
-}
-.label-primary[href]:focus, .label-primary[href]:hover {
-  background-color: #025aa5;
-}
+  background-color: #0275d8; }
+  .label-primary[href]:focus,
+  .label-primary[href]:hover {
+    background-color: #025aa5; }
 
 .label-success {
-  background-color: #5cb85c;
-}
-.label-success[href]:focus, .label-success[href]:hover {
-  background-color: #449d44;
-}
+  background-color: #5cb85c; }
+  .label-success[href]:focus,
+  .label-success[href]:hover {
+    background-color: #449d44; }
 
 .label-info {
-  background-color: #5bc0de;
-}
-.label-info[href]:focus, .label-info[href]:hover {
-  background-color: #31b0d5;
-}
+  background-color: #5bc0de; }
+  .label-info[href]:focus,
+  .label-info[href]:hover {
+    background-color: #31b0d5; }
 
 .label-warning {
-  background-color: #f0ad4e;
-}
-.label-warning[href]:focus, .label-warning[href]:hover {
-  background-color: #ec971f;
-}
+  background-color: #f0ad4e; }
+  .label-warning[href]:focus,
+  .label-warning[href]:hover {
+    background-color: #ec971f; }
 
 .label-danger {
-  background-color: #d9534f;
-}
-.label-danger[href]:focus, .label-danger[href]:hover {
-  background-color: #c9302c;
-}
+  background-color: #d9534f; }
+  .label-danger[href]:focus,
+  .label-danger[href]:hover {
+    background-color: #c9302c; }
 
 .badge {
   position: relative;
@@ -4030,362 +3369,260 @@ a.label:focus, a.label:hover {
   text-align: center;
   white-space: nowrap;
   background-color: #818a91;
-  border-radius: 2em;
-}
-.badge:empty {
-  display: none;
-}
-.badge.pull-left, .badge.pull-right {
-  top: .2em;
-}
-.list-group-item.active > .badge, .nav-pills > .active > a > .badge {
-  color: #0275d8;
-  background-color: #fff;
-}
-.list-group-item > .badge {
-  float: right;
-}
-.list-group-item > .badge + .badge {
-  margin-right: 5px;
-}
-.nav-pills > li > a > .badge {
-  margin-left: 3px;
-}
-
-a.badge:focus, a.badge:hover {
+  border-radius: 2em; }
+  .badge:empty {
+    display: none; }
+  .badge.pull-left,
+  .badge.pull-right {
+    top: .2em; }
+  .list-group-item.active > .badge,
+  .nav-pills > .active > a > .badge {
+    color: #0275d8;
+    background-color: #fff; }
+  .list-group-item > .badge {
+    float: right; }
+  .list-group-item > .badge + .badge {
+    margin-right: 5px; }
+  .nav-pills > li > a > .badge {
+    margin-left: 3px; }
+
+a.badge:focus,
+a.badge:hover {
   color: #fff;
   text-decoration: none;
-  cursor: pointer;
-}
+  cursor: pointer; }
 
 .jumbotron {
   padding: 2rem 1rem;
   margin-bottom: 2rem;
   color: inherit;
   background-color: #eceeef;
-  border-radius: .3rem;
-}
+  border-radius: 0.3rem; }
 
 .jumbotron-heading {
-  color: inherit;
-}
+  color: inherit; }
 
 .jumbotron-hr {
-  border-top-color: #d0d5d8;
-}
+  border-top-color: #d0d5d8; }
 
 @media (min-width: 34em) {
   .jumbotron {
-    padding: 4rem 2rem;
-  }
+    padding: 4rem 2rem; }
   .jumbotron-heading {
-    font-size: 4.5rem;
-  }
-}
+    font-size: 4.5rem; } }
 
 .jumbotron-fluid {
   padding-right: 0;
   padding-left: 0;
-  border-radius: 0;
-}
+  border-radius: 0; }
 
 .alert {
   padding: 15px;
   margin-bottom: 1rem;
   border: 1px solid transparent;
-  border-radius: .25rem;
-}
-.alert > p, .alert > ul {
-  margin-bottom: 0;
-}
-.alert > p + p {
-  margin-top: 5px;
-}
+  border-radius: 0.25rem; }
+  .alert > p,
+  .alert > ul {
+    margin-bottom: 0; }
+  .alert > p + p {
+    margin-top: 5px; }
 
 .alert-heading {
   margin-top: 0;
-  color: inherit;
-}
+  color: inherit; }
 
 .alert-link {
-  font-weight: bold;
-}
+  font-weight: bold; }
 
 .alert-dismissible {
-  padding-right: 35px;
-}
-.alert-dismissible .close {
-  position: relative;
-  top: -2px;
-  right: -21px;
-  color: inherit;
-}
+  padding-right: 35px; }
+  .alert-dismissible .close {
+    position: relative;
+    top: -2px;
+    right: -21px;
+    color: inherit; }
 
 .alert-success {
-  color: #3c763d; 
   background-color: #dff0d8;
   border-color: #d0e9c6;
-}
-.alert-success hr {
-  border-top-color: #c1e2b3;
-}
-.alert-success .alert-link {
-  color: #2b542c;
-}
+  color: #3c763d; }
+  .alert-success hr {
+    border-top-color: #c1e2b3; }
+  .alert-success .alert-link {
+    color: #2b542c; }
 
 .alert-info {
-  color: #31708f; 
   background-color: #d9edf7;
   border-color: #bcdff1;
-}
-.alert-info hr {
-  border-top-color: #a6d5ec;
-}
-.alert-info .alert-link {
-  color: #245269;
-}
+  color: #31708f; }
+  .alert-info hr {
+    border-top-color: #a6d5ec; }
+  .alert-info .alert-link {
+    color: #245269; }
 
 .alert-warning {
-  color: #8a6d3b; 
   background-color: #fcf8e3;
   border-color: #faf2cc;
-}
-.alert-warning hr {
-  border-top-color: #f7ecb5;
-}
-.alert-warning .alert-link {
-  color: #66512c;
-}
+  color: #8a6d3b; }
+  .alert-warning hr {
+    border-top-color: #f7ecb5; }
+  .alert-warning .alert-link {
+    color: #66512c; }
 
 .alert-danger {
-  color: #a94442; 
   background-color: #f2dede;
   border-color: #ebcccc;
-}
-.alert-danger hr {
-  border-top-color: #e4b9b9;
-}
-.alert-danger .alert-link {
-  color: #843534;
-}
-
-@-webkit-keyframes progress-bar-stripes {
-  from {
-    background-position: 1 0;
-  }
-
-  to {
-    background-position: 0 0;
-  }
-}
-
-@-o-keyframes progress-bar-stripes {
-  from {
-    background-position: 1 0;
-  }
-
-  to {
-    background-position: 0 0;
-  }
-}
+  color: #a94442; }
+  .alert-danger hr {
+    border-top-color: #e4b9b9; }
+  .alert-danger .alert-link {
+    color: #843534; }
 
 @keyframes progress-bar-stripes {
   from {
-    background-position: 1 0;
-  }
-
+    background-position: 1rem 0; }
   to {
-    background-position: 0 0;
-  }
-}
+    background-position: 0 0; } }
 
 .progress {
   display: block;
   width: 100%;
-  height: 1;
-  margin-bottom: 1;
-}
+  height: 1rem;
+  margin-bottom: 1rem; }
 
 .progress[value] {
   color: #0074d9;
   border: 0;
-
-  appearance: none;
-}
+  appearance: none; }
 
 .progress[value]::-webkit-progress-bar {
   background-color: #eee;
-  border-radius: .25rem;
-}
+  border-radius: 0.25rem; }
 
 .progress[value]::-webkit-progress-value::before {
-  content: attr(value);
-}
+  content: attr(value); }
 
 .progress[value]::-webkit-progress-value {
   background-color: #0074d9;
-  border-top-left-radius: .25rem;
-  border-bottom-left-radius: .25rem;
-}
+  border-top-left-radius: 0.25rem;
+  border-bottom-left-radius: 0.25rem; }
 
 .progress[value="100"]::-webkit-progress-value {
-  border-top-right-radius: .25rem;
-  border-bottom-right-radius: .25rem;
-}
+  border-top-right-radius: 0.25rem;
+  border-bottom-right-radius: 0.25rem; }
 
-@media screen and ("min-width:0\0") {
+@media screen and ("min-width:0�") {
   .progress {
     background-color: #eee;
-    border-radius: .25rem;
-  }
+    border-radius: 0.25rem; }
   .progress-bar {
     display: inline-block;
-    height: 1;
+    height: 1rem;
     text-indent: -999rem;
     background-color: #0074d9;
-    border-top-left-radius: .25rem;
-    border-bottom-left-radius: .25rem;
-  }
+    border-top-left-radius: 0.25rem;
+    border-bottom-left-radius: 0.25rem; }
   .progress[width^="0"] {
     min-width: 2rem;
     color: #818a91;
     background-color: transparent;
-    background-image: none;
-  }
+    background-image: none; }
   .progress[width="100%"] {
-    border-top-right-radius: .25rem;
-    border-bottom-right-radius: .25rem;
-  }
-}
+    border-top-right-radius: 0.25rem;
+    border-bottom-right-radius: 0.25rem; } }
 
 .progress-striped[value]::-webkit-progress-value {
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
-  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
-  -webkit-background-size: 1 1;
-          background-size: 1 1;
-}
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-size: 1rem 1rem; }
 
 .progress-striped[value]::-moz-progress-bar {
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
-  background-size: 1 1;
-}
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-size: 1rem 1rem; }
 
-@media screen and ("min-width:0\0") {
+@media screen and ("min-width:0�") {
   .progress-bar-striped {
-    background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
-    background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
-    background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
-    -webkit-background-size: 1 1;
-            background-size: 1 1;
-  }
-}
+    background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+    background-size: 1rem 1rem; } }
 
 .progress-animated[value]::-webkit-progress-value {
-  -webkit-animation: progress-bar-stripes 2s linear infinite;
-          animation: progress-bar-stripes 2s linear infinite;
-}
+  animation: progress-bar-stripes 2s linear infinite; }
 
 .progress-animated[value]::-moz-progress-bar {
-  animation: progress-bar-stripes 2s linear infinite;
-}
+  animation: progress-bar-stripes 2s linear infinite; }
 
-@media screen and ("min-width:0\0") {
+@media screen and ("min-width:0�") {
   .progress-animated .progress-bar-striped {
-    -webkit-animation: progress-bar-stripes 2s linear infinite;
-         -o-animation: progress-bar-stripes 2s linear infinite;
-            animation: progress-bar-stripes 2s linear infinite;
-  }
-}
+    animation: progress-bar-stripes 2s linear infinite; } }
 
 .progress-success[value]::-webkit-progress-value {
-  background-color: #5cb85c;
-}
+  background-color: #5cb85c; }
+
 .progress-success[value]::-moz-progress-bar {
-  background-color: #5cb85c;
-}
-@media screen and ("min-width:0\0") {
+  background-color: #5cb85c; }
+
+@media screen and ("min-width:0�") {
   .progress-success .progress-bar {
-    background-color: #5cb85c;
-  }
-}
+    background-color: #5cb85c; } }
 
 .progress-info[value]::-webkit-progress-value {
-  background-color: #5bc0de;
-}
+  background-color: #5bc0de; }
+
 .progress-info[value]::-moz-progress-bar {
-  background-color: #5bc0de;
-}
-@media screen and ("min-width:0\0") {
+  background-color: #5bc0de; }
+
+@media screen and ("min-width:0�") {
   .progress-info .progress-bar {
-    background-color: #5bc0de;
-  }
-}
+    background-color: #5bc0de; } }
 
 .progress-warning[value]::-webkit-progress-value {
-  background-color: #f0ad4e;
-}
+  background-color: #f0ad4e; }
+
 .progress-warning[value]::-moz-progress-bar {
-  background-color: #f0ad4e;
-}
-@media screen and ("min-width:0\0") {
+  background-color: #f0ad4e; }
+
+@media screen and ("min-width:0�") {
   .progress-warning .progress-bar {
-    background-color: #f0ad4e;
-  }
-}
+    background-color: #f0ad4e; } }
 
 .progress-danger[value]::-webkit-progress-value {
-  background-color: #d9534f;
-}
+  background-color: #d9534f; }
+
 .progress-danger[value]::-moz-progress-bar {
-  background-color: #d9534f;
-}
-@media screen and ("min-width:0\0") {
+  background-color: #d9534f; }
+
+@media screen and ("min-width:0�") {
   .progress-danger .progress-bar {
-    background-color: #d9534f;
-  }
-}
+    background-color: #d9534f; } }
 
 .media {
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -ms-flexbox;
-  display:         flex;
-  margin-bottom: 1rem;
-}
+  display: flex;
+  margin-bottom: 1rem; }
 
 .media-body {
-  -webkit-box-flex: 1;
-  -webkit-flex: 1;
-      -ms-flex: 1;
-          flex: 1;
-}
+  flex: 1; }
 
 .media-object {
-  display: block;
-}
+  display: block; }
 
-.media-right, .media > .pull-right {
-  padding-left: 10px;
-}
+.media-right,
+.media > .pull-right {
+  padding-left: 10px; }
 
-.media-left, .media > .pull-left {
-  padding-right: 10px;
-}
+.media-left,
+.media > .pull-left {
+  padding-right: 10px; }
 
 .media-heading {
   margin-top: 0;
-  margin-bottom: 5px;
-}
+  margin-bottom: 5px; }
 
 .media-list {
   padding-left: 0;
-  list-style: none;
-}
+  list-style: none; }
 
 .list-group {
   padding-left: 0;
-  margin-bottom: 20px;
-}
+  margin-bottom: 20px; }
 
 .list-group-item {
   position: relative;
@@ -4393,172 +3630,170 @@ a.badge:focus, a.badge:hover {
   padding: 10px 15px;
   margin-bottom: -1px;
   background-color: #fff;
-  border: 1px solid #ddd;
-}
-.list-group-item:first-child {
-  border-top-left-radius: .25rem; 
-  border-top-right-radius: .25rem;
-}
-.list-group-item:last-child {
-  margin-bottom: 0;
-  border-bottom-right-radius: .25rem;
-  border-bottom-left-radius: .25rem;
-}
+  border: 1px solid #ddd; }
+  .list-group-item:first-child {
+    border-top-right-radius: 0.25rem;
+    border-top-left-radius: 0.25rem; }
+  .list-group-item:last-child {
+    margin-bottom: 0;
+    border-bottom-right-radius: 0.25rem;
+    border-bottom-left-radius: 0.25rem; }
 
 a.list-group-item {
-  color: #555;
-}
-a.list-group-item .list-group-item-heading {
-  color: #333;
-}
-a.list-group-item:focus, a.list-group-item:hover {
-  color: #555;
-  text-decoration: none;
-  background-color: #f5f5f5;
-}
+  color: #555; }
+  a.list-group-item .list-group-item-heading {
+    color: #333; }
+  a.list-group-item:focus,
+  a.list-group-item:hover {
+    color: #555;
+    text-decoration: none;
+    background-color: #f5f5f5; }
 
-.list-group-item.disabled, .list-group-item.disabled:focus, .list-group-item.disabled:hover {
-  color: #818a91;
-  cursor: false;
-  background-color: #eceeef;
-}
-.list-group-item.disabled .list-group-item-heading, .list-group-item.disabled:focus .list-group-item-heading, .list-group-item.disabled:hover .list-group-item-heading {
-  color: inherit;
-}
-.list-group-item.disabled .list-group-item-text, .list-group-item.disabled:focus .list-group-item-text, .list-group-item.disabled:hover .list-group-item-text {
+.list-group-item.disabled,
+.list-group-item.disabled:focus,
+.list-group-item.disabled:hover {
   color: #818a91;
-}
-.list-group-item.active, .list-group-item.active:focus, .list-group-item.active:hover {
+  cursor: not-allowed;
+  background-color: #eceeef; }
+  .list-group-item.disabled .list-group-item-heading,
+  .list-group-item.disabled:focus .list-group-item-heading,
+  .list-group-item.disabled:hover .list-group-item-heading {
+    color: inherit; }
+  .list-group-item.disabled .list-group-item-text,
+  .list-group-item.disabled:focus .list-group-item-text,
+  .list-group-item.disabled:hover .list-group-item-text {
+    color: #818a91; }
+
+.list-group-item.active,
+.list-group-item.active:focus,
+.list-group-item.active:hover {
   z-index: 2;
   color: #fff;
   background-color: #0275d8;
-  border-color: #0275d8;
-}
-.list-group-item.active .list-group-item-heading, .list-group-item.active .list-group-item-heading > small, .list-group-item.active .list-group-item-heading > .small, .list-group-item.active:focus .list-group-item-heading, .list-group-item.active:focus .list-group-item-heading > small, .list-group-item.active:focus .list-group-item-heading > .small, .list-group-item.active:hover .list-group-item-heading, .list-group-item.active:hover .list-group-item-heading > small, .list-group-item.active:hover .list-group-item-heading > .small {
-  color: inherit;
-}
-.list-group-item.active .list-group-item-text, .list-group-item.active:focus .list-group-item-text, .list-group-item.active:hover .list-group-item-text {
-  color: #a8d6fe;
-}
+  border-color: #0275d8; }
+  .list-group-item.active .list-group-item-heading,
+  .list-group-item.active .list-group-item-heading > small,
+  .list-group-item.active .list-group-item-heading > .small,
+  .list-group-item.active:focus .list-group-item-heading,
+  .list-group-item.active:focus .list-group-item-heading > small,
+  .list-group-item.active:focus .list-group-item-heading > .small,
+  .list-group-item.active:hover .list-group-item-heading,
+  .list-group-item.active:hover .list-group-item-heading > small,
+  .list-group-item.active:hover .list-group-item-heading > .small {
+    color: inherit; }
+  .list-group-item.active .list-group-item-text,
+  .list-group-item.active:focus .list-group-item-text,
+  .list-group-item.active:hover .list-group-item-text {
+    color: #a8d6fe; }
 
 .list-group-item-state {
   color: #3c763d;
-  background-color: #dff0d8;
-}
+  background-color: #dff0d8; }
 
 a.list-group-item-state {
-  color: #3c763d;
-}
-a.list-group-item-state .list-group-item-heading {
-  color: inherit;
-}
-a.list-group-item-state:focus, a.list-group-item-state:hover {
-  color: #3c763d;
-  background-color: #d0e9c6;
-}
-a.list-group-item-state.active, a.list-group-item-state.active:focus, a.list-group-item-state.active:hover {
-  color: #fff;
-  background-color: #3c763d;
-  border-color: #3c763d;
-}
+  color: #3c763d; }
+  a.list-group-item-state .list-group-item-heading {
+    color: inherit; }
+  a.list-group-item-state:focus,
+  a.list-group-item-state:hover {
+    color: #3c763d;
+    background-color: #d0e9c6; }
+  a.list-group-item-state.active,
+  a.list-group-item-state.active:focus,
+  a.list-group-item-state.active:hover {
+    color: #fff;
+    background-color: #3c763d;
+    border-color: #3c763d; }
 
 .list-group-item-state {
   color: #31708f;
-  background-color: #d9edf7;
-}
+  background-color: #d9edf7; }
 
 a.list-group-item-state {
-  color: #31708f;
-}
-a.list-group-item-state .list-group-item-heading {
-  color: inherit;
-}
-a.list-group-item-state:focus, a.list-group-item-state:hover {
-  color: #31708f;
-  background-color: #c4e3f3;
-}
-a.list-group-item-state.active, a.list-group-item-state.active:focus, a.list-group-item-state.active:hover {
-  color: #fff;
-  background-color: #31708f;
-  border-color: #31708f;
-}
+  color: #31708f; }
+  a.list-group-item-state .list-group-item-heading {
+    color: inherit; }
+  a.list-group-item-state:focus,
+  a.list-group-item-state:hover {
+    color: #31708f;
+    background-color: #c4e3f3; }
+  a.list-group-item-state.active,
+  a.list-group-item-state.active:focus,
+  a.list-group-item-state.active:hover {
+    color: #fff;
+    background-color: #31708f;
+    border-color: #31708f; }
 
 .list-group-item-state {
   color: #8a6d3b;
-  background-color: #fcf8e3;
-}
+  background-color: #fcf8e3; }
 
 a.list-group-item-state {
-  color: #8a6d3b;
-}
-a.list-group-item-state .list-group-item-heading {
-  color: inherit;
-}
-a.list-group-item-state:focus, a.list-group-item-state:hover {
-  color: #8a6d3b;
-  background-color: #faf2cc;
-}
-a.list-group-item-state.active, a.list-group-item-state.active:focus, a.list-group-item-state.active:hover {
-  color: #fff;
-  background-color: #8a6d3b;
-  border-color: #8a6d3b;
-}
+  color: #8a6d3b; }
+  a.list-group-item-state .list-group-item-heading {
+    color: inherit; }
+  a.list-group-item-state:focus,
+  a.list-group-item-state:hover {
+    color: #8a6d3b;
+    background-color: #faf2cc; }
+  a.list-group-item-state.active,
+  a.list-group-item-state.active:focus,
+  a.list-group-item-state.active:hover {
+    color: #fff;
+    background-color: #8a6d3b;
+    border-color: #8a6d3b; }
 
 .list-group-item-state {
   color: #a94442;
-  background-color: #f2dede;
-}
+  background-color: #f2dede; }
 
 a.list-group-item-state {
-  color: #a94442;
-}
-a.list-group-item-state .list-group-item-heading {
-  color: inherit;
-}
-a.list-group-item-state:focus, a.list-group-item-state:hover {
-  color: #a94442;
-  background-color: #ebcccc;
-}
-a.list-group-item-state.active, a.list-group-item-state.active:focus, a.list-group-item-state.active:hover {
-  color: #fff;
-  background-color: #a94442;
-  border-color: #a94442;
-}
+  color: #a94442; }
+  a.list-group-item-state .list-group-item-heading {
+    color: inherit; }
+  a.list-group-item-state:focus,
+  a.list-group-item-state:hover {
+    color: #a94442;
+    background-color: #ebcccc; }
+  a.list-group-item-state.active,
+  a.list-group-item-state.active:focus,
+  a.list-group-item-state.active:hover {
+    color: #fff;
+    background-color: #a94442;
+    border-color: #a94442; }
 
 .list-group-item-heading {
   margin-top: 0;
-  margin-bottom: 5px;
-}
+  margin-bottom: 5px; }
 
 .list-group-item-text {
   margin-bottom: 0;
-  line-height: 1.3;
-}
+  line-height: 1.3; }
 
 .embed-responsive {
   position: relative;
   display: block;
   height: 0;
   padding: 0;
-  overflow: hidden;
-}
-.embed-responsive .embed-responsive-item, .embed-responsive iframe, .embed-responsive embed, .embed-responsive object, .embed-responsive video {
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  border: 0;
-}
+  overflow: hidden; }
+  .embed-responsive .embed-responsive-item,
+  .embed-responsive iframe,
+  .embed-responsive embed,
+  .embed-responsive object,
+  .embed-responsive video {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    border: 0; }
 
 .embed-responsive-16by9 {
-  padding-bottom: 56.25%;
-}
+  padding-bottom: 56.25%; }
 
 .embed-responsive-4by3 {
-  padding-bottom: 75%;
-}
+  padding-bottom: 75%; }
 
 .close {
   float: right;
@@ -4567,26 +3802,23 @@ a.list-group-item-state.active, a.list-group-item-state.active:focus, a.list-gro
   line-height: 1;
   color: #000;
   text-shadow: 0 1px 0 #fff;
-  opacity: .2;
-}
-.close:focus, .close:hover {
-  color: #000;
-  text-decoration: none;
-  cursor: pointer;
-  opacity: .5;
-}
+  opacity: .2; }
+  .close:focus,
+  .close:hover {
+    color: #000;
+    text-decoration: none;
+    cursor: pointer;
+    opacity: .5; }
 
 button.close {
-  -webkit-appearance: none; 
   padding: 0;
   cursor: pointer;
   background: transparent;
   border: 0;
-}
+  -webkit-appearance: none; }
 
 .modal-open {
-  overflow: hidden;
-}
+  overflow: hidden; }
 
 .modal {
   position: fixed;
@@ -4597,42 +3829,29 @@ button.close {
   z-index: 1050;
   display: none;
   overflow: hidden;
-  -webkit-overflow-scrolling: touch; 
   outline: 0;
-}
-.modal.fade .modal-dialog {
-  -webkit-transform: transition .3s ease-out, translate(0, -25%);
-      -ms-transform: transition .3s ease-out, translate(0, -25%);
-       -o-transform: transition .3s ease-out, translate(0, -25%);
-          transform: transition .3s ease-out, translate(0, -25%);
-}
-.modal.in .modal-dialog {
-  -webkit-transform: translate(0, 0);
-      -ms-transform: translate(0, 0);
-       -o-transform: translate(0, 0);
-          transform: translate(0, 0);
-}
+  -webkit-overflow-scrolling: touch; }
+  .modal.fade .modal-dialog {
+    transform: transition 0.3s ease-out, translate(0, -25%); }
+  .modal.in .modal-dialog {
+    transform: translate(0, 0); }
 
 .modal-open .modal {
   overflow-x: hidden;
-  overflow-y: auto;
-}
+  overflow-y: auto; }
 
 .modal-dialog {
   position: relative;
   width: auto;
-  margin: 10px;
-}
+  margin: 10px; }
 
 .modal-content {
   position: relative;
   background-color: #fff;
-  -webkit-background-clip: padding-box;
-          background-clip: padding-box;
-  border: 1px solid rgba(0, 0, 0, .2);
-  border-radius: .3rem;
-  outline: 0;
-}
+  background-clip: padding-box;
+  border: 1px solid rgba(0, 0, 0, 0.2);
+  border-radius: 0.3rem;
+  outline: 0; }
 
 .modal-backdrop {
   position: fixed;
@@ -4641,115 +3860,119 @@ button.close {
   bottom: 0;
   left: 0;
   z-index: 1040;
-  background-color: #000;
-}
-.modal-backdrop.fade {
-  opacity: 0;
-}
-.modal-backdrop.in {
-  opacity: .5;
-}
+  background-color: #000; }
+  .modal-backdrop.fade {
+    opacity: 0; }
+  .modal-backdrop.in {
+    opacity: 0.5; }
 
 .modal-header {
   min-height: 16.5px;
   padding: 15px;
-  border-bottom: 1px solid #e5e5e5;
-}
+  border-bottom: 1px solid #e5e5e5; }
 
 .modal-header .close {
-  margin-top: -2px;
-}
+  margin-top: -2px; }
 
 .modal-title {
   margin: 0;
-  line-height: 1.5;
-}
+  line-height: 1.5; }
 
 .modal-body {
   position: relative;
-  padding: 15px;
-}
+  padding: 15px; }
 
 .modal-footer {
   padding: 15px;
   text-align: right;
-  border-top: 1px solid #e5e5e5;
-}
-.modal-footer:before, .modal-footer:after {
-  display: table; 
-  content: " ";
-}
-.modal-footer:after {
-  clear: both;
-}
-.modal-footer .btn + .btn {
-  margin-bottom: 0;
-  margin-left: 5px;
-}
-.modal-footer .btn-group .btn + .btn {
-  margin-left: -1px;
-}
-.modal-footer .btn-block + .btn-block {
-  margin-left: 0;
-}
+  border-top: 1px solid #e5e5e5; }
+  .modal-footer:before,
+  .modal-footer:after {
+    content: " ";
+    display: table; }
+  .modal-footer:after {
+    clear: both; }
+  .modal-footer .btn + .btn {
+    margin-bottom: 0;
+    margin-left: 5px; }
+  .modal-footer .btn-group .btn + .btn {
+    margin-left: -1px; }
+  .modal-footer .btn-block + .btn-block {
+    margin-left: 0; }
 
 .modal-scrollbar-measure {
   position: absolute;
   top: -9999px;
   width: 50px;
   height: 50px;
-  overflow: scroll;
-}
+  overflow: scroll; }
 
 @media (min-width: 34em) {
   .modal-dialog {
     width: 600px;
-    margin: 30px auto;
-  }
+    margin: 30px auto; }
   .modal-sm {
-    width: 300px;
-  }
-}
+    width: 300px; } }
 
 @media (min-width: 48em) {
   .modal-lg {
-    width: 900px;
-  }
-}
+    width: 900px; } }
 
 .tooltip {
   position: absolute;
   z-index: 1070;
   display: block;
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-  font-size: .85rem;
+  font-size: 0.85rem;
   font-weight: normal;
   line-height: 1.4;
-  opacity: 0;
-}
-.tooltip.in {
-  opacity: .9;
-}
-
-.tooltip-top {
-  padding: 5px 0;
-  margin-top: -3px;
-}
-
-.tooltip-right {
-  padding: 0 5px;
-  margin-left: 3px;
-}
-
-.tooltip-bottom {
-  padding: 5px 0;
-  margin-top: 3px;
-}
-
-.tooltip-left {
-  padding: 0 5px;
-  margin-left: -3px;
-}
+  opacity: 0; }
+  .tooltip.in {
+    opacity: 0.9; }
+  .tooltip.tooltip-top,
+  .tooltip.bs-tether-element-attached-bottom {
+    padding: 5px 0;
+    margin-top: -3px; }
+    .tooltip.tooltip-top .tooltip-arrow,
+    .tooltip.bs-tether-element-attached-bottom .tooltip-arrow {
+      bottom: 0;
+      left: 50%;
+      margin-left: -5px;
+      border-width: 5px 5px 0;
+      border-top-color: #000; }
+  .tooltip.tooltip-right,
+  .tooltip.bs-tether-element-attached-left {
+    padding: 0 5px;
+    margin-left: 3px; }
+    .tooltip.tooltip-right .tooltip-arrow,
+    .tooltip.bs-tether-element-attached-left .tooltip-arrow {
+      top: 50%;
+      left: 0;
+      margin-top: -5px;
+      border-width: 5px 5px 5px 0;
+      border-right-color: #000; }
+  .tooltip.tooltip-bottom,
+  .tooltip.bs-tether-element-attached-top {
+    padding: 5px 0;
+    margin-top: 3px; }
+    .tooltip.tooltip-bottom .tooltip-arrow,
+    .tooltip.bs-tether-element-attached-top .tooltip-arrow {
+      top: 0;
+      left: 50%;
+      margin-left: -5px;
+      border-width: 0 5px 5px;
+      border-bottom-color: #000; }
+  .tooltip.tooltip-left,
+  .tooltip.bs-tether-element-attached-right {
+    padding: 0 5px;
+    margin-left: -3px; }
+    .tooltip.tooltip-left .tooltip-arrow,
+    .tooltip.bs-tether-element-attached-right .tooltip-arrow {
+      top: 50%;
+      right: 0;
+      margin-top: -5px;
+      border-width: 5px 0 5px 5px;
+      border-left-color: #000; }
 
 .tooltip-inner {
   max-width: 200px;
@@ -4758,55 +3981,21 @@ button.close {
   text-align: center;
   text-decoration: none;
   background-color: #000;
-  border-radius: .25rem;
-}
+  border-radius: 0.25rem; }
 
 .tooltip-arrow {
   position: absolute;
   width: 0;
   height: 0;
   border-color: transparent;
-  border-style: solid;
-}
-
-.tooltip-top .tooltip-arrow {
-  bottom: 0;
-  left: 50%;
-  margin-left: -5px;
-  border-width: 5px 5px 0;
-  border-top-color: #000;
-}
-
-.tooltip-right .tooltip-arrow {
-  top: 50%;
-  left: 0;
-  margin-top: -5px;
-  border-width: 5px 5px 5px 0;
-  border-right-color: #000;
-}
-
-.tooltip-left .tooltip-arrow {
-  top: 50%;
-  right: 0;
-  margin-top: -5px;
-  border-width: 5px 0 5px 5px;
-  border-left-color: #000;
-}
-
-.tooltip-bottom .tooltip-arrow {
-  top: 0;
-  left: 50%;
-  margin-left: -5px;
-  border-width: 0 5px 5px;
-  border-bottom-color: #000;
-}
+  border-style: solid; }
 
 .popover {
   position: absolute;
   top: 0;
   left: 0;
   z-index: 1060;
-  display: none;
+  display: block;
   max-width: 276px;
   padding: 1px;
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
@@ -4816,27 +4005,77 @@ button.close {
   text-align: left;
   white-space: normal;
   background-color: #fff;
-  -webkit-background-clip: padding-box;
-          background-clip: padding-box;
-  border: 1px solid rgba(0, 0, 0, .2);
-  border-radius: .3rem;
-}
-
-.popover-top {
-  margin-top: -10px;
-}
-
-.popover-right {
-  margin-left: 10px;
-}
-
-.popover-bottom {
-  margin-top: 10px;
-}
-
-.popover-left {
-  margin-left: -10px;
-}
+  background-clip: padding-box;
+  border: 1px solid rgba(0, 0, 0, 0.2);
+  border-radius: 0.3rem; }
+  .popover.popover-top,
+  .popover.bs-tether-element-attached-bottom {
+    margin-top: -10px; }
+    .popover.popover-top .popover-arrow,
+    .popover.bs-tether-element-attached-bottom .popover-arrow {
+      bottom: -11px;
+      left: 50%;
+      margin-left: -11px;
+      border-top-color: rgba(0, 0, 0, 0.25);
+      border-bottom-width: 0; }
+      .popover.popover-top .popover-arrow:after,
+      .popover.bs-tether-element-attached-bottom .popover-arrow:after {
+        bottom: 1px;
+        margin-left: -10px;
+        content: "";
+        border-top-color: #fff;
+        border-bottom-width: 0; }
+  .popover.popover-right,
+  .popover.bs-tether-element-attached-left {
+    margin-left: 10px; }
+    .popover.popover-right .popover-arrow,
+    .popover.bs-tether-element-attached-left .popover-arrow {
+      top: 50%;
+      left: -11px;
+      margin-top: -11px;
+      border-right-color: rgba(0, 0, 0, 0.25);
+      border-left-width: 0; }
+      .popover.popover-right .popover-arrow:after,
+      .popover.bs-tether-element-attached-left .popover-arrow:after {
+        bottom: -10px;
+        left: 1px;
+        content: "";
+        border-right-color: #fff;
+        border-left-width: 0; }
+  .popover.popover-bottom,
+  .popover.bs-tether-element-attached-top {
+    margin-top: 10px; }
+    .popover.popover-bottom .popover-arrow,
+    .popover.bs-tether-element-attached-top .popover-arrow {
+      top: -11px;
+      left: 50%;
+      margin-left: -11px;
+      border-top-width: 0;
+      border-bottom-color: rgba(0, 0, 0, 0.25); }
+      .popover.popover-bottom .popover-arrow:after,
+      .popover.bs-tether-element-attached-top .popover-arrow:after {
+        top: 1px;
+        margin-left: -10px;
+        content: "";
+        border-top-width: 0;
+        border-bottom-color: #fff; }
+  .popover.popover-left,
+  .popover.bs-tether-element-attached-right {
+    margin-left: -10px; }
+    .popover.popover-left .popover-arrow,
+    .popover.bs-tether-element-attached-right .popover-arrow {
+      top: 50%;
+      right: -11px;
+      margin-top: -11px;
+      border-right-width: 0;
+      border-left-color: rgba(0, 0, 0, 0.25); }
+      .popover.popover-left .popover-arrow:after,
+      .popover.bs-tether-element-attached-right .popover-arrow:after {
+        right: 1px;
+        bottom: -10px;
+        content: "";
+        border-right-width: 0;
+        border-left-color: #fff; }
 
 .popover-title {
   padding: 8px 14px;
@@ -4844,163 +4083,81 @@ button.close {
   font-size: 1rem;
   background-color: #f7f7f7;
   border-bottom: 1px solid #ebebeb;
-  border-radius: -.7rem -.7rem 0 0;
-}
+  border-radius: -0.7rem -0.7rem 0 0; }
 
 .popover-content {
-  padding: 9px 14px;
-}
+  padding: 9px 14px; }
 
-.popover-arrow, .popover-arrow:after {
+.popover-arrow,
+.popover-arrow:after {
   position: absolute;
   display: block;
   width: 0;
   height: 0;
   border-color: transparent;
-  border-style: solid;
-}
+  border-style: solid; }
 
 .popover-arrow {
-  border-width: 11px;
-}
+  border-width: 11px; }
 
 .popover-arrow:after {
   content: "";
-  border-width: 10px;
-}
-
-.popover-top > .popover-arrow {
-  bottom: -11px;
-  left: 50%;
-  margin-left: -11px;
-  border-top-color: rgba(0, 0, 0, .25);
-  border-bottom-width: 0;
-}
-.popover-top > .popover-arrow:after {
-  bottom: 1px;
-  margin-left: -10px;
-  content: "";
-  border-top-color: #fff;
-  border-bottom-width: 0;
-}
-
-.popover-right > .popover-arrow {
-  top: 50%;
-  left: -11px;
-  margin-top: -11px;
-  border-right-color: rgba(0, 0, 0, .25);
-  border-left-width: 0;
-}
-.popover-right > .popover-arrow:after {
-  bottom: -10px;
-  left: 1px;
-  content: "";
-  border-right-color: #fff;
-  border-left-width: 0;
-}
-
-.popover-bottom > .popover-arrow {
-  top: -11px;
-  left: 50%;
-  margin-left: -11px;
-  border-top-width: 0;
-  border-bottom-color: rgba(0, 0, 0, .25);
-}
-.popover-bottom > .popover-arrow:after {
-  top: 1px;
-  margin-left: -10px;
-  content: "";
-  border-top-width: 0;
-  border-bottom-color: #fff;
-}
-
-.popover-left > .popover-arrow {
-  top: 50%;
-  right: -11px;
-  margin-top: -11px;
-  border-right-width: 0;
-  border-left-color: rgba(0, 0, 0, .25);
-}
-.popover-left > .popover-arrow:after {
-  right: 1px;
-  bottom: -10px;
-  content: "";
-  border-right-width: 0;
-  border-left-color: #fff;
-}
+  border-width: 10px; }
 
 .carousel {
-  position: relative;
-}
+  position: relative; }
 
 .carousel-inner {
   position: relative;
   width: 100%;
-  overflow: hidden;
-}
-.carousel-inner > .carousel-item {
-  position: relative;
-  display: none;
-  -webkit-transition: .6s ease-in-out left;
-       -o-transition: .6s ease-in-out left;
-          transition: .6s ease-in-out left;
-}
-.carousel-inner > .carousel-item > img, .carousel-inner > .carousel-item > a > img {
-  line-height: 1;
-}
-@media all and (transform-3d), (-webkit-transform-3d) {
+  overflow: hidden; }
   .carousel-inner > .carousel-item {
-    -webkit-transition: -webkit-transform .6s ease-in-out;
-         -o-transition:      -o-transform .6s ease-in-out;
-            transition:         transform .6s ease-in-out;
-
-    -webkit-backface-visibility: hidden;
-            backface-visibility: hidden;
-    -webkit-perspective: 1000;
-            perspective: 1000;
-  }
-  .carousel-inner > .carousel-item.next, .carousel-inner > .carousel-item.active.right {
-    left: 0;
-    -webkit-transform: translate3d(100%, 0, 0);
-            transform: translate3d(100%, 0, 0);
-  }
-  .carousel-inner > .carousel-item.prev, .carousel-inner > .carousel-item.active.left {
-    left: 0;
-    -webkit-transform: translate3d(-100%, 0, 0);
-            transform: translate3d(-100%, 0, 0);
-  }
-  .carousel-inner > .carousel-item.next.left, .carousel-inner > .carousel-item.prev.right, .carousel-inner > .carousel-item.active {
-    left: 0;
-    -webkit-transform: translate3d(0, 0, 0);
-            transform: translate3d(0, 0, 0);
-  }
-}
-.carousel-inner > .active, .carousel-inner > .next, .carousel-inner > .prev {
-  display: block;
-}
-.carousel-inner > .active {
-  left: 0;
-}
-.carousel-inner > .next, .carousel-inner > .prev {
-  position: absolute;
-  top: 0;
-  width: 100%;
-}
-.carousel-inner > .next {
-  left: 100%;
-}
-.carousel-inner > .prev {
-  left: -100%;
-}
-.carousel-inner > .next.left, .carousel-inner > .prev.right {
-  left: 0;
-}
-.carousel-inner > .active.left {
-  left: -100%;
-}
-.carousel-inner > .active.right {
-  left: 100%;
-}
+    position: relative;
+    display: none;
+    transition: .6s ease-in-out left; }
+    .carousel-inner > .carousel-item > img,
+    .carousel-inner > .carousel-item > a > img {
+      line-height: 1; }
+    @media all and (transform-3d), (-webkit-transform-3d) {
+      .carousel-inner > .carousel-item {
+        transition: transform 0.6s ease-in-out;
+        backface-visibility: hidden;
+        perspective: 1000; }
+        .carousel-inner > .carousel-item.next,
+        .carousel-inner > .carousel-item.active.right {
+          left: 0;
+          transform: translate3d(100%, 0, 0); }
+        .carousel-inner > .carousel-item.prev,
+        .carousel-inner > .carousel-item.active.left {
+          left: 0;
+          transform: translate3d(-100%, 0, 0); }
+        .carousel-inner > .carousel-item.next.left,
+        .carousel-inner > .carousel-item.prev.right,
+        .carousel-inner > .carousel-item.active {
+          left: 0;
+          transform: translate3d(0, 0, 0); } }
+  .carousel-inner > .active,
+  .carousel-inner > .next,
+  .carousel-inner > .prev {
+    display: block; }
+  .carousel-inner > .active {
+    left: 0; }
+  .carousel-inner > .next,
+  .carousel-inner > .prev {
+    position: absolute;
+    top: 0;
+    width: 100%; }
+  .carousel-inner > .next {
+    left: 100%; }
+  .carousel-inner > .prev {
+    left: -100%; }
+  .carousel-inner > .next.left,
+  .carousel-inner > .prev.right {
+    left: 0; }
+  .carousel-inner > .active.left {
+    left: -100%; }
+  .carousel-inner > .active.right {
+    left: 100%; }
 
 .carousel-control {
   position: absolute;
@@ -5011,58 +4168,45 @@ button.close {
   font-size: 20px;
   color: #fff;
   text-align: center;
-  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
-  opacity: .5;
-}
-.carousel-control.left {
-  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));
-  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
-  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
-  background-image:         linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); 
-  background-repeat: repeat-x;
-}
-.carousel-control.right {
-  right: 0;
-  left: auto;
-  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));
-  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
-  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
-  background-image:         linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); 
-  background-repeat: repeat-x;
-}
-.carousel-control:focus, .carousel-control:hover {
-  color: #fff;
-  text-decoration: none;
-  outline: 0;
-  opacity: .9;
-}
-.carousel-control .icon-prev, .carousel-control .icon-next {
-  position: absolute;
-  top: 50%;
-  z-index: 5;
-  display: inline-block;
-  width: 20px;
-  height: 20px;
-  margin-top: -10px;
-  font-family: serif;
-  line-height: 1;
-}
-.carousel-control .icon-prev {
-  left: 50%;
-  margin-left: -10px;
-}
-.carousel-control .icon-next {
-  right: 50%;
-  margin-right: -10px;
-}
-.carousel-control .icon-prev:before {
-  content: "\2039";
-}
-.carousel-control .icon-next:before {
-  content: "\203a";
-}
+  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
+  opacity: 0.5; }
+  .carousel-control.left {
+    background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+    background-repeat: repeat-x;
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); }
+  .carousel-control.right {
+    right: 0;
+    left: auto;
+    background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+    background-repeat: repeat-x;
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); }
+  .carousel-control:focus,
+  .carousel-control:hover {
+    color: #fff;
+    text-decoration: none;
+    outline: 0;
+    opacity: .9; }
+  .carousel-control .icon-prev,
+  .carousel-control .icon-next {
+    position: absolute;
+    top: 50%;
+    z-index: 5;
+    display: inline-block;
+    width: 20px;
+    height: 20px;
+    margin-top: -10px;
+    font-family: serif;
+    line-height: 1; }
+  .carousel-control .icon-prev {
+    left: 50%;
+    margin-left: -10px; }
+  .carousel-control .icon-next {
+    right: 50%;
+    margin-right: -10px; }
+  .carousel-control .icon-prev:before {
+    content: "\2039"; }
+  .carousel-control .icon-next:before {
+    content: "\203a"; }
 
 .carousel-indicators {
   position: absolute;
@@ -5073,25 +4217,22 @@ button.close {
   padding-left: 0;
   margin-left: -30%;
   text-align: center;
-  list-style: none;
-}
-.carousel-indicators li {
-  display: inline-block;
-  width: 10px;
-  height: 10px;
-  margin: 1px;
-  text-indent: -999px;
-  cursor: pointer;
-  background-color: transparent;
-  border: 1px solid #fff;
-  border-radius: 10px;
-}
-.carousel-indicators .active {
-  width: 12px;
-  height: 12px;
-  margin: 0;
-  background-color: #fff;
-}
+  list-style: none; }
+  .carousel-indicators li {
+    display: inline-block;
+    width: 10px;
+    height: 10px;
+    margin: 1px;
+    text-indent: -999px;
+    cursor: pointer;
+    background-color: transparent;
+    border: 1px solid #fff;
+    border-radius: 10px; }
+  .carousel-indicators .active {
+    width: 12px;
+    height: 12px;
+    margin: 0;
+    background-color: #fff; }
 
 .carousel-caption {
   position: absolute;
@@ -5103,56 +4244,46 @@ button.close {
   padding-bottom: 20px;
   color: #fff;
   text-align: center;
-  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
-}
-.carousel-caption .btn {
-  text-shadow: none;
-}
+  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); }
+  .carousel-caption .btn {
+    text-shadow: none; }
 
 @media (min-width: 34em) {
-  .carousel-control .icon-prev, .carousel-control .icon-next {
+  .carousel-control .icon-prev,
+  .carousel-control .icon-next {
     width: 30px;
     height: 30px;
     margin-top: -15px;
-    font-size: 30px;
-  }
+    font-size: 30px; }
   .carousel-control .icon-prev {
-    margin-left: -15px;
-  }
+    margin-left: -15px; }
   .carousel-control .icon-next {
-    margin-right: -15px;
-  }
+    margin-right: -15px; }
   .carousel-caption {
     right: 20%;
     left: 20%;
-    padding-bottom: 30px;
-  }
+    padding-bottom: 30px; }
   .carousel-indicators {
-    bottom: 20px;
-  }
-}
+    bottom: 20px; } }
 
-.clearfix:before, .clearfix:after {
-  display: table; 
+.clearfix:before,
+.clearfix:after {
   content: " ";
-}
+  display: table; }
+
 .clearfix:after {
-  clear: both;
-}
+  clear: both; }
 
 .center-block {
   display: block;
-  margin-right: auto; 
   margin-left: auto;
-}
+  margin-right: auto; }
 
 .pull-right {
-  float: right !important;
-}
+  float: right !important; }
 
 .pull-left {
-  float: left !important;
-}
+  float: left !important; }
 
 .sr-only {
   position: absolute;
@@ -5162,463 +4293,360 @@ button.close {
   margin: -1px;
   overflow: hidden;
   clip: rect(0, 0, 0, 0);
-  border: 0;
-}
+  border: 0; }
 
-.sr-only-focusable:active, .sr-only-focusable:focus {
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
   position: static;
   width: auto;
   height: auto;
   margin: 0;
   overflow: visible;
-  clip: auto;
-}
+  clip: auto; }
 
 .m-a-0 {
-  margin: 0;
-}
+  margin: 0; }
 
 .m-t-0 {
-  margin-top: 0;
-}
+  margin-top: 0; }
 
 .m-r-0 {
-  margin-right: 0;
-}
+  margin-right: 0; }
 
 .m-b-0 {
-  margin-bottom: 0;
-}
+  margin-bottom: 0; }
 
 .m-l-0 {
-  margin-left: 0;
-}
+  margin-left: 0; }
 
 .m-a {
-  margin: 1rem;
-}
+  margin: 1rem; }
 
 .m-t {
-  margin-top: 1rem;
-}
+  margin-top: 1rem; }
 
 .m-r {
-  margin-right: 1rem;
-}
+  margin-right: 1rem; }
 
 .m-b {
-  margin-bottom: 1rem;
-}
+  margin-bottom: 1rem; }
 
 .m-l {
-  margin-left: 1rem;
-}
+  margin-left: 1rem; }
 
 .m-x {
   margin-right: 1rem;
-  margin-left: 1rem;
-}
+  margin-left: 1rem; }
 
 .m-y {
   margin-top: 1rem;
-  margin-bottom: 1rem;
-}
+  margin-bottom: 1rem; }
 
 .m-t-md {
-  margin-top: 1.5rem;
-}
+  margin-top: 1.5rem; }
 
 .m-r-md {
-  margin-right: 1.5rem;
-}
+  margin-right: 1.5rem; }
 
 .m-b-md {
-  margin-bottom: 1.5rem;
-}
+  margin-bottom: 1.5rem; }
 
 .m-l-md {
-  margin-left: 1.5rem;
-}
+  margin-left: 1.5rem; }
 
 .m-x-md {
   margin-right: 1.5rem;
-  margin-left: 1.5rem;
-}
+  margin-left: 1.5rem; }
 
 .m-y-md {
   margin-top: 1.5rem;
-  margin-bottom: 1.5rem;
-}
+  margin-bottom: 1.5rem; }
 
 .m-t-lg {
-  margin-top: 3rem;
-}
+  margin-top: 3rem; }
 
 .m-r-lg {
-  margin-right: 3rem;
-}
+  margin-right: 3rem; }
 
 .m-b-lg {
-  margin-bottom: 3rem;
-}
+  margin-bottom: 3rem; }
 
 .m-l-lg {
-  margin-left: 3rem;
-}
+  margin-left: 3rem; }
 
 .m-x-lg {
   margin-right: 3rem;
-  margin-left: 3rem;
-}
+  margin-left: 3rem; }
 
 .m-y-lg {
   margin-top: 3rem;
-  margin-bottom: 3rem;
-}
+  margin-bottom: 3rem; }
 
 .p-a-0 {
-  padding: 0;
-}
+  padding: 0; }
 
 .p-t-0 {
-  padding-top: 0;
-}
+  padding-top: 0; }
 
 .p-r-0 {
-  padding-right: 0;
-}
+  padding-right: 0; }
 
 .p-b-0 {
-  padding-bottom: 0;
-}
+  padding-bottom: 0; }
 
 .p-l-0 {
-  padding-left: 0;
-}
+  padding-left: 0; }
 
 .p-a {
-  padding: 1rem;
-}
+  padding: 1rem; }
 
 .p-t {
-  padding-top: 1rem;
-}
+  padding-top: 1rem; }
 
 .p-r {
-  padding-right: 1rem;
-}
+  padding-right: 1rem; }
 
 .p-b {
-  padding-bottom: 1rem;
-}
+  padding-bottom: 1rem; }
 
 .p-l {
-  padding-left: 1rem;
-}
+  padding-left: 1rem; }
 
 .p-x {
   padding-right: 1rem;
-  padding-left: 1rem;
-}
+  padding-left: 1rem; }
 
 .p-y {
   padding-top: 1rem;
-  padding-bottom: 1rem;
-}
+  padding-bottom: 1rem; }
 
 .p-t-md {
-  padding-top: 1.5rem;
-}
+  padding-top: 1.5rem; }
 
 .p-r-md {
-  padding-right: 1.5rem;
-}
+  padding-right: 1.5rem; }
 
 .p-b-md {
-  padding-bottom: 1.5rem;
-}
+  padding-bottom: 1.5rem; }
 
 .p-l-md {
-  padding-left: 1.5rem;
-}
+  padding-left: 1.5rem; }
 
 .p-x-md {
   padding-right: 1.5rem;
-  padding-left: 1.5rem;
-}
+  padding-left: 1.5rem; }
 
 .p-y-md {
   padding-top: 1.5rem;
-  padding-bottom: 1.5rem;
-}
+  padding-bottom: 1.5rem; }
 
 .p-t-lg {
-  padding-top: 3rem;
-}
+  padding-top: 3rem; }
 
 .p-r-lg {
-  padding-right: 3rem;
-}
+  padding-right: 3rem; }
 
 .p-b-lg {
-  padding-bottom: 3rem;
-}
+  padding-bottom: 3rem; }
 
 .p-l-lg {
-  padding-left: 3rem;
-}
+  padding-left: 3rem; }
 
 .p-x-lg {
   padding-right: 3rem;
-  padding-left: 3rem;
-}
+  padding-left: 3rem; }
 
 .p-y-lg {
   padding-top: 3rem;
-  padding-bottom: 3rem;
-}
+  padding-bottom: 3rem; }
 
 .pos-f-t {
   position: fixed;
   top: 0;
   right: 0;
   left: 0;
-  z-index: 1030;
-}
+  z-index: 1030; }
 
 [hidden] {
-  display: none !important;
-}
+  display: none !important; }
 
 .invisible {
-  visibility: hidden;
-}
+  visibility: hidden; }
 
 .text-hide {
   font: "0/0" a;
   color: transparent;
   text-shadow: none;
   background-color: transparent;
-  border: 0;
-}
+  border: 0; }
 
 .text-left {
-  text-align: left;
-}
+  text-align: left; }
 
 .text-right {
-  text-align: right;
-}
+  text-align: right; }
 
 .text-center {
-  text-align: center;
-}
+  text-align: center; }
 
 .text-justify {
-  text-align: justify;
-}
+  text-align: justify; }
 
 .text-nowrap {
-  white-space: nowrap;
-}
+  white-space: nowrap; }
 
 .text-truncate {
   overflow: hidden;
   text-overflow: ellipsis;
-  white-space: nowrap;
-}
+  white-space: nowrap; }
 
 .text-lowercase {
-  text-transform: lowercase;
-}
+  text-transform: lowercase; }
 
 .text-uppercase {
-  text-transform: uppercase;
-}
+  text-transform: uppercase; }
 
 .text-capitalize {
-  text-transform: capitalize;
-}
+  text-transform: capitalize; }
 
 .text-muted {
-  color: #818a91;
-}
+  color: #818a91; }
 
 .text-primary {
-  color: #0275d8;
-}
+  color: #0275d8; }
 
-a.text-primary:focus, a.text-primary:hover {
-  color: #025aa5;
-}
+a.text-primary:focus,
+a.text-primary:hover {
+  color: #025aa5; }
 
 .text-success {
-  color: #3c763d;
-}
+  color: #3c763d; }
 
-a.text-success:focus, a.text-success:hover {
-  color: #2b542c;
-}
+a.text-success:focus,
+a.text-success:hover {
+  color: #2b542c; }
 
 .text-info {
-  color: #31708f;
-}
+  color: #31708f; }
 
-a.text-info:focus, a.text-info:hover {
-  color: #245269;
-}
+a.text-info:focus,
+a.text-info:hover {
+  color: #245269; }
 
 .text-warning {
-  color: #8a6d3b;
-}
+  color: #8a6d3b; }
 
-a.text-warning:focus, a.text-warning:hover {
-  color: #66512c;
-}
+a.text-warning:focus,
+a.text-warning:hover {
+  color: #66512c; }
 
 .text-danger {
-  color: #a94442;
-}
+  color: #a94442; }
 
-a.text-danger:focus, a.text-danger:hover {
-  color: #843534;
-}
+a.text-danger:focus,
+a.text-danger:hover {
+  color: #843534; }
 
 .inverse {
   color: #eceeef;
-  background-color: #373a3c;
-}
+  background-color: #373a3c; }
 
 .bg-primary {
-  color: #fff;
-}
+  color: #fff; }
 
 .bg-primary {
-  background-color: #0275d8;
-}
+  background-color: #0275d8; }
 
-a.bg-primary:focus, a.bg-primary:hover {
-  background-color: #025aa5;
-}
+a.bg-primary:focus,
+a.bg-primary:hover {
+  background-color: #025aa5; }
 
 .bg-success {
-  background-color: #dff0d8;
-}
+  background-color: #dff0d8; }
 
-a.bg-success:focus, a.bg-success:hover {
-  background-color: #c1e2b3;
-}
+a.bg-success:focus,
+a.bg-success:hover {
+  background-color: #c1e2b3; }
 
 .bg-info {
-  background-color: #d9edf7;
-}
+  background-color: #d9edf7; }
 
-a.bg-info:focus, a.bg-info:hover {
-  background-color: #afd9ee;
-}
+a.bg-info:focus,
+a.bg-info:hover {
+  background-color: #afd9ee; }
 
 .bg-warning {
-  background-color: #fcf8e3;
-}
+  background-color: #fcf8e3; }
 
-a.bg-warning:focus, a.bg-warning:hover {
-  background-color: #f7ecb5;
-}
+a.bg-warning:focus,
+a.bg-warning:hover {
+  background-color: #f7ecb5; }
 
 .bg-danger {
-  background-color: #f2dede;
-}
+  background-color: #f2dede; }
 
-a.bg-danger:focus, a.bg-danger:hover {
-  background-color: #e4b9b9;
-}
+a.bg-danger:focus,
+a.bg-danger:hover {
+  background-color: #e4b9b9; }
 
 .hidden-xs-up {
-  display: none !important;
-}
+  display: none !important; }
 
 @media (max-width: 33.9em) {
   .hidden-xs-down {
-    display: none !important;
-  }
-}
+    display: none !important; } }
 
 @media (min-width: 34em) {
   .hidden-sm-up {
-    display: none !important;
-  }
-}
+    display: none !important; } }
 
 @media (max-width: 47.9em) {
   .hidden-sm-down {
-    display: none !important;
-  }
-}
+    display: none !important; } }
 
 @media (min-width: 48em) {
   .hidden-md-up {
-    display: none !important;
-  }
-}
+    display: none !important; } }
 
 @media (max-width: 61.9em) {
   .hidden-md-down {
-    display: none !important;
-  }
-}
+    display: none !important; } }
 
 @media (min-width: 62em) {
   .hidden-lg-up {
-    display: none !important;
-  }
-}
+    display: none !important; } }
 
 @media (max-width: 74.9em) {
   .hidden-lg-down {
-    display: none !important;
-  }
-}
+    display: none !important; } }
 
 @media (min-width: 75em) {
   .hidden-xl-up {
-    display: none !important;
-  }
-}
+    display: none !important; } }
 
 .hidden-xl-down {
-  display: none !important;
-}
+  display: none !important; }
 
 .visible-print-block {
-  display: none !important;
-}
-@media print {
-  .visible-print-block {
-    display: block !important;
-  }
-}
+  display: none !important; }
+  @media print {
+    .visible-print-block {
+      display: block !important; } }
 
 .visible-print-inline {
-  display: none !important;
-}
-@media print {
-  .visible-print-inline {
-    display: inline !important;
-  }
-}
+  display: none !important; }
+  @media print {
+    .visible-print-inline {
+      display: inline !important; } }
 
 .visible-print-inline-block {
-  display: none !important;
-}
-@media print {
-  .visible-print-inline-block {
-    display: inline-block !important;
-  }
-}
+  display: none !important; }
+  @media print {
+    .visible-print-inline-block {
+      display: inline-block !important; } }
 
 @media print {
   .hidden-print .hidden-print {
-    display: none !important;
-  }
-}
-/*# sourceMappingURL=bootstrap.css.map */
+    display: none !important; } }
+
+/*# sourceMappingURL=bootstrap.css.map */
\ No newline at end of file
diff --git a/dist/css/bootstrap.css.map b/dist/css/bootstrap.css.map
index 1d038873a74a0105d38805be620795a3e7e818bd..e21e231a9776f41a995b3a52058587a5081092c6 100644
Binary files a/dist/css/bootstrap.css.map and b/dist/css/bootstrap.css.map differ
diff --git a/dist/js/bootstrap.js b/dist/js/bootstrap.js
index a6827d652cb5ef6603678cd7915dea68db63e5b6..01f0a6dac21198bbe359737b5ebd2a2b6632f69c 100644
--- a/dist/js/bootstrap.js
+++ b/dist/js/bootstrap.js
@@ -15,2348 +15,3491 @@ if (typeof jQuery === 'undefined') {
   }
 }(jQuery);
 
-/* ========================================================================
- * Bootstrap: transition.js v3.3.4
- * http://getbootstrap.com/javascript/#transitions
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
+
++function ($) {
+
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): util.js
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
+ * --------------------------------------------------------------------------
+ */
 
+var Util = (function ($) {
 
-+function ($) {
-  'use strict';
+  /**
+   * ------------------------------------------------------------------------
+   * Private TransitionEnd Helpers
+   * ------------------------------------------------------------------------
+   */
+
+  var transition = false;
+
+  var TransitionEndEvent = {
+    WebkitTransition: 'webkitTransitionEnd',
+    MozTransition: 'transitionend',
+    OTransition: 'oTransitionEnd otransitionend',
+    transition: 'transitionend'
+  };
 
-  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
-  // ============================================================
+  // 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 transitionEnd() {
-    var el = document.createElement('bootstrap')
+  function getSpecialTransitionEndEvent() {
+    return {
+      bindType: transition.end,
+      delegateType: transition.end,
+      handle: function handle(event) {
+        if ($(event.target).is(this)) {
+          return event.handleObj.handler.apply(this, arguments);
+        }
+      }
+    };
+  }
 
-    var transEndEventNames = {
-      WebkitTransition : 'webkitTransitionEnd',
-      MozTransition    : 'transitionend',
-      OTransition      : 'oTransitionEnd otransitionend',
-      transition       : 'transitionend'
+  function transitionEndTest() {
+    if (window.QUnit) {
+      return false;
     }
 
-    for (var name in transEndEventNames) {
+    var el = document.createElement('bootstrap');
+
+    for (var name in TransitionEndEvent) {
       if (el.style[name] !== undefined) {
-        return { end: transEndEventNames[name] }
+        return { end: TransitionEndEvent[name] };
       }
     }
 
-    return false // explicit for ie8 (  ._.)
+    return false;
   }
 
-  // http://blog.alexmaccaw.com/css-transitions
-  $.fn.emulateTransitionEnd = function (duration) {
-    var called = false
-    var $el = this
-    $(this).one('bsTransitionEnd', function () { called = true })
-    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
-    setTimeout(callback, duration)
-    return this
-  }
+  function transitionEndEmulator(duration) {
+    var _this = this;
 
-  $(function () {
-    $.support.transition = transitionEnd()
+    var called = false;
 
-    if (!$.support.transition) return
+    $(this).one(Util.TRANSITION_END, function () {
+      called = true;
+    });
 
-    $.event.special.bsTransitionEnd = {
-      bindType: $.support.transition.end,
-      delegateType: $.support.transition.end,
-      handle: function (e) {
-        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
+    setTimeout(function () {
+      if (!called) {
+        Util.triggerTransitionEnd(_this);
       }
-    }
-  })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: alert.js v3.3.4
- * http://getbootstrap.com/javascript/#alerts
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
+    }, duration);
 
+    return this;
+  }
 
-+function ($) {
-  'use strict';
+  function setTransitionEndSupport() {
+    transition = transitionEndTest();
 
-  // ALERT CLASS DEFINITION
-  // ======================
+    $.fn.emulateTransitionEnd = transitionEndEmulator;
 
-  var dismiss = '[data-dismiss="alert"]'
-  var Alert   = function (el) {
-    $(el).on('click', dismiss, this.close)
+    if (Util.supportsTransitionEnd()) {
+      $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
+    }
   }
 
-  Alert.VERSION = '3.3.4'
+  /**
+   * --------------------------------------------------------------------------
+   * Public Util Api
+   * --------------------------------------------------------------------------
+   */
 
-  Alert.TRANSITION_DURATION = 150
+  var Util = {
 
-  Alert.prototype.close = function (e) {
-    var $this    = $(this)
-    var selector = $this.attr('data-target')
+    TRANSITION_END: 'bsTransitionEnd',
 
-    if (!selector) {
-      selector = $this.attr('href')
-      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
-    }
+    getUID: function getUID(prefix) {
+      do prefix += ~ ~(Math.random() * 1000000); while (document.getElementById(prefix));
+      return prefix;
+    },
 
-    var $parent = $(selector)
+    getSelectorFromElement: function getSelectorFromElement(element) {
+      var selector = element.getAttribute('data-target');
 
-    if (e) e.preventDefault()
+      if (!selector) {
+        selector = element.getAttribute('href') || '';
+        selector = /^#[a-z]/i.test(selector) ? selector : null;
+      }
 
-    if (!$parent.length) {
-      $parent = $this.closest('.alert')
-    }
+      return selector;
+    },
 
-    $parent.trigger(e = $.Event('close.bs.alert'))
+    reflow: function reflow(element) {
+      new Function('bs', 'return bs')(element.offsetHeight);
+    },
 
-    if (e.isDefaultPrevented()) return
+    triggerTransitionEnd: function triggerTransitionEnd(element) {
+      $(element).trigger(transition.end);
+    },
 
-    $parent.removeClass('in')
+    supportsTransitionEnd: function supportsTransitionEnd() {
+      return !!transition;
+    },
 
-    function removeElement() {
-      // detach from parent, fire event then clean up data
-      $parent.detach().trigger('closed.bs.alert').remove()
-    }
+    typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
 
-    $.support.transition && $parent.hasClass('fade') ?
-      $parent
-        .one('bsTransitionEnd', removeElement)
-        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
-      removeElement()
-  }
+      for (var property in configTypes) {
+        var expectedTypes = configTypes[property];
+        var value = config[property];
+        var valueType = undefined;
 
+        if (value && isElement(value)) valueType = 'element';else valueType = toType(value);
 
-  // ALERT PLUGIN DEFINITION
-  // =======================
+        if (!new RegExp(expectedTypes).test(valueType)) {
+          throw new Error('' + componentName.toUpperCase() + ': ' + ('Option "' + property + '" provided type "' + valueType + '" ') + ('but expected type "' + expectedTypes + '".'));
+        }
+      }
+    }
 
-  function Plugin(option) {
-    return this.each(function () {
-      var $this = $(this)
-      var data  = $this.data('bs.alert')
+  };
 
-      if (!data) $this.data('bs.alert', (data = new Alert(this)))
-      if (typeof option == 'string') data[option].call($this)
-    })
-  }
+  setTransitionEndSupport();
 
-  var old = $.fn.alert
+  return Util;
+})(jQuery);
 
-  $.fn.alert             = Plugin
-  $.fn.alert.Constructor = Alert
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): alert.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
 
+var Alert = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'alert';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.alert';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 150;
+
+  var Selector = {
+    DISMISS: '[data-dismiss="alert"]'
+  };
+
+  var Event = {
+    CLOSE: 'close' + EVENT_KEY,
+    CLOSED: 'closed' + EVENT_KEY,
+    CLICK_DATA_API: 'click' + EVENT_KEY + '' + DATA_API_KEY
+  };
+
+  var ClassName = {
+    ALERT: 'alert',
+    FADE: 'fade',
+    IN: 'in'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Alert = (function () {
+    function Alert(element) {
+      _classCallCheck(this, Alert);
+
+      this._element = element;
+    }
 
-  // ALERT NO CONFLICT
-  // =================
+    _createClass(Alert, [{
+      key: 'close',
 
-  $.fn.alert.noConflict = function () {
-    $.fn.alert = old
-    return this
-  }
+      // public
 
+      value: function close(element) {
+        element = element || this._element;
 
-  // ALERT DATA-API
-  // ==============
+        var rootElement = this._getRootElement(element);
+        var customEvent = this._triggerCloseEvent(rootElement);
 
-  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
+        if (customEvent.isDefaultPrevented()) {
+          return;
+        }
 
-}(jQuery);
+        this._removeElement(rootElement);
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeData(this._element, DATA_KEY);
+        this._element = null;
+      }
+    }, {
+      key: '_getRootElement',
 
-/* ========================================================================
- * Bootstrap: button.js v3.3.4
- * http://getbootstrap.com/javascript/#buttons
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
+      // private
 
+      value: function _getRootElement(element) {
+        var parent = false;
+        var selector = Util.getSelectorFromElement(element);
 
-+function ($) {
-  'use strict';
+        if (selector) {
+          parent = $(selector)[0];
+        }
 
-  // BUTTON PUBLIC CLASS DEFINITION
-  // ==============================
+        if (!parent) {
+          parent = $(element).closest('.' + ClassName.ALERT)[0];
+        }
 
-  var Button = function (element, options) {
-    this.$element  = $(element)
-    this.options   = $.extend({}, Button.DEFAULTS, options)
-    this.isLoading = false
-  }
+        return parent;
+      }
+    }, {
+      key: '_triggerCloseEvent',
+      value: function _triggerCloseEvent(element) {
+        var closeEvent = $.Event(Event.CLOSE);
+        $(element).trigger(closeEvent);
+        return closeEvent;
+      }
+    }, {
+      key: '_removeElement',
+      value: function _removeElement(element) {
+        $(element).removeClass(ClassName.IN);
+
+        if (!Util.supportsTransitionEnd() || !$(element).hasClass(ClassName.FADE)) {
+          this._destroyElement(element);
+          return;
+        }
 
-  Button.VERSION  = '3.3.4'
+        $(element).one(Util.TRANSITION_END, this._destroyElement.bind(this, element)).emulateTransitionEnd(TRANSITION_DURATION);
+      }
+    }, {
+      key: '_destroyElement',
+      value: function _destroyElement(element) {
+        $(element).detach().trigger(Event.CLOSED).remove();
+      }
+    }], [{
+      key: 'VERSION',
 
-  Button.DEFAULTS = {
-    loadingText: 'loading...'
-  }
+      // getters
 
-  Button.prototype.setState = function (state) {
-    var d    = 'disabled'
-    var $el  = this.$element
-    var val  = $el.is('input') ? 'val' : 'html'
-    var data = $el.data()
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: '_jQueryInterface',
 
-    state += 'Text'
+      // static
 
-    if (data.resetText == null) $el.data('resetText', $el[val]())
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var $element = $(this);
+          var data = $element.data(DATA_KEY);
 
-    // push to event loop to allow forms to submit
-    setTimeout($.proxy(function () {
-      $el[val](data[state] == null ? this.options[state] : data[state])
+          if (!data) {
+            data = new Alert(this);
+            $element.data(DATA_KEY, data);
+          }
 
-      if (state == 'loadingText') {
-        this.isLoading = true
-        $el.addClass(d).attr(d, d)
-      } else if (this.isLoading) {
-        this.isLoading = false
-        $el.removeClass(d).removeAttr(d)
+          if (config === 'close') {
+            data[config](this);
+          }
+        });
       }
-    }, this), 0)
-  }
+    }, {
+      key: '_handleDismiss',
+      value: function _handleDismiss(alertInstance) {
+        return function (event) {
+          if (event) {
+            event.preventDefault();
+          }
+
+          alertInstance.close(this);
+        };
+      }
+    }]);
+
+    return Alert;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * 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);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): button.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
 
-  Button.prototype.toggle = function () {
-    var changed = true
-    var $parent = this.$element.closest('[data-toggle="buttons"]')
-
-    if ($parent.length) {
-      var $input = this.$element.find('input')
-      if ($input.prop('type') == 'radio') {
-        if ($input.prop('checked')) changed = false
-        $parent.find('.active').removeClass('active')
-        this.$element.addClass('active')
-      } else if ($input.prop('type') == 'checkbox') {
-        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
-        this.$element.toggleClass('active')
-      }
-      $input.prop('checked', this.$element.hasClass('active'))
-      if (changed) $input.trigger('change')
-    } else {
-      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
-      this.$element.toggleClass('active')
+var Button = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'button';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.button';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 150;
+
+  var ClassName = {
+    ACTIVE: 'active',
+    BUTTON: 'btn',
+    FOCUS: 'focus'
+  };
+
+  var Selector = {
+    DATA_TOGGLE_CARROT: '[data-toggle^="button"]',
+    DATA_TOGGLE: '[data-toggle="buttons"]',
+    INPUT: 'input',
+    ACTIVE: '.active',
+    BUTTON: '.btn'
+  };
+
+  var 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
+   * ------------------------------------------------------------------------
+   */
+
+  var Button = (function () {
+    function Button(element) {
+      _classCallCheck(this, Button);
+
+      this._element = element;
     }
-  }
 
+    _createClass(Button, [{
+      key: 'toggle',
+
+      // public
+
+      value: function toggle() {
+        var triggerChangeEvent = true;
+        var rootElement = $(this._element).closest(Selector.DATA_TOGGLE)[0];
+
+        if (rootElement) {
+          var input = $(this._element).find(Selector.INPUT)[0];
+
+          if (input) {
+            if (input.type === 'radio') {
+              if (input.checked && $(this._element).hasClass(ClassName.ACTIVE)) {
+                triggerChangeEvent = false;
+              } else {
+                var activeElement = $(rootElement).find(Selector.ACTIVE)[0];
+
+                if (activeElement) {
+                  $(activeElement).removeClass(ClassName.ACTIVE);
+                }
+              }
+            }
+
+            if (triggerChangeEvent) {
+              input.checked = !$(this._element).hasClass(ClassName.ACTIVE);
+              $(this._element).trigger('change');
+            }
+          }
+        } else {
+          this._element.setAttribute('aria-pressed', !$(this._element).hasClass(ClassName.ACTIVE));
+        }
 
-  // BUTTON PLUGIN DEFINITION
-  // ========================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.button')
-      var options = typeof option == 'object' && option
+        if (triggerChangeEvent) {
+          $(this._element).toggleClass(ClassName.ACTIVE);
+        }
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeData(this._element, DATA_KEY);
+        this._element = null;
+      }
+    }], [{
+      key: 'VERSION',
 
-      if (!data) $this.data('bs.button', (data = new Button(this, options)))
+      // getters
 
-      if (option == 'toggle') data.toggle()
-      else if (option) data.setState(option)
-    })
-  }
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: '_jQueryInterface',
 
-  var old = $.fn.button
+      // static
 
-  $.fn.button             = Plugin
-  $.fn.button.Constructor = Button
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
 
+          if (!data) {
+            data = new Button(this);
+            $(this).data(DATA_KEY, data);
+          }
 
-  // BUTTON NO CONFLICT
-  // ==================
+          if (config === 'toggle') {
+            data[config]();
+          }
+        });
+      }
+    }]);
 
-  $.fn.button.noConflict = function () {
-    $.fn.button = old
-    return this
-  }
+    return Button;
+  })();
 
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
 
-  // BUTTON DATA-API
-  // ===============
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) {
+    event.preventDefault();
 
-  $(document)
-    .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
-      var $btn = $(e.target)
-      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
-      Plugin.call($btn, 'toggle')
-      if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault()
-    })
-    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
-      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
-    })
+    var button = event.target;
 
-}(jQuery);
+    if (!$(button).hasClass(ClassName.BUTTON)) {
+      button = $(button).closest(Selector.BUTTON);
+    }
 
-/* ========================================================================
- * Bootstrap: carousel.js v3.3.4
- * http://getbootstrap.com/javascript/#carousel
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
+    Button._jQueryInterface.call($(button), 'toggle');
+  }).on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) {
+    var 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);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): carousel.js
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
+ * --------------------------------------------------------------------------
+ */
 
-+function ($) {
-  'use strict';
-
-  // CAROUSEL CLASS DEFINITION
-  // =========================
-
-  var Carousel = function (element, options) {
-    this.$element    = $(element)
-    this.$indicators = this.$element.find('.carousel-indicators')
-    this.options     = options
-    this.paused      = null
-    this.sliding     = null
-    this.interval    = null
-    this.$active     = null
-    this.$items      = null
-
-    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
-
-    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
-      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
-      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
-  }
+var Carousel = (function ($) {
 
-  Carousel.VERSION  = '3.3.4'
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
 
-  Carousel.TRANSITION_DURATION = 600
+  var NAME = 'carousel';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.carousel';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 600;
 
-  Carousel.DEFAULTS = {
+  var Default = {
     interval: 5000,
+    keyboard: true,
+    slide: false,
     pause: 'hover',
-    wrap: true,
-    keyboard: true
-  }
-
-  Carousel.prototype.keydown = function (e) {
-    if (/input|textarea/i.test(e.target.tagName)) return
-    switch (e.which) {
-      case 37: this.prev(); break
-      case 39: this.next(); break
-      default: return
+    wrap: true
+  };
+
+  var DefaultType = {
+    interval: '(number|boolean)',
+    keyboard: 'boolean',
+    slide: '(boolean|string)',
+    pause: '(string|boolean)',
+    wrap: 'boolean'
+  };
+
+  var Direction = {
+    NEXT: 'next',
+    PREVIOUS: 'prev'
+  };
+
+  var 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
+  };
+
+  var ClassName = {
+    CAROUSEL: 'carousel',
+    ACTIVE: 'active',
+    SLIDE: 'slide',
+    RIGHT: 'right',
+    LEFT: 'left',
+    ITEM: 'carousel-item'
+  };
+
+  var Selector = {
+    ACTIVE: '.active',
+    ACTIVE_ITEM: '.active.carousel-item',
+    ITEM: '.carousel-item',
+    NEXT_PREV: '.next, .prev',
+    INDICATORS: '.carousel-indicators',
+    DATA_SLIDE: '[data-slide], [data-slide-to]',
+    DATA_RIDE: '[data-ride="carousel"]'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Carousel = (function () {
+    function Carousel(element, config) {
+      _classCallCheck(this, Carousel);
+
+      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();
     }
 
-    e.preventDefault()
-  }
+    _createClass(Carousel, [{
+      key: 'next',
 
-  Carousel.prototype.cycle = function (e) {
-    e || (this.paused = false)
+      // public
 
-    this.interval && clearInterval(this.interval)
+      value: function next() {
+        if (!this._isSliding) {
+          this._slide(Direction.NEXT);
+        }
+      }
+    }, {
+      key: 'prev',
+      value: function prev() {
+        if (!this._isSliding) {
+          this._slide(Direction.PREVIOUS);
+        }
+      }
+    }, {
+      key: 'pause',
+      value: function pause(event) {
+        if (!event) {
+          this._isPaused = true;
+        }
 
-    this.options.interval
-      && !this.paused
-      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
+        if ($(this._element).find(Selector.NEXT_PREV)[0] && Util.supportsTransitionEnd()) {
+          Util.triggerTransitionEnd(this._element);
+          this.cycle(true);
+        }
 
-    return this
-  }
+        clearInterval(this._interval);
+        this._interval = null;
+      }
+    }, {
+      key: 'cycle',
+      value: function cycle(event) {
+        if (!event) {
+          this._isPaused = false;
+        }
 
-  Carousel.prototype.getItemIndex = function (item) {
-    this.$items = item.parent().children('.item')
-    return this.$items.index(item || this.$active)
-  }
+        if (this._interval) {
+          clearInterval(this._interval);
+          this._interval = null;
+        }
 
-  Carousel.prototype.getItemForDirection = function (direction, active) {
-    var activeIndex = this.getItemIndex(active)
-    var willWrap = (direction == 'prev' && activeIndex === 0)
-                || (direction == 'next' && activeIndex == (this.$items.length - 1))
-    if (willWrap && !this.options.wrap) return active
-    var delta = direction == 'prev' ? -1 : 1
-    var itemIndex = (activeIndex + delta) % this.$items.length
-    return this.$items.eq(itemIndex)
-  }
+        if (this._config.interval && !this._isPaused) {
+          this._interval = setInterval($.proxy(this.next, this), this._config.interval);
+        }
+      }
+    }, {
+      key: 'to',
+      value: function to(index) {
+        var _this2 = this;
 
-  Carousel.prototype.to = function (pos) {
-    var that        = this
-    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
+        this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
 
-    if (pos > (this.$items.length - 1) || pos < 0) return
+        var activeIndex = this._getItemIndex(this._activeElement);
 
-    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
-    if (activeIndex == pos) return this.pause().cycle()
+        if (index > this._items.length - 1 || index < 0) {
+          return;
+        }
 
-    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
-  }
+        if (this._isSliding) {
+          $(this._element).one(Event.SLID, function () {
+            return _this2.to(index);
+          });
+          return;
+        }
 
-  Carousel.prototype.pause = function (e) {
-    e || (this.paused = true)
+        if (activeIndex == index) {
+          this.pause();
+          this.cycle();
+          return;
+        }
 
-    if (this.$element.find('.next, .prev').length && $.support.transition) {
-      this.$element.trigger($.support.transition.end)
-      this.cycle(true)
-    }
+        var direction = index > activeIndex ? Direction.NEXT : Direction.PREVIOUS;
 
-    this.interval = clearInterval(this.interval)
+        this._slide(direction, this._items[index]);
+      }
+    }, {
+      key: 'dispose',
+      value: function 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;
+      }
+    }, {
+      key: '_getConfig',
 
-    return this
-  }
+      // private
 
-  Carousel.prototype.next = function () {
-    if (this.sliding) return
-    return this.slide('next')
-  }
+      value: function _getConfig(config) {
+        config = $.extend({}, Default, config);
+        Util.typeCheckConfig(NAME, config, DefaultType);
+        return config;
+      }
+    }, {
+      key: '_addEventListeners',
+      value: function _addEventListeners() {
+        if (this._config.keyboard) {
+          $(this._element).on(Event.KEYDOWN, $.proxy(this._keydown, this));
+        }
 
-  Carousel.prototype.prev = function () {
-    if (this.sliding) return
-    return this.slide('prev')
-  }
+        if (this._config.pause == 'hover' && !('ontouchstart' in document.documentElement)) {
+          $(this._element).on(Event.MOUSEENTER, $.proxy(this.pause, this)).on(Event.MOUSELEAVE, $.proxy(this.cycle, this));
+        }
+      }
+    }, {
+      key: '_keydown',
+      value: function _keydown(event) {
+        event.preventDefault();
+
+        if (/input|textarea/i.test(event.target.tagName)) return;
+
+        switch (event.which) {
+          case 37:
+            this.prev();break;
+          case 39:
+            this.next();break;
+          default:
+            return;
+        }
+      }
+    }, {
+      key: '_getItemIndex',
+      value: function _getItemIndex(element) {
+        this._items = $.makeArray($(element).parent().find(Selector.ITEM));
+        return this._items.indexOf(element);
+      }
+    }, {
+      key: '_getItemByDirection',
+      value: function _getItemByDirection(direction, activeElement) {
+        var isNextDirection = direction === Direction.NEXT;
+        var isPrevDirection = direction === Direction.PREVIOUS;
+        var activeIndex = this._getItemIndex(activeElement);
+        var lastItemIndex = this._items.length - 1;
+        var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex == lastItemIndex;
+
+        if (isGoingToWrap && !this._config.wrap) {
+          return activeElement;
+        }
 
-  Carousel.prototype.slide = function (type, next) {
-    var $active   = this.$element.find('.item.active')
-    var $next     = next || this.getItemForDirection(type, $active)
-    var isCycling = this.interval
-    var direction = type == 'next' ? 'left' : 'right'
-    var that      = this
+        var delta = direction == Direction.PREVIOUS ? -1 : 1;
+        var itemIndex = (activeIndex + delta) % this._items.length;
 
-    if ($next.hasClass('active')) return (this.sliding = false)
+        return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
+      }
+    }, {
+      key: '_triggerSlideEvent',
+      value: function _triggerSlideEvent(relatedTarget, directionalClassname) {
+        var slideEvent = $.Event(Event.SLIDE, {
+          relatedTarget: relatedTarget,
+          direction: directionalClassname
+        });
 
-    var relatedTarget = $next[0]
-    var slideEvent = $.Event('slide.bs.carousel', {
-      relatedTarget: relatedTarget,
-      direction: direction
-    })
-    this.$element.trigger(slideEvent)
-    if (slideEvent.isDefaultPrevented()) return
+        $(this._element).trigger(slideEvent);
 
-    this.sliding = true
+        return slideEvent;
+      }
+    }, {
+      key: '_setActiveIndicatorElement',
+      value: function _setActiveIndicatorElement(element) {
+        if (this._indicatorsElement) {
+          $(this._indicatorsElement).find(Selector.ACTIVE).removeClass(ClassName.ACTIVE);
 
-    isCycling && this.pause()
+          var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
 
-    if (this.$indicators.length) {
-      this.$indicators.find('.active').removeClass('active')
-      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
-      $nextIndicator && $nextIndicator.addClass('active')
-    }
+          if (nextIndicator) {
+            $(nextIndicator).addClass(ClassName.ACTIVE);
+          }
+        }
+      }
+    }, {
+      key: '_slide',
+      value: function _slide(direction, element) {
+        var _this3 = this;
 
-    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
-    if ($.support.transition && this.$element.hasClass('slide')) {
-      $next.addClass(type)
-      $next[0].offsetWidth // force reflow
-      $active.addClass(direction)
-      $next.addClass(direction)
-      $active
-        .one('bsTransitionEnd', function () {
-          $next.removeClass([type, direction].join(' ')).addClass('active')
-          $active.removeClass(['active', direction].join(' '))
-          that.sliding = false
-          setTimeout(function () {
-            that.$element.trigger(slidEvent)
-          }, 0)
-        })
-        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
-    } else {
-      $active.removeClass('active')
-      $next.addClass('active')
-      this.sliding = false
-      this.$element.trigger(slidEvent)
-    }
+        var activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
+        var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
 
-    isCycling && this.cycle()
+        var isCycling = !!this._interval;
 
-    return this
-  }
+        var directionalClassName = direction == Direction.NEXT ? ClassName.LEFT : ClassName.RIGHT;
+
+        if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {
+          this._isSliding = false;
+          return;
+        }
 
+        var slideEvent = this._triggerSlideEvent(nextElement, directionalClassName);
+        if (slideEvent.isDefaultPrevented()) {
+          return;
+        }
 
-  // CAROUSEL PLUGIN DEFINITION
-  // ==========================
+        if (!activeElement || !nextElement) {
+          // some weirdness is happening, so we bail
+          return;
+        }
 
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.carousel')
-      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
-      var action  = typeof option == 'string' ? option : options.slide
+        this._isSliding = true;
 
-      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
-      if (typeof option == 'number') data.to(option)
-      else if (action) data[action]()
-      else if (options.interval) data.pause().cycle()
-    })
-  }
+        if (isCycling) {
+          this.pause();
+        }
 
-  var old = $.fn.carousel
+        this._setActiveIndicatorElement(nextElement);
 
-  $.fn.carousel             = Plugin
-  $.fn.carousel.Constructor = Carousel
+        var slidEvent = $.Event(Event.SLID, {
+          relatedTarget: nextElement,
+          direction: directionalClassName
+        });
 
+        if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.SLIDE)) {
 
-  // CAROUSEL NO CONFLICT
-  // ====================
+          $(nextElement).addClass(direction);
 
-  $.fn.carousel.noConflict = function () {
-    $.fn.carousel = old
-    return this
-  }
+          Util.reflow(nextElement);
 
+          $(activeElement).addClass(directionalClassName);
+          $(nextElement).addClass(directionalClassName);
 
-  // CAROUSEL DATA-API
-  // =================
+          $(activeElement).one(Util.TRANSITION_END, function () {
+            $(nextElement).removeClass(directionalClassName).removeClass(direction);
 
-  var clickHandler = function (e) {
-    var href
-    var $this   = $(this)
-    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
-    if (!$target.hasClass('carousel')) return
-    var options = $.extend({}, $target.data(), $this.data())
-    var slideIndex = $this.attr('data-slide-to')
-    if (slideIndex) options.interval = false
+            $(nextElement).addClass(ClassName.ACTIVE);
 
-    Plugin.call($target, options)
+            $(activeElement).removeClass(ClassName.ACTIVE).removeClass(direction).removeClass(directionalClassName);
 
-    if (slideIndex) {
-      $target.data('bs.carousel').to(slideIndex)
-    }
+            _this3._isSliding = false;
 
-    e.preventDefault()
-  }
+            setTimeout(function () {
+              return $(_this3._element).trigger(slidEvent);
+            }, 0);
+          }).emulateTransitionEnd(TRANSITION_DURATION);
+        } else {
+          $(activeElement).removeClass(ClassName.ACTIVE);
+          $(nextElement).addClass(ClassName.ACTIVE);
 
-  $(document)
-    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
-    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
+          this._isSliding = false;
+          $(this._element).trigger(slidEvent);
+        }
 
-  $(window).on('load', function () {
-    $('[data-ride="carousel"]').each(function () {
-      var $carousel = $(this)
-      Plugin.call($carousel, $carousel.data())
-    })
-  })
+        if (isCycling) {
+          this.cycle();
+        }
+      }
+    }], [{
+      key: 'VERSION',
 
-}(jQuery);
+      // getters
 
-/* ========================================================================
- * Bootstrap: collapse.js v3.3.4
- * http://getbootstrap.com/javascript/#collapse
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+          var _config = $.extend({}, Default, $(this).data());
+
+          if (typeof config === 'object') {
+            $.extend(_config, config);
+          }
+
+          var 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 (action) {
+            data[action]();
+          } else if (_config.interval) {
+            data.pause();
+            data.cycle();
+          }
+        });
+      }
+    }, {
+      key: '_dataApiClickHandler',
+      value: function _dataApiClickHandler(event) {
+        var selector = Util.getSelectorFromElement(this);
 
+        if (!selector) {
+          return;
+        }
 
-+function ($) {
-  'use strict';
-
-  // COLLAPSE PUBLIC CLASS DEFINITION
-  // ================================
-
-  var Collapse = function (element, options) {
-    this.$element      = $(element)
-    this.options       = $.extend({}, Collapse.DEFAULTS, options)
-    this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
-                           '[data-toggle="collapse"][data-target="#' + element.id + '"]')
-    this.transitioning = null
-
-    if (this.options.parent) {
-      this.$parent = this.getParent()
-    } else {
-      this.addAriaAndCollapsedClass(this.$element, this.$trigger)
-    }
+        var target = $(selector)[0];
 
-    if (this.options.toggle) this.toggle()
-  }
+        if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {
+          return;
+        }
 
-  Collapse.VERSION  = '3.3.4'
+        var config = $.extend({}, $(target).data(), $(this).data());
 
-  Collapse.TRANSITION_DURATION = 350
+        var slideIndex = this.getAttribute('data-slide-to');
+        if (slideIndex) {
+          config.interval = false;
+        }
 
-  Collapse.DEFAULTS = {
-    toggle: true
-  }
+        Carousel._jQueryInterface.call($(target), config);
 
-  Collapse.prototype.dimension = function () {
-    var hasWidth = this.$element.hasClass('width')
-    return hasWidth ? 'width' : 'height'
-  }
+        if (slideIndex) {
+          $(target).data(DATA_KEY).to(slideIndex);
+        }
 
-  Collapse.prototype.show = function () {
-    if (this.transitioning || this.$element.hasClass('in')) return
+        event.preventDefault();
+      }
+    }]);
+
+    return Carousel;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler);
+
+  $(window).on(Event.LOAD_DATA_API, function () {
+    $(Selector.DATA_RIDE).each(function () {
+      var $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);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): collapse.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
 
-    var activesData
-    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
+var Collapse = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'collapse';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.collapse';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 600;
+
+  var Default = {
+    toggle: true,
+    parent: ''
+  };
+
+  var DefaultType = {
+    toggle: 'boolean',
+    parent: 'string'
+  };
+
+  var 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
+  };
+
+  var ClassName = {
+    IN: 'in',
+    COLLAPSE: 'collapse',
+    COLLAPSING: 'collapsing',
+    COLLAPSED: 'collapsed'
+  };
+
+  var Dimension = {
+    WIDTH: 'width',
+    HEIGHT: 'height'
+  };
+
+  var Selector = {
+    ACTIVES: '.panel > .in, .panel > .collapsing',
+    DATA_TOGGLE: '[data-toggle="collapse"]'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Collapse = (function () {
+    function Collapse(element, config) {
+      _classCallCheck(this, Collapse);
+
+      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);
+      }
 
-    if (actives && actives.length) {
-      activesData = actives.data('bs.collapse')
-      if (activesData && activesData.transitioning) return
+      if (this._config.toggle) {
+        this.toggle();
+      }
     }
 
-    var startEvent = $.Event('show.bs.collapse')
-    this.$element.trigger(startEvent)
-    if (startEvent.isDefaultPrevented()) return
+    _createClass(Collapse, [{
+      key: 'toggle',
 
-    if (actives && actives.length) {
-      Plugin.call(actives, 'hide')
-      activesData || actives.data('bs.collapse', null)
-    }
+      // public
 
-    var dimension = this.dimension()
+      value: function toggle() {
+        if ($(this._element).hasClass(ClassName.IN)) {
+          this.hide();
+        } else {
+          this.show();
+        }
+      }
+    }, {
+      key: 'show',
+      value: function show() {
+        var _this4 = this;
 
-    this.$element
-      .removeClass('collapse')
-      .addClass('collapsing')[dimension](0)
-      .attr('aria-expanded', true)
+        if (this._isTransitioning || $(this._element).hasClass(ClassName.IN)) {
+          return;
+        }
 
-    this.$trigger
-      .removeClass('collapsed')
-      .attr('aria-expanded', true)
+        var actives = undefined;
+        var activesData = undefined;
 
-    this.transitioning = 1
+        if (this._parent) {
+          actives = $.makeArray($(Selector.ACTIVES));
+          if (!actives.length) {
+            actives = null;
+          }
+        }
 
-    var complete = function () {
-      this.$element
-        .removeClass('collapsing')
-        .addClass('collapse in')[dimension]('')
-      this.transitioning = 0
-      this.$element
-        .trigger('shown.bs.collapse')
-    }
+        if (actives) {
+          activesData = $(actives).data(DATA_KEY);
+          if (activesData && activesData._isTransitioning) {
+            return;
+          }
+        }
 
-    if (!$.support.transition) return complete.call(this)
+        var startEvent = $.Event(Event.SHOW);
+        $(this._element).trigger(startEvent);
+        if (startEvent.isDefaultPrevented()) {
+          return;
+        }
 
-    var scrollSize = $.camelCase(['scroll', dimension].join('-'))
+        if (actives) {
+          Collapse._jQueryInterface.call($(actives), 'hide');
+          if (!activesData) {
+            $(actives).data(DATA_KEY, null);
+          }
+        }
 
-    this.$element
-      .one('bsTransitionEnd', $.proxy(complete, this))
-      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
-  }
+        var dimension = this._getDimension();
 
-  Collapse.prototype.hide = function () {
-    if (this.transitioning || !this.$element.hasClass('in')) return
+        $(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING);
 
-    var startEvent = $.Event('hide.bs.collapse')
-    this.$element.trigger(startEvent)
-    if (startEvent.isDefaultPrevented()) return
+        this._element.style[dimension] = 0;
+        this._element.setAttribute('aria-expanded', true);
 
-    var dimension = this.dimension()
+        if (this._triggerArray.length) {
+          $(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true);
+        }
 
-    this.$element[dimension](this.$element[dimension]())[0].offsetHeight
+        this.setTransitioning(true);
 
-    this.$element
-      .addClass('collapsing')
-      .removeClass('collapse in')
-      .attr('aria-expanded', false)
+        var complete = function complete() {
+          $(_this4._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.IN);
 
-    this.$trigger
-      .addClass('collapsed')
-      .attr('aria-expanded', false)
+          _this4._element.style[dimension] = '';
 
-    this.transitioning = 1
+          _this4.setTransitioning(false);
 
-    var complete = function () {
-      this.transitioning = 0
-      this.$element
-        .removeClass('collapsing')
-        .addClass('collapse')
-        .trigger('hidden.bs.collapse')
-    }
+          $(_this4._element).trigger(Event.SHOWN);
+        };
 
-    if (!$.support.transition) return complete.call(this)
+        if (!Util.supportsTransitionEnd()) {
+          complete();
+          return;
+        }
 
-    this.$element
-      [dimension](0)
-      .one('bsTransitionEnd', $.proxy(complete, this))
-      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
-  }
+        var scrollSize = 'scroll' + (dimension[0].toUpperCase() + dimension.slice(1));
 
-  Collapse.prototype.toggle = function () {
-    this[this.$element.hasClass('in') ? 'hide' : 'show']()
-  }
+        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
 
-  Collapse.prototype.getParent = function () {
-    return $(this.options.parent)
-      .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
-      .each($.proxy(function (i, element) {
-        var $element = $(element)
-        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
-      }, this))
-      .end()
-  }
+        this._element.style[dimension] = this._element[scrollSize] + 'px';
+      }
+    }, {
+      key: 'hide',
+      value: function hide() {
+        var _this5 = this;
 
-  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
-    var isOpen = $element.hasClass('in')
+        if (this._isTransitioning || !$(this._element).hasClass(ClassName.IN)) {
+          return;
+        }
 
-    $element.attr('aria-expanded', isOpen)
-    $trigger
-      .toggleClass('collapsed', !isOpen)
-      .attr('aria-expanded', isOpen)
-  }
+        var startEvent = $.Event(Event.HIDE);
+        $(this._element).trigger(startEvent);
+        if (startEvent.isDefaultPrevented()) {
+          return;
+        }
 
-  function getTargetFromTrigger($trigger) {
-    var href
-    var target = $trigger.attr('data-target')
-      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
+        var dimension = this._getDimension();
+        var offsetDimension = dimension === Dimension.WIDTH ? 'offsetWidth' : 'offsetHeight';
 
-    return $(target)
-  }
+        this._element.style[dimension] = this._element[offsetDimension] + 'px';
 
+        Util.reflow(this._element);
 
-  // COLLAPSE PLUGIN DEFINITION
-  // ==========================
+        $(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.IN);
 
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.collapse')
-      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
+        this._element.setAttribute('aria-expanded', false);
 
-      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
-      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
+        if (this._triggerArray.length) {
+          $(this._triggerArray).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);
+        }
 
-  var old = $.fn.collapse
+        this.setTransitioning(true);
 
-  $.fn.collapse             = Plugin
-  $.fn.collapse.Constructor = Collapse
+        var complete = function complete() {
+          _this5.setTransitioning(false);
+          $(_this5._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN);
+        };
 
+        this._element.style[dimension] = 0;
 
-  // COLLAPSE NO CONFLICT
-  // ====================
+        if (!Util.supportsTransitionEnd()) {
+          return complete();
+        }
 
-  $.fn.collapse.noConflict = function () {
-    $.fn.collapse = old
-    return this
-  }
+        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+      }
+    }, {
+      key: 'setTransitioning',
+      value: function setTransitioning(isTransitioning) {
+        this._isTransitioning = isTransitioning;
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeData(this._element, DATA_KEY);
+
+        this._config = null;
+        this._parent = null;
+        this._element = null;
+        this._triggerArray = null;
+        this._isTransitioning = null;
+      }
+    }, {
+      key: '_getConfig',
 
+      // private
 
-  // COLLAPSE DATA-API
-  // =================
+      value: function _getConfig(config) {
+        config = $.extend({}, Default, config);
+        config.toggle = !!config.toggle; // coerce string values
+        Util.typeCheckConfig(NAME, config, DefaultType);
+        return config;
+      }
+    }, {
+      key: '_getDimension',
+      value: function _getDimension() {
+        var hasWidth = $(this._element).hasClass(Dimension.WIDTH);
+        return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;
+      }
+    }, {
+      key: '_getParent',
+      value: function _getParent() {
+        var _this6 = this;
 
-  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
-    var $this   = $(this)
+        var parent = $(this._config.parent)[0];
+        var selector = '[data-toggle="collapse"][data-parent="' + this._config.parent + '"]';
 
-    if (!$this.attr('data-target')) e.preventDefault()
+        $(parent).find(selector).each(function (i, element) {
+          _this6._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
+        });
 
-    var $target = getTargetFromTrigger($this)
-    var data    = $target.data('bs.collapse')
-    var option  = data ? 'toggle' : $this.data()
+        return parent;
+      }
+    }, {
+      key: '_addAriaAndCollapsedClass',
+      value: function _addAriaAndCollapsedClass(element, triggerArray) {
+        if (element) {
+          var isOpen = $(element).hasClass(ClassName.IN);
+          element.setAttribute('aria-expanded', isOpen);
+
+          if (triggerArray.length) {
+            $(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
+          }
+        }
+      }
+    }], [{
+      key: 'VERSION',
 
-    Plugin.call($target, option)
-  })
+      // getters
 
-}(jQuery);
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: '_getTargetFromElement',
 
-/* ========================================================================
- * Bootstrap: dropdown.js v3.3.4
- * http://getbootstrap.com/javascript/#dropdowns
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
+      // static
 
+      value: function _getTargetFromElement(element) {
+        var selector = Util.getSelectorFromElement(element);
+        return selector ? $(selector)[0] : null;
+      }
+    }, {
+      key: '_jQueryInterface',
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var $this = $(this);
+          var data = $this.data(DATA_KEY);
+          var _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') {
+            data[config]();
+          }
+        });
+      }
+    }]);
 
-+function ($) {
-  'use strict';
+    return Collapse;
+  })();
 
-  // DROPDOWN CLASS DEFINITION
-  // =========================
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
 
-  var backdrop = '.dropdown-backdrop'
-  var toggle   = '[data-toggle="dropdown"]'
-  var Dropdown = function (element) {
-    $(element).on('click.bs.dropdown', this.toggle)
-  }
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+    event.preventDefault();
+
+    var target = Collapse._getTargetFromElement(this);
+
+    var data = $(target).data(DATA_KEY);
+    var config = data ? 'toggle' : $(this).data();
+
+    Collapse._jQueryInterface.call($(target), config);
+  });
 
-  Dropdown.VERSION = '3.3.4'
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
 
-  function getParent($this) {
-    var selector = $this.attr('data-target')
+  $.fn[NAME] = Collapse._jQueryInterface;
+  $.fn[NAME].Constructor = Collapse;
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Collapse._jQueryInterface;
+  };
 
-    if (!selector) {
-      selector = $this.attr('href')
-      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+  return Collapse;
+})(jQuery);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): dropdown.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Dropdown = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'dropdown';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.dropdown';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+
+  var 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,
+    KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + '' + DATA_API_KEY
+  };
+
+  var ClassName = {
+    BACKDROP: 'dropdown-backdrop',
+    DISABLED: 'disabled',
+    OPEN: 'open'
+  };
+
+  var 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
+   * ------------------------------------------------------------------------
+   */
+
+  var Dropdown = (function () {
+    function Dropdown(element) {
+      _classCallCheck(this, Dropdown);
+
+      this._element = element;
+
+      this._addEventListeners();
     }
 
-    var $parent = selector && $(selector)
+    _createClass(Dropdown, [{
+      key: 'toggle',
 
-    return $parent && $parent.length ? $parent : $this.parent()
-  }
+      // public
 
-  function clearMenus(e) {
-    if (e && e.which === 3) return
-    $(backdrop).remove()
-    $(toggle).each(function () {
-      var $this         = $(this)
-      var $parent       = getParent($this)
-      var relatedTarget = { relatedTarget: this }
+      value: function toggle() {
+        if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+          return;
+        }
 
-      if (!$parent.hasClass('open')) return
+        var parent = Dropdown._getParentFromElement(this);
+        var isActive = $(parent).hasClass(ClassName.OPEN);
 
-      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
+        Dropdown._clearMenus();
 
-      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
+        if (isActive) {
+          return false;
+        }
 
-      if (e.isDefaultPrevented()) return
+        if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) {
 
-      $this.attr('aria-expanded', 'false')
-      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
-    })
-  }
+          // if mobile we use a backdrop because click events don't delegate
+          var dropdown = document.createElement('div');
+          dropdown.className = ClassName.BACKDROP;
+          $(dropdown).insertBefore(this);
+          $(dropdown).on('click', Dropdown._clearMenus);
+        }
+
+        var relatedTarget = { relatedTarget: this };
+        var showEvent = $.Event(Event.SHOW, relatedTarget);
 
-  Dropdown.prototype.toggle = function (e) {
-    var $this = $(this)
+        $(parent).trigger(showEvent);
 
-    if ($this.is('.disabled, :disabled')) return
+        if (showEvent.isDefaultPrevented()) {
+          return;
+        }
 
-    var $parent  = getParent($this)
-    var isActive = $parent.hasClass('open')
+        this.focus();
+        this.setAttribute('aria-expanded', 'true');
 
-    clearMenus()
+        $(parent).toggleClass(ClassName.OPEN);
+        $(parent).trigger(Event.SHOWN, relatedTarget);
 
-    if (!isActive) {
-      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
-        // if mobile we use a backdrop because click events don't delegate
-        $(document.createElement('div'))
-          .addClass('dropdown-backdrop')
-          .insertAfter($(this))
-          .on('click', clearMenus)
+        return false;
       }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeData(this._element, DATA_KEY);
+        $(this._element).off(EVENT_KEY);
+        this._element = null;
+      }
+    }, {
+      key: '_addEventListeners',
 
-      var relatedTarget = { relatedTarget: this }
-      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
-
-      if (e.isDefaultPrevented()) return
+      // private
 
-      $this
-        .trigger('focus')
-        .attr('aria-expanded', 'true')
+      value: function _addEventListeners() {
+        $(this._element).on(Event.CLICK, this.toggle);
+      }
+    }], [{
+      key: 'VERSION',
 
-      $parent
-        .toggleClass('open')
-        .trigger('shown.bs.dropdown', relatedTarget)
-    }
+      // getters
 
-    return false
-  }
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: '_jQueryInterface',
 
-  Dropdown.prototype.keydown = function (e) {
-    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
+      // static
 
-    var $this = $(this)
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
 
-    e.preventDefault()
-    e.stopPropagation()
+          if (!data) {
+            $(this).data(DATA_KEY, data = new Dropdown(this));
+          }
 
-    if ($this.is('.disabled, :disabled')) return
+          if (typeof config === 'string') {
+            data[config].call(this);
+          }
+        });
+      }
+    }, {
+      key: '_clearMenus',
+      value: function _clearMenus(event) {
+        if (event && event.which === 3) {
+          return;
+        }
 
-    var $parent  = getParent($this)
-    var isActive = $parent.hasClass('open')
+        var backdrop = $(Selector.BACKDROP)[0];
+        if (backdrop) {
+          backdrop.parentNode.removeChild(backdrop);
+        }
 
-    if (!isActive && e.which != 27 || isActive && e.which == 27) {
-      if (e.which == 27) $parent.find(toggle).trigger('focus')
-      return $this.trigger('click')
-    }
+        var toggles = $.makeArray($(Selector.DATA_TOGGLE));
 
-    var desc = ' li:not(.disabled):visible a'
-    var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
+        for (var i = 0; i < toggles.length; i++) {
+          var _parent = Dropdown._getParentFromElement(toggles[i]);
+          var relatedTarget = { relatedTarget: toggles[i] };
 
-    if (!$items.length) return
+          if (!$(_parent).hasClass(ClassName.OPEN)) {
+            continue;
+          }
 
-    var index = $items.index(e.target)
+          if (event && event.type === 'click' && /input|textarea/i.test(event.target.tagName) && $.contains(_parent, event.target)) {
+            continue;
+          }
 
-    if (e.which == 38 && index > 0)                 index--         // up
-    if (e.which == 40 && index < $items.length - 1) index++         // down
-    if (!~index)                                    index = 0
+          var hideEvent = $.Event(Event.HIDE, relatedTarget);
+          $(_parent).trigger(hideEvent);
+          if (hideEvent.isDefaultPrevented()) {
+            continue;
+          }
 
-    $items.eq(index).trigger('focus')
-  }
+          toggles[i].setAttribute('aria-expanded', 'false');
 
+          $(_parent).removeClass(ClassName.OPEN).trigger(Event.HIDDEN, relatedTarget);
+        }
+      }
+    }, {
+      key: '_getParentFromElement',
+      value: function _getParentFromElement(element) {
+        var parent = undefined;
+        var selector = Util.getSelectorFromElement(element);
+
+        if (selector) {
+          parent = $(selector)[0];
+        }
 
-  // DROPDOWN PLUGIN DEFINITION
-  // ==========================
+        return parent || element.parentNode;
+      }
+    }, {
+      key: '_dataApiKeydownHandler',
+      value: function _dataApiKeydownHandler(event) {
+        if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) {
+          return;
+        }
 
-  function Plugin(option) {
-    return this.each(function () {
-      var $this = $(this)
-      var data  = $this.data('bs.dropdown')
+        event.preventDefault();
+        event.stopPropagation();
 
-      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
-      if (typeof option == 'string') data[option].call($this)
-    })
-  }
+        if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+          return;
+        }
 
-  var old = $.fn.dropdown
+        var parent = Dropdown._getParentFromElement(this);
+        var isActive = $(parent).hasClass(ClassName.OPEN);
 
-  $.fn.dropdown             = Plugin
-  $.fn.dropdown.Constructor = Dropdown
+        if (!isActive && event.which !== 27 || isActive && event.which === 27) {
 
+          if (event.which === 27) {
+            var toggle = $(parent).find(Selector.DATA_TOGGLE)[0];
+            $(toggle).trigger('focus');
+          }
 
-  // DROPDOWN NO CONFLICT
-  // ====================
+          $(this).trigger('click');
+          return;
+        }
 
-  $.fn.dropdown.noConflict = function () {
-    $.fn.dropdown = old
-    return this
-  }
+        var items = $.makeArray($(Selector.VISIBLE_ITEMS));
 
+        items = items.filter(function (item) {
+          return item.offsetWidth || item.offsetHeight;
+        });
 
-  // APPLY TO STANDARD DROPDOWN ELEMENTS
-  // ===================================
+        if (!items.length) {
+          return;
+        }
 
-  $(document)
-    .on('click.bs.dropdown.data-api', clearMenus)
-    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
-    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
-    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
-    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
+        var index = items.indexOf(event.target);
 
-}(jQuery);
+        if (event.which === 38 && index > 0) index--; // up
+        if (event.which === 40 && index < items.length - 1) index++; // down
+        if (! ~index) index = 0;
 
-/* ========================================================================
- * Bootstrap: modal.js v3.3.4
- * http://getbootstrap.com/javascript/#modals
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
+        items[index].focus();
+      }
+    }]);
+
+    return Dropdown;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * 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, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (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);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): modal.js
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
+ * --------------------------------------------------------------------------
+ */
 
-+function ($) {
-  'use strict';
-
-  // MODAL CLASS DEFINITION
-  // ======================
-
-  var Modal = function (element, options) {
-    this.options             = options
-    this.$body               = $(document.body)
-    this.$element            = $(element)
-    this.$dialog             = this.$element.find('.modal-dialog')
-    this.$backdrop           = null
-    this.isShown             = null
-    this.originalBodyPad     = null
-    this.scrollbarWidth      = 0
-    this.ignoreBackdropClick = false
-
-    if (this.options.remote) {
-      this.$element
-        .find('.modal-content')
-        .load(this.options.remote, $.proxy(function () {
-          this.$element.trigger('loaded.bs.modal')
-        }, this))
-    }
-  }
+var Modal = (function ($) {
 
-  Modal.VERSION  = '3.3.4'
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
 
-  Modal.TRANSITION_DURATION = 300
-  Modal.BACKDROP_TRANSITION_DURATION = 150
+  var NAME = 'modal';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.modal';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 300;
+  var BACKDROP_TRANSITION_DURATION = 150;
 
-  Modal.DEFAULTS = {
+  var Default = {
     backdrop: true,
     keyboard: true,
+    focus: true,
     show: true
-  }
-
-  Modal.prototype.toggle = function (_relatedTarget) {
-    return this.isShown ? this.hide() : this.show(_relatedTarget)
-  }
+  };
+
+  var DefaultType = {
+    backdrop: '(boolean|string)',
+    keyboard: 'boolean',
+    focus: 'boolean',
+    show: 'boolean'
+  };
+
+  var 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
+  };
+
+  var ClassName = {
+    BACKDROP: 'modal-backdrop',
+    OPEN: 'modal-open',
+    FADE: 'fade',
+    IN: 'in'
+  };
+
+  var Selector = {
+    DIALOG: '.modal-dialog',
+    DATA_TOGGLE: '[data-toggle="modal"]',
+    DATA_DISMISS: '[data-dismiss="modal"]',
+    SCROLLBAR_MEASURER: 'modal-scrollbar-measure'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Modal = (function () {
+    function Modal(element, config) {
+      _classCallCheck(this, Modal);
+
+      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._originalBodyPadding = 0;
+      this._scrollbarWidth = 0;
+    }
 
-  Modal.prototype.show = function (_relatedTarget) {
-    var that = this
-    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
+    _createClass(Modal, [{
+      key: 'toggle',
 
-    this.$element.trigger(e)
+      // public
 
-    if (this.isShown || e.isDefaultPrevented()) return
+      value: function toggle(relatedTarget) {
+        return this._isShown ? this.hide() : this.show(relatedTarget);
+      }
+    }, {
+      key: 'show',
+      value: function show(relatedTarget) {
+        var _this7 = this;
 
-    this.isShown = true
+        var showEvent = $.Event(Event.SHOW, {
+          relatedTarget: relatedTarget
+        });
 
-    this.checkScrollbar()
-    this.setScrollbar()
-    this.$body.addClass('modal-open')
+        $(this._element).trigger(showEvent);
 
-    this.escape()
-    this.resize()
+        if (this._isShown || showEvent.isDefaultPrevented()) {
+          return;
+        }
 
-    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
+        this._isShown = true;
 
-    this.$dialog.on('mousedown.dismiss.bs.modal', function () {
-      that.$element.one('mouseup.dismiss.bs.modal', function (e) {
-        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
-      })
-    })
+        this._checkScrollbar();
+        this._setScrollbar();
 
-    this.backdrop(function () {
-      var transition = $.support.transition && that.$element.hasClass('fade')
+        $(document.body).addClass(ClassName.OPEN);
 
-      if (!that.$element.parent().length) {
-        that.$element.appendTo(that.$body) // don't move modals dom position
-      }
+        this._setEscapeEvent();
+        this._setResizeEvent();
 
-      that.$element
-        .show()
-        .scrollTop(0)
+        $(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, $.proxy(this.hide, this));
 
-      that.adjustDialog()
+        $(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () {
+          $(_this7._element).one(Event.MOUSEUP_DISMISS, function (event) {
+            if ($(event.target).is(_this7._element)) {
+              that._ignoreBackdropClick = true;
+            }
+          });
+        });
 
-      if (transition) {
-        that.$element[0].offsetWidth // force reflow
+        this._showBackdrop($.proxy(this._showElement, this, relatedTarget));
       }
+    }, {
+      key: 'hide',
+      value: function hide(event) {
+        if (event) {
+          event.preventDefault();
+        }
 
-      that.$element.addClass('in')
-
-      that.enforceFocus()
+        var hideEvent = $.Event(Event.HIDE);
 
-      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
+        $(this._element).trigger(hideEvent);
 
-      transition ?
-        that.$dialog // wait for modal to slide in
-          .one('bsTransitionEnd', function () {
-            that.$element.trigger('focus').trigger(e)
-          })
-          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
-        that.$element.trigger('focus').trigger(e)
-    })
-  }
+        if (!this._isShown || hideEvent.isDefaultPrevented()) {
+          return;
+        }
 
-  Modal.prototype.hide = function (e) {
-    if (e) e.preventDefault()
+        this._isShown = false;
 
-    e = $.Event('hide.bs.modal')
+        this._setEscapeEvent();
+        this._setResizeEvent();
 
-    this.$element.trigger(e)
+        $(document).off(Event.FOCUSIN);
 
-    if (!this.isShown || e.isDefaultPrevented()) return
+        $(this._element).removeClass(ClassName.IN);
 
-    this.isShown = false
+        $(this._element).off(Event.CLICK_DISMISS);
+        $(this._dialog).off(Event.MOUSEDOWN_DISMISS);
 
-    this.escape()
-    this.resize()
+        if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
 
-    $(document).off('focusin.bs.modal')
+          $(this._element).one(Util.TRANSITION_END, $.proxy(this._hideModal, this)).emulateTransitionEnd(TRANSITION_DURATION);
+        } else {
+          this._hideModal();
+        }
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeData(this._element, DATA_KEY);
+
+        $(window).off(EVENT_KEY);
+        $(document).off(EVENT_KEY);
+        $(this._element).off(EVENT_KEY);
+        $(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;
+      }
+    }, {
+      key: '_getConfig',
 
-    this.$element
-      .removeClass('in')
-      .off('click.dismiss.bs.modal')
-      .off('mouseup.dismiss.bs.modal')
+      // private
 
-    this.$dialog.off('mousedown.dismiss.bs.modal')
+      value: function _getConfig(config) {
+        config = $.extend({}, Default, config);
+        Util.typeCheckConfig(NAME, config, DefaultType);
+        return config;
+      }
+    }, {
+      key: '_showElement',
+      value: function _showElement(relatedTarget) {
+        var _this8 = this;
 
-    $.support.transition && this.$element.hasClass('fade') ?
-      this.$element
-        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
-        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
-      this.hideModal()
-  }
+        var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE);
 
-  Modal.prototype.enforceFocus = function () {
-    $(document)
-      .off('focusin.bs.modal') // guard against infinite focus loop
-      .on('focusin.bs.modal', $.proxy(function (e) {
-        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
-          this.$element.trigger('focus')
+        if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
+          // don't move modals dom position
+          document.body.appendChild(this._element);
         }
-      }, this))
-  }
-
-  Modal.prototype.escape = function () {
-    if (this.isShown && this.options.keyboard) {
-      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
-        e.which == 27 && this.hide()
-      }, this))
-    } else if (!this.isShown) {
-      this.$element.off('keydown.dismiss.bs.modal')
-    }
-  }
-
-  Modal.prototype.resize = function () {
-    if (this.isShown) {
-      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
-    } else {
-      $(window).off('resize.bs.modal')
-    }
-  }
-
-  Modal.prototype.hideModal = function () {
-    var that = this
-    this.$element.hide()
-    this.backdrop(function () {
-      that.$body.removeClass('modal-open')
-      that.resetAdjustments()
-      that.resetScrollbar()
-      that.$element.trigger('hidden.bs.modal')
-    })
-  }
-
-  Modal.prototype.removeBackdrop = function () {
-    this.$backdrop && this.$backdrop.remove()
-    this.$backdrop = null
-  }
-
-  Modal.prototype.backdrop = function (callback) {
-    var that = this
-    var animate = this.$element.hasClass('fade') ? 'fade' : ''
 
-    if (this.isShown && this.options.backdrop) {
-      var doAnimate = $.support.transition && animate
+        this._element.style.display = 'block';
+        this._element.scrollTop = 0;
 
-      this.$backdrop = $(document.createElement('div'))
-        .addClass('modal-backdrop ' + animate)
-        .appendTo(this.$body)
-
-      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
-        if (this.ignoreBackdropClick) {
-          this.ignoreBackdropClick = false
-          return
+        if (transition) {
+          Util.reflow(this._element);
         }
-        if (e.target !== e.currentTarget) return
-        this.options.backdrop == 'static'
-          ? this.$element[0].focus()
-          : this.hide()
-      }, this))
-
-      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
 
-      this.$backdrop.addClass('in')
+        $(this._element).addClass(ClassName.IN);
 
-      if (!callback) return
+        if (this._config.focus) this._enforceFocus();
 
-      doAnimate ?
-        this.$backdrop
-          .one('bsTransitionEnd', callback)
-          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
-        callback()
+        var shownEvent = $.Event(Event.SHOWN, {
+          relatedTarget: relatedTarget
+        });
 
-    } else if (!this.isShown && this.$backdrop) {
-      this.$backdrop.removeClass('in')
+        var transitionComplete = function transitionComplete() {
+          if (_this8._config.focus) _this8._element.focus();
+          $(_this8._element).trigger(shownEvent);
+        };
 
-      var callbackRemove = function () {
-        that.removeBackdrop()
-        callback && callback()
+        if (transition) {
+          $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(TRANSITION_DURATION);
+        } else {
+          transitionComplete();
+        }
       }
-      $.support.transition && this.$element.hasClass('fade') ?
-        this.$backdrop
-          .one('bsTransitionEnd', callbackRemove)
-          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
-        callbackRemove()
-
-    } else if (callback) {
-      callback()
-    }
-  }
-
-  // these following methods are used to handle overflowing modals
-
-  Modal.prototype.handleUpdate = function () {
-    this.adjustDialog()
-  }
-
-  Modal.prototype.adjustDialog = function () {
-    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
-
-    this.$element.css({
-      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
-      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
-    })
-  }
-
-  Modal.prototype.resetAdjustments = function () {
-    this.$element.css({
-      paddingLeft: '',
-      paddingRight: ''
-    })
-  }
-
-  Modal.prototype.checkScrollbar = function () {
-    var fullWindowWidth = window.innerWidth
-    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
-      var documentElementRect = document.documentElement.getBoundingClientRect()
-      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
-    }
-    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
-    this.scrollbarWidth = this.measureScrollbar()
-  }
-
-  Modal.prototype.setScrollbar = function () {
-    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
-    this.originalBodyPad = document.body.style.paddingRight || ''
-    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
-  }
-
-  Modal.prototype.resetScrollbar = function () {
-    this.$body.css('padding-right', this.originalBodyPad)
-  }
-
-  Modal.prototype.measureScrollbar = function () { // thx walsh
-    var scrollDiv = document.createElement('div')
-    scrollDiv.className = 'modal-scrollbar-measure'
-    this.$body.append(scrollDiv)
-    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
-    this.$body[0].removeChild(scrollDiv)
-    return scrollbarWidth
-  }
-
-
-  // MODAL PLUGIN DEFINITION
-  // =======================
-
-  function Plugin(option, _relatedTarget) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.modal')
-      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
-
-      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
-      if (typeof option == 'string') data[option](_relatedTarget)
-      else if (options.show) data.show(_relatedTarget)
-    })
-  }
-
-  var old = $.fn.modal
-
-  $.fn.modal             = Plugin
-  $.fn.modal.Constructor = Modal
-
-
-  // MODAL NO CONFLICT
-  // =================
-
-  $.fn.modal.noConflict = function () {
-    $.fn.modal = old
-    return this
-  }
-
-
-  // MODAL DATA-API
-  // ==============
-
-  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
-    var $this   = $(this)
-    var href    = $this.attr('href')
-    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
-    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
-
-    if ($this.is('a')) e.preventDefault()
-
-    $target.one('show.bs.modal', function (showEvent) {
-      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
-      $target.one('hidden.bs.modal', function () {
-        $this.is(':visible') && $this.trigger('focus')
-      })
-    })
-    Plugin.call($target, option, this)
-  })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: tooltip.js v3.3.4
- * http://getbootstrap.com/javascript/#tooltip
- * Inspired by the original jQuery.tipsy by Jason Frame
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // TOOLTIP PUBLIC CLASS DEFINITION
-  // ===============================
-
-  var Tooltip = function (element, options) {
-    this.type       = null
-    this.options    = null
-    this.enabled    = null
-    this.timeout    = null
-    this.hoverState = null
-    this.$element   = null
-    this.inState    = null
-
-    this.init('tooltip', element, options)
-  }
-
-  Tooltip.VERSION  = '3.3.4'
-
-  Tooltip.TRANSITION_DURATION = 150
-
-  Tooltip.DEFAULTS = {
-    animation: true,
-    placement: 'top',
-    selector: false,
-    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
-    trigger: 'hover focus',
-    title: '',
-    delay: 0,
-    html: false,
-    container: false,
-    viewport: {
-      selector: 'body',
-      padding: 0
-    }
-  }
-
-  Tooltip.prototype.init = function (type, element, options) {
-    this.enabled   = true
-    this.type      = type
-    this.$element  = $(element)
-    this.options   = this.getOptions(options)
-    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
-    this.inState   = { click: false, hover: false, focus: false }
-
-    if (this.$element[0] instanceof document.constructor && !this.options.selector) {
-      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
-    }
-
-    var triggers = this.options.trigger.split(' ')
-
-    for (var i = triggers.length; i--;) {
-      var trigger = triggers[i]
+    }, {
+      key: '_enforceFocus',
+      value: function _enforceFocus() {
+        var _this9 = this;
+
+        $(document).off(Event.FOCUSIN) // guard against infinite focus loop
+        .on(Event.FOCUSIN, function (event) {
+          if (_this9._element !== event.target && !$(_this9._element).has(event.target).length) {
+            _this9._element.focus();
+          }
+        });
+      }
+    }, {
+      key: '_setEscapeEvent',
+      value: function _setEscapeEvent() {
+        var _this10 = this;
+
+        if (this._isShown && this._config.keyboard) {
+          $(this._element).on(Event.KEYDOWN_DISMISS, function (event) {
+            if (event.which === 27) {
+              _this10.hide();
+            }
+          });
+        } else if (!this._isShown) {
+          $(this._element).off(Event.KEYDOWN_DISMISS);
+        }
+      }
+    }, {
+      key: '_setResizeEvent',
+      value: function _setResizeEvent() {
+        if (this._isShown) {
+          $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this));
+        } else {
+          $(window).off(Event.RESIZE);
+        }
+      }
+    }, {
+      key: '_hideModal',
+      value: function _hideModal() {
+        var _this11 = this;
+
+        this._element.style.display = 'none';
+        this._showBackdrop(function () {
+          $(document.body).removeClass(ClassName.OPEN);
+          _this11._resetAdjustments();
+          _this11._resetScrollbar();
+          $(_this11._element).trigger(Event.HIDDEN);
+        });
+      }
+    }, {
+      key: '_removeBackdrop',
+      value: function _removeBackdrop() {
+        if (this._backdrop) {
+          $(this._backdrop).remove();
+          this._backdrop = null;
+        }
+      }
+    }, {
+      key: '_showBackdrop',
+      value: function _showBackdrop(callback) {
+        var _this12 = this;
+
+        var animate = $(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : '';
+
+        if (this._isShown && this._config.backdrop) {
+          var doAnimate = Util.supportsTransitionEnd() && animate;
+
+          this._backdrop = document.createElement('div');
+          this._backdrop.className = ClassName.BACKDROP;
+
+          if (animate) {
+            $(this._backdrop).addClass(animate);
+          }
+
+          $(this._backdrop).appendTo(this.$body);
+
+          $(this._element).on(Event.CLICK_DISMISS, function (event) {
+            if (_this12._ignoreBackdropClick) {
+              _this12._ignoreBackdropClick = false;
+              return;
+            }
+            if (event.target !== event.currentTarget) {
+              return;
+            }
+            if (_this12._config.backdrop === 'static') {
+              _this12._element.focus();
+            } else {
+              _this12.hide();
+            }
+          });
+
+          if (doAnimate) {
+            Util.reflow(this._backdrop);
+          }
+
+          $(this._backdrop).addClass(ClassName.IN);
+
+          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.IN);
+
+          var callbackRemove = function callbackRemove() {
+            _this12._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();
+        }
+      }
+    }, {
+      key: '_handleUpdate',
 
-      if (trigger == 'click') {
-        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
-      } else if (trigger != 'manual') {
-        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
-        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
+      // ----------------------------------------------------------------------
+      // the following methods are used to handle overflowing modals
+      // todo (fat): these should probably be refactored out of modal.js
+      // ----------------------------------------------------------------------
 
-        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
-        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
+      value: function _handleUpdate() {
+        this._adjustDialog();
       }
-    }
+    }, {
+      key: '_adjustDialog',
+      value: function _adjustDialog() {
+        var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
 
-    this.options.selector ?
-      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
-      this.fixTitle()
-  }
+        if (!this._isBodyOverflowing && isModalOverflowing) {
+          this._element.style.paddingLeft = this._scrollbarWidth + 'px';
+        }
 
-  Tooltip.prototype.getDefaults = function () {
-    return Tooltip.DEFAULTS
-  }
+        if (this._isBodyOverflowing && !isModalOverflowing) {
+          this._element.style.paddingRight = this._scrollbarWidth + 'px';
+        }
+      }
+    }, {
+      key: '_resetAdjustments',
+      value: function _resetAdjustments() {
+        this._element.style.paddingLeft = '';
+        this._element.style.paddingRight = '';
+      }
+    }, {
+      key: '_checkScrollbar',
+      value: function _checkScrollbar() {
+        var fullWindowWidth = window.innerWidth;
+        if (!fullWindowWidth) {
+          // workaround for missing window.innerWidth in IE8
+          var documentElementRect = document.documentElement.getBoundingClientRect();
+          fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
+        }
+        this._isBodyOverflowing = document.body.clientWidth < fullWindowWidth;
+        this._scrollbarWidth = this._getScrollbarWidth();
+      }
+    }, {
+      key: '_setScrollbar',
+      value: function _setScrollbar() {
+        var bodyPadding = parseInt($(document.body).css('padding-right') || 0, 10);
 
-  Tooltip.prototype.getOptions = function (options) {
-    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
+        this._originalBodyPadding = document.body.style.paddingRight || '';
 
-    if (options.delay && typeof options.delay == 'number') {
-      options.delay = {
-        show: options.delay,
-        hide: options.delay
+        if (this._isBodyOverflowing) {
+          document.body.style.paddingRight = bodyPadding + this._scrollbarWidth + 'px';
+        }
       }
-    }
-
-    return options
-  }
+    }, {
+      key: '_resetScrollbar',
+      value: function _resetScrollbar() {
+        document.body.style.paddingRight = this._originalBodyPadding;
+      }
+    }, {
+      key: '_getScrollbarWidth',
+      value: function _getScrollbarWidth() {
+        // thx d.walsh
+        var scrollDiv = document.createElement('div');
+        scrollDiv.className = Selector.SCROLLBAR_MEASURER;
+        document.body.appendChild(scrollDiv);
+        var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
+        document.body.removeChild(scrollDiv);
+        return scrollbarWidth;
+      }
+    }], [{
+      key: 'VERSION',
 
-  Tooltip.prototype.getDelegateOptions = function () {
-    var options  = {}
-    var defaults = this.getDefaults()
+      // getters
 
-    this._options && $.each(this._options, function (key, value) {
-      if (defaults[key] != value) options[key] = value
-    })
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config, relatedTarget) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+          var _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') {
+            data[config](relatedTarget);
+          } else if (_config.show) {
+            data.show(relatedTarget);
+          }
+        });
+      }
+    }]);
 
-    return options
-  }
+    return Modal;
+  })();
 
-  Tooltip.prototype.enter = function (obj) {
-    var self = obj instanceof this.constructor ?
-      obj : $(obj.currentTarget).data('bs.' + this.type)
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
 
-    if (!self) {
-      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
-      $(obj.currentTarget).data('bs.' + this.type, self)
-    }
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+    var _this13 = this;
 
-    if (obj instanceof $.Event) {
-      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
-    }
+    var target = undefined;
+    var selector = Util.getSelectorFromElement(this);
 
-    if (self.tip().hasClass('in') || self.hoverState == 'in') {
-      self.hoverState = 'in'
-      return
+    if (selector) {
+      target = $(selector)[0];
     }
 
-    clearTimeout(self.timeout)
-
-    self.hoverState = 'in'
-
-    if (!self.options.delay || !self.options.delay.show) return self.show()
-
-    self.timeout = setTimeout(function () {
-      if (self.hoverState == 'in') self.show()
-    }, self.options.delay.show)
-  }
+    var config = $(target).data(DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data());
 
-  Tooltip.prototype.isInStateTrue = function () {
-    for (var key in this.inState) {
-      if (this.inState[key]) return true
+    if (this.tagName === 'A') {
+      event.preventDefault();
     }
 
-    return false
-  }
-
-  Tooltip.prototype.leave = function (obj) {
-    var self = obj instanceof this.constructor ?
-      obj : $(obj.currentTarget).data('bs.' + this.type)
+    var $target = $(target).one(Event.SHOW, function (showEvent) {
+      if (showEvent.isDefaultPrevented()) {
+        // only register focus restorer if modal will actually get shown
+        return;
+      }
 
-    if (!self) {
-      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
-      $(obj.currentTarget).data('bs.' + this.type, self)
-    }
+      $target.one(Event.HIDDEN, function () {
+        if ($(_this13).is(':visible')) {
+          _this13.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);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): scrollspy.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
 
-    if (obj instanceof $.Event) {
-      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
+var ScrollSpy = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'scrollspy';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.scrollspy';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+
+  var Default = {
+    offset: 10,
+    method: 'auto',
+    target: ''
+  };
+
+  var DefaultType = {
+    offset: 'number',
+    method: 'string',
+    target: '(string|element)'
+  };
+
+  var Event = {
+    ACTIVATE: 'activate' + EVENT_KEY,
+    SCROLL: 'scroll' + EVENT_KEY,
+    LOAD_DATA_API: 'load' + EVENT_KEY + '' + DATA_API_KEY
+  };
+
+  var ClassName = {
+    DROPDOWN_MENU: 'dropdown-menu',
+    ACTIVE: 'active'
+  };
+
+  var Selector = {
+    DATA_SPY: '[data-spy="scroll"]',
+    ACTIVE: '.active',
+    LI: 'li',
+    LI_DROPDOWN: 'li.dropdown',
+    NAV_ANCHORS: '.nav li > a'
+  };
+
+  var OffsetMethod = {
+    OFFSET: 'offset',
+    POSITION: 'position'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var ScrollSpy = (function () {
+    function ScrollSpy(element, config) {
+      _classCallCheck(this, ScrollSpy);
+
+      this._element = element;
+      this._scrollElement = element.tagName === 'BODY' ? window : element;
+      this._config = this._getConfig(config);
+      this._selector = '' + this._config.target + ' ' + Selector.NAV_ANCHORS;
+      this._offsets = [];
+      this._targets = [];
+      this._activeTarget = null;
+      this._scrollHeight = 0;
+
+      $(this._scrollElement).on(Event.SCROLL, $.proxy(this._process, this));
+
+      this.refresh();
+      this._process();
     }
 
-    if (self.isInStateTrue()) return
-
-    clearTimeout(self.timeout)
-
-    self.hoverState = 'out'
-
-    if (!self.options.delay || !self.options.delay.hide) return self.hide()
-
-    self.timeout = setTimeout(function () {
-      if (self.hoverState == 'out') self.hide()
-    }, self.options.delay.hide)
-  }
+    _createClass(ScrollSpy, [{
+      key: 'refresh',
 
-  Tooltip.prototype.show = function () {
-    var e = $.Event('show.bs.' + this.type)
+      // public
 
-    if (this.hasContent() && this.enabled) {
-      this.$element.trigger(e)
+      value: function refresh() {
+        var _this14 = this;
 
-      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
-      if (e.isDefaultPrevented() || !inDom) return
-      var that = this
+        var autoMethod = this._scrollElement !== this._scrollElement.window ? OffsetMethod.POSITION : OffsetMethod.OFFSET;
 
-      var $tip = this.tip()
+        var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
 
-      var tipId = this.getUID(this.type)
+        var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;
 
-      this.setContent()
-      $tip.attr('id', tipId)
-      this.$element.attr('aria-describedby', tipId)
+        this._offsets = [];
+        this._targets = [];
 
-      if (this.options.animation) $tip.addClass('fade')
+        this._scrollHeight = this._getScrollHeight();
 
-      var placement = typeof this.options.placement == 'function' ?
-        this.options.placement.call(this, $tip[0], this.$element[0]) :
-        this.options.placement
+        var targets = $.makeArray($(this._selector));
 
-      var autoToken = /\s?auto?\s?/i
-      var autoPlace = autoToken.test(placement)
-      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
+        targets.map(function (element) {
+          var target = undefined;
+          var targetSelector = Util.getSelectorFromElement(element);
 
-      $tip
-        .detach()
-        .css({ top: 0, left: 0, display: 'block' })
-        .addClass(placement)
-        .data('bs.' + this.type, this)
+          if (targetSelector) {
+            target = $(targetSelector)[0];
+          }
 
-      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
-      this.$element.trigger('inserted.bs.' + this.type)
-
-      var pos          = this.getPosition()
-      var actualWidth  = $tip[0].offsetWidth
-      var actualHeight = $tip[0].offsetHeight
-
-      if (autoPlace) {
-        var orgPlacement = placement
-        var viewportDim = this.getPosition(this.$viewport)
-
-        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :
-                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :
-                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :
-                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :
-                    placement
-
-        $tip
-          .removeClass(orgPlacement)
-          .addClass(placement)
+          if (target && (target.offsetWidth || target.offsetHeight)) {
+            // todo (fat): remove sketch reliance on jQuery position/offset
+            return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
+          }
+        }).filter(function (item) {
+          return item;
+        }).sort(function (a, b) {
+          return a[0] - b[0];
+        }).forEach(function (item) {
+          _this14._offsets.push(item[0]);
+          _this14._targets.push(item[1]);
+        });
       }
-
-      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
-
-      this.applyPlacement(calculatedOffset, placement)
-
-      var complete = function () {
-        var prevHoverState = that.hoverState
-        that.$element.trigger('shown.bs.' + that.type)
-        that.hoverState = null
-
-        if (prevHoverState == 'out') that.leave(that)
+    }, {
+      key: 'dispose',
+      value: function 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;
       }
+    }, {
+      key: '_getConfig',
 
-      $.support.transition && this.$tip.hasClass('fade') ?
-        $tip
-          .one('bsTransitionEnd', complete)
-          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
-        complete()
-    }
-  }
-
-  Tooltip.prototype.applyPlacement = function (offset, placement) {
-    var $tip   = this.tip()
-    var width  = $tip[0].offsetWidth
-    var height = $tip[0].offsetHeight
+      // private
 
-    // manually read margins because getBoundingClientRect includes difference
-    var marginTop = parseInt($tip.css('margin-top'), 10)
-    var marginLeft = parseInt($tip.css('margin-left'), 10)
+      value: function _getConfig(config) {
+        config = $.extend({}, Default, config);
 
-    // we must check for NaN for ie 8/9
-    if (isNaN(marginTop))  marginTop  = 0
-    if (isNaN(marginLeft)) marginLeft = 0
+        if (typeof config.target !== 'string') {
+          var id = $(config.target).attr('id');
+          if (!id) {
+            id = Util.getUID(NAME);
+            $(config.target).attr('id', id);
+          }
+          config.target = '#' + id;
+        }
 
-    offset.top  += marginTop
-    offset.left += marginLeft
+        Util.typeCheckConfig(NAME, config, DefaultType);
 
-    // $.fn.offset doesn't round pixel values
-    // so we use setOffset directly with our own function B-0
-    $.offset.setOffset($tip[0], $.extend({
-      using: function (props) {
-        $tip.css({
-          top: Math.round(props.top),
-          left: Math.round(props.left)
-        })
+        return config;
       }
-    }, offset), 0)
-
-    $tip.addClass('in')
-
-    // check to see if placing tip in new offset caused the tip to resize itself
-    var actualWidth  = $tip[0].offsetWidth
-    var actualHeight = $tip[0].offsetHeight
-
-    if (placement == 'top' && actualHeight != height) {
-      offset.top = offset.top + height - actualHeight
-    }
-
-    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
-
-    if (delta.left) offset.left += delta.left
-    else offset.top += delta.top
-
-    var isVertical          = /top|bottom/.test(placement)
-    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
-    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
-
-    $tip.offset(offset)
-    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
-  }
-
-  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
-    this.arrow()
-      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
-      .css(isVertical ? 'top' : 'left', '')
-  }
-
-  Tooltip.prototype.setContent = function () {
-    var $tip  = this.tip()
-    var title = this.getTitle()
-
-    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
-    $tip.removeClass('fade in top bottom left right')
-  }
-
-  Tooltip.prototype.hide = function (callback) {
-    var that = this
-    var $tip = $(this.$tip)
-    var e    = $.Event('hide.bs.' + this.type)
-
-    function complete() {
-      if (that.hoverState != 'in') $tip.detach()
-      that.$element
-        .removeAttr('aria-describedby')
-        .trigger('hidden.bs.' + that.type)
-      callback && callback()
-    }
-
-    this.$element.trigger(e)
-
-    if (e.isDefaultPrevented()) return
+    }, {
+      key: '_getScrollTop',
+      value: function _getScrollTop() {
+        return this._scrollElement === window ? this._scrollElement.scrollY : this._scrollElement.scrollTop;
+      }
+    }, {
+      key: '_getScrollHeight',
+      value: function _getScrollHeight() {
+        return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
+      }
+    }, {
+      key: '_process',
+      value: function _process() {
+        var scrollTop = this._getScrollTop() + this._config.offset;
+        var scrollHeight = this._getScrollHeight();
+        var maxScroll = this._config.offset + scrollHeight - this._scrollElement.offsetHeight;
+
+        if (this._scrollHeight !== scrollHeight) {
+          this.refresh();
+        }
 
-    $tip.removeClass('in')
+        if (scrollTop >= maxScroll) {
+          var target = this._targets[this._targets.length - 1];
 
-    $.support.transition && $tip.hasClass('fade') ?
-      $tip
-        .one('bsTransitionEnd', complete)
-        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
-      complete()
+          if (this._activeTarget !== target) {
+            this._activate(target);
+          }
+        }
 
-    this.hoverState = null
+        if (this._activeTarget && scrollTop < this._offsets[0]) {
+          this._activeTarget = null;
+          this._clear();
+          return;
+        }
 
-    return this
-  }
+        for (var i = this._offsets.length; i--;) {
+          var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (this._offsets[i + 1] === undefined || scrollTop < this._offsets[i + 1]);
 
-  Tooltip.prototype.fixTitle = function () {
-    var $e = this.$element
-    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
-      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
-    }
-  }
+          if (isActiveTarget) {
+            this._activate(this._targets[i]);
+          }
+        }
+      }
+    }, {
+      key: '_activate',
+      value: function _activate(target) {
+        this._activeTarget = target;
 
-  Tooltip.prototype.hasContent = function () {
-    return this.getTitle()
-  }
+        this._clear();
 
-  Tooltip.prototype.getPosition = function ($element) {
-    $element   = $element || this.$element
+        var selector = '' + this._selector + '[data-target="' + target + '"],' + ('' + this._selector + '[href="' + target + '"]');
 
-    var el     = $element[0]
-    var isBody = el.tagName == 'BODY'
+        // todo (fat): getting all the raw li's up the tree is not great.
+        var parentListItems = $(selector).parents(Selector.LI);
 
-    var elRect    = el.getBoundingClientRect()
-    if (elRect.width == null) {
-      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
-      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
-    }
-    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()
-    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
-    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
+        for (var i = parentListItems.length; i--;) {
+          $(parentListItems[i]).addClass(ClassName.ACTIVE);
 
-    return $.extend({}, elRect, scroll, outerDims, elOffset)
-  }
+          var itemParent = parentListItems[i].parentNode;
 
-  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
-    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :
-           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
-           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
-        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
+          if (itemParent && $(itemParent).hasClass(ClassName.DROPDOWN_MENU)) {
+            var closestDropdown = $(itemParent).closest(Selector.LI_DROPDOWN)[0];
+            $(closestDropdown).addClass(ClassName.ACTIVE);
+          }
+        }
 
-  }
+        $(this._scrollElement).trigger(Event.ACTIVATE, {
+          relatedTarget: target
+        });
+      }
+    }, {
+      key: '_clear',
+      value: function _clear() {
+        var activeParents = $(this._selector).parentsUntil(this._config.target, Selector.ACTIVE);
 
-  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
-    var delta = { top: 0, left: 0 }
-    if (!this.$viewport) return delta
-
-    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
-    var viewportDimensions = this.getPosition(this.$viewport)
-
-    if (/right|left/.test(placement)) {
-      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
-      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
-      if (topEdgeOffset < viewportDimensions.top) { // top overflow
-        delta.top = viewportDimensions.top - topEdgeOffset
-      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
-        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
-      }
-    } else {
-      var leftEdgeOffset  = pos.left - viewportPadding
-      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
-      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
-        delta.left = viewportDimensions.left - leftEdgeOffset
-      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
-        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
+        for (var i = activeParents.length; i--;) {
+          $(activeParents[i]).removeClass(ClassName.ACTIVE);
+        }
       }
-    }
+    }], [{
+      key: 'VERSION',
 
-    return delta
-  }
+      // getters
 
-  Tooltip.prototype.getTitle = function () {
-    var title
-    var $e = this.$element
-    var o  = this.options
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: '_jQueryInterface',
 
-    title = $e.attr('data-original-title')
-      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
+      // static
 
-    return title
-  }
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+          var _config = typeof config === 'object' && config || null;
 
-  Tooltip.prototype.getUID = function (prefix) {
-    do prefix += ~~(Math.random() * 1000000)
-    while (document.getElementById(prefix))
-    return prefix
-  }
+          if (!data) {
+            data = new ScrollSpy(this, _config);
+            $(this).data(DATA_KEY, data);
+          }
 
-  Tooltip.prototype.tip = function () {
-    if (!this.$tip) {
-      this.$tip = $(this.options.template)
-      if (this.$tip.length != 1) {
-        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
+          if (typeof config === 'string') {
+            data[config]();
+          }
+        });
       }
-    }
-    return this.$tip
-  }
+    }]);
 
-  Tooltip.prototype.arrow = function () {
-    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
-  }
+    return ScrollSpy;
+  })();
 
-  Tooltip.prototype.enable = function () {
-    this.enabled = true
-  }
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
 
-  Tooltip.prototype.disable = function () {
-    this.enabled = false
-  }
-
-  Tooltip.prototype.toggleEnabled = function () {
-    this.enabled = !this.enabled
-  }
+  $(window).on(Event.LOAD_DATA_API, function () {
+    var scrollSpys = $.makeArray($(Selector.DATA_SPY));
 
-  Tooltip.prototype.toggle = function (e) {
-    var self = this
-    if (e) {
-      self = $(e.currentTarget).data('bs.' + this.type)
-      if (!self) {
-        self = new this.constructor(e.currentTarget, this.getDelegateOptions())
-        $(e.currentTarget).data('bs.' + this.type, self)
-      }
+    for (var i = scrollSpys.length; i--;) {
+      var $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);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): tab.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
 
-    if (e) {
-      self.inState.click = !self.inState.click
-      if (self.isInStateTrue()) self.enter(self)
-      else self.leave(self)
-    } else {
-      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
+var Tab = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'tab';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.tab';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 150;
+
+  var 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
+  };
+
+  var ClassName = {
+    DROPDOWN_MENU: 'dropdown-menu',
+    ACTIVE: 'active',
+    FADE: 'fade',
+    IN: 'in'
+  };
+
+  var Selector = {
+    A: 'a',
+    LI: 'li',
+    LI_DROPDOWN: 'li.dropdown',
+    UL: 'ul:not(.dropdown-menu)',
+    FADE_CHILD: '> .fade',
+    ACTIVE: '.active',
+    ACTIVE_CHILD: '> .active',
+    DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"]',
+    DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu > .active'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Tab = (function () {
+    function Tab(element) {
+      _classCallCheck(this, Tab);
+
+      this._element = element;
     }
-  }
-
-  Tooltip.prototype.destroy = function () {
-    var that = this
-    clearTimeout(this.timeout)
-    this.hide(function () {
-      that.$element.off('.' + that.type).removeData('bs.' + that.type)
-      if (that.$tip) {
-        that.$tip.detach()
-      }
-      that.$tip = null
-      that.$arrow = null
-      that.$viewport = null
-    })
-  }
 
+    _createClass(Tab, [{
+      key: 'show',
 
-  // TOOLTIP PLUGIN DEFINITION
-  // =========================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.tooltip')
-      var options = typeof option == 'object' && option
-
-      if (!data && /destroy|hide/.test(option)) return
-      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
+      // public
 
-  var old = $.fn.tooltip
+      value: function show() {
+        var _this15 = this;
 
-  $.fn.tooltip             = Plugin
-  $.fn.tooltip.Constructor = Tooltip
-
-
-  // TOOLTIP NO CONFLICT
-  // ===================
-
-  $.fn.tooltip.noConflict = function () {
-    $.fn.tooltip = old
-    return this
-  }
-
-}(jQuery);
+        if (this._element.parentNode && this._element.parentNode.nodeType == Node.ELEMENT_NODE && $(this._element).parent().hasClass(ClassName.ACTIVE)) {
+          return;
+        }
 
-/* ========================================================================
- * Bootstrap: popover.js v3.3.4
- * http://getbootstrap.com/javascript/#popovers
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
+        var target = undefined;
+        var previous = undefined;
+        var ulElement = $(this._element).closest(Selector.UL)[0];
+        var selector = Util.getSelectorFromElement(this._element);
 
+        if (ulElement) {
+          previous = $.makeArray($(ulElement).find(Selector.ACTIVE));
+          previous = previous[previous.length - 1];
 
-+function ($) {
-  'use strict';
+          if (previous) {
+            previous = $(previous).find(Selector.A)[0];
+          }
+        }
 
-  // POPOVER PUBLIC CLASS DEFINITION
-  // ===============================
+        var hideEvent = $.Event(Event.HIDE, {
+          relatedTarget: this._element
+        });
 
-  var Popover = function (element, options) {
-    this.init('popover', element, options)
-  }
+        var showEvent = $.Event(Event.SHOW, {
+          relatedTarget: previous
+        });
 
-  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
+        if (previous) {
+          $(previous).trigger(hideEvent);
+        }
 
-  Popover.VERSION  = '3.3.4'
+        $(this._element).trigger(showEvent);
 
-  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
-    placement: 'right',
-    trigger: 'click',
-    content: '',
-    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
-  })
+        if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) {
+          return;
+        }
 
+        if (selector) {
+          target = $(selector)[0];
+        }
 
-  // NOTE: POPOVER EXTENDS tooltip.js
-  // ================================
+        this._activate($(this._element).closest(Selector.LI)[0], ulElement);
 
-  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
+        var complete = function complete() {
+          var hiddenEvent = $.Event(Event.HIDDEN, {
+            relatedTarget: _this15._element
+          });
 
-  Popover.prototype.constructor = Popover
+          var shownEvent = $.Event(Event.SHOWN, {
+            relatedTarget: previous
+          });
 
-  Popover.prototype.getDefaults = function () {
-    return Popover.DEFAULTS
-  }
+          $(previous).trigger(hiddenEvent);
+          $(_this15._element).trigger(shownEvent);
+        };
 
-  Popover.prototype.setContent = function () {
-    var $tip    = this.tip()
-    var title   = this.getTitle()
-    var content = this.getContent()
+        if (target) {
+          this._activate(target, target.parentNode, complete);
+        } else {
+          complete();
+        }
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeClass(this._element, DATA_KEY);
+        this._element = null;
+      }
+    }, {
+      key: '_activate',
 
-    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
-    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
-      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
-    ](content)
+      // private
 
-    $tip.removeClass('fade top bottom left right in')
+      value: function _activate(element, container, callback) {
+        var active = $(container).find(Selector.ACTIVE_CHILD)[0];
+        var isTransitioning = callback && Util.supportsTransitionEnd() && (active && $(active).hasClass(ClassName.FADE) || !!$(container).find(Selector.FADE_CHILD)[0]);
 
-    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
-    // this manually by checking the contents.
-    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
-  }
+        var complete = $.proxy(this._transitionComplete, this, element, active, isTransitioning, callback);
 
-  Popover.prototype.hasContent = function () {
-    return this.getTitle() || this.getContent()
-  }
+        if (active && isTransitioning) {
+          $(active).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+        } else {
+          complete();
+        }
 
-  Popover.prototype.getContent = function () {
-    var $e = this.$element
-    var o  = this.options
+        if (active) {
+          $(active).removeClass(ClassName.IN);
+        }
+      }
+    }, {
+      key: '_transitionComplete',
+      value: function _transitionComplete(element, active, isTransitioning, callback) {
+        if (active) {
+          $(active).removeClass(ClassName.ACTIVE);
+
+          var dropdownChild = $(active).find(Selector.DROPDOWN_ACTIVE_CHILD)[0];
+          if (dropdownChild) {
+            $(dropdownChild).removeClass(ClassName.ACTIVE);
+          }
+
+          var activeToggle = $(active).find(Selector.DATA_TOGGLE)[0];
+          if (activeToggle) {
+            activeToggle.setAttribute('aria-expanded', false);
+          }
+        }
 
-    return $e.attr('data-content')
-      || (typeof o.content == 'function' ?
-            o.content.call($e[0]) :
-            o.content)
-  }
+        $(element).addClass(ClassName.ACTIVE);
 
-  Popover.prototype.arrow = function () {
-    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
-  }
+        var elementToggle = $(element).find(Selector.DATA_TOGGLE)[0];
+        if (elementToggle) {
+          elementToggle.setAttribute('aria-expanded', true);
+        }
 
+        if (isTransitioning) {
+          Util.reflow(element);
+          $(element).addClass(ClassName.IN);
+        } else {
+          $(element).removeClass(ClassName.FADE);
+        }
 
-  // POPOVER PLUGIN DEFINITION
-  // =========================
+        if (element.parentNode && $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
 
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.popover')
-      var options = typeof option == 'object' && option
+          var dropdownElement = $(element).closest(Selector.LI_DROPDOWN)[0];
+          if (dropdownElement) {
+            $(dropdownElement).addClass(ClassName.ACTIVE);
+          }
 
-      if (!data && /destroy|hide/.test(option)) return
-      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
+          elementToggle = $(element).find(Selector.DATA_TOGGLE)[0];
+          if (elementToggle) {
+            elementToggle.setAttribute('aria-expanded', true);
+          }
+        }
 
-  var old = $.fn.popover
+        if (callback) {
+          callback();
+        }
+      }
+    }], [{
+      key: 'VERSION',
 
-  $.fn.popover             = Plugin
-  $.fn.popover.Constructor = Popover
+      // getters
 
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: '_jQueryInterface',
 
-  // POPOVER NO CONFLICT
-  // ===================
+      // static
 
-  $.fn.popover.noConflict = function () {
-    $.fn.popover = old
-    return this
-  }
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var $this = $(this);
+          var data = $this.data(DATA_KEY);
 
-}(jQuery);
+          if (!data) {
+            data = data = new Tab(this);
+            $this.data(DATA_KEY, data);
+          }
 
-/* ========================================================================
- * Bootstrap: scrollspy.js v3.3.4
- * http://getbootstrap.com/javascript/#scrollspy
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
+          if (typeof config === 'string') {
+            data[config]();
+          }
+        });
+      }
+    }]);
+
+    return Tab;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * 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);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): tooltip.js
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // SCROLLSPY CLASS DEFINITION
-  // ==========================
-
-  function ScrollSpy(element, options) {
-    this.$body          = $(document.body)
-    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
-    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
-    this.selector       = (this.options.target || '') + ' .nav li > a'
-    this.offsets        = []
-    this.targets        = []
-    this.activeTarget   = null
-    this.scrollHeight   = 0
-
-    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
-    this.refresh()
-    this.process()
-  }
-
-  ScrollSpy.VERSION  = '3.3.4'
-
-  ScrollSpy.DEFAULTS = {
-    offset: 10
-  }
-
-  ScrollSpy.prototype.getScrollHeight = function () {
-    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
-  }
-
-  ScrollSpy.prototype.refresh = function () {
-    var that          = this
-    var offsetMethod  = 'offset'
-    var offsetBase    = 0
-
-    this.offsets      = []
-    this.targets      = []
-    this.scrollHeight = this.getScrollHeight()
-
-    if (!$.isWindow(this.$scrollElement[0])) {
-      offsetMethod = 'position'
-      offsetBase   = this.$scrollElement.scrollTop()
-    }
-
-    this.$body
-      .find(this.selector)
-      .map(function () {
-        var $el   = $(this)
-        var href  = $el.data('target') || $el.attr('href')
-        var $href = /^#./.test(href) && $(href)
-
-        return ($href
-          && $href.length
-          && $href.is(':visible')
-          && [[$href[offsetMethod]().top + offsetBase, href]]) || null
-      })
-      .sort(function (a, b) { return a[0] - b[0] })
-      .each(function () {
-        that.offsets.push(this[0])
-        that.targets.push(this[1])
-      })
-  }
+ * --------------------------------------------------------------------------
+ */
 
-  ScrollSpy.prototype.process = function () {
-    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
-    var scrollHeight = this.getScrollHeight()
-    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
-    var offsets      = this.offsets
-    var targets      = this.targets
-    var activeTarget = this.activeTarget
-    var i
-
-    if (this.scrollHeight != scrollHeight) {
-      this.refresh()
-    }
+var Tooltip = (function ($) {
 
-    if (scrollTop >= maxScroll) {
-      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
-    }
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
 
-    if (activeTarget && scrollTop < offsets[0]) {
-      this.activeTarget = null
-      return this.clear()
-    }
+  var NAME = 'tooltip';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.tooltip';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 150;
+  var CLASS_PREFIX = 'bs-tether';
 
-    for (i = offsets.length; i--;) {
-      activeTarget != targets[i]
-        && scrollTop >= offsets[i]
-        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
-        && this.activate(targets[i])
+  var Default = {
+    animation: true,
+    template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div></div>',
+    trigger: 'hover focus',
+    title: '',
+    delay: 0,
+    html: false,
+    selector: false,
+    placement: 'top',
+    offset: '0 0',
+    constraints: []
+  };
+
+  var DefaultType = {
+    animation: 'boolean',
+    template: 'string',
+    title: '(string|function)',
+    trigger: 'string',
+    delay: '(number|object)',
+    html: 'boolean',
+    selector: '(string|boolean)',
+    placement: '(string|function)',
+    offset: 'string',
+    constraints: 'array'
+  };
+
+  var AttachmentMap = {
+    TOP: 'bottom center',
+    RIGHT: 'middle left',
+    BOTTOM: 'top center',
+    LEFT: 'middle right'
+  };
+
+  var HoverState = {
+    IN: 'in',
+    OUT: 'out'
+  };
+
+  var 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
+  };
+
+  var ClassName = {
+    FADE: 'fade',
+    IN: 'in'
+  };
+
+  var Selector = {
+    TOOLTIP: '.tooltip',
+    TOOLTIP_INNER: '.tooltip-inner'
+  };
+
+  var TetherClass = {
+    element: false,
+    enabled: false
+  };
+
+  var Trigger = {
+    HOVER: 'hover',
+    FOCUS: 'focus',
+    CLICK: 'click',
+    MANUAL: 'manual'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Tooltip = (function () {
+    function Tooltip(element, config) {
+      _classCallCheck(this, Tooltip);
+
+      // private
+      this._isEnabled = true;
+      this._timeout = 0;
+      this._hoverState = '';
+      this._activeTrigger = {};
+      this._tether = null;
+
+      // protected
+      this.element = element;
+      this.config = this._getConfig(config);
+      this.tip = null;
+
+      this._setListeners();
     }
-  }
-
-  ScrollSpy.prototype.activate = function (target) {
-    this.activeTarget = target
 
-    this.clear()
+    _createClass(Tooltip, [{
+      key: 'enable',
 
-    var selector = this.selector +
-      '[data-target="' + target + '"],' +
-      this.selector + '[href="' + target + '"]'
+      // public
 
-    var active = $(selector)
-      .parents('li')
-      .addClass('active')
-
-    if (active.parent('.dropdown-menu').length) {
-      active = active
-        .closest('li.dropdown')
-        .addClass('active')
-    }
-
-    active.trigger('activate.bs.scrollspy')
-  }
-
-  ScrollSpy.prototype.clear = function () {
-    $(this.selector)
-      .parentsUntil(this.options.target, '.active')
-      .removeClass('active')
-  }
+      value: function enable() {
+        this._isEnabled = true;
+      }
+    }, {
+      key: 'disable',
+      value: function disable() {
+        this._isEnabled = false;
+      }
+    }, {
+      key: 'toggleEnabled',
+      value: function toggleEnabled() {
+        this._isEnabled = !this._isEnabled;
+      }
+    }, {
+      key: 'toggle',
+      value: function toggle(event) {
+        var context = this;
+        var dataKey = this.constructor.DATA_KEY;
+
+        if (event) {
+          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 {
+          $(context.getTipElement()).hasClass(ClassName.IN) ? context._leave(null, context) : context._enter(null, context);
+        }
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        clearTimeout(this._timeout);
 
+        this.cleanupTether();
 
-  // SCROLLSPY PLUGIN DEFINITION
-  // ===========================
+        $.removeData(this.element, this.constructor.DATA_KEY);
 
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.scrollspy')
-      var options = typeof option == 'object' && option
+        $(this.element).off(this.constructor.EVENT_KEY);
 
-      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
+        if (this.tip) {
+          $(this.tip).remove();
+        }
 
-  var old = $.fn.scrollspy
+        this._isEnabled = null;
+        this._timeout = null;
+        this._hoverState = null;
+        this._activeTrigger = null;
+        this._tether = null;
 
-  $.fn.scrollspy             = Plugin
-  $.fn.scrollspy.Constructor = ScrollSpy
+        this.element = null;
+        this.config = null;
+        this.tip = null;
+      }
+    }, {
+      key: 'show',
+      value: function show() {
+        var _this16 = this;
 
+        var showEvent = $.Event(this.constructor.Event.SHOW);
 
-  // SCROLLSPY NO CONFLICT
-  // =====================
+        if (this.isWithContent() && this._isEnabled) {
+          $(this.element).trigger(showEvent);
 
-  $.fn.scrollspy.noConflict = function () {
-    $.fn.scrollspy = old
-    return this
-  }
+          var isInTheDom = $.contains(this.element.ownerDocument.documentElement, this.element);
 
+          if (showEvent.isDefaultPrevented() || !isInTheDom) {
+            return;
+          }
 
-  // SCROLLSPY DATA-API
-  // ==================
+          var tip = this.getTipElement();
+          var tipId = Util.getUID(this.constructor.NAME);
 
-  $(window).on('load.bs.scrollspy.data-api', function () {
-    $('[data-spy="scroll"]').each(function () {
-      var $spy = $(this)
-      Plugin.call($spy, $spy.data())
-    })
-  })
+          tip.setAttribute('id', tipId);
+          this.element.setAttribute('aria-describedby', tipId);
 
-}(jQuery);
+          this.setContent();
 
-/* ========================================================================
- * Bootstrap: tab.js v3.3.4
- * http://getbootstrap.com/javascript/#tabs
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
+          if (this.config.animation) {
+            $(tip).addClass(ClassName.FADE);
+          }
 
+          var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
 
-+function ($) {
-  'use strict';
+          var attachment = this._getAttachment(placement);
 
-  // TAB CLASS DEFINITION
-  // ====================
+          $(tip).data(this.constructor.DATA_KEY, this).appendTo(document.body);
 
-  var Tab = function (element) {
-    // jscs:disable requireDollarBeforejQueryAssignment
-    this.element = $(element)
-    // jscs:enable requireDollarBeforejQueryAssignment
-  }
+          $(this.element).trigger(this.constructor.Event.INSERTED);
 
-  Tab.VERSION = '3.3.4'
+          this._tether = new Tether({
+            element: tip,
+            target: this.element,
+            attachment: attachment,
+            classes: TetherClass,
+            classPrefix: CLASS_PREFIX,
+            offset: this.config.offset,
+            constraints: this.config.constraints
+          });
 
-  Tab.TRANSITION_DURATION = 150
+          Util.reflow(tip);
+          this._tether.position();
 
-  Tab.prototype.show = function () {
-    var $this    = this.element
-    var $ul      = $this.closest('ul:not(.dropdown-menu)')
-    var selector = $this.data('target')
+          $(tip).addClass(ClassName.IN);
 
-    if (!selector) {
-      selector = $this.attr('href')
-      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
-    }
+          var complete = function complete() {
+            var prevHoverState = _this16._hoverState;
+            _this16._hoverState = null;
 
-    if ($this.parent('li').hasClass('active')) return
-
-    var $previous = $ul.find('.active:last a')
-    var hideEvent = $.Event('hide.bs.tab', {
-      relatedTarget: $this[0]
-    })
-    var showEvent = $.Event('show.bs.tab', {
-      relatedTarget: $previous[0]
-    })
-
-    $previous.trigger(hideEvent)
-    $this.trigger(showEvent)
-
-    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
-
-    var $target = $(selector)
-
-    this.activate($this.closest('li'), $ul)
-    this.activate($target, $target.parent(), function () {
-      $previous.trigger({
-        type: 'hidden.bs.tab',
-        relatedTarget: $this[0]
-      })
-      $this.trigger({
-        type: 'shown.bs.tab',
-        relatedTarget: $previous[0]
-      })
-    })
-  }
+            $(_this16.element).trigger(_this16.constructor.Event.SHOWN);
 
-  Tab.prototype.activate = function (element, container, callback) {
-    var $active    = container.find('> .active')
-    var transition = callback
-      && $.support.transition
-      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
-
-    function next() {
-      $active
-        .removeClass('active')
-        .find('> .dropdown-menu > .active')
-          .removeClass('active')
-        .end()
-        .find('[data-toggle="tab"]')
-          .attr('aria-expanded', false)
-
-      element
-        .addClass('active')
-        .find('[data-toggle="tab"]')
-          .attr('aria-expanded', true)
-
-      if (transition) {
-        element[0].offsetWidth // reflow for transition
-        element.addClass('in')
-      } else {
-        element.removeClass('fade')
-      }
-
-      if (element.parent('.dropdown-menu').length) {
-        element
-          .closest('li.dropdown')
-            .addClass('active')
-          .end()
-          .find('[data-toggle="tab"]')
-            .attr('aria-expanded', true)
-      }
-
-      callback && callback()
-    }
+            if (prevHoverState === HoverState.OUT) {
+              _this16._leave(null, _this16);
+            }
+          };
 
-    $active.length && transition ?
-      $active
-        .one('bsTransitionEnd', next)
-        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
-      next()
+          Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE) ? $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(Tooltip._TRANSITION_DURATION) : complete();
+        }
+      }
+    }, {
+      key: 'hide',
+      value: function hide(callback) {
+        var _this17 = this;
+
+        var tip = this.getTipElement();
+        var hideEvent = $.Event(this.constructor.Event.HIDE);
+        var complete = function complete() {
+          if (_this17._hoverState !== HoverState.IN && tip.parentNode) {
+            tip.parentNode.removeChild(tip);
+          }
+
+          _this17.element.removeAttribute('aria-describedby');
+          $(_this17.element).trigger(_this17.constructor.Event.HIDDEN);
+          _this17.cleanupTether();
+
+          if (callback) {
+            callback();
+          }
+        };
+
+        $(this.element).trigger(hideEvent);
+
+        if (hideEvent.isDefaultPrevented()) {
+          return;
+        }
 
-    $active.removeClass('in')
-  }
+        $(tip).removeClass(ClassName.IN);
 
+        if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
 
-  // TAB PLUGIN DEFINITION
-  // =====================
+          $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+        } else {
+          complete();
+        }
 
-  function Plugin(option) {
-    return this.each(function () {
-      var $this = $(this)
-      var data  = $this.data('bs.tab')
+        this._hoverState = '';
+      }
+    }, {
+      key: 'isWithContent',
 
-      if (!data) $this.data('bs.tab', (data = new Tab(this)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
+      // protected
 
-  var old = $.fn.tab
+      value: function isWithContent() {
+        return !!this.getTitle();
+      }
+    }, {
+      key: 'getTipElement',
+      value: function getTipElement() {
+        return this.tip = this.tip || $(this.config.template)[0];
+      }
+    }, {
+      key: 'setContent',
+      value: function setContent() {
+        var tip = this.getTipElement();
+        var title = this.getTitle();
+        var method = this.config.html ? 'innerHTML' : 'innerText';
 
-  $.fn.tab             = Plugin
-  $.fn.tab.Constructor = Tab
+        $(tip).find(Selector.TOOLTIP_INNER)[0][method] = title;
 
+        $(tip).removeClass(ClassName.FADE).removeClass(ClassName.IN);
 
-  // TAB NO CONFLICT
-  // ===============
+        this.cleanupTether();
+      }
+    }, {
+      key: 'getTitle',
+      value: function getTitle() {
+        var title = this.element.getAttribute('data-original-title');
 
-  $.fn.tab.noConflict = function () {
-    $.fn.tab = old
-    return this
-  }
+        if (!title) {
+          title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;
+        }
 
+        return title;
+      }
+    }, {
+      key: 'cleanupTether',
+      value: function cleanupTether() {
+        if (this._tether) {
+          this._tether.destroy();
+
+          // clean up after tether's junk classes
+          // remove after they fix issue
+          // (https://github.com/HubSpot/tether/issues/36)
+          $(this.element).removeClass(this._removeTetherClasses);
+          $(this.tip).removeClass(this._removeTetherClasses);
+        }
+      }
+    }, {
+      key: '_getAttachment',
 
-  // TAB DATA-API
-  // ============
+      // private
 
-  var clickHandler = function (e) {
-    e.preventDefault()
-    Plugin.call($(this), 'show')
-  }
+      value: function _getAttachment(placement) {
+        return AttachmentMap[placement.toUpperCase()];
+      }
+    }, {
+      key: '_setListeners',
+      value: function _setListeners() {
+        var _this18 = this;
+
+        var triggers = this.config.trigger.split(' ');
+
+        triggers.forEach(function (trigger) {
+          if (trigger === 'click') {
+            $(_this18.element).on(_this18.constructor.Event.CLICK, _this18.config.selector, $.proxy(_this18.toggle, _this18));
+          } else if (trigger !== Trigger.MANUAL) {
+            var eventIn = trigger == Trigger.HOVER ? _this18.constructor.Event.MOUSEENTER : _this18.constructor.Event.FOCUSIN;
+            var eventOut = trigger == Trigger.HOVER ? _this18.constructor.Event.MOUSELEAVE : _this18.constructor.Event.FOCUSOUT;
+
+            $(_this18.element).on(eventIn, _this18.config.selector, $.proxy(_this18._enter, _this18)).on(eventOut, _this18.config.selector, $.proxy(_this18._leave, _this18));
+          }
+        });
+
+        if (this.config.selector) {
+          this.config = $.extend({}, this.config, {
+            trigger: 'manual',
+            selector: ''
+          });
+        } else {
+          this._fixTitle();
+        }
+      }
+    }, {
+      key: '_removeTetherClasses',
+      value: function _removeTetherClasses(i, css) {
+        return ((css.baseVal || css).match(new RegExp('(^|\\s)' + CLASS_PREFIX + '-\\S+', 'g')) || []).join(' ');
+      }
+    }, {
+      key: '_fixTitle',
+      value: function _fixTitle() {
+        var 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', '');
+        }
+      }
+    }, {
+      key: '_enter',
+      value: function _enter(event, context) {
+        var dataKey = this.constructor.DATA_KEY;
 
-  $(document)
-    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
-    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
+        context = context || $(event.currentTarget).data(dataKey);
 
-}(jQuery);
+        if (!context) {
+          context = new this.constructor(event.currentTarget, this._getDelegateConfig());
+          $(event.currentTarget).data(dataKey, context);
+        }
 
-/* ========================================================================
- * Bootstrap: affix.js v3.3.4
- * http://getbootstrap.com/javascript/#affix
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
+        if (event) {
+          context._activeTrigger[event.type == 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true;
+        }
 
+        if ($(context.getTipElement()).hasClass(ClassName.IN) || context._hoverState === HoverState.IN) {
+          context._hoverState = HoverState.IN;
+          return;
+        }
 
-+function ($) {
-  'use strict';
+        clearTimeout(context._timeout);
 
-  // AFFIX CLASS DEFINITION
-  // ======================
+        context._hoverState = HoverState.IN;
 
-  var Affix = function (element, options) {
-    this.options = $.extend({}, Affix.DEFAULTS, options)
+        if (!context.config.delay || !context.config.delay.show) {
+          context.show();
+          return;
+        }
 
-    this.$target = $(this.options.target)
-      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
-      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))
+        context._timeout = setTimeout(function () {
+          if (context._hoverState === HoverState.IN) {
+            context.show();
+          }
+        }, context.config.delay.show);
+      }
+    }, {
+      key: '_leave',
+      value: function _leave(event, context) {
+        var dataKey = this.constructor.DATA_KEY;
 
-    this.$element     = $(element)
-    this.affixed      = null
-    this.unpin        = null
-    this.pinnedOffset = null
+        context = context || $(event.currentTarget).data(dataKey);
 
-    this.checkPosition()
-  }
+        if (!context) {
+          context = new this.constructor(event.currentTarget, this._getDelegateConfig());
+          $(event.currentTarget).data(dataKey, context);
+        }
 
-  Affix.VERSION  = '3.3.4'
+        if (event) {
+          context._activeTrigger[event.type == 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false;
+        }
 
-  Affix.RESET    = 'affix affix-top affix-bottom'
+        if (context._isWithActiveTrigger()) {
+          return;
+        }
 
-  Affix.DEFAULTS = {
-    offset: 0,
-    target: window
-  }
+        clearTimeout(context._timeout);
 
-  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
-    var scrollTop    = this.$target.scrollTop()
-    var position     = this.$element.offset()
-    var targetHeight = this.$target.height()
+        context._hoverState = HoverState.OUT;
 
-    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
+        if (!context.config.delay || !context.config.delay.hide) {
+          context.hide();
+          return;
+        }
 
-    if (this.affixed == 'bottom') {
-      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
-      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
-    }
+        context._timeout = setTimeout(function () {
+          if (context._hoverState === HoverState.OUT) {
+            context.hide();
+          }
+        }, context.config.delay.hide);
+      }
+    }, {
+      key: '_isWithActiveTrigger',
+      value: function _isWithActiveTrigger() {
+        for (var trigger in this._activeTrigger) {
+          if (this._activeTrigger[trigger]) {
+            return true;
+          }
+        }
 
-    var initializing   = this.affixed == null
-    var colliderTop    = initializing ? scrollTop : position.top
-    var colliderHeight = initializing ? targetHeight : height
+        return false;
+      }
+    }, {
+      key: '_getConfig',
+      value: function _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
+          };
+        }
 
-    if (offsetTop != null && scrollTop <= offsetTop) return 'top'
-    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
+        Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
 
-    return false
-  }
+        return config;
+      }
+    }, {
+      key: '_getDelegateConfig',
+      value: function _getDelegateConfig() {
+        var config = {};
+
+        if (this.config) {
+          for (var key in this.config) {
+            var value = this.config[key];
+            if (this.constructor.Default[key] !== value) {
+              config[key] = value;
+            }
+          }
+        }
 
-  Affix.prototype.getPinnedOffset = function () {
-    if (this.pinnedOffset) return this.pinnedOffset
-    this.$element.removeClass(Affix.RESET).addClass('affix')
-    var scrollTop = this.$target.scrollTop()
-    var position  = this.$element.offset()
-    return (this.pinnedOffset = position.top - scrollTop)
-  }
+        return config;
+      }
+    }], [{
+      key: 'VERSION',
 
-  Affix.prototype.checkPositionWithEventLoop = function () {
-    setTimeout($.proxy(this.checkPosition, this), 1)
-  }
+      // getters
 
-  Affix.prototype.checkPosition = function () {
-    if (!this.$element.is(':visible')) return
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: 'NAME',
+      get: function () {
+        return NAME;
+      }
+    }, {
+      key: 'DATA_KEY',
+      get: function () {
+        return DATA_KEY;
+      }
+    }, {
+      key: 'Event',
+      get: function () {
+        return Event;
+      }
+    }, {
+      key: 'EVENT_KEY',
+      get: function () {
+        return EVENT_KEY;
+      }
+    }, {
+      key: 'DefaultType',
+      get: function () {
+        return DefaultType;
+      }
+    }, {
+      key: '_jQueryInterface',
 
-    var height       = this.$element.height()
-    var offset       = this.options.offset
-    var offsetTop    = offset.top
-    var offsetBottom = offset.bottom
-    var scrollHeight = Math.max($(document).height(), $(document.body).height())
+      // static
 
-    if (typeof offset != 'object')         offsetBottom = offsetTop = offset
-    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)
-    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+          var _config = typeof config === 'object' ? config : null;
 
-    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
+          if (!data && /destroy|hide/.test(config)) {
+            return;
+          }
 
-    if (this.affixed != affix) {
-      if (this.unpin != null) this.$element.css('top', '')
+          if (!data) {
+            data = new Tooltip(this, _config);
+            $(this).data(DATA_KEY, data);
+          }
 
-      var affixType = 'affix' + (affix ? '-' + affix : '')
-      var e         = $.Event(affixType + '.bs.affix')
+          if (typeof config === 'string') {
+            data[config]();
+          }
+        });
+      }
+    }]);
+
+    return Tooltip;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = Tooltip._jQueryInterface;
+  $.fn[NAME].Constructor = Tooltip;
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Tooltip._jQueryInterface;
+  };
+
+  return Tooltip;
+})(jQuery);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): popover.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
 
-      this.$element.trigger(e)
+var Popover = (function ($) {
 
-      if (e.isDefaultPrevented()) return
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
 
-      this.affixed = affix
-      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
+  var NAME = 'popover';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.popover';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
 
-      this.$element
-        .removeClass(Affix.RESET)
-        .addClass(affixType)
-        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
+  var Default = $.extend({}, Tooltip.Default, {
+    placement: 'right',
+    trigger: 'click',
+    content: '',
+    template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-title"></h3>' + '<div class="popover-content"></div></div>'
+  });
+
+  var DefaultType = $.extend({}, Tooltip.DefaultType, {
+    content: '(string|function)'
+  });
+
+  var ClassName = {
+    FADE: 'fade',
+    IN: 'in'
+  };
+
+  var Selector = {
+    TITLE: '.popover-title',
+    CONTENT: '.popover-content',
+    ARROW: '.popover-arrow'
+  };
+
+  var 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
+   * ------------------------------------------------------------------------
+   */
+
+  var Popover = (function (_Tooltip) {
+    function Popover() {
+      _classCallCheck(this, Popover);
+
+      if (_Tooltip != null) {
+        _Tooltip.apply(this, arguments);
+      }
     }
 
-    if (affix == 'bottom') {
-      this.$element.offset({
-        top: scrollHeight - height - offsetBottom
-      })
-    }
-  }
+    _inherits(Popover, _Tooltip);
 
+    _createClass(Popover, [{
+      key: 'isWithContent',
 
-  // AFFIX PLUGIN DEFINITION
-  // =======================
+      // overrides
 
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.affix')
-      var options = typeof option == 'object' && option
+      value: function isWithContent() {
+        return this.getTitle() || this._getContent();
+      }
+    }, {
+      key: 'getTipElement',
+      value: function getTipElement() {
+        return this.tip = this.tip || $(this.config.template)[0];
+      }
+    }, {
+      key: 'setContent',
+      value: function setContent() {
+        var tip = this.getTipElement();
+        var title = this.getTitle();
+        var content = this._getContent();
+        var titleElement = $(tip).find(Selector.TITLE)[0];
+
+        if (titleElement) {
+          titleElement[this.config.html ? 'innerHTML' : 'innerText'] = title;
+        }
 
-      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
+        // we use append for html objects to maintain js events
+        $(tip).find(Selector.CONTENT).children().detach().end()[this.config.html ? typeof content === 'string' ? 'html' : 'append' : 'text'](content);
 
-  var old = $.fn.affix
+        $(tip).removeClass(ClassName.FADE).removeClass(ClassName.IN);
 
-  $.fn.affix             = Plugin
-  $.fn.affix.Constructor = Affix
+        this.cleanupTether();
+      }
+    }, {
+      key: '_getContent',
 
+      // private
 
-  // AFFIX NO CONFLICT
-  // =================
+      value: function _getContent() {
+        return this.element.getAttribute('data-content') || (typeof this.config.content == 'function' ? this.config.content.call(this.element) : this.config.content);
+      }
+    }], [{
+      key: 'VERSION',
 
-  $.fn.affix.noConflict = function () {
-    $.fn.affix = old
-    return this
-  }
+      // getters
 
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: 'NAME',
+      get: function () {
+        return NAME;
+      }
+    }, {
+      key: 'DATA_KEY',
+      get: function () {
+        return DATA_KEY;
+      }
+    }, {
+      key: 'Event',
+      get: function () {
+        return Event;
+      }
+    }, {
+      key: 'EVENT_KEY',
+      get: function () {
+        return EVENT_KEY;
+      }
+    }, {
+      key: 'DefaultType',
+      get: function () {
+        return DefaultType;
+      }
+    }, {
+      key: '_jQueryInterface',
 
-  // AFFIX DATA-API
-  // ==============
+      // static
 
-  $(window).on('load', function () {
-    $('[data-spy="affix"]').each(function () {
-      var $spy = $(this)
-      var data = $spy.data()
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+          var _config = typeof config === 'object' ? config : null;
 
-      data.offset = data.offset || {}
+          if (!data && /destroy|hide/.test(config)) {
+            return;
+          }
 
-      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
-      if (data.offsetTop    != null) data.offset.top    = data.offsetTop
+          if (!data) {
+            data = new Popover(this, _config);
+            $(this).data(DATA_KEY, data);
+          }
 
-      Plugin.call($spy, data)
-    })
-  })
+          if (typeof config === 'string') {
+            data[config]();
+          }
+        });
+      }
+    }]);
+
+    return Popover;
+  })(Tooltip);
+
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = Popover._jQueryInterface;
+  $.fn[NAME].Constructor = Popover;
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Popover._jQueryInterface;
+  };
+
+  return Popover;
+})(jQuery);
 
 }(jQuery);
diff --git a/dist/js/bootstrap.min.js b/dist/js/bootstrap.min.js
index 7665759238a9ce3af557f650c5ecec0d7685fddc..497cc8176c66d01e9bc3b9e4b67bb70a73b3ec04 100644
--- a/dist/js/bootstrap.min.js
+++ b/dist/js/bootstrap.min.js
@@ -3,5 +3,6 @@
  * Copyright 2011-2015 Twitter, Inc.
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  */
-if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.4",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.4",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.4",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.4",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.4",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.4",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),
-d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.4",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
\ No newline at end of file
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(){"use strict";function a(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(a.__proto__=b)}function b(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}{var c=function(){function a(a,b){for(var c=0;c<b.length;c++){var d=b[c];d.enumerable=d.enumerable||!1,d.configurable=!0,"value"in d&&(d.writable=!0),Object.defineProperty(a,d.key,d)}}return function(b,c,d){return c&&a(b.prototype,c),d&&a(b,d),b}}(),d=function(a){function b(a){return{}.toString.call(a).match(/\s([a-zA-Z]+)/)[1].toLowerCase()}function c(a){return(a[0]||a).nodeType}function d(){return{bindType:h.end,delegateType:h.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}}}function e(){if(window.QUnit)return!1;var a=document.createElement("bootstrap");for(var b in i)if(void 0!==a.style[b])return{end:i[b]};return!1}function f(b){var c=this,d=!1;return a(this).one(j.TRANSITION_END,function(){d=!0}),setTimeout(function(){d||j.triggerTransitionEnd(c)},b),this}function g(){h=e(),a.fn.emulateTransitionEnd=f,j.supportsTransitionEnd()&&(a.event.special[j.TRANSITION_END]=d())}var h=!1,i={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},j={TRANSITION_END:"bsTransitionEnd",getUID:function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},getSelectorFromElement:function(a){var b=a.getAttribute("data-target");return b||(b=a.getAttribute("href")||"",b=/^#[a-z]/i.test(b)?b:null),b},reflow:function(a){new Function("bs","return bs")(a.offsetHeight)},triggerTransitionEnd:function(b){a(b).trigger(h.end)},supportsTransitionEnd:function(){return!!h},typeCheckConfig:function(a,d,e){for(var f in e){var g=e[f],h=d[f],i=void 0;if(i=h&&c(h)?"element":b(h),!new RegExp(g).test(i))throw new Error(""+a.toUpperCase()+": "+('Option "'+f+'" provided type "'+i+'" ')+('but expected type "'+g+'".'))}}};return g(),j}(jQuery),e=(function(a){var e="alert",f="4.0.0",g="bs.alert",h="."+g,i=".data-api",j=a.fn[e],k=150,l={DISMISS:'[data-dismiss="alert"]'},m={CLOSE:"close"+h,CLOSED:"closed"+h,CLICK_DATA_API:"click"+h+i},n={ALERT:"alert",FADE:"fade",IN:"in"},o=function(){function e(a){b(this,e),this._element=a}return c(e,[{key:"close",value:function(a){a=a||this._element;var b=this._getRootElement(a),c=this._triggerCloseEvent(b);c.isDefaultPrevented()||this._removeElement(b)}},{key:"dispose",value:function(){a.removeData(this._element,g),this._element=null}},{key:"_getRootElement",value:function(b){var c=!1,e=d.getSelectorFromElement(b);return e&&(c=a(e)[0]),c||(c=a(b).closest("."+n.ALERT)[0]),c}},{key:"_triggerCloseEvent",value:function(b){var c=a.Event(m.CLOSE);return a(b).trigger(c),c}},{key:"_removeElement",value:function(b){return a(b).removeClass(n.IN),d.supportsTransitionEnd()&&a(b).hasClass(n.FADE)?void a(b).one(d.TRANSITION_END,this._destroyElement.bind(this,b)).emulateTransitionEnd(k):void this._destroyElement(b)}},{key:"_destroyElement",value:function(b){a(b).detach().trigger(m.CLOSED).remove()}}],[{key:"VERSION",get:function(){return f}},{key:"_jQueryInterface",value:function(b){return this.each(function(){var c=a(this),d=c.data(g);d||(d=new e(this),c.data(g,d)),"close"===b&&d[b](this)})}},{key:"_handleDismiss",value:function(a){return function(b){b&&b.preventDefault(),a.close(this)}}}]),e}();return a(document).on(m.CLICK_DATA_API,l.DISMISS,o._handleDismiss(new o)),a.fn[e]=o._jQueryInterface,a.fn[e].Constructor=o,a.fn[e].noConflict=function(){return a.fn[e]=j,o._jQueryInterface},o}(jQuery),function(a){var d="button",e="4.0.0",f="bs.button",g="."+f,h=".data-api",i=a.fn[d],j={ACTIVE:"active",BUTTON:"btn",FOCUS:"focus"},k={DATA_TOGGLE_CARROT:'[data-toggle^="button"]',DATA_TOGGLE:'[data-toggle="buttons"]',INPUT:"input",ACTIVE:".active",BUTTON:".btn"},l={CLICK_DATA_API:"click"+g+h,FOCUS_BLUR_DATA_API:"focus"+g+h+" "+("blur"+g+h)},m=function(){function d(a){b(this,d),this._element=a}return c(d,[{key:"toggle",value:function(){var b=!0,c=a(this._element).closest(k.DATA_TOGGLE)[0];if(c){var d=a(this._element).find(k.INPUT)[0];if(d){if("radio"===d.type)if(d.checked&&a(this._element).hasClass(j.ACTIVE))b=!1;else{var e=a(c).find(k.ACTIVE)[0];e&&a(e).removeClass(j.ACTIVE)}b&&(d.checked=!a(this._element).hasClass(j.ACTIVE),a(this._element).trigger("change"))}}else this._element.setAttribute("aria-pressed",!a(this._element).hasClass(j.ACTIVE));b&&a(this._element).toggleClass(j.ACTIVE)}},{key:"dispose",value:function(){a.removeData(this._element,f),this._element=null}}],[{key:"VERSION",get:function(){return e}},{key:"_jQueryInterface",value:function(b){return this.each(function(){var c=a(this).data(f);c||(c=new d(this),a(this).data(f,c)),"toggle"===b&&c[b]()})}}]),d}();return a(document).on(l.CLICK_DATA_API,k.DATA_TOGGLE_CARROT,function(b){b.preventDefault();var c=b.target;a(c).hasClass(j.BUTTON)||(c=a(c).closest(k.BUTTON)),m._jQueryInterface.call(a(c),"toggle")}).on(l.FOCUS_BLUR_DATA_API,k.DATA_TOGGLE_CARROT,function(b){var c=a(b.target).closest(k.BUTTON)[0];a(c).toggleClass(j.FOCUS,/^focus(in)?$/.test(b.type))}),a.fn[d]=m._jQueryInterface,a.fn[d].Constructor=m,a.fn[d].noConflict=function(){return a.fn[d]=i,m._jQueryInterface},m}(jQuery),function(a){var e="carousel",f="4.0.0",g="bs.carousel",h="."+g,i=".data-api",j=a.fn[e],k=600,l={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0},m={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean"},n={NEXT:"next",PREVIOUS:"prev"},o={SLIDE:"slide"+h,SLID:"slid"+h,KEYDOWN:"keydown"+h,MOUSEENTER:"mouseenter"+h,MOUSELEAVE:"mouseleave"+h,LOAD_DATA_API:"load"+h+i,CLICK_DATA_API:"click"+h+i},p={CAROUSEL:"carousel",ACTIVE:"active",SLIDE:"slide",RIGHT:"right",LEFT:"left",ITEM:"carousel-item"},q={ACTIVE:".active",ACTIVE_ITEM:".active.carousel-item",ITEM:".carousel-item",NEXT_PREV:".next, .prev",INDICATORS:".carousel-indicators",DATA_SLIDE:"[data-slide], [data-slide-to]",DATA_RIDE:'[data-ride="carousel"]'},r=function(){function i(c,d){b(this,i),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this._config=this._getConfig(d),this._element=a(c)[0],this._indicatorsElement=a(this._element).find(q.INDICATORS)[0],this._addEventListeners()}return c(i,[{key:"next",value:function(){this._isSliding||this._slide(n.NEXT)}},{key:"prev",value:function(){this._isSliding||this._slide(n.PREVIOUS)}},{key:"pause",value:function(b){b||(this._isPaused=!0),a(this._element).find(q.NEXT_PREV)[0]&&d.supportsTransitionEnd()&&(d.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}},{key:"cycle",value:function(b){b||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval(a.proxy(this.next,this),this._config.interval))}},{key:"to",value:function(b){var c=this;this._activeElement=a(this._element).find(q.ACTIVE_ITEM)[0];var d=this._getItemIndex(this._activeElement);if(!(b>this._items.length-1||0>b)){if(this._isSliding)return void a(this._element).one(o.SLID,function(){return c.to(b)});if(d==b)return this.pause(),void this.cycle();var e=b>d?n.NEXT:n.PREVIOUS;this._slide(e,this._items[b])}}},{key:"dispose",value:function(){a(this._element).off(h),a.removeData(this._element,g),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null}},{key:"_getConfig",value:function(b){return b=a.extend({},l,b),d.typeCheckConfig(e,b,m),b}},{key:"_addEventListeners",value:function(){this._config.keyboard&&a(this._element).on(o.KEYDOWN,a.proxy(this._keydown,this)),"hover"!=this._config.pause||"ontouchstart"in document.documentElement||a(this._element).on(o.MOUSEENTER,a.proxy(this.pause,this)).on(o.MOUSELEAVE,a.proxy(this.cycle,this))}},{key:"_keydown",value:function(a){if(a.preventDefault(),!/input|textarea/i.test(a.target.tagName))switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}}},{key:"_getItemIndex",value:function(b){return this._items=a.makeArray(a(b).parent().find(q.ITEM)),this._items.indexOf(b)}},{key:"_getItemByDirection",value:function(a,b){var c=a===n.NEXT,d=a===n.PREVIOUS,e=this._getItemIndex(b),f=this._items.length-1,g=d&&0===e||c&&e==f;if(g&&!this._config.wrap)return b;var h=a==n.PREVIOUS?-1:1,i=(e+h)%this._items.length;return-1===i?this._items[this._items.length-1]:this._items[i]}},{key:"_triggerSlideEvent",value:function(b,c){var d=a.Event(o.SLIDE,{relatedTarget:b,direction:c});return a(this._element).trigger(d),d}},{key:"_setActiveIndicatorElement",value:function(b){if(this._indicatorsElement){a(this._indicatorsElement).find(q.ACTIVE).removeClass(p.ACTIVE);var c=this._indicatorsElement.children[this._getItemIndex(b)];c&&a(c).addClass(p.ACTIVE)}}},{key:"_slide",value:function(b,c){var e=this,f=a(this._element).find(q.ACTIVE_ITEM)[0],g=c||f&&this._getItemByDirection(b,f),h=!!this._interval,i=b==n.NEXT?p.LEFT:p.RIGHT;if(g&&a(g).hasClass(p.ACTIVE))return void(this._isSliding=!1);var j=this._triggerSlideEvent(g,i);if(!j.isDefaultPrevented()&&f&&g){this._isSliding=!0,h&&this.pause(),this._setActiveIndicatorElement(g);var l=a.Event(o.SLID,{relatedTarget:g,direction:i});d.supportsTransitionEnd()&&a(this._element).hasClass(p.SLIDE)?(a(g).addClass(b),d.reflow(g),a(f).addClass(i),a(g).addClass(i),a(f).one(d.TRANSITION_END,function(){a(g).removeClass(i).removeClass(b),a(g).addClass(p.ACTIVE),a(f).removeClass(p.ACTIVE).removeClass(b).removeClass(i),e._isSliding=!1,setTimeout(function(){return a(e._element).trigger(l)},0)}).emulateTransitionEnd(k)):(a(f).removeClass(p.ACTIVE),a(g).addClass(p.ACTIVE),this._isSliding=!1,a(this._element).trigger(l)),h&&this.cycle()}}}],[{key:"VERSION",get:function(){return f}},{key:"Default",get:function(){return l}},{key:"_jQueryInterface",value:function(b){return this.each(function(){var c=a(this).data(g),d=a.extend({},l,a(this).data());"object"==typeof b&&a.extend(d,b);var e="string"==typeof b?b:d.slide;c||(c=new i(this,d),a(this).data(g,c)),"number"==typeof b?c.to(b):e?c[e]():d.interval&&(c.pause(),c.cycle())})}},{key:"_dataApiClickHandler",value:function(b){var c=d.getSelectorFromElement(this);if(c){var e=a(c)[0];if(e&&a(e).hasClass(p.CAROUSEL)){var f=a.extend({},a(e).data(),a(this).data()),h=this.getAttribute("data-slide-to");h&&(f.interval=!1),i._jQueryInterface.call(a(e),f),h&&a(e).data(g).to(h),b.preventDefault()}}}}]),i}();return a(document).on(o.CLICK_DATA_API,q.DATA_SLIDE,r._dataApiClickHandler),a(window).on(o.LOAD_DATA_API,function(){a(q.DATA_RIDE).each(function(){var b=a(this);r._jQueryInterface.call(b,b.data())})}),a.fn[e]=r._jQueryInterface,a.fn[e].Constructor=r,a.fn[e].noConflict=function(){return a.fn[e]=j,r._jQueryInterface},r}(jQuery),function(a){var e="collapse",f="4.0.0",g="bs.collapse",h="."+g,i=".data-api",j=a.fn[e],k=600,l={toggle:!0,parent:""},m={toggle:"boolean",parent:"string"},n={SHOW:"show"+h,SHOWN:"shown"+h,HIDE:"hide"+h,HIDDEN:"hidden"+h,CLICK_DATA_API:"click"+h+i},o={IN:"in",COLLAPSE:"collapse",COLLAPSING:"collapsing",COLLAPSED:"collapsed"},p={WIDTH:"width",HEIGHT:"height"},q={ACTIVES:".panel > .in, .panel > .collapsing",DATA_TOGGLE:'[data-toggle="collapse"]'},r=function(){function h(c,d){b(this,h),this._isTransitioning=!1,this._element=c,this._config=this._getConfig(d),this._triggerArray=a.makeArray(a('[data-toggle="collapse"][href="#'+c.id+'"],'+('[data-toggle="collapse"][data-target="#'+c.id+'"]'))),this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}return c(h,[{key:"toggle",value:function(){a(this._element).hasClass(o.IN)?this.hide():this.show()}},{key:"show",value:function(){var b=this;if(!this._isTransitioning&&!a(this._element).hasClass(o.IN)){var c=void 0,e=void 0;if(this._parent&&(c=a.makeArray(a(q.ACTIVES)),c.length||(c=null)),!(c&&(e=a(c).data(g),e&&e._isTransitioning))){var f=a.Event(n.SHOW);if(a(this._element).trigger(f),!f.isDefaultPrevented()){c&&(h._jQueryInterface.call(a(c),"hide"),e||a(c).data(g,null));var i=this._getDimension();a(this._element).removeClass(o.COLLAPSE).addClass(o.COLLAPSING),this._element.style[i]=0,this._element.setAttribute("aria-expanded",!0),this._triggerArray.length&&a(this._triggerArray).removeClass(o.COLLAPSED).attr("aria-expanded",!0),this.setTransitioning(!0);var j=function(){a(b._element).removeClass(o.COLLAPSING).addClass(o.COLLAPSE).addClass(o.IN),b._element.style[i]="",b.setTransitioning(!1),a(b._element).trigger(n.SHOWN)};if(!d.supportsTransitionEnd())return void j();var l="scroll"+(i[0].toUpperCase()+i.slice(1));a(this._element).one(d.TRANSITION_END,j).emulateTransitionEnd(k),this._element.style[i]=this._element[l]+"px"}}}}},{key:"hide",value:function(){var b=this;if(!this._isTransitioning&&a(this._element).hasClass(o.IN)){var c=a.Event(n.HIDE);if(a(this._element).trigger(c),!c.isDefaultPrevented()){var e=this._getDimension(),f=e===p.WIDTH?"offsetWidth":"offsetHeight";this._element.style[e]=this._element[f]+"px",d.reflow(this._element),a(this._element).addClass(o.COLLAPSING).removeClass(o.COLLAPSE).removeClass(o.IN),this._element.setAttribute("aria-expanded",!1),this._triggerArray.length&&a(this._triggerArray).addClass(o.COLLAPSED).attr("aria-expanded",!1),this.setTransitioning(!0);var g=function(){b.setTransitioning(!1),a(b._element).removeClass(o.COLLAPSING).addClass(o.COLLAPSE).trigger(n.HIDDEN)};return this._element.style[e]=0,d.supportsTransitionEnd()?void a(this._element).one(d.TRANSITION_END,g).emulateTransitionEnd(k):g()}}}},{key:"setTransitioning",value:function(a){this._isTransitioning=a}},{key:"dispose",value:function(){a.removeData(this._element,g),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null}},{key:"_getConfig",value:function(b){return b=a.extend({},l,b),b.toggle=!!b.toggle,d.typeCheckConfig(e,b,m),b}},{key:"_getDimension",value:function(){var b=a(this._element).hasClass(p.WIDTH);return b?p.WIDTH:p.HEIGHT}},{key:"_getParent",value:function(){var b=this,c=a(this._config.parent)[0],d='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]';return a(c).find(d).each(function(a,c){b._addAriaAndCollapsedClass(h._getTargetFromElement(c),[c])}),c}},{key:"_addAriaAndCollapsedClass",value:function(b,c){if(b){var d=a(b).hasClass(o.IN);b.setAttribute("aria-expanded",d),c.length&&a(c).toggleClass(o.COLLAPSED,!d).attr("aria-expanded",d)}}}],[{key:"VERSION",get:function(){return f}},{key:"Default",get:function(){return l}},{key:"_getTargetFromElement",value:function(b){var c=d.getSelectorFromElement(b);return c?a(c)[0]:null}},{key:"_jQueryInterface",value:function(b){return this.each(function(){var c=a(this),d=c.data(g),e=a.extend({},l,c.data(),"object"==typeof b&&b);!d&&e.toggle&&/show|hide/.test(b)&&(e.toggle=!1),d||(d=new h(this,e),c.data(g,d)),"string"==typeof b&&d[b]()})}}]),h}();return a(document).on(n.CLICK_DATA_API,q.DATA_TOGGLE,function(b){b.preventDefault();var c=r._getTargetFromElement(this),d=a(c).data(g),e=d?"toggle":a(this).data();r._jQueryInterface.call(a(c),e)}),a.fn[e]=r._jQueryInterface,a.fn[e].Constructor=r,a.fn[e].noConflict=function(){return a.fn[e]=j,r._jQueryInterface},r}(jQuery),function(a){var e="dropdown",f="4.0.0",g="bs.dropdown",h="."+g,i=".data-api",j=a.fn[e],k={HIDE:"hide"+h,HIDDEN:"hidden"+h,SHOW:"show"+h,SHOWN:"shown"+h,CLICK:"click"+h,CLICK_DATA_API:"click"+h+i,KEYDOWN_DATA_API:"keydown"+h+i},l={BACKDROP:"dropdown-backdrop",DISABLED:"disabled",OPEN:"open"},m={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'},n=function(){function e(a){b(this,e),this._element=a,this._addEventListeners()}return c(e,[{key:"toggle",value:function(){if(!this.disabled&&!a(this).hasClass(l.DISABLED)){var b=e._getParentFromElement(this),c=a(b).hasClass(l.OPEN);if(e._clearMenus(),c)return!1;if("ontouchstart"in document.documentElement&&!a(b).closest(m.NAVBAR_NAV).length){var d=document.createElement("div");d.className=l.BACKDROP,a(d).insertBefore(this),a(d).on("click",e._clearMenus)}var f={relatedTarget:this},g=a.Event(k.SHOW,f);if(a(b).trigger(g),!g.isDefaultPrevented())return this.focus(),this.setAttribute("aria-expanded","true"),a(b).toggleClass(l.OPEN),a(b).trigger(k.SHOWN,f),!1}}},{key:"dispose",value:function(){a.removeData(this._element,g),a(this._element).off(h),this._element=null}},{key:"_addEventListeners",value:function(){a(this._element).on(k.CLICK,this.toggle)}}],[{key:"VERSION",get:function(){return f}},{key:"_jQueryInterface",value:function(b){return this.each(function(){var c=a(this).data(g);c||a(this).data(g,c=new e(this)),"string"==typeof b&&c[b].call(this)})}},{key:"_clearMenus",value:function(b){if(!b||3!==b.which){var c=a(m.BACKDROP)[0];c&&c.parentNode.removeChild(c);for(var d=a.makeArray(a(m.DATA_TOGGLE)),f=0;f<d.length;f++){var g=e._getParentFromElement(d[f]),h={relatedTarget:d[f]};if(a(g).hasClass(l.OPEN)&&!(b&&"click"===b.type&&/input|textarea/i.test(b.target.tagName)&&a.contains(g,b.target))){var i=a.Event(k.HIDE,h);a(g).trigger(i),i.isDefaultPrevented()||(d[f].setAttribute("aria-expanded","false"),a(g).removeClass(l.OPEN).trigger(k.HIDDEN,h))}}}}},{key:"_getParentFromElement",value:function(b){var c=void 0,e=d.getSelectorFromElement(b);return e&&(c=a(e)[0]),c||b.parentNode}},{key:"_dataApiKeydownHandler",value:function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)&&(b.preventDefault(),b.stopPropagation(),!this.disabled&&!a(this).hasClass(l.DISABLED))){var c=e._getParentFromElement(this),d=a(c).hasClass(l.OPEN);if(!d&&27!==b.which||d&&27===b.which){if(27===b.which){var f=a(c).find(m.DATA_TOGGLE)[0];a(f).trigger("focus")}return void a(this).trigger("click")}var g=a.makeArray(a(m.VISIBLE_ITEMS));if(g=g.filter(function(a){return a.offsetWidth||a.offsetHeight}),g.length){var h=g.indexOf(b.target);38===b.which&&h>0&&h--,40===b.which&&h<g.length-1&&h++,~h||(h=0),g[h].focus()}}}}]),e}();return a(document).on(k.KEYDOWN_DATA_API,m.DATA_TOGGLE,n._dataApiKeydownHandler).on(k.KEYDOWN_DATA_API,m.ROLE_MENU,n._dataApiKeydownHandler).on(k.KEYDOWN_DATA_API,m.ROLE_LISTBOX,n._dataApiKeydownHandler).on(k.CLICK_DATA_API,n._clearMenus).on(k.CLICK_DATA_API,m.DATA_TOGGLE,n.prototype.toggle).on(k.CLICK_DATA_API,m.FORM_CHILD,function(a){a.stopPropagation()}),a.fn[e]=n._jQueryInterface,a.fn[e].Constructor=n,a.fn[e].noConflict=function(){return a.fn[e]=j,n._jQueryInterface},n}(jQuery),function(a){var e="modal",f="4.0.0",g="bs.modal",h="."+g,i=".data-api",j=a.fn[e],k=300,l=150,m={backdrop:!0,keyboard:!0,focus:!0,show:!0},n={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},o={HIDE:"hide"+h,HIDDEN:"hidden"+h,SHOW:"show"+h,SHOWN:"shown"+h,FOCUSIN:"focusin"+h,RESIZE:"resize"+h,CLICK_DISMISS:"click.dismiss"+h,KEYDOWN_DISMISS:"keydown.dismiss"+h,MOUSEUP_DISMISS:"mouseup.dismiss"+h,MOUSEDOWN_DISMISS:"mousedown.dismiss"+h,CLICK_DATA_API:"click"+h+i},p={BACKDROP:"modal-backdrop",OPEN:"modal-open",FADE:"fade",IN:"in"},q={DIALOG:".modal-dialog",DATA_TOGGLE:'[data-toggle="modal"]',DATA_DISMISS:'[data-dismiss="modal"]',SCROLLBAR_MEASURER:"modal-scrollbar-measure"},r=function(){function i(c,d){b(this,i),this._config=this._getConfig(d),this._element=c,this._dialog=a(c).find(q.DIALOG)[0],this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._originalBodyPadding=0,this._scrollbarWidth=0}return c(i,[{key:"toggle",value:function(a){return this._isShown?this.hide():this.show(a)}},{key:"show",value:function(b){var c=this,d=a.Event(o.SHOW,{relatedTarget:b});a(this._element).trigger(d),this._isShown||d.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),a(document.body).addClass(p.OPEN),this._setEscapeEvent(),this._setResizeEvent(),a(this._element).on(o.CLICK_DISMISS,q.DATA_DISMISS,a.proxy(this.hide,this)),a(this._dialog).on(o.MOUSEDOWN_DISMISS,function(){a(c._element).one(o.MOUSEUP_DISMISS,function(b){a(b.target).is(c._element)&&(that._ignoreBackdropClick=!0)})}),this._showBackdrop(a.proxy(this._showElement,this,b)))}},{key:"hide",value:function(b){b&&b.preventDefault();var c=a.Event(o.HIDE);a(this._element).trigger(c),this._isShown&&!c.isDefaultPrevented()&&(this._isShown=!1,this._setEscapeEvent(),this._setResizeEvent(),a(document).off(o.FOCUSIN),a(this._element).removeClass(p.IN),a(this._element).off(o.CLICK_DISMISS),a(this._dialog).off(o.MOUSEDOWN_DISMISS),d.supportsTransitionEnd()&&a(this._element).hasClass(p.FADE)?a(this._element).one(d.TRANSITION_END,a.proxy(this._hideModal,this)).emulateTransitionEnd(k):this._hideModal())}},{key:"dispose",value:function(){a.removeData(this._element,g),a(window).off(h),a(document).off(h),a(this._element).off(h),a(this._backdrop).off(h),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}},{key:"_getConfig",value:function(b){return b=a.extend({},m,b),d.typeCheckConfig(e,b,n),b}},{key:"_showElement",value:function(b){var c=this,e=d.supportsTransitionEnd()&&a(this._element).hasClass(p.FADE);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.scrollTop=0,e&&d.reflow(this._element),a(this._element).addClass(p.IN),this._config.focus&&this._enforceFocus();var f=a.Event(o.SHOWN,{relatedTarget:b}),g=function(){c._config.focus&&c._element.focus(),a(c._element).trigger(f)};e?a(this._dialog).one(d.TRANSITION_END,g).emulateTransitionEnd(k):g()}},{key:"_enforceFocus",value:function(){var b=this;a(document).off(o.FOCUSIN).on(o.FOCUSIN,function(c){b._element===c.target||a(b._element).has(c.target).length||b._element.focus()})}},{key:"_setEscapeEvent",value:function(){var b=this;this._isShown&&this._config.keyboard?a(this._element).on(o.KEYDOWN_DISMISS,function(a){27===a.which&&b.hide()}):this._isShown||a(this._element).off(o.KEYDOWN_DISMISS)}},{key:"_setResizeEvent",value:function(){this._isShown?a(window).on(o.RESIZE,a.proxy(this._handleUpdate,this)):a(window).off(o.RESIZE)}},{key:"_hideModal",value:function(){var b=this;this._element.style.display="none",this._showBackdrop(function(){a(document.body).removeClass(p.OPEN),b._resetAdjustments(),b._resetScrollbar(),a(b._element).trigger(o.HIDDEN)})}},{key:"_removeBackdrop",value:function(){this._backdrop&&(a(this._backdrop).remove(),this._backdrop=null)}},{key:"_showBackdrop",value:function(b){var c=this,e=a(this._element).hasClass(p.FADE)?p.FADE:"";if(this._isShown&&this._config.backdrop){var f=d.supportsTransitionEnd()&&e;if(this._backdrop=document.createElement("div"),this._backdrop.className=p.BACKDROP,e&&a(this._backdrop).addClass(e),a(this._backdrop).appendTo(this.$body),a(this._element).on(o.CLICK_DISMISS,function(a){return c._ignoreBackdropClick?void(c._ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"===c._config.backdrop?c._element.focus():c.hide()))}),f&&d.reflow(this._backdrop),a(this._backdrop).addClass(p.IN),!b)return;if(!f)return void b();a(this._backdrop).one(d.TRANSITION_END,b).emulateTransitionEnd(l)}else if(!this._isShown&&this._backdrop){a(this._backdrop).removeClass(p.IN);var g=function(){c._removeBackdrop(),b&&b()};d.supportsTransitionEnd()&&a(this._element).hasClass(p.FADE)?a(this._backdrop).one(d.TRANSITION_END,g).emulateTransitionEnd(l):g()}else b&&b()}},{key:"_handleUpdate",value:function(){this._adjustDialog()}},{key:"_adjustDialog",value:function(){var a=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&a&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!a&&(this._element.style.paddingRight=this._scrollbarWidth+"px")}},{key:"_resetAdjustments",value:function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}},{key:"_checkScrollbar",value:function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this._isBodyOverflowing=document.body.clientWidth<a,this._scrollbarWidth=this._getScrollbarWidth()}},{key:"_setScrollbar",value:function(){var b=parseInt(a(document.body).css("padding-right")||0,10);this._originalBodyPadding=document.body.style.paddingRight||"",this._isBodyOverflowing&&(document.body.style.paddingRight=b+this._scrollbarWidth+"px")}},{key:"_resetScrollbar",value:function(){document.body.style.paddingRight=this._originalBodyPadding}},{key:"_getScrollbarWidth",value:function(){var a=document.createElement("div");a.className=q.SCROLLBAR_MEASURER,document.body.appendChild(a);var b=a.offsetWidth-a.clientWidth;return document.body.removeChild(a),b}}],[{key:"VERSION",get:function(){return f}},{key:"Default",get:function(){return m}},{key:"_jQueryInterface",value:function(b,c){return this.each(function(){var d=a(this).data(g),e=a.extend({},i.Default,a(this).data(),"object"==typeof b&&b);d||(d=new i(this,e),a(this).data(g,d)),"string"==typeof b?d[b](c):e.show&&d.show(c)})}}]),i}();return a(document).on(o.CLICK_DATA_API,q.DATA_TOGGLE,function(b){var c=this,e=void 0,f=d.getSelectorFromElement(this);f&&(e=a(f)[0]);var h=a(e).data(g)?"toggle":a.extend({},a(e).data(),a(this).data());"A"===this.tagName&&b.preventDefault();var i=a(e).one(o.SHOW,function(b){b.isDefaultPrevented()||i.one(o.HIDDEN,function(){a(c).is(":visible")&&c.focus()})});r._jQueryInterface.call(a(e),h,this)}),a.fn[e]=r._jQueryInterface,a.fn[e].Constructor=r,a.fn[e].noConflict=function(){return a.fn[e]=j,r._jQueryInterface},r}(jQuery),function(a){var e="scrollspy",f="4.0.0",g="bs.scrollspy",h="."+g,i=".data-api",j=a.fn[e],k={offset:10,method:"auto",target:""},l={offset:"number",method:"string",target:"(string|element)"},m={ACTIVATE:"activate"+h,SCROLL:"scroll"+h,LOAD_DATA_API:"load"+h+i},n={DROPDOWN_MENU:"dropdown-menu",ACTIVE:"active"},o={DATA_SPY:'[data-spy="scroll"]',ACTIVE:".active",LI:"li",LI_DROPDOWN:"li.dropdown",NAV_ANCHORS:".nav li > a"},p={OFFSET:"offset",POSITION:"position"},q=function(){function i(c,d){b(this,i),this._element=c,this._scrollElement="BODY"===c.tagName?window:c,this._config=this._getConfig(d),this._selector=""+this._config.target+" "+o.NAV_ANCHORS,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,a(this._scrollElement).on(m.SCROLL,a.proxy(this._process,this)),this.refresh(),this._process()}return c(i,[{key:"refresh",value:function(){var b=this,c=this._scrollElement!==this._scrollElement.window?p.POSITION:p.OFFSET,e="auto"===this._config.method?c:this._config.method,f=e===p.POSITION?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight();var g=a.makeArray(a(this._selector));g.map(function(b){var c=void 0,g=d.getSelectorFromElement(b);return g&&(c=a(g)[0]),c&&(c.offsetWidth||c.offsetHeight)?[a(c)[e]().top+f,g]:void 0}).filter(function(a){return a}).sort(function(a,b){return a[0]-b[0]}).forEach(function(a){b._offsets.push(a[0]),b._targets.push(a[1])})}},{key:"dispose",value:function(){a.removeData(this._element,g),a(this._scrollElement).off(h),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null}},{key:"_getConfig",value:function(b){if(b=a.extend({},k,b),"string"!=typeof b.target){var c=a(b.target).attr("id");c||(c=d.getUID(e),a(b.target).attr("id",c)),b.target="#"+c}return d.typeCheckConfig(e,b,l),b}},{key:"_getScrollTop",value:function(){return this._scrollElement===window?this._scrollElement.scrollY:this._scrollElement.scrollTop}},{key:"_getScrollHeight",value:function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}},{key:"_process",value:function(){var a=this._getScrollTop()+this._config.offset,b=this._getScrollHeight(),c=this._config.offset+b-this._scrollElement.offsetHeight;if(this._scrollHeight!==b&&this.refresh(),a>=c){var d=this._targets[this._targets.length-1];this._activeTarget!==d&&this._activate(d)}if(this._activeTarget&&a<this._offsets[0])return this._activeTarget=null,void this._clear();for(var e=this._offsets.length;e--;){var f=this._activeTarget!==this._targets[e]&&a>=this._offsets[e]&&(void 0===this._offsets[e+1]||a<this._offsets[e+1]);f&&this._activate(this._targets[e])}}},{key:"_activate",value:function(b){this._activeTarget=b,this._clear();for(var c=""+this._selector+'[data-target="'+b+'"],'+(""+this._selector+'[href="'+b+'"]'),d=a(c).parents(o.LI),e=d.length;e--;){a(d[e]).addClass(n.ACTIVE);var f=d[e].parentNode;if(f&&a(f).hasClass(n.DROPDOWN_MENU)){var g=a(f).closest(o.LI_DROPDOWN)[0];a(g).addClass(n.ACTIVE)}}a(this._scrollElement).trigger(m.ACTIVATE,{relatedTarget:b})}},{key:"_clear",value:function(){for(var b=a(this._selector).parentsUntil(this._config.target,o.ACTIVE),c=b.length;c--;)a(b[c]).removeClass(n.ACTIVE)}}],[{key:"VERSION",get:function(){return f}},{key:"Default",get:function(){return k}},{key:"_jQueryInterface",value:function(b){return this.each(function(){var c=a(this).data(g),d="object"==typeof b&&b||null;c||(c=new i(this,d),a(this).data(g,c)),"string"==typeof b&&c[b]()})}}]),i}();return a(window).on(m.LOAD_DATA_API,function(){for(var b=a.makeArray(a(o.DATA_SPY)),c=b.length;c--;){var d=a(b[c]);q._jQueryInterface.call(d,d.data())}}),a.fn[e]=q._jQueryInterface,a.fn[e].Constructor=q,a.fn[e].noConflict=function(){return a.fn[e]=j,q._jQueryInterface},q}(jQuery),function(a){var e="tab",f="4.0.0",g="bs.tab",h="."+g,i=".data-api",j=a.fn[e],k=150,l={HIDE:"hide"+h,HIDDEN:"hidden"+h,SHOW:"show"+h,SHOWN:"shown"+h,CLICK_DATA_API:"click"+h+i},m={DROPDOWN_MENU:"dropdown-menu",ACTIVE:"active",FADE:"fade",IN:"in"},n={A:"a",LI:"li",LI_DROPDOWN:"li.dropdown",UL:"ul:not(.dropdown-menu)",FADE_CHILD:"> .fade",ACTIVE:".active",ACTIVE_CHILD:"> .active",DATA_TOGGLE:'[data-toggle="tab"], [data-toggle="pill"]',DROPDOWN_ACTIVE_CHILD:"> .dropdown-menu > .active"},o=function(){function e(a){b(this,e),this._element=a}return c(e,[{key:"show",value:function(){var b=this;if(!this._element.parentNode||this._element.parentNode.nodeType!=Node.ELEMENT_NODE||!a(this._element).parent().hasClass(m.ACTIVE)){var c=void 0,e=void 0,f=a(this._element).closest(n.UL)[0],g=d.getSelectorFromElement(this._element);f&&(e=a.makeArray(a(f).find(n.ACTIVE)),e=e[e.length-1],e&&(e=a(e).find(n.A)[0]));var h=a.Event(l.HIDE,{relatedTarget:this._element}),i=a.Event(l.SHOW,{relatedTarget:e});if(e&&a(e).trigger(h),a(this._element).trigger(i),!i.isDefaultPrevented()&&!h.isDefaultPrevented()){g&&(c=a(g)[0]),this._activate(a(this._element).closest(n.LI)[0],f);var j=function(){var c=a.Event(l.HIDDEN,{relatedTarget:b._element}),d=a.Event(l.SHOWN,{relatedTarget:e});a(e).trigger(c),a(b._element).trigger(d)};c?this._activate(c,c.parentNode,j):j()}}}},{key:"dispose",value:function(){a.removeClass(this._element,g),this._element=null}},{key:"_activate",value:function(b,c,e){var f=a(c).find(n.ACTIVE_CHILD)[0],g=e&&d.supportsTransitionEnd()&&(f&&a(f).hasClass(m.FADE)||!!a(c).find(n.FADE_CHILD)[0]),h=a.proxy(this._transitionComplete,this,b,f,g,e);
+
+f&&g?a(f).one(d.TRANSITION_END,h).emulateTransitionEnd(k):h(),f&&a(f).removeClass(m.IN)}},{key:"_transitionComplete",value:function(b,c,e,f){if(c){a(c).removeClass(m.ACTIVE);var g=a(c).find(n.DROPDOWN_ACTIVE_CHILD)[0];g&&a(g).removeClass(m.ACTIVE);var h=a(c).find(n.DATA_TOGGLE)[0];h&&h.setAttribute("aria-expanded",!1)}a(b).addClass(m.ACTIVE);var i=a(b).find(n.DATA_TOGGLE)[0];if(i&&i.setAttribute("aria-expanded",!0),e?(d.reflow(b),a(b).addClass(m.IN)):a(b).removeClass(m.FADE),b.parentNode&&a(b.parentNode).hasClass(m.DROPDOWN_MENU)){var j=a(b).closest(n.LI_DROPDOWN)[0];j&&a(j).addClass(m.ACTIVE),i=a(b).find(n.DATA_TOGGLE)[0],i&&i.setAttribute("aria-expanded",!0)}f&&f()}}],[{key:"VERSION",get:function(){return f}},{key:"_jQueryInterface",value:function(b){return this.each(function(){var c=a(this),d=c.data(g);d||(d=d=new e(this),c.data(g,d)),"string"==typeof b&&d[b]()})}}]),e}();return a(document).on(l.CLICK_DATA_API,n.DATA_TOGGLE,function(b){b.preventDefault(),o._jQueryInterface.call(a(this),"show")}),a.fn[e]=o._jQueryInterface,a.fn[e].Constructor=o,a.fn[e].noConflict=function(){return a.fn[e]=j,o._jQueryInterface},o}(jQuery),function(a){var e="tooltip",f="4.0.0",g="bs.tooltip",h="."+g,i=a.fn[e],j=150,k="bs-tether",l={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:"0 0",constraints:[]},m={animation:"boolean",template:"string",title:"(string|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"string",constraints:"array"},n={TOP:"bottom center",RIGHT:"middle left",BOTTOM:"top center",LEFT:"middle right"},o={IN:"in",OUT:"out"},p={HIDE:"hide"+h,HIDDEN:"hidden"+h,SHOW:"show"+h,SHOWN:"shown"+h,INSERTED:"inserted"+h,CLICK:"click"+h,FOCUSIN:"focusin"+h,FOCUSOUT:"focusout"+h,MOUSEENTER:"mouseenter"+h,MOUSELEAVE:"mouseleave"+h},q={FADE:"fade",IN:"in"},r={TOOLTIP:".tooltip",TOOLTIP_INNER:".tooltip-inner"},s={element:!1,enabled:!1},t={HOVER:"hover",FOCUS:"focus",CLICK:"click",MANUAL:"manual"},u=function(){function i(a,c){b(this,i),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._tether=null,this.element=a,this.config=this._getConfig(c),this.tip=null,this._setListeners()}return c(i,[{key:"enable",value:function(){this._isEnabled=!0}},{key:"disable",value:function(){this._isEnabled=!1}},{key:"toggleEnabled",value:function(){this._isEnabled=!this._isEnabled}},{key:"toggle",value:function(b){var c=this,d=this.constructor.DATA_KEY;b?(c=a(b.currentTarget).data(d),c||(c=new this.constructor(b.currentTarget,this._getDelegateConfig()),a(b.currentTarget).data(d,c)),c._activeTrigger.click=!c._activeTrigger.click,c._isWithActiveTrigger()?c._enter(null,c):c._leave(null,c)):a(c.getTipElement()).hasClass(q.IN)?c._leave(null,c):c._enter(null,c)}},{key:"dispose",value:function(){clearTimeout(this._timeout),this.cleanupTether(),a.removeData(this.element,this.constructor.DATA_KEY),a(this.element).off(this.constructor.EVENT_KEY),this.tip&&a(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}},{key:"show",value:function(){var b=this,c=a.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){a(this.element).trigger(c);var e=a.contains(this.element.ownerDocument.documentElement,this.element);if(c.isDefaultPrevented()||!e)return;var f=this.getTipElement(),g=d.getUID(this.constructor.NAME);f.setAttribute("id",g),this.element.setAttribute("aria-describedby",g),this.setContent(),this.config.animation&&a(f).addClass(q.FADE);var h="function"==typeof this.config.placement?this.config.placement.call(this,f,this.element):this.config.placement,j=this._getAttachment(h);a(f).data(this.constructor.DATA_KEY,this).appendTo(document.body),a(this.element).trigger(this.constructor.Event.INSERTED),this._tether=new Tether({element:f,target:this.element,attachment:j,classes:s,classPrefix:k,offset:this.config.offset,constraints:this.config.constraints}),d.reflow(f),this._tether.position(),a(f).addClass(q.IN);var l=function(){var c=b._hoverState;b._hoverState=null,a(b.element).trigger(b.constructor.Event.SHOWN),c===o.OUT&&b._leave(null,b)};d.supportsTransitionEnd()&&a(this.tip).hasClass(q.FADE)?a(this.tip).one(d.TRANSITION_END,l).emulateTransitionEnd(i._TRANSITION_DURATION):l()}}},{key:"hide",value:function(b){var c=this,e=this.getTipElement(),f=a.Event(this.constructor.Event.HIDE),g=function(){c._hoverState!==o.IN&&e.parentNode&&e.parentNode.removeChild(e),c.element.removeAttribute("aria-describedby"),a(c.element).trigger(c.constructor.Event.HIDDEN),c.cleanupTether(),b&&b()};a(this.element).trigger(f),f.isDefaultPrevented()||(a(e).removeClass(q.IN),d.supportsTransitionEnd()&&a(this.tip).hasClass(q.FADE)?a(e).one(d.TRANSITION_END,g).emulateTransitionEnd(j):g(),this._hoverState="")}},{key:"isWithContent",value:function(){return!!this.getTitle()}},{key:"getTipElement",value:function(){return this.tip=this.tip||a(this.config.template)[0]}},{key:"setContent",value:function(){var b=this.getTipElement(),c=this.getTitle(),d=this.config.html?"innerHTML":"innerText";a(b).find(r.TOOLTIP_INNER)[0][d]=c,a(b).removeClass(q.FADE).removeClass(q.IN),this.cleanupTether()}},{key:"getTitle",value:function(){var a=this.element.getAttribute("data-original-title");return a||(a="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),a}},{key:"cleanupTether",value:function(){this._tether&&(this._tether.destroy(),a(this.element).removeClass(this._removeTetherClasses),a(this.tip).removeClass(this._removeTetherClasses))}},{key:"_getAttachment",value:function(a){return n[a.toUpperCase()]}},{key:"_setListeners",value:function(){var b=this,c=this.config.trigger.split(" ");c.forEach(function(c){if("click"===c)a(b.element).on(b.constructor.Event.CLICK,b.config.selector,a.proxy(b.toggle,b));else if(c!==t.MANUAL){var d=c==t.HOVER?b.constructor.Event.MOUSEENTER:b.constructor.Event.FOCUSIN,e=c==t.HOVER?b.constructor.Event.MOUSELEAVE:b.constructor.Event.FOCUSOUT;a(b.element).on(d,b.config.selector,a.proxy(b._enter,b)).on(e,b.config.selector,a.proxy(b._leave,b))}}),this.config.selector?this.config=a.extend({},this.config,{trigger:"manual",selector:""}):this._fixTitle()}},{key:"_removeTetherClasses",value:function(a,b){return((b.baseVal||b).match(new RegExp("(^|\\s)"+k+"-\\S+","g"))||[]).join(" ")}},{key:"_fixTitle",value:function(){var a=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==a)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))}},{key:"_enter",value:function(b,c){var d=this.constructor.DATA_KEY;return c=c||a(b.currentTarget).data(d),c||(c=new this.constructor(b.currentTarget,this._getDelegateConfig()),a(b.currentTarget).data(d,c)),b&&(c._activeTrigger["focusin"==b.type?t.FOCUS:t.HOVER]=!0),a(c.getTipElement()).hasClass(q.IN)||c._hoverState===o.IN?void(c._hoverState=o.IN):(clearTimeout(c._timeout),c._hoverState=o.IN,c.config.delay&&c.config.delay.show?void(c._timeout=setTimeout(function(){c._hoverState===o.IN&&c.show()},c.config.delay.show)):void c.show())}},{key:"_leave",value:function(b,c){var d=this.constructor.DATA_KEY;return c=c||a(b.currentTarget).data(d),c||(c=new this.constructor(b.currentTarget,this._getDelegateConfig()),a(b.currentTarget).data(d,c)),b&&(c._activeTrigger["focusout"==b.type?t.FOCUS:t.HOVER]=!1),c._isWithActiveTrigger()?void 0:(clearTimeout(c._timeout),c._hoverState=o.OUT,c.config.delay&&c.config.delay.hide?void(c._timeout=setTimeout(function(){c._hoverState===o.OUT&&c.hide()},c.config.delay.hide)):void c.hide())}},{key:"_isWithActiveTrigger",value:function(){for(var a in this._activeTrigger)if(this._activeTrigger[a])return!0;return!1}},{key:"_getConfig",value:function(b){return b=a.extend({},this.constructor.Default,a(this.element).data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),d.typeCheckConfig(e,b,this.constructor.DefaultType),b}},{key:"_getDelegateConfig",value:function(){var a={};if(this.config)for(var b in this.config){var c=this.config[b];this.constructor.Default[b]!==c&&(a[b]=c)}return a}}],[{key:"VERSION",get:function(){return f}},{key:"Default",get:function(){return l}},{key:"NAME",get:function(){return e}},{key:"DATA_KEY",get:function(){return g}},{key:"Event",get:function(){return p}},{key:"EVENT_KEY",get:function(){return h}},{key:"DefaultType",get:function(){return m}},{key:"_jQueryInterface",value:function(b){return this.each(function(){var c=a(this).data(g),d="object"==typeof b?b:null;(c||!/destroy|hide/.test(b))&&(c||(c=new i(this,d),a(this).data(g,c)),"string"==typeof b&&c[b]())})}}]),i}();return a.fn[e]=u._jQueryInterface,a.fn[e].Constructor=u,a.fn[e].noConflict=function(){return a.fn[e]=i,u._jQueryInterface},u}(jQuery));!function(d){var f="popover",g="4.0.0",h="bs.popover",i="."+h,j=d.fn[f],k=d.extend({},e.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),l=d.extend({},e.DefaultType,{content:"(string|function)"}),m={FADE:"fade",IN:"in"},n={TITLE:".popover-title",CONTENT:".popover-content",ARROW:".popover-arrow"},o={HIDE:"hide"+i,HIDDEN:"hidden"+i,SHOW:"show"+i,SHOWN:"shown"+i,INSERTED:"inserted"+i,CLICK:"click"+i,FOCUSIN:"focusin"+i,FOCUSOUT:"focusout"+i,MOUSEENTER:"mouseenter"+i,MOUSELEAVE:"mouseleave"+i},p=function(e){function j(){b(this,j),null!=e&&e.apply(this,arguments)}return a(j,e),c(j,[{key:"isWithContent",value:function(){return this.getTitle()||this._getContent()}},{key:"getTipElement",value:function(){return this.tip=this.tip||d(this.config.template)[0]}},{key:"setContent",value:function(){var a=this.getTipElement(),b=this.getTitle(),c=this._getContent(),e=d(a).find(n.TITLE)[0];e&&(e[this.config.html?"innerHTML":"innerText"]=b),d(a).find(n.CONTENT).children().detach().end()[this.config.html?"string"==typeof c?"html":"append":"text"](c),d(a).removeClass(m.FADE).removeClass(m.IN),this.cleanupTether()}},{key:"_getContent",value:function(){return this.element.getAttribute("data-content")||("function"==typeof this.config.content?this.config.content.call(this.element):this.config.content)}}],[{key:"VERSION",get:function(){return g}},{key:"Default",get:function(){return k}},{key:"NAME",get:function(){return f}},{key:"DATA_KEY",get:function(){return h}},{key:"Event",get:function(){return o}},{key:"EVENT_KEY",get:function(){return i}},{key:"DefaultType",get:function(){return l}},{key:"_jQueryInterface",value:function(a){return this.each(function(){var b=d(this).data(h),c="object"==typeof a?a:null;(b||!/destroy|hide/.test(a))&&(b||(b=new j(this,c),d(this).data(h,b)),"string"==typeof a&&b[a]())})}}]),j}(e);return d.fn[f]=p._jQueryInterface,d.fn[f].Constructor=p,d.fn[f].noConflict=function(){return d.fn[f]=j,p._jQueryInterface},p}(jQuery)}}(jQuery);
\ No newline at end of file
diff --git a/dist/js/npm.js b/dist/js/npm.js
index bf6aa80602d9303b61e8d5e63c10568e55b6a4d8..d0564681c86d0453ca5742f5a2e9f89d2398957b 100644
--- a/dist/js/npm.js
+++ b/dist/js/npm.js
@@ -1,13 +1,12 @@
 // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
-require('../../js/transition.js')
-require('../../js/alert.js')
-require('../../js/button.js')
-require('../../js/carousel.js')
-require('../../js/collapse.js')
-require('../../js/dropdown.js')
-require('../../js/modal.js')
-require('../../js/tooltip.js')
-require('../../js/popover.js')
-require('../../js/scrollspy.js')
-require('../../js/tab.js')
-require('../../js/affix.js')
\ No newline at end of file
+require('./umd/util.js')
+require('./umd/alert.js')
+require('./umd/button.js')
+require('./umd/carousel.js')
+require('./umd/collapse.js')
+require('./umd/dropdown.js')
+require('./umd/modal.js')
+require('./umd/scrollspy.js')
+require('./umd/tab.js')
+require('./umd/tooltip.js')
+require('./umd/popover.js')
\ No newline at end of file
diff --git a/dist/js/umd/alert.js b/dist/js/umd/alert.js
new file mode 100644
index 0000000000000000000000000000000000000000..eae17ceb6bfb65e8cf74ca9c0de92e8b7dcadeb6
--- /dev/null
+++ b/dist/js/umd/alert.js
@@ -0,0 +1,211 @@
+(function (global, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['exports', 'module', './util'], factory);
+  } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
+    factory(exports, module, require('./util'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, mod, global.Util);
+    global.alert = mod.exports;
+  }
+})(this, function (exports, module, _util) {
+  'use strict';
+
+  var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+  function _interopRequire(obj) { return obj && obj.__esModule ? obj['default'] : obj; }
+
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+  var _Util = _interopRequire(_util);
+
+  /**
+   * --------------------------------------------------------------------------
+   * Bootstrap (v4.0.0): alert.js
+   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+   * --------------------------------------------------------------------------
+   */
+
+  var Alert = (function ($) {
+
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+
+    var NAME = 'alert';
+    var VERSION = '4.0.0';
+    var DATA_KEY = 'bs.alert';
+    var EVENT_KEY = '.' + DATA_KEY;
+    var DATA_API_KEY = '.data-api';
+    var JQUERY_NO_CONFLICT = $.fn[NAME];
+    var TRANSITION_DURATION = 150;
+
+    var Selector = {
+      DISMISS: '[data-dismiss="alert"]'
+    };
+
+    var Event = {
+      CLOSE: 'close' + EVENT_KEY,
+      CLOSED: 'closed' + EVENT_KEY,
+      CLICK_DATA_API: 'click' + EVENT_KEY + '' + DATA_API_KEY
+    };
+
+    var ClassName = {
+      ALERT: 'alert',
+      FADE: 'fade',
+      IN: 'in'
+    };
+
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+    var Alert = (function () {
+      function Alert(element) {
+        _classCallCheck(this, Alert);
+
+        this._element = element;
+      }
+
+      _createClass(Alert, [{
+        key: 'close',
+
+        // public
+
+        value: function close(element) {
+          element = element || this._element;
+
+          var rootElement = this._getRootElement(element);
+          var customEvent = this._triggerCloseEvent(rootElement);
+
+          if (customEvent.isDefaultPrevented()) {
+            return;
+          }
+
+          this._removeElement(rootElement);
+        }
+      }, {
+        key: 'dispose',
+        value: function dispose() {
+          $.removeData(this._element, DATA_KEY);
+          this._element = null;
+        }
+      }, {
+        key: '_getRootElement',
+
+        // private
+
+        value: function _getRootElement(element) {
+          var parent = false;
+          var selector = _Util.getSelectorFromElement(element);
+
+          if (selector) {
+            parent = $(selector)[0];
+          }
+
+          if (!parent) {
+            parent = $(element).closest('.' + ClassName.ALERT)[0];
+          }
+
+          return parent;
+        }
+      }, {
+        key: '_triggerCloseEvent',
+        value: function _triggerCloseEvent(element) {
+          var closeEvent = $.Event(Event.CLOSE);
+          $(element).trigger(closeEvent);
+          return closeEvent;
+        }
+      }, {
+        key: '_removeElement',
+        value: function _removeElement(element) {
+          $(element).removeClass(ClassName.IN);
+
+          if (!_Util.supportsTransitionEnd() || !$(element).hasClass(ClassName.FADE)) {
+            this._destroyElement(element);
+            return;
+          }
+
+          $(element).one(_Util.TRANSITION_END, this._destroyElement.bind(this, element)).emulateTransitionEnd(TRANSITION_DURATION);
+        }
+      }, {
+        key: '_destroyElement',
+        value: function _destroyElement(element) {
+          $(element).detach().trigger(Event.CLOSED).remove();
+        }
+      }], [{
+        key: 'VERSION',
+
+        // getters
+
+        get: function () {
+          return VERSION;
+        }
+      }, {
+        key: '_jQueryInterface',
+
+        // static
+
+        value: function _jQueryInterface(config) {
+          return this.each(function () {
+            var $element = $(this);
+            var data = $element.data(DATA_KEY);
+
+            if (!data) {
+              data = new Alert(this);
+              $element.data(DATA_KEY, data);
+            }
+
+            if (config === 'close') {
+              data[config](this);
+            }
+          });
+        }
+      }, {
+        key: '_handleDismiss',
+        value: function _handleDismiss(alertInstance) {
+          return function (event) {
+            if (event) {
+              event.preventDefault();
+            }
+
+            alertInstance.close(this);
+          };
+        }
+      }]);
+
+      return Alert;
+    })();
+
+    /**
+     * ------------------------------------------------------------------------
+     * 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);
+
+  module.exports = Alert;
+});
\ No newline at end of file
diff --git a/dist/js/umd/button.js b/dist/js/umd/button.js
new file mode 100644
index 0000000000000000000000000000000000000000..730b3ef01877742e4c47422d89e841037bb8944d
--- /dev/null
+++ b/dist/js/umd/button.js
@@ -0,0 +1,189 @@
+(function (global, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['exports', 'module'], factory);
+  } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
+    factory(exports, module);
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, mod);
+    global.button = mod.exports;
+  }
+})(this, function (exports, module) {
+  'use strict';
+
+  var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+  /**
+   * --------------------------------------------------------------------------
+   * Bootstrap (v4.0.0): button.js
+   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+   * --------------------------------------------------------------------------
+   */
+
+  var Button = (function ($) {
+
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+
+    var NAME = 'button';
+    var VERSION = '4.0.0';
+    var DATA_KEY = 'bs.button';
+    var EVENT_KEY = '.' + DATA_KEY;
+    var DATA_API_KEY = '.data-api';
+    var JQUERY_NO_CONFLICT = $.fn[NAME];
+    var TRANSITION_DURATION = 150;
+
+    var ClassName = {
+      ACTIVE: 'active',
+      BUTTON: 'btn',
+      FOCUS: 'focus'
+    };
+
+    var Selector = {
+      DATA_TOGGLE_CARROT: '[data-toggle^="button"]',
+      DATA_TOGGLE: '[data-toggle="buttons"]',
+      INPUT: 'input',
+      ACTIVE: '.active',
+      BUTTON: '.btn'
+    };
+
+    var 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
+     * ------------------------------------------------------------------------
+     */
+
+    var Button = (function () {
+      function Button(element) {
+        _classCallCheck(this, Button);
+
+        this._element = element;
+      }
+
+      _createClass(Button, [{
+        key: 'toggle',
+
+        // public
+
+        value: function toggle() {
+          var triggerChangeEvent = true;
+          var rootElement = $(this._element).closest(Selector.DATA_TOGGLE)[0];
+
+          if (rootElement) {
+            var input = $(this._element).find(Selector.INPUT)[0];
+
+            if (input) {
+              if (input.type === 'radio') {
+                if (input.checked && $(this._element).hasClass(ClassName.ACTIVE)) {
+                  triggerChangeEvent = false;
+                } else {
+                  var activeElement = $(rootElement).find(Selector.ACTIVE)[0];
+
+                  if (activeElement) {
+                    $(activeElement).removeClass(ClassName.ACTIVE);
+                  }
+                }
+              }
+
+              if (triggerChangeEvent) {
+                input.checked = !$(this._element).hasClass(ClassName.ACTIVE);
+                $(this._element).trigger('change');
+              }
+            }
+          } else {
+            this._element.setAttribute('aria-pressed', !$(this._element).hasClass(ClassName.ACTIVE));
+          }
+
+          if (triggerChangeEvent) {
+            $(this._element).toggleClass(ClassName.ACTIVE);
+          }
+        }
+      }, {
+        key: 'dispose',
+        value: function dispose() {
+          $.removeData(this._element, DATA_KEY);
+          this._element = null;
+        }
+      }], [{
+        key: 'VERSION',
+
+        // getters
+
+        get: function () {
+          return VERSION;
+        }
+      }, {
+        key: '_jQueryInterface',
+
+        // static
+
+        value: function _jQueryInterface(config) {
+          return this.each(function () {
+            var data = $(this).data(DATA_KEY);
+
+            if (!data) {
+              data = new Button(this);
+              $(this).data(DATA_KEY, data);
+            }
+
+            if (config === 'toggle') {
+              data[config]();
+            }
+          });
+        }
+      }]);
+
+      return Button;
+    })();
+
+    /**
+     * ------------------------------------------------------------------------
+     * Data Api implementation
+     * ------------------------------------------------------------------------
+     */
+
+    $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) {
+      event.preventDefault();
+
+      var 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, function (event) {
+      var 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);
+
+  module.exports = Button;
+});
\ No newline at end of file
diff --git a/dist/js/umd/carousel.js b/dist/js/umd/carousel.js
new file mode 100644
index 0000000000000000000000000000000000000000..1352a5dc2d9641630d4644891d8118edecd19fd7
--- /dev/null
+++ b/dist/js/umd/carousel.js
@@ -0,0 +1,485 @@
+(function (global, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['exports', 'module', './util'], factory);
+  } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
+    factory(exports, module, require('./util'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, mod, global.Util);
+    global.carousel = mod.exports;
+  }
+})(this, function (exports, module, _util) {
+  'use strict';
+
+  var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+  function _interopRequire(obj) { return obj && obj.__esModule ? obj['default'] : obj; }
+
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+  var _Util = _interopRequire(_util);
+
+  /**
+   * --------------------------------------------------------------------------
+   * Bootstrap (v4.0.0): carousel.js
+   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+   * --------------------------------------------------------------------------
+   */
+
+  var Carousel = (function ($) {
+
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+
+    var NAME = 'carousel';
+    var VERSION = '4.0.0';
+    var DATA_KEY = 'bs.carousel';
+    var EVENT_KEY = '.' + DATA_KEY;
+    var DATA_API_KEY = '.data-api';
+    var JQUERY_NO_CONFLICT = $.fn[NAME];
+    var TRANSITION_DURATION = 600;
+
+    var Default = {
+      interval: 5000,
+      keyboard: true,
+      slide: false,
+      pause: 'hover',
+      wrap: true
+    };
+
+    var DefaultType = {
+      interval: '(number|boolean)',
+      keyboard: 'boolean',
+      slide: '(boolean|string)',
+      pause: '(string|boolean)',
+      wrap: 'boolean'
+    };
+
+    var Direction = {
+      NEXT: 'next',
+      PREVIOUS: 'prev'
+    };
+
+    var 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
+    };
+
+    var ClassName = {
+      CAROUSEL: 'carousel',
+      ACTIVE: 'active',
+      SLIDE: 'slide',
+      RIGHT: 'right',
+      LEFT: 'left',
+      ITEM: 'carousel-item'
+    };
+
+    var Selector = {
+      ACTIVE: '.active',
+      ACTIVE_ITEM: '.active.carousel-item',
+      ITEM: '.carousel-item',
+      NEXT_PREV: '.next, .prev',
+      INDICATORS: '.carousel-indicators',
+      DATA_SLIDE: '[data-slide], [data-slide-to]',
+      DATA_RIDE: '[data-ride="carousel"]'
+    };
+
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+    var Carousel = (function () {
+      function Carousel(element, config) {
+        _classCallCheck(this, Carousel);
+
+        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();
+      }
+
+      _createClass(Carousel, [{
+        key: 'next',
+
+        // public
+
+        value: function next() {
+          if (!this._isSliding) {
+            this._slide(Direction.NEXT);
+          }
+        }
+      }, {
+        key: 'prev',
+        value: function prev() {
+          if (!this._isSliding) {
+            this._slide(Direction.PREVIOUS);
+          }
+        }
+      }, {
+        key: 'pause',
+        value: function 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;
+        }
+      }, {
+        key: 'cycle',
+        value: function 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($.proxy(this.next, this), this._config.interval);
+          }
+        }
+      }, {
+        key: 'to',
+        value: function to(index) {
+          var _this = this;
+
+          this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
+
+          var activeIndex = this._getItemIndex(this._activeElement);
+
+          if (index > this._items.length - 1 || index < 0) {
+            return;
+          }
+
+          if (this._isSliding) {
+            $(this._element).one(Event.SLID, function () {
+              return _this.to(index);
+            });
+            return;
+          }
+
+          if (activeIndex == index) {
+            this.pause();
+            this.cycle();
+            return;
+          }
+
+          var direction = index > activeIndex ? Direction.NEXT : Direction.PREVIOUS;
+
+          this._slide(direction, this._items[index]);
+        }
+      }, {
+        key: 'dispose',
+        value: function 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;
+        }
+      }, {
+        key: '_getConfig',
+
+        // private
+
+        value: function _getConfig(config) {
+          config = $.extend({}, Default, config);
+          _Util.typeCheckConfig(NAME, config, DefaultType);
+          return config;
+        }
+      }, {
+        key: '_addEventListeners',
+        value: function _addEventListeners() {
+          if (this._config.keyboard) {
+            $(this._element).on(Event.KEYDOWN, $.proxy(this._keydown, this));
+          }
+
+          if (this._config.pause == 'hover' && !('ontouchstart' in document.documentElement)) {
+            $(this._element).on(Event.MOUSEENTER, $.proxy(this.pause, this)).on(Event.MOUSELEAVE, $.proxy(this.cycle, this));
+          }
+        }
+      }, {
+        key: '_keydown',
+        value: function _keydown(event) {
+          event.preventDefault();
+
+          if (/input|textarea/i.test(event.target.tagName)) return;
+
+          switch (event.which) {
+            case 37:
+              this.prev();break;
+            case 39:
+              this.next();break;
+            default:
+              return;
+          }
+        }
+      }, {
+        key: '_getItemIndex',
+        value: function _getItemIndex(element) {
+          this._items = $.makeArray($(element).parent().find(Selector.ITEM));
+          return this._items.indexOf(element);
+        }
+      }, {
+        key: '_getItemByDirection',
+        value: function _getItemByDirection(direction, activeElement) {
+          var isNextDirection = direction === Direction.NEXT;
+          var isPrevDirection = direction === Direction.PREVIOUS;
+          var activeIndex = this._getItemIndex(activeElement);
+          var lastItemIndex = this._items.length - 1;
+          var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex == lastItemIndex;
+
+          if (isGoingToWrap && !this._config.wrap) {
+            return activeElement;
+          }
+
+          var delta = direction == Direction.PREVIOUS ? -1 : 1;
+          var itemIndex = (activeIndex + delta) % this._items.length;
+
+          return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
+        }
+      }, {
+        key: '_triggerSlideEvent',
+        value: function _triggerSlideEvent(relatedTarget, directionalClassname) {
+          var slideEvent = $.Event(Event.SLIDE, {
+            relatedTarget: relatedTarget,
+            direction: directionalClassname
+          });
+
+          $(this._element).trigger(slideEvent);
+
+          return slideEvent;
+        }
+      }, {
+        key: '_setActiveIndicatorElement',
+        value: function _setActiveIndicatorElement(element) {
+          if (this._indicatorsElement) {
+            $(this._indicatorsElement).find(Selector.ACTIVE).removeClass(ClassName.ACTIVE);
+
+            var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
+
+            if (nextIndicator) {
+              $(nextIndicator).addClass(ClassName.ACTIVE);
+            }
+          }
+        }
+      }, {
+        key: '_slide',
+        value: function _slide(direction, element) {
+          var _this2 = this;
+
+          var activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
+          var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
+
+          var isCycling = !!this._interval;
+
+          var directionalClassName = direction == Direction.NEXT ? ClassName.LEFT : ClassName.RIGHT;
+
+          if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {
+            this._isSliding = false;
+            return;
+          }
+
+          var slideEvent = this._triggerSlideEvent(nextElement, directionalClassName);
+          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);
+
+          var slidEvent = $.Event(Event.SLID, {
+            relatedTarget: nextElement,
+            direction: directionalClassName
+          });
+
+          if (_Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.SLIDE)) {
+
+            $(nextElement).addClass(direction);
+
+            _Util.reflow(nextElement);
+
+            $(activeElement).addClass(directionalClassName);
+            $(nextElement).addClass(directionalClassName);
+
+            $(activeElement).one(_Util.TRANSITION_END, function () {
+              $(nextElement).removeClass(directionalClassName).removeClass(direction);
+
+              $(nextElement).addClass(ClassName.ACTIVE);
+
+              $(activeElement).removeClass(ClassName.ACTIVE).removeClass(direction).removeClass(directionalClassName);
+
+              _this2._isSliding = false;
+
+              setTimeout(function () {
+                return $(_this2._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();
+          }
+        }
+      }], [{
+        key: 'VERSION',
+
+        // getters
+
+        get: function () {
+          return VERSION;
+        }
+      }, {
+        key: 'Default',
+        get: function () {
+          return Default;
+        }
+      }, {
+        key: '_jQueryInterface',
+
+        // static
+
+        value: function _jQueryInterface(config) {
+          return this.each(function () {
+            var data = $(this).data(DATA_KEY);
+            var _config = $.extend({}, Default, $(this).data());
+
+            if (typeof config === 'object') {
+              $.extend(_config, config);
+            }
+
+            var 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 (action) {
+              data[action]();
+            } else if (_config.interval) {
+              data.pause();
+              data.cycle();
+            }
+          });
+        }
+      }, {
+        key: '_dataApiClickHandler',
+        value: function _dataApiClickHandler(event) {
+          var selector = _Util.getSelectorFromElement(this);
+
+          if (!selector) {
+            return;
+          }
+
+          var target = $(selector)[0];
+
+          if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {
+            return;
+          }
+
+          var config = $.extend({}, $(target).data(), $(this).data());
+
+          var 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();
+        }
+      }]);
+
+      return Carousel;
+    })();
+
+    /**
+     * ------------------------------------------------------------------------
+     * Data Api implementation
+     * ------------------------------------------------------------------------
+     */
+
+    $(document).on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler);
+
+    $(window).on(Event.LOAD_DATA_API, function () {
+      $(Selector.DATA_RIDE).each(function () {
+        var $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);
+
+  module.exports = Carousel;
+});
\ No newline at end of file
diff --git a/dist/js/umd/collapse.js b/dist/js/umd/collapse.js
new file mode 100644
index 0000000000000000000000000000000000000000..35c29c984866fbcfb2b3a172081abd9f0f5e7fd9
--- /dev/null
+++ b/dist/js/umd/collapse.js
@@ -0,0 +1,380 @@
+(function (global, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['exports', 'module', './util'], factory);
+  } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
+    factory(exports, module, require('./util'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, mod, global.Util);
+    global.collapse = mod.exports;
+  }
+})(this, function (exports, module, _util) {
+  'use strict';
+
+  var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+  function _interopRequire(obj) { return obj && obj.__esModule ? obj['default'] : obj; }
+
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+  var _Util = _interopRequire(_util);
+
+  /**
+   * --------------------------------------------------------------------------
+   * Bootstrap (v4.0.0): collapse.js
+   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+   * --------------------------------------------------------------------------
+   */
+
+  var Collapse = (function ($) {
+
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+
+    var NAME = 'collapse';
+    var VERSION = '4.0.0';
+    var DATA_KEY = 'bs.collapse';
+    var EVENT_KEY = '.' + DATA_KEY;
+    var DATA_API_KEY = '.data-api';
+    var JQUERY_NO_CONFLICT = $.fn[NAME];
+    var TRANSITION_DURATION = 600;
+
+    var Default = {
+      toggle: true,
+      parent: ''
+    };
+
+    var DefaultType = {
+      toggle: 'boolean',
+      parent: 'string'
+    };
+
+    var 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
+    };
+
+    var ClassName = {
+      IN: 'in',
+      COLLAPSE: 'collapse',
+      COLLAPSING: 'collapsing',
+      COLLAPSED: 'collapsed'
+    };
+
+    var Dimension = {
+      WIDTH: 'width',
+      HEIGHT: 'height'
+    };
+
+    var Selector = {
+      ACTIVES: '.panel > .in, .panel > .collapsing',
+      DATA_TOGGLE: '[data-toggle="collapse"]'
+    };
+
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+    var Collapse = (function () {
+      function Collapse(element, config) {
+        _classCallCheck(this, Collapse);
+
+        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);
+        }
+
+        if (this._config.toggle) {
+          this.toggle();
+        }
+      }
+
+      _createClass(Collapse, [{
+        key: 'toggle',
+
+        // public
+
+        value: function toggle() {
+          if ($(this._element).hasClass(ClassName.IN)) {
+            this.hide();
+          } else {
+            this.show();
+          }
+        }
+      }, {
+        key: 'show',
+        value: function show() {
+          var _this = this;
+
+          if (this._isTransitioning || $(this._element).hasClass(ClassName.IN)) {
+            return;
+          }
+
+          var actives = undefined;
+          var activesData = undefined;
+
+          if (this._parent) {
+            actives = $.makeArray($(Selector.ACTIVES));
+            if (!actives.length) {
+              actives = null;
+            }
+          }
+
+          if (actives) {
+            activesData = $(actives).data(DATA_KEY);
+            if (activesData && activesData._isTransitioning) {
+              return;
+            }
+          }
+
+          var 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);
+            }
+          }
+
+          var 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);
+
+          var complete = function complete() {
+            $(_this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.IN);
+
+            _this._element.style[dimension] = '';
+
+            _this.setTransitioning(false);
+
+            $(_this._element).trigger(Event.SHOWN);
+          };
+
+          if (!_Util.supportsTransitionEnd()) {
+            complete();
+            return;
+          }
+
+          var scrollSize = 'scroll' + (dimension[0].toUpperCase() + dimension.slice(1));
+
+          $(this._element).one(_Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+
+          this._element.style[dimension] = this._element[scrollSize] + 'px';
+        }
+      }, {
+        key: 'hide',
+        value: function hide() {
+          var _this2 = this;
+
+          if (this._isTransitioning || !$(this._element).hasClass(ClassName.IN)) {
+            return;
+          }
+
+          var startEvent = $.Event(Event.HIDE);
+          $(this._element).trigger(startEvent);
+          if (startEvent.isDefaultPrevented()) {
+            return;
+          }
+
+          var dimension = this._getDimension();
+          var offsetDimension = dimension === Dimension.WIDTH ? 'offsetWidth' : 'offsetHeight';
+
+          this._element.style[dimension] = this._element[offsetDimension] + 'px';
+
+          _Util.reflow(this._element);
+
+          $(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.IN);
+
+          this._element.setAttribute('aria-expanded', false);
+
+          if (this._triggerArray.length) {
+            $(this._triggerArray).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);
+          }
+
+          this.setTransitioning(true);
+
+          var complete = function complete() {
+            _this2.setTransitioning(false);
+            $(_this2._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN);
+          };
+
+          this._element.style[dimension] = 0;
+
+          if (!_Util.supportsTransitionEnd()) {
+            return complete();
+          }
+
+          $(this._element).one(_Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+        }
+      }, {
+        key: 'setTransitioning',
+        value: function setTransitioning(isTransitioning) {
+          this._isTransitioning = isTransitioning;
+        }
+      }, {
+        key: 'dispose',
+        value: function dispose() {
+          $.removeData(this._element, DATA_KEY);
+
+          this._config = null;
+          this._parent = null;
+          this._element = null;
+          this._triggerArray = null;
+          this._isTransitioning = null;
+        }
+      }, {
+        key: '_getConfig',
+
+        // private
+
+        value: function _getConfig(config) {
+          config = $.extend({}, Default, config);
+          config.toggle = !!config.toggle; // coerce string values
+          _Util.typeCheckConfig(NAME, config, DefaultType);
+          return config;
+        }
+      }, {
+        key: '_getDimension',
+        value: function _getDimension() {
+          var hasWidth = $(this._element).hasClass(Dimension.WIDTH);
+          return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;
+        }
+      }, {
+        key: '_getParent',
+        value: function _getParent() {
+          var _this3 = this;
+
+          var parent = $(this._config.parent)[0];
+          var selector = '[data-toggle="collapse"][data-parent="' + this._config.parent + '"]';
+
+          $(parent).find(selector).each(function (i, element) {
+            _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
+          });
+
+          return parent;
+        }
+      }, {
+        key: '_addAriaAndCollapsedClass',
+        value: function _addAriaAndCollapsedClass(element, triggerArray) {
+          if (element) {
+            var isOpen = $(element).hasClass(ClassName.IN);
+            element.setAttribute('aria-expanded', isOpen);
+
+            if (triggerArray.length) {
+              $(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
+            }
+          }
+        }
+      }], [{
+        key: 'VERSION',
+
+        // getters
+
+        get: function () {
+          return VERSION;
+        }
+      }, {
+        key: 'Default',
+        get: function () {
+          return Default;
+        }
+      }, {
+        key: '_getTargetFromElement',
+
+        // static
+
+        value: function _getTargetFromElement(element) {
+          var selector = _Util.getSelectorFromElement(element);
+          return selector ? $(selector)[0] : null;
+        }
+      }, {
+        key: '_jQueryInterface',
+        value: function _jQueryInterface(config) {
+          return this.each(function () {
+            var $this = $(this);
+            var data = $this.data(DATA_KEY);
+            var _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') {
+              data[config]();
+            }
+          });
+        }
+      }]);
+
+      return Collapse;
+    })();
+
+    /**
+     * ------------------------------------------------------------------------
+     * Data Api implementation
+     * ------------------------------------------------------------------------
+     */
+
+    $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+      event.preventDefault();
+
+      var target = Collapse._getTargetFromElement(this);
+
+      var data = $(target).data(DATA_KEY);
+      var 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);
+
+  module.exports = Collapse;
+});
\ No newline at end of file
diff --git a/dist/js/umd/dropdown.js b/dist/js/umd/dropdown.js
new file mode 100644
index 0000000000000000000000000000000000000000..86ac7500df38be683d3bad0004e2a63428a1f696
--- /dev/null
+++ b/dist/js/umd/dropdown.js
@@ -0,0 +1,300 @@
+(function (global, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['exports', 'module', './util'], factory);
+  } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
+    factory(exports, module, require('./util'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, mod, global.Util);
+    global.dropdown = mod.exports;
+  }
+})(this, function (exports, module, _util) {
+  'use strict';
+
+  var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+  function _interopRequire(obj) { return obj && obj.__esModule ? obj['default'] : obj; }
+
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+  var _Util = _interopRequire(_util);
+
+  /**
+   * --------------------------------------------------------------------------
+   * Bootstrap (v4.0.0): dropdown.js
+   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+   * --------------------------------------------------------------------------
+   */
+
+  var Dropdown = (function ($) {
+
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+
+    var NAME = 'dropdown';
+    var VERSION = '4.0.0';
+    var DATA_KEY = 'bs.dropdown';
+    var EVENT_KEY = '.' + DATA_KEY;
+    var DATA_API_KEY = '.data-api';
+    var JQUERY_NO_CONFLICT = $.fn[NAME];
+
+    var 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,
+      KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + '' + DATA_API_KEY
+    };
+
+    var ClassName = {
+      BACKDROP: 'dropdown-backdrop',
+      DISABLED: 'disabled',
+      OPEN: 'open'
+    };
+
+    var 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
+     * ------------------------------------------------------------------------
+     */
+
+    var Dropdown = (function () {
+      function Dropdown(element) {
+        _classCallCheck(this, Dropdown);
+
+        this._element = element;
+
+        this._addEventListeners();
+      }
+
+      _createClass(Dropdown, [{
+        key: 'toggle',
+
+        // public
+
+        value: function toggle() {
+          if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+            return;
+          }
+
+          var parent = Dropdown._getParentFromElement(this);
+          var isActive = $(parent).hasClass(ClassName.OPEN);
+
+          Dropdown._clearMenus();
+
+          if (isActive) {
+            return false;
+          }
+
+          if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) {
+
+            // if mobile we use a backdrop because click events don't delegate
+            var dropdown = document.createElement('div');
+            dropdown.className = ClassName.BACKDROP;
+            $(dropdown).insertBefore(this);
+            $(dropdown).on('click', Dropdown._clearMenus);
+          }
+
+          var relatedTarget = { relatedTarget: this };
+          var showEvent = $.Event(Event.SHOW, relatedTarget);
+
+          $(parent).trigger(showEvent);
+
+          if (showEvent.isDefaultPrevented()) {
+            return;
+          }
+
+          this.focus();
+          this.setAttribute('aria-expanded', 'true');
+
+          $(parent).toggleClass(ClassName.OPEN);
+          $(parent).trigger(Event.SHOWN, relatedTarget);
+
+          return false;
+        }
+      }, {
+        key: 'dispose',
+        value: function dispose() {
+          $.removeData(this._element, DATA_KEY);
+          $(this._element).off(EVENT_KEY);
+          this._element = null;
+        }
+      }, {
+        key: '_addEventListeners',
+
+        // private
+
+        value: function _addEventListeners() {
+          $(this._element).on(Event.CLICK, this.toggle);
+        }
+      }], [{
+        key: 'VERSION',
+
+        // getters
+
+        get: function () {
+          return VERSION;
+        }
+      }, {
+        key: '_jQueryInterface',
+
+        // static
+
+        value: function _jQueryInterface(config) {
+          return this.each(function () {
+            var data = $(this).data(DATA_KEY);
+
+            if (!data) {
+              $(this).data(DATA_KEY, data = new Dropdown(this));
+            }
+
+            if (typeof config === 'string') {
+              data[config].call(this);
+            }
+          });
+        }
+      }, {
+        key: '_clearMenus',
+        value: function _clearMenus(event) {
+          if (event && event.which === 3) {
+            return;
+          }
+
+          var backdrop = $(Selector.BACKDROP)[0];
+          if (backdrop) {
+            backdrop.parentNode.removeChild(backdrop);
+          }
+
+          var toggles = $.makeArray($(Selector.DATA_TOGGLE));
+
+          for (var i = 0; i < toggles.length; i++) {
+            var _parent = Dropdown._getParentFromElement(toggles[i]);
+            var relatedTarget = { relatedTarget: toggles[i] };
+
+            if (!$(_parent).hasClass(ClassName.OPEN)) {
+              continue;
+            }
+
+            if (event && event.type === 'click' && /input|textarea/i.test(event.target.tagName) && $.contains(_parent, event.target)) {
+              continue;
+            }
+
+            var hideEvent = $.Event(Event.HIDE, relatedTarget);
+            $(_parent).trigger(hideEvent);
+            if (hideEvent.isDefaultPrevented()) {
+              continue;
+            }
+
+            toggles[i].setAttribute('aria-expanded', 'false');
+
+            $(_parent).removeClass(ClassName.OPEN).trigger(Event.HIDDEN, relatedTarget);
+          }
+        }
+      }, {
+        key: '_getParentFromElement',
+        value: function _getParentFromElement(element) {
+          var parent = undefined;
+          var selector = _Util.getSelectorFromElement(element);
+
+          if (selector) {
+            parent = $(selector)[0];
+          }
+
+          return parent || element.parentNode;
+        }
+      }, {
+        key: '_dataApiKeydownHandler',
+        value: function _dataApiKeydownHandler(event) {
+          if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) {
+            return;
+          }
+
+          event.preventDefault();
+          event.stopPropagation();
+
+          if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+            return;
+          }
+
+          var parent = Dropdown._getParentFromElement(this);
+          var isActive = $(parent).hasClass(ClassName.OPEN);
+
+          if (!isActive && event.which !== 27 || isActive && event.which === 27) {
+
+            if (event.which === 27) {
+              var toggle = $(parent).find(Selector.DATA_TOGGLE)[0];
+              $(toggle).trigger('focus');
+            }
+
+            $(this).trigger('click');
+            return;
+          }
+
+          var items = $.makeArray($(Selector.VISIBLE_ITEMS));
+
+          items = items.filter(function (item) {
+            return item.offsetWidth || item.offsetHeight;
+          });
+
+          if (!items.length) {
+            return;
+          }
+
+          var index = items.indexOf(event.target);
+
+          if (event.which === 38 && index > 0) index--; // up
+          if (event.which === 40 && index < items.length - 1) index++; // down
+          if (! ~index) index = 0;
+
+          items[index].focus();
+        }
+      }]);
+
+      return Dropdown;
+    })();
+
+    /**
+     * ------------------------------------------------------------------------
+     * 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, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (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);
+
+  module.exports = Dropdown;
+});
\ No newline at end of file
diff --git a/dist/js/umd/modal.js b/dist/js/umd/modal.js
new file mode 100644
index 0000000000000000000000000000000000000000..7d419695714ed894032028b35914b36d9f2ef4f7
--- /dev/null
+++ b/dist/js/umd/modal.js
@@ -0,0 +1,548 @@
+(function (global, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['exports', 'module', './util'], factory);
+  } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
+    factory(exports, module, require('./util'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, mod, global.Util);
+    global.modal = mod.exports;
+  }
+})(this, function (exports, module, _util) {
+  'use strict';
+
+  var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+  function _interopRequire(obj) { return obj && obj.__esModule ? obj['default'] : obj; }
+
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+  var _Util = _interopRequire(_util);
+
+  /**
+   * --------------------------------------------------------------------------
+   * Bootstrap (v4.0.0): modal.js
+   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+   * --------------------------------------------------------------------------
+   */
+
+  var Modal = (function ($) {
+
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+
+    var NAME = 'modal';
+    var VERSION = '4.0.0';
+    var DATA_KEY = 'bs.modal';
+    var EVENT_KEY = '.' + DATA_KEY;
+    var DATA_API_KEY = '.data-api';
+    var JQUERY_NO_CONFLICT = $.fn[NAME];
+    var TRANSITION_DURATION = 300;
+    var BACKDROP_TRANSITION_DURATION = 150;
+
+    var Default = {
+      backdrop: true,
+      keyboard: true,
+      focus: true,
+      show: true
+    };
+
+    var DefaultType = {
+      backdrop: '(boolean|string)',
+      keyboard: 'boolean',
+      focus: 'boolean',
+      show: 'boolean'
+    };
+
+    var 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
+    };
+
+    var ClassName = {
+      BACKDROP: 'modal-backdrop',
+      OPEN: 'modal-open',
+      FADE: 'fade',
+      IN: 'in'
+    };
+
+    var Selector = {
+      DIALOG: '.modal-dialog',
+      DATA_TOGGLE: '[data-toggle="modal"]',
+      DATA_DISMISS: '[data-dismiss="modal"]',
+      SCROLLBAR_MEASURER: 'modal-scrollbar-measure'
+    };
+
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+    var Modal = (function () {
+      function Modal(element, config) {
+        _classCallCheck(this, Modal);
+
+        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._originalBodyPadding = 0;
+        this._scrollbarWidth = 0;
+      }
+
+      _createClass(Modal, [{
+        key: 'toggle',
+
+        // public
+
+        value: function toggle(relatedTarget) {
+          return this._isShown ? this.hide() : this.show(relatedTarget);
+        }
+      }, {
+        key: 'show',
+        value: function show(relatedTarget) {
+          var _this = this;
+
+          var showEvent = $.Event(Event.SHOW, {
+            relatedTarget: 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, $.proxy(this.hide, this));
+
+          $(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () {
+            $(_this._element).one(Event.MOUSEUP_DISMISS, function (event) {
+              if ($(event.target).is(_this._element)) {
+                that._ignoreBackdropClick = true;
+              }
+            });
+          });
+
+          this._showBackdrop($.proxy(this._showElement, this, relatedTarget));
+        }
+      }, {
+        key: 'hide',
+        value: function hide(event) {
+          if (event) {
+            event.preventDefault();
+          }
+
+          var 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.IN);
+
+          $(this._element).off(Event.CLICK_DISMISS);
+          $(this._dialog).off(Event.MOUSEDOWN_DISMISS);
+
+          if (_Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
+
+            $(this._element).one(_Util.TRANSITION_END, $.proxy(this._hideModal, this)).emulateTransitionEnd(TRANSITION_DURATION);
+          } else {
+            this._hideModal();
+          }
+        }
+      }, {
+        key: 'dispose',
+        value: function dispose() {
+          $.removeData(this._element, DATA_KEY);
+
+          $(window).off(EVENT_KEY);
+          $(document).off(EVENT_KEY);
+          $(this._element).off(EVENT_KEY);
+          $(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;
+        }
+      }, {
+        key: '_getConfig',
+
+        // private
+
+        value: function _getConfig(config) {
+          config = $.extend({}, Default, config);
+          _Util.typeCheckConfig(NAME, config, DefaultType);
+          return config;
+        }
+      }, {
+        key: '_showElement',
+        value: function _showElement(relatedTarget) {
+          var _this2 = this;
+
+          var 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.scrollTop = 0;
+
+          if (transition) {
+            _Util.reflow(this._element);
+          }
+
+          $(this._element).addClass(ClassName.IN);
+
+          if (this._config.focus) this._enforceFocus();
+
+          var shownEvent = $.Event(Event.SHOWN, {
+            relatedTarget: relatedTarget
+          });
+
+          var transitionComplete = function transitionComplete() {
+            if (_this2._config.focus) _this2._element.focus();
+            $(_this2._element).trigger(shownEvent);
+          };
+
+          if (transition) {
+            $(this._dialog).one(_Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(TRANSITION_DURATION);
+          } else {
+            transitionComplete();
+          }
+        }
+      }, {
+        key: '_enforceFocus',
+        value: function _enforceFocus() {
+          var _this3 = this;
+
+          $(document).off(Event.FOCUSIN) // guard against infinite focus loop
+          .on(Event.FOCUSIN, function (event) {
+            if (_this3._element !== event.target && !$(_this3._element).has(event.target).length) {
+              _this3._element.focus();
+            }
+          });
+        }
+      }, {
+        key: '_setEscapeEvent',
+        value: function _setEscapeEvent() {
+          var _this4 = this;
+
+          if (this._isShown && this._config.keyboard) {
+            $(this._element).on(Event.KEYDOWN_DISMISS, function (event) {
+              if (event.which === 27) {
+                _this4.hide();
+              }
+            });
+          } else if (!this._isShown) {
+            $(this._element).off(Event.KEYDOWN_DISMISS);
+          }
+        }
+      }, {
+        key: '_setResizeEvent',
+        value: function _setResizeEvent() {
+          if (this._isShown) {
+            $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this));
+          } else {
+            $(window).off(Event.RESIZE);
+          }
+        }
+      }, {
+        key: '_hideModal',
+        value: function _hideModal() {
+          var _this5 = this;
+
+          this._element.style.display = 'none';
+          this._showBackdrop(function () {
+            $(document.body).removeClass(ClassName.OPEN);
+            _this5._resetAdjustments();
+            _this5._resetScrollbar();
+            $(_this5._element).trigger(Event.HIDDEN);
+          });
+        }
+      }, {
+        key: '_removeBackdrop',
+        value: function _removeBackdrop() {
+          if (this._backdrop) {
+            $(this._backdrop).remove();
+            this._backdrop = null;
+          }
+        }
+      }, {
+        key: '_showBackdrop',
+        value: function _showBackdrop(callback) {
+          var _this6 = this;
+
+          var animate = $(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : '';
+
+          if (this._isShown && this._config.backdrop) {
+            var doAnimate = _Util.supportsTransitionEnd() && animate;
+
+            this._backdrop = document.createElement('div');
+            this._backdrop.className = ClassName.BACKDROP;
+
+            if (animate) {
+              $(this._backdrop).addClass(animate);
+            }
+
+            $(this._backdrop).appendTo(this.$body);
+
+            $(this._element).on(Event.CLICK_DISMISS, function (event) {
+              if (_this6._ignoreBackdropClick) {
+                _this6._ignoreBackdropClick = false;
+                return;
+              }
+              if (event.target !== event.currentTarget) {
+                return;
+              }
+              if (_this6._config.backdrop === 'static') {
+                _this6._element.focus();
+              } else {
+                _this6.hide();
+              }
+            });
+
+            if (doAnimate) {
+              _Util.reflow(this._backdrop);
+            }
+
+            $(this._backdrop).addClass(ClassName.IN);
+
+            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.IN);
+
+            var callbackRemove = function callbackRemove() {
+              _this6._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();
+          }
+        }
+      }, {
+        key: '_handleUpdate',
+
+        // ----------------------------------------------------------------------
+        // the following methods are used to handle overflowing modals
+        // todo (fat): these should probably be refactored out of modal.js
+        // ----------------------------------------------------------------------
+
+        value: function _handleUpdate() {
+          this._adjustDialog();
+        }
+      }, {
+        key: '_adjustDialog',
+        value: function _adjustDialog() {
+          var 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';
+          }
+        }
+      }, {
+        key: '_resetAdjustments',
+        value: function _resetAdjustments() {
+          this._element.style.paddingLeft = '';
+          this._element.style.paddingRight = '';
+        }
+      }, {
+        key: '_checkScrollbar',
+        value: function _checkScrollbar() {
+          var fullWindowWidth = window.innerWidth;
+          if (!fullWindowWidth) {
+            // workaround for missing window.innerWidth in IE8
+            var documentElementRect = document.documentElement.getBoundingClientRect();
+            fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
+          }
+          this._isBodyOverflowing = document.body.clientWidth < fullWindowWidth;
+          this._scrollbarWidth = this._getScrollbarWidth();
+        }
+      }, {
+        key: '_setScrollbar',
+        value: function _setScrollbar() {
+          var bodyPadding = parseInt($(document.body).css('padding-right') || 0, 10);
+
+          this._originalBodyPadding = document.body.style.paddingRight || '';
+
+          if (this._isBodyOverflowing) {
+            document.body.style.paddingRight = bodyPadding + this._scrollbarWidth + 'px';
+          }
+        }
+      }, {
+        key: '_resetScrollbar',
+        value: function _resetScrollbar() {
+          document.body.style.paddingRight = this._originalBodyPadding;
+        }
+      }, {
+        key: '_getScrollbarWidth',
+        value: function _getScrollbarWidth() {
+          // thx d.walsh
+          var scrollDiv = document.createElement('div');
+          scrollDiv.className = Selector.SCROLLBAR_MEASURER;
+          document.body.appendChild(scrollDiv);
+          var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
+          document.body.removeChild(scrollDiv);
+          return scrollbarWidth;
+        }
+      }], [{
+        key: 'VERSION',
+
+        // getters
+
+        get: function () {
+          return VERSION;
+        }
+      }, {
+        key: 'Default',
+        get: function () {
+          return Default;
+        }
+      }, {
+        key: '_jQueryInterface',
+
+        // static
+
+        value: function _jQueryInterface(config, relatedTarget) {
+          return this.each(function () {
+            var data = $(this).data(DATA_KEY);
+            var _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') {
+              data[config](relatedTarget);
+            } else if (_config.show) {
+              data.show(relatedTarget);
+            }
+          });
+        }
+      }]);
+
+      return Modal;
+    })();
+
+    /**
+     * ------------------------------------------------------------------------
+     * Data Api implementation
+     * ------------------------------------------------------------------------
+     */
+
+    $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+      var _this7 = this;
+
+      var target = undefined;
+      var selector = _Util.getSelectorFromElement(this);
+
+      if (selector) {
+        target = $(selector)[0];
+      }
+
+      var config = $(target).data(DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data());
+
+      if (this.tagName === 'A') {
+        event.preventDefault();
+      }
+
+      var $target = $(target).one(Event.SHOW, function (showEvent) {
+        if (showEvent.isDefaultPrevented()) {
+          // only register focus restorer if modal will actually get shown
+          return;
+        }
+
+        $target.one(Event.HIDDEN, function () {
+          if ($(_this7).is(':visible')) {
+            _this7.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);
+
+  module.exports = Modal;
+});
\ No newline at end of file
diff --git a/dist/js/umd/popover.js b/dist/js/umd/popover.js
new file mode 100644
index 0000000000000000000000000000000000000000..8be0b805660fde2832a87bf4761112a109d36260
--- /dev/null
+++ b/dist/js/umd/popover.js
@@ -0,0 +1,223 @@
+(function (global, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['exports', 'module', './tooltip'], factory);
+  } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
+    factory(exports, module, require('./tooltip'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, mod, global.Tooltip);
+    global.popover = mod.exports;
+  }
+})(this, function (exports, module, _tooltip) {
+  'use strict';
+
+  var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+  function _interopRequire(obj) { return obj && obj.__esModule ? obj['default'] : obj; }
+
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }
+
+  var _Tooltip2 = _interopRequire(_tooltip);
+
+  /**
+   * --------------------------------------------------------------------------
+   * Bootstrap (v4.0.0): popover.js
+   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+   * --------------------------------------------------------------------------
+   */
+
+  var Popover = (function ($) {
+
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+
+    var NAME = 'popover';
+    var VERSION = '4.0.0';
+    var DATA_KEY = 'bs.popover';
+    var EVENT_KEY = '.' + DATA_KEY;
+    var JQUERY_NO_CONFLICT = $.fn[NAME];
+
+    var Default = $.extend({}, _Tooltip2.Default, {
+      placement: 'right',
+      trigger: 'click',
+      content: '',
+      template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-title"></h3>' + '<div class="popover-content"></div></div>'
+    });
+
+    var DefaultType = $.extend({}, _Tooltip2.DefaultType, {
+      content: '(string|function)'
+    });
+
+    var ClassName = {
+      FADE: 'fade',
+      IN: 'in'
+    };
+
+    var Selector = {
+      TITLE: '.popover-title',
+      CONTENT: '.popover-content',
+      ARROW: '.popover-arrow'
+    };
+
+    var 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
+     * ------------------------------------------------------------------------
+     */
+
+    var Popover = (function (_Tooltip) {
+      function Popover() {
+        _classCallCheck(this, Popover);
+
+        if (_Tooltip != null) {
+          _Tooltip.apply(this, arguments);
+        }
+      }
+
+      _inherits(Popover, _Tooltip);
+
+      _createClass(Popover, [{
+        key: 'isWithContent',
+
+        // overrides
+
+        value: function isWithContent() {
+          return this.getTitle() || this._getContent();
+        }
+      }, {
+        key: 'getTipElement',
+        value: function getTipElement() {
+          return this.tip = this.tip || $(this.config.template)[0];
+        }
+      }, {
+        key: 'setContent',
+        value: function setContent() {
+          var tip = this.getTipElement();
+          var title = this.getTitle();
+          var content = this._getContent();
+          var titleElement = $(tip).find(Selector.TITLE)[0];
+
+          if (titleElement) {
+            titleElement[this.config.html ? 'innerHTML' : 'innerText'] = title;
+          }
+
+          // we use append for html objects to maintain js events
+          $(tip).find(Selector.CONTENT).children().detach().end()[this.config.html ? typeof content === 'string' ? 'html' : 'append' : 'text'](content);
+
+          $(tip).removeClass(ClassName.FADE).removeClass(ClassName.IN);
+
+          this.cleanupTether();
+        }
+      }, {
+        key: '_getContent',
+
+        // private
+
+        value: function _getContent() {
+          return this.element.getAttribute('data-content') || (typeof this.config.content == 'function' ? this.config.content.call(this.element) : this.config.content);
+        }
+      }], [{
+        key: 'VERSION',
+
+        // getters
+
+        get: function () {
+          return VERSION;
+        }
+      }, {
+        key: 'Default',
+        get: function () {
+          return Default;
+        }
+      }, {
+        key: 'NAME',
+        get: function () {
+          return NAME;
+        }
+      }, {
+        key: 'DATA_KEY',
+        get: function () {
+          return DATA_KEY;
+        }
+      }, {
+        key: 'Event',
+        get: function () {
+          return Event;
+        }
+      }, {
+        key: 'EVENT_KEY',
+        get: function () {
+          return EVENT_KEY;
+        }
+      }, {
+        key: 'DefaultType',
+        get: function () {
+          return DefaultType;
+        }
+      }, {
+        key: '_jQueryInterface',
+
+        // static
+
+        value: function _jQueryInterface(config) {
+          return this.each(function () {
+            var data = $(this).data(DATA_KEY);
+            var _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') {
+              data[config]();
+            }
+          });
+        }
+      }]);
+
+      return Popover;
+    })(_Tooltip2);
+
+    /**
+     * ------------------------------------------------------------------------
+     * jQuery
+     * ------------------------------------------------------------------------
+     */
+
+    $.fn[NAME] = Popover._jQueryInterface;
+    $.fn[NAME].Constructor = Popover;
+    $.fn[NAME].noConflict = function () {
+      $.fn[NAME] = JQUERY_NO_CONFLICT;
+      return Popover._jQueryInterface;
+    };
+
+    return Popover;
+  })(jQuery);
+
+  module.exports = Popover;
+});
\ No newline at end of file
diff --git a/dist/js/umd/scrollspy.js b/dist/js/umd/scrollspy.js
new file mode 100644
index 0000000000000000000000000000000000000000..feb77672cc05f3a7d242ce2e212824753433f68b
--- /dev/null
+++ b/dist/js/umd/scrollspy.js
@@ -0,0 +1,334 @@
+(function (global, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['exports', 'module', './util'], factory);
+  } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
+    factory(exports, module, require('./util'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, mod, global.Util);
+    global.scrollspy = mod.exports;
+  }
+})(this, function (exports, module, _util) {
+  'use strict';
+
+  var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+  function _interopRequire(obj) { return obj && obj.__esModule ? obj['default'] : obj; }
+
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+  var _Util = _interopRequire(_util);
+
+  /**
+   * --------------------------------------------------------------------------
+   * Bootstrap (v4.0.0): scrollspy.js
+   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+   * --------------------------------------------------------------------------
+   */
+
+  var ScrollSpy = (function ($) {
+
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+
+    var NAME = 'scrollspy';
+    var VERSION = '4.0.0';
+    var DATA_KEY = 'bs.scrollspy';
+    var EVENT_KEY = '.' + DATA_KEY;
+    var DATA_API_KEY = '.data-api';
+    var JQUERY_NO_CONFLICT = $.fn[NAME];
+
+    var Default = {
+      offset: 10,
+      method: 'auto',
+      target: ''
+    };
+
+    var DefaultType = {
+      offset: 'number',
+      method: 'string',
+      target: '(string|element)'
+    };
+
+    var Event = {
+      ACTIVATE: 'activate' + EVENT_KEY,
+      SCROLL: 'scroll' + EVENT_KEY,
+      LOAD_DATA_API: 'load' + EVENT_KEY + '' + DATA_API_KEY
+    };
+
+    var ClassName = {
+      DROPDOWN_MENU: 'dropdown-menu',
+      ACTIVE: 'active'
+    };
+
+    var Selector = {
+      DATA_SPY: '[data-spy="scroll"]',
+      ACTIVE: '.active',
+      LI: 'li',
+      LI_DROPDOWN: 'li.dropdown',
+      NAV_ANCHORS: '.nav li > a'
+    };
+
+    var OffsetMethod = {
+      OFFSET: 'offset',
+      POSITION: 'position'
+    };
+
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+    var ScrollSpy = (function () {
+      function ScrollSpy(element, config) {
+        _classCallCheck(this, ScrollSpy);
+
+        this._element = element;
+        this._scrollElement = element.tagName === 'BODY' ? window : element;
+        this._config = this._getConfig(config);
+        this._selector = '' + this._config.target + ' ' + Selector.NAV_ANCHORS;
+        this._offsets = [];
+        this._targets = [];
+        this._activeTarget = null;
+        this._scrollHeight = 0;
+
+        $(this._scrollElement).on(Event.SCROLL, $.proxy(this._process, this));
+
+        this.refresh();
+        this._process();
+      }
+
+      _createClass(ScrollSpy, [{
+        key: 'refresh',
+
+        // public
+
+        value: function refresh() {
+          var _this = this;
+
+          var autoMethod = this._scrollElement !== this._scrollElement.window ? OffsetMethod.POSITION : OffsetMethod.OFFSET;
+
+          var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
+
+          var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;
+
+          this._offsets = [];
+          this._targets = [];
+
+          this._scrollHeight = this._getScrollHeight();
+
+          var targets = $.makeArray($(this._selector));
+
+          targets.map(function (element) {
+            var target = undefined;
+            var targetSelector = _Util.getSelectorFromElement(element);
+
+            if (targetSelector) {
+              target = $(targetSelector)[0];
+            }
+
+            if (target && (target.offsetWidth || target.offsetHeight)) {
+              // todo (fat): remove sketch reliance on jQuery position/offset
+              return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
+            }
+          }).filter(function (item) {
+            return item;
+          }).sort(function (a, b) {
+            return a[0] - b[0];
+          }).forEach(function (item) {
+            _this._offsets.push(item[0]);
+            _this._targets.push(item[1]);
+          });
+        }
+      }, {
+        key: 'dispose',
+        value: function 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;
+        }
+      }, {
+        key: '_getConfig',
+
+        // private
+
+        value: function _getConfig(config) {
+          config = $.extend({}, Default, config);
+
+          if (typeof config.target !== 'string') {
+            var 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;
+        }
+      }, {
+        key: '_getScrollTop',
+        value: function _getScrollTop() {
+          return this._scrollElement === window ? this._scrollElement.scrollY : this._scrollElement.scrollTop;
+        }
+      }, {
+        key: '_getScrollHeight',
+        value: function _getScrollHeight() {
+          return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
+        }
+      }, {
+        key: '_process',
+        value: function _process() {
+          var scrollTop = this._getScrollTop() + this._config.offset;
+          var scrollHeight = this._getScrollHeight();
+          var maxScroll = this._config.offset + scrollHeight - this._scrollElement.offsetHeight;
+
+          if (this._scrollHeight !== scrollHeight) {
+            this.refresh();
+          }
+
+          if (scrollTop >= maxScroll) {
+            var target = this._targets[this._targets.length - 1];
+
+            if (this._activeTarget !== target) {
+              this._activate(target);
+            }
+          }
+
+          if (this._activeTarget && scrollTop < this._offsets[0]) {
+            this._activeTarget = null;
+            this._clear();
+            return;
+          }
+
+          for (var i = this._offsets.length; i--;) {
+            var 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]);
+            }
+          }
+        }
+      }, {
+        key: '_activate',
+        value: function _activate(target) {
+          this._activeTarget = target;
+
+          this._clear();
+
+          var selector = '' + this._selector + '[data-target="' + target + '"],' + ('' + this._selector + '[href="' + target + '"]');
+
+          // todo (fat): getting all the raw li's up the tree is not great.
+          var parentListItems = $(selector).parents(Selector.LI);
+
+          for (var i = parentListItems.length; i--;) {
+            $(parentListItems[i]).addClass(ClassName.ACTIVE);
+
+            var itemParent = parentListItems[i].parentNode;
+
+            if (itemParent && $(itemParent).hasClass(ClassName.DROPDOWN_MENU)) {
+              var closestDropdown = $(itemParent).closest(Selector.LI_DROPDOWN)[0];
+              $(closestDropdown).addClass(ClassName.ACTIVE);
+            }
+          }
+
+          $(this._scrollElement).trigger(Event.ACTIVATE, {
+            relatedTarget: target
+          });
+        }
+      }, {
+        key: '_clear',
+        value: function _clear() {
+          var activeParents = $(this._selector).parentsUntil(this._config.target, Selector.ACTIVE);
+
+          for (var i = activeParents.length; i--;) {
+            $(activeParents[i]).removeClass(ClassName.ACTIVE);
+          }
+        }
+      }], [{
+        key: 'VERSION',
+
+        // getters
+
+        get: function () {
+          return VERSION;
+        }
+      }, {
+        key: 'Default',
+        get: function () {
+          return Default;
+        }
+      }, {
+        key: '_jQueryInterface',
+
+        // static
+
+        value: function _jQueryInterface(config) {
+          return this.each(function () {
+            var data = $(this).data(DATA_KEY);
+            var _config = typeof config === 'object' && config || null;
+
+            if (!data) {
+              data = new ScrollSpy(this, _config);
+              $(this).data(DATA_KEY, data);
+            }
+
+            if (typeof config === 'string') {
+              data[config]();
+            }
+          });
+        }
+      }]);
+
+      return ScrollSpy;
+    })();
+
+    /**
+     * ------------------------------------------------------------------------
+     * Data Api implementation
+     * ------------------------------------------------------------------------
+     */
+
+    $(window).on(Event.LOAD_DATA_API, function () {
+      var scrollSpys = $.makeArray($(Selector.DATA_SPY));
+
+      for (var i = scrollSpys.length; i--;) {
+        var $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);
+
+  module.exports = ScrollSpy;
+});
\ No newline at end of file
diff --git a/dist/js/umd/tab.js b/dist/js/umd/tab.js
new file mode 100644
index 0000000000000000000000000000000000000000..3fbf4869c0c32ec155ce750e2cf9b1789047cfcd
--- /dev/null
+++ b/dist/js/umd/tab.js
@@ -0,0 +1,292 @@
+(function (global, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['exports', 'module', './util'], factory);
+  } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
+    factory(exports, module, require('./util'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, mod, global.Util);
+    global.tab = mod.exports;
+  }
+})(this, function (exports, module, _util) {
+  'use strict';
+
+  var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+  function _interopRequire(obj) { return obj && obj.__esModule ? obj['default'] : obj; }
+
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+  var _Util = _interopRequire(_util);
+
+  /**
+   * --------------------------------------------------------------------------
+   * Bootstrap (v4.0.0): tab.js
+   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+   * --------------------------------------------------------------------------
+   */
+
+  var Tab = (function ($) {
+
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+
+    var NAME = 'tab';
+    var VERSION = '4.0.0';
+    var DATA_KEY = 'bs.tab';
+    var EVENT_KEY = '.' + DATA_KEY;
+    var DATA_API_KEY = '.data-api';
+    var JQUERY_NO_CONFLICT = $.fn[NAME];
+    var TRANSITION_DURATION = 150;
+
+    var 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
+    };
+
+    var ClassName = {
+      DROPDOWN_MENU: 'dropdown-menu',
+      ACTIVE: 'active',
+      FADE: 'fade',
+      IN: 'in'
+    };
+
+    var Selector = {
+      A: 'a',
+      LI: 'li',
+      LI_DROPDOWN: 'li.dropdown',
+      UL: 'ul:not(.dropdown-menu)',
+      FADE_CHILD: '> .fade',
+      ACTIVE: '.active',
+      ACTIVE_CHILD: '> .active',
+      DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"]',
+      DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu > .active'
+    };
+
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+    var Tab = (function () {
+      function Tab(element) {
+        _classCallCheck(this, Tab);
+
+        this._element = element;
+      }
+
+      _createClass(Tab, [{
+        key: 'show',
+
+        // public
+
+        value: function show() {
+          var _this = this;
+
+          if (this._element.parentNode && this._element.parentNode.nodeType == Node.ELEMENT_NODE && $(this._element).parent().hasClass(ClassName.ACTIVE)) {
+            return;
+          }
+
+          var target = undefined;
+          var previous = undefined;
+          var ulElement = $(this._element).closest(Selector.UL)[0];
+          var selector = _Util.getSelectorFromElement(this._element);
+
+          if (ulElement) {
+            previous = $.makeArray($(ulElement).find(Selector.ACTIVE));
+            previous = previous[previous.length - 1];
+
+            if (previous) {
+              previous = $(previous).find(Selector.A)[0];
+            }
+          }
+
+          var hideEvent = $.Event(Event.HIDE, {
+            relatedTarget: this._element
+          });
+
+          var 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).closest(Selector.LI)[0], ulElement);
+
+          var complete = function complete() {
+            var hiddenEvent = $.Event(Event.HIDDEN, {
+              relatedTarget: _this._element
+            });
+
+            var shownEvent = $.Event(Event.SHOWN, {
+              relatedTarget: previous
+            });
+
+            $(previous).trigger(hiddenEvent);
+            $(_this._element).trigger(shownEvent);
+          };
+
+          if (target) {
+            this._activate(target, target.parentNode, complete);
+          } else {
+            complete();
+          }
+        }
+      }, {
+        key: 'dispose',
+        value: function dispose() {
+          $.removeClass(this._element, DATA_KEY);
+          this._element = null;
+        }
+      }, {
+        key: '_activate',
+
+        // private
+
+        value: function _activate(element, container, callback) {
+          var active = $(container).find(Selector.ACTIVE_CHILD)[0];
+          var isTransitioning = callback && _Util.supportsTransitionEnd() && (active && $(active).hasClass(ClassName.FADE) || !!$(container).find(Selector.FADE_CHILD)[0]);
+
+          var complete = $.proxy(this._transitionComplete, this, element, active, isTransitioning, callback);
+
+          if (active && isTransitioning) {
+            $(active).one(_Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+          } else {
+            complete();
+          }
+
+          if (active) {
+            $(active).removeClass(ClassName.IN);
+          }
+        }
+      }, {
+        key: '_transitionComplete',
+        value: function _transitionComplete(element, active, isTransitioning, callback) {
+          if (active) {
+            $(active).removeClass(ClassName.ACTIVE);
+
+            var dropdownChild = $(active).find(Selector.DROPDOWN_ACTIVE_CHILD)[0];
+            if (dropdownChild) {
+              $(dropdownChild).removeClass(ClassName.ACTIVE);
+            }
+
+            var activeToggle = $(active).find(Selector.DATA_TOGGLE)[0];
+            if (activeToggle) {
+              activeToggle.setAttribute('aria-expanded', false);
+            }
+          }
+
+          $(element).addClass(ClassName.ACTIVE);
+
+          var elementToggle = $(element).find(Selector.DATA_TOGGLE)[0];
+          if (elementToggle) {
+            elementToggle.setAttribute('aria-expanded', true);
+          }
+
+          if (isTransitioning) {
+            _Util.reflow(element);
+            $(element).addClass(ClassName.IN);
+          } else {
+            $(element).removeClass(ClassName.FADE);
+          }
+
+          if (element.parentNode && $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
+
+            var dropdownElement = $(element).closest(Selector.LI_DROPDOWN)[0];
+            if (dropdownElement) {
+              $(dropdownElement).addClass(ClassName.ACTIVE);
+            }
+
+            elementToggle = $(element).find(Selector.DATA_TOGGLE)[0];
+            if (elementToggle) {
+              elementToggle.setAttribute('aria-expanded', true);
+            }
+          }
+
+          if (callback) {
+            callback();
+          }
+        }
+      }], [{
+        key: 'VERSION',
+
+        // getters
+
+        get: function () {
+          return VERSION;
+        }
+      }, {
+        key: '_jQueryInterface',
+
+        // static
+
+        value: function _jQueryInterface(config) {
+          return this.each(function () {
+            var $this = $(this);
+            var data = $this.data(DATA_KEY);
+
+            if (!data) {
+              data = data = new Tab(this);
+              $this.data(DATA_KEY, data);
+            }
+
+            if (typeof config === 'string') {
+              data[config]();
+            }
+          });
+        }
+      }]);
+
+      return Tab;
+    })();
+
+    /**
+     * ------------------------------------------------------------------------
+     * 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);
+
+  module.exports = Tab;
+});
\ No newline at end of file
diff --git a/dist/js/umd/tooltip.js b/dist/js/umd/tooltip.js
new file mode 100644
index 0000000000000000000000000000000000000000..07142ccd335444d0c692dbba42ba1cf28d1edb9a
--- /dev/null
+++ b/dist/js/umd/tooltip.js
@@ -0,0 +1,613 @@
+(function (global, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['exports', 'module', './util'], factory);
+  } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
+    factory(exports, module, require('./util'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, mod, global.Util);
+    global.tooltip = mod.exports;
+  }
+})(this, function (exports, module, _util) {
+  'use strict';
+
+  var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+  function _interopRequire(obj) { return obj && obj.__esModule ? obj['default'] : obj; }
+
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+  var _Util = _interopRequire(_util);
+
+  /**
+   * --------------------------------------------------------------------------
+   * Bootstrap (v4.0.0): tooltip.js
+   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+   * --------------------------------------------------------------------------
+   */
+
+  var Tooltip = (function ($) {
+
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+
+    var NAME = 'tooltip';
+    var VERSION = '4.0.0';
+    var DATA_KEY = 'bs.tooltip';
+    var EVENT_KEY = '.' + DATA_KEY;
+    var JQUERY_NO_CONFLICT = $.fn[NAME];
+    var TRANSITION_DURATION = 150;
+    var CLASS_PREFIX = 'bs-tether';
+
+    var Default = {
+      animation: true,
+      template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div></div>',
+      trigger: 'hover focus',
+      title: '',
+      delay: 0,
+      html: false,
+      selector: false,
+      placement: 'top',
+      offset: '0 0',
+      constraints: []
+    };
+
+    var DefaultType = {
+      animation: 'boolean',
+      template: 'string',
+      title: '(string|function)',
+      trigger: 'string',
+      delay: '(number|object)',
+      html: 'boolean',
+      selector: '(string|boolean)',
+      placement: '(string|function)',
+      offset: 'string',
+      constraints: 'array'
+    };
+
+    var AttachmentMap = {
+      TOP: 'bottom center',
+      RIGHT: 'middle left',
+      BOTTOM: 'top center',
+      LEFT: 'middle right'
+    };
+
+    var HoverState = {
+      IN: 'in',
+      OUT: 'out'
+    };
+
+    var 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
+    };
+
+    var ClassName = {
+      FADE: 'fade',
+      IN: 'in'
+    };
+
+    var Selector = {
+      TOOLTIP: '.tooltip',
+      TOOLTIP_INNER: '.tooltip-inner'
+    };
+
+    var TetherClass = {
+      element: false,
+      enabled: false
+    };
+
+    var Trigger = {
+      HOVER: 'hover',
+      FOCUS: 'focus',
+      CLICK: 'click',
+      MANUAL: 'manual'
+    };
+
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+    var Tooltip = (function () {
+      function Tooltip(element, config) {
+        _classCallCheck(this, Tooltip);
+
+        // private
+        this._isEnabled = true;
+        this._timeout = 0;
+        this._hoverState = '';
+        this._activeTrigger = {};
+        this._tether = null;
+
+        // protected
+        this.element = element;
+        this.config = this._getConfig(config);
+        this.tip = null;
+
+        this._setListeners();
+      }
+
+      _createClass(Tooltip, [{
+        key: 'enable',
+
+        // public
+
+        value: function enable() {
+          this._isEnabled = true;
+        }
+      }, {
+        key: 'disable',
+        value: function disable() {
+          this._isEnabled = false;
+        }
+      }, {
+        key: 'toggleEnabled',
+        value: function toggleEnabled() {
+          this._isEnabled = !this._isEnabled;
+        }
+      }, {
+        key: 'toggle',
+        value: function toggle(event) {
+          var context = this;
+          var dataKey = this.constructor.DATA_KEY;
+
+          if (event) {
+            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 {
+            $(context.getTipElement()).hasClass(ClassName.IN) ? context._leave(null, context) : context._enter(null, context);
+          }
+        }
+      }, {
+        key: 'dispose',
+        value: function dispose() {
+          clearTimeout(this._timeout);
+
+          this.cleanupTether();
+
+          $.removeData(this.element, this.constructor.DATA_KEY);
+
+          $(this.element).off(this.constructor.EVENT_KEY);
+
+          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;
+        }
+      }, {
+        key: 'show',
+        value: function show() {
+          var _this = this;
+
+          var showEvent = $.Event(this.constructor.Event.SHOW);
+
+          if (this.isWithContent() && this._isEnabled) {
+            $(this.element).trigger(showEvent);
+
+            var isInTheDom = $.contains(this.element.ownerDocument.documentElement, this.element);
+
+            if (showEvent.isDefaultPrevented() || !isInTheDom) {
+              return;
+            }
+
+            var tip = this.getTipElement();
+            var 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);
+            }
+
+            var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
+
+            var attachment = this._getAttachment(placement);
+
+            $(tip).data(this.constructor.DATA_KEY, this).appendTo(document.body);
+
+            $(this.element).trigger(this.constructor.Event.INSERTED);
+
+            this._tether = new Tether({
+              element: tip,
+              target: this.element,
+              attachment: attachment,
+              classes: TetherClass,
+              classPrefix: CLASS_PREFIX,
+              offset: this.config.offset,
+              constraints: this.config.constraints
+            });
+
+            _Util.reflow(tip);
+            this._tether.position();
+
+            $(tip).addClass(ClassName.IN);
+
+            var complete = function complete() {
+              var prevHoverState = _this._hoverState;
+              _this._hoverState = null;
+
+              $(_this.element).trigger(_this.constructor.Event.SHOWN);
+
+              if (prevHoverState === HoverState.OUT) {
+                _this._leave(null, _this);
+              }
+            };
+
+            _Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE) ? $(this.tip).one(_Util.TRANSITION_END, complete).emulateTransitionEnd(Tooltip._TRANSITION_DURATION) : complete();
+          }
+        }
+      }, {
+        key: 'hide',
+        value: function hide(callback) {
+          var _this2 = this;
+
+          var tip = this.getTipElement();
+          var hideEvent = $.Event(this.constructor.Event.HIDE);
+          var complete = function complete() {
+            if (_this2._hoverState !== HoverState.IN && tip.parentNode) {
+              tip.parentNode.removeChild(tip);
+            }
+
+            _this2.element.removeAttribute('aria-describedby');
+            $(_this2.element).trigger(_this2.constructor.Event.HIDDEN);
+            _this2.cleanupTether();
+
+            if (callback) {
+              callback();
+            }
+          };
+
+          $(this.element).trigger(hideEvent);
+
+          if (hideEvent.isDefaultPrevented()) {
+            return;
+          }
+
+          $(tip).removeClass(ClassName.IN);
+
+          if (_Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
+
+            $(tip).one(_Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+          } else {
+            complete();
+          }
+
+          this._hoverState = '';
+        }
+      }, {
+        key: 'isWithContent',
+
+        // protected
+
+        value: function isWithContent() {
+          return !!this.getTitle();
+        }
+      }, {
+        key: 'getTipElement',
+        value: function getTipElement() {
+          return this.tip = this.tip || $(this.config.template)[0];
+        }
+      }, {
+        key: 'setContent',
+        value: function setContent() {
+          var tip = this.getTipElement();
+          var title = this.getTitle();
+          var method = this.config.html ? 'innerHTML' : 'innerText';
+
+          $(tip).find(Selector.TOOLTIP_INNER)[0][method] = title;
+
+          $(tip).removeClass(ClassName.FADE).removeClass(ClassName.IN);
+
+          this.cleanupTether();
+        }
+      }, {
+        key: 'getTitle',
+        value: function getTitle() {
+          var 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;
+        }
+      }, {
+        key: 'cleanupTether',
+        value: function cleanupTether() {
+          if (this._tether) {
+            this._tether.destroy();
+
+            // clean up after tether's junk classes
+            // remove after they fix issue
+            // (https://github.com/HubSpot/tether/issues/36)
+            $(this.element).removeClass(this._removeTetherClasses);
+            $(this.tip).removeClass(this._removeTetherClasses);
+          }
+        }
+      }, {
+        key: '_getAttachment',
+
+        // private
+
+        value: function _getAttachment(placement) {
+          return AttachmentMap[placement.toUpperCase()];
+        }
+      }, {
+        key: '_setListeners',
+        value: function _setListeners() {
+          var _this3 = this;
+
+          var triggers = this.config.trigger.split(' ');
+
+          triggers.forEach(function (trigger) {
+            if (trigger === 'click') {
+              $(_this3.element).on(_this3.constructor.Event.CLICK, _this3.config.selector, $.proxy(_this3.toggle, _this3));
+            } else if (trigger !== Trigger.MANUAL) {
+              var eventIn = trigger == Trigger.HOVER ? _this3.constructor.Event.MOUSEENTER : _this3.constructor.Event.FOCUSIN;
+              var eventOut = trigger == Trigger.HOVER ? _this3.constructor.Event.MOUSELEAVE : _this3.constructor.Event.FOCUSOUT;
+
+              $(_this3.element).on(eventIn, _this3.config.selector, $.proxy(_this3._enter, _this3)).on(eventOut, _this3.config.selector, $.proxy(_this3._leave, _this3));
+            }
+          });
+
+          if (this.config.selector) {
+            this.config = $.extend({}, this.config, {
+              trigger: 'manual',
+              selector: ''
+            });
+          } else {
+            this._fixTitle();
+          }
+        }
+      }, {
+        key: '_removeTetherClasses',
+        value: function _removeTetherClasses(i, css) {
+          return ((css.baseVal || css).match(new RegExp('(^|\\s)' + CLASS_PREFIX + '-\\S+', 'g')) || []).join(' ');
+        }
+      }, {
+        key: '_fixTitle',
+        value: function _fixTitle() {
+          var 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', '');
+          }
+        }
+      }, {
+        key: '_enter',
+        value: function _enter(event, context) {
+          var 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.IN) || context._hoverState === HoverState.IN) {
+            context._hoverState = HoverState.IN;
+            return;
+          }
+
+          clearTimeout(context._timeout);
+
+          context._hoverState = HoverState.IN;
+
+          if (!context.config.delay || !context.config.delay.show) {
+            context.show();
+            return;
+          }
+
+          context._timeout = setTimeout(function () {
+            if (context._hoverState === HoverState.IN) {
+              context.show();
+            }
+          }, context.config.delay.show);
+        }
+      }, {
+        key: '_leave',
+        value: function _leave(event, context) {
+          var 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(function () {
+            if (context._hoverState === HoverState.OUT) {
+              context.hide();
+            }
+          }, context.config.delay.hide);
+        }
+      }, {
+        key: '_isWithActiveTrigger',
+        value: function _isWithActiveTrigger() {
+          for (var trigger in this._activeTrigger) {
+            if (this._activeTrigger[trigger]) {
+              return true;
+            }
+          }
+
+          return false;
+        }
+      }, {
+        key: '_getConfig',
+        value: function _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;
+        }
+      }, {
+        key: '_getDelegateConfig',
+        value: function _getDelegateConfig() {
+          var config = {};
+
+          if (this.config) {
+            for (var key in this.config) {
+              var value = this.config[key];
+              if (this.constructor.Default[key] !== value) {
+                config[key] = value;
+              }
+            }
+          }
+
+          return config;
+        }
+      }], [{
+        key: 'VERSION',
+
+        // getters
+
+        get: function () {
+          return VERSION;
+        }
+      }, {
+        key: 'Default',
+        get: function () {
+          return Default;
+        }
+      }, {
+        key: 'NAME',
+        get: function () {
+          return NAME;
+        }
+      }, {
+        key: 'DATA_KEY',
+        get: function () {
+          return DATA_KEY;
+        }
+      }, {
+        key: 'Event',
+        get: function () {
+          return Event;
+        }
+      }, {
+        key: 'EVENT_KEY',
+        get: function () {
+          return EVENT_KEY;
+        }
+      }, {
+        key: 'DefaultType',
+        get: function () {
+          return DefaultType;
+        }
+      }, {
+        key: '_jQueryInterface',
+
+        // static
+
+        value: function _jQueryInterface(config) {
+          return this.each(function () {
+            var data = $(this).data(DATA_KEY);
+            var _config = typeof config === 'object' ? config : null;
+
+            if (!data && /destroy|hide/.test(config)) {
+              return;
+            }
+
+            if (!data) {
+              data = new Tooltip(this, _config);
+              $(this).data(DATA_KEY, data);
+            }
+
+            if (typeof config === 'string') {
+              data[config]();
+            }
+          });
+        }
+      }]);
+
+      return Tooltip;
+    })();
+
+    /**
+     * ------------------------------------------------------------------------
+     * jQuery
+     * ------------------------------------------------------------------------
+     */
+
+    $.fn[NAME] = Tooltip._jQueryInterface;
+    $.fn[NAME].Constructor = Tooltip;
+    $.fn[NAME].noConflict = function () {
+      $.fn[NAME] = JQUERY_NO_CONFLICT;
+      return Tooltip._jQueryInterface;
+    };
+
+    return Tooltip;
+  })(jQuery);
+
+  module.exports = Tooltip;
+});
\ No newline at end of file
diff --git a/dist/js/umd/util.js b/dist/js/umd/util.js
new file mode 100644
index 0000000000000000000000000000000000000000..a813505c840c1f7fde90b80381dbce7ab6bd8a0b
--- /dev/null
+++ b/dist/js/umd/util.js
@@ -0,0 +1,166 @@
+(function (global, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['exports', 'module'], factory);
+  } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
+    factory(exports, module);
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, mod);
+    global.util = mod.exports;
+  }
+})(this, function (exports, module) {
+  /**
+   * --------------------------------------------------------------------------
+   * Bootstrap (v4.0.0): util.js
+   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+   * --------------------------------------------------------------------------
+   */
+
+  'use strict';
+
+  var Util = (function ($) {
+
+    /**
+     * ------------------------------------------------------------------------
+     * Private TransitionEnd Helpers
+     * ------------------------------------------------------------------------
+     */
+
+    var transition = false;
+
+    var 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: function handle(event) {
+          if ($(event.target).is(this)) {
+            return event.handleObj.handler.apply(this, arguments);
+          }
+        }
+      };
+    }
+
+    function transitionEndTest() {
+      if (window.QUnit) {
+        return false;
+      }
+
+      var el = document.createElement('bootstrap');
+
+      for (var name in TransitionEndEvent) {
+        if (el.style[name] !== undefined) {
+          return { end: TransitionEndEvent[name] };
+        }
+      }
+
+      return false;
+    }
+
+    function transitionEndEmulator(duration) {
+      var _this = this;
+
+      var called = false;
+
+      $(this).one(Util.TRANSITION_END, function () {
+        called = true;
+      });
+
+      setTimeout(function () {
+        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
+     * --------------------------------------------------------------------------
+     */
+
+    var Util = {
+
+      TRANSITION_END: 'bsTransitionEnd',
+
+      getUID: function getUID(prefix) {
+        do prefix += ~ ~(Math.random() * 1000000); while (document.getElementById(prefix));
+        return prefix;
+      },
+
+      getSelectorFromElement: function getSelectorFromElement(element) {
+        var selector = element.getAttribute('data-target');
+
+        if (!selector) {
+          selector = element.getAttribute('href') || '';
+          selector = /^#[a-z]/i.test(selector) ? selector : null;
+        }
+
+        return selector;
+      },
+
+      reflow: function reflow(element) {
+        new Function('bs', 'return bs')(element.offsetHeight);
+      },
+
+      triggerTransitionEnd: function triggerTransitionEnd(element) {
+        $(element).trigger(transition.end);
+      },
+
+      supportsTransitionEnd: function supportsTransitionEnd() {
+        return !!transition;
+      },
+
+      typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
+
+        for (var property in configTypes) {
+          var expectedTypes = configTypes[property];
+          var value = config[property];
+          var valueType = undefined;
+
+          if (value && isElement(value)) valueType = 'element';else valueType = 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);
+
+  module.exports = Util;
+});
\ No newline at end of file
diff --git a/docs/assets/css/docs.min.css b/docs/assets/css/docs.min.css
index 96239e4c4121576e71ce1e425ffd019febc5c87a..24ee63e5433e66cf8269f1d3e2d3c8e19abb9a82 100644
--- a/docs/assets/css/docs.min.css
+++ b/docs/assets/css/docs.min.css
@@ -3,4 +3,1256 @@
  * Copyright 2011-2014 Twitter, Inc.
  * Licensed under the Creative Commons Attribution 3.0 Unported License. For
  * details, see http://creativecommons.org/licenses/by/3.0/.
- */.bd-featurette,.bd-footer{border-top:1px solid #eee}.bd-example:after,.bd-header:after{clear:both}.ge,.sd{font-style:italic}.bd-container{position:relative;max-width:62rem;padding:0 1rem 1rem;margin-right:auto;margin-left:auto}@media (min-width:768px){.bd-container{padding:2rem}}@media (min-width:992px){.bd-container{padding:4rem}}.bd-container>table{display:block;width:100%;max-width:100%;overflow-y:auto;margin-bottom:1rem}.bd-container>table>tbody>tr>td,.bd-container>table>tbody>tr>th,.bd-container>table>tfoot>tr>td,.bd-container>table>tfoot>tr>th,.bd-container>table>thead>tr>td,.bd-container>table>thead>tr>th{padding:.75rem;line-height:1.5;vertical-align:top;border:1px solid #eceeef}.bd-container>table td:first-child>code{white-space:nowrap}.bd-content>h2{margin-top:3rem}.bd-content>h3{margin-top:1.5rem}.bd-content>ol li,.bd-content>ul li{margin-bottom:.25rem}@media (min-width:34em){.bd-title{font-size:4rem}.bd-title+p{font-size:1.5rem;font-weight:300}}.bd-sidebar{padding:0;margin-bottom:0;background-color:#fafafa}.bd-sidebar .navbar-toggler{position:absolute;top:1.25rem;right:0;z-index:5}.bd-sidebar .navbar-header{float:none;margin-right:-15px}.bd-sidebar .navbar-collapse{padding:0;border:0}@media (min-width:992px){.bd-docs{margin-left:240px}.bd-sidebar{position:fixed;top:0;bottom:0;left:0;width:240px;overflow-y:auto;border-right:1px solid #eee}}.bd-example,.bd-masthead,.bd-search{position:relative}.bd-sidebar .navbar-brand{display:block;float:none;height:auto;padding:1.75rem 1.25rem;font-size:20px;font-weight:500;line-height:1}.bd-sidebar-brand:focus,.bd-sidebar-brand:hover{text-decoration:none}.bd-search{margin-right:1.25rem;margin-bottom:1.5rem;margin-left:1.25rem}.bd-search .form-control{height:2.45rem;padding-top:.4rem;padding-bottom:.4rem}.bd-search-results{right:0;display:block;padding:0;overflow:hidden;font-size:.9rem}.bd-search-results:empty{display:none}.bd-search-results>li>a{padding-left:.75rem;padding-right:.75rem}.bd-search-results>li:first-child{margin-top:.25rem}.bd-search-results>li:last-child{margin-bottom:.25rem}.bd-search-results>.no-results{padding:.75rem 1rem;color:#7a7a7a;text-align:center}.bd-sidenav{display:none}.active>.bd-sidenav,.bd-toc-link{display:block}.bd-toc-link{padding:.25rem 1.25rem;color:#55595c}.bd-toc-link:focus,.bd-toc-link:hover{color:#0275d8;text-decoration:none}.active>.bd-toc-link{font-weight:500;color:#373a3c}.bd-toc-item.active{margin-top:1rem;margin-bottom:1rem}.bd-toc-item:first-child{margin-top:0}.bd-toc-item:last-child{margin-bottom:2rem}.bd-sidebar .nav>li>a{display:block;padding:.25rem 1.25rem;font-size:90%;color:#99979c}.bd-sidebar .nav>li>a:focus,.bd-sidebar .nav>li>a:hover{color:#0275d8;text-decoration:none;background-color:transparent}.bd-sidebar .nav>.active:focus>a,.bd-sidebar .nav>.active:hover>a,.bd-sidebar .nav>.active>a{font-weight:500;color:#373a3c;background-color:transparent}.bd-sidebar .nav .nav{display:none;padding-bottom:.75rem}.bd-booticon,.bd-sidebar .nav>.active>.nav{display:block}.bd-sidebar .nav .nav>li>a{padding-top:1px;padding-bottom:1px;font-weight:400;padding-top:.125rem;padding-bottom:.125rem;padding-left:2rem;font-size:80%}.bd-sidebar .nav .nav>.active:focus>a,.bd-sidebar .nav .nav>.active:hover>a,.bd-sidebar .nav .nav>.active>a{font-weight:500}.bd-booticon{width:9rem;height:9rem;font-size:6.5rem;line-height:9rem;color:#fff;text-align:center;cursor:default;background-color:#563d7c;border-radius:15%}.bd-brand-logos,.bd-callout,.bd-callout code,.bd-team img,.color-swatch{border-radius:.25rem}.carbonad,.carbonad-tag,.carbonad-text{width:auto!important;height:auto!important}.bd-booticon.inverse{color:#563d7c;background-color:#fff}.bd-booticon.outline{background-color:transparent;border:1px solid #cdbfe3}.bd-nav-home{margin-bottom:0;background-color:#563d7c;border-bottom:0}.bd-nav-home .navbar-brand>a{font-weight:500;color:#fff}.bd-nav-home .nav-link{font-weight:500;color:#cdbfe3}.bd-nav-home .nav-link:focus,.bd-nav-home .nav-link:hover{color:#fff;background-color:rgba(0,0,0,.5)}.bd-header{padding-bottom:.5rem;margin-bottom:1rem;border-bottom:1px solid rgba(255,255,255,.25)}.bd-header:after,.bd-header:before{content:" ";display:table}.bd-header .bd-header-mark{float:left;padding-top:.6em;padding-bottom:.6em;font-size:1.25rem;font-weight:500}.bd-header-nav{float:right}.bd-header-nav .nav-link{float:left}.bd-header-nav .nav-link:hover{background-color:transparent}.bd-masthead{padding:2rem 0;text-align:center}.bd-masthead .bd-booticon{margin:0 auto 2rem;color:#55595c;border-color:#55595c}.bd-masthead h1{font-weight:300;line-height:1}.bd-masthead .lead{margin-left:auto;margin-right:auto;margin-bottom:2rem;font-size:1.25rem}.bd-masthead .version{margin-top:-1rem;margin-bottom:2rem}.bd-masthead .btn{width:100%;padding:1rem 2rem;font-size:1.25rem;font-weight:500;color:#55595c;border-color:#55595c}.bd-masthead .btn:hover{color:#fff;background-color:#55595c}@media (min-width:480px){.bd-masthead .btn{width:auto}}@media (min-width:768px){.bd-masthead{padding:2rem 0 4rem}.bd-header{margin-bottom:4rem}.bd-masthead h1{font-size:4rem}.bd-masthead .lead{font-size:1.5rem}}@media (min-width:992px){.bd-masthead .lead{width:80%;font-size:2rem}}.bd-featurette{padding-top:3rem;padding-bottom:3rem;font-size:1rem;line-height:1.5;color:#555;text-align:center;background-color:#fff}.bd-featurette .highlight,.carbonad{text-align:left}.bd-featurette-title{margin-bottom:.5rem;font-size:2rem;font-weight:400;color:#333}.half-rule{width:6rem;margin:2.5rem auto}.bd-featurette h4{margin-top:1rem;margin-bottom:.5rem;font-weight:400;color:#333}.bd-featurette-img{display:block;margin-bottom:1.25rem;color:#333}.bd-featurette-img:hover{color:#0275d8;text-decoration:none}.bd-featurette-img img{display:block;margin-bottom:1rem}@media (min-width:480px){.bd-featurette .img-responsive{margin-top:2rem}}@media (min-width:768px){.bd-featurette{padding-top:6rem;padding-bottom:6rem}.bd-featurette-title{font-size:2.5rem}.bd-featurette .lead{max-width:80%;margin-right:auto;margin-left:auto}.bd-featurette .img-responsive{margin-top:0}}.bd-featured-sites{margin-right:-1px;margin-left:-1px}.bd-featured-sites .col-xs-6{padding:1px}.bd-featured-sites .img-responsive{margin-top:0}.carbonad{padding:1.25rem!important;margin:0 -1rem 2rem!important;overflow:hidden;font-size:.8rem!important;line-height:1rem!important;color:#55595c!important;background:#f5f5f5!important;border:0!important}.carbonad-img{margin:0!important}.carbonad-tag,.carbonad-text{display:block!important;float:none!important;margin-left:145px!important;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif!important}.carbonad-text{padding-top:0!important}.carbonad-tag{color:inherit!important;text-align:left!important}.anchorjs-link,.bd-brand-item,.bd-example-tooltips,.responsive-utilities td{text-align:center}.carbonad-tag a,.carbonad-text a{color:#55595c!important}.carbonad-tag a:hover,.carbonad-text a:hover{color:#0275d8!important}.carbonad #azcarbon>img{display:none}@media (min-width:34em){.carbonad{width:330px!important;margin:1.5rem auto!important;border-width:1px!important;border-radius:.25rem}.bd-masthead .carbonad{margin:3rem auto 0!important}}@media (min-width:48em){.carbonad{margin-right:0!important;margin-left:0!important}}@media (min-width:62em){.carbonad{float:right;width:330px!important;padding:1rem!important;margin:.5rem 0 1rem 2rem!important}.bd-masthead .carbonad{float:none;margin:0 auto!important}}.bd-footer{padding-top:2rem;margin-top:2rem;font-size:85%;color:#777}.bd-footer-links{padding-left:0;margin-top:20px;color:#999}.bd-footer-links li{display:inline;padding:0 2px}.bd-footer-links li:first-child{padding-left:0}@media (min-width:768px){.bd-featured-sites .col-sm-3:first-child img{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.bd-featured-sites .col-sm-3:last-child img{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.bd-footer p{margin-bottom:0}}.bd-social{margin-bottom:1.5rem;margin-left:-.5rem}.bd-social-buttons{display:inline-block;padding-left:0;margin-bottom:0;list-style:none}.bd-social-buttons li{display:inline-block;padding:.25rem .5rem;line-height:1}.bd-social-buttons .twitter-follow-button{width:225px!important}.bd-social-buttons .twitter-share-button{width:98px!important}.github-btn{overflow:hidden;border:0}.bd-example-row .row{margin-bottom:1rem}.bd-example-row .row>[class^=col-]{padding-top:.75rem;padding-bottom:.75rem;background-color:rgba(86,61,124,.15);border:1px solid rgba(86,61,124,.2)}.bd-example{padding:1rem;margin:1rem -1rem;border:solid #f7f7f9;border-width:.2rem 0 0}.bd-example:after,.bd-example:before{content:" ";display:table}@media (min-width:34em){.bd-example{margin-left:0;margin-right:0;margin-bottom:0;padding:1.5rem;border-width:.2rem}}.bd-example+.highlight{margin-top:-1rem}.bd-example+.zero-clipboard+.highlight{margin-top:0}.bd-example+p{margin-top:2rem}.bd-example .container{width:auto}.bd-example>.alert+.alert,.bd-example>.nav+.nav,.bd-example>.navbar+.navbar,.bd-example>.progress+.btn,.bd-example>.progress+.progress{margin-top:1rem}.bd-example>.dropdown-menu:first-child{position:static;display:block}.bd-example>.table-responsive:last-child>.table,.bd-example>:last-child{margin-bottom:0!important}.bd-example>.close{float:none}.bd-example-type .table .type-info{color:#999;vertical-align:middle}.bd-example-type .table td{padding:1rem 0;border-color:#eee}.bd-example-type .table tr:first-child td{border-top:0}.bd-example-type h1,.bd-example-type h2,.bd-example-type h3,.bd-example-type h4,.bd-example-type h5,.bd-example-type h6{margin:0}.bd-example-bg-classes p{padding:1rem}.bd-example>img+img{margin-left:.5rem}.bd-example>.btn-group{margin-top:.25rem;margin-bottom:.25rem}.bd-example-control-sizing input[type=text]+input[type=text],.bd-example-control-sizing select,.bd-example>.btn-toolbar+.btn-toolbar{margin-top:.5rem}.bd-example-form .input-group{margin-bottom:.5rem}.bd-example>textarea.form-control{resize:vertical}.bd-example>.list-group{max-width:400px}.bd-example .navbar:last-child{margin-bottom:0}.bd-navbar-bottom-example,.bd-navbar-top-example{z-index:1;padding:0;overflow:hidden}.bd-navbar-bottom-example .navbar-header,.bd-navbar-top-example .navbar-header{margin-left:0}.bd-navbar-bottom-example .navbar-fixed-bottom,.bd-navbar-top-example .navbar-fixed-top{position:relative;margin-right:0;margin-left:0}.bd-navbar-top-example{padding-bottom:45px}.bd-navbar-top-example .navbar-fixed-top{top:-1px}.bd-navbar-bottom-example{padding-top:45px}.bd-navbar-bottom-example .navbar-fixed-bottom{bottom:-1px}.bd-navbar-bottom-example .navbar{margin-bottom:0}@media (min-width:768px){.bd-navbar-bottom-example .navbar-fixed-bottom,.bd-navbar-top-example .navbar-fixed-top{position:absolute}}.bd-example .pagination{margin-top:.5rem;margin-bottom:.5rem}.bd-example>.pager{margin-top:0}.bd-example-modal{background-color:#f5f5f5}.bd-example-modal .modal{position:relative;top:auto;right:auto;bottom:auto;left:auto;z-index:1;display:block}.bd-example-modal .modal-dialog{left:auto;margin-right:auto;margin-left:auto}.bd-example>.dropdown>.dropdown-toggle{float:left}.bd-example>.dropdown>.dropdown-menu{position:static;display:block;margin-bottom:.25rem;clear:left}.bd-example-tabs .nav-tabs{margin-bottom:1rem}.bd-example-tooltips>.btn{margin-top:.25rem;margin-bottom:.25rem}.bd-example-popover{padding-bottom:1.5rem;background-color:#f9f9f9}.bd-example-popover .popover{position:relative;display:block;float:left;width:260px;margin:1.25rem}.bd-example-tooltip .tooltip{position:relative;display:inline-block;margin:10px 20px;opacity:1}.scrollspy-example{position:relative;height:200px;margin-top:.5rem;overflow:auto}.bd-example>.center-block:not(img){max-width:200px;padding:.5rem;background-color:#eee}.bd-example>.bg-danger,.bd-example>.bg-info,.bd-example>.bg-primary,.bd-example>.bg-success,.bd-example>.bg-warning{padding:.5rem;margin-top:.5rem;margin-bottom:.5rem}.highlight{padding:1rem;margin:1rem -1rem;background-color:#f7f7f9}@media (min-width:34em){.highlight{padding:1.5rem;margin-right:0;margin-left:0}}.highlight pre{padding:0;margin-top:0;margin-bottom:0;background-color:transparent;border:0}.highlight pre code{font-size:inherit;color:#373a3c}#focusedInput{border-color:#66afe9;outline:0;outline:dotted thin;-webkit-box-shadow:0 0 .5rem rgba(102,175,233,.6);box-shadow:0 0 .5rem rgba(102,175,233,.6)}.table-responsive .highlight pre{white-space:normal}.bd-table th small,.responsive-utilities th small{display:block;font-weight:400;color:#999}.responsive-utilities tbody th{font-weight:400}.responsive-utilities td.is-visible{color:#468847;background-color:#dff0d8!important}.responsive-utilities td.is-hidden{color:#ccc;background-color:#f9f9f9!important}.responsive-utilities-test{margin-top:.25rem}.responsive-utilities-test .col-xs-6{margin-bottom:.5rem}.responsive-utilities-test span{display:block;padding:1rem .5rem;font-size:1rem;font-weight:700;line-height:1.1;text-align:center;border-radius:.25rem}.hidden-on .col-xs-6>.not-visible,.visible-on .col-xs-6>.not-visible{color:#999;border:1px solid #ddd}.hidden-on .col-xs-6 .visible,.visible-on .col-xs-6 .visible{color:#468847;background-color:#dff0d8;border:1px solid #d6e9c6}@media (max-width:33.9em){.hidden-xs-only{display:none!important}}@media (min-width:34em)and (max-width:47.9em){.hidden-sm-only{display:none!important}}@media (min-width:48em)and (max-width:61.9em){.hidden-md-only{display:none!important}}@media (min-width:62em)and (max-width:74.9em){.hidden-lg-only{display:none!important}}@media (min-width:75em){.hidden-xl-only{display:none!important}}.btn-outline{color:#563d7c;background-color:transparent;border-color:#563d7c}.btn-outline:active,.btn-outline:focus,.btn-outline:hover{color:#fff;background-color:#563d7c;border-color:#563d7c}.btn-outline-inverse{color:#fff;background-color:transparent;border-color:#cdbfe3}.btn-outline-inverse:active,.btn-outline-inverse:focus,.btn-outline-inverse:hover{color:#563d7c;text-shadow:none;background-color:#fff;border-color:#fff}.bd-callout{padding:1.25rem;margin-top:1.25rem;margin-bottom:1.25rem;border:1px solid #eee;border-left-width:.25rem}.bd-callout h4{margin-top:0;margin-bottom:.25rem}.bd-callout p:last-child{margin-bottom:0}.bd-callout+.bd-callout{margin-top:-.25rem}.bd-callout-info{border-left-color:#5bc0de}.bd-callout-info h4{color:#5bc0de}.bd-callout-warning{border-left-color:#f0ad4e}.bd-callout-warning h4{color:#f0ad4e}.bd-callout-danger{border-left-color:#d9534f}.bd-callout-danger h4{color:#d9534f}.bd-examples .img-thumbnail{margin-bottom:.75rem}.bd-examples h4{margin-bottom:.25rem}.bd-examples p{margin-bottom:1.25rem}@media (max-width:480px){.bd-examples{margin-right:-.75rem;margin-left:-.75rem}.bd-examples>[class^=col-]{padding-right:.75rem;padding-left:.75rem}}.bd-team .team-member{line-height:2rem;color:#555}.bd-team .team-member:hover{color:#333;text-decoration:none}.bd-team .github-btn{float:right;width:180px;height:1.25rem;margin-top:.25rem}.bd-team img{float:left;width:2rem;margin-right:.5rem}.bd-browser-bugs td p{margin-bottom:0}.bd-browser-bugs th:first-child{width:18%}.bd-brand-logos{display:table;width:100%;margin-bottom:1rem;overflow:hidden;color:#563d7c;background-color:#f9f9f9}.bd-brand-logos .inverse,.color-swatches .bd-purple{background-color:#563d7c}.bd-brand-item{padding:4rem 0}.bd-brand-item+.bd-brand-item{border-top:1px solid #fff}.bd-brand-logos .inverse{color:#fff}.bd-brand-item h1,.bd-brand-item h3{margin-top:0;margin-bottom:0}.bd-brand-item .bd-booticon{margin-right:auto;margin-left:auto}@media (min-width:768px){.bd-brand-item{display:table-cell;width:1%}.bd-brand-item+.bd-brand-item{border-top:0;border-left:1px solid #fff}.bd-brand-item h1{font-size:4rem}}.color-swatches{margin:0 -5px;overflow:hidden}.color-swatch{float:left;width:4rem;height:4rem;margin-right:.25rem;margin-left:.25rem}.color-swatches .bd-purple-light{background-color:#cdbfe3}.color-swatches .bd-purple-lighter{background-color:#e5e1ea}.color-swatches .bd-gray{background-color:#f9f9f9}.zero-clipboard{position:relative;display:none;float:right}.btn-clipboard{position:absolute;top:0;right:0;z-index:10;display:block;padding:.25rem .5rem;font-size:75%;color:#818a91;cursor:pointer;background-color:#eceeef;border-radius:0 .2rem}.btn-clipboard-hover{color:#fff;background-color:#027de7}@media (min-width:768px){.color-swatch{width:6rem;height:6rem}.zero-clipboard{display:block}}.hll{background-color:#ffc}.c{color:#999}.err{color:#A00;background-color:#FAA}.k{color:#069}.o{color:#555}.cm{color:#999}.cp{color:#099}.c1,.cs{color:#999}.gd{background-color:#FCC;border:1px solid #C00}.gr{color:red}.gh{color:#030}.gi{background-color:#CFC;border:1px solid #0C0}.go{color:#AAA}.gp{color:#009}.gu{color:#030}.gt{color:#9C6}.kc,.kd,.kn,.kp,.kr{color:#069}.kt{color:#078}.m{color:#F60}.s{color:#d44950}.na{color:#4f9fcf}.nb{color:#366}.nc{color:#0A8}.no{color:#360}.nd{color:#99F}.ni{color:#999}.ne{color:#C00}.nf{color:#C0F}.nl{color:#99F}.nn{color:#0CF}.nt{color:#2f6f9f}.nv{color:#033}.ow{color:#000}.w{color:#bbb}.mf,.mh,.mi,.mo{color:#F60}.s2,.sb,.sc,.sd,.se,.sh{color:#C30}.si{color:#A00}.sx{color:#C30}.sr{color:#3AA}.s1{color:#C30}.ss{color:#FC3}.bp{color:#366}.vc,.vg,.vi{color:#033}.il{color:#F60}.css .nt+.nt,.css .o,.css .o+.nt{color:#999}@font-face{font-family:anchorjs-icons;src:url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg6v8yoAAAC8AAAAYGNtYXDL8RqdAAABHAAAADxnYXNwAAAAEAAAAVgAAAAIZ2x5Zkm2oNUAAAFgAAABWGhlYWQAHd4cAAACuAAAADZoaGVhB3sECwAAAvAAAAAkaG10eAYAAEcAAAMUAAAADGxvY2EACgCsAAADIAAAAAhtYXhwAAYAcAAAAygAAAAgbmFtZUQXtNYAAANIAAABOXBvc3QAAwAAAAAEhAAAACAAAwQAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAACDmAAPA/8D/wAPAAEAAAAAAAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEACgAAAAGAAQAAQACACDmAP//AAAAIOYA////4RoCAAEAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAIARwAHA7kDeQA2AG0AAAEnLgEiBg8BDgEUFh8BHgMXNy4DLwEuATQ2PwE+ATIWHwEeARQGDwEeAxU3PgE0JicBLgMnBx4DHwEeARQGDwEOASImLwEuATQ2PwEuAzUHDgEUFh8BHgEyNj8BPgE0Ji8BA7kEI1ldWiPaIyQkIwQDBgYGBFAEBwYHAwQTExMT2xMwMjETBBMTExNjBwkGA5gkIyMk/r4DBgYGBFAEBwYHAwQTExMT2xMwMjETBBMTExNjBwkGA5gkIyMkBCNZXVoj2iMkJCMEA3UEJCMjJNojWV1aIwQDBgUFA1ACBQUFAwQUMDIxE9oTExMTBBMxMjATYxAhISIRmSNaXVkj/sYDBgUFA1ACBQUFAwQUMDIxE9oTExMTBBMxMjATYxAhISIRmSNaXVkjBCQjIyTaI1ldWiMEAAEAAAABAABR/4xQXw889QALBAAAAAAAzqNM0wAAAADOo0zTAAAAAAO5A3kAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAABHA7kAAQAAAAAAAAAAAAAAAAAAAAMAAAAAAgAAAAQAAEcAAAAAAAoArAABAAAAAwBuAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIADgBHAAEAAAAAAAMADgAkAAEAAAAAAAQADgBVAAEAAAAAAAUAFgAOAAEAAAAAAAYABwAyAAEAAAAAAAoAKABjAAMAAQQJAAEADgAAAAMAAQQJAAIADgBHAAMAAQQJAAMADgAkAAMAAQQJAAQADgBVAAMAAQQJAAUAFgAOAAMAAQQJAAYADgA5AAMAAQQJAAoAKABjAGkAYwBvAG0AbwBvAG4AVgBlAHIAcwBpAG8AbgAgADAALgAwAGkAYwBvAG0AbwBvAG5pY29tb29uAGkAYwBvAG0AbwBvAG4AUgBlAGcAdQBsAGEAcgBpAGMAbwBtAG8AbwBuAEcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('truetype'),url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAATwAAsAAAAABKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABCAAAAGAAAABgDq/zKmNtYXAAAAFoAAAAPAAAADzL8RqdZ2FzcAAAAaQAAAAIAAAACAAAABBnbHlmAAABrAAAAVgAAAFYSbag1WhlYWQAAAMEAAAANgAAADYAHd4caGhlYQAAAzwAAAAkAAAAJAd7BAtobXR4AAADYAAAAAwAAAAMBgAAR2xvY2EAAANsAAAACAAAAAgACgCsbWF4cAAAA3QAAAAgAAAAIAAGAHBuYW1lAAADlAAAATkAAAE5RBe01nBvc3QAAATQAAAAIAAAACAAAwAAAAMEAAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAg5gADwP/A/8ADwABAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAgAAAAMAAAAUAAMAAQAAABQABAAoAAAABgAEAAEAAgAg5gD//wAAACDmAP///+EaAgABAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAACAEcABwO5A3kANgBtAAABJy4BIgYPAQ4BFBYfAR4DFzcuAy8BLgE0Nj8BPgEyFh8BHgEUBg8BHgMVNz4BNCYnAS4DJwceAx8BHgEUBg8BDgEiJi8BLgE0Nj8BLgM1Bw4BFBYfAR4BMjY/AT4BNCYvAQO5BCNZXVoj2iMkJCMEAwYGBgRQBAcGBwMEExMTE9sTMDIxEwQTExMTYwcJBgOYJCMjJP6+AwYGBgRQBAcGBwMEExMTE9sTMDIxEwQTExMTYwcJBgOYJCMjJAQjWV1aI9ojJCQjBAN1BCQjIyTaI1ldWiMEAwYFBQNQAgUFBQMEFDAyMRPaExMTEwQTMTIwE2MQISEiEZkjWl1ZI/7GAwYFBQNQAgUFBQMEFDAyMRPaExMTEwQTMTIwE2MQISEiEZkjWl1ZIwQkIyMk2iNZXVojBAABAAAAAQAAUf+MUF8PPPUACwQAAAAAAM6jTNMAAAAAzqNM0wAAAAADuQN5AAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAARwO5AAEAAAAAAAAAAAAAAAAAAAADAAAAAAIAAAAEAABHAAAAAAAKAKwAAQAAAAMAbgACAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAA4AAAABAAAAAAACAA4ARwABAAAAAAADAA4AJAABAAAAAAAEAA4AVQABAAAAAAAFABYADgABAAAAAAAGAAcAMgABAAAAAAAKACgAYwADAAEECQABAA4AAAADAAEECQACAA4ARwADAAEECQADAA4AJAADAAEECQAEAA4AVQADAAEECQAFABYADgADAAEECQAGAA4AOQADAAEECQAKACgAYwBpAGMAbwBtAG8AbwBuAFYAZQByAHMAaQBvAG4AIAAwAC4AMABpAGMAbwBtAG8AbwBuaWNvbW9vbgBpAGMAbwBtAG8AbwBuAFIAZQBnAHUAbABhAHIAaQBjAG8AbQBvAG8AbgBHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4AAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format('woff');font-style:normal;font-weight:400}.anchorjs-icon{font-family:anchorjs-icons;font-style:normal;font-variant:normal;font-weight:400;line-height:1;speak:none;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.anchorjs-link{opacity:0;text-decoration:none}.anchorjs-link:focus,:hover>.anchorjs-link{opacity:1;-webkit-transition:color .16s linear;-o-transition:color .16s linear;transition:color .16s linear}.anchorjs-description{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.anchorjs-link{float:left;width:1.2em;height:1em;padding-right:.2em;margin-top:.25em;margin-left:-1.2em;font-size:70%;color:inherit}:hover>.anchorjs-link:hover{color:#0275d8;text-decoration:none}.anchorjs-icon:before{content:'\e600'}@media (max-width:47.9em){.anchorjs-link{display:none}}
\ No newline at end of file
+ */
+.bd-container {
+  position: relative;
+  max-width: 62rem;
+  padding: 0 1rem 1rem;
+  margin-right: auto;
+  margin-left: auto; }
+  @media (min-width: 768px) {
+    .bd-container {
+      padding: 2rem; } }
+  @media (min-width: 992px) {
+    .bd-container {
+      padding: 4rem; } }
+  .bd-container > table {
+    display: block;
+    width: 100%;
+    max-width: 100%;
+    overflow-y: auto;
+    margin-bottom: 1rem; }
+    .bd-container > table > thead > tr > th,
+    .bd-container > table > thead > tr > td,
+    .bd-container > table > tbody > tr > th,
+    .bd-container > table > tbody > tr > td,
+    .bd-container > table > tfoot > tr > th,
+    .bd-container > table > tfoot > tr > td {
+      padding: 0.75rem;
+      line-height: 1.5;
+      vertical-align: top;
+      border: 1px solid #eceeef; }
+    .bd-container > table td:first-child > code {
+      white-space: nowrap; }
+
+.bd-content > h2 {
+  margin-top: 3rem; }
+
+.bd-content > h3 {
+  margin-top: 1.5rem; }
+
+.bd-content > ul li,
+.bd-content > ol li {
+  margin-bottom: .25rem; }
+
+@media (min-width: 34em) {
+  .bd-title {
+    font-size: 4rem; }
+    .bd-title + p {
+      font-size: 1.5rem;
+      font-weight: 300; } }
+
+.bd-sidebar {
+  padding: 0;
+  margin-bottom: 0;
+  background-color: #fafafa; }
+  .bd-sidebar .navbar-toggler {
+    position: absolute;
+    top: 1.25rem;
+    right: 0;
+    z-index: 5; }
+
+.bd-sidebar .navbar-header {
+  float: none;
+  margin-right: -15px; }
+
+.bd-sidebar .navbar-collapse {
+  padding: 0;
+  border: 0; }
+
+@media (min-width: 992px) {
+  .bd-docs {
+    margin-left: 240px; }
+  .bd-sidebar {
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    width: 240px;
+    overflow-y: auto;
+    border-right: 1px solid #eee; } }
+
+.bd-sidebar .navbar-brand {
+  display: block;
+  float: none;
+  height: auto;
+  padding: 1.75rem 1.25rem;
+  font-size: 20px;
+  font-weight: 500;
+  line-height: 1; }
+
+.bd-sidebar-brand:hover,
+.bd-sidebar-brand:focus {
+  text-decoration: none; }
+
+.bd-search {
+  position: relative;
+  margin-right: 1.25rem;
+  margin-bottom: 1.5rem;
+  margin-left: 1.25rem; }
+  .bd-search .form-control {
+    height: 2.45rem;
+    padding-top: .4rem;
+    padding-bottom: .4rem; }
+
+.bd-search-results {
+  right: 0;
+  display: block;
+  padding: 0;
+  overflow: hidden;
+  font-size: .9rem; }
+  .bd-search-results:empty {
+    display: none; }
+  .bd-search-results > li > a {
+    padding-left: .75rem;
+    padding-right: .75rem; }
+  .bd-search-results > li:first-child {
+    margin-top: .25rem; }
+  .bd-search-results > li:last-child {
+    margin-bottom: .25rem; }
+  .bd-search-results > .no-results {
+    padding: 0.75rem 1rem;
+    color: #7a7a7a;
+    text-align: center; }
+
+.bd-sidenav {
+  display: none; }
+
+.bd-toc-link {
+  display: block;
+  padding: 0.25rem 1.25rem;
+  color: #55595c; }
+
+.bd-toc-link:hover,
+.bd-toc-link:focus {
+  color: #0275d8;
+  text-decoration: none; }
+
+.active > .bd-toc-link {
+  font-weight: 500;
+  color: #373a3c; }
+
+.active > .bd-sidenav {
+  display: block; }
+
+.bd-toc-item.active {
+  margin-top: 1rem;
+  margin-bottom: 1rem; }
+
+.bd-toc-item:first-child {
+  margin-top: 0; }
+
+.bd-toc-item:last-child {
+  margin-bottom: 2rem; }
+
+.bd-sidebar .nav > li > a {
+  display: block;
+  padding: 0.25rem 1.25rem;
+  font-size: 90%;
+  color: #99979c; }
+
+.bd-sidebar .nav > li > a:hover,
+.bd-sidebar .nav > li > a:focus {
+  color: #0275d8;
+  text-decoration: none;
+  background-color: transparent; }
+
+.bd-sidebar .nav > .active > a,
+.bd-sidebar .nav > .active:hover > a,
+.bd-sidebar .nav > .active:focus > a {
+  font-weight: 500;
+  color: #373a3c;
+  background-color: transparent; }
+
+.bd-sidebar .nav .nav {
+  display: none;
+  padding-bottom: .75rem; }
+
+.bd-sidebar .nav .nav > li > a {
+  padding-top: 1px;
+  padding-bottom: 1px;
+  padding-left: 2rem;
+  font-size: 75%;
+  font-weight: normal; }
+
+.bd-sidebar .nav .nav > .active > a,
+.bd-sidebar .nav .nav > .active:hover > a,
+.bd-sidebar .nav .nav > .active:focus > a {
+  font-weight: 500; }
+
+.bd-sidebar .nav > .active > .nav {
+  display: block; }
+
+.bd-sidebar .nav .nav > li > a {
+  padding-top: .125rem;
+  padding-bottom: .125rem;
+  padding-left: 2rem;
+  font-size: 80%; }
+
+.bd-booticon {
+  display: block;
+  width: 9rem;
+  height: 9rem;
+  font-size: 6.5rem;
+  line-height: 9rem;
+  color: #fff;
+  text-align: center;
+  cursor: default;
+  background-color: #563d7c;
+  border-radius: 15%; }
+  .bd-booticon.inverse {
+    color: #563d7c;
+    background-color: #fff; }
+  .bd-booticon.outline {
+    background-color: transparent;
+    border: 1px solid #cdbfe3; }
+
+.bd-nav-home {
+  margin-bottom: 0;
+  background-color: #563d7c;
+  border-bottom: 0; }
+  .bd-nav-home .navbar-brand > a {
+    font-weight: 500;
+    color: #fff; }
+  .bd-nav-home .nav-link {
+    font-weight: 500;
+    color: #cdbfe3; }
+    .bd-nav-home .nav-link:hover,
+    .bd-nav-home .nav-link:focus {
+      color: #fff;
+      background-color: rgba(0, 0, 0, 0.5); }
+
+.bd-header {
+  padding-bottom: .5rem;
+  margin-bottom: 1rem;
+  border-bottom: 1px solid rgba(255, 255, 255, 0.25); }
+  .bd-header:before,
+  .bd-header:after {
+    content: " ";
+    display: table; }
+  .bd-header:after {
+    clear: both; }
+  .bd-header .bd-header-mark {
+    float: left;
+    padding-top: .6em;
+    padding-bottom: .6em;
+    font-size: 1.25rem;
+    font-weight: 500; }
+
+.bd-header-nav {
+  float: right; }
+  .bd-header-nav .nav-link {
+    float: left; }
+    .bd-header-nav .nav-link:hover {
+      background-color: transparent; }
+
+.bd-masthead {
+  position: relative;
+  padding: 2rem 0;
+  text-align: center; }
+
+.bd-masthead .bd-booticon {
+  margin: 0 auto 2rem;
+  color: #55595c;
+  border-color: #55595c; }
+
+.bd-masthead h1 {
+  font-weight: 300;
+  line-height: 1; }
+
+.bd-masthead .lead {
+  margin-left: auto;
+  margin-right: auto;
+  margin-bottom: 2rem;
+  font-size: 1.25rem; }
+
+.bd-masthead .version {
+  margin-top: -1rem;
+  margin-bottom: 2rem; }
+
+.bd-masthead .btn {
+  width: 100%;
+  padding: 1rem 2rem;
+  font-size: 1.25rem;
+  font-weight: 500;
+  color: #55595c;
+  border-color: #55595c; }
+  .bd-masthead .btn:hover {
+    color: #fff;
+    background-color: #55595c; }
+
+@media (min-width: 480px) {
+  .bd-masthead .btn {
+    width: auto; } }
+
+@media (min-width: 768px) {
+  .bd-masthead {
+    padding: 2rem 0 4rem; }
+  .bd-header {
+    margin-bottom: 4rem; }
+  .bd-masthead h1 {
+    font-size: 4rem; }
+  .bd-masthead .lead {
+    font-size: 1.5rem; } }
+
+@media (min-width: 992px) {
+  .bd-masthead .lead {
+    width: 80%;
+    font-size: 2rem; } }
+
+.bd-featurette {
+  padding-top: 3rem;
+  padding-bottom: 3rem;
+  font-size: 1rem;
+  line-height: 1.5;
+  color: #555;
+  text-align: center;
+  background-color: #fff;
+  border-top: 1px solid #eee; }
+  .bd-featurette .highlight {
+    text-align: left; }
+
+.bd-featurette-title {
+  margin-bottom: .5rem;
+  font-size: 2rem;
+  font-weight: normal;
+  color: #333; }
+
+.half-rule {
+  width: 6rem;
+  margin: 2.5rem auto; }
+
+.bd-featurette h4 {
+  margin-top: 1rem;
+  margin-bottom: .5rem;
+  font-weight: normal;
+  color: #333; }
+
+.bd-featurette-img {
+  display: block;
+  margin-bottom: 1.25rem;
+  color: #333; }
+
+.bd-featurette-img:hover {
+  color: #0275d8;
+  text-decoration: none; }
+
+.bd-featurette-img img {
+  display: block;
+  margin-bottom: 1rem; }
+
+@media (min-width: 480px) {
+  .bd-featurette .img-responsive {
+    margin-top: 2rem; } }
+
+@media (min-width: 768px) {
+  .bd-featurette {
+    padding-top: 6rem;
+    padding-bottom: 6rem; }
+  .bd-featurette-title {
+    font-size: 2.5rem; }
+  .bd-featurette .lead {
+    max-width: 80%;
+    margin-right: auto;
+    margin-left: auto; }
+  .bd-featurette .img-responsive {
+    margin-top: 0; } }
+
+.bd-featured-sites {
+  margin-right: -1px;
+  margin-left: -1px; }
+
+.bd-featured-sites .col-xs-6 {
+  padding: 1px; }
+
+.bd-featured-sites .img-responsive {
+  margin-top: 0; }
+
+@media (min-width: 768px) {
+  .bd-featured-sites .col-sm-3:first-child img {
+    border-top-left-radius: .25rem;
+    border-bottom-left-radius: .25rem; }
+  .bd-featured-sites .col-sm-3:last-child img {
+    border-top-right-radius: .25rem;
+    border-bottom-right-radius: .25rem; } }
+
+.carbonad {
+  width: auto !important;
+  height: auto !important;
+  padding: 1.25rem !important;
+  margin: 0 -1rem 2rem !important;
+  overflow: hidden;
+  /* clearfix */
+  font-size: .8rem !important;
+  line-height: 1rem !important;
+  color: #55595c !important;
+  text-align: left;
+  background: #f5f5f5 !important;
+  border: 0 !important; }
+
+.carbonad-img {
+  margin: 0 !important; }
+
+.carbonad-text,
+.carbonad-tag {
+  display: block !important;
+  float: none !important;
+  width: auto !important;
+  height: auto !important;
+  margin-left: 145px !important;
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !important; }
+
+.carbonad-text {
+  padding-top: 0 !important; }
+
+.carbonad-tag {
+  color: inherit !important;
+  text-align: left !important; }
+
+.carbonad-text a,
+.carbonad-tag a {
+  color: #55595c !important; }
+  .carbonad-text a:hover,
+  .carbonad-tag a:hover {
+    color: #0275d8 !important; }
+
+.carbonad #azcarbon > img {
+  display: none; }
+
+@media (min-width: 34em) {
+  .carbonad {
+    width: 330px !important;
+    margin: 1.5rem auto !important;
+    border-width: 1px !important;
+    border-radius: .25rem; }
+  .bd-masthead .carbonad {
+    margin: 3rem auto 0 !important; } }
+
+@media (min-width: 48em) {
+  .carbonad {
+    margin-right: 0 !important;
+    margin-left: 0 !important; } }
+
+@media (min-width: 62em) {
+  .carbonad {
+    float: right;
+    width: 330px !important;
+    padding: 1rem !important;
+    margin: 0.5rem 0 1rem 2rem !important; }
+  .bd-masthead .carbonad {
+    float: none;
+    margin: 0 auto !important; } }
+
+.bd-footer {
+  padding-top: 2rem;
+  margin-top: 2rem;
+  font-size: 85%;
+  color: #777;
+  border-top: 1px solid #eee; }
+
+.bd-footer-links {
+  padding-left: 0;
+  margin-top: 20px;
+  color: #999; }
+
+.bd-footer-links li {
+  display: inline;
+  padding: 0 2px; }
+
+.bd-footer-links li:first-child {
+  padding-left: 0; }
+
+@media (min-width: 768px) {
+  .bd-footer p {
+    margin-bottom: 0; } }
+
+.bd-social {
+  margin-bottom: 1.5rem;
+  margin-left: -.5rem; }
+
+.bd-social-buttons {
+  display: inline-block;
+  padding-left: 0;
+  margin-bottom: 0;
+  list-style: none; }
+
+.bd-social-buttons li {
+  display: inline-block;
+  padding: 0.25rem 0.5rem;
+  line-height: 1; }
+
+.bd-social-buttons .twitter-follow-button {
+  width: 225px !important; }
+
+.bd-social-buttons .twitter-share-button {
+  width: 98px !important; }
+
+.github-btn {
+  overflow: hidden;
+  border: 0; }
+
+.bd-example-row .row {
+  margin-bottom: 1rem; }
+  .bd-example-row .row > [class^="col-"] {
+    padding-top: .75rem;
+    padding-bottom: .75rem;
+    background-color: rgba(86, 61, 124, 0.15);
+    border: 1px solid rgba(86, 61, 124, 0.2); }
+
+.bd-example {
+  position: relative;
+  padding: 1rem;
+  margin: 1rem -1rem;
+  border: solid #f7f7f9;
+  border-width: .2rem 0 0; }
+  .bd-example:before,
+  .bd-example:after {
+    content: " ";
+    display: table; }
+  .bd-example:after {
+    clear: both; }
+  @media (min-width: 34em) {
+    .bd-example {
+      margin-left: 0;
+      margin-right: 0;
+      margin-bottom: 0;
+      padding: 1.5rem;
+      border-width: .2rem; } }
+  .bd-example + .highlight {
+    margin-top: -1rem; }
+  .bd-example + .zero-clipboard + .highlight {
+    margin-top: 0; }
+  .bd-example + p {
+    margin-top: 2rem; }
+  .bd-example .container {
+    width: auto; }
+  .bd-example > .nav + .nav,
+  .bd-example > .alert + .alert,
+  .bd-example > .navbar + .navbar,
+  .bd-example > .progress + .progress,
+  .bd-example > .progress + .btn {
+    margin-top: 1rem; }
+  .bd-example > .dropdown-menu:first-child {
+    position: static;
+    display: block; }
+
+.bd-example > *:last-child,
+.bd-example > .table-responsive:last-child > .table {
+  margin-bottom: 0 !important; }
+
+.bd-example > .close {
+  float: none; }
+
+.bd-example-type .table .type-info {
+  color: #999;
+  vertical-align: middle; }
+
+.bd-example-type .table td {
+  padding: 1rem 0;
+  border-color: #eee; }
+
+.bd-example-type .table tr:first-child td {
+  border-top: 0; }
+
+.bd-example-type h1,
+.bd-example-type h2,
+.bd-example-type h3,
+.bd-example-type h4,
+.bd-example-type h5,
+.bd-example-type h6 {
+  margin: 0; }
+
+.bd-example-bg-classes p {
+  padding: 1rem; }
+
+.bd-example > img + img {
+  margin-left: .5rem; }
+
+.bd-example > .btn-group {
+  margin-top: .25rem;
+  margin-bottom: .25rem; }
+
+.bd-example > .btn-toolbar + .btn-toolbar {
+  margin-top: .5rem; }
+
+.bd-example-control-sizing select,
+.bd-example-control-sizing input[type="text"] + input[type="text"] {
+  margin-top: .5rem; }
+
+.bd-example-form .input-group {
+  margin-bottom: .5rem; }
+
+.bd-example > textarea.form-control {
+  resize: vertical; }
+
+.bd-example > .list-group {
+  max-width: 400px; }
+
+.bd-example .navbar:last-child {
+  margin-bottom: 0; }
+
+.bd-navbar-top-example,
+.bd-navbar-bottom-example {
+  z-index: 1;
+  padding: 0;
+  overflow: hidden; }
+
+.bd-navbar-top-example .navbar-header,
+.bd-navbar-bottom-example .navbar-header {
+  margin-left: 0; }
+
+.bd-navbar-top-example .navbar-fixed-top,
+.bd-navbar-bottom-example .navbar-fixed-bottom {
+  position: relative;
+  margin-right: 0;
+  margin-left: 0; }
+
+.bd-navbar-top-example {
+  padding-bottom: 45px; }
+
+.bd-navbar-top-example .navbar-fixed-top {
+  top: -1px; }
+
+.bd-navbar-bottom-example {
+  padding-top: 45px; }
+
+.bd-navbar-bottom-example .navbar-fixed-bottom {
+  bottom: -1px; }
+
+.bd-navbar-bottom-example .navbar {
+  margin-bottom: 0; }
+
+@media (min-width: 768px) {
+  .bd-navbar-top-example .navbar-fixed-top,
+  .bd-navbar-bottom-example .navbar-fixed-bottom {
+    position: absolute; } }
+
+.bd-example .pagination {
+  margin-top: .5rem;
+  margin-bottom: .5rem; }
+
+.bd-example > .pager {
+  margin-top: 0; }
+
+.bd-example-modal {
+  background-color: #f5f5f5; }
+
+.bd-example-modal .modal {
+  position: relative;
+  top: auto;
+  right: auto;
+  bottom: auto;
+  left: auto;
+  z-index: 1;
+  display: block; }
+
+.bd-example-modal .modal-dialog {
+  left: auto;
+  margin-right: auto;
+  margin-left: auto; }
+
+.bd-example > .dropdown > .dropdown-toggle {
+  float: left; }
+
+.bd-example > .dropdown > .dropdown-menu {
+  position: static;
+  display: block;
+  margin-bottom: .25rem;
+  clear: left; }
+
+.bd-example-tabs .nav-tabs {
+  margin-bottom: 1rem; }
+
+.bd-example-tooltips {
+  text-align: center; }
+
+.bd-example-tooltips > .btn {
+  margin-top: .25rem;
+  margin-bottom: .25rem; }
+
+.bd-example-popover {
+  padding-bottom: 1.5rem;
+  background-color: #f9f9f9; }
+
+.bd-example-popover .popover {
+  position: relative;
+  display: block;
+  float: left;
+  width: 260px;
+  margin: 1.25rem; }
+
+.bd-example-tooltip .tooltip {
+  position: relative;
+  display: inline-block;
+  margin: 10px 20px;
+  opacity: 1; }
+
+.scrollspy-example {
+  position: relative;
+  height: 200px;
+  margin-top: .5rem;
+  overflow: auto; }
+
+.bd-example > .center-block:not(img) {
+  max-width: 200px;
+  padding: .5rem;
+  background-color: #eee; }
+
+.bd-example > .bg-primary,
+.bd-example > .bg-success,
+.bd-example > .bg-info,
+.bd-example > .bg-warning,
+.bd-example > .bg-danger {
+  padding: .5rem;
+  margin-top: .5rem;
+  margin-bottom: .5rem; }
+
+.highlight {
+  padding: 1rem;
+  margin: 1rem -1rem;
+  background-color: #f7f7f9; }
+  @media (min-width: 34em) {
+    .highlight {
+      padding: 1.5rem;
+      margin-right: 0;
+      margin-left: 0; } }
+
+.highlight pre {
+  padding: 0;
+  margin-top: 0;
+  margin-bottom: 0;
+  background-color: transparent;
+  border: 0; }
+
+.highlight pre code {
+  font-size: inherit;
+  color: #373a3c; }
+
+#focusedInput {
+  border-color: #66afe9;
+  outline: 0;
+  outline: thin dotted \9;
+  box-shadow: 0 0 0.5rem rgba(102, 175, 233, 0.6); }
+
+.table-responsive .highlight pre {
+  white-space: normal; }
+
+.bd-table th small,
+.responsive-utilities th small {
+  display: block;
+  font-weight: normal;
+  color: #999; }
+
+.responsive-utilities tbody th {
+  font-weight: normal; }
+
+.responsive-utilities td {
+  text-align: center; }
+
+.responsive-utilities td.is-visible {
+  color: #468847;
+  background-color: #dff0d8 !important; }
+
+.responsive-utilities td.is-hidden {
+  color: #ccc;
+  background-color: #f9f9f9 !important; }
+
+.responsive-utilities-test {
+  margin-top: .25rem; }
+
+.responsive-utilities-test .col-xs-6 {
+  margin-bottom: .5rem; }
+
+.responsive-utilities-test span {
+  display: block;
+  padding: 1rem 0.5rem;
+  font-size: 1rem;
+  font-weight: bold;
+  line-height: 1.1;
+  text-align: center;
+  border-radius: .25rem; }
+
+.visible-on .col-xs-6 > .not-visible,
+.hidden-on .col-xs-6 > .not-visible {
+  color: #999;
+  border: 1px solid #ddd; }
+
+.visible-on .col-xs-6 .visible,
+.hidden-on .col-xs-6 .visible {
+  color: #468847;
+  background-color: #dff0d8;
+  border: 1px solid #d6e9c6; }
+
+@media (max-width: 33.9em) {
+  .hidden-xs-only {
+    display: none !important; } }
+
+@media (min-width: 34em) and (max-width: 47.9em) {
+  .hidden-sm-only {
+    display: none !important; } }
+
+@media (min-width: 48em) and (max-width: 61.9em) {
+  .hidden-md-only {
+    display: none !important; } }
+
+@media (min-width: 62em) and (max-width: 74.9em) {
+  .hidden-lg-only {
+    display: none !important; } }
+
+@media (min-width: 75em) {
+  .hidden-xl-only {
+    display: none !important; } }
+
+.btn-outline {
+  color: #563d7c;
+  background-color: transparent;
+  border-color: #563d7c; }
+  .btn-outline:hover,
+  .btn-outline:focus,
+  .btn-outline:active {
+    color: #fff;
+    background-color: #563d7c;
+    border-color: #563d7c; }
+
+.btn-outline-inverse {
+  color: #fff;
+  background-color: transparent;
+  border-color: #cdbfe3; }
+  .btn-outline-inverse:hover,
+  .btn-outline-inverse:focus,
+  .btn-outline-inverse:active {
+    color: #563d7c;
+    text-shadow: none;
+    background-color: #fff;
+    border-color: #fff; }
+
+.bd-callout {
+  padding: 1.25rem;
+  margin-top: 1.25rem;
+  margin-bottom: 1.25rem;
+  border: 1px solid #eee;
+  border-left-width: .25rem;
+  border-radius: .25rem; }
+
+.bd-callout h4 {
+  margin-top: 0;
+  margin-bottom: .25rem; }
+
+.bd-callout p:last-child {
+  margin-bottom: 0; }
+
+.bd-callout code {
+  border-radius: .25rem; }
+
+.bd-callout + .bd-callout {
+  margin-top: -.25rem; }
+
+.bd-callout-info {
+  border-left-color: #5bc0de; }
+  .bd-callout-info h4 {
+    color: #5bc0de; }
+
+.bd-callout-warning {
+  border-left-color: #f0ad4e; }
+  .bd-callout-warning h4 {
+    color: #f0ad4e; }
+
+.bd-callout-danger {
+  border-left-color: #d9534f; }
+  .bd-callout-danger h4 {
+    color: #d9534f; }
+
+.bd-examples .img-thumbnail {
+  margin-bottom: .75rem; }
+
+.bd-examples h4 {
+  margin-bottom: .25rem; }
+
+.bd-examples p {
+  margin-bottom: 1.25rem; }
+
+@media (max-width: 480px) {
+  .bd-examples {
+    margin-right: -.75rem;
+    margin-left: -.75rem; }
+  .bd-examples > [class^="col-"] {
+    padding-right: .75rem;
+    padding-left: .75rem; } }
+
+.bd-team .team-member {
+  line-height: 2rem;
+  color: #555; }
+
+.bd-team .team-member:hover {
+  color: #333;
+  text-decoration: none; }
+
+.bd-team .github-btn {
+  float: right;
+  width: 180px;
+  height: 1.25rem;
+  margin-top: .25rem; }
+
+.bd-team img {
+  float: left;
+  width: 2rem;
+  margin-right: .5rem;
+  border-radius: .25rem; }
+
+.bd-browser-bugs td p {
+  margin-bottom: 0; }
+
+.bd-browser-bugs th:first-child {
+  width: 18%; }
+
+.bd-brand-logos {
+  display: table;
+  width: 100%;
+  margin-bottom: 1rem;
+  overflow: hidden;
+  color: #563d7c;
+  background-color: #f9f9f9;
+  border-radius: .25rem; }
+
+.bd-brand-item {
+  padding: 4rem 0;
+  text-align: center; }
+
+.bd-brand-item + .bd-brand-item {
+  border-top: 1px solid #fff; }
+
+.bd-brand-logos .inverse {
+  color: #fff;
+  background-color: #563d7c; }
+
+.bd-brand-item h1,
+.bd-brand-item h3 {
+  margin-top: 0;
+  margin-bottom: 0; }
+
+.bd-brand-item .bd-booticon {
+  margin-right: auto;
+  margin-left: auto; }
+
+@media (min-width: 768px) {
+  .bd-brand-item {
+    display: table-cell;
+    width: 1%; }
+  .bd-brand-item + .bd-brand-item {
+    border-top: 0;
+    border-left: 1px solid #fff; }
+  .bd-brand-item h1 {
+    font-size: 4rem; } }
+
+.color-swatches {
+  margin: 0 -5px;
+  overflow: hidden; }
+
+.color-swatch {
+  float: left;
+  width: 4rem;
+  height: 4rem;
+  margin-right: .25rem;
+  margin-left: .25rem;
+  border-radius: .25rem; }
+  @media (min-width: 768px) {
+    .color-swatch {
+      width: 6rem;
+      height: 6rem; } }
+
+.color-swatches .bd-purple {
+  background-color: #563d7c; }
+
+.color-swatches .bd-purple-light {
+  background-color: #cdbfe3; }
+
+.color-swatches .bd-purple-lighter {
+  background-color: #e5e1ea; }
+
+.color-swatches .bd-gray {
+  background-color: #f9f9f9; }
+
+.zero-clipboard {
+  position: relative;
+  display: none;
+  float: right; }
+
+.btn-clipboard {
+  position: absolute;
+  top: 0;
+  right: 0;
+  z-index: 10;
+  display: block;
+  padding: 0.25rem 0.5rem;
+  font-size: 75%;
+  color: #818a91;
+  cursor: pointer;
+  background-color: #eceeef;
+  border-radius: 0 0.2rem 0 0.2rem; }
+
+.btn-clipboard-hover {
+  color: #fff;
+  background-color: #027de7; }
+
+@media (min-width: 768px) {
+  .zero-clipboard {
+    display: block; } }
+
+.hll {
+  background-color: #ffffcc; }
+
+.c {
+  color: #999; }
+
+.err {
+  color: #AA0000;
+  background-color: #FFAAAA; }
+
+.k {
+  color: #006699; }
+
+.o {
+  color: #555555; }
+
+.cm {
+  color: #999; }
+
+.cp {
+  color: #009999; }
+
+.c1 {
+  color: #999; }
+
+.cs {
+  color: #999; }
+
+.gd {
+  background-color: #FFCCCC;
+  border: 1px solid #CC0000; }
+
+.ge {
+  font-style: italic; }
+
+.gr {
+  color: #FF0000; }
+
+.gh {
+  color: #003300; }
+
+.gi {
+  background-color: #CCFFCC;
+  border: 1px solid #00CC00; }
+
+.go {
+  color: #AAAAAA; }
+
+.gp {
+  color: #000099; }
+
+.gu {
+  color: #003300; }
+
+.gt {
+  color: #99CC66; }
+
+.kc {
+  color: #006699; }
+
+.kd {
+  color: #006699; }
+
+.kn {
+  color: #006699; }
+
+.kp {
+  color: #006699; }
+
+.kr {
+  color: #006699; }
+
+.kt {
+  color: #007788; }
+
+.m {
+  color: #FF6600; }
+
+.s {
+  color: #d44950; }
+
+.na {
+  color: #4f9fcf; }
+
+.nb {
+  color: #336666; }
+
+.nc {
+  color: #00AA88; }
+
+.no {
+  color: #336600; }
+
+.nd {
+  color: #9999FF; }
+
+.ni {
+  color: #999999; }
+
+.ne {
+  color: #CC0000; }
+
+.nf {
+  color: #CC00FF; }
+
+.nl {
+  color: #9999FF; }
+
+.nn {
+  color: #00CCFF; }
+
+.nt {
+  color: #2f6f9f; }
+
+.nv {
+  color: #003333; }
+
+.ow {
+  color: #000000; }
+
+.w {
+  color: #bbbbbb; }
+
+.mf {
+  color: #FF6600; }
+
+.mh {
+  color: #FF6600; }
+
+.mi {
+  color: #FF6600; }
+
+.mo {
+  color: #FF6600; }
+
+.sb {
+  color: #CC3300; }
+
+.sc {
+  color: #CC3300; }
+
+.sd {
+  color: #CC3300;
+  font-style: italic; }
+
+.s2 {
+  color: #CC3300; }
+
+.se {
+  color: #CC3300; }
+
+.sh {
+  color: #CC3300; }
+
+.si {
+  color: #AA0000; }
+
+.sx {
+  color: #CC3300; }
+
+.sr {
+  color: #33AAAA; }
+
+.s1 {
+  color: #CC3300; }
+
+.ss {
+  color: #FFCC33; }
+
+.bp {
+  color: #336666; }
+
+.vc {
+  color: #003333; }
+
+.vg {
+  color: #003333; }
+
+.vi {
+  color: #003333; }
+
+.il {
+  color: #FF6600; }
+
+.css .o,
+.css .o + .nt,
+.css .nt + .nt {
+  color: #999; }
+
+@font-face {
+  font-family: 'anchorjs-icons';
+  src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg6v8yoAAAC8AAAAYGNtYXDL8RqdAAABHAAAADxnYXNwAAAAEAAAAVgAAAAIZ2x5Zkm2oNUAAAFgAAABWGhlYWQAHd4cAAACuAAAADZoaGVhB3sECwAAAvAAAAAkaG10eAYAAEcAAAMUAAAADGxvY2EACgCsAAADIAAAAAhtYXhwAAYAcAAAAygAAAAgbmFtZUQXtNYAAANIAAABOXBvc3QAAwAAAAAEhAAAACAAAwQAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAACDmAAPA/8D/wAPAAEAAAAAAAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEACgAAAAGAAQAAQACACDmAP//AAAAIOYA////4RoCAAEAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAIARwAHA7kDeQA2AG0AAAEnLgEiBg8BDgEUFh8BHgMXNy4DLwEuATQ2PwE+ATIWHwEeARQGDwEeAxU3PgE0JicBLgMnBx4DHwEeARQGDwEOASImLwEuATQ2PwEuAzUHDgEUFh8BHgEyNj8BPgE0Ji8BA7kEI1ldWiPaIyQkIwQDBgYGBFAEBwYHAwQTExMT2xMwMjETBBMTExNjBwkGA5gkIyMk/r4DBgYGBFAEBwYHAwQTExMT2xMwMjETBBMTExNjBwkGA5gkIyMkBCNZXVoj2iMkJCMEA3UEJCMjJNojWV1aIwQDBgUFA1ACBQUFAwQUMDIxE9oTExMTBBMxMjATYxAhISIRmSNaXVkj/sYDBgUFA1ACBQUFAwQUMDIxE9oTExMTBBMxMjATYxAhISIRmSNaXVkjBCQjIyTaI1ldWiMEAAEAAAABAABR/4xQXw889QALBAAAAAAAzqNM0wAAAADOo0zTAAAAAAO5A3kAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAABHA7kAAQAAAAAAAAAAAAAAAAAAAAMAAAAAAgAAAAQAAEcAAAAAAAoArAABAAAAAwBuAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIADgBHAAEAAAAAAAMADgAkAAEAAAAAAAQADgBVAAEAAAAAAAUAFgAOAAEAAAAAAAYABwAyAAEAAAAAAAoAKABjAAMAAQQJAAEADgAAAAMAAQQJAAIADgBHAAMAAQQJAAMADgAkAAMAAQQJAAQADgBVAAMAAQQJAAUAFgAOAAMAAQQJAAYADgA5AAMAAQQJAAoAKABjAGkAYwBvAG0AbwBvAG4AVgBlAHIAcwBpAG8AbgAgADAALgAwAGkAYwBvAG0AbwBvAG5pY29tb29uAGkAYwBvAG0AbwBvAG4AUgBlAGcAdQBsAGEAcgBpAGMAbwBtAG8AbwBuAEcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format("truetype"), url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAATwAAsAAAAABKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABCAAAAGAAAABgDq/zKmNtYXAAAAFoAAAAPAAAADzL8RqdZ2FzcAAAAaQAAAAIAAAACAAAABBnbHlmAAABrAAAAVgAAAFYSbag1WhlYWQAAAMEAAAANgAAADYAHd4caGhlYQAAAzwAAAAkAAAAJAd7BAtobXR4AAADYAAAAAwAAAAMBgAAR2xvY2EAAANsAAAACAAAAAgACgCsbWF4cAAAA3QAAAAgAAAAIAAGAHBuYW1lAAADlAAAATkAAAE5RBe01nBvc3QAAATQAAAAIAAAACAAAwAAAAMEAAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAg5gADwP/A/8ADwABAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAgAAAAMAAAAUAAMAAQAAABQABAAoAAAABgAEAAEAAgAg5gD//wAAACDmAP///+EaAgABAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAACAEcABwO5A3kANgBtAAABJy4BIgYPAQ4BFBYfAR4DFzcuAy8BLgE0Nj8BPgEyFh8BHgEUBg8BHgMVNz4BNCYnAS4DJwceAx8BHgEUBg8BDgEiJi8BLgE0Nj8BLgM1Bw4BFBYfAR4BMjY/AT4BNCYvAQO5BCNZXVoj2iMkJCMEAwYGBgRQBAcGBwMEExMTE9sTMDIxEwQTExMTYwcJBgOYJCMjJP6+AwYGBgRQBAcGBwMEExMTE9sTMDIxEwQTExMTYwcJBgOYJCMjJAQjWV1aI9ojJCQjBAN1BCQjIyTaI1ldWiMEAwYFBQNQAgUFBQMEFDAyMRPaExMTEwQTMTIwE2MQISEiEZkjWl1ZI/7GAwYFBQNQAgUFBQMEFDAyMRPaExMTEwQTMTIwE2MQISEiEZkjWl1ZIwQkIyMk2iNZXVojBAABAAAAAQAAUf+MUF8PPPUACwQAAAAAAM6jTNMAAAAAzqNM0wAAAAADuQN5AAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAARwO5AAEAAAAAAAAAAAAAAAAAAAADAAAAAAIAAAAEAABHAAAAAAAKAKwAAQAAAAMAbgACAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAA4AAAABAAAAAAACAA4ARwABAAAAAAADAA4AJAABAAAAAAAEAA4AVQABAAAAAAAFABYADgABAAAAAAAGAAcAMgABAAAAAAAKACgAYwADAAEECQABAA4AAAADAAEECQACAA4ARwADAAEECQADAA4AJAADAAEECQAEAA4AVQADAAEECQAFABYADgADAAEECQAGAA4AOQADAAEECQAKACgAYwBpAGMAbwBtAG8AbwBuAFYAZQByAHMAaQBvAG4AIAAwAC4AMABpAGMAbwBtAG8AbwBuaWNvbW9vbgBpAGMAbwBtAG8AbwBuAFIAZQBnAHUAbABhAHIAaQBjAG8AbQBvAG8AbgBHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4AAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("woff");
+  font-style: normal;
+  font-weight: normal; }
+
+.anchorjs-icon {
+  font-family: 'anchorjs-icons';
+  font-style: normal;
+  font-variant: normal;
+  font-weight: normal;
+  line-height: 1;
+  speak: none;
+  text-transform: none;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale; }
+
+.anchorjs-link {
+  opacity: 0;
+  text-decoration: none; }
+
+*:hover > .anchorjs-link,
+.anchorjs-link:focus {
+  opacity: 1;
+  transition: color 0.16s linear; }
+
+.anchorjs-description {
+  border: 0;
+  clip: rect(0 0 0 0);
+  height: 1px;
+  margin: -1px;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  width: 1px; }
+
+.anchorjs-link {
+  float: left;
+  width: 1.2em;
+  height: 1em;
+  padding-right: .2em;
+  margin-top: .25em;
+  margin-left: -1.2em;
+  font-size: 70%;
+  color: inherit;
+  text-align: center; }
+
+*:hover > .anchorjs-link:hover {
+  color: #0275d8;
+  text-decoration: none; }
+
+.anchorjs-icon:before {
+  content: '\e600'; }
+
+@media (max-width: 47.9em) {
+  .anchorjs-link {
+    display: none; } }
+
+/*# sourceMappingURL=docs.min.css.map */
\ No newline at end of file
diff --git a/docs/assets/css/docs.min.css.map b/docs/assets/css/docs.min.css.map
index c00d288af37ae28a4f9d27df56e69473fa13e546..a90258684b6b99e76c33239fbdaee8ccc95bec6d 100644
Binary files a/docs/assets/css/docs.min.css.map and b/docs/assets/css/docs.min.css.map differ
diff --git a/grunt/bs-commonjs-generator.js b/grunt/bs-commonjs-generator.js
index 5a3fc156d10b0e9b2aa840b99bcdd7f7637326a8..700b839ce063489e726210675f5c554d7b3ff65d 100644
--- a/grunt/bs-commonjs-generator.js
+++ b/grunt/bs-commonjs-generator.js
@@ -9,8 +9,7 @@ module.exports = function generateCommonJSModule(grunt, srcFiles, destFilepath)
   var destDir = path.dirname(destFilepath);
 
   function srcPathToDestRequire(srcFilepath) {
-    var requirePath = path.relative(destDir, srcFilepath).replace(/\\/g, '/');
-    return 'require(\'' + requirePath + '\')';
+    return 'require(\'' + srcFilepath + '\')';
   }
 
   var moduleOutputJs = COMMONJS_BANNER + srcFiles.map(srcPathToDestRequire).join('\n');
diff --git a/js/.jscsrc b/js/.jscsrc
index 9544d2d2b5972a72e8a56997d14981f3ebf647f4..8d5ef3e56937c8b76f06eef0970b6b7be107b62e 100644
--- a/js/.jscsrc
+++ b/js/.jscsrc
@@ -1,4 +1,5 @@
 {
+  "esnext": true,
   "disallowEmptyBlocks": true,
   "disallowKeywords": ["with"],
   "disallowMixedSpacesAndTabs": true,
diff --git a/js/.jshintrc b/js/.jshintrc
deleted file mode 100644
index a59e1d00a1136c3e14693ea08af584c601aa5bc0..0000000000000000000000000000000000000000
--- a/js/.jshintrc
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "asi"      : true,
-  "browser"  : true,
-  "eqeqeq"   : false,
-  "eqnull"   : true,
-  "es3"      : true,
-  "expr"     : true,
-  "jquery"   : true,
-  "latedef"  : true,
-  "laxbreak" : true,
-  "nonbsp"   : true,
-  "strict"   : true,
-  "undef"    : true,
-  "unused"   : true
-}
diff --git a/js/affix.js b/js/affix.js
deleted file mode 100644
index 9997379123a17270a515e1ca5d9a86d8a8fd79d2..0000000000000000000000000000000000000000
--- a/js/affix.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/* ========================================================================
- * Bootstrap: affix.js v3.3.4
- * http://getbootstrap.com/javascript/#affix
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // AFFIX CLASS DEFINITION
-  // ======================
-
-  var Affix = function (element, options) {
-    this.options = $.extend({}, Affix.DEFAULTS, options)
-
-    this.$target = $(this.options.target)
-      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
-      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))
-
-    this.$element     = $(element)
-    this.affixed      = null
-    this.unpin        = null
-    this.pinnedOffset = null
-
-    this.checkPosition()
-  }
-
-  Affix.VERSION  = '3.3.4'
-
-  Affix.RESET    = 'affix affix-top affix-bottom'
-
-  Affix.DEFAULTS = {
-    offset: 0,
-    target: window
-  }
-
-  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
-    var scrollTop    = this.$target.scrollTop()
-    var position     = this.$element.offset()
-    var targetHeight = this.$target.height()
-
-    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
-
-    if (this.affixed == 'bottom') {
-      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
-      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
-    }
-
-    var initializing   = this.affixed == null
-    var colliderTop    = initializing ? scrollTop : position.top
-    var colliderHeight = initializing ? targetHeight : height
-
-    if (offsetTop != null && scrollTop <= offsetTop) return 'top'
-    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
-
-    return false
-  }
-
-  Affix.prototype.getPinnedOffset = function () {
-    if (this.pinnedOffset) return this.pinnedOffset
-    this.$element.removeClass(Affix.RESET).addClass('affix')
-    var scrollTop = this.$target.scrollTop()
-    var position  = this.$element.offset()
-    return (this.pinnedOffset = position.top - scrollTop)
-  }
-
-  Affix.prototype.checkPositionWithEventLoop = function () {
-    setTimeout($.proxy(this.checkPosition, this), 1)
-  }
-
-  Affix.prototype.checkPosition = function () {
-    if (!this.$element.is(':visible')) return
-
-    var height       = this.$element.height()
-    var offset       = this.options.offset
-    var offsetTop    = offset.top
-    var offsetBottom = offset.bottom
-    var scrollHeight = Math.max($(document).height(), $(document.body).height())
-
-    if (typeof offset != 'object')         offsetBottom = offsetTop = offset
-    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)
-    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
-
-    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
-
-    if (this.affixed != affix) {
-      if (this.unpin != null) this.$element.css('top', '')
-
-      var affixType = 'affix' + (affix ? '-' + affix : '')
-      var e         = $.Event(affixType + '.bs.affix')
-
-      this.$element.trigger(e)
-
-      if (e.isDefaultPrevented()) return
-
-      this.affixed = affix
-      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
-
-      this.$element
-        .removeClass(Affix.RESET)
-        .addClass(affixType)
-        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
-    }
-
-    if (affix == 'bottom') {
-      this.$element.offset({
-        top: scrollHeight - height - offsetBottom
-      })
-    }
-  }
-
-
-  // AFFIX PLUGIN DEFINITION
-  // =======================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.affix')
-      var options = typeof option == 'object' && option
-
-      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
-
-  var old = $.fn.affix
-
-  $.fn.affix             = Plugin
-  $.fn.affix.Constructor = Affix
-
-
-  // AFFIX NO CONFLICT
-  // =================
-
-  $.fn.affix.noConflict = function () {
-    $.fn.affix = old
-    return this
-  }
-
-
-  // AFFIX DATA-API
-  // ==============
-
-  $(window).on('load', function () {
-    $('[data-spy="affix"]').each(function () {
-      var $spy = $(this)
-      var data = $spy.data()
-
-      data.offset = data.offset || {}
-
-      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
-      if (data.offsetTop    != null) data.offset.top    = data.offsetTop
-
-      Plugin.call($spy, data)
-    })
-  })
-
-}(jQuery);
diff --git a/js/alert.js b/js/alert.js
deleted file mode 100644
index 1925ef011c1038d3b39fe49c6ed0d89478ced726..0000000000000000000000000000000000000000
--- a/js/alert.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/* ========================================================================
- * Bootstrap: alert.js v3.3.4
- * http://getbootstrap.com/javascript/#alerts
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // ALERT CLASS DEFINITION
-  // ======================
-
-  var dismiss = '[data-dismiss="alert"]'
-  var Alert   = function (el) {
-    $(el).on('click', dismiss, this.close)
-  }
-
-  Alert.VERSION = '3.3.4'
-
-  Alert.TRANSITION_DURATION = 150
-
-  Alert.prototype.close = function (e) {
-    var $this    = $(this)
-    var selector = $this.attr('data-target')
-
-    if (!selector) {
-      selector = $this.attr('href')
-      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
-    }
-
-    var $parent = $(selector)
-
-    if (e) e.preventDefault()
-
-    if (!$parent.length) {
-      $parent = $this.closest('.alert')
-    }
-
-    $parent.trigger(e = $.Event('close.bs.alert'))
-
-    if (e.isDefaultPrevented()) return
-
-    $parent.removeClass('in')
-
-    function removeElement() {
-      // detach from parent, fire event then clean up data
-      $parent.detach().trigger('closed.bs.alert').remove()
-    }
-
-    $.support.transition && $parent.hasClass('fade') ?
-      $parent
-        .one('bsTransitionEnd', removeElement)
-        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
-      removeElement()
-  }
-
-
-  // ALERT PLUGIN DEFINITION
-  // =======================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this = $(this)
-      var data  = $this.data('bs.alert')
-
-      if (!data) $this.data('bs.alert', (data = new Alert(this)))
-      if (typeof option == 'string') data[option].call($this)
-    })
-  }
-
-  var old = $.fn.alert
-
-  $.fn.alert             = Plugin
-  $.fn.alert.Constructor = Alert
-
-
-  // ALERT NO CONFLICT
-  // =================
-
-  $.fn.alert.noConflict = function () {
-    $.fn.alert = old
-    return this
-  }
-
-
-  // ALERT DATA-API
-  // ==============
-
-  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
-
-}(jQuery);
diff --git a/js/button.js b/js/button.js
deleted file mode 100644
index 3e2e345127ab6c085f6fc10f2355719561ad2e29..0000000000000000000000000000000000000000
--- a/js/button.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/* ========================================================================
- * Bootstrap: button.js v3.3.4
- * http://getbootstrap.com/javascript/#buttons
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // BUTTON PUBLIC CLASS DEFINITION
-  // ==============================
-
-  var Button = function (element, options) {
-    this.$element  = $(element)
-    this.options   = $.extend({}, Button.DEFAULTS, options)
-    this.isLoading = false
-  }
-
-  Button.VERSION  = '3.3.4'
-
-  Button.DEFAULTS = {
-    loadingText: 'loading...'
-  }
-
-  Button.prototype.setState = function (state) {
-    var d    = 'disabled'
-    var $el  = this.$element
-    var val  = $el.is('input') ? 'val' : 'html'
-    var data = $el.data()
-
-    state += 'Text'
-
-    if (data.resetText == null) $el.data('resetText', $el[val]())
-
-    // push to event loop to allow forms to submit
-    setTimeout($.proxy(function () {
-      $el[val](data[state] == null ? this.options[state] : data[state])
-
-      if (state == 'loadingText') {
-        this.isLoading = true
-        $el.addClass(d).attr(d, d)
-      } else if (this.isLoading) {
-        this.isLoading = false
-        $el.removeClass(d).removeAttr(d)
-      }
-    }, this), 0)
-  }
-
-  Button.prototype.toggle = function () {
-    var changed = true
-    var $parent = this.$element.closest('[data-toggle="buttons"]')
-
-    if ($parent.length) {
-      var $input = this.$element.find('input')
-      if ($input.prop('type') == 'radio') {
-        if ($input.prop('checked')) changed = false
-        $parent.find('.active').removeClass('active')
-        this.$element.addClass('active')
-      } else if ($input.prop('type') == 'checkbox') {
-        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
-        this.$element.toggleClass('active')
-      }
-      $input.prop('checked', this.$element.hasClass('active'))
-      if (changed) $input.trigger('change')
-    } else {
-      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
-      this.$element.toggleClass('active')
-    }
-  }
-
-
-  // BUTTON PLUGIN DEFINITION
-  // ========================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.button')
-      var options = typeof option == 'object' && option
-
-      if (!data) $this.data('bs.button', (data = new Button(this, options)))
-
-      if (option == 'toggle') data.toggle()
-      else if (option) data.setState(option)
-    })
-  }
-
-  var old = $.fn.button
-
-  $.fn.button             = Plugin
-  $.fn.button.Constructor = Button
-
-
-  // BUTTON NO CONFLICT
-  // ==================
-
-  $.fn.button.noConflict = function () {
-    $.fn.button = old
-    return this
-  }
-
-
-  // BUTTON DATA-API
-  // ===============
-
-  $(document)
-    .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
-      var $btn = $(e.target)
-      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
-      Plugin.call($btn, 'toggle')
-      if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault()
-    })
-    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
-      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
-    })
-
-}(jQuery);
diff --git a/js/carousel.js b/js/carousel.js
deleted file mode 100644
index a38ef14d0b51da2024333592467c841e1f5a38c3..0000000000000000000000000000000000000000
--- a/js/carousel.js
+++ /dev/null
@@ -1,237 +0,0 @@
-/* ========================================================================
- * Bootstrap: carousel.js v3.3.4
- * http://getbootstrap.com/javascript/#carousel
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // CAROUSEL CLASS DEFINITION
-  // =========================
-
-  var Carousel = function (element, options) {
-    this.$element    = $(element)
-    this.$indicators = this.$element.find('.carousel-indicators')
-    this.options     = options
-    this.paused      = null
-    this.sliding     = null
-    this.interval    = null
-    this.$active     = null
-    this.$items      = null
-
-    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
-
-    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
-      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
-      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
-  }
-
-  Carousel.VERSION  = '3.3.4'
-
-  Carousel.TRANSITION_DURATION = 600
-
-  Carousel.DEFAULTS = {
-    interval: 5000,
-    pause: 'hover',
-    wrap: true,
-    keyboard: true
-  }
-
-  Carousel.prototype.keydown = function (e) {
-    if (/input|textarea/i.test(e.target.tagName)) return
-    switch (e.which) {
-      case 37: this.prev(); break
-      case 39: this.next(); break
-      default: return
-    }
-
-    e.preventDefault()
-  }
-
-  Carousel.prototype.cycle = function (e) {
-    e || (this.paused = false)
-
-    this.interval && clearInterval(this.interval)
-
-    this.options.interval
-      && !this.paused
-      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
-
-    return this
-  }
-
-  Carousel.prototype.getItemIndex = function (item) {
-    this.$items = item.parent().children('.item')
-    return this.$items.index(item || this.$active)
-  }
-
-  Carousel.prototype.getItemForDirection = function (direction, active) {
-    var activeIndex = this.getItemIndex(active)
-    var willWrap = (direction == 'prev' && activeIndex === 0)
-                || (direction == 'next' && activeIndex == (this.$items.length - 1))
-    if (willWrap && !this.options.wrap) return active
-    var delta = direction == 'prev' ? -1 : 1
-    var itemIndex = (activeIndex + delta) % this.$items.length
-    return this.$items.eq(itemIndex)
-  }
-
-  Carousel.prototype.to = function (pos) {
-    var that        = this
-    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
-
-    if (pos > (this.$items.length - 1) || pos < 0) return
-
-    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
-    if (activeIndex == pos) return this.pause().cycle()
-
-    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
-  }
-
-  Carousel.prototype.pause = function (e) {
-    e || (this.paused = true)
-
-    if (this.$element.find('.next, .prev').length && $.support.transition) {
-      this.$element.trigger($.support.transition.end)
-      this.cycle(true)
-    }
-
-    this.interval = clearInterval(this.interval)
-
-    return this
-  }
-
-  Carousel.prototype.next = function () {
-    if (this.sliding) return
-    return this.slide('next')
-  }
-
-  Carousel.prototype.prev = function () {
-    if (this.sliding) return
-    return this.slide('prev')
-  }
-
-  Carousel.prototype.slide = function (type, next) {
-    var $active   = this.$element.find('.item.active')
-    var $next     = next || this.getItemForDirection(type, $active)
-    var isCycling = this.interval
-    var direction = type == 'next' ? 'left' : 'right'
-    var that      = this
-
-    if ($next.hasClass('active')) return (this.sliding = false)
-
-    var relatedTarget = $next[0]
-    var slideEvent = $.Event('slide.bs.carousel', {
-      relatedTarget: relatedTarget,
-      direction: direction
-    })
-    this.$element.trigger(slideEvent)
-    if (slideEvent.isDefaultPrevented()) return
-
-    this.sliding = true
-
-    isCycling && this.pause()
-
-    if (this.$indicators.length) {
-      this.$indicators.find('.active').removeClass('active')
-      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
-      $nextIndicator && $nextIndicator.addClass('active')
-    }
-
-    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
-    if ($.support.transition && this.$element.hasClass('slide')) {
-      $next.addClass(type)
-      $next[0].offsetWidth // force reflow
-      $active.addClass(direction)
-      $next.addClass(direction)
-      $active
-        .one('bsTransitionEnd', function () {
-          $next.removeClass([type, direction].join(' ')).addClass('active')
-          $active.removeClass(['active', direction].join(' '))
-          that.sliding = false
-          setTimeout(function () {
-            that.$element.trigger(slidEvent)
-          }, 0)
-        })
-        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
-    } else {
-      $active.removeClass('active')
-      $next.addClass('active')
-      this.sliding = false
-      this.$element.trigger(slidEvent)
-    }
-
-    isCycling && this.cycle()
-
-    return this
-  }
-
-
-  // CAROUSEL PLUGIN DEFINITION
-  // ==========================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.carousel')
-      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
-      var action  = typeof option == 'string' ? option : options.slide
-
-      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
-      if (typeof option == 'number') data.to(option)
-      else if (action) data[action]()
-      else if (options.interval) data.pause().cycle()
-    })
-  }
-
-  var old = $.fn.carousel
-
-  $.fn.carousel             = Plugin
-  $.fn.carousel.Constructor = Carousel
-
-
-  // CAROUSEL NO CONFLICT
-  // ====================
-
-  $.fn.carousel.noConflict = function () {
-    $.fn.carousel = old
-    return this
-  }
-
-
-  // CAROUSEL DATA-API
-  // =================
-
-  var clickHandler = function (e) {
-    var href
-    var $this   = $(this)
-    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
-    if (!$target.hasClass('carousel')) return
-    var options = $.extend({}, $target.data(), $this.data())
-    var slideIndex = $this.attr('data-slide-to')
-    if (slideIndex) options.interval = false
-
-    Plugin.call($target, options)
-
-    if (slideIndex) {
-      $target.data('bs.carousel').to(slideIndex)
-    }
-
-    e.preventDefault()
-  }
-
-  $(document)
-    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
-    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
-
-  $(window).on('load', function () {
-    $('[data-ride="carousel"]').each(function () {
-      var $carousel = $(this)
-      Plugin.call($carousel, $carousel.data())
-    })
-  })
-
-}(jQuery);
diff --git a/js/collapse.js b/js/collapse.js
deleted file mode 100644
index 954513c5e13fda29072b7c89a9df3194e27a206c..0000000000000000000000000000000000000000
--- a/js/collapse.js
+++ /dev/null
@@ -1,211 +0,0 @@
-/* ========================================================================
- * Bootstrap: collapse.js v3.3.4
- * http://getbootstrap.com/javascript/#collapse
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // COLLAPSE PUBLIC CLASS DEFINITION
-  // ================================
-
-  var Collapse = function (element, options) {
-    this.$element      = $(element)
-    this.options       = $.extend({}, Collapse.DEFAULTS, options)
-    this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
-                           '[data-toggle="collapse"][data-target="#' + element.id + '"]')
-    this.transitioning = null
-
-    if (this.options.parent) {
-      this.$parent = this.getParent()
-    } else {
-      this.addAriaAndCollapsedClass(this.$element, this.$trigger)
-    }
-
-    if (this.options.toggle) this.toggle()
-  }
-
-  Collapse.VERSION  = '3.3.4'
-
-  Collapse.TRANSITION_DURATION = 350
-
-  Collapse.DEFAULTS = {
-    toggle: true
-  }
-
-  Collapse.prototype.dimension = function () {
-    var hasWidth = this.$element.hasClass('width')
-    return hasWidth ? 'width' : 'height'
-  }
-
-  Collapse.prototype.show = function () {
-    if (this.transitioning || this.$element.hasClass('in')) return
-
-    var activesData
-    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
-
-    if (actives && actives.length) {
-      activesData = actives.data('bs.collapse')
-      if (activesData && activesData.transitioning) return
-    }
-
-    var startEvent = $.Event('show.bs.collapse')
-    this.$element.trigger(startEvent)
-    if (startEvent.isDefaultPrevented()) return
-
-    if (actives && actives.length) {
-      Plugin.call(actives, 'hide')
-      activesData || actives.data('bs.collapse', null)
-    }
-
-    var dimension = this.dimension()
-
-    this.$element
-      .removeClass('collapse')
-      .addClass('collapsing')[dimension](0)
-      .attr('aria-expanded', true)
-
-    this.$trigger
-      .removeClass('collapsed')
-      .attr('aria-expanded', true)
-
-    this.transitioning = 1
-
-    var complete = function () {
-      this.$element
-        .removeClass('collapsing')
-        .addClass('collapse in')[dimension]('')
-      this.transitioning = 0
-      this.$element
-        .trigger('shown.bs.collapse')
-    }
-
-    if (!$.support.transition) return complete.call(this)
-
-    var scrollSize = $.camelCase(['scroll', dimension].join('-'))
-
-    this.$element
-      .one('bsTransitionEnd', $.proxy(complete, this))
-      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
-  }
-
-  Collapse.prototype.hide = function () {
-    if (this.transitioning || !this.$element.hasClass('in')) return
-
-    var startEvent = $.Event('hide.bs.collapse')
-    this.$element.trigger(startEvent)
-    if (startEvent.isDefaultPrevented()) return
-
-    var dimension = this.dimension()
-
-    this.$element[dimension](this.$element[dimension]())[0].offsetHeight
-
-    this.$element
-      .addClass('collapsing')
-      .removeClass('collapse in')
-      .attr('aria-expanded', false)
-
-    this.$trigger
-      .addClass('collapsed')
-      .attr('aria-expanded', false)
-
-    this.transitioning = 1
-
-    var complete = function () {
-      this.transitioning = 0
-      this.$element
-        .removeClass('collapsing')
-        .addClass('collapse')
-        .trigger('hidden.bs.collapse')
-    }
-
-    if (!$.support.transition) return complete.call(this)
-
-    this.$element
-      [dimension](0)
-      .one('bsTransitionEnd', $.proxy(complete, this))
-      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
-  }
-
-  Collapse.prototype.toggle = function () {
-    this[this.$element.hasClass('in') ? 'hide' : 'show']()
-  }
-
-  Collapse.prototype.getParent = function () {
-    return $(this.options.parent)
-      .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
-      .each($.proxy(function (i, element) {
-        var $element = $(element)
-        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
-      }, this))
-      .end()
-  }
-
-  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
-    var isOpen = $element.hasClass('in')
-
-    $element.attr('aria-expanded', isOpen)
-    $trigger
-      .toggleClass('collapsed', !isOpen)
-      .attr('aria-expanded', isOpen)
-  }
-
-  function getTargetFromTrigger($trigger) {
-    var href
-    var target = $trigger.attr('data-target')
-      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
-
-    return $(target)
-  }
-
-
-  // COLLAPSE PLUGIN DEFINITION
-  // ==========================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.collapse')
-      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
-
-      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
-      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
-
-  var old = $.fn.collapse
-
-  $.fn.collapse             = Plugin
-  $.fn.collapse.Constructor = Collapse
-
-
-  // COLLAPSE NO CONFLICT
-  // ====================
-
-  $.fn.collapse.noConflict = function () {
-    $.fn.collapse = old
-    return this
-  }
-
-
-  // COLLAPSE DATA-API
-  // =================
-
-  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
-    var $this   = $(this)
-
-    if (!$this.attr('data-target')) e.preventDefault()
-
-    var $target = getTargetFromTrigger($this)
-    var data    = $target.data('bs.collapse')
-    var option  = data ? 'toggle' : $this.data()
-
-    Plugin.call($target, option)
-  })
-
-}(jQuery);
diff --git a/js/dist/alert.js b/js/dist/alert.js
new file mode 100644
index 0000000000000000000000000000000000000000..876a5f3d04c88a1168c4c2fb984c0e7282d38c25
--- /dev/null
+++ b/js/dist/alert.js
@@ -0,0 +1,192 @@
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): alert.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Alert = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'alert';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.alert';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 150;
+
+  var Selector = {
+    DISMISS: '[data-dismiss="alert"]'
+  };
+
+  var Event = {
+    CLOSE: 'close' + EVENT_KEY,
+    CLOSED: 'closed' + EVENT_KEY,
+    CLICK_DATA_API: 'click' + EVENT_KEY + '' + DATA_API_KEY
+  };
+
+  var ClassName = {
+    ALERT: 'alert',
+    FADE: 'fade',
+    IN: 'in'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Alert = (function () {
+    function Alert(element) {
+      _classCallCheck(this, Alert);
+
+      this._element = element;
+    }
+
+    _createClass(Alert, [{
+      key: 'close',
+
+      // public
+
+      value: function close(element) {
+        element = element || this._element;
+
+        var rootElement = this._getRootElement(element);
+        var customEvent = this._triggerCloseEvent(rootElement);
+
+        if (customEvent.isDefaultPrevented()) {
+          return;
+        }
+
+        this._removeElement(rootElement);
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeData(this._element, DATA_KEY);
+        this._element = null;
+      }
+    }, {
+      key: '_getRootElement',
+
+      // private
+
+      value: function _getRootElement(element) {
+        var parent = false;
+        var selector = Util.getSelectorFromElement(element);
+
+        if (selector) {
+          parent = $(selector)[0];
+        }
+
+        if (!parent) {
+          parent = $(element).closest('.' + ClassName.ALERT)[0];
+        }
+
+        return parent;
+      }
+    }, {
+      key: '_triggerCloseEvent',
+      value: function _triggerCloseEvent(element) {
+        var closeEvent = $.Event(Event.CLOSE);
+        $(element).trigger(closeEvent);
+        return closeEvent;
+      }
+    }, {
+      key: '_removeElement',
+      value: function _removeElement(element) {
+        $(element).removeClass(ClassName.IN);
+
+        if (!Util.supportsTransitionEnd() || !$(element).hasClass(ClassName.FADE)) {
+          this._destroyElement(element);
+          return;
+        }
+
+        $(element).one(Util.TRANSITION_END, this._destroyElement.bind(this, element)).emulateTransitionEnd(TRANSITION_DURATION);
+      }
+    }, {
+      key: '_destroyElement',
+      value: function _destroyElement(element) {
+        $(element).detach().trigger(Event.CLOSED).remove();
+      }
+    }], [{
+      key: 'VERSION',
+
+      // getters
+
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var $element = $(this);
+          var data = $element.data(DATA_KEY);
+
+          if (!data) {
+            data = new Alert(this);
+            $element.data(DATA_KEY, data);
+          }
+
+          if (config === 'close') {
+            data[config](this);
+          }
+        });
+      }
+    }, {
+      key: '_handleDismiss',
+      value: function _handleDismiss(alertInstance) {
+        return function (event) {
+          if (event) {
+            event.preventDefault();
+          }
+
+          alertInstance.close(this);
+        };
+      }
+    }]);
+
+    return Alert;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * 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);
+//# sourceMappingURL=alert.js.map
\ No newline at end of file
diff --git a/js/dist/alert.js.map b/js/dist/alert.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..a030fb73c8aacde1e21a3c658620ec4766379c17
Binary files /dev/null and b/js/dist/alert.js.map differ
diff --git a/js/dist/button.js b/js/dist/button.js
new file mode 100644
index 0000000000000000000000000000000000000000..fe6cfe9818d2b882948228a0e9fc1e0e97a729d6
--- /dev/null
+++ b/js/dist/button.js
@@ -0,0 +1,174 @@
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): button.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Button = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'button';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.button';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 150;
+
+  var ClassName = {
+    ACTIVE: 'active',
+    BUTTON: 'btn',
+    FOCUS: 'focus'
+  };
+
+  var Selector = {
+    DATA_TOGGLE_CARROT: '[data-toggle^="button"]',
+    DATA_TOGGLE: '[data-toggle="buttons"]',
+    INPUT: 'input',
+    ACTIVE: '.active',
+    BUTTON: '.btn'
+  };
+
+  var 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
+   * ------------------------------------------------------------------------
+   */
+
+  var Button = (function () {
+    function Button(element) {
+      _classCallCheck(this, Button);
+
+      this._element = element;
+    }
+
+    _createClass(Button, [{
+      key: 'toggle',
+
+      // public
+
+      value: function toggle() {
+        var triggerChangeEvent = true;
+        var rootElement = $(this._element).closest(Selector.DATA_TOGGLE)[0];
+
+        if (rootElement) {
+          var input = $(this._element).find(Selector.INPUT)[0];
+
+          if (input) {
+            if (input.type === 'radio') {
+              if (input.checked && $(this._element).hasClass(ClassName.ACTIVE)) {
+                triggerChangeEvent = false;
+              } else {
+                var activeElement = $(rootElement).find(Selector.ACTIVE)[0];
+
+                if (activeElement) {
+                  $(activeElement).removeClass(ClassName.ACTIVE);
+                }
+              }
+            }
+
+            if (triggerChangeEvent) {
+              input.checked = !$(this._element).hasClass(ClassName.ACTIVE);
+              $(this._element).trigger('change');
+            }
+          }
+        } else {
+          this._element.setAttribute('aria-pressed', !$(this._element).hasClass(ClassName.ACTIVE));
+        }
+
+        if (triggerChangeEvent) {
+          $(this._element).toggleClass(ClassName.ACTIVE);
+        }
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeData(this._element, DATA_KEY);
+        this._element = null;
+      }
+    }], [{
+      key: 'VERSION',
+
+      // getters
+
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+
+          if (!data) {
+            data = new Button(this);
+            $(this).data(DATA_KEY, data);
+          }
+
+          if (config === 'toggle') {
+            data[config]();
+          }
+        });
+      }
+    }]);
+
+    return Button;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) {
+    event.preventDefault();
+
+    var 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, function (event) {
+    var 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);
+//# sourceMappingURL=button.js.map
\ No newline at end of file
diff --git a/js/dist/button.js.map b/js/dist/button.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..109755be803c025b397cb7941b17991e8d889553
Binary files /dev/null and b/js/dist/button.js.map differ
diff --git a/js/dist/carousel.js b/js/dist/carousel.js
new file mode 100644
index 0000000000000000000000000000000000000000..029c69fdba9c90d60fbef1395bc327442672ea62
--- /dev/null
+++ b/js/dist/carousel.js
@@ -0,0 +1,466 @@
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): carousel.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Carousel = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'carousel';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.carousel';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 600;
+
+  var Default = {
+    interval: 5000,
+    keyboard: true,
+    slide: false,
+    pause: 'hover',
+    wrap: true
+  };
+
+  var DefaultType = {
+    interval: '(number|boolean)',
+    keyboard: 'boolean',
+    slide: '(boolean|string)',
+    pause: '(string|boolean)',
+    wrap: 'boolean'
+  };
+
+  var Direction = {
+    NEXT: 'next',
+    PREVIOUS: 'prev'
+  };
+
+  var 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
+  };
+
+  var ClassName = {
+    CAROUSEL: 'carousel',
+    ACTIVE: 'active',
+    SLIDE: 'slide',
+    RIGHT: 'right',
+    LEFT: 'left',
+    ITEM: 'carousel-item'
+  };
+
+  var Selector = {
+    ACTIVE: '.active',
+    ACTIVE_ITEM: '.active.carousel-item',
+    ITEM: '.carousel-item',
+    NEXT_PREV: '.next, .prev',
+    INDICATORS: '.carousel-indicators',
+    DATA_SLIDE: '[data-slide], [data-slide-to]',
+    DATA_RIDE: '[data-ride="carousel"]'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Carousel = (function () {
+    function Carousel(element, config) {
+      _classCallCheck(this, Carousel);
+
+      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();
+    }
+
+    _createClass(Carousel, [{
+      key: 'next',
+
+      // public
+
+      value: function next() {
+        if (!this._isSliding) {
+          this._slide(Direction.NEXT);
+        }
+      }
+    }, {
+      key: 'prev',
+      value: function prev() {
+        if (!this._isSliding) {
+          this._slide(Direction.PREVIOUS);
+        }
+      }
+    }, {
+      key: 'pause',
+      value: function 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;
+      }
+    }, {
+      key: 'cycle',
+      value: function 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($.proxy(this.next, this), this._config.interval);
+        }
+      }
+    }, {
+      key: 'to',
+      value: function to(index) {
+        var _this = this;
+
+        this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
+
+        var activeIndex = this._getItemIndex(this._activeElement);
+
+        if (index > this._items.length - 1 || index < 0) {
+          return;
+        }
+
+        if (this._isSliding) {
+          $(this._element).one(Event.SLID, function () {
+            return _this.to(index);
+          });
+          return;
+        }
+
+        if (activeIndex == index) {
+          this.pause();
+          this.cycle();
+          return;
+        }
+
+        var direction = index > activeIndex ? Direction.NEXT : Direction.PREVIOUS;
+
+        this._slide(direction, this._items[index]);
+      }
+    }, {
+      key: 'dispose',
+      value: function 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;
+      }
+    }, {
+      key: '_getConfig',
+
+      // private
+
+      value: function _getConfig(config) {
+        config = $.extend({}, Default, config);
+        Util.typeCheckConfig(NAME, config, DefaultType);
+        return config;
+      }
+    }, {
+      key: '_addEventListeners',
+      value: function _addEventListeners() {
+        if (this._config.keyboard) {
+          $(this._element).on(Event.KEYDOWN, $.proxy(this._keydown, this));
+        }
+
+        if (this._config.pause == 'hover' && !('ontouchstart' in document.documentElement)) {
+          $(this._element).on(Event.MOUSEENTER, $.proxy(this.pause, this)).on(Event.MOUSELEAVE, $.proxy(this.cycle, this));
+        }
+      }
+    }, {
+      key: '_keydown',
+      value: function _keydown(event) {
+        event.preventDefault();
+
+        if (/input|textarea/i.test(event.target.tagName)) return;
+
+        switch (event.which) {
+          case 37:
+            this.prev();break;
+          case 39:
+            this.next();break;
+          default:
+            return;
+        }
+      }
+    }, {
+      key: '_getItemIndex',
+      value: function _getItemIndex(element) {
+        this._items = $.makeArray($(element).parent().find(Selector.ITEM));
+        return this._items.indexOf(element);
+      }
+    }, {
+      key: '_getItemByDirection',
+      value: function _getItemByDirection(direction, activeElement) {
+        var isNextDirection = direction === Direction.NEXT;
+        var isPrevDirection = direction === Direction.PREVIOUS;
+        var activeIndex = this._getItemIndex(activeElement);
+        var lastItemIndex = this._items.length - 1;
+        var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex == lastItemIndex;
+
+        if (isGoingToWrap && !this._config.wrap) {
+          return activeElement;
+        }
+
+        var delta = direction == Direction.PREVIOUS ? -1 : 1;
+        var itemIndex = (activeIndex + delta) % this._items.length;
+
+        return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
+      }
+    }, {
+      key: '_triggerSlideEvent',
+      value: function _triggerSlideEvent(relatedTarget, directionalClassname) {
+        var slideEvent = $.Event(Event.SLIDE, {
+          relatedTarget: relatedTarget,
+          direction: directionalClassname
+        });
+
+        $(this._element).trigger(slideEvent);
+
+        return slideEvent;
+      }
+    }, {
+      key: '_setActiveIndicatorElement',
+      value: function _setActiveIndicatorElement(element) {
+        if (this._indicatorsElement) {
+          $(this._indicatorsElement).find(Selector.ACTIVE).removeClass(ClassName.ACTIVE);
+
+          var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
+
+          if (nextIndicator) {
+            $(nextIndicator).addClass(ClassName.ACTIVE);
+          }
+        }
+      }
+    }, {
+      key: '_slide',
+      value: function _slide(direction, element) {
+        var _this2 = this;
+
+        var activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
+        var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
+
+        var isCycling = !!this._interval;
+
+        var directionalClassName = direction == Direction.NEXT ? ClassName.LEFT : ClassName.RIGHT;
+
+        if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {
+          this._isSliding = false;
+          return;
+        }
+
+        var slideEvent = this._triggerSlideEvent(nextElement, directionalClassName);
+        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);
+
+        var slidEvent = $.Event(Event.SLID, {
+          relatedTarget: nextElement,
+          direction: directionalClassName
+        });
+
+        if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.SLIDE)) {
+
+          $(nextElement).addClass(direction);
+
+          Util.reflow(nextElement);
+
+          $(activeElement).addClass(directionalClassName);
+          $(nextElement).addClass(directionalClassName);
+
+          $(activeElement).one(Util.TRANSITION_END, function () {
+            $(nextElement).removeClass(directionalClassName).removeClass(direction);
+
+            $(nextElement).addClass(ClassName.ACTIVE);
+
+            $(activeElement).removeClass(ClassName.ACTIVE).removeClass(direction).removeClass(directionalClassName);
+
+            _this2._isSliding = false;
+
+            setTimeout(function () {
+              return $(_this2._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();
+        }
+      }
+    }], [{
+      key: 'VERSION',
+
+      // getters
+
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+          var _config = $.extend({}, Default, $(this).data());
+
+          if (typeof config === 'object') {
+            $.extend(_config, config);
+          }
+
+          var 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 (action) {
+            data[action]();
+          } else if (_config.interval) {
+            data.pause();
+            data.cycle();
+          }
+        });
+      }
+    }, {
+      key: '_dataApiClickHandler',
+      value: function _dataApiClickHandler(event) {
+        var selector = Util.getSelectorFromElement(this);
+
+        if (!selector) {
+          return;
+        }
+
+        var target = $(selector)[0];
+
+        if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {
+          return;
+        }
+
+        var config = $.extend({}, $(target).data(), $(this).data());
+
+        var 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();
+      }
+    }]);
+
+    return Carousel;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler);
+
+  $(window).on(Event.LOAD_DATA_API, function () {
+    $(Selector.DATA_RIDE).each(function () {
+      var $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);
+//# sourceMappingURL=carousel.js.map
\ No newline at end of file
diff --git a/js/dist/carousel.js.map b/js/dist/carousel.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..0978f4836febf93699a69336543edded126d7dfa
Binary files /dev/null and b/js/dist/carousel.js.map differ
diff --git a/js/dist/collapse.js b/js/dist/collapse.js
new file mode 100644
index 0000000000000000000000000000000000000000..9db1b8e6032a8348d6d06d8d55e883584e009e6e
--- /dev/null
+++ b/js/dist/collapse.js
@@ -0,0 +1,361 @@
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): collapse.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Collapse = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'collapse';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.collapse';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 600;
+
+  var Default = {
+    toggle: true,
+    parent: ''
+  };
+
+  var DefaultType = {
+    toggle: 'boolean',
+    parent: 'string'
+  };
+
+  var 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
+  };
+
+  var ClassName = {
+    IN: 'in',
+    COLLAPSE: 'collapse',
+    COLLAPSING: 'collapsing',
+    COLLAPSED: 'collapsed'
+  };
+
+  var Dimension = {
+    WIDTH: 'width',
+    HEIGHT: 'height'
+  };
+
+  var Selector = {
+    ACTIVES: '.panel > .in, .panel > .collapsing',
+    DATA_TOGGLE: '[data-toggle="collapse"]'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Collapse = (function () {
+    function Collapse(element, config) {
+      _classCallCheck(this, Collapse);
+
+      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);
+      }
+
+      if (this._config.toggle) {
+        this.toggle();
+      }
+    }
+
+    _createClass(Collapse, [{
+      key: 'toggle',
+
+      // public
+
+      value: function toggle() {
+        if ($(this._element).hasClass(ClassName.IN)) {
+          this.hide();
+        } else {
+          this.show();
+        }
+      }
+    }, {
+      key: 'show',
+      value: function show() {
+        var _this = this;
+
+        if (this._isTransitioning || $(this._element).hasClass(ClassName.IN)) {
+          return;
+        }
+
+        var actives = undefined;
+        var activesData = undefined;
+
+        if (this._parent) {
+          actives = $.makeArray($(Selector.ACTIVES));
+          if (!actives.length) {
+            actives = null;
+          }
+        }
+
+        if (actives) {
+          activesData = $(actives).data(DATA_KEY);
+          if (activesData && activesData._isTransitioning) {
+            return;
+          }
+        }
+
+        var 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);
+          }
+        }
+
+        var 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);
+
+        var complete = function complete() {
+          $(_this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.IN);
+
+          _this._element.style[dimension] = '';
+
+          _this.setTransitioning(false);
+
+          $(_this._element).trigger(Event.SHOWN);
+        };
+
+        if (!Util.supportsTransitionEnd()) {
+          complete();
+          return;
+        }
+
+        var scrollSize = 'scroll' + (dimension[0].toUpperCase() + dimension.slice(1));
+
+        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+
+        this._element.style[dimension] = this._element[scrollSize] + 'px';
+      }
+    }, {
+      key: 'hide',
+      value: function hide() {
+        var _this2 = this;
+
+        if (this._isTransitioning || !$(this._element).hasClass(ClassName.IN)) {
+          return;
+        }
+
+        var startEvent = $.Event(Event.HIDE);
+        $(this._element).trigger(startEvent);
+        if (startEvent.isDefaultPrevented()) {
+          return;
+        }
+
+        var dimension = this._getDimension();
+        var offsetDimension = dimension === Dimension.WIDTH ? 'offsetWidth' : 'offsetHeight';
+
+        this._element.style[dimension] = this._element[offsetDimension] + 'px';
+
+        Util.reflow(this._element);
+
+        $(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.IN);
+
+        this._element.setAttribute('aria-expanded', false);
+
+        if (this._triggerArray.length) {
+          $(this._triggerArray).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);
+        }
+
+        this.setTransitioning(true);
+
+        var complete = function complete() {
+          _this2.setTransitioning(false);
+          $(_this2._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN);
+        };
+
+        this._element.style[dimension] = 0;
+
+        if (!Util.supportsTransitionEnd()) {
+          return complete();
+        }
+
+        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+      }
+    }, {
+      key: 'setTransitioning',
+      value: function setTransitioning(isTransitioning) {
+        this._isTransitioning = isTransitioning;
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeData(this._element, DATA_KEY);
+
+        this._config = null;
+        this._parent = null;
+        this._element = null;
+        this._triggerArray = null;
+        this._isTransitioning = null;
+      }
+    }, {
+      key: '_getConfig',
+
+      // private
+
+      value: function _getConfig(config) {
+        config = $.extend({}, Default, config);
+        config.toggle = !!config.toggle; // coerce string values
+        Util.typeCheckConfig(NAME, config, DefaultType);
+        return config;
+      }
+    }, {
+      key: '_getDimension',
+      value: function _getDimension() {
+        var hasWidth = $(this._element).hasClass(Dimension.WIDTH);
+        return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;
+      }
+    }, {
+      key: '_getParent',
+      value: function _getParent() {
+        var _this3 = this;
+
+        var parent = $(this._config.parent)[0];
+        var selector = '[data-toggle="collapse"][data-parent="' + this._config.parent + '"]';
+
+        $(parent).find(selector).each(function (i, element) {
+          _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
+        });
+
+        return parent;
+      }
+    }, {
+      key: '_addAriaAndCollapsedClass',
+      value: function _addAriaAndCollapsedClass(element, triggerArray) {
+        if (element) {
+          var isOpen = $(element).hasClass(ClassName.IN);
+          element.setAttribute('aria-expanded', isOpen);
+
+          if (triggerArray.length) {
+            $(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
+          }
+        }
+      }
+    }], [{
+      key: 'VERSION',
+
+      // getters
+
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: '_getTargetFromElement',
+
+      // static
+
+      value: function _getTargetFromElement(element) {
+        var selector = Util.getSelectorFromElement(element);
+        return selector ? $(selector)[0] : null;
+      }
+    }, {
+      key: '_jQueryInterface',
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var $this = $(this);
+          var data = $this.data(DATA_KEY);
+          var _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') {
+            data[config]();
+          }
+        });
+      }
+    }]);
+
+    return Collapse;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+    event.preventDefault();
+
+    var target = Collapse._getTargetFromElement(this);
+
+    var data = $(target).data(DATA_KEY);
+    var 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);
+//# sourceMappingURL=collapse.js.map
\ No newline at end of file
diff --git a/js/dist/collapse.js.map b/js/dist/collapse.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..abd2bac68aa304a3e350ce70399544ed43314f04
Binary files /dev/null and b/js/dist/collapse.js.map differ
diff --git a/js/dist/dropdown.js b/js/dist/dropdown.js
new file mode 100644
index 0000000000000000000000000000000000000000..2ab5cf700df4ebbc330244b7bca0f552180c8822
--- /dev/null
+++ b/js/dist/dropdown.js
@@ -0,0 +1,281 @@
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): dropdown.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Dropdown = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'dropdown';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.dropdown';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+
+  var 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,
+    KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + '' + DATA_API_KEY
+  };
+
+  var ClassName = {
+    BACKDROP: 'dropdown-backdrop',
+    DISABLED: 'disabled',
+    OPEN: 'open'
+  };
+
+  var 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
+   * ------------------------------------------------------------------------
+   */
+
+  var Dropdown = (function () {
+    function Dropdown(element) {
+      _classCallCheck(this, Dropdown);
+
+      this._element = element;
+
+      this._addEventListeners();
+    }
+
+    _createClass(Dropdown, [{
+      key: 'toggle',
+
+      // public
+
+      value: function toggle() {
+        if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+          return;
+        }
+
+        var parent = Dropdown._getParentFromElement(this);
+        var isActive = $(parent).hasClass(ClassName.OPEN);
+
+        Dropdown._clearMenus();
+
+        if (isActive) {
+          return false;
+        }
+
+        if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) {
+
+          // if mobile we use a backdrop because click events don't delegate
+          var dropdown = document.createElement('div');
+          dropdown.className = ClassName.BACKDROP;
+          $(dropdown).insertBefore(this);
+          $(dropdown).on('click', Dropdown._clearMenus);
+        }
+
+        var relatedTarget = { relatedTarget: this };
+        var showEvent = $.Event(Event.SHOW, relatedTarget);
+
+        $(parent).trigger(showEvent);
+
+        if (showEvent.isDefaultPrevented()) {
+          return;
+        }
+
+        this.focus();
+        this.setAttribute('aria-expanded', 'true');
+
+        $(parent).toggleClass(ClassName.OPEN);
+        $(parent).trigger(Event.SHOWN, relatedTarget);
+
+        return false;
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeData(this._element, DATA_KEY);
+        $(this._element).off(EVENT_KEY);
+        this._element = null;
+      }
+    }, {
+      key: '_addEventListeners',
+
+      // private
+
+      value: function _addEventListeners() {
+        $(this._element).on(Event.CLICK, this.toggle);
+      }
+    }], [{
+      key: 'VERSION',
+
+      // getters
+
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+
+          if (!data) {
+            $(this).data(DATA_KEY, data = new Dropdown(this));
+          }
+
+          if (typeof config === 'string') {
+            data[config].call(this);
+          }
+        });
+      }
+    }, {
+      key: '_clearMenus',
+      value: function _clearMenus(event) {
+        if (event && event.which === 3) {
+          return;
+        }
+
+        var backdrop = $(Selector.BACKDROP)[0];
+        if (backdrop) {
+          backdrop.parentNode.removeChild(backdrop);
+        }
+
+        var toggles = $.makeArray($(Selector.DATA_TOGGLE));
+
+        for (var i = 0; i < toggles.length; i++) {
+          var _parent = Dropdown._getParentFromElement(toggles[i]);
+          var relatedTarget = { relatedTarget: toggles[i] };
+
+          if (!$(_parent).hasClass(ClassName.OPEN)) {
+            continue;
+          }
+
+          if (event && event.type === 'click' && /input|textarea/i.test(event.target.tagName) && $.contains(_parent, event.target)) {
+            continue;
+          }
+
+          var hideEvent = $.Event(Event.HIDE, relatedTarget);
+          $(_parent).trigger(hideEvent);
+          if (hideEvent.isDefaultPrevented()) {
+            continue;
+          }
+
+          toggles[i].setAttribute('aria-expanded', 'false');
+
+          $(_parent).removeClass(ClassName.OPEN).trigger(Event.HIDDEN, relatedTarget);
+        }
+      }
+    }, {
+      key: '_getParentFromElement',
+      value: function _getParentFromElement(element) {
+        var parent = undefined;
+        var selector = Util.getSelectorFromElement(element);
+
+        if (selector) {
+          parent = $(selector)[0];
+        }
+
+        return parent || element.parentNode;
+      }
+    }, {
+      key: '_dataApiKeydownHandler',
+      value: function _dataApiKeydownHandler(event) {
+        if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) {
+          return;
+        }
+
+        event.preventDefault();
+        event.stopPropagation();
+
+        if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+          return;
+        }
+
+        var parent = Dropdown._getParentFromElement(this);
+        var isActive = $(parent).hasClass(ClassName.OPEN);
+
+        if (!isActive && event.which !== 27 || isActive && event.which === 27) {
+
+          if (event.which === 27) {
+            var toggle = $(parent).find(Selector.DATA_TOGGLE)[0];
+            $(toggle).trigger('focus');
+          }
+
+          $(this).trigger('click');
+          return;
+        }
+
+        var items = $.makeArray($(Selector.VISIBLE_ITEMS));
+
+        items = items.filter(function (item) {
+          return item.offsetWidth || item.offsetHeight;
+        });
+
+        if (!items.length) {
+          return;
+        }
+
+        var index = items.indexOf(event.target);
+
+        if (event.which === 38 && index > 0) index--; // up
+        if (event.which === 40 && index < items.length - 1) index++; // down
+        if (! ~index) index = 0;
+
+        items[index].focus();
+      }
+    }]);
+
+    return Dropdown;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * 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, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (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);
+//# sourceMappingURL=dropdown.js.map
\ No newline at end of file
diff --git a/js/dist/dropdown.js.map b/js/dist/dropdown.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..fa59184e944069625d6a0823928e5eb330eb0578
Binary files /dev/null and b/js/dist/dropdown.js.map differ
diff --git a/js/dist/modal.js b/js/dist/modal.js
new file mode 100644
index 0000000000000000000000000000000000000000..2a638772592ba1005f89dd24563cc53cbf900dce
--- /dev/null
+++ b/js/dist/modal.js
@@ -0,0 +1,529 @@
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): modal.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Modal = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'modal';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.modal';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 300;
+  var BACKDROP_TRANSITION_DURATION = 150;
+
+  var Default = {
+    backdrop: true,
+    keyboard: true,
+    focus: true,
+    show: true
+  };
+
+  var DefaultType = {
+    backdrop: '(boolean|string)',
+    keyboard: 'boolean',
+    focus: 'boolean',
+    show: 'boolean'
+  };
+
+  var 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
+  };
+
+  var ClassName = {
+    BACKDROP: 'modal-backdrop',
+    OPEN: 'modal-open',
+    FADE: 'fade',
+    IN: 'in'
+  };
+
+  var Selector = {
+    DIALOG: '.modal-dialog',
+    DATA_TOGGLE: '[data-toggle="modal"]',
+    DATA_DISMISS: '[data-dismiss="modal"]',
+    SCROLLBAR_MEASURER: 'modal-scrollbar-measure'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Modal = (function () {
+    function Modal(element, config) {
+      _classCallCheck(this, Modal);
+
+      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._originalBodyPadding = 0;
+      this._scrollbarWidth = 0;
+    }
+
+    _createClass(Modal, [{
+      key: 'toggle',
+
+      // public
+
+      value: function toggle(relatedTarget) {
+        return this._isShown ? this.hide() : this.show(relatedTarget);
+      }
+    }, {
+      key: 'show',
+      value: function show(relatedTarget) {
+        var _this = this;
+
+        var showEvent = $.Event(Event.SHOW, {
+          relatedTarget: 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, $.proxy(this.hide, this));
+
+        $(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () {
+          $(_this._element).one(Event.MOUSEUP_DISMISS, function (event) {
+            if ($(event.target).is(_this._element)) {
+              that._ignoreBackdropClick = true;
+            }
+          });
+        });
+
+        this._showBackdrop($.proxy(this._showElement, this, relatedTarget));
+      }
+    }, {
+      key: 'hide',
+      value: function hide(event) {
+        if (event) {
+          event.preventDefault();
+        }
+
+        var 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.IN);
+
+        $(this._element).off(Event.CLICK_DISMISS);
+        $(this._dialog).off(Event.MOUSEDOWN_DISMISS);
+
+        if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
+
+          $(this._element).one(Util.TRANSITION_END, $.proxy(this._hideModal, this)).emulateTransitionEnd(TRANSITION_DURATION);
+        } else {
+          this._hideModal();
+        }
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeData(this._element, DATA_KEY);
+
+        $(window).off(EVENT_KEY);
+        $(document).off(EVENT_KEY);
+        $(this._element).off(EVENT_KEY);
+        $(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;
+      }
+    }, {
+      key: '_getConfig',
+
+      // private
+
+      value: function _getConfig(config) {
+        config = $.extend({}, Default, config);
+        Util.typeCheckConfig(NAME, config, DefaultType);
+        return config;
+      }
+    }, {
+      key: '_showElement',
+      value: function _showElement(relatedTarget) {
+        var _this2 = this;
+
+        var 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.scrollTop = 0;
+
+        if (transition) {
+          Util.reflow(this._element);
+        }
+
+        $(this._element).addClass(ClassName.IN);
+
+        if (this._config.focus) this._enforceFocus();
+
+        var shownEvent = $.Event(Event.SHOWN, {
+          relatedTarget: relatedTarget
+        });
+
+        var transitionComplete = function transitionComplete() {
+          if (_this2._config.focus) _this2._element.focus();
+          $(_this2._element).trigger(shownEvent);
+        };
+
+        if (transition) {
+          $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(TRANSITION_DURATION);
+        } else {
+          transitionComplete();
+        }
+      }
+    }, {
+      key: '_enforceFocus',
+      value: function _enforceFocus() {
+        var _this3 = this;
+
+        $(document).off(Event.FOCUSIN) // guard against infinite focus loop
+        .on(Event.FOCUSIN, function (event) {
+          if (_this3._element !== event.target && !$(_this3._element).has(event.target).length) {
+            _this3._element.focus();
+          }
+        });
+      }
+    }, {
+      key: '_setEscapeEvent',
+      value: function _setEscapeEvent() {
+        var _this4 = this;
+
+        if (this._isShown && this._config.keyboard) {
+          $(this._element).on(Event.KEYDOWN_DISMISS, function (event) {
+            if (event.which === 27) {
+              _this4.hide();
+            }
+          });
+        } else if (!this._isShown) {
+          $(this._element).off(Event.KEYDOWN_DISMISS);
+        }
+      }
+    }, {
+      key: '_setResizeEvent',
+      value: function _setResizeEvent() {
+        if (this._isShown) {
+          $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this));
+        } else {
+          $(window).off(Event.RESIZE);
+        }
+      }
+    }, {
+      key: '_hideModal',
+      value: function _hideModal() {
+        var _this5 = this;
+
+        this._element.style.display = 'none';
+        this._showBackdrop(function () {
+          $(document.body).removeClass(ClassName.OPEN);
+          _this5._resetAdjustments();
+          _this5._resetScrollbar();
+          $(_this5._element).trigger(Event.HIDDEN);
+        });
+      }
+    }, {
+      key: '_removeBackdrop',
+      value: function _removeBackdrop() {
+        if (this._backdrop) {
+          $(this._backdrop).remove();
+          this._backdrop = null;
+        }
+      }
+    }, {
+      key: '_showBackdrop',
+      value: function _showBackdrop(callback) {
+        var _this6 = this;
+
+        var animate = $(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : '';
+
+        if (this._isShown && this._config.backdrop) {
+          var doAnimate = Util.supportsTransitionEnd() && animate;
+
+          this._backdrop = document.createElement('div');
+          this._backdrop.className = ClassName.BACKDROP;
+
+          if (animate) {
+            $(this._backdrop).addClass(animate);
+          }
+
+          $(this._backdrop).appendTo(this.$body);
+
+          $(this._element).on(Event.CLICK_DISMISS, function (event) {
+            if (_this6._ignoreBackdropClick) {
+              _this6._ignoreBackdropClick = false;
+              return;
+            }
+            if (event.target !== event.currentTarget) {
+              return;
+            }
+            if (_this6._config.backdrop === 'static') {
+              _this6._element.focus();
+            } else {
+              _this6.hide();
+            }
+          });
+
+          if (doAnimate) {
+            Util.reflow(this._backdrop);
+          }
+
+          $(this._backdrop).addClass(ClassName.IN);
+
+          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.IN);
+
+          var callbackRemove = function callbackRemove() {
+            _this6._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();
+        }
+      }
+    }, {
+      key: '_handleUpdate',
+
+      // ----------------------------------------------------------------------
+      // the following methods are used to handle overflowing modals
+      // todo (fat): these should probably be refactored out of modal.js
+      // ----------------------------------------------------------------------
+
+      value: function _handleUpdate() {
+        this._adjustDialog();
+      }
+    }, {
+      key: '_adjustDialog',
+      value: function _adjustDialog() {
+        var 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';
+        }
+      }
+    }, {
+      key: '_resetAdjustments',
+      value: function _resetAdjustments() {
+        this._element.style.paddingLeft = '';
+        this._element.style.paddingRight = '';
+      }
+    }, {
+      key: '_checkScrollbar',
+      value: function _checkScrollbar() {
+        var fullWindowWidth = window.innerWidth;
+        if (!fullWindowWidth) {
+          // workaround for missing window.innerWidth in IE8
+          var documentElementRect = document.documentElement.getBoundingClientRect();
+          fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
+        }
+        this._isBodyOverflowing = document.body.clientWidth < fullWindowWidth;
+        this._scrollbarWidth = this._getScrollbarWidth();
+      }
+    }, {
+      key: '_setScrollbar',
+      value: function _setScrollbar() {
+        var bodyPadding = parseInt($(document.body).css('padding-right') || 0, 10);
+
+        this._originalBodyPadding = document.body.style.paddingRight || '';
+
+        if (this._isBodyOverflowing) {
+          document.body.style.paddingRight = bodyPadding + this._scrollbarWidth + 'px';
+        }
+      }
+    }, {
+      key: '_resetScrollbar',
+      value: function _resetScrollbar() {
+        document.body.style.paddingRight = this._originalBodyPadding;
+      }
+    }, {
+      key: '_getScrollbarWidth',
+      value: function _getScrollbarWidth() {
+        // thx d.walsh
+        var scrollDiv = document.createElement('div');
+        scrollDiv.className = Selector.SCROLLBAR_MEASURER;
+        document.body.appendChild(scrollDiv);
+        var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
+        document.body.removeChild(scrollDiv);
+        return scrollbarWidth;
+      }
+    }], [{
+      key: 'VERSION',
+
+      // getters
+
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config, relatedTarget) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+          var _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') {
+            data[config](relatedTarget);
+          } else if (_config.show) {
+            data.show(relatedTarget);
+          }
+        });
+      }
+    }]);
+
+    return Modal;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+    var _this7 = this;
+
+    var target = undefined;
+    var selector = Util.getSelectorFromElement(this);
+
+    if (selector) {
+      target = $(selector)[0];
+    }
+
+    var config = $(target).data(DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data());
+
+    if (this.tagName === 'A') {
+      event.preventDefault();
+    }
+
+    var $target = $(target).one(Event.SHOW, function (showEvent) {
+      if (showEvent.isDefaultPrevented()) {
+        // only register focus restorer if modal will actually get shown
+        return;
+      }
+
+      $target.one(Event.HIDDEN, function () {
+        if ($(_this7).is(':visible')) {
+          _this7.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);
+//# sourceMappingURL=modal.js.map
\ No newline at end of file
diff --git a/js/dist/modal.js.map b/js/dist/modal.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..5d10cd6d37479496ac2c9d5598b9f04c20978e60
Binary files /dev/null and b/js/dist/modal.js.map differ
diff --git a/js/dist/popover.js b/js/dist/popover.js
new file mode 100644
index 0000000000000000000000000000000000000000..8a30917c3b26a5f7f959318b92cbd0783941d784
--- /dev/null
+++ b/js/dist/popover.js
@@ -0,0 +1,204 @@
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): popover.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Popover = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'popover';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.popover';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+
+  var Default = $.extend({}, Tooltip.Default, {
+    placement: 'right',
+    trigger: 'click',
+    content: '',
+    template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-title"></h3>' + '<div class="popover-content"></div></div>'
+  });
+
+  var DefaultType = $.extend({}, Tooltip.DefaultType, {
+    content: '(string|function)'
+  });
+
+  var ClassName = {
+    FADE: 'fade',
+    IN: 'in'
+  };
+
+  var Selector = {
+    TITLE: '.popover-title',
+    CONTENT: '.popover-content',
+    ARROW: '.popover-arrow'
+  };
+
+  var 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
+   * ------------------------------------------------------------------------
+   */
+
+  var Popover = (function (_Tooltip) {
+    function Popover() {
+      _classCallCheck(this, Popover);
+
+      if (_Tooltip != null) {
+        _Tooltip.apply(this, arguments);
+      }
+    }
+
+    _inherits(Popover, _Tooltip);
+
+    _createClass(Popover, [{
+      key: 'isWithContent',
+
+      // overrides
+
+      value: function isWithContent() {
+        return this.getTitle() || this._getContent();
+      }
+    }, {
+      key: 'getTipElement',
+      value: function getTipElement() {
+        return this.tip = this.tip || $(this.config.template)[0];
+      }
+    }, {
+      key: 'setContent',
+      value: function setContent() {
+        var tip = this.getTipElement();
+        var title = this.getTitle();
+        var content = this._getContent();
+        var titleElement = $(tip).find(Selector.TITLE)[0];
+
+        if (titleElement) {
+          titleElement[this.config.html ? 'innerHTML' : 'innerText'] = title;
+        }
+
+        // we use append for html objects to maintain js events
+        $(tip).find(Selector.CONTENT).children().detach().end()[this.config.html ? typeof content === 'string' ? 'html' : 'append' : 'text'](content);
+
+        $(tip).removeClass(ClassName.FADE).removeClass(ClassName.IN);
+
+        this.cleanupTether();
+      }
+    }, {
+      key: '_getContent',
+
+      // private
+
+      value: function _getContent() {
+        return this.element.getAttribute('data-content') || (typeof this.config.content == 'function' ? this.config.content.call(this.element) : this.config.content);
+      }
+    }], [{
+      key: 'VERSION',
+
+      // getters
+
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: 'NAME',
+      get: function () {
+        return NAME;
+      }
+    }, {
+      key: 'DATA_KEY',
+      get: function () {
+        return DATA_KEY;
+      }
+    }, {
+      key: 'Event',
+      get: function () {
+        return Event;
+      }
+    }, {
+      key: 'EVENT_KEY',
+      get: function () {
+        return EVENT_KEY;
+      }
+    }, {
+      key: 'DefaultType',
+      get: function () {
+        return DefaultType;
+      }
+    }, {
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+          var _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') {
+            data[config]();
+          }
+        });
+      }
+    }]);
+
+    return Popover;
+  })(Tooltip);
+
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = Popover._jQueryInterface;
+  $.fn[NAME].Constructor = Popover;
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Popover._jQueryInterface;
+  };
+
+  return Popover;
+})(jQuery);
+//# sourceMappingURL=popover.js.map
\ No newline at end of file
diff --git a/js/dist/popover.js.map b/js/dist/popover.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..edc1301017b50ae24bb15614ab7f5423bd11f576
Binary files /dev/null and b/js/dist/popover.js.map differ
diff --git a/js/dist/scrollspy.js b/js/dist/scrollspy.js
new file mode 100644
index 0000000000000000000000000000000000000000..b214f86eeb0267758a929973f3c9db8704f57d6d
--- /dev/null
+++ b/js/dist/scrollspy.js
@@ -0,0 +1,315 @@
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): scrollspy.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var ScrollSpy = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'scrollspy';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.scrollspy';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+
+  var Default = {
+    offset: 10,
+    method: 'auto',
+    target: ''
+  };
+
+  var DefaultType = {
+    offset: 'number',
+    method: 'string',
+    target: '(string|element)'
+  };
+
+  var Event = {
+    ACTIVATE: 'activate' + EVENT_KEY,
+    SCROLL: 'scroll' + EVENT_KEY,
+    LOAD_DATA_API: 'load' + EVENT_KEY + '' + DATA_API_KEY
+  };
+
+  var ClassName = {
+    DROPDOWN_MENU: 'dropdown-menu',
+    ACTIVE: 'active'
+  };
+
+  var Selector = {
+    DATA_SPY: '[data-spy="scroll"]',
+    ACTIVE: '.active',
+    LI: 'li',
+    LI_DROPDOWN: 'li.dropdown',
+    NAV_ANCHORS: '.nav li > a'
+  };
+
+  var OffsetMethod = {
+    OFFSET: 'offset',
+    POSITION: 'position'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var ScrollSpy = (function () {
+    function ScrollSpy(element, config) {
+      _classCallCheck(this, ScrollSpy);
+
+      this._element = element;
+      this._scrollElement = element.tagName === 'BODY' ? window : element;
+      this._config = this._getConfig(config);
+      this._selector = '' + this._config.target + ' ' + Selector.NAV_ANCHORS;
+      this._offsets = [];
+      this._targets = [];
+      this._activeTarget = null;
+      this._scrollHeight = 0;
+
+      $(this._scrollElement).on(Event.SCROLL, $.proxy(this._process, this));
+
+      this.refresh();
+      this._process();
+    }
+
+    _createClass(ScrollSpy, [{
+      key: 'refresh',
+
+      // public
+
+      value: function refresh() {
+        var _this = this;
+
+        var autoMethod = this._scrollElement !== this._scrollElement.window ? OffsetMethod.POSITION : OffsetMethod.OFFSET;
+
+        var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
+
+        var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;
+
+        this._offsets = [];
+        this._targets = [];
+
+        this._scrollHeight = this._getScrollHeight();
+
+        var targets = $.makeArray($(this._selector));
+
+        targets.map(function (element) {
+          var target = undefined;
+          var targetSelector = Util.getSelectorFromElement(element);
+
+          if (targetSelector) {
+            target = $(targetSelector)[0];
+          }
+
+          if (target && (target.offsetWidth || target.offsetHeight)) {
+            // todo (fat): remove sketch reliance on jQuery position/offset
+            return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
+          }
+        }).filter(function (item) {
+          return item;
+        }).sort(function (a, b) {
+          return a[0] - b[0];
+        }).forEach(function (item) {
+          _this._offsets.push(item[0]);
+          _this._targets.push(item[1]);
+        });
+      }
+    }, {
+      key: 'dispose',
+      value: function 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;
+      }
+    }, {
+      key: '_getConfig',
+
+      // private
+
+      value: function _getConfig(config) {
+        config = $.extend({}, Default, config);
+
+        if (typeof config.target !== 'string') {
+          var 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;
+      }
+    }, {
+      key: '_getScrollTop',
+      value: function _getScrollTop() {
+        return this._scrollElement === window ? this._scrollElement.scrollY : this._scrollElement.scrollTop;
+      }
+    }, {
+      key: '_getScrollHeight',
+      value: function _getScrollHeight() {
+        return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
+      }
+    }, {
+      key: '_process',
+      value: function _process() {
+        var scrollTop = this._getScrollTop() + this._config.offset;
+        var scrollHeight = this._getScrollHeight();
+        var maxScroll = this._config.offset + scrollHeight - this._scrollElement.offsetHeight;
+
+        if (this._scrollHeight !== scrollHeight) {
+          this.refresh();
+        }
+
+        if (scrollTop >= maxScroll) {
+          var target = this._targets[this._targets.length - 1];
+
+          if (this._activeTarget !== target) {
+            this._activate(target);
+          }
+        }
+
+        if (this._activeTarget && scrollTop < this._offsets[0]) {
+          this._activeTarget = null;
+          this._clear();
+          return;
+        }
+
+        for (var i = this._offsets.length; i--;) {
+          var 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]);
+          }
+        }
+      }
+    }, {
+      key: '_activate',
+      value: function _activate(target) {
+        this._activeTarget = target;
+
+        this._clear();
+
+        var selector = '' + this._selector + '[data-target="' + target + '"],' + ('' + this._selector + '[href="' + target + '"]');
+
+        // todo (fat): getting all the raw li's up the tree is not great.
+        var parentListItems = $(selector).parents(Selector.LI);
+
+        for (var i = parentListItems.length; i--;) {
+          $(parentListItems[i]).addClass(ClassName.ACTIVE);
+
+          var itemParent = parentListItems[i].parentNode;
+
+          if (itemParent && $(itemParent).hasClass(ClassName.DROPDOWN_MENU)) {
+            var closestDropdown = $(itemParent).closest(Selector.LI_DROPDOWN)[0];
+            $(closestDropdown).addClass(ClassName.ACTIVE);
+          }
+        }
+
+        $(this._scrollElement).trigger(Event.ACTIVATE, {
+          relatedTarget: target
+        });
+      }
+    }, {
+      key: '_clear',
+      value: function _clear() {
+        var activeParents = $(this._selector).parentsUntil(this._config.target, Selector.ACTIVE);
+
+        for (var i = activeParents.length; i--;) {
+          $(activeParents[i]).removeClass(ClassName.ACTIVE);
+        }
+      }
+    }], [{
+      key: 'VERSION',
+
+      // getters
+
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+          var _config = typeof config === 'object' && config || null;
+
+          if (!data) {
+            data = new ScrollSpy(this, _config);
+            $(this).data(DATA_KEY, data);
+          }
+
+          if (typeof config === 'string') {
+            data[config]();
+          }
+        });
+      }
+    }]);
+
+    return ScrollSpy;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+  $(window).on(Event.LOAD_DATA_API, function () {
+    var scrollSpys = $.makeArray($(Selector.DATA_SPY));
+
+    for (var i = scrollSpys.length; i--;) {
+      var $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);
+//# sourceMappingURL=scrollspy.js.map
\ No newline at end of file
diff --git a/js/dist/scrollspy.js.map b/js/dist/scrollspy.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..bde96eda320c68fd9c2a282764341699f96f1108
Binary files /dev/null and b/js/dist/scrollspy.js.map differ
diff --git a/js/dist/tab.js b/js/dist/tab.js
new file mode 100644
index 0000000000000000000000000000000000000000..95c56194008a2de027b27bd8bbba38cebd93adb6
--- /dev/null
+++ b/js/dist/tab.js
@@ -0,0 +1,273 @@
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): tab.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Tab = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'tab';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.tab';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 150;
+
+  var 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
+  };
+
+  var ClassName = {
+    DROPDOWN_MENU: 'dropdown-menu',
+    ACTIVE: 'active',
+    FADE: 'fade',
+    IN: 'in'
+  };
+
+  var Selector = {
+    A: 'a',
+    LI: 'li',
+    LI_DROPDOWN: 'li.dropdown',
+    UL: 'ul:not(.dropdown-menu)',
+    FADE_CHILD: '> .fade',
+    ACTIVE: '.active',
+    ACTIVE_CHILD: '> .active',
+    DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"]',
+    DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu > .active'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Tab = (function () {
+    function Tab(element) {
+      _classCallCheck(this, Tab);
+
+      this._element = element;
+    }
+
+    _createClass(Tab, [{
+      key: 'show',
+
+      // public
+
+      value: function show() {
+        var _this = this;
+
+        if (this._element.parentNode && this._element.parentNode.nodeType == Node.ELEMENT_NODE && $(this._element).parent().hasClass(ClassName.ACTIVE)) {
+          return;
+        }
+
+        var target = undefined;
+        var previous = undefined;
+        var ulElement = $(this._element).closest(Selector.UL)[0];
+        var selector = Util.getSelectorFromElement(this._element);
+
+        if (ulElement) {
+          previous = $.makeArray($(ulElement).find(Selector.ACTIVE));
+          previous = previous[previous.length - 1];
+
+          if (previous) {
+            previous = $(previous).find(Selector.A)[0];
+          }
+        }
+
+        var hideEvent = $.Event(Event.HIDE, {
+          relatedTarget: this._element
+        });
+
+        var 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).closest(Selector.LI)[0], ulElement);
+
+        var complete = function complete() {
+          var hiddenEvent = $.Event(Event.HIDDEN, {
+            relatedTarget: _this._element
+          });
+
+          var shownEvent = $.Event(Event.SHOWN, {
+            relatedTarget: previous
+          });
+
+          $(previous).trigger(hiddenEvent);
+          $(_this._element).trigger(shownEvent);
+        };
+
+        if (target) {
+          this._activate(target, target.parentNode, complete);
+        } else {
+          complete();
+        }
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        $.removeClass(this._element, DATA_KEY);
+        this._element = null;
+      }
+    }, {
+      key: '_activate',
+
+      // private
+
+      value: function _activate(element, container, callback) {
+        var active = $(container).find(Selector.ACTIVE_CHILD)[0];
+        var isTransitioning = callback && Util.supportsTransitionEnd() && (active && $(active).hasClass(ClassName.FADE) || !!$(container).find(Selector.FADE_CHILD)[0]);
+
+        var complete = $.proxy(this._transitionComplete, this, element, active, isTransitioning, callback);
+
+        if (active && isTransitioning) {
+          $(active).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+        } else {
+          complete();
+        }
+
+        if (active) {
+          $(active).removeClass(ClassName.IN);
+        }
+      }
+    }, {
+      key: '_transitionComplete',
+      value: function _transitionComplete(element, active, isTransitioning, callback) {
+        if (active) {
+          $(active).removeClass(ClassName.ACTIVE);
+
+          var dropdownChild = $(active).find(Selector.DROPDOWN_ACTIVE_CHILD)[0];
+          if (dropdownChild) {
+            $(dropdownChild).removeClass(ClassName.ACTIVE);
+          }
+
+          var activeToggle = $(active).find(Selector.DATA_TOGGLE)[0];
+          if (activeToggle) {
+            activeToggle.setAttribute('aria-expanded', false);
+          }
+        }
+
+        $(element).addClass(ClassName.ACTIVE);
+
+        var elementToggle = $(element).find(Selector.DATA_TOGGLE)[0];
+        if (elementToggle) {
+          elementToggle.setAttribute('aria-expanded', true);
+        }
+
+        if (isTransitioning) {
+          Util.reflow(element);
+          $(element).addClass(ClassName.IN);
+        } else {
+          $(element).removeClass(ClassName.FADE);
+        }
+
+        if (element.parentNode && $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
+
+          var dropdownElement = $(element).closest(Selector.LI_DROPDOWN)[0];
+          if (dropdownElement) {
+            $(dropdownElement).addClass(ClassName.ACTIVE);
+          }
+
+          elementToggle = $(element).find(Selector.DATA_TOGGLE)[0];
+          if (elementToggle) {
+            elementToggle.setAttribute('aria-expanded', true);
+          }
+        }
+
+        if (callback) {
+          callback();
+        }
+      }
+    }], [{
+      key: 'VERSION',
+
+      // getters
+
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var $this = $(this);
+          var data = $this.data(DATA_KEY);
+
+          if (!data) {
+            data = data = new Tab(this);
+            $this.data(DATA_KEY, data);
+          }
+
+          if (typeof config === 'string') {
+            data[config]();
+          }
+        });
+      }
+    }]);
+
+    return Tab;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * 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);
+//# sourceMappingURL=tab.js.map
\ No newline at end of file
diff --git a/js/dist/tab.js.map b/js/dist/tab.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..82a86ecb168f0dd46c95923ce9dbcb5fced65440
Binary files /dev/null and b/js/dist/tab.js.map differ
diff --git a/js/dist/tooltip.js b/js/dist/tooltip.js
new file mode 100644
index 0000000000000000000000000000000000000000..864e0bb762dd7b11319685ef5e6b6c8570848844
--- /dev/null
+++ b/js/dist/tooltip.js
@@ -0,0 +1,594 @@
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): tooltip.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Tooltip = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'tooltip';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.tooltip';
+  var EVENT_KEY = '.' + DATA_KEY;
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 150;
+  var CLASS_PREFIX = 'bs-tether';
+
+  var Default = {
+    animation: true,
+    template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div></div>',
+    trigger: 'hover focus',
+    title: '',
+    delay: 0,
+    html: false,
+    selector: false,
+    placement: 'top',
+    offset: '0 0',
+    constraints: []
+  };
+
+  var DefaultType = {
+    animation: 'boolean',
+    template: 'string',
+    title: '(string|function)',
+    trigger: 'string',
+    delay: '(number|object)',
+    html: 'boolean',
+    selector: '(string|boolean)',
+    placement: '(string|function)',
+    offset: 'string',
+    constraints: 'array'
+  };
+
+  var AttachmentMap = {
+    TOP: 'bottom center',
+    RIGHT: 'middle left',
+    BOTTOM: 'top center',
+    LEFT: 'middle right'
+  };
+
+  var HoverState = {
+    IN: 'in',
+    OUT: 'out'
+  };
+
+  var 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
+  };
+
+  var ClassName = {
+    FADE: 'fade',
+    IN: 'in'
+  };
+
+  var Selector = {
+    TOOLTIP: '.tooltip',
+    TOOLTIP_INNER: '.tooltip-inner'
+  };
+
+  var TetherClass = {
+    element: false,
+    enabled: false
+  };
+
+  var Trigger = {
+    HOVER: 'hover',
+    FOCUS: 'focus',
+    CLICK: 'click',
+    MANUAL: 'manual'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Tooltip = (function () {
+    function Tooltip(element, config) {
+      _classCallCheck(this, Tooltip);
+
+      // private
+      this._isEnabled = true;
+      this._timeout = 0;
+      this._hoverState = '';
+      this._activeTrigger = {};
+      this._tether = null;
+
+      // protected
+      this.element = element;
+      this.config = this._getConfig(config);
+      this.tip = null;
+
+      this._setListeners();
+    }
+
+    _createClass(Tooltip, [{
+      key: 'enable',
+
+      // public
+
+      value: function enable() {
+        this._isEnabled = true;
+      }
+    }, {
+      key: 'disable',
+      value: function disable() {
+        this._isEnabled = false;
+      }
+    }, {
+      key: 'toggleEnabled',
+      value: function toggleEnabled() {
+        this._isEnabled = !this._isEnabled;
+      }
+    }, {
+      key: 'toggle',
+      value: function toggle(event) {
+        var context = this;
+        var dataKey = this.constructor.DATA_KEY;
+
+        if (event) {
+          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 {
+          $(context.getTipElement()).hasClass(ClassName.IN) ? context._leave(null, context) : context._enter(null, context);
+        }
+      }
+    }, {
+      key: 'dispose',
+      value: function dispose() {
+        clearTimeout(this._timeout);
+
+        this.cleanupTether();
+
+        $.removeData(this.element, this.constructor.DATA_KEY);
+
+        $(this.element).off(this.constructor.EVENT_KEY);
+
+        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;
+      }
+    }, {
+      key: 'show',
+      value: function show() {
+        var _this = this;
+
+        var showEvent = $.Event(this.constructor.Event.SHOW);
+
+        if (this.isWithContent() && this._isEnabled) {
+          $(this.element).trigger(showEvent);
+
+          var isInTheDom = $.contains(this.element.ownerDocument.documentElement, this.element);
+
+          if (showEvent.isDefaultPrevented() || !isInTheDom) {
+            return;
+          }
+
+          var tip = this.getTipElement();
+          var 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);
+          }
+
+          var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
+
+          var attachment = this._getAttachment(placement);
+
+          $(tip).data(this.constructor.DATA_KEY, this).appendTo(document.body);
+
+          $(this.element).trigger(this.constructor.Event.INSERTED);
+
+          this._tether = new Tether({
+            element: tip,
+            target: this.element,
+            attachment: attachment,
+            classes: TetherClass,
+            classPrefix: CLASS_PREFIX,
+            offset: this.config.offset,
+            constraints: this.config.constraints
+          });
+
+          Util.reflow(tip);
+          this._tether.position();
+
+          $(tip).addClass(ClassName.IN);
+
+          var complete = function complete() {
+            var prevHoverState = _this._hoverState;
+            _this._hoverState = null;
+
+            $(_this.element).trigger(_this.constructor.Event.SHOWN);
+
+            if (prevHoverState === HoverState.OUT) {
+              _this._leave(null, _this);
+            }
+          };
+
+          Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE) ? $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(Tooltip._TRANSITION_DURATION) : complete();
+        }
+      }
+    }, {
+      key: 'hide',
+      value: function hide(callback) {
+        var _this2 = this;
+
+        var tip = this.getTipElement();
+        var hideEvent = $.Event(this.constructor.Event.HIDE);
+        var complete = function complete() {
+          if (_this2._hoverState !== HoverState.IN && tip.parentNode) {
+            tip.parentNode.removeChild(tip);
+          }
+
+          _this2.element.removeAttribute('aria-describedby');
+          $(_this2.element).trigger(_this2.constructor.Event.HIDDEN);
+          _this2.cleanupTether();
+
+          if (callback) {
+            callback();
+          }
+        };
+
+        $(this.element).trigger(hideEvent);
+
+        if (hideEvent.isDefaultPrevented()) {
+          return;
+        }
+
+        $(tip).removeClass(ClassName.IN);
+
+        if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
+
+          $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+        } else {
+          complete();
+        }
+
+        this._hoverState = '';
+      }
+    }, {
+      key: 'isWithContent',
+
+      // protected
+
+      value: function isWithContent() {
+        return !!this.getTitle();
+      }
+    }, {
+      key: 'getTipElement',
+      value: function getTipElement() {
+        return this.tip = this.tip || $(this.config.template)[0];
+      }
+    }, {
+      key: 'setContent',
+      value: function setContent() {
+        var tip = this.getTipElement();
+        var title = this.getTitle();
+        var method = this.config.html ? 'innerHTML' : 'innerText';
+
+        $(tip).find(Selector.TOOLTIP_INNER)[0][method] = title;
+
+        $(tip).removeClass(ClassName.FADE).removeClass(ClassName.IN);
+
+        this.cleanupTether();
+      }
+    }, {
+      key: 'getTitle',
+      value: function getTitle() {
+        var 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;
+      }
+    }, {
+      key: 'cleanupTether',
+      value: function cleanupTether() {
+        if (this._tether) {
+          this._tether.destroy();
+
+          // clean up after tether's junk classes
+          // remove after they fix issue
+          // (https://github.com/HubSpot/tether/issues/36)
+          $(this.element).removeClass(this._removeTetherClasses);
+          $(this.tip).removeClass(this._removeTetherClasses);
+        }
+      }
+    }, {
+      key: '_getAttachment',
+
+      // private
+
+      value: function _getAttachment(placement) {
+        return AttachmentMap[placement.toUpperCase()];
+      }
+    }, {
+      key: '_setListeners',
+      value: function _setListeners() {
+        var _this3 = this;
+
+        var triggers = this.config.trigger.split(' ');
+
+        triggers.forEach(function (trigger) {
+          if (trigger === 'click') {
+            $(_this3.element).on(_this3.constructor.Event.CLICK, _this3.config.selector, $.proxy(_this3.toggle, _this3));
+          } else if (trigger !== Trigger.MANUAL) {
+            var eventIn = trigger == Trigger.HOVER ? _this3.constructor.Event.MOUSEENTER : _this3.constructor.Event.FOCUSIN;
+            var eventOut = trigger == Trigger.HOVER ? _this3.constructor.Event.MOUSELEAVE : _this3.constructor.Event.FOCUSOUT;
+
+            $(_this3.element).on(eventIn, _this3.config.selector, $.proxy(_this3._enter, _this3)).on(eventOut, _this3.config.selector, $.proxy(_this3._leave, _this3));
+          }
+        });
+
+        if (this.config.selector) {
+          this.config = $.extend({}, this.config, {
+            trigger: 'manual',
+            selector: ''
+          });
+        } else {
+          this._fixTitle();
+        }
+      }
+    }, {
+      key: '_removeTetherClasses',
+      value: function _removeTetherClasses(i, css) {
+        return ((css.baseVal || css).match(new RegExp('(^|\\s)' + CLASS_PREFIX + '-\\S+', 'g')) || []).join(' ');
+      }
+    }, {
+      key: '_fixTitle',
+      value: function _fixTitle() {
+        var 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', '');
+        }
+      }
+    }, {
+      key: '_enter',
+      value: function _enter(event, context) {
+        var 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.IN) || context._hoverState === HoverState.IN) {
+          context._hoverState = HoverState.IN;
+          return;
+        }
+
+        clearTimeout(context._timeout);
+
+        context._hoverState = HoverState.IN;
+
+        if (!context.config.delay || !context.config.delay.show) {
+          context.show();
+          return;
+        }
+
+        context._timeout = setTimeout(function () {
+          if (context._hoverState === HoverState.IN) {
+            context.show();
+          }
+        }, context.config.delay.show);
+      }
+    }, {
+      key: '_leave',
+      value: function _leave(event, context) {
+        var 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(function () {
+          if (context._hoverState === HoverState.OUT) {
+            context.hide();
+          }
+        }, context.config.delay.hide);
+      }
+    }, {
+      key: '_isWithActiveTrigger',
+      value: function _isWithActiveTrigger() {
+        for (var trigger in this._activeTrigger) {
+          if (this._activeTrigger[trigger]) {
+            return true;
+          }
+        }
+
+        return false;
+      }
+    }, {
+      key: '_getConfig',
+      value: function _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;
+      }
+    }, {
+      key: '_getDelegateConfig',
+      value: function _getDelegateConfig() {
+        var config = {};
+
+        if (this.config) {
+          for (var key in this.config) {
+            var value = this.config[key];
+            if (this.constructor.Default[key] !== value) {
+              config[key] = value;
+            }
+          }
+        }
+
+        return config;
+      }
+    }], [{
+      key: 'VERSION',
+
+      // getters
+
+      get: function () {
+        return VERSION;
+      }
+    }, {
+      key: 'Default',
+      get: function () {
+        return Default;
+      }
+    }, {
+      key: 'NAME',
+      get: function () {
+        return NAME;
+      }
+    }, {
+      key: 'DATA_KEY',
+      get: function () {
+        return DATA_KEY;
+      }
+    }, {
+      key: 'Event',
+      get: function () {
+        return Event;
+      }
+    }, {
+      key: 'EVENT_KEY',
+      get: function () {
+        return EVENT_KEY;
+      }
+    }, {
+      key: 'DefaultType',
+      get: function () {
+        return DefaultType;
+      }
+    }, {
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+          var _config = typeof config === 'object' ? config : null;
+
+          if (!data && /destroy|hide/.test(config)) {
+            return;
+          }
+
+          if (!data) {
+            data = new Tooltip(this, _config);
+            $(this).data(DATA_KEY, data);
+          }
+
+          if (typeof config === 'string') {
+            data[config]();
+          }
+        });
+      }
+    }]);
+
+    return Tooltip;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = Tooltip._jQueryInterface;
+  $.fn[NAME].Constructor = Tooltip;
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Tooltip._jQueryInterface;
+  };
+
+  return Tooltip;
+})(jQuery);
+//# sourceMappingURL=tooltip.js.map
\ No newline at end of file
diff --git a/js/dist/tooltip.js.map b/js/dist/tooltip.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..e823424cb71ebd8ad1152c437a1cf8e9176a2066
Binary files /dev/null and b/js/dist/tooltip.js.map differ
diff --git a/js/dist/util.js b/js/dist/util.js
new file mode 100644
index 0000000000000000000000000000000000000000..a135c3f385fa3cf68073bcfdae49a9b907811e84
--- /dev/null
+++ b/js/dist/util.js
@@ -0,0 +1,151 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): util.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+'use strict';
+
+var Util = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Private TransitionEnd Helpers
+   * ------------------------------------------------------------------------
+   */
+
+  var transition = false;
+
+  var 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: function handle(event) {
+        if ($(event.target).is(this)) {
+          return event.handleObj.handler.apply(this, arguments);
+        }
+      }
+    };
+  }
+
+  function transitionEndTest() {
+    if (window.QUnit) {
+      return false;
+    }
+
+    var el = document.createElement('bootstrap');
+
+    for (var name in TransitionEndEvent) {
+      if (el.style[name] !== undefined) {
+        return { end: TransitionEndEvent[name] };
+      }
+    }
+
+    return false;
+  }
+
+  function transitionEndEmulator(duration) {
+    var _this = this;
+
+    var called = false;
+
+    $(this).one(Util.TRANSITION_END, function () {
+      called = true;
+    });
+
+    setTimeout(function () {
+      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
+   * --------------------------------------------------------------------------
+   */
+
+  var Util = {
+
+    TRANSITION_END: 'bsTransitionEnd',
+
+    getUID: function getUID(prefix) {
+      do prefix += ~ ~(Math.random() * 1000000); while (document.getElementById(prefix));
+      return prefix;
+    },
+
+    getSelectorFromElement: function getSelectorFromElement(element) {
+      var selector = element.getAttribute('data-target');
+
+      if (!selector) {
+        selector = element.getAttribute('href') || '';
+        selector = /^#[a-z]/i.test(selector) ? selector : null;
+      }
+
+      return selector;
+    },
+
+    reflow: function reflow(element) {
+      new Function('bs', 'return bs')(element.offsetHeight);
+    },
+
+    triggerTransitionEnd: function triggerTransitionEnd(element) {
+      $(element).trigger(transition.end);
+    },
+
+    supportsTransitionEnd: function supportsTransitionEnd() {
+      return !!transition;
+    },
+
+    typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
+
+      for (var property in configTypes) {
+        var expectedTypes = configTypes[property];
+        var value = config[property];
+        var valueType = undefined;
+
+        if (value && isElement(value)) valueType = 'element';else valueType = 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);
+//# sourceMappingURL=util.js.map
\ No newline at end of file
diff --git a/js/dist/util.js.map b/js/dist/util.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..7c73c492e64d7d98d334591b132fbf4ce9bf0991
Binary files /dev/null and b/js/dist/util.js.map differ
diff --git a/js/dropdown.js b/js/dropdown.js
deleted file mode 100644
index 8fd86a025409e276c22271567d8d267f7bb2f9de..0000000000000000000000000000000000000000
--- a/js/dropdown.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/* ========================================================================
- * Bootstrap: dropdown.js v3.3.4
- * http://getbootstrap.com/javascript/#dropdowns
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // DROPDOWN CLASS DEFINITION
-  // =========================
-
-  var backdrop = '.dropdown-backdrop'
-  var toggle   = '[data-toggle="dropdown"]'
-  var Dropdown = function (element) {
-    $(element).on('click.bs.dropdown', this.toggle)
-  }
-
-  Dropdown.VERSION = '3.3.4'
-
-  function getParent($this) {
-    var selector = $this.attr('data-target')
-
-    if (!selector) {
-      selector = $this.attr('href')
-      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
-    }
-
-    var $parent = selector && $(selector)
-
-    return $parent && $parent.length ? $parent : $this.parent()
-  }
-
-  function clearMenus(e) {
-    if (e && e.which === 3) return
-    $(backdrop).remove()
-    $(toggle).each(function () {
-      var $this         = $(this)
-      var $parent       = getParent($this)
-      var relatedTarget = { relatedTarget: this }
-
-      if (!$parent.hasClass('open')) return
-
-      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
-
-      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
-
-      if (e.isDefaultPrevented()) return
-
-      $this.attr('aria-expanded', 'false')
-      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
-    })
-  }
-
-  Dropdown.prototype.toggle = function (e) {
-    var $this = $(this)
-
-    if ($this.is('.disabled, :disabled')) return
-
-    var $parent  = getParent($this)
-    var isActive = $parent.hasClass('open')
-
-    clearMenus()
-
-    if (!isActive) {
-      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
-        // if mobile we use a backdrop because click events don't delegate
-        $(document.createElement('div'))
-          .addClass('dropdown-backdrop')
-          .insertAfter($(this))
-          .on('click', clearMenus)
-      }
-
-      var relatedTarget = { relatedTarget: this }
-      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
-
-      if (e.isDefaultPrevented()) return
-
-      $this
-        .trigger('focus')
-        .attr('aria-expanded', 'true')
-
-      $parent
-        .toggleClass('open')
-        .trigger('shown.bs.dropdown', relatedTarget)
-    }
-
-    return false
-  }
-
-  Dropdown.prototype.keydown = function (e) {
-    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
-
-    var $this = $(this)
-
-    e.preventDefault()
-    e.stopPropagation()
-
-    if ($this.is('.disabled, :disabled')) return
-
-    var $parent  = getParent($this)
-    var isActive = $parent.hasClass('open')
-
-    if (!isActive && e.which != 27 || isActive && e.which == 27) {
-      if (e.which == 27) $parent.find(toggle).trigger('focus')
-      return $this.trigger('click')
-    }
-
-    var desc = ' li:not(.disabled):visible a'
-    var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
-
-    if (!$items.length) return
-
-    var index = $items.index(e.target)
-
-    if (e.which == 38 && index > 0)                 index--         // up
-    if (e.which == 40 && index < $items.length - 1) index++         // down
-    if (!~index)                                    index = 0
-
-    $items.eq(index).trigger('focus')
-  }
-
-
-  // DROPDOWN PLUGIN DEFINITION
-  // ==========================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this = $(this)
-      var data  = $this.data('bs.dropdown')
-
-      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
-      if (typeof option == 'string') data[option].call($this)
-    })
-  }
-
-  var old = $.fn.dropdown
-
-  $.fn.dropdown             = Plugin
-  $.fn.dropdown.Constructor = Dropdown
-
-
-  // DROPDOWN NO CONFLICT
-  // ====================
-
-  $.fn.dropdown.noConflict = function () {
-    $.fn.dropdown = old
-    return this
-  }
-
-
-  // APPLY TO STANDARD DROPDOWN ELEMENTS
-  // ===================================
-
-  $(document)
-    .on('click.bs.dropdown.data-api', clearMenus)
-    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
-    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
-    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
-    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
-
-}(jQuery);
diff --git a/js/modal.js b/js/modal.js
deleted file mode 100644
index 0426561af69955886785c8d0e506eee08d9a68e4..0000000000000000000000000000000000000000
--- a/js/modal.js
+++ /dev/null
@@ -1,337 +0,0 @@
-/* ========================================================================
- * Bootstrap: modal.js v3.3.4
- * http://getbootstrap.com/javascript/#modals
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // MODAL CLASS DEFINITION
-  // ======================
-
-  var Modal = function (element, options) {
-    this.options             = options
-    this.$body               = $(document.body)
-    this.$element            = $(element)
-    this.$dialog             = this.$element.find('.modal-dialog')
-    this.$backdrop           = null
-    this.isShown             = null
-    this.originalBodyPad     = null
-    this.scrollbarWidth      = 0
-    this.ignoreBackdropClick = false
-
-    if (this.options.remote) {
-      this.$element
-        .find('.modal-content')
-        .load(this.options.remote, $.proxy(function () {
-          this.$element.trigger('loaded.bs.modal')
-        }, this))
-    }
-  }
-
-  Modal.VERSION  = '3.3.4'
-
-  Modal.TRANSITION_DURATION = 300
-  Modal.BACKDROP_TRANSITION_DURATION = 150
-
-  Modal.DEFAULTS = {
-    backdrop: true,
-    keyboard: true,
-    show: true
-  }
-
-  Modal.prototype.toggle = function (_relatedTarget) {
-    return this.isShown ? this.hide() : this.show(_relatedTarget)
-  }
-
-  Modal.prototype.show = function (_relatedTarget) {
-    var that = this
-    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
-
-    this.$element.trigger(e)
-
-    if (this.isShown || e.isDefaultPrevented()) return
-
-    this.isShown = true
-
-    this.checkScrollbar()
-    this.setScrollbar()
-    this.$body.addClass('modal-open')
-
-    this.escape()
-    this.resize()
-
-    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
-
-    this.$dialog.on('mousedown.dismiss.bs.modal', function () {
-      that.$element.one('mouseup.dismiss.bs.modal', function (e) {
-        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
-      })
-    })
-
-    this.backdrop(function () {
-      var transition = $.support.transition && that.$element.hasClass('fade')
-
-      if (!that.$element.parent().length) {
-        that.$element.appendTo(that.$body) // don't move modals dom position
-      }
-
-      that.$element
-        .show()
-        .scrollTop(0)
-
-      that.adjustDialog()
-
-      if (transition) {
-        that.$element[0].offsetWidth // force reflow
-      }
-
-      that.$element.addClass('in')
-
-      that.enforceFocus()
-
-      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
-
-      transition ?
-        that.$dialog // wait for modal to slide in
-          .one('bsTransitionEnd', function () {
-            that.$element.trigger('focus').trigger(e)
-          })
-          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
-        that.$element.trigger('focus').trigger(e)
-    })
-  }
-
-  Modal.prototype.hide = function (e) {
-    if (e) e.preventDefault()
-
-    e = $.Event('hide.bs.modal')
-
-    this.$element.trigger(e)
-
-    if (!this.isShown || e.isDefaultPrevented()) return
-
-    this.isShown = false
-
-    this.escape()
-    this.resize()
-
-    $(document).off('focusin.bs.modal')
-
-    this.$element
-      .removeClass('in')
-      .off('click.dismiss.bs.modal')
-      .off('mouseup.dismiss.bs.modal')
-
-    this.$dialog.off('mousedown.dismiss.bs.modal')
-
-    $.support.transition && this.$element.hasClass('fade') ?
-      this.$element
-        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
-        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
-      this.hideModal()
-  }
-
-  Modal.prototype.enforceFocus = function () {
-    $(document)
-      .off('focusin.bs.modal') // guard against infinite focus loop
-      .on('focusin.bs.modal', $.proxy(function (e) {
-        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
-          this.$element.trigger('focus')
-        }
-      }, this))
-  }
-
-  Modal.prototype.escape = function () {
-    if (this.isShown && this.options.keyboard) {
-      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
-        e.which == 27 && this.hide()
-      }, this))
-    } else if (!this.isShown) {
-      this.$element.off('keydown.dismiss.bs.modal')
-    }
-  }
-
-  Modal.prototype.resize = function () {
-    if (this.isShown) {
-      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
-    } else {
-      $(window).off('resize.bs.modal')
-    }
-  }
-
-  Modal.prototype.hideModal = function () {
-    var that = this
-    this.$element.hide()
-    this.backdrop(function () {
-      that.$body.removeClass('modal-open')
-      that.resetAdjustments()
-      that.resetScrollbar()
-      that.$element.trigger('hidden.bs.modal')
-    })
-  }
-
-  Modal.prototype.removeBackdrop = function () {
-    this.$backdrop && this.$backdrop.remove()
-    this.$backdrop = null
-  }
-
-  Modal.prototype.backdrop = function (callback) {
-    var that = this
-    var animate = this.$element.hasClass('fade') ? 'fade' : ''
-
-    if (this.isShown && this.options.backdrop) {
-      var doAnimate = $.support.transition && animate
-
-      this.$backdrop = $(document.createElement('div'))
-        .addClass('modal-backdrop ' + animate)
-        .appendTo(this.$body)
-
-      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
-        if (this.ignoreBackdropClick) {
-          this.ignoreBackdropClick = false
-          return
-        }
-        if (e.target !== e.currentTarget) return
-        this.options.backdrop == 'static'
-          ? this.$element[0].focus()
-          : this.hide()
-      }, this))
-
-      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
-
-      this.$backdrop.addClass('in')
-
-      if (!callback) return
-
-      doAnimate ?
-        this.$backdrop
-          .one('bsTransitionEnd', callback)
-          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
-        callback()
-
-    } else if (!this.isShown && this.$backdrop) {
-      this.$backdrop.removeClass('in')
-
-      var callbackRemove = function () {
-        that.removeBackdrop()
-        callback && callback()
-      }
-      $.support.transition && this.$element.hasClass('fade') ?
-        this.$backdrop
-          .one('bsTransitionEnd', callbackRemove)
-          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
-        callbackRemove()
-
-    } else if (callback) {
-      callback()
-    }
-  }
-
-  // these following methods are used to handle overflowing modals
-
-  Modal.prototype.handleUpdate = function () {
-    this.adjustDialog()
-  }
-
-  Modal.prototype.adjustDialog = function () {
-    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
-
-    this.$element.css({
-      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
-      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
-    })
-  }
-
-  Modal.prototype.resetAdjustments = function () {
-    this.$element.css({
-      paddingLeft: '',
-      paddingRight: ''
-    })
-  }
-
-  Modal.prototype.checkScrollbar = function () {
-    var fullWindowWidth = window.innerWidth
-    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
-      var documentElementRect = document.documentElement.getBoundingClientRect()
-      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
-    }
-    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
-    this.scrollbarWidth = this.measureScrollbar()
-  }
-
-  Modal.prototype.setScrollbar = function () {
-    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
-    this.originalBodyPad = document.body.style.paddingRight || ''
-    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
-  }
-
-  Modal.prototype.resetScrollbar = function () {
-    this.$body.css('padding-right', this.originalBodyPad)
-  }
-
-  Modal.prototype.measureScrollbar = function () { // thx walsh
-    var scrollDiv = document.createElement('div')
-    scrollDiv.className = 'modal-scrollbar-measure'
-    this.$body.append(scrollDiv)
-    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
-    this.$body[0].removeChild(scrollDiv)
-    return scrollbarWidth
-  }
-
-
-  // MODAL PLUGIN DEFINITION
-  // =======================
-
-  function Plugin(option, _relatedTarget) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.modal')
-      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
-
-      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
-      if (typeof option == 'string') data[option](_relatedTarget)
-      else if (options.show) data.show(_relatedTarget)
-    })
-  }
-
-  var old = $.fn.modal
-
-  $.fn.modal             = Plugin
-  $.fn.modal.Constructor = Modal
-
-
-  // MODAL NO CONFLICT
-  // =================
-
-  $.fn.modal.noConflict = function () {
-    $.fn.modal = old
-    return this
-  }
-
-
-  // MODAL DATA-API
-  // ==============
-
-  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
-    var $this   = $(this)
-    var href    = $this.attr('href')
-    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
-    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
-
-    if ($this.is('a')) e.preventDefault()
-
-    $target.one('show.bs.modal', function (showEvent) {
-      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
-      $target.one('hidden.bs.modal', function () {
-        $this.is(':visible') && $this.trigger('focus')
-      })
-    })
-    Plugin.call($target, option, this)
-  })
-
-}(jQuery);
diff --git a/js/popover.js b/js/popover.js
deleted file mode 100644
index 0b0755ee27bb7882fa6786c13408e2e8b0b3b7a7..0000000000000000000000000000000000000000
--- a/js/popover.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/* ========================================================================
- * Bootstrap: popover.js v3.3.4
- * http://getbootstrap.com/javascript/#popovers
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // POPOVER PUBLIC CLASS DEFINITION
-  // ===============================
-
-  var Popover = function (element, options) {
-    this.init('popover', element, options)
-  }
-
-  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
-
-  Popover.VERSION  = '3.3.4'
-
-  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
-    placement: 'right',
-    trigger: 'click',
-    content: '',
-    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
-  })
-
-
-  // NOTE: POPOVER EXTENDS tooltip.js
-  // ================================
-
-  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
-
-  Popover.prototype.constructor = Popover
-
-  Popover.prototype.getDefaults = function () {
-    return Popover.DEFAULTS
-  }
-
-  Popover.prototype.setContent = function () {
-    var $tip    = this.tip()
-    var title   = this.getTitle()
-    var content = this.getContent()
-
-    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
-    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
-      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
-    ](content)
-
-    $tip.removeClass('fade top bottom left right in')
-
-    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
-    // this manually by checking the contents.
-    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
-  }
-
-  Popover.prototype.hasContent = function () {
-    return this.getTitle() || this.getContent()
-  }
-
-  Popover.prototype.getContent = function () {
-    var $e = this.$element
-    var o  = this.options
-
-    return $e.attr('data-content')
-      || (typeof o.content == 'function' ?
-            o.content.call($e[0]) :
-            o.content)
-  }
-
-  Popover.prototype.arrow = function () {
-    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
-  }
-
-
-  // POPOVER PLUGIN DEFINITION
-  // =========================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.popover')
-      var options = typeof option == 'object' && option
-
-      if (!data && /destroy|hide/.test(option)) return
-      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
-
-  var old = $.fn.popover
-
-  $.fn.popover             = Plugin
-  $.fn.popover.Constructor = Popover
-
-
-  // POPOVER NO CONFLICT
-  // ===================
-
-  $.fn.popover.noConflict = function () {
-    $.fn.popover = old
-    return this
-  }
-
-}(jQuery);
diff --git a/js/scrollspy.js b/js/scrollspy.js
deleted file mode 100644
index f860c1abadb18cb798d118bbdada881b2c47002d..0000000000000000000000000000000000000000
--- a/js/scrollspy.js
+++ /dev/null
@@ -1,172 +0,0 @@
-/* ========================================================================
- * Bootstrap: scrollspy.js v3.3.4
- * http://getbootstrap.com/javascript/#scrollspy
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // SCROLLSPY CLASS DEFINITION
-  // ==========================
-
-  function ScrollSpy(element, options) {
-    this.$body          = $(document.body)
-    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
-    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
-    this.selector       = (this.options.target || '') + ' .nav li > a'
-    this.offsets        = []
-    this.targets        = []
-    this.activeTarget   = null
-    this.scrollHeight   = 0
-
-    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
-    this.refresh()
-    this.process()
-  }
-
-  ScrollSpy.VERSION  = '3.3.4'
-
-  ScrollSpy.DEFAULTS = {
-    offset: 10
-  }
-
-  ScrollSpy.prototype.getScrollHeight = function () {
-    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
-  }
-
-  ScrollSpy.prototype.refresh = function () {
-    var that          = this
-    var offsetMethod  = 'offset'
-    var offsetBase    = 0
-
-    this.offsets      = []
-    this.targets      = []
-    this.scrollHeight = this.getScrollHeight()
-
-    if (!$.isWindow(this.$scrollElement[0])) {
-      offsetMethod = 'position'
-      offsetBase   = this.$scrollElement.scrollTop()
-    }
-
-    this.$body
-      .find(this.selector)
-      .map(function () {
-        var $el   = $(this)
-        var href  = $el.data('target') || $el.attr('href')
-        var $href = /^#./.test(href) && $(href)
-
-        return ($href
-          && $href.length
-          && $href.is(':visible')
-          && [[$href[offsetMethod]().top + offsetBase, href]]) || null
-      })
-      .sort(function (a, b) { return a[0] - b[0] })
-      .each(function () {
-        that.offsets.push(this[0])
-        that.targets.push(this[1])
-      })
-  }
-
-  ScrollSpy.prototype.process = function () {
-    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
-    var scrollHeight = this.getScrollHeight()
-    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
-    var offsets      = this.offsets
-    var targets      = this.targets
-    var activeTarget = this.activeTarget
-    var i
-
-    if (this.scrollHeight != scrollHeight) {
-      this.refresh()
-    }
-
-    if (scrollTop >= maxScroll) {
-      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
-    }
-
-    if (activeTarget && scrollTop < offsets[0]) {
-      this.activeTarget = null
-      return this.clear()
-    }
-
-    for (i = offsets.length; i--;) {
-      activeTarget != targets[i]
-        && scrollTop >= offsets[i]
-        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
-        && this.activate(targets[i])
-    }
-  }
-
-  ScrollSpy.prototype.activate = function (target) {
-    this.activeTarget = target
-
-    this.clear()
-
-    var selector = this.selector +
-      '[data-target="' + target + '"],' +
-      this.selector + '[href="' + target + '"]'
-
-    var active = $(selector)
-      .parents('li')
-      .addClass('active')
-
-    if (active.parent('.dropdown-menu').length) {
-      active = active
-        .closest('li.dropdown')
-        .addClass('active')
-    }
-
-    active.trigger('activate.bs.scrollspy')
-  }
-
-  ScrollSpy.prototype.clear = function () {
-    $(this.selector)
-      .parentsUntil(this.options.target, '.active')
-      .removeClass('active')
-  }
-
-
-  // SCROLLSPY PLUGIN DEFINITION
-  // ===========================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.scrollspy')
-      var options = typeof option == 'object' && option
-
-      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
-
-  var old = $.fn.scrollspy
-
-  $.fn.scrollspy             = Plugin
-  $.fn.scrollspy.Constructor = ScrollSpy
-
-
-  // SCROLLSPY NO CONFLICT
-  // =====================
-
-  $.fn.scrollspy.noConflict = function () {
-    $.fn.scrollspy = old
-    return this
-  }
-
-
-  // SCROLLSPY DATA-API
-  // ==================
-
-  $(window).on('load.bs.scrollspy.data-api', function () {
-    $('[data-spy="scroll"]').each(function () {
-      var $spy = $(this)
-      Plugin.call($spy, $spy.data())
-    })
-  })
-
-}(jQuery);
diff --git a/js/src/alert.js b/js/src/alert.js
new file mode 100644
index 0000000000000000000000000000000000000000..eda74d7064704fdf773b5ebf64287577643f1516
--- /dev/null
+++ b/js/src/alert.js
@@ -0,0 +1,192 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): alert.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Alert = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  const NAME                = 'alert'
+  const VERSION             = '4.0.0'
+  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',
+    IN    : 'in'
+  }
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  class Alert {
+
+    constructor(element) {
+      this._element = element
+    }
+
+
+    // getters
+
+    static get VERSION() {
+      return VERSION
+    }
+
+
+    // public
+
+    close(element) {
+      element = element || this._element
+
+      let rootElement = this._getRootElement(element)
+      let customEvent = this._triggerCloseEvent(rootElement)
+
+      if (customEvent.isDefaultPrevented()) {
+        return
+      }
+
+      this._removeElement(rootElement)
+    }
+
+    dispose() {
+      $.removeData(this._element, DATA_KEY)
+      this._element = null
+    }
+
+
+    // private
+
+    _getRootElement(element) {
+      let parent   = false
+      let selector = Util.getSelectorFromElement(element)
+
+      if (selector) {
+        parent = $(selector)[0]
+      }
+
+      if (!parent) {
+        parent = $(element).closest(`.${ClassName.ALERT}`)[0]
+      }
+
+      return parent
+    }
+
+    _triggerCloseEvent(element) {
+      var closeEvent = $.Event(Event.CLOSE)
+      $(element).trigger(closeEvent)
+      return closeEvent
+    }
+
+    _removeElement(element) {
+      $(element).removeClass(ClassName.IN)
+
+      if (!Util.supportsTransitionEnd() ||
+          !$(element).hasClass(ClassName.FADE)) {
+        this._destroyElement(element)
+        return
+      }
+
+      $(element)
+        .one(Util.TRANSITION_END, this._destroyElement.bind(this, element))
+        .emulateTransitionEnd(TRANSITION_DURATION)
+    }
+
+    _destroyElement(element) {
+      $(element)
+        .detach()
+        .trigger(Event.CLOSED)
+        .remove()
+    }
+
+
+    // static
+
+    static _jQueryInterface(config) {
+      return this.each(function () {
+        let $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/js/src/button.js b/js/src/button.js
new file mode 100644
index 0000000000000000000000000000000000000000..8210e8ae072e091623f2280f4d3ba5501fb35211
--- /dev/null
+++ b/js/src/button.js
@@ -0,0 +1,174 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): button.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Button = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  const NAME                = 'button'
+  const VERSION             = '4.0.0'
+  const DATA_KEY            = 'bs.button'
+  const EVENT_KEY           = `.${DATA_KEY}`
+  const DATA_API_KEY        = '.data-api'
+  const JQUERY_NO_CONFLICT  = $.fn[NAME]
+  const TRANSITION_DURATION = 150
+
+  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
+      let rootElement = $(this._element).closest(
+        Selector.DATA_TOGGLE
+      )[0]
+
+      if (rootElement) {
+        let input = $(this._element).find(Selector.INPUT)[0]
+
+        if (input) {
+          if (input.type === 'radio') {
+            if (input.checked &&
+              $(this._element).hasClass(ClassName.ACTIVE)) {
+              triggerChangeEvent = false
+
+            } else {
+              let activeElement = $(rootElement).find(Selector.ACTIVE)[0]
+
+              if (activeElement) {
+                $(activeElement).removeClass(ClassName.ACTIVE)
+              }
+            }
+          }
+
+          if (triggerChangeEvent) {
+            input.checked = !$(this._element).hasClass(ClassName.ACTIVE)
+            $(this._element).trigger('change')
+          }
+        }
+      } else {
+        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, function (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, function (event) {
+      var 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/js/src/carousel.js b/js/src/carousel.js
new file mode 100644
index 0000000000000000000000000000000000000000..c11f0a599d5752b2d126a32e1995db6c6407126c
--- /dev/null
+++ b/js/src/carousel.js
@@ -0,0 +1,468 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): carousel.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Carousel = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  const NAME                = 'carousel'
+  const VERSION             = '4.0.0'
+  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 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',
+    PREVIOUS : 'prev'
+  }
+
+  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    : 'right',
+    LEFT     : 'left',
+    ITEM     : 'carousel-item'
+  }
+
+  const Selector = {
+    ACTIVE      : '.active',
+    ACTIVE_ITEM : '.active.carousel-item',
+    ITEM        : '.carousel-item',
+    NEXT_PREV   : '.next, .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) {
+        this._slide(Direction.NEXT)
+      }
+    }
+
+    prev() {
+      if (!this._isSliding) {
+        this._slide(Direction.PREVIOUS)
+      }
+    }
+
+    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(
+          $.proxy(this.next, this), this._config.interval
+        )
+      }
+    }
+
+    to(index) {
+      this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]
+
+      let 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
+      }
+
+      var direction = index > activeIndex ?
+        Direction.NEXT :
+        Direction.PREVIOUS
+
+      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, $.proxy(this._keydown, this))
+      }
+
+      if (this._config.pause == 'hover' &&
+        !('ontouchstart' in document.documentElement)) {
+        $(this._element)
+          .on(Event.MOUSEENTER, $.proxy(this.pause, this))
+          .on(Event.MOUSELEAVE, $.proxy(this.cycle, this))
+      }
+    }
+
+    _keydown(event) {
+      event.preventDefault()
+
+      if (/input|textarea/i.test(event.target.tagName)) return
+
+      switch (event.which) {
+        case 37: this.prev(); break
+        case 39: this.next(); break
+        default: return
+      }
+    }
+
+    _getItemIndex(element) {
+      this._items = $.makeArray($(element).parent().find(Selector.ITEM))
+      return this._items.indexOf(element)
+    }
+
+    _getItemByDirection(direction, activeElement) {
+      let isNextDirection = direction === Direction.NEXT
+      let isPrevDirection = direction === Direction.PREVIOUS
+      let activeIndex     = this._getItemIndex(activeElement)
+      let lastItemIndex   = (this._items.length - 1)
+      let isGoingToWrap   = (isPrevDirection && activeIndex === 0) ||
+                            (isNextDirection && activeIndex == lastItemIndex)
+
+      if (isGoingToWrap && !this._config.wrap) {
+        return activeElement
+      }
+
+      let delta     = direction == Direction.PREVIOUS ? -1 : 1
+      let itemIndex = (activeIndex + delta) % this._items.length
+
+      return itemIndex === -1 ?
+        this._items[this._items.length - 1] : this._items[itemIndex]
+    }
+
+
+    _triggerSlideEvent(relatedTarget, directionalClassname) {
+      let slideEvent = $.Event(Event.SLIDE, {
+        relatedTarget: relatedTarget,
+        direction: directionalClassname
+      })
+
+      $(this._element).trigger(slideEvent)
+
+      return slideEvent
+    }
+
+    _setActiveIndicatorElement(element) {
+      if (this._indicatorsElement) {
+        $(this._indicatorsElement)
+          .find(Selector.ACTIVE)
+          .removeClass(ClassName.ACTIVE)
+
+        let nextIndicator = this._indicatorsElement.children[
+          this._getItemIndex(element)
+        ]
+
+        if (nextIndicator) {
+          $(nextIndicator).addClass(ClassName.ACTIVE)
+        }
+      }
+    }
+
+    _slide(direction, element) {
+      let activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]
+      let nextElement   = element || activeElement &&
+        this._getItemByDirection(direction, activeElement)
+
+      let isCycling = !!this._interval
+
+      let directionalClassName = direction == Direction.NEXT ?
+        ClassName.LEFT :
+        ClassName.RIGHT
+
+      if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {
+        this._isSliding = false
+        return
+      }
+
+      let slideEvent = this._triggerSlideEvent(nextElement, directionalClassName)
+      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)
+
+      var slidEvent = $.Event(Event.SLID, {
+        relatedTarget: nextElement,
+        direction: directionalClassName
+      })
+
+      if (Util.supportsTransitionEnd() &&
+        $(this._element).hasClass(ClassName.SLIDE)) {
+
+        $(nextElement).addClass(direction)
+
+        Util.reflow(nextElement)
+
+        $(activeElement).addClass(directionalClassName)
+        $(nextElement).addClass(directionalClassName)
+
+        $(activeElement)
+          .one(Util.TRANSITION_END, () => {
+            $(nextElement)
+              .removeClass(directionalClassName)
+              .removeClass(direction)
+
+            $(nextElement).addClass(ClassName.ACTIVE)
+
+            $(activeElement)
+              .removeClass(ClassName.ACTIVE)
+              .removeClass(direction)
+              .removeClass(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)
+        let _config = $.extend({}, Default, $(this).data())
+
+        if (typeof config === 'object') {
+          $.extend(_config, config)
+        }
+
+        let 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 (action) {
+          data[action]()
+
+        } else if (_config.interval) {
+          data.pause()
+          data.cycle()
+        }
+      })
+    }
+
+    static _dataApiClickHandler(event) {
+      let selector = Util.getSelectorFromElement(this)
+
+      if (!selector) {
+        return
+      }
+
+      let target = $(selector)[0]
+
+      if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {
+        return
+      }
+
+      let config = $.extend({}, $(target).data(), $(this).data())
+
+      let 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, function () {
+    $(Selector.DATA_RIDE).each(function () {
+      let $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/js/src/collapse.js b/js/src/collapse.js
new file mode 100644
index 0000000000000000000000000000000000000000..e911c98d1da39b4cf62f2303653491b561d90e4d
--- /dev/null
+++ b/js/src/collapse.js
@@ -0,0 +1,379 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): collapse.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Collapse = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  const NAME                = 'collapse'
+  const VERSION             = '4.0.0'
+  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 = {
+    IN         : 'in',
+    COLLAPSE   : 'collapse',
+    COLLAPSING : 'collapsing',
+    COLLAPSED  : 'collapsed'
+  }
+
+  const Dimension = {
+    WIDTH  : 'width',
+    HEIGHT : 'height'
+  }
+
+  const Selector = {
+    ACTIVES     : '.panel > .in, .panel > .collapsing',
+    DATA_TOGGLE : '[data-toggle="collapse"]'
+  }
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * 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)
+      }
+
+      if (this._config.toggle) {
+        this.toggle()
+      }
+    }
+
+
+    // getters
+
+    static get VERSION() {
+      return VERSION
+    }
+
+    static get Default() {
+      return Default
+    }
+
+
+    // public
+
+    toggle() {
+      if ($(this._element).hasClass(ClassName.IN)) {
+        this.hide()
+      } else {
+        this.show()
+      }
+    }
+
+    show() {
+      if (this._isTransitioning ||
+        $(this._element).hasClass(ClassName.IN)) {
+        return
+      }
+
+      let actives
+      let activesData
+
+      if (this._parent) {
+        actives = $.makeArray($(Selector.ACTIVES))
+        if (!actives.length) {
+          actives = null
+        }
+      }
+
+      if (actives) {
+        activesData = $(actives).data(DATA_KEY)
+        if (activesData && activesData._isTransitioning) {
+          return
+        }
+      }
+
+      let 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)
+        }
+      }
+
+      let 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)
+
+      let complete = () => {
+        $(this._element)
+          .removeClass(ClassName.COLLAPSING)
+          .addClass(ClassName.COLLAPSE)
+          .addClass(ClassName.IN)
+
+        this._element.style[dimension] = ''
+
+        this.setTransitioning(false)
+
+        $(this._element).trigger(Event.SHOWN)
+      }
+
+      if (!Util.supportsTransitionEnd()) {
+        complete()
+        return
+      }
+
+      let scrollSize = 'scroll'
+        + (dimension[0].toUpperCase()
+        + dimension.slice(1))
+
+      $(this._element)
+        .one(Util.TRANSITION_END, complete)
+        .emulateTransitionEnd(TRANSITION_DURATION)
+
+      this._element.style[dimension] = this._element[scrollSize] + 'px'
+    }
+
+    hide() {
+      if (this._isTransitioning ||
+        !$(this._element).hasClass(ClassName.IN)) {
+        return
+      }
+
+      let startEvent = $.Event(Event.HIDE)
+      $(this._element).trigger(startEvent)
+      if (startEvent.isDefaultPrevented()) {
+        return
+      }
+
+      let dimension = this._getDimension()
+      let offsetDimension = dimension === Dimension.WIDTH ?
+        'offsetWidth' : 'offsetHeight'
+
+      this._element.style[dimension] = this._element[offsetDimension] + 'px'
+
+      Util.reflow(this._element)
+
+      $(this._element)
+        .addClass(ClassName.COLLAPSING)
+        .removeClass(ClassName.COLLAPSE)
+        .removeClass(ClassName.IN)
+
+      this._element.setAttribute('aria-expanded', false)
+
+      if (this._triggerArray.length) {
+        $(this._triggerArray)
+          .addClass(ClassName.COLLAPSED)
+          .attr('aria-expanded', false)
+      }
+
+      this.setTransitioning(true)
+
+      let complete = () => {
+        this.setTransitioning(false)
+        $(this._element)
+          .removeClass(ClassName.COLLAPSING)
+          .addClass(ClassName.COLLAPSE)
+          .trigger(Event.HIDDEN)
+      }
+
+      this._element.style[dimension] = 0
+
+      if (!Util.supportsTransitionEnd()) {
+        return complete()
+      }
+
+      $(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 = !!config.toggle // coerce string values
+      Util.typeCheckConfig(NAME, config, DefaultType)
+      return config
+    }
+
+    _getDimension() {
+      let hasWidth = $(this._element).hasClass(Dimension.WIDTH)
+      return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT
+    }
+
+    _getParent() {
+      let parent   = $(this._config.parent)[0]
+      let 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) {
+        let isOpen = $(element).hasClass(ClassName.IN)
+        element.setAttribute('aria-expanded', isOpen)
+
+        if (triggerArray.length) {
+          $(triggerArray)
+            .toggleClass(ClassName.COLLAPSED, !isOpen)
+            .attr('aria-expanded', isOpen)
+        }
+      }
+    }
+
+
+    // static
+
+    static _getTargetFromElement(element) {
+      let selector = Util.getSelectorFromElement(element)
+      return selector ? $(selector)[0] : null
+    }
+
+    static _jQueryInterface(config) {
+      return this.each(function () {
+        let $this   = $(this)
+        let data    = $this.data(DATA_KEY)
+        let _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') {
+          data[config]()
+        }
+      })
+    }
+
+  }
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+    event.preventDefault()
+
+    let target = Collapse._getTargetFromElement(this)
+
+    let data = $(target).data(DATA_KEY)
+    let 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/js/src/dropdown.js b/js/src/dropdown.js
new file mode 100644
index 0000000000000000000000000000000000000000..bae0f7adb2261491276f6c38382add5fd373b336
--- /dev/null
+++ b/js/src/dropdown.js
@@ -0,0 +1,286 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): dropdown.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Dropdown = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  const NAME                = 'dropdown'
+  const VERSION             = '4.0.0'
+  const DATA_KEY            = 'bs.dropdown'
+  const EVENT_KEY           = `.${DATA_KEY}`
+  const DATA_API_KEY        = '.data-api'
+  const JQUERY_NO_CONFLICT  = $.fn[NAME]
+
+  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}`,
+    KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`
+  }
+
+  const ClassName = {
+    BACKDROP : 'dropdown-backdrop',
+    DISABLED : 'disabled',
+    OPEN     : 'open'
+  }
+
+  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
+      }
+
+      let parent   = Dropdown._getParentFromElement(this)
+      let isActive = $(parent).hasClass(ClassName.OPEN)
+
+      Dropdown._clearMenus()
+
+      if (isActive) {
+        return false
+      }
+
+      if ('ontouchstart' in document.documentElement &&
+         (!$(parent).closest(Selector.NAVBAR_NAV).length)) {
+
+        // if mobile we use a backdrop because click events don't delegate
+        let dropdown       = document.createElement('div')
+        dropdown.className = ClassName.BACKDROP
+        $(dropdown).insertBefore(this)
+        $(dropdown).on('click', Dropdown._clearMenus)
+      }
+
+      let relatedTarget = { relatedTarget : this }
+      let showEvent     = $.Event(Event.SHOW, relatedTarget)
+
+      $(parent).trigger(showEvent)
+
+      if (showEvent.isDefaultPrevented()) {
+        return
+      }
+
+      this.focus()
+      this.setAttribute('aria-expanded', 'true')
+
+      $(parent).toggleClass(ClassName.OPEN)
+      $(parent).trigger(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) {
+          $(this).data(DATA_KEY, (data = new Dropdown(this)))
+        }
+
+        if (typeof config === 'string') {
+          data[config].call(this)
+        }
+      })
+    }
+
+    static _clearMenus(event) {
+      if (event && event.which === 3) {
+        return
+      }
+
+      let backdrop = $(Selector.BACKDROP)[0]
+      if (backdrop) {
+        backdrop.parentNode.removeChild(backdrop)
+      }
+
+      let toggles = $.makeArray($(Selector.DATA_TOGGLE))
+
+      for (let i = 0; i < toggles.length; i++) {
+        let parent        = Dropdown._getParentFromElement(toggles[i])
+        let relatedTarget = { relatedTarget : toggles[i] }
+
+        if (!$(parent).hasClass(ClassName.OPEN)) {
+          continue
+        }
+
+        if (event && event.type === 'click' &&
+           (/input|textarea/i.test(event.target.tagName)) &&
+           ($.contains(parent, event.target))) {
+          continue
+        }
+
+        let hideEvent = $.Event(Event.HIDE, relatedTarget)
+        $(parent).trigger(hideEvent)
+        if (hideEvent.isDefaultPrevented()) {
+          continue
+        }
+
+        toggles[i].setAttribute('aria-expanded', 'false')
+
+        $(parent)
+          .removeClass(ClassName.OPEN)
+          .trigger(Event.HIDDEN, relatedTarget)
+      }
+    }
+
+    static _getParentFromElement(element) {
+      let parent
+      let selector = Util.getSelectorFromElement(element)
+
+      if (selector) {
+        parent = $(selector)[0]
+      }
+
+      return parent || element.parentNode
+    }
+
+    static _dataApiKeydownHandler(event) {
+      if (!/(38|40|27|32)/.test(event.which) ||
+         /input|textarea/i.test(event.target.tagName)) {
+        return
+      }
+
+      event.preventDefault()
+      event.stopPropagation()
+
+      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+        return
+      }
+
+      let parent   = Dropdown._getParentFromElement(this)
+      let isActive = $(parent).hasClass(ClassName.OPEN)
+
+      if ((!isActive && event.which !== 27) ||
+           (isActive && event.which === 27)) {
+
+        if (event.which === 27) {
+          let toggle = $(parent).find(Selector.DATA_TOGGLE)[0]
+          $(toggle).trigger('focus')
+        }
+
+        $(this).trigger('click')
+        return
+      }
+
+      let items = $.makeArray($(Selector.VISIBLE_ITEMS))
+
+      items = items.filter((item) => {
+        return item.offsetWidth || item.offsetHeight
+      })
+
+      if (!items.length) {
+        return
+      }
+
+      let index = items.indexOf(event.target)
+
+      if (event.which === 38 && index > 0)                index--  // up
+      if (event.which === 40 && index < items.length - 1) index++  // down
+      if (!~index)                                        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, Dropdown._clearMenus)
+    .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle)
+    .on(Event.CLICK_DATA_API, Selector.FORM_CHILD,  function (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/js/src/modal.js b/js/src/modal.js
new file mode 100644
index 0000000000000000000000000000000000000000..2ca603b23ba07c3255e2010b7085206a5682be63
--- /dev/null
+++ b/js/src/modal.js
@@ -0,0 +1,527 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): modal.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Modal = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  const NAME                         = 'modal'
+  const VERSION                      = '4.0.0'
+  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 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 = {
+    BACKDROP : 'modal-backdrop',
+    OPEN     : 'modal-open',
+    FADE     : 'fade',
+    IN       : 'in'
+  }
+
+  const Selector = {
+    DIALOG             : '.modal-dialog',
+    DATA_TOGGLE        : '[data-toggle="modal"]',
+    DATA_DISMISS       : '[data-dismiss="modal"]',
+    SCROLLBAR_MEASURER : 'modal-scrollbar-measure'
+  }
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * 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._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) {
+      let showEvent = $.Event(Event.SHOW, {
+        relatedTarget: 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,
+        $.proxy(this.hide, this)
+      )
+
+      $(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => {
+        $(this._element).one(Event.MOUSEUP_DISMISS, (event) => {
+          if ($(event.target).is(this._element)) {
+            that._ignoreBackdropClick = true
+          }
+        })
+      })
+
+      this._showBackdrop(
+        $.proxy(this._showElement, this, relatedTarget)
+      )
+    }
+
+    hide(event) {
+      if (event) {
+        event.preventDefault()
+      }
+
+      let 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.IN)
+
+      $(this._element).off(Event.CLICK_DISMISS)
+      $(this._dialog).off(Event.MOUSEDOWN_DISMISS)
+
+      if (Util.supportsTransitionEnd() &&
+         ($(this._element).hasClass(ClassName.FADE))) {
+
+        $(this._element)
+          .one(Util.TRANSITION_END, $.proxy(this._hideModal, this))
+          .emulateTransitionEnd(TRANSITION_DURATION)
+      } else {
+        this._hideModal()
+      }
+    }
+
+    dispose() {
+      $.removeData(this._element, DATA_KEY)
+
+      $(window).off(EVENT_KEY)
+      $(document).off(EVENT_KEY)
+      $(this._element).off(EVENT_KEY)
+      $(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) {
+      let 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.scrollTop = 0
+
+      if (transition) {
+        Util.reflow(this._element)
+      }
+
+      $(this._element).addClass(ClassName.IN)
+
+      if (this._config.focus) this._enforceFocus()
+
+      let shownEvent = $.Event(Event.SHOWN, {
+        relatedTarget: relatedTarget
+      })
+
+      let transitionComplete = () => {
+        if (this._config.focus) this._element.focus()
+        $(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 (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 === 27) {
+            this.hide()
+          }
+        })
+
+      } else if (!this._isShown) {
+        $(this._element).off(Event.KEYDOWN_DISMISS)
+      }
+    }
+
+    _setResizeEvent() {
+      if (this._isShown) {
+        $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this))
+      } else {
+        $(window).off(Event.RESIZE)
+      }
+    }
+
+    _hideModal() {
+      this._element.style.display = 'none'
+      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) {
+      let animate = $(this._element).hasClass(ClassName.FADE) ?
+        ClassName.FADE : ''
+
+      if (this._isShown && this._config.backdrop) {
+        let doAnimate = Util.supportsTransitionEnd() && animate
+
+        this._backdrop = document.createElement('div')
+        this._backdrop.className = ClassName.BACKDROP
+
+        if (animate) {
+          $(this._backdrop).addClass(animate)
+        }
+
+        $(this._backdrop).appendTo(this.$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.IN)
+
+        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.IN)
+
+        let 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() {
+      let 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() {
+      let fullWindowWidth = window.innerWidth
+      if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
+        let documentElementRect = document.documentElement.getBoundingClientRect()
+        fullWindowWidth =
+          documentElementRect.right - Math.abs(documentElementRect.left)
+      }
+      this._isBodyOverflowing = document.body.clientWidth < fullWindowWidth
+      this._scrollbarWidth = this._getScrollbarWidth()
+    }
+
+    _setScrollbar() {
+      let bodyPadding = parseInt(
+        $(document.body).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
+      let scrollDiv = document.createElement('div')
+      scrollDiv.className = Selector.SCROLLBAR_MEASURER
+      document.body.appendChild(scrollDiv)
+      let scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
+      document.body.removeChild(scrollDiv)
+      return scrollbarWidth
+    }
+
+
+    // static
+
+    static _jQueryInterface(config, relatedTarget) {
+      return this.each(function () {
+        let data    = $(this).data(DATA_KEY)
+        let _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') {
+          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
+    let selector = Util.getSelectorFromElement(this)
+
+    if (selector) {
+      target = $(selector)[0]
+    }
+
+    let config = $(target).data(DATA_KEY) ?
+      'toggle' : $.extend({}, $(target).data(), $(this).data())
+
+    if (this.tagName === 'A') {
+      event.preventDefault()
+    }
+
+    let $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/js/src/popover.js b/js/src/popover.js
new file mode 100644
index 0000000000000000000000000000000000000000..31c7a3ae1a59b168cd476e1d94fda152f077f94e
--- /dev/null
+++ b/js/src/popover.js
@@ -0,0 +1,191 @@
+import Tooltip from './tooltip'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): popover.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Popover = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  const NAME                = 'popover'
+  const VERSION             = '4.0.0'
+  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">'
+              + '<div class="popover-arrow"></div>'
+              + '<h3 class="popover-title"></h3>'
+              + '<div class="popover-content"></div></div>'
+  })
+
+  const DefaultType = $.extend({}, Tooltip.DefaultType, {
+    content : '(string|function)'
+  })
+
+  const ClassName = {
+    FADE : 'fade',
+    IN  : 'in'
+  }
+
+  const Selector = {
+    TITLE   : '.popover-title',
+    CONTENT : '.popover-content',
+    ARROW   : '.popover-arrow'
+  }
+
+  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() {
+      let tip          = this.getTipElement()
+      let title        = this.getTitle()
+      let content      = this._getContent()
+      let titleElement = $(tip).find(Selector.TITLE)[0]
+
+      if (titleElement) {
+        titleElement[
+          this.config.html ? 'innerHTML' : 'innerText'
+        ] = title
+      }
+
+      // we use append for html objects to maintain js events
+      $(tip).find(Selector.CONTENT).children().detach().end()[
+        this.config.html ?
+          (typeof content === 'string' ? 'html' : 'append') : 'text'
+      ](content)
+
+      $(tip)
+        .removeClass(ClassName.FADE)
+        .removeClass(ClassName.IN)
+
+      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)
+        let _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') {
+          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/js/src/scrollspy.js b/js/src/scrollspy.js
new file mode 100644
index 0000000000000000000000000000000000000000..a407511f65cbeff6341534fb5b7c25523581d7f4
--- /dev/null
+++ b/js/src/scrollspy.js
@@ -0,0 +1,323 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): scrollspy.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const ScrollSpy = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  const NAME               = 'scrollspy'
+  const VERSION            = '4.0.0'
+  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_MENU : 'dropdown-menu',
+    ACTIVE        : 'active'
+  }
+
+  const Selector = {
+    DATA_SPY    : '[data-spy="scroll"]',
+    ACTIVE      : '.active',
+    LI          : 'li',
+    LI_DROPDOWN : 'li.dropdown',
+    NAV_ANCHORS : '.nav li > a'
+  }
+
+  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_ANCHORS}`
+      this._offsets       = []
+      this._targets       = []
+      this._activeTarget  = null
+      this._scrollHeight  = 0
+
+      $(this._scrollElement).on(Event.SCROLL, $.proxy(this._process, this))
+
+      this.refresh()
+      this._process()
+    }
+
+
+    // getters
+
+    static get VERSION() {
+      return VERSION
+    }
+
+    static get Default() {
+      return Default
+    }
+
+
+    // public
+
+    refresh() {
+      let autoMethod = this._scrollElement !== this._scrollElement.window ?
+        OffsetMethod.POSITION : OffsetMethod.OFFSET
+
+      let offsetMethod = this._config.method === 'auto' ?
+        autoMethod : this._config.method
+
+      let offsetBase = offsetMethod === OffsetMethod.POSITION ?
+        this._getScrollTop() : 0
+
+      this._offsets = []
+      this._targets = []
+
+      this._scrollHeight = this._getScrollHeight()
+
+      let targets = $.makeArray($(this._selector))
+
+      targets
+        .map((element) => {
+          let target
+          let targetSelector = Util.getSelectorFromElement(element)
+
+          if (targetSelector) {
+            target = $(targetSelector)[0]
+          }
+
+          if (target && (target.offsetWidth || target.offsetHeight)) {
+            // todo (fat): remove sketch reliance on jQuery position/offset
+            return [
+              $(target)[offsetMethod]().top + offsetBase,
+              targetSelector
+            ]
+          }
+        })
+        .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.scrollY : this._scrollElement.scrollTop
+    }
+
+    _getScrollHeight() {
+      return this._scrollElement.scrollHeight || Math.max(
+        document.body.scrollHeight,
+        document.documentElement.scrollHeight
+      )
+    }
+
+    _process() {
+      let scrollTop    = this._getScrollTop() + this._config.offset
+      let scrollHeight = this._getScrollHeight()
+      let maxScroll    = this._config.offset
+        + scrollHeight
+        - this._scrollElement.offsetHeight
+
+      if (this._scrollHeight !== scrollHeight) {
+        this.refresh()
+      }
+
+      if (scrollTop >= maxScroll) {
+        let target = this._targets[this._targets.length - 1]
+
+        if (this._activeTarget !== target) {
+          this._activate(target)
+        }
+      }
+
+      if (this._activeTarget && scrollTop < this._offsets[0]) {
+        this._activeTarget = null
+        this._clear()
+        return
+      }
+
+      for (let i = this._offsets.length; i--;) {
+        let 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 selector =
+        `${this._selector}[data-target="${target}"],` +
+        `${this._selector}[href="${target}"]`
+
+      // todo (fat): getting all the raw li's up the tree is not great.
+      let parentListItems = $(selector).parents(Selector.LI)
+
+      for (let i = parentListItems.length; i--;) {
+        $(parentListItems[i]).addClass(ClassName.ACTIVE)
+
+        let itemParent = parentListItems[i].parentNode
+
+        if (itemParent && $(itemParent).hasClass(ClassName.DROPDOWN_MENU)) {
+          let closestDropdown = $(itemParent)
+            .closest(Selector.LI_DROPDOWN)[0]
+          $(closestDropdown).addClass(ClassName.ACTIVE)
+        }
+      }
+
+      $(this._scrollElement).trigger(Event.ACTIVATE, {
+        relatedTarget: target
+      })
+    }
+
+    _clear() {
+      let activeParents = $(this._selector).parentsUntil(
+        this._config.target,
+        Selector.ACTIVE
+      )
+
+      for (let i = activeParents.length; i--;) {
+        $(activeParents[i]).removeClass(ClassName.ACTIVE)
+      }
+    }
+
+
+    // static
+
+    static _jQueryInterface(config) {
+      return this.each(function () {
+        let data    = $(this).data(DATA_KEY)
+        let _config = typeof config === 'object' && config || null
+
+        if (!data) {
+          data = new ScrollSpy(this, _config)
+          $(this).data(DATA_KEY, data)
+        }
+
+        if (typeof config === 'string') {
+          data[config]()
+        }
+      })
+    }
+
+
+  }
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+  $(window).on(Event.LOAD_DATA_API, function () {
+    let scrollSpys = $.makeArray($(Selector.DATA_SPY))
+
+    for (let i = scrollSpys.length; i--;) {
+      let $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/js/src/tab.js b/js/src/tab.js
new file mode 100644
index 0000000000000000000000000000000000000000..4d8d7dec8de54db3618bb276dcab30e8d8d94b3f
--- /dev/null
+++ b/js/src/tab.js
@@ -0,0 +1,287 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): tab.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Tab = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  const NAME                = 'tab'
+  const VERSION             = '4.0.0'
+  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',
+    FADE          : 'fade',
+    IN            : 'in'
+  }
+
+  const Selector = {
+    A                     : 'a',
+    LI                    : 'li',
+    LI_DROPDOWN           : 'li.dropdown',
+    UL                    : 'ul:not(.dropdown-menu)',
+    FADE_CHILD            : '> .fade',
+    ACTIVE                : '.active',
+    ACTIVE_CHILD          : '> .active',
+    DATA_TOGGLE           : '[data-toggle="tab"], [data-toggle="pill"]',
+    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).parent().hasClass(ClassName.ACTIVE))) {
+        return
+      }
+
+      let target
+      let previous
+      let ulElement = $(this._element).closest(Selector.UL)[0]
+      let selector  = Util.getSelectorFromElement(this._element)
+
+      if (ulElement) {
+        previous = $.makeArray($(ulElement).find(Selector.ACTIVE))
+        previous = previous[previous.length - 1]
+
+        if (previous) {
+          previous = $(previous).find(Selector.A)[0]
+        }
+      }
+
+      let hideEvent = $.Event(Event.HIDE, {
+        relatedTarget: this._element
+      })
+
+      let 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).closest(Selector.LI)[0],
+        ulElement
+      )
+
+      let complete = () => {
+        let hiddenEvent = $.Event(Event.HIDDEN, {
+          relatedTarget: this._element
+        })
+
+        let 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) {
+      let active          = $(container).find(Selector.ACTIVE_CHILD)[0]
+      let isTransitioning = callback
+        && Util.supportsTransitionEnd()
+        && ((active && $(active).hasClass(ClassName.FADE))
+           || !!$(container).find(Selector.FADE_CHILD)[0])
+
+      let complete = $.proxy(
+        this._transitionComplete,
+        this,
+        element,
+        active,
+        isTransitioning,
+        callback
+      )
+
+      if (active && isTransitioning) {
+        $(active)
+          .one(Util.TRANSITION_END, complete)
+          .emulateTransitionEnd(TRANSITION_DURATION)
+
+      } else {
+        complete()
+      }
+
+      if (active) {
+        $(active).removeClass(ClassName.IN)
+      }
+    }
+
+    _transitionComplete(element, active, isTransitioning, callback) {
+      if (active) {
+        $(active).removeClass(ClassName.ACTIVE)
+
+        let dropdownChild = $(active).find(
+          Selector.DROPDOWN_ACTIVE_CHILD
+        )[0]
+        if (dropdownChild) {
+          $(dropdownChild).removeClass(ClassName.ACTIVE)
+        }
+
+        let activeToggle = $(active).find(Selector.DATA_TOGGLE)[0]
+        if (activeToggle) {
+          activeToggle.setAttribute('aria-expanded', false)
+        }
+      }
+
+      $(element).addClass(ClassName.ACTIVE)
+
+      let elementToggle = $(element).find(Selector.DATA_TOGGLE)[0]
+      if (elementToggle) {
+        elementToggle.setAttribute('aria-expanded', true)
+      }
+
+      if (isTransitioning) {
+        Util.reflow(element)
+        $(element).addClass(ClassName.IN)
+      } else {
+        $(element).removeClass(ClassName.FADE)
+      }
+
+      if (element.parentNode &&
+         ($(element.parentNode).hasClass(ClassName.DROPDOWN_MENU))) {
+
+        let dropdownElement = $(element).closest(Selector.LI_DROPDOWN)[0]
+        if (dropdownElement) {
+          $(dropdownElement).addClass(ClassName.ACTIVE)
+        }
+
+        elementToggle = $(element).find(Selector.DATA_TOGGLE)[0]
+        if (elementToggle) {
+          elementToggle.setAttribute('aria-expanded', true)
+        }
+      }
+
+      if (callback) {
+        callback()
+      }
+    }
+
+
+    // static
+
+    static _jQueryInterface(config) {
+      return this.each(function () {
+        let $this = $(this)
+        let data  = $this.data(DATA_KEY)
+
+        if (!data) {
+          data = data = new Tab(this)
+          $this.data(DATA_KEY, data)
+        }
+
+        if (typeof config === 'string') {
+          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/js/src/tooltip.js b/js/src/tooltip.js
new file mode 100644
index 0000000000000000000000000000000000000000..5d62e154ad7b0c19652387425912866f2cef0c4e
--- /dev/null
+++ b/js/src/tooltip.js
@@ -0,0 +1,632 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): tooltip.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Tooltip = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  const NAME                = 'tooltip'
+  const VERSION             = '4.0.0'
+  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-arrow"></div>'
+                + '<div class="tooltip-inner"></div></div>',
+    trigger     : 'hover focus',
+    title       : '',
+    delay       : 0,
+    html        : false,
+    selector    : false,
+    placement   : 'top',
+    offset      : '0 0',
+    constraints : []
+  }
+
+  const DefaultType = {
+    animation   : 'boolean',
+    template    : 'string',
+    title       : '(string|function)',
+    trigger     : 'string',
+    delay       : '(number|object)',
+    html        : 'boolean',
+    selector    : '(string|boolean)',
+    placement   : '(string|function)',
+    offset      : 'string',
+    constraints : 'array'
+  }
+
+  const AttachmentMap = {
+    TOP    : 'bottom center',
+    RIGHT  : 'middle left',
+    BOTTOM : 'top center',
+    LEFT   : 'middle right'
+  }
+
+  const HoverState = {
+    IN  : 'in',
+    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',
+    IN   : 'in'
+  }
+
+  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._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) {
+      let context = this
+      let dataKey = this.constructor.DATA_KEY
+
+      if (event) {
+        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 {
+        $(context.getTipElement()).hasClass(ClassName.IN) ?
+          context._leave(null, context) :
+          context._enter(null, context)
+      }
+    }
+
+    dispose() {
+      clearTimeout(this._timeout)
+
+      this.cleanupTether()
+
+      $.removeData(this.element, this.constructor.DATA_KEY)
+
+      $(this.element).off(this.constructor.EVENT_KEY)
+
+      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() {
+      let showEvent = $.Event(this.constructor.Event.SHOW)
+
+      if (this.isWithContent() && this._isEnabled) {
+        $(this.element).trigger(showEvent)
+
+        let isInTheDom = $.contains(
+          this.element.ownerDocument.documentElement,
+          this.element
+        )
+
+        if (showEvent.isDefaultPrevented() || !isInTheDom) {
+          return
+        }
+
+        let tip   = this.getTipElement()
+        let 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)
+        }
+
+        let placement  = typeof this.config.placement === 'function' ?
+          this.config.placement.call(this, tip, this.element) :
+          this.config.placement
+
+        let attachment = this._getAttachment(placement)
+
+        $(tip)
+          .data(this.constructor.DATA_KEY, this)
+          .appendTo(document.body)
+
+        $(this.element).trigger(this.constructor.Event.INSERTED)
+
+        this._tether = new Tether({
+          element     : tip,
+          target      : this.element,
+          attachment  : attachment,
+          classes     : TetherClass,
+          classPrefix : CLASS_PREFIX,
+          offset      : this.config.offset,
+          constraints : this.config.constraints
+        })
+
+        Util.reflow(tip)
+        this._tether.position()
+
+        $(tip).addClass(ClassName.IN)
+
+        let complete = () => {
+          let prevHoverState = this._hoverState
+          this._hoverState   = null
+
+          $(this.element).trigger(this.constructor.Event.SHOWN)
+
+          if (prevHoverState === HoverState.OUT) {
+            this._leave(null, this)
+          }
+        }
+
+        Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE) ?
+          $(this.tip)
+            .one(Util.TRANSITION_END, complete)
+            .emulateTransitionEnd(Tooltip._TRANSITION_DURATION) :
+          complete()
+      }
+    }
+
+    hide(callback) {
+      let tip       = this.getTipElement()
+      let hideEvent = $.Event(this.constructor.Event.HIDE)
+      let complete  = () => {
+        if (this._hoverState !== HoverState.IN && tip.parentNode) {
+          tip.parentNode.removeChild(tip)
+        }
+
+        this.element.removeAttribute('aria-describedby')
+        $(this.element).trigger(this.constructor.Event.HIDDEN)
+        this.cleanupTether()
+
+        if (callback) {
+          callback()
+        }
+      }
+
+      $(this.element).trigger(hideEvent)
+
+      if (hideEvent.isDefaultPrevented()) {
+        return
+      }
+
+      $(tip).removeClass(ClassName.IN)
+
+      if (Util.supportsTransitionEnd() &&
+         ($(this.tip).hasClass(ClassName.FADE))) {
+
+        $(tip)
+          .one(Util.TRANSITION_END, complete)
+          .emulateTransitionEnd(TRANSITION_DURATION)
+
+      } else {
+        complete()
+      }
+
+      this._hoverState = ''
+    }
+
+
+    // protected
+
+    isWithContent() {
+      return !!this.getTitle()
+    }
+
+    getTipElement() {
+      return (this.tip = this.tip || $(this.config.template)[0])
+    }
+
+    setContent() {
+      let tip    = this.getTipElement()
+      let title  = this.getTitle()
+      let method = this.config.html ? 'innerHTML' : 'innerText'
+
+      $(tip).find(Selector.TOOLTIP_INNER)[0][method] = title
+
+      $(tip)
+        .removeClass(ClassName.FADE)
+        .removeClass(ClassName.IN)
+
+      this.cleanupTether()
+    }
+
+    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()
+
+        // clean up after tether's junk classes
+        // remove after they fix issue
+        // (https://github.com/HubSpot/tether/issues/36)
+        $(this.element).removeClass(this._removeTetherClasses)
+        $(this.tip).removeClass(this._removeTetherClasses)
+      }
+    }
+
+
+    // private
+
+    _getAttachment(placement) {
+      return AttachmentMap[placement.toUpperCase()]
+    }
+
+    _setListeners() {
+      let triggers = this.config.trigger.split(' ')
+
+      triggers.forEach((trigger) => {
+        if (trigger === 'click') {
+          $(this.element).on(
+            this.constructor.Event.CLICK,
+            this.config.selector,
+            $.proxy(this.toggle, this)
+          )
+
+        } else if (trigger !== Trigger.MANUAL) {
+          let eventIn  = trigger == Trigger.HOVER ?
+            this.constructor.Event.MOUSEENTER :
+            this.constructor.Event.FOCUSIN
+          let eventOut = trigger == Trigger.HOVER ?
+            this.constructor.Event.MOUSELEAVE :
+            this.constructor.Event.FOCUSOUT
+
+          $(this.element)
+            .on(
+              eventIn,
+              this.config.selector,
+              $.proxy(this._enter, this)
+            )
+            .on(
+              eventOut,
+              this.config.selector,
+              $.proxy(this._leave, this)
+            )
+        }
+      })
+
+      if (this.config.selector) {
+        this.config = $.extend({}, this.config, {
+          trigger  : 'manual',
+          selector : ''
+        })
+      } else {
+        this._fixTitle()
+      }
+    }
+
+    _removeTetherClasses(i, css) {
+      return ((css.baseVal || css).match(
+        new RegExp(`(^|\\s)${CLASS_PREFIX}-\\S+`, 'g')) || []
+      ).join(' ')
+    }
+
+    _fixTitle() {
+      let 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) {
+      let 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.IN) ||
+         (context._hoverState === HoverState.IN)) {
+        context._hoverState = HoverState.IN
+        return
+      }
+
+      clearTimeout(context._timeout)
+
+      context._hoverState = HoverState.IN
+
+      if (!context.config.delay || !context.config.delay.show) {
+        context.show()
+        return
+      }
+
+      context._timeout = setTimeout(() => {
+        if (context._hoverState === HoverState.IN) {
+          context.show()
+        }
+      }, context.config.delay.show)
+    }
+
+    _leave(event, context) {
+      let 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 (let 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() {
+      let config = {}
+
+      if (this.config) {
+        for (let key in this.config) {
+          let value = this.config[key]
+          if (this.constructor.Default[key] !== value) {
+            config[key] = value
+          }
+        }
+      }
+
+      return config
+    }
+
+
+    // static
+
+    static _jQueryInterface(config) {
+      return this.each(function () {
+        let data   = $(this).data(DATA_KEY)
+        let _config = typeof config === 'object' ?
+          config : null
+
+        if (!data && /destroy|hide/.test(config)) {
+          return
+        }
+
+        if (!data) {
+          data = new Tooltip(this, _config)
+          $(this).data(DATA_KEY, data)
+        }
+
+        if (typeof config === 'string') {
+          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/js/src/util.js b/js/src/util.js
new file mode 100644
index 0000000000000000000000000000000000000000..86bea65788c05265bbe78bc44845fcd2f84d39fc
--- /dev/null
+++ b/js/src/util.js
@@ -0,0 +1,156 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): util.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Util = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Private TransitionEnd Helpers
+   * ------------------------------------------------------------------------
+   */
+
+  let transition = false
+
+  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: function (event) {
+        if ($(event.target).is(this)) {
+          return event.handleObj.handler.apply(this, arguments)
+        }
+      }
+    }
+  }
+
+  function transitionEndTest() {
+    if (window.QUnit) {
+      return false
+    }
+
+    let el = document.createElement('bootstrap')
+
+    for (var 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, function () {
+      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
+   * --------------------------------------------------------------------------
+   */
+
+  let Util = {
+
+    TRANSITION_END: 'bsTransitionEnd',
+
+    getUID(prefix) {
+      do prefix += ~~(Math.random() * 1000000)
+      while (document.getElementById(prefix))
+      return prefix
+    },
+
+    getSelectorFromElement(element) {
+      let selector = element.getAttribute('data-target')
+
+      if (!selector) {
+        selector = element.getAttribute('href') || ''
+        selector = /^#[a-z]/i.test(selector) ? selector : null
+      }
+
+      return selector
+    },
+
+    reflow(element) {
+      new Function('bs', 'return bs')(element.offsetHeight)
+    },
+
+    triggerTransitionEnd(element) {
+      $(element).trigger(transition.end)
+    },
+
+    supportsTransitionEnd() {
+      return !!transition
+    },
+
+    typeCheckConfig(componentName, config, configTypes) {
+
+      for (let property in configTypes) {
+        let expectedTypes = configTypes[property]
+        let value         = config[property]
+        let valueType
+
+        if (value && isElement(value)) valueType = 'element'
+        else valueType = 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/js/tab.js b/js/tab.js
deleted file mode 100644
index 416189e3d1902531c8da2e743c8e508be102ae33..0000000000000000000000000000000000000000
--- a/js/tab.js
+++ /dev/null
@@ -1,155 +0,0 @@
-/* ========================================================================
- * Bootstrap: tab.js v3.3.4
- * http://getbootstrap.com/javascript/#tabs
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // TAB CLASS DEFINITION
-  // ====================
-
-  var Tab = function (element) {
-    // jscs:disable requireDollarBeforejQueryAssignment
-    this.element = $(element)
-    // jscs:enable requireDollarBeforejQueryAssignment
-  }
-
-  Tab.VERSION = '3.3.4'
-
-  Tab.TRANSITION_DURATION = 150
-
-  Tab.prototype.show = function () {
-    var $this    = this.element
-    var $ul      = $this.closest('ul:not(.dropdown-menu)')
-    var selector = $this.data('target')
-
-    if (!selector) {
-      selector = $this.attr('href')
-      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
-    }
-
-    if ($this.parent('li').hasClass('active')) return
-
-    var $previous = $ul.find('.active:last a')
-    var hideEvent = $.Event('hide.bs.tab', {
-      relatedTarget: $this[0]
-    })
-    var showEvent = $.Event('show.bs.tab', {
-      relatedTarget: $previous[0]
-    })
-
-    $previous.trigger(hideEvent)
-    $this.trigger(showEvent)
-
-    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
-
-    var $target = $(selector)
-
-    this.activate($this.closest('li'), $ul)
-    this.activate($target, $target.parent(), function () {
-      $previous.trigger({
-        type: 'hidden.bs.tab',
-        relatedTarget: $this[0]
-      })
-      $this.trigger({
-        type: 'shown.bs.tab',
-        relatedTarget: $previous[0]
-      })
-    })
-  }
-
-  Tab.prototype.activate = function (element, container, callback) {
-    var $active    = container.find('> .active')
-    var transition = callback
-      && $.support.transition
-      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
-
-    function next() {
-      $active
-        .removeClass('active')
-        .find('> .dropdown-menu > .active')
-          .removeClass('active')
-        .end()
-        .find('[data-toggle="tab"]')
-          .attr('aria-expanded', false)
-
-      element
-        .addClass('active')
-        .find('[data-toggle="tab"]')
-          .attr('aria-expanded', true)
-
-      if (transition) {
-        element[0].offsetWidth // reflow for transition
-        element.addClass('in')
-      } else {
-        element.removeClass('fade')
-      }
-
-      if (element.parent('.dropdown-menu').length) {
-        element
-          .closest('li.dropdown')
-            .addClass('active')
-          .end()
-          .find('[data-toggle="tab"]')
-            .attr('aria-expanded', true)
-      }
-
-      callback && callback()
-    }
-
-    $active.length && transition ?
-      $active
-        .one('bsTransitionEnd', next)
-        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
-      next()
-
-    $active.removeClass('in')
-  }
-
-
-  // TAB PLUGIN DEFINITION
-  // =====================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this = $(this)
-      var data  = $this.data('bs.tab')
-
-      if (!data) $this.data('bs.tab', (data = new Tab(this)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
-
-  var old = $.fn.tab
-
-  $.fn.tab             = Plugin
-  $.fn.tab.Constructor = Tab
-
-
-  // TAB NO CONFLICT
-  // ===============
-
-  $.fn.tab.noConflict = function () {
-    $.fn.tab = old
-    return this
-  }
-
-
-  // TAB DATA-API
-  // ============
-
-  var clickHandler = function (e) {
-    e.preventDefault()
-    Plugin.call($(this), 'show')
-  }
-
-  $(document)
-    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
-    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
-
-}(jQuery);
diff --git a/js/tests/index.html b/js/tests/index.html
index fab2ebc163bdd91a56697680baa88dce343a281e..0e2bdd012fe437e1c7daed63e636ff53808f13f9 100644
--- a/js/tests/index.html
+++ b/js/tests/index.html
@@ -7,6 +7,7 @@
 
     <!-- jQuery -->
     <script src="vendor/jquery.min.js"></script>
+    <script src="vendor/tether.min.js"></script>
     <script>
       // Disable jQuery event aliases to ensure we don't accidentally use any of them
       (function () {
@@ -129,19 +130,18 @@
       })();
     </script>
 
-    <!-- Plugin sources -->
-    <script>$.support.transition = false</script>
-    <script src="../../js/alert.js"></script>
-    <script src="../../js/button.js"></script>
-    <script src="../../js/carousel.js"></script>
-    <script src="../../js/collapse.js"></script>
-    <script src="../../js/dropdown.js"></script>
-    <script src="../../js/modal.js"></script>
-    <script src="../../js/scrollspy.js"></script>
-    <script src="../../js/tab.js"></script>
-    <script src="../../js/tooltip.js"></script>
-    <script src="../../js/popover.js"></script>
-    <script src="../../js/affix.js"></script>
+    <!-- es6 Plugin sources -->
+    <script src="../../js/dist/util.js"></script>
+    <script src="../../js/dist/alert.js"></script>
+    <script src="../../js/dist/button.js"></script>
+    <script src="../../js/dist/carousel.js"></script>
+    <script src="../../js/dist/collapse.js"></script>
+    <script src="../../js/dist/dropdown.js"></script>
+    <script src="../../js/dist/modal.js"></script>
+    <script src="../../js/dist/scrollspy.js"></script>
+    <script src="../../js/dist/tab.js"></script>
+    <script src="../../js/dist/tooltip.js"></script>
+    <script src="../../js/dist/popover.js"></script>
 
     <!-- Unit tests -->
     <script src="unit/alert.js"></script>
@@ -154,7 +154,6 @@
     <script src="unit/tab.js"></script>
     <script src="unit/tooltip.js"></script>
     <script src="unit/popover.js"></script>
-    <script src="unit/affix.js"></script>
 
   </head>
   <body>
diff --git a/js/tests/unit/affix.js b/js/tests/unit/affix.js
deleted file mode 100644
index 3a6918f86673204f5f3b28a5da5ceae8d5c8bcee..0000000000000000000000000000000000000000
--- a/js/tests/unit/affix.js
+++ /dev/null
@@ -1,107 +0,0 @@
-$(function () {
-  'use strict';
-
-  QUnit.module('affix plugin')
-
-  QUnit.test('should be defined on jquery object', function (assert) {
-    assert.expect(1)
-    assert.ok($(document.body).affix, 'affix method is defined')
-  })
-
-  QUnit.module('affix', {
-    beforeEach: function () {
-      // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
-      $.fn.bootstrapAffix = $.fn.affix.noConflict()
-    },
-    afterEach: function () {
-      $.fn.affix = $.fn.bootstrapAffix
-      delete $.fn.bootstrapAffix
-    }
-  })
-
-  QUnit.test('should provide no conflict', function (assert) {
-    assert.expect(1)
-    assert.strictEqual($.fn.affix, undefined, 'affix was set back to undefined (org value)')
-  })
-
-  QUnit.test('should return jquery collection containing the element', function (assert) {
-    assert.expect(2)
-    var $el = $('<div/>')
-    var $affix = $el.bootstrapAffix()
-    assert.ok($affix instanceof $, 'returns jquery collection')
-    assert.strictEqual($affix[0], $el[0], 'collection contains element')
-  })
-
-  QUnit.test('should exit early if element is not visible', function (assert) {
-    assert.expect(1)
-    var $affix = $('<div style="display: none"/>').bootstrapAffix()
-    $affix.data('bs.affix').checkPosition()
-    assert.ok(!$affix.hasClass('affix'), 'affix class was not added')
-  })
-
-  QUnit.test('should trigger affixed event after affix', function (assert) {
-    assert.expect(2)
-    var done = assert.async()
-
-    var templateHTML = '<div id="affixTarget">'
-        + '<ul>'
-        + '<li>Please affix</li>'
-        + '<li>And unaffix</li>'
-        + '</ul>'
-        + '</div>'
-        + '<div id="affixAfter" style="height: 20000px; display: block;"/>'
-    $(templateHTML).appendTo(document.body)
-
-    $('#affixTarget').bootstrapAffix({
-      offset: $('#affixTarget ul').position()
-    })
-
-    $('#affixTarget')
-      .on('affix.bs.affix', function () {
-        assert.ok(true, 'affix event fired')
-      }).on('affixed.bs.affix', function () {
-        assert.ok(true, 'affixed event fired')
-        $('#affixTarget, #affixAfter').remove()
-        done()
-      })
-
-    setTimeout(function () {
-      window.scrollTo(0, document.body.scrollHeight)
-
-      setTimeout(function () {
-        window.scroll(0, 0)
-      }, 16) // for testing in a browser
-    }, 0)
-  })
-
-  QUnit.test('should affix-top when scrolling up to offset when parent has padding', function (assert) {
-    assert.expect(1)
-    var done = assert.async()
-
-    var templateHTML = '<div id="padding-offset" style="padding-top: 20px;">'
-        + '<div id="affixTopTarget">'
-        + '<p>Testing affix-top class is added</p>'
-        + '</div>'
-        + '<div style="height: 1000px; display: block;"/>'
-        + '</div>'
-    $(templateHTML).appendTo(document.body)
-
-    $('#affixTopTarget')
-      .bootstrapAffix({
-        offset: { top: 120, bottom: 0 }
-      })
-      .on('affixed-top.bs.affix', function () {
-        assert.ok($('#affixTopTarget').hasClass('affix-top'), 'affix-top class applied')
-        $('#padding-offset').remove()
-        done()
-      })
-
-    setTimeout(function () {
-      window.scrollTo(0, document.body.scrollHeight)
-
-      setTimeout(function () {
-        window.scroll(0, 119)
-      }, 250)
-    }, 250)
-  })
-})
diff --git a/js/tests/unit/alert.js b/js/tests/unit/alert.js
index 6be990a518a76c98075271a8a2e4231b3f316fcd..97818960ac9d9531bcb818870b09b07030f9336f 100644
--- a/js/tests/unit/alert.js
+++ b/js/tests/unit/alert.js
@@ -38,7 +38,8 @@ $(function () {
         + '<a class="close" href="#" data-dismiss="alert">×</a>'
         + '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>'
         + '</div>'
-    var $alert = $(alertHTML).bootstrapAlert()
+
+    var $alert = $(alertHTML).bootstrapAlert().appendTo($('#qunit-fixture'))
 
     $alert.find('.close').trigger('click')
 
diff --git a/js/tests/unit/button.js b/js/tests/unit/button.js
index 691796c42885b376ac4f309d7b19862bf125da44..5648506cf5745fdfa98001da637319b03b5bc5e8 100644
--- a/js/tests/unit/button.js
+++ b/js/tests/unit/button.js
@@ -32,64 +32,6 @@ $(function () {
     assert.strictEqual($button[0], $el[0], 'collection contains element')
   })
 
-  QUnit.test('should return set state to loading', function (assert) {
-    assert.expect(4)
-    var $btn = $('<button class="btn" data-loading-text="fat">mdo</button>')
-    assert.strictEqual($btn.html(), 'mdo', 'btn text equals mdo')
-    $btn.bootstrapButton('loading')
-    var done = assert.async()
-    setTimeout(function () {
-      assert.strictEqual($btn.html(), 'fat', 'btn text equals fat')
-      assert.ok($btn[0].hasAttribute('disabled'), 'btn is disabled')
-      assert.ok($btn.hasClass('disabled'), 'btn has disabled class')
-      done()
-    }, 0)
-  })
-
-  QUnit.test('should return reset state', function (assert) {
-    assert.expect(7)
-    var $btn = $('<button class="btn" data-loading-text="fat">mdo</button>')
-    assert.strictEqual($btn.html(), 'mdo', 'btn text equals mdo')
-    $btn.bootstrapButton('loading')
-    var doneOne = assert.async()
-    setTimeout(function () {
-      assert.strictEqual($btn.html(), 'fat', 'btn text equals fat')
-      assert.ok($btn[0].hasAttribute('disabled'), 'btn is disabled')
-      assert.ok($btn.hasClass('disabled'), 'btn has disabled class')
-      doneOne()
-      var doneTwo = assert.async()
-      $btn.bootstrapButton('reset')
-      setTimeout(function () {
-        assert.strictEqual($btn.html(), 'mdo', 'btn text equals mdo')
-        assert.ok(!$btn[0].hasAttribute('disabled'), 'btn is not disabled')
-        assert.ok(!$btn.hasClass('disabled'), 'btn does not have disabled class')
-        doneTwo()
-      }, 0)
-    }, 0)
-  })
-
-  QUnit.test('should work with an empty string as reset state', function (assert) {
-    assert.expect(7)
-    var $btn = $('<button class="btn" data-loading-text="fat"/>')
-    assert.strictEqual($btn.html(), '', 'btn text equals ""')
-    $btn.bootstrapButton('loading')
-    var doneOne = assert.async()
-    setTimeout(function () {
-      assert.strictEqual($btn.html(), 'fat', 'btn text equals fat')
-      assert.ok($btn[0].hasAttribute('disabled'), 'btn is disabled')
-      assert.ok($btn.hasClass('disabled'), 'btn has disabled class')
-      doneOne()
-      var doneTwo = assert.async()
-      $btn.bootstrapButton('reset')
-      setTimeout(function () {
-        assert.strictEqual($btn.html(), '', 'btn text equals ""')
-        assert.ok(!$btn[0].hasAttribute('disabled'), 'btn is not disabled')
-        assert.ok(!$btn.hasClass('disabled'), 'btn does not have disabled class')
-        doneTwo()
-      }, 0)
-    }, 0)
-  })
-
   QUnit.test('should toggle active', function (assert) {
     assert.expect(2)
     var $btn = $('<button class="btn" data-toggle="button">mdo</button>')
diff --git a/js/tests/unit/carousel.js b/js/tests/unit/carousel.js
index 39d2505980cbe5ed9e8b1d4c87b4d13a227b0917..017bd9beeee142cdc3b26ebe1e122aacd70235e3 100644
--- a/js/tests/unit/carousel.js
+++ b/js/tests/unit/carousel.js
@@ -32,6 +32,38 @@ $(function () {
     assert.strictEqual($carousel[0], $el[0], 'collection contains element')
   })
 
+  QUnit.test('should type check config options', function (assert) {
+    assert.expect(2)
+
+    var message
+    var expectedMessage = 'CAROUSEL: Option "interval" provided type "string" but expected type "(number|boolean)".'
+    var config = {
+      interval: 'fat sux'
+    }
+
+    try {
+      $('<div/>').bootstrapCarousel(config)
+    } catch (e) {
+      message = e.message
+    }
+
+    assert.ok(message === expectedMessage, 'correct error message')
+
+    config = {
+      keyboard: document.createElement('div')
+    }
+    expectedMessage = 'CAROUSEL: Option "keyboard" provided type "element" but expected type "boolean".'
+
+    try {
+      $('<div/>').bootstrapCarousel(config)
+    } catch (e) {
+      message = e.message
+    }
+
+    assert.ok(message === expectedMessage, 'correct error message')
+  })
+
+
   QUnit.test('should not fire slid when slide is prevented', function (assert) {
     assert.expect(1)
     var done = assert.async()
@@ -56,13 +88,13 @@ $(function () {
         + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
         + '</ol>'
         + '<div class="carousel-inner">'
-        + '<div class="item active">'
+        + '<div class="carousel-item active">'
         + '<div class="carousel-caption"/>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<div class="carousel-caption"/>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<div class="carousel-caption"/>'
         + '</div>'
         + '</div>'
@@ -76,16 +108,16 @@ $(function () {
       .one('slide.bs.carousel', function (e) {
         e.preventDefault()
         setTimeout(function () {
-          assert.ok($carousel.find('.item:eq(0)').is('.active'), 'first item still active')
+          assert.ok($carousel.find('.carousel-item:eq(0)').is('.active'), 'first item still active')
           assert.ok($carousel.find('.carousel-indicators li:eq(0)').is('.active'), 'first indicator still active')
           $carousel.bootstrapCarousel('next')
         }, 0)
       })
       .one('slid.bs.carousel', function () {
         setTimeout(function () {
-          assert.ok(!$carousel.find('.item:eq(0)').is('.active'), 'first item still active')
+          assert.ok(!$carousel.find('.carousel-item:eq(0)').is('.active'), 'first item still active')
           assert.ok(!$carousel.find('.carousel-indicators li:eq(0)').is('.active'), 'first indicator still active')
-          assert.ok($carousel.find('.item:eq(1)').is('.active'), 'second item active')
+          assert.ok($carousel.find('.carousel-item:eq(1)').is('.active'), 'second item active')
           assert.ok($carousel.find('.carousel-indicators li:eq(1)').is('.active'), 'second indicator active')
           done()
         }, 0)
@@ -97,7 +129,7 @@ $(function () {
     assert.expect(4)
     var carouselHTML = '<div id="myCarousel" class="carousel slide">'
         + '<div class="carousel-inner">'
-        + '<div class="item active">'
+        + '<div class="carousel-item active">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>First Thumbnail label</h4>'
@@ -106,7 +138,7 @@ $(function () {
         + 'ultricies vehicula ut id elit.</p>'
         + '</div>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>Second Thumbnail label</h4>'
@@ -115,7 +147,7 @@ $(function () {
         + 'ultricies vehicula ut id elit.</p>'
         + '</div>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>Third Thumbnail label</h4>'
@@ -152,7 +184,7 @@ $(function () {
     assert.expect(4)
     var carouselHTML = '<div id="myCarousel" class="carousel slide">'
         + '<div class="carousel-inner">'
-        + '<div class="item active">'
+        + '<div class="carousel-item active">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>First Thumbnail label</h4>'
@@ -161,7 +193,7 @@ $(function () {
         + 'ultricies vehicula ut id elit.</p>'
         + '</div>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>Second Thumbnail label</h4>'
@@ -170,7 +202,7 @@ $(function () {
         + 'ultricies vehicula ut id elit.</p>'
         + '</div>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>Third Thumbnail label</h4>'
@@ -207,7 +239,7 @@ $(function () {
     assert.expect(2)
     var template = '<div id="myCarousel" class="carousel slide">'
         + '<div class="carousel-inner">'
-        + '<div class="item active">'
+        + '<div class="carousel-item active">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>First Thumbnail label</h4>'
@@ -216,7 +248,7 @@ $(function () {
         + 'ultricies vehicula ut id elit.</p>'
         + '</div>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>Second Thumbnail label</h4>'
@@ -225,7 +257,7 @@ $(function () {
         + 'ultricies vehicula ut id elit.</p>'
         + '</div>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>Third Thumbnail label</h4>'
@@ -244,7 +276,7 @@ $(function () {
     $(template)
       .on('slide.bs.carousel', function (e) {
         assert.ok(e.relatedTarget, 'relatedTarget present')
-        assert.ok($(e.relatedTarget).hasClass('item'), 'relatedTarget has class "item"')
+        assert.ok($(e.relatedTarget).hasClass('carousel-item'), 'relatedTarget has class "item"')
         done()
       })
       .bootstrapCarousel('next')
@@ -254,7 +286,7 @@ $(function () {
     assert.expect(2)
     var template = '<div id="myCarousel" class="carousel slide">'
         + '<div class="carousel-inner">'
-        + '<div class="item active">'
+        + '<div class="carousel-item active">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>First Thumbnail label</h4>'
@@ -263,7 +295,7 @@ $(function () {
         + 'ultricies vehicula ut id elit.</p>'
         + '</div>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>Second Thumbnail label</h4>'
@@ -272,7 +304,7 @@ $(function () {
         + 'ultricies vehicula ut id elit.</p>'
         + '</div>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>Third Thumbnail label</h4>'
@@ -291,7 +323,7 @@ $(function () {
     $(template)
       .on('slid.bs.carousel', function (e) {
         assert.ok(e.relatedTarget, 'relatedTarget present')
-        assert.ok($(e.relatedTarget).hasClass('item'), 'relatedTarget has class "item"')
+        assert.ok($(e.relatedTarget).hasClass('carousel-item'), 'relatedTarget has class "item"')
         done()
       })
       .bootstrapCarousel('next')
@@ -301,7 +333,7 @@ $(function () {
     assert.expect(4)
     var templateHTML = '<div id="myCarousel" class="carousel slide">'
         + '<div class="carousel-inner">'
-        + '<div class="item active">'
+        + '<div class="carousel-item active">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>First Thumbnail label</h4>'
@@ -310,7 +342,7 @@ $(function () {
         + 'ultricies vehicula ut id elit.</p>'
         + '</div>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>Second Thumbnail label</h4>'
@@ -319,7 +351,7 @@ $(function () {
         + 'ultricies vehicula ut id elit.</p>'
         + '</div>'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '<div class="carousel-caption">'
         + '<h4>Third Thumbnail label</h4>'
@@ -337,25 +369,25 @@ $(function () {
 
     $carousel.appendTo('body')
     $('[data-slide]').first().trigger('click')
-    assert.strictEqual($carousel.data('bs.carousel').options.interval, 1814)
+    assert.strictEqual($carousel.data('bs.carousel')._config.interval, 1814)
     $carousel.remove()
 
     $carousel.appendTo('body').attr('data-modal', 'foobar')
     $('[data-slide]').first().trigger('click')
-    assert.strictEqual($carousel.data('bs.carousel').options.interval, 1814, 'even if there is an data-modal attribute set')
+    assert.strictEqual($carousel.data('bs.carousel')._config.interval, 1814, 'even if there is an data-modal attribute set')
     $carousel.remove()
 
     $carousel.appendTo('body')
     $('[data-slide]').first().trigger('click')
     $carousel.attr('data-interval', 1860)
     $('[data-slide]').first().trigger('click')
-    assert.strictEqual($carousel.data('bs.carousel').options.interval, 1814, 'attributes should be read only on initialization')
+    assert.strictEqual($carousel.data('bs.carousel')._config.interval, 1814, 'attributes should be read only on initialization')
     $carousel.remove()
 
     $carousel.attr('data-interval', false)
     $carousel.appendTo('body')
     $carousel.bootstrapCarousel(1)
-    assert.strictEqual($carousel.data('bs.carousel').options.interval, false, 'data attribute has higher priority than default options')
+    assert.strictEqual($carousel.data('bs.carousel')._config.interval, false, 'data attribute has higher priority than default options')
     $carousel.remove()
   })
 
@@ -363,14 +395,14 @@ $(function () {
     assert.expect(2)
     var templateHTML = '<div id="myCarousel" class="carousel" data-interval="1814">'
         + '<div class="carousel-inner">'
-        + '<div class="item active">'
+        + '<div class="carousel-item active">'
         + '<img alt="">'
         + '</div>'
         + '<script type="text/x-metamorph" id="thingy"/>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '</div>'
         + '</div>'
         + '</div>'
@@ -378,25 +410,25 @@ $(function () {
 
     $template.bootstrapCarousel()
 
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
 
     $template.bootstrapCarousel(1)
 
-    assert.strictEqual($template.find('.item')[1], $template.find('.active')[0], 'second item active')
+    assert.strictEqual($template.find('.carousel-item')[1], $template.find('.active')[0], 'second item active')
   })
 
   QUnit.test('should skip over non-items when using next/prev methods', function (assert) {
     assert.expect(2)
     var templateHTML = '<div id="myCarousel" class="carousel" data-interval="1814">'
         + '<div class="carousel-inner">'
-        + '<div class="item active">'
+        + '<div class="carousel-item active">'
         + '<img alt="">'
         + '</div>'
         + '<script type="text/x-metamorph" id="thingy"/>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '<img alt="">'
         + '</div>'
-        + '<div class="item">'
+        + '<div class="carousel-item">'
         + '</div>'
         + '</div>'
         + '</div>'
@@ -404,24 +436,24 @@ $(function () {
 
     $template.bootstrapCarousel()
 
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
 
     $template.bootstrapCarousel('next')
 
-    assert.strictEqual($template.find('.item')[1], $template.find('.active')[0], 'second item active')
+    assert.strictEqual($template.find('.carousel-item')[1], $template.find('.active')[0], 'second item active')
   })
 
   QUnit.test('should go to previous item if left arrow key is pressed', function (assert) {
     assert.expect(2)
     var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false">'
         + '<div class="carousel-inner">'
-        + '<div id="first" class="item">'
+        + '<div id="first" class="carousel-item">'
         + '<img alt="">'
         + '</div>'
-        + '<div id="second" class="item active">'
+        + '<div id="second" class="carousel-item active">'
         + '<img alt="">'
         + '</div>'
-        + '<div id="third" class="item">'
+        + '<div id="third" class="carousel-item">'
         + '<img alt="">'
         + '</div>'
         + '</div>'
@@ -430,24 +462,24 @@ $(function () {
 
     $template.bootstrapCarousel()
 
-    assert.strictEqual($template.find('.item')[1], $template.find('.active')[0], 'second item active')
+    assert.strictEqual($template.find('.carousel-item')[1], $template.find('.active')[0], 'second item active')
 
     $template.trigger($.Event('keydown', { which: 37 }))
 
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
   })
 
   QUnit.test('should go to next item if right arrow key is pressed', function (assert) {
     assert.expect(2)
     var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false">'
         + '<div class="carousel-inner">'
-        + '<div id="first" class="item active">'
+        + '<div id="first" class="carousel-item active">'
         + '<img alt="">'
         + '</div>'
-        + '<div id="second" class="item">'
+        + '<div id="second" class="carousel-item">'
         + '<img alt="">'
         + '</div>'
-        + '<div id="third" class="item">'
+        + '<div id="third" class="carousel-item">'
         + '<img alt="">'
         + '</div>'
         + '</div>'
@@ -456,24 +488,24 @@ $(function () {
 
     $template.bootstrapCarousel()
 
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
 
     $template.trigger($.Event('keydown', { which: 39 }))
 
-    assert.strictEqual($template.find('.item')[1], $template.find('.active')[0], 'second item active')
+    assert.strictEqual($template.find('.carousel-item')[1], $template.find('.active')[0], 'second item active')
   })
 
   QUnit.test('should support disabling the keyboard navigation', function (assert) {
     assert.expect(3)
     var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false" data-keyboard="false">'
         + '<div class="carousel-inner">'
-        + '<div id="first" class="item active">'
+        + '<div id="first" class="carousel-item active">'
         + '<img alt="">'
         + '</div>'
-        + '<div id="second" class="item">'
+        + '<div id="second" class="carousel-item">'
         + '<img alt="">'
         + '</div>'
-        + '<div id="third" class="item">'
+        + '<div id="third" class="carousel-item">'
         + '<img alt="">'
         + '</div>'
         + '</div>'
@@ -482,30 +514,30 @@ $(function () {
 
     $template.bootstrapCarousel()
 
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
 
     $template.trigger($.Event('keydown', { which: 39 }))
 
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after right arrow press')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after right arrow press')
 
     $template.trigger($.Event('keydown', { which: 37 }))
 
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after left arrow press')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after left arrow press')
   })
 
   QUnit.test('should ignore keyboard events within <input>s and <textarea>s', function (assert) {
     assert.expect(7)
     var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false">'
         + '<div class="carousel-inner">'
-        + '<div id="first" class="item active">'
+        + '<div id="first" class="carousel-item active">'
         + '<img alt="">'
         + '<input type="text" id="in-put">'
         + '<textarea id="text-area"></textarea>'
         + '</div>'
-        + '<div id="second" class="item">'
+        + '<div id="second" class="carousel-item">'
         + '<img alt="">'
         + '</div>'
-        + '<div id="third" class="item">'
+        + '<div id="third" class="carousel-item">'
         + '<img alt="">'
         + '</div>'
         + '</div>'
@@ -519,21 +551,21 @@ $(function () {
 
     $template.bootstrapCarousel()
 
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
 
 
     $input.trigger($.Event('keydown', { which: 39 }))
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after right arrow press in <input>')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after right arrow press in <input>')
 
     $input.trigger($.Event('keydown', { which: 37 }))
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after left arrow press in <input>')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after left arrow press in <input>')
 
 
     $textarea.trigger($.Event('keydown', { which: 39 }))
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after right arrow press in <textarea>')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after right arrow press in <textarea>')
 
     $textarea.trigger($.Event('keydown', { which: 37 }))
-    assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after left arrow press in <textarea>')
+    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after left arrow press in <textarea>')
   })
 
   QUnit.test('should only add mouseenter and mouseleave listeners when not on mobile', function (assert) {
@@ -541,13 +573,13 @@ $(function () {
     var isMobile     = 'ontouchstart' in document.documentElement
     var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false" data-pause="hover">'
         + '<div class="carousel-inner">'
-        + '<div id="first" class="item active">'
+        + '<div id="first" class="carousel-item active">'
         + '<img alt="">'
         + '</div>'
-        + '<div id="second" class="item">'
+        + '<div id="second" class="carousel-item">'
         + '<img alt="">'
         + '</div>'
-        + '<div id="third" class="item">'
+        + '<div id="third" class="carousel-item">'
         + '<img alt="">'
         + '</div>'
         + '</div>'
@@ -568,13 +600,13 @@ $(function () {
         + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
         + '</ol>'
         + '<div class="carousel-inner">'
-        + '<div class="item active" id="one">'
+        + '<div class="carousel-item active" id="one">'
         + '<div class="carousel-caption"/>'
         + '</div>'
-        + '<div class="item" id="two">'
+        + '<div class="carousel-item" id="two">'
         + '<div class="carousel-caption"/>'
         + '</div>'
-        + '<div class="item" id="three">'
+        + '<div class="carousel-item" id="three">'
         + '<div class="carousel-caption"/>'
         + '</div>'
         + '</div>'
@@ -582,7 +614,7 @@ $(function () {
         + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
         + '</div>'
     var $carousel = $(carouselHTML)
-    var getActiveId = function () { return $carousel.find('.item.active').attr('id') }
+    var getActiveId = function () { return $carousel.find('.carousel-item.active').attr('id') }
 
     var done = assert.async()
 
@@ -613,13 +645,13 @@ $(function () {
         + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
         + '</ol>'
         + '<div class="carousel-inner">'
-        + '<div class="item active" id="one">'
+        + '<div class="carousel-item active" id="one">'
         + '<div class="carousel-caption"/>'
         + '</div>'
-        + '<div class="item" id="two">'
+        + '<div class="carousel-item" id="two">'
         + '<div class="carousel-caption"/>'
         + '</div>'
-        + '<div class="item" id="three">'
+        + '<div class="carousel-item" id="three">'
         + '<div class="carousel-caption"/>'
         + '</div>'
         + '</div>'
@@ -632,7 +664,7 @@ $(function () {
 
     $carousel
       .on('slid.bs.carousel', function () {
-        assert.strictEqual($carousel.find('.item.active').attr('id'), 'three', 'carousel wrapped around and slid from 1st to 3rd slide')
+        assert.strictEqual($carousel.find('.carousel-item.active').attr('id'), 'three', 'carousel wrapped around and slid from 1st to 3rd slide')
         done()
       })
       .bootstrapCarousel('prev')
@@ -647,13 +679,13 @@ $(function () {
         + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
         + '</ol>'
         + '<div class="carousel-inner">'
-        + '<div class="item active" id="one">'
+        + '<div class="carousel-item active" id="one">'
         + '<div class="carousel-caption"/>'
         + '</div>'
-        + '<div class="item" id="two">'
+        + '<div class="carousel-item" id="two">'
         + '<div class="carousel-caption"/>'
         + '</div>'
-        + '<div class="item" id="three">'
+        + '<div class="carousel-item" id="three">'
         + '<div class="carousel-caption"/>'
         + '</div>'
         + '</div>'
@@ -661,7 +693,7 @@ $(function () {
         + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
         + '</div>'
     var $carousel = $(carouselHTML)
-    var getActiveId = function () { return $carousel.find('.item.active').attr('id') }
+    var getActiveId = function () { return $carousel.find('.carousel-item.active').attr('id') }
 
     var done = assert.async()
 
@@ -693,13 +725,13 @@ $(function () {
         + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
         + '</ol>'
         + '<div class="carousel-inner">'
-        + '<div class="item active" id="one">'
+        + '<div class="carousel-item active" id="one">'
         + '<div class="carousel-caption"/>'
         + '</div>'
-        + '<div class="item" id="two">'
+        + '<div class="carousel-item" id="two">'
         + '<div class="carousel-caption"/>'
         + '</div>'
-        + '<div class="item" id="three">'
+        + '<div class="carousel-item" id="three">'
         + '<div class="carousel-caption"/>'
         + '</div>'
         + '</div>'
@@ -713,6 +745,6 @@ $(function () {
         assert.ok(false, 'carousel slid when it should not have slid')
       })
       .bootstrapCarousel('prev')
-    assert.strictEqual($carousel.find('.item.active').attr('id'), 'one', 'carousel did not wrap around and stayed on 1st slide')
+    assert.strictEqual($carousel.find('.carousel-item.active').attr('id'), 'one', 'carousel did not wrap around and stayed on 1st slide')
   })
 })
diff --git a/js/tests/unit/collapse.js b/js/tests/unit/collapse.js
index 0efa65400d3304d3a47418c7a1560e91a97c69e4..78fafc6c2d8826d4e6724413f3e370da7770ea78 100644
--- a/js/tests/unit/collapse.js
+++ b/js/tests/unit/collapse.js
@@ -355,7 +355,7 @@ $(function () {
 
     $('<div id="body1" aria-expanded="true" class="in"/>').appendTo($groups.eq(0))
 
-    var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
+    var $target2 = $('<a role="button" data-toggle="collapse" href="#body2" data-parent="#accordion" class="collapsed" />').appendTo($groups.eq(1))
 
     $('<div id="body2" aria-expanded="false"/>').appendTo($groups.eq(1))
 
@@ -400,7 +400,7 @@ $(function () {
 
     $body2
       .toggleClass('in collapsing')
-      .data('bs.collapse').transitioning = 1
+      .data('bs.collapse')._isTransitioning = 1
 
     $target1.trigger('click')
 
diff --git a/js/tests/unit/modal.js b/js/tests/unit/modal.js
index 217e4d7f76fea9bfff712f1fbc74898d6786208a..6da09e3c6e2369f20217619246a1a57936b9dfda 100644
--- a/js/tests/unit/modal.js
+++ b/js/tests/unit/modal.js
@@ -34,7 +34,7 @@ $(function () {
 
   QUnit.test('should expose defaults var for settings', function (assert) {
     assert.expect(1)
-    assert.ok($.fn.bootstrapModal.Constructor.DEFAULTS, 'default object exposed')
+    assert.ok($.fn.bootstrapModal.Constructor.Default, 'default object exposed')
   })
 
   QUnit.test('should insert into dom when show method is called', function (assert) {
diff --git a/js/tests/unit/popover.js b/js/tests/unit/popover.js
index a25df3a58dd5582ef05689921c031eac87e6cef7..8347e9f03452d6e5a66b1cec20138520101f1a3d 100644
--- a/js/tests/unit/popover.js
+++ b/js/tests/unit/popover.js
@@ -16,6 +16,7 @@ $(function () {
     afterEach: function () {
       $.fn.popover = $.fn.bootstrapPopover
       delete $.fn.bootstrapPopover
+      $('.popover').remove()
     }
   })
 
@@ -81,6 +82,7 @@ $(function () {
     assert.strictEqual($('.popover .popover-content').text(), 'loves writing tests (╯°□°)╯︵ ┻━┻', 'content correctly inserted')
 
     $popover.bootstrapPopover('hide')
+
     assert.strictEqual($('.popover').length, 0, 'popover was removed')
   })
 
@@ -91,6 +93,7 @@ $(function () {
     var $popover = $('<a href="#">@fat</a>')
       .appendTo('#qunit-fixture')
       .bootstrapPopover({
+        html: true,
         content: function () {
           return $div
         }
@@ -98,14 +101,14 @@ $(function () {
 
     $popover.bootstrapPopover('show')
     assert.notEqual($('.popover').length, 0, 'popover was inserted')
-    assert.equal($('.popover .popover-content').html(), $div, 'content correctly inserted')
+    assert.equal($('.popover .popover-content').html(), $div[0].outerHTML, 'content correctly inserted')
 
     $popover.bootstrapPopover('hide')
     assert.strictEqual($('.popover').length, 0, 'popover was removed')
 
     $popover.bootstrapPopover('show')
     assert.notEqual($('.popover').length, 0, 'popover was inserted')
-    assert.equal($('.popover .popover-content').html(), $div, 'content correctly inserted')
+    assert.equal($('.popover .popover-content').html(), $div[0].outerHTML, 'content correctly inserted')
 
     $popover.bootstrapPopover('hide')
     assert.strictEqual($('.popover').length, 0, 'popover was removed')
@@ -126,7 +129,6 @@ $(function () {
     assert.strictEqual($('.popover').length, 0, 'popover was removed')
   })
 
-
   QUnit.test('should get title and content from attributes ignoring options passed via js', function (assert) {
     assert.expect(4)
     var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
@@ -177,7 +179,7 @@ $(function () {
     assert.strictEqual($._data($popover[0], 'events').click[0].namespace, 'foo', 'popover has extra click.foo event')
 
     $popover.bootstrapPopover('show')
-    $popover.bootstrapPopover('destroy')
+    $popover.bootstrapPopover('dispose')
 
     assert.ok(!$popover.hasClass('in'), 'popover is hidden')
     assert.ok(!$popover.data('popover'), 'popover does not have data')
@@ -229,7 +231,7 @@ $(function () {
             $div
               .one('shown.bs.popover', function () {
                 $('.content-with-handler .btn').trigger('click')
-                $div.bootstrapPopover('destroy')
+                $div.bootstrapPopover('dispose')
                 assert.ok(handlerCalled, 'content\'s event handler still present')
                 done()
               })
@@ -240,13 +242,6 @@ $(function () {
       .bootstrapPopover('show')
   })
 
-  QUnit.test('should throw an error when initializing popover on the document object without specifying a delegation selector', function (assert) {
-    assert.expect(1)
-    assert.throws(function () {
-      $(document).bootstrapPopover({ title: 'What am I on?', content: 'My selector is missing' })
-    }, new Error('`selector` option must be specified when initializing popover on the window.document object!'))
-  })
-
   QUnit.test('should do nothing when an attempt is made to hide an uninitialized popover', function (assert) {
     assert.expect(1)
 
@@ -259,16 +254,6 @@ $(function () {
     assert.strictEqual($popover.data('bs.popover'), undefined, 'should not initialize the popover')
   })
 
-  QUnit.test('should throw an error when template contains multiple top-level elements', function (assert) {
-    assert.expect(1)
-    assert.throws(function () {
-      $('<span data-toggle="popover" data-title="some title" data-content="some content">some text</span>')
-        .appendTo('#qunit-fixture')
-        .bootstrapPopover({ template: '<div>Foo</div><div>Bar</div>' })
-        .bootstrapPopover('show')
-    }, new Error('popover `template` option must consist of exactly 1 top-level element!'))
-  })
-
   QUnit.test('should fire inserted event', function (assert) {
     assert.expect(2)
     var done = assert.async()
diff --git a/js/tests/unit/scrollspy.js b/js/tests/unit/scrollspy.js
index bf5fa0bff55689d11342d4b4873ccf7a7eb0d408..063dfabcfbba5c4f3567b8253aaf49fba23b0da3 100644
--- a/js/tests/unit/scrollspy.js
+++ b/js/tests/unit/scrollspy.js
@@ -77,6 +77,51 @@ $(function () {
     $scrollspy.scrollTop(350)
   })
 
+  QUnit.test('should only switch "active" class on current target specified w element', function (assert) {
+    assert.expect(1)
+    var done = assert.async()
+
+    var sectionHTML = '<div id="root" class="active">'
+        + '<div class="topbar">'
+        + '<div class="topbar-inner">'
+        + '<div class="container" id="ss-target">'
+        + '<ul class="nav">'
+        + '<li><a href="#masthead">Overview</a></li>'
+        + '<li><a href="#detail">Detail</a></li>'
+        + '</ul>'
+        + '</div>'
+        + '</div>'
+        + '</div>'
+        + '<div id="scrollspy-example" style="height: 100px; overflow: auto;">'
+        + '<div style="height: 200px;">'
+        + '<h4 id="masthead">Overview</h4>'
+        + '<p style="height: 200px">'
+        + 'Ad leggings keytar, brunch id art party dolor labore.'
+        + '</p>'
+        + '</div>'
+        + '<div style="height: 200px;">'
+        + '<h4 id="detail">Detail</h4>'
+        + '<p style="height: 200px">'
+        + 'Veniam marfa mustache skateboard, adipisicing fugiat velit pitchfork beard.'
+        + '</p>'
+        + '</div>'
+        + '</div>'
+        + '</div>'
+    var $section = $(sectionHTML).appendTo('#qunit-fixture')
+
+    var $scrollspy = $section
+      .show()
+      .find('#scrollspy-example')
+      .bootstrapScrollspy({ target: document.getElementById('#ss-target') })
+
+    $scrollspy.on('scroll.bs.scrollspy', function () {
+      assert.ok($section.hasClass('active'), '"active" class still on root node')
+      done()
+    })
+
+    $scrollspy.scrollTop(350)
+  })
+
   QUnit.test('should correctly select middle navigation option when large offset is used', function (assert) {
     assert.expect(3)
     var done = assert.async()
@@ -275,4 +320,90 @@ $(function () {
       .then(function () { return testElementIsActiveAfterScroll('#li-100-1', '#div-100-1') })
   })
 
+  QUnit.test('should allow passed in option offset method: offset', function (assert) {
+    assert.expect(4)
+
+    var testOffsetMethod = function (type) {
+      var deferred = $.Deferred()
+      var navbarHtml =
+          '<nav class="navbar"' + (type === 'data' ? ' id="navbar-offset-method-menu"' : '') + '>'
+        + '<ul class="nav">'
+        + '<li id="li-' + type + 'm-1"><a href="#div-' + type + 'm-1">div 1</a></li>'
+        + '<li id="li-' + type + 'm-2"><a href="#div-' + type + 'm-2">div 2</a></li>'
+        + '<li id="li-' + type + 'm-3"><a href="#div-' + type + 'm-3">div 3</a></li>'
+        + '</ul>'
+        + '</nav>'
+      var contentHtml =
+          '<div class="content"' + (type === 'data' ? ' data-spy="scroll" data-target="#navbar-offset-method-menu" data-offset="0" data-method="offset"' : '') + ' style="position: relative; overflow: auto; height: 100px">'
+        + '<div id="div-' + type + 'm-1" style="position: relative; height: 200px; padding: 0; margin: 0">div 1</div>'
+        + '<div id="div-' + type + 'm-2" style="position: relative; height: 150px; padding: 0; margin: 0">div 2</div>'
+        + '<div id="div-' + type + 'm-3" style="position: relative; height: 250px; padding: 0; margin: 0">div 3</div>'
+        + '</div>'
+
+
+      $(navbarHtml).appendTo('#qunit-fixture')
+      var $content = $(contentHtml)
+        .appendTo('#qunit-fixture')
+
+      if (type === 'js') $content.bootstrapScrollspy({ target: '.navbar', offset: 0, method: 'offset' })
+      else if (type === 'data') $(window).trigger('load.bs.scrollspy.data-api')
+
+      var $target = $('#div-' + type + 'm-2')
+      var scrollspy = $content.data('bs.scrollspy')
+
+      assert.ok(scrollspy._offsets[1] === $target.offset().top, 'offsed method with ' + type + ' option')
+      assert.ok(scrollspy._offsets[1] !== $target.position().top, 'position method with ' + type + ' option')
+
+      deferred.resolve()
+
+      return deferred.promise()
+    }
+
+    $.when(testOffsetMethod('js'))
+      .then(function () { testOffsetMethod('data') })
+  })
+
+  QUnit.test('should allow passed in option offset method: position', function (assert) {
+    assert.expect(4)
+
+    var testOffsetMethod = function (type) {
+      var deferred = $.Deferred()
+      var navbarHtml =
+          '<nav class="navbar"' + (type === 'data' ? ' id="navbar-offset-method-menu"' : '') + '>'
+        + '<ul class="nav">'
+        + '<li id="li-' + type + 'm-1"><a href="#div-' + type + 'm-1">div 1</a></li>'
+        + '<li id="li-' + type + 'm-2"><a href="#div-' + type + 'm-2">div 2</a></li>'
+        + '<li id="li-' + type + 'm-3"><a href="#div-' + type + 'm-3">div 3</a></li>'
+        + '</ul>'
+        + '</nav>'
+      var contentHtml =
+          '<div class="content"' + (type === 'data' ? ' data-spy="scroll" data-target="#navbar-offset-method-menu" data-offset="0" data-method="position"' : '') + ' style="position: relative; overflow: auto; height: 100px">'
+        + '<div id="div-' + type + 'm-1" style="position: relative; height: 200px; padding: 0; margin: 0">div 1</div>'
+        + '<div id="div-' + type + 'm-2" style="position: relative; height: 150px; padding: 0; margin: 0">div 2</div>'
+        + '<div id="div-' + type + 'm-3" style="position: relative; height: 250px; padding: 0; margin: 0">div 3</div>'
+        + '</div>'
+
+
+      $(navbarHtml).appendTo('#qunit-fixture')
+      var $content = $(contentHtml)
+        .appendTo('#qunit-fixture')
+
+      if (type === 'js') $content.bootstrapScrollspy({ target: '.navbar', offset: 0, method: 'position' })
+      else if (type === 'data') $(window).trigger('load.bs.scrollspy.data-api')
+
+      var $target = $('#div-' + type + 'm-2')
+      var scrollspy = $content.data('bs.scrollspy')
+
+      assert.ok(scrollspy._offsets[1] !== $target.offset().top, 'offsed method with ' + type + ' option')
+      assert.ok(scrollspy._offsets[1] === $target.position().top, 'position method with ' + type + ' option')
+
+      deferred.resolve()
+
+      return deferred.promise()
+    }
+
+    $.when(testOffsetMethod('js'))
+      .then(function () { testOffsetMethod('data') })
+  })
+
 })
diff --git a/js/tests/unit/tooltip.js b/js/tests/unit/tooltip.js
index 27ce6208e7279dfb96f365df9046419467cbdca2..f4deb29f8ec20a51ad6ef962187462bfd53f15e2 100644
--- a/js/tests/unit/tooltip.js
+++ b/js/tests/unit/tooltip.js
@@ -16,6 +16,7 @@ $(function () {
     afterEach: function () {
       $.fn.tooltip = $.fn.bootstrapTooltip
       delete $.fn.bootstrapTooltip
+      $('.tooltip').remove()
     }
   })
 
@@ -34,7 +35,7 @@ $(function () {
 
   QUnit.test('should expose default settings', function (assert) {
     assert.expect(1)
-    assert.ok($.fn.bootstrapTooltip.Constructor.DEFAULTS, 'defaults is defined')
+    assert.ok($.fn.bootstrapTooltip.Constructor.Default, 'defaults is defined')
   })
 
   QUnit.test('should empty title attribute', function (assert) {
@@ -95,10 +96,14 @@ $(function () {
       .bootstrapTooltip({ placement: 'bottom' })
 
     $tooltip.bootstrapTooltip('show')
-    assert.ok($('.tooltip').is('.fade.bottom.in'), 'has correct classes applied')
+
+    assert
+      .ok($('.tooltip')
+      .is('.fade.bs-tether-element-attached-top.bs-tether-element-attached-center.in'), 'has correct classes applied')
 
     $tooltip.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed')
+
+    assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
   })
 
   QUnit.test('should allow html entities', function (assert) {
@@ -111,7 +116,7 @@ $(function () {
     assert.notEqual($('.tooltip b').length, 0, 'b tag was inserted')
 
     $tooltip.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed')
+    assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
   })
 
   QUnit.test('should respect custom classes', function (assert) {
@@ -124,7 +129,7 @@ $(function () {
     assert.ok($('.tooltip').hasClass('some-class'), 'custom class is present')
 
     $tooltip.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed')
+    assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
   })
 
   QUnit.test('should fire show event', function (assert) {
@@ -245,7 +250,7 @@ $(function () {
     assert.strictEqual($._data($tooltip[0], 'events').click[0].namespace, 'foo', 'tooltip has extra click.foo event')
 
     $tooltip.bootstrapTooltip('show')
-    $tooltip.bootstrapTooltip('destroy')
+    $tooltip.bootstrapTooltip('dispose')
 
     assert.ok(!$tooltip.hasClass('in'), 'tooltip is hidden')
     assert.ok(!$._data($tooltip[0], 'bs.tooltip'), 'tooltip does not have data')
@@ -253,21 +258,21 @@ $(function () {
     assert.ok(!$._data($tooltip[0], 'events').mouseover && !$._data($tooltip[0], 'events').mouseout, 'tooltip does not have hover events')
   })
 
-  QUnit.test('should show tooltip with delegate selector on click', function (assert) {
-    assert.expect(2)
-    var $div = $('<div><a href="#" rel="tooltip" title="Another tooltip"/></div>')
-      .appendTo('#qunit-fixture')
-      .bootstrapTooltip({
-        selector: 'a[rel="tooltip"]',
-        trigger: 'click'
-      })
+  // QUnit.test('should show tooltip with delegate selector on click', function (assert) {
+  //   assert.expect(2)
+  //   var $div = $('<div><a href="#" rel="tooltip" title="Another tooltip"/></div>')
+  //     .appendTo('#qunit-fixture')
+  //     .bootstrapTooltip({
+  //       selector: 'a[rel="tooltip"]',
+  //       trigger: 'click'
+  //     })
 
-    $div.find('a').trigger('click')
-    assert.ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
+  //   $div.find('a').trigger('click')
+  //   assert.ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
 
-    $div.find('a').trigger('click')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip was removed from dom')
-  })
+  //   $div.find('a').trigger('click')
+  //   assert.strictEqual($div.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
+  // })
 
   QUnit.test('should show tooltip when toggle is called', function (assert) {
     assert.expect(1)
@@ -307,20 +312,20 @@ $(function () {
   QUnit.test('should add position class before positioning so that position-specific styles are taken into account', function (assert) {
     assert.expect(1)
     var styles = '<style>'
-        + '.tooltip.right { white-space: nowrap; }'
-        + '.tooltip.right .tooltip-inner { max-width: none; }'
-        + '</style>'
+      + '.tooltip.right { white-space: nowrap; }'
+      + '.tooltip.right .tooltip-inner { max-width: none; }'
+      + '</style>'
     var $styles = $(styles).appendTo('head')
 
     var $container = $('<div/>').appendTo('#qunit-fixture')
     var $target = $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line"/>')
       .appendTo($container)
       .bootstrapTooltip({
-        placement: 'right',
-        viewport: null
+        placement: 'right'
       })
       .bootstrapTooltip('show')
-    var $tooltip = $container.find('.tooltip')
+
+    var $tooltip = $($target.data('bs.tooltip').tip)
 
     // this is some dumb hack shit because sub pixels in firefox
     var top = Math.round($target.offset().top + ($target[0].offsetHeight / 2) - ($tooltip[0].offsetHeight / 2))
@@ -376,444 +381,7 @@ $(function () {
     assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
   })
 
-  QUnit.test('should be placed dynamically to viewport with the dynamic placement option', function (assert) {
-    assert.expect(6)
-    var $style = $('<style> div[rel="tooltip"] { position: absolute; } #qunit-fixture { top: inherit; left: inherit } </style>').appendTo('head')
-    var $container = $('<div/>')
-      .css({
-        position: 'relative',
-        height: '100%'
-      })
-      .appendTo('#qunit-fixture')
-
-    var $topTooltip = $('<div style="left: 0; top: 0;" rel="tooltip" title="Top tooltip">Top Dynamic Tooltip</div>')
-      .appendTo($container)
-      .bootstrapTooltip({ placement: 'auto', viewport: '#qunit-fixture' })
-
-    $topTooltip.bootstrapTooltip('show')
-    assert.ok($('.tooltip').is('.bottom'), 'top positioned tooltip is dynamically positioned to bottom')
-
-    $topTooltip.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'top positioned tooltip removed from dom')
-
-    var $rightTooltip = $('<div style="right: 0;" rel="tooltip" title="Right tooltip">Right Dynamic Tooltip</div>')
-      .appendTo($container)
-      .bootstrapTooltip({ placement: 'right auto', viewport: '#qunit-fixture' })
-
-    $rightTooltip.bootstrapTooltip('show')
-    assert.ok($('.tooltip').is('.left'), 'right positioned tooltip is dynamically positioned left')
-
-    $rightTooltip.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'right positioned tooltip removed from dom')
-
-    var $leftTooltip = $('<div style="left: 0;" rel="tooltip" title="Left tooltip">Left Dynamic Tooltip</div>')
-      .appendTo($container)
-      .bootstrapTooltip({ placement: 'auto left', viewport: '#qunit-fixture' })
-
-    $leftTooltip.bootstrapTooltip('show')
-    assert.ok($('.tooltip').is('.right'), 'left positioned tooltip is dynamically positioned right')
-
-    $leftTooltip.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'left positioned tooltip removed from dom')
-
-    $container.remove()
-    $style.remove()
-  })
-
-  QUnit.test('should position tip on top if viewport has enough space and placement is "auto top"', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + 'body { padding-top: 100px; }'
-        + '#section { height: 300px; border: 1px solid red; padding-top: 50px }'
-        + 'div[rel="tooltip"] { width: 150px; border: 1px solid blue; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div id="section"/>').appendTo('#qunit-fixture')
-    var $target = $('<div rel="tooltip" title="tip"/>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'auto top',
-        viewport: '#section'
-      })
-
-    $target.bootstrapTooltip('show')
-    assert.ok($('.tooltip').is('.top'), 'top positioned tooltip is dynamically positioned to top')
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $styles.remove()
-  })
-
-  QUnit.test('should position tip on top if viewport has enough space and is not parent', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + '#section { height: 300px; border: 1px solid red; margin-top: 100px; }'
-        + 'div[rel="tooltip"] { width: 150px; border: 1px solid blue; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div id="section"/>').appendTo('#qunit-fixture')
-    var $target = $('<div rel="tooltip" title="tip"/>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'auto top',
-        viewport: '#qunit-fixture'
-      })
-
-    $target.bootstrapTooltip('show')
-    assert.ok($('.tooltip').is('.top'), 'top positioned tooltip is dynamically positioned to top')
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $styles.remove()
-  })
-
-  QUnit.test('should position tip on bottom if the tip\'s dimension exceeds the viewport area and placement is "auto top"', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + 'body { padding-top: 100px; }'
-        + '#section { height: 300px; border: 1px solid red; }'
-        + 'div[rel="tooltip"] { width: 150px; border: 1px solid blue; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div id="section"/>').appendTo('#qunit-fixture')
-    var $target = $('<div rel="tooltip" title="tip"/>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'auto top',
-        viewport: '#section'
-      })
-
-    $target.bootstrapTooltip('show')
-    assert.ok($('.tooltip').is('.bottom'), 'top positioned tooltip is dynamically positioned to bottom')
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $styles.remove()
-  })
-
-  QUnit.test('should display the tip on top whenever scrollable viewport has enough room if the given placement is "auto top"', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + '#scrollable-div { height: 200px; overflow: auto; }'
-        + '.tooltip-item { margin: 200px 0 400px; width: 150px; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div id="scrollable-div"/>').appendTo('#qunit-fixture')
-    var $target = $('<div rel="tooltip" title="tip" class="tooltip-item">Tooltip Item</div>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'top auto',
-        viewport: '#scrollable-div'
-      })
-
-    $('#scrollable-div').scrollTop(100)
-
-    $target.bootstrapTooltip('show')
-    assert.ok($('.tooltip').is('.fade.top.in'), 'has correct classes applied')
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $styles.remove()
-  })
-
-  QUnit.test('should display the tip on bottom whenever scrollable viewport doesn\'t have enough room if the given placement is "auto top"', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + '#scrollable-div { height: 200px; overflow: auto; }'
-        + '.tooltip-item { padding: 200px 0 400px; width: 150px; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div id="scrollable-div"/>').appendTo('#qunit-fixture')
-    var $target = $('<div rel="tooltip" title="tip" class="tooltip-item">Tooltip Item</div>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'top auto',
-        viewport: '#scrollable-div'
-      })
-
-    $('#scrollable-div').scrollTop(200)
-
-    $target.bootstrapTooltip('show')
-    assert.ok($('.tooltip').is('.fade.bottom.in'), 'has correct classes applied')
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $styles.remove()
-  })
-
-  QUnit.test('should display the tip on bottom whenever scrollable viewport has enough room if the given placement is "auto bottom"', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + '#scrollable-div { height: 200px; overflow: auto; }'
-        + '.spacer { height: 400px; }'
-        + '.spacer:first-child { height: 200px; }'
-        + '.tooltip-item { width: 150px; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div id="scrollable-div"/>').appendTo('#qunit-fixture')
-    var $target = $('<div rel="tooltip" title="tip" class="tooltip-item">Tooltip Item</div>')
-      .appendTo($container)
-      .before('<div class="spacer"/>')
-      .after('<div class="spacer"/>')
-      .bootstrapTooltip({
-        placement: 'bottom auto',
-        viewport: '#scrollable-div'
-      })
-
-    $('#scrollable-div').scrollTop(200)
-
-    $target.bootstrapTooltip('show')
-    assert.ok($('.tooltip').is('.fade.bottom.in'), 'has correct classes applied')
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $styles.remove()
-  })
-
-  QUnit.test('should display the tip on top whenever scrollable viewport doesn\'t have enough room if the given placement is "auto bottom"', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + '#scrollable-div { height: 200px; overflow: auto; }'
-        + '.tooltip-item { margin-top: 400px; width: 150px; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div id="scrollable-div"/>').appendTo('#qunit-fixture')
-    var $target = $('<div rel="tooltip" title="tip" class="tooltip-item">Tooltip Item</div>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'bottom auto',
-        viewport: '#scrollable-div'
-      })
-
-    $('#scrollable-div').scrollTop(400)
-
-    $target.bootstrapTooltip('show')
-    assert.ok($('.tooltip').is('.fade.top.in'), 'has correct classes applied')
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $styles.remove()
-  })
-
-  QUnit.test('should adjust the tip\'s top position when up against the top of the viewport', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
-        + 'a[rel="tooltip"] { position: fixed; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div/>').appendTo('#qunit-fixture')
-    var $target = $('<a href="#" rel="tooltip" title="tip" style="top: 0px; left: 0px;"/>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'right',
-        viewport: {
-          selector: 'body',
-          padding: 12
-        }
-      })
-
-    $target.bootstrapTooltip('show')
-    assert.strictEqual(Math.round($container.find('.tooltip').offset().top), 12)
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $styles.remove()
-  })
-
-  QUnit.test('should adjust the tip\'s top position when up against the bottom of the viewport', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
-        + 'a[rel="tooltip"] { position: fixed; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div/>').appendTo('#qunit-fixture')
-    var $target = $('<a href="#" rel="tooltip" title="tip" style="bottom: 0px; left: 0px;"/>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'right',
-        viewport: {
-          selector: 'body',
-          padding: 12
-        }
-      })
-
-    $target.bootstrapTooltip('show')
-    var $tooltip = $container.find('.tooltip')
-    assert.strictEqual(Math.round($tooltip.offset().top), Math.round($(window).height() - 12 - $tooltip[0].offsetHeight))
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $container.remove()
-    $styles.remove()
-  })
-
-  QUnit.test('should adjust the tip\'s left position when up against the left of the viewport', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
-        + 'a[rel="tooltip"] { position: fixed; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div/>').appendTo('#qunit-fixture')
-    var $target = $('<a href="#" rel="tooltip" title="tip" style="top: 0px; left: 0px;"/>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'bottom',
-        viewport: {
-          selector: 'body',
-          padding: 12
-        }
-      })
-
-    $target.bootstrapTooltip('show')
-    assert.strictEqual(Math.round($container.find('.tooltip').offset().left), 12)
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $container.remove()
-    $styles.remove()
-  })
-
-  QUnit.test('should adjust the tip\'s left position when up against the right of the viewport', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
-        + 'a[rel="tooltip"] { position: fixed; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div/>').appendTo('body')
-    var $target = $('<a href="#" rel="tooltip" title="tip" style="top: 0px; right: 0px;"/>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'bottom',
-        viewport: {
-          selector: 'body',
-          padding: 12
-        }
-      })
-
-    $target.bootstrapTooltip('show')
-    var $tooltip = $container.find('.tooltip')
-    assert.strictEqual(Math.round($tooltip.offset().left), Math.round($(window).width() - 12 - $tooltip[0].offsetWidth))
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $container.remove()
-    $styles.remove()
-  })
-
-  QUnit.test('should adjust the tip when up against the right of an arbitrary viewport', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + '.tooltip, .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
-        + '.container-viewport { position: absolute; top: 50px; left: 60px; width: 300px; height: 300px; }'
-        + 'a[rel="tooltip"] { position: fixed; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div class="container-viewport"/>').appendTo(document.body)
-    var $target = $('<a href="#" rel="tooltip" title="tip" style="top: 50px; left: 350px;"/>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'bottom',
-        viewport: '.container-viewport'
-      })
-
-    $target.bootstrapTooltip('show')
-    var $tooltip = $container.find('.tooltip')
-    assert.strictEqual(Math.round($tooltip.offset().left), Math.round(60 + $container.width() - $tooltip[0].offsetWidth))
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $container.remove()
-    $styles.remove()
-  })
-
-  QUnit.test('should get viewport element from function', function (assert) {
-    assert.expect(3)
-    var styles = '<style>'
-        + '.tooltip, .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
-        + '.container-viewport { position: absolute; top: 50px; left: 60px; width: 300px; height: 300px; }'
-        + 'a[rel="tooltip"] { position: fixed; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div class="container-viewport"/>').appendTo(document.body)
-    var $target = $('<a href="#" rel="tooltip" title="tip" style="top: 50px; left: 350px;"/>').appendTo($container)
-    $target
-      .bootstrapTooltip({
-        placement: 'bottom',
-        viewport: function ($element) {
-          assert.strictEqual($element[0], $target[0], 'viewport function was passed target as argument')
-          return ($element.closest('.container-viewport'))
-        }
-      })
-
-    $target.bootstrapTooltip('show')
-    var $tooltip = $container.find('.tooltip')
-    assert.strictEqual(Math.round($tooltip.offset().left), Math.round(60 + $container.width() - $tooltip[0].offsetWidth))
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $container.remove()
-    $styles.remove()
-  })
-
-  QUnit.test('should not misplace the tip when the right edge offset is greater or equal than the viewport width', function (assert) {
-    assert.expect(2)
-    var styles = '<style>'
-        + '.tooltip, .tooltip *, .tooltip *:before, .tooltip *:after { box-sizing: border-box; }'
-        + '.container-viewport, .container-viewport *, .container-viewport *:before, .container-viewport *:after { box-sizing: border-box; }'
-        + '.tooltip, .tooltip .tooltip-inner { width: 50px; height: 50px; max-width: none; background: red; }'
-        + '.container-viewport { padding: 100px; margin-left: 100px; width: 100px; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    var $container = $('<div class="container-viewport"/>').appendTo(document.body)
-    var $target = $('<a href="#" rel="tooltip" title="tip">foobar</a>')
-      .appendTo($container)
-      .bootstrapTooltip({
-        viewport: '.container-viewport'
-      })
-
-    $target.bootstrapTooltip('show')
-    var $tooltip = $container.find('.tooltip')
-    assert.strictEqual(Math.round($tooltip.offset().left), Math.round($target.position().left + $target.width() / 2 - $tooltip[0].offsetWidth / 2))
-
-    $target.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-
-    $container.remove()
-    $styles.remove()
-  })
-
-  QUnit.test('should not error when trying to show an auto-placed tooltip that has been removed from the dom', function (assert) {
+  QUnit.test('should not error when trying to show an top-placed tooltip that has been removed from the dom', function (assert) {
     assert.expect(1)
     var passed = true
     var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
@@ -821,7 +389,7 @@ $(function () {
       .one('show.bs.tooltip', function () {
         $(this).remove()
       })
-      .bootstrapTooltip({ placement: 'auto' })
+      .bootstrapTooltip({ placement: 'top' })
 
     try {
       $tooltip.bootstrapTooltip('show')
@@ -863,7 +431,7 @@ $(function () {
       })
       .bootstrapTooltip('show')
 
-    var $tooltip = $container.find('.tooltip')
+    var $tooltip = $($trigger.data('bs.tooltip').tip)
 
     setTimeout(function () {
       assert.ok(Math.round($tooltip.offset().top + $tooltip.outerHeight()) <= Math.round($trigger.offset().top))
@@ -871,38 +439,6 @@ $(function () {
     }, 0)
   })
 
-  QUnit.test('should place tooltip inside viewport', function (assert) {
-    assert.expect(1)
-    var done = assert.async()
-
-    var $container = $('<div/>')
-      .css({
-        position: 'absolute',
-        width: 200,
-        height: 200,
-        bottom: 0,
-        left: 0
-      })
-      .appendTo('#qunit-fixture')
-
-    $('<a href="#" title="Very very very very very very very very long tooltip">Hover me</a>')
-      .css({
-        position: 'absolute',
-        top: 0,
-        left: 0
-      })
-      .appendTo($container)
-      .bootstrapTooltip({
-        placement: 'top'
-      })
-      .bootstrapTooltip('show')
-
-    setTimeout(function () {
-      assert.ok($('.tooltip').offset().left >= 0)
-      done()
-    }, 0)
-  })
-
   QUnit.test('should show tooltip if leave event hasn\'t occurred before delay expires', function (assert) {
     assert.expect(2)
     var done = assert.async()
@@ -1021,16 +557,16 @@ $(function () {
       .bootstrapTooltip({ delay: { show: 0, hide: 150 }})
 
     setTimeout(function () {
-      assert.ok($tooltip.data('bs.tooltip').$tip.is('.fade.in'), '1ms: tooltip faded in')
+      assert.ok($($tooltip.data('bs.tooltip').tip).is('.fade.in'), '1ms: tooltip faded in')
 
       $tooltip.trigger('mouseout')
 
       setTimeout(function () {
-        assert.ok($tooltip.data('bs.tooltip').$tip.is('.fade.in'), '100ms: tooltip still faded in')
+        assert.ok($($tooltip.data('bs.tooltip').tip).is('.fade.in'), '100ms: tooltip still faded in')
       }, 100)
 
       setTimeout(function () {
-        assert.ok(!$tooltip.data('bs.tooltip').$tip.is('.in'), '200ms: tooltip removed')
+        assert.ok(!$($tooltip.data('bs.tooltip').tip).is('.in'), '200ms: tooltip removed')
         done()
       }, 200)
 
@@ -1073,57 +609,15 @@ $(function () {
         assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
         done()
       })
-      .bootstrapTooltip({ container: 'body', placement: 'top', trigger: 'manual' })
+      .bootstrapTooltip({ placement: 'top', trigger: 'manual' })
 
     $circle.bootstrapTooltip('show')
   })
 
-  QUnit.test('should correctly determine auto placement based on container rather than parent', function (assert) {
-    assert.expect(2)
-    var done = assert.async()
-
-    var styles = '<style>'
-        + '.tooltip, .tooltip *, .tooltip *:before, .tooltip *:after { box-sizing: border-box; }'
-        + '.tooltip { position: absolute; display: block; font-size: 12px; line-height: 1.4; }'
-        + '.tooltip .tooltip-inner { max-width: 200px; padding: 3px 8px; font-family: Helvetica; text-align: center; }'
-        + '#trigger-parent {'
-        + '  position: fixed;'
-        + '  top: 100px;'
-        + '  right: 17px;'
-        + '}'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    $('#qunit-fixture').append('<span id="trigger-parent"><a id="tt-trigger" title="If a_larger_text is written here, it won\'t fit using older broken version of BS">HOVER OVER ME</a></span>')
-    var $trigger = $('#tt-trigger')
-
-    $trigger
-      .on('shown.bs.tooltip', function () {
-        var $tip = $('.tooltip-inner')
-        var tipXrightEdge = $tip.offset().left + $tip.width()
-        var triggerXleftEdge = $trigger.offset().left
-        assert.ok(tipXrightEdge < triggerXleftEdge, 'tooltip with auto left placement, when near the right edge of the viewport, gets left placement')
-        $trigger.bootstrapTooltip('hide')
-      })
-      .on('hidden.bs.tooltip', function () {
-        $styles.remove()
-        $(this).remove()
-        assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-        done()
-      })
-      .bootstrapTooltip({
-        container: 'body',
-        placement: 'auto left',
-        trigger: 'manual'
-      })
-
-    $trigger.bootstrapTooltip('show')
-  })
-
   QUnit.test('should not reload the tooltip on subsequent mouseenter events', function (assert) {
     assert.expect(1)
     var titleHtml = function () {
-      var uid = $.fn.bootstrapTooltip.Constructor.prototype.getUID('tooltip')
+      var uid = Util.getUID('tooltip')
       return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
     }
 
@@ -1149,8 +643,9 @@ $(function () {
 
   QUnit.test('should not reload the tooltip if the mouse leaves and re-enters before hiding', function (assert) {
     assert.expect(4)
+
     var titleHtml = function () {
-      var uid = $.fn.bootstrapTooltip.Constructor.prototype.getUID('tooltip')
+      var uid = Util.getUID('tooltip')
       return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
     }
 
@@ -1162,7 +657,6 @@ $(function () {
       animation: false,
       trigger: 'hover',
       delay: { show: 0, hide: 500 },
-      container: $tooltip,
       title: titleHtml
     })
 
@@ -1175,47 +669,14 @@ $(function () {
     $('#tt-outer').trigger('mouseleave')
     assert.strictEqual(currentUid, $('#tt-content').text())
 
-    assert.ok(obj.hoverState == 'out', 'the tooltip hoverState should be set to "out"')
+    assert.ok(obj._hoverState == 'out', 'the tooltip hoverState should be set to "out"')
 
-    $('#tt-content').trigger('mouseenter')
-    assert.ok(obj.hoverState == 'in', 'the tooltip hoverState should be set to "in"')
+    $('#tt-outer').trigger('mouseenter')
+    assert.ok(obj._hoverState == 'in', 'the tooltip hoverState should be set to "in"')
 
     assert.strictEqual(currentUid, $('#tt-content').text())
   })
 
-  QUnit.test('should position arrow correctly when tooltip is moved to not appear offscreen', function (assert) {
-    assert.expect(2)
-    var done = assert.async()
-
-    var styles = '<style>'
-        + '.tooltip, .tooltip *, .tooltip *:before, .tooltip *:after { box-sizing: border-box; }'
-        + '.tooltip { position: absolute; }'
-        + '.tooltip-arrow { position: absolute; width: 0; height: 0; }'
-        + '.tooltip .tooltip-inner { max-width: 200px; padding: 3px 8px; }'
-        + '</style>'
-    var $styles = $(styles).appendTo('head')
-
-    $('<a href="#" title="tooltip title" style="position: absolute; bottom: 0; right: 0;">Foobar</a>')
-      .appendTo('body')
-      .on('shown.bs.tooltip', function () {
-        var arrowStyles = $(this).data('bs.tooltip').$tip.find('.tooltip-arrow').attr('style')
-        assert.ok(/left/i.test(arrowStyles) && !/top/i.test(arrowStyles), 'arrow positioned correctly')
-        $(this).bootstrapTooltip('hide')
-      })
-      .on('hidden.bs.tooltip', function () {
-        $styles.remove()
-        $(this).remove()
-        assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
-        done()
-      })
-      .bootstrapTooltip({
-        container: 'body',
-        placement: 'top',
-        trigger: 'manual'
-      })
-      .bootstrapTooltip('show')
-  })
-
   QUnit.test('should correctly position tooltips on transformed elements', function (assert) {
     var styleProps = document.documentElement.style
     if (!('transform' in styleProps) && !('webkitTransform' in styleProps) && !('msTransform' in styleProps)) {
@@ -1247,21 +708,12 @@ $(function () {
         done()
       })
       .bootstrapTooltip({
-        container: 'body',
-        placement: 'top',
         trigger: 'manual'
       })
 
     $element.bootstrapTooltip('show')
   })
 
-  QUnit.test('should throw an error when initializing tooltip on the document object without specifying a delegation selector', function (assert) {
-    assert.expect(1)
-    assert.throws(function () {
-      $(document).bootstrapTooltip({ title: 'What am I on?' })
-    }, new Error('`selector` option must be specified when initializing tooltip on the window.document object!'))
-  })
-
   QUnit.test('should do nothing when an attempt is made to hide an uninitialized tooltip', function (assert) {
     assert.expect(1)
 
@@ -1274,25 +726,15 @@ $(function () {
     assert.strictEqual($tooltip.data('bs.tooltip'), undefined, 'should not initialize the tooltip')
   })
 
-  QUnit.test('should throw an error when template contains multiple top-level elements', function (assert) {
-    assert.expect(1)
-    assert.throws(function () {
-      $('<a href="#" data-toggle="tooltip" title="Another tooltip"></a>')
-        .appendTo('#qunit-fixture')
-        .bootstrapTooltip({ template: '<div>Foo</div><div>Bar</div>' })
-        .bootstrapTooltip('show')
-    }, new Error('tooltip `template` option must consist of exactly 1 top-level element!'))
-  })
-
   QUnit.test('should not remove tooltip if multiple triggers are set and one is still active', function (assert) {
     assert.expect(41)
     var $el = $('<button>Trigger</button>')
       .appendTo('#qunit-fixture')
       .bootstrapTooltip({ trigger: 'click hover focus', animation: false })
     var tooltip = $el.data('bs.tooltip')
-    var $tooltip = tooltip.tip()
+    var $tooltip = $(tooltip.getTipElement())
 
-    function showingTooltip() { return $tooltip.hasClass('in') || tooltip.hoverState == 'in' }
+    function showingTooltip() { return $tooltip.hasClass('in') || tooltip._hoverState == 'in' }
 
     var tests = [
         ['mouseenter', 'mouseleave'],
diff --git a/js/tests/vendor/tether.min.js b/js/tests/vendor/tether.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..882e9e8c88bea296f483e7680c4488f78a9b2e66
--- /dev/null
+++ b/js/tests/vendor/tether.min.js
@@ -0,0 +1,2 @@
+/*! tether 0.7.1 */
+!function(t,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e(require,exports,module):t.Tether=e()}(this,function(t,e,o){return function(){var t,e,o,i,n,s,l,r,h,a,f,p,u,d,g,c,m,b,v,y={}.hasOwnProperty,w=[].indexOf||function(t){for(var e=0,o=this.length;o>e;e++)if(e in this&&this[e]===t)return e;return-1},C=[].slice;null==this.Tether&&(this.Tether={modules:[]}),p=function(t){var e,o,i,n,s;if(o=getComputedStyle(t).position,"fixed"===o)return t;for(i=void 0,e=t;e=e.parentNode;){try{n=getComputedStyle(e)}catch(l){}if(null==n)return e;if(/(auto|scroll)/.test(n.overflow+n.overflowY+n.overflowX)&&("absolute"!==o||"relative"===(s=n.position)||"absolute"===s||"fixed"===s))return e}return document.body},m=function(){var t;return t=0,function(){return t++}}(),v={},a=function(t){var e,i,s,l,r;if(s=t._tetherZeroElement,null==s&&(s=t.createElement("div"),s.setAttribute("data-tether-id",m()),n(s.style,{top:0,left:0,position:"absolute"}),t.body.appendChild(s),t._tetherZeroElement=s),e=s.getAttribute("data-tether-id"),null==v[e]){v[e]={},r=s.getBoundingClientRect();for(i in r)l=r[i],v[e][i]=l;o(function(){return v[e]=void 0})}return v[e]},d=null,l=function(t){var e,o,i,n,s,l,r;t===document?(o=document,t=document.documentElement):o=t.ownerDocument,i=o.documentElement,e={},r=t.getBoundingClientRect();for(n in r)l=r[n],e[n]=l;return s=a(o),e.top-=s.top,e.left-=s.left,null==e.width&&(e.width=document.body.scrollWidth-e.left-e.right),null==e.height&&(e.height=document.body.scrollHeight-e.top-e.bottom),e.top=e.top-i.clientTop,e.left=e.left-i.clientLeft,e.right=o.body.clientWidth-e.width-e.left,e.bottom=o.body.clientHeight-e.height-e.top,e},h=function(t){return t.offsetParent||document.documentElement},f=function(){var t,e,o,i,s;return t=document.createElement("div"),t.style.width="100%",t.style.height="200px",e=document.createElement("div"),n(e.style,{position:"absolute",top:0,left:0,pointerEvents:"none",visibility:"hidden",width:"200px",height:"150px",overflow:"hidden"}),e.appendChild(t),document.body.appendChild(e),i=t.offsetWidth,e.style.overflow="scroll",s=t.offsetWidth,i===s&&(s=e.clientWidth),document.body.removeChild(e),o=i-s,{width:o,height:o}},n=function(t){var e,o,i,n,s,l,r;for(null==t&&(t={}),e=[],Array.prototype.push.apply(e,arguments),r=e.slice(1),s=0,l=r.length;l>s;s++)if(i=r[s])for(o in i)y.call(i,o)&&(n=i[o],t[o]=n);return t},g=function(t,e){var o,i,n,s,l,h;if(null!=t.classList){for(l=e.split(" "),h=[],n=0,s=l.length;s>n;n++)i=l[n],i.trim()&&h.push(t.classList.remove(i));return h}return o=r(t).replace(new RegExp("(^| )"+e.split(" ").join("|")+"( |$)","gi")," "),c(t,o)},e=function(t,e){var o,i,n,s,l;if(null!=t.classList){for(s=e.split(" "),l=[],i=0,n=s.length;n>i;i++)o=s[i],o.trim()&&l.push(t.classList.add(o));return l}return g(t,e),o=r(t)+(" "+e),c(t,o)},u=function(t,e){return null!=t.classList?t.classList.contains(e):new RegExp("(^| )"+e+"( |$)","gi").test(r(t))},r=function(t){return t.className instanceof SVGAnimatedString?t.className.baseVal:t.className},c=function(t,e){return t.setAttribute("class",e)},b=function(t,o,i){var n,s,l,r,h,a;for(s=0,r=i.length;r>s;s++)n=i[s],w.call(o,n)<0&&u(t,n)&&g(t,n);for(a=[],l=0,h=o.length;h>l;l++)n=o[l],a.push(u(t,n)?void 0:e(t,n));return a},i=[],o=function(t){return i.push(t)},s=function(){var t,e;for(e=[];t=i.pop();)e.push(t());return e},t=function(){function t(){}return t.prototype.on=function(t,e,o,i){var n;return null==i&&(i=!1),null==this.bindings&&(this.bindings={}),null==(n=this.bindings)[t]&&(n[t]=[]),this.bindings[t].push({handler:e,ctx:o,once:i})},t.prototype.once=function(t,e,o){return this.on(t,e,o,!0)},t.prototype.off=function(t,e){var o,i,n;if(null!=(null!=(i=this.bindings)?i[t]:void 0)){if(null==e)return delete this.bindings[t];for(o=0,n=[];o<this.bindings[t].length;)n.push(this.bindings[t][o].handler===e?this.bindings[t].splice(o,1):o++);return n}},t.prototype.trigger=function(){var t,e,o,i,n,s,l,r,h;if(o=arguments[0],t=2<=arguments.length?C.call(arguments,1):[],null!=(l=this.bindings)?l[o]:void 0){for(n=0,h=[];n<this.bindings[o].length;)r=this.bindings[o][n],i=r.handler,e=r.ctx,s=r.once,i.apply(null!=e?e:this,t),h.push(s?this.bindings[o].splice(n,1):n++);return h}},t}(),this.Tether.Utils={getScrollParent:p,getBounds:l,getOffsetParent:h,extend:n,addClass:e,removeClass:g,hasClass:u,updateClasses:b,defer:o,flush:s,uniqueId:m,Evented:t,getScrollBarSize:f}}.call(this),function(){var t,e,o,i,n,s,l,r,h,a,f,p,u,d,g,c,m,b,v,y,w,C,O,T,x,A,E,S,W,M=[].slice,P=function(t,e){return function(){return t.apply(e,arguments)}};if(null==this.Tether)throw new Error("You must include the utils.js file before tether.js");i=this.Tether,W=i.Utils,c=W.getScrollParent,m=W.getSize,d=W.getOuterSize,p=W.getBounds,u=W.getOffsetParent,a=W.extend,n=W.addClass,O=W.removeClass,A=W.updateClasses,h=W.defer,f=W.flush,g=W.getScrollBarSize,E=function(t,e,o){return null==o&&(o=1),t+o>=e&&e>=t-o},x=function(){var t,e,o,i,n;for(t=document.createElement("div"),n=["transform","webkitTransform","OTransform","MozTransform","msTransform"],o=0,i=n.length;i>o;o++)if(e=n[o],void 0!==t.style[e])return e}(),T=[],C=function(){var t,e,o;for(e=0,o=T.length;o>e;e++)t=T[e],t.position(!1);return f()},b=function(){var t;return null!=(t="undefined"!=typeof performance&&null!==performance&&"function"==typeof performance.now?performance.now():void 0)?t:+new Date},function(){var t,e,o,i,n,s,l,r,h;for(e=null,o=null,i=null,n=function(){if(null!=o&&o>16)return o=Math.min(o-16,250),void(i=setTimeout(n,250));if(!(null!=e&&b()-e<10))return null!=i&&(clearTimeout(i),i=null),e=b(),C(),o=b()-e},r=["resize","scroll","touchmove"],h=[],s=0,l=r.length;l>s;s++)t=r[s],h.push(window.addEventListener(t,n));return h}(),t={center:"center",left:"right",right:"left"},e={middle:"middle",top:"bottom",bottom:"top"},o={top:0,left:0,middle:"50%",center:"50%",bottom:"100%",right:"100%"},r=function(o,i){var n,s;return n=o.left,s=o.top,"auto"===n&&(n=t[i.left]),"auto"===s&&(s=e[i.top]),{left:n,top:s}},l=function(t){var e,i;return{left:null!=(e=o[t.left])?e:t.left,top:null!=(i=o[t.top])?i:t.top}},s=function(){var t,e,o,i,n,s,l;for(e=1<=arguments.length?M.call(arguments,0):[],o={top:0,left:0},n=0,s=e.length;s>n;n++)l=e[n],i=l.top,t=l.left,"string"==typeof i&&(i=parseFloat(i,10)),"string"==typeof t&&(t=parseFloat(t,10)),o.top+=i,o.left+=t;return o},v=function(t,e){return"string"==typeof t.left&&-1!==t.left.indexOf("%")&&(t.left=parseFloat(t.left,10)/100*e.width),"string"==typeof t.top&&-1!==t.top.indexOf("%")&&(t.top=parseFloat(t.top,10)/100*e.height),t},y=w=function(t){var e,o,i;return i=t.split(" "),o=i[0],e=i[1],{top:o,left:e}},S=function(){function t(t){this.position=P(this.position,this);var e,o,n,s,l;for(T.push(this),this.history=[],this.setOptions(t,!1),s=i.modules,o=0,n=s.length;n>o;o++)e=s[o],null!=(l=e.initialize)&&l.call(this);this.position()}return t.modules=[],t.prototype.getClass=function(t){var e,o;return(null!=(e=this.options.classes)?e[t]:void 0)?this.options.classes[t]:(null!=(o=this.options.classes)?o[t]:void 0)!==!1?this.options.classPrefix?""+this.options.classPrefix+"-"+t:t:""},t.prototype.setOptions=function(t,e){var o,i,s,l,r,h;for(this.options=t,null==e&&(e=!0),o={offset:"0 0",targetOffset:"0 0",targetAttachment:"auto auto",classPrefix:"tether"},this.options=a(o,this.options),r=this.options,this.element=r.element,this.target=r.target,this.targetModifier=r.targetModifier,"viewport"===this.target?(this.target=document.body,this.targetModifier="visible"):"scroll-handle"===this.target&&(this.target=document.body,this.targetModifier="scroll-handle"),h=["element","target"],s=0,l=h.length;l>s;s++){if(i=h[s],null==this[i])throw new Error("Tether Error: Both element and target must be defined");null!=this[i].jquery?this[i]=this[i][0]:"string"==typeof this[i]&&(this[i]=document.querySelector(this[i]))}if(n(this.element,this.getClass("element")),this.options.addTargetClasses!==!1&&n(this.target,this.getClass("target")),!this.options.attachment)throw new Error("Tether Error: You must provide an attachment");return this.targetAttachment=y(this.options.targetAttachment),this.attachment=y(this.options.attachment),this.offset=w(this.options.offset),this.targetOffset=w(this.options.targetOffset),null!=this.scrollParent&&this.disable(),"scroll-handle"===this.targetModifier?this.scrollParent=this.target:this.scrollParent=c(this.target),this.options.enabled!==!1?this.enable(e):void 0},t.prototype.getTargetBounds=function(){var t,e,o,i,n,s,l,r,h;if(null==this.targetModifier)return p(this.target);switch(this.targetModifier){case"visible":return this.target===document.body?{top:pageYOffset,left:pageXOffset,height:innerHeight,width:innerWidth}:(t=p(this.target),n={height:t.height,width:t.width,top:t.top,left:t.left},n.height=Math.min(n.height,t.height-(pageYOffset-t.top)),n.height=Math.min(n.height,t.height-(t.top+t.height-(pageYOffset+innerHeight))),n.height=Math.min(innerHeight,n.height),n.height-=2,n.width=Math.min(n.width,t.width-(pageXOffset-t.left)),n.width=Math.min(n.width,t.width-(t.left+t.width-(pageXOffset+innerWidth))),n.width=Math.min(innerWidth,n.width),n.width-=2,n.top<pageYOffset&&(n.top=pageYOffset),n.left<pageXOffset&&(n.left=pageXOffset),n);case"scroll-handle":return h=this.target,h===document.body?(h=document.documentElement,t={left:pageXOffset,top:pageYOffset,height:innerHeight,width:innerWidth}):t=p(h),r=getComputedStyle(h),o=h.scrollWidth>h.clientWidth||"scroll"===[r.overflow,r.overflowX]||this.target!==document.body,s=0,o&&(s=15),i=t.height-parseFloat(r.borderTopWidth)-parseFloat(r.borderBottomWidth)-s,n={width:15,height:.975*i*(i/h.scrollHeight),left:t.left+t.width-parseFloat(r.borderLeftWidth)-15},e=0,408>i&&this.target===document.body&&(e=-11e-5*Math.pow(i,2)-.00727*i+22.58),this.target!==document.body&&(n.height=Math.max(n.height,24)),l=this.target.scrollTop/(h.scrollHeight-i),n.top=l*(i-n.height-e)+t.top+parseFloat(r.borderTopWidth),this.target===document.body&&(n.height=Math.max(n.height,24)),n}},t.prototype.clearCache=function(){return this._cache={}},t.prototype.cache=function(t,e){return null==this._cache&&(this._cache={}),null==this._cache[t]&&(this._cache[t]=e.call(this)),this._cache[t]},t.prototype.enable=function(t){return null==t&&(t=!0),this.options.addTargetClasses!==!1&&n(this.target,this.getClass("enabled")),n(this.element,this.getClass("enabled")),this.enabled=!0,this.scrollParent!==document&&this.scrollParent.addEventListener("scroll",this.position),t?this.position():void 0},t.prototype.disable=function(){return O(this.target,this.getClass("enabled")),O(this.element,this.getClass("enabled")),this.enabled=!1,null!=this.scrollParent?this.scrollParent.removeEventListener("scroll",this.position):void 0},t.prototype.destroy=function(){var t,e,o,i,n;for(this.disable(),n=[],t=o=0,i=T.length;i>o;t=++o){if(e=T[t],e===this){T.splice(t,1);break}n.push(void 0)}return n},t.prototype.updateAttachClasses=function(t,e){var o,i,n,s,l,r,a,f,p,u=this;for(null==t&&(t=this.attachment),null==e&&(e=this.targetAttachment),s=["left","top","bottom","right","middle","center"],(null!=(p=this._addAttachClasses)?p.length:void 0)&&this._addAttachClasses.splice(0,this._addAttachClasses.length),o=null!=this._addAttachClasses?this._addAttachClasses:this._addAttachClasses=[],t.top&&o.push(""+this.getClass("element-attached")+"-"+t.top),t.left&&o.push(""+this.getClass("element-attached")+"-"+t.left),e.top&&o.push(""+this.getClass("target-attached")+"-"+e.top),e.left&&o.push(""+this.getClass("target-attached")+"-"+e.left),i=[],l=0,a=s.length;a>l;l++)n=s[l],i.push(""+this.getClass("element-attached")+"-"+n);for(r=0,f=s.length;f>r;r++)n=s[r],i.push(""+this.getClass("target-attached")+"-"+n);return h(function(){return null!=u._addAttachClasses?(A(u.element,u._addAttachClasses,i),u.options.addTargetClasses!==!1&&A(u.target,u._addAttachClasses,i),u._addAttachClasses=void 0):void 0})},t.prototype.position=function(t){var e,o,n,h,a,d,c,m,b,y,w,C,O,T,x,A,E,S,W,M,P,z,B,_,F,L,Y,H,X,N,j,R,U,q,k,D=this;if(null==t&&(t=!0),this.enabled){for(this.clearCache(),M=r(this.targetAttachment,this.attachment),this.updateAttachClasses(this.attachment,M),e=this.cache("element-bounds",function(){return p(D.element)}),F=e.width,n=e.height,0===F&&0===n&&null!=this.lastSize?(N=this.lastSize,F=N.width,n=N.height):this.lastSize={width:F,height:n},B=z=this.cache("target-bounds",function(){return D.getTargetBounds()}),b=v(l(this.attachment),{width:F,height:n}),P=v(l(M),B),a=v(this.offset,{width:F,height:n}),d=v(this.targetOffset,B),b=s(b,a),P=s(P,d),h=z.left+P.left-b.left,_=z.top+P.top-b.top,j=i.modules,L=0,H=j.length;H>L;L++){if(c=j[L],x=c.position.call(this,{left:h,top:_,targetAttachment:M,targetPos:z,attachment:this.attachment,elementPos:e,offset:b,targetOffset:P,manualOffset:a,manualTargetOffset:d,scrollbarSize:S}),x===!1)return!1;null!=x&&"object"==typeof x&&(_=x.top,h=x.left)}if(m={page:{top:_,left:h},viewport:{top:_-pageYOffset,bottom:pageYOffset-_-n+innerHeight,left:h-pageXOffset,right:pageXOffset-h-F+innerWidth}},document.body.scrollWidth>window.innerWidth&&(S=this.cache("scrollbar-size",g),m.viewport.bottom-=S.height),document.body.scrollHeight>window.innerHeight&&(S=this.cache("scrollbar-size",g),m.viewport.right-=S.width),(""!==(R=document.body.style.position)&&"static"!==R||""!==(U=document.body.parentElement.style.position)&&"static"!==U)&&(m.page.bottom=document.body.scrollHeight-_-n,m.page.right=document.body.scrollWidth-h-F),(null!=(q=this.options.optimizations)?q.moveElement:void 0)!==!1&&null==this.targetModifier){for(w=this.cache("target-offsetparent",function(){return u(D.target)}),T=this.cache("target-offsetparent-bounds",function(){return p(w)}),O=getComputedStyle(w),o=getComputedStyle(this.element),C=T,y={},k=["Top","Left","Bottom","Right"],Y=0,X=k.length;X>Y;Y++)W=k[Y],y[W.toLowerCase()]=parseFloat(O["border"+W+"Width"]);T.right=document.body.scrollWidth-T.left-C.width+y.right,T.bottom=document.body.scrollHeight-T.top-C.height+y.bottom,m.page.top>=T.top+y.top&&m.page.bottom>=T.bottom&&m.page.left>=T.left+y.left&&m.page.right>=T.right&&(E=w.scrollTop,A=w.scrollLeft,m.offset={top:m.page.top-T.top+E-y.top,left:m.page.left-T.left+A-y.left})}return this.move(m),this.history.unshift(m),this.history.length>3&&this.history.pop(),t&&f(),!0}},t.prototype.move=function(t){var e,o,i,n,s,l,r,f,p,d,g,c,m,b,v,y,w,C=this;if(null!=this.element.parentNode){f={};for(d in t){f[d]={};for(n in t[d]){for(i=!1,y=this.history,b=0,v=y.length;v>b;b++)if(r=y[b],!E(null!=(w=r[d])?w[n]:void 0,t[d][n])){i=!0;break}i||(f[d][n]=!0)}}e={top:"",left:"",right:"",bottom:""},p=function(t,o){var i,n,s;return(null!=(s=C.options.optimizations)?s.gpu:void 0)===!1?(t.top?e.top=""+o.top+"px":e.bottom=""+o.bottom+"px",t.left?e.left=""+o.left+"px":e.right=""+o.right+"px"):(t.top?(e.top=0,n=o.top):(e.bottom=0,n=-o.bottom),t.left?(e.left=0,i=o.left):(e.right=0,i=-o.right),e[x]="translateX("+Math.round(i)+"px) translateY("+Math.round(n)+"px)","msTransform"!==x?e[x]+=" translateZ(0)":void 0)},s=!1,(f.page.top||f.page.bottom)&&(f.page.left||f.page.right)?(e.position="absolute",p(f.page,t.page)):(f.viewport.top||f.viewport.bottom)&&(f.viewport.left||f.viewport.right)?(e.position="fixed",p(f.viewport,t.viewport)):null!=f.offset&&f.offset.top&&f.offset.left?(e.position="absolute",l=this.cache("target-offsetparent",function(){return u(C.target)}),u(this.element)!==l&&h(function(){return C.element.parentNode.removeChild(C.element),l.appendChild(C.element)}),p(f.offset,t.offset),s=!0):(e.position="absolute",p({top:!0,left:!0},t.page)),s||"BODY"===this.element.parentNode.tagName||(this.element.parentNode.removeChild(this.element),document.body.appendChild(this.element)),m={},c=!1;for(n in e)g=e[n],o=this.element.style[n],""===o||""===g||"top"!==n&&"left"!==n&&"bottom"!==n&&"right"!==n||(o=parseFloat(o),g=parseFloat(g)),o!==g&&(c=!0,m[n]=e[n]);return c?h(function(){return a(C.element.style,m)}):void 0}},t}(),i.position=C,this.Tether=a(S,i)}.call(this),function(){var t,e,o,i,n,s,l,r,h,a,f=[].indexOf||function(t){for(var e=0,o=this.length;o>e;e++)if(e in this&&this[e]===t)return e;return-1};a=this.Tether.Utils,l=a.getOuterSize,s=a.getBounds,r=a.getSize,i=a.extend,h=a.updateClasses,o=a.defer,e={left:"right",right:"left",top:"bottom",bottom:"top",middle:"middle"},t=["left","top","right","bottom"],n=function(e,o){var i,n,l,r,h,a,f;if("scrollParent"===o?o=e.scrollParent:"window"===o&&(o=[pageXOffset,pageYOffset,innerWidth+pageXOffset,innerHeight+pageYOffset]),o===document&&(o=o.documentElement),null!=o.nodeType)for(n=r=s(o),h=getComputedStyle(o),o=[n.left,n.top,r.width+n.left,r.height+n.top],i=a=0,f=t.length;f>a;i=++a)l=t[i],l=l[0].toUpperCase()+l.substr(1),"Top"===l||"Left"===l?o[i]+=parseFloat(h["border"+l+"Width"]):o[i]-=parseFloat(h["border"+l+"Width"]);return o},this.Tether.modules.push({position:function(e){var l,r,a,p,u,d,g,c,m,b,v,y,w,C,O,T,x,A,E,S,W,M,P,z,B,_,F,L,Y,H,X,N,j,R,U,q,k,D,Z,V,$,G,I,J,K,Q,tt,et=this;if(_=e.top,v=e.left,W=e.targetAttachment,!this.options.constraints)return!0;for(A=function(e){var o,i,n,s;for(et.removeClass(e),s=[],i=0,n=t.length;n>i;i++)o=t[i],s.push(et.removeClass(""+e+"-"+o));return s},V=this.cache("element-bounds",function(){return s(et.element)}),b=V.height,F=V.width,0===F&&0===b&&null!=this.lastSize&&($=this.lastSize,F=$.width,b=$.height),P=this.cache("target-bounds",function(){return et.getTargetBounds()}),M=P.height,z=P.width,S={},m={},r=[this.getClass("pinned"),this.getClass("out-of-bounds")],G=this.options.constraints,L=0,N=G.length;N>L;L++)c=G[L],c.outOfBoundsClass&&r.push(c.outOfBoundsClass),c.pinnedClass&&r.push(c.pinnedClass);for(Y=0,j=r.length;j>Y;Y++)for(g=r[Y],I=["left","top","right","bottom"],H=0,R=I.length;R>H;H++)E=I[H],r.push(""+g+"-"+E);for(l=[],S=i({},W),m=i({},this.attachment),J=this.options.constraints,X=0,U=J.length;U>X;X++){if(c=J[X],B=c.to,a=c.attachment,O=c.pin,null==a&&(a=""),f.call(a," ")>=0?(K=a.split(" "),d=K[0],u=K[1]):u=d=a,p=n(this,B),("target"===d||"both"===d)&&(_<p[1]&&"top"===S.top&&(_+=M,S.top="bottom"),_+b>p[3]&&"bottom"===S.top&&(_-=M,S.top="top")),"together"===d&&(_<p[1]&&"top"===S.top&&("bottom"===m.top?(_+=M,S.top="bottom",_+=b,m.top="top"):"top"===m.top&&(_+=M,S.top="bottom",_-=b,m.top="bottom")),_+b>p[3]&&"bottom"===S.top&&("top"===m.top?(_-=M,S.top="top",_-=b,m.top="bottom"):"bottom"===m.top&&(_-=M,S.top="top",_+=b,m.top="top")),"middle"===S.top&&(_+b>p[3]&&"top"===m.top?(_-=b,m.top="bottom"):_<p[1]&&"bottom"===m.top&&(_+=b,m.top="top"))),("target"===u||"both"===u)&&(v<p[0]&&"left"===S.left&&(v+=z,S.left="right"),v+F>p[2]&&"right"===S.left&&(v-=z,S.left="left")),"together"===u&&(v<p[0]&&"left"===S.left?"right"===m.left?(v+=z,S.left="right",v+=F,m.left="left"):"left"===m.left&&(v+=z,S.left="right",v-=F,m.left="right"):v+F>p[2]&&"right"===S.left?"left"===m.left?(v-=z,S.left="left",v-=F,m.left="right"):"right"===m.left&&(v-=z,S.left="left",v+=F,m.left="left"):"center"===S.left&&(v+F>p[2]&&"left"===m.left?(v-=F,m.left="right"):v<p[0]&&"right"===m.left&&(v+=F,m.left="left"))),("element"===d||"both"===d)&&(_<p[1]&&"bottom"===m.top&&(_+=b,m.top="top"),_+b>p[3]&&"top"===m.top&&(_-=b,m.top="bottom")),("element"===u||"both"===u)&&(v<p[0]&&"right"===m.left&&(v+=F,m.left="left"),v+F>p[2]&&"left"===m.left&&(v-=F,m.left="right")),"string"==typeof O?O=function(){var t,e,o,i;for(o=O.split(","),i=[],e=0,t=o.length;t>e;e++)C=o[e],i.push(C.trim());return i}():O===!0&&(O=["top","left","right","bottom"]),O||(O=[]),T=[],y=[],_<p[1]&&(f.call(O,"top")>=0?(_=p[1],T.push("top")):y.push("top")),_+b>p[3]&&(f.call(O,"bottom")>=0?(_=p[3]-b,T.push("bottom")):y.push("bottom")),v<p[0]&&(f.call(O,"left")>=0?(v=p[0],T.push("left")):y.push("left")),v+F>p[2]&&(f.call(O,"right")>=0?(v=p[2]-F,T.push("right")):y.push("right")),T.length)for(x=null!=(Q=this.options.pinnedClass)?Q:this.getClass("pinned"),l.push(x),D=0,q=T.length;q>D;D++)E=T[D],l.push(""+x+"-"+E);if(y.length)for(w=null!=(tt=this.options.outOfBoundsClass)?tt:this.getClass("out-of-bounds"),l.push(w),Z=0,k=y.length;k>Z;Z++)E=y[Z],l.push(""+w+"-"+E);(f.call(T,"left")>=0||f.call(T,"right")>=0)&&(m.left=S.left=!1),(f.call(T,"top")>=0||f.call(T,"bottom")>=0)&&(m.top=S.top=!1),(S.top!==W.top||S.left!==W.left||m.top!==this.attachment.top||m.left!==this.attachment.left)&&this.updateAttachClasses(m,S)}return o(function(){return et.options.addTargetClasses!==!1&&h(et.target,l,r),h(et.element,l,r)}),{top:_,left:v}}})}.call(this),function(){var t,e,o,i;i=this.Tether.Utils,e=i.getBounds,o=i.updateClasses,t=i.defer,this.Tether.modules.push({position:function(i){var n,s,l,r,h,a,f,p,u,d,g,c,m,b,v,y,w,C,O,T,x,A,E,S,W,M=this;if(g=i.top,a=i.left,x=this.cache("element-bounds",function(){return e(M.element)}),h=x.height,c=x.width,d=this.getTargetBounds(),r=g+h,f=a+c,n=[],g<=d.bottom&&r>=d.top)for(A=["left","right"],m=0,w=A.length;w>m;m++)p=A[m],((E=d[p])===a||E===f)&&n.push(p);if(a<=d.right&&f>=d.left)for(S=["top","bottom"],b=0,C=S.length;C>b;b++)p=S[b],((W=d[p])===g||W===r)&&n.push(p);for(l=[],s=[],u=["left","top","right","bottom"],l.push(this.getClass("abutted")),v=0,O=u.length;O>v;v++)p=u[v],l.push(""+this.getClass("abutted")+"-"+p);for(n.length&&s.push(this.getClass("abutted")),y=0,T=n.length;T>y;y++)p=n[y],s.push(""+this.getClass("abutted")+"-"+p);return t(function(){return M.options.addTargetClasses!==!1&&o(M.target,s,l),o(M.element,s,l)}),!0}})}.call(this),function(){this.Tether.modules.push({position:function(t){var e,o,i,n,s,l,r;return l=t.top,e=t.left,this.options.shift?(o=function(t){return"function"==typeof t?t.call(this,{top:l,left:e}):t},i=o(this.options.shift),"string"==typeof i?(i=i.split(" "),i[1]||(i[1]=i[0]),s=i[0],n=i[1],s=parseFloat(s,10),n=parseFloat(n,10)):(r=[i.top,i.left],s=r[0],n=r[1]),l+=s,e+=n,{top:l,left:e}):void 0}})}.call(this),this.Tether});
\ No newline at end of file
diff --git a/js/tests/visual/affix-with-sticky-footer.html b/js/tests/visual/affix-with-sticky-footer.html
deleted file mode 100644
index 5c413067ad78c3dc4a50ac84a3aeaa13afede285..0000000000000000000000000000000000000000
--- a/js/tests/visual/affix-with-sticky-footer.html
+++ /dev/null
@@ -1,317 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <title>Affix</title>
-  <link rel="stylesheet" href="../../../dist/css/bootstrap.min.css">
-
-  <style>
-    html {
-      position: relative;
-      min-height: 100%;
-    }
-    body {
-      /* Margin bottom by footer height */
-      margin-bottom: 200px;
-    }
-    .footer {
-      position: absolute;
-      bottom: 0;
-      width: 100%;
-      /* Set the fixed height of the footer here */
-      height: 200px;
-      background-color: #f5f5f5;
-    }
-    /* Test Styles */
-    .affixed-element-top.affix {
-      top: 10px;
-    }
-    .affixed-element-top.affix-bottom {
-      position: absolute;
-    }
-    .affixed-element-bottom {
-      margin-bottom: 0;
-    }
-    .affixed-element-bottom.affix {
-      bottom: 10px;
-    }
-    .affixed-element-bottom.affix-bottom {
-      position: relative;
-    }
-    .grow-btn, .shrink-btn {
-      color: #FFF;
-    }
-    .grow-btn {
-      background-color: #2ECC40;
-    }
-    .grow-btn:hover {
-      background-color: #3D9970;
-    }
-    .shrink-btn {
-      background-color: #FF4136;
-    }
-    .shrink-btn:hover {
-      background-color: #85144B;
-    }
-  </style>
-
-  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
-  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
-  <!--[if lt IE 9]>
-  <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
-  <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
-  <![endif]-->
-</head>
-<body>
-
-<div class="container">
-
-  <div class="page-header js-page-header">
-    <h1>Affix <small>Bootstrap Visual Test</small></h1>
-  </div>
-
-  <div class="col-md-3">
-    <ul class="list-group affixed-element-top js-affixed-element-top">
-      <li class="list-group-item">Cras justo odio</li>
-      <li class="list-group-item">Dapibus ac facilisis in</li>
-      <li class="list-group-item">Morbi leo risus</li>
-      <li class="list-group-item">Porta ac consectetur ac</li>
-      <li class="list-group-item">Vestibulum at eros</li>
-      <li class="list-group-item">Cras justo odio</li>
-      <li class="list-group-item">Dapibus ac facilisis in</li>
-      <li class="list-group-item">Morbi leo risus</li>
-      <li class="list-group-item">Porta ac consectetur ac</li>
-      <li class="list-group-item">Vestibulum at eros</li>
-      <li class="list-group-item">Cras justo odio</li>
-      <li class="list-group-item">Dapibus ac facilisis in</li>
-      <li class="list-group-item">Morbi leo risus</li>
-      <li class="list-group-item">Porta ac consectetur ac</li>
-      <li class="list-group-item">Vestibulum at eros</li>
-      <li class="list-group-item">Porta ac consectetur ac</li>
-    </ul>
-  </div>
-
-  <div class="col-md-6 js-content">
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-  </div>
-
-  <div class="col-md-3">
-    <ul class="list-group affixed-element-bottom js-affixed-element-bottom">
-      <li class="list-group-item">Sit necessitatibus aspernatur.</li>
-      <li class="list-group-item">Adipisicing alias dolor!</li>
-      <li class="list-group-item">Ipsum molestiae impedit.</li>
-      <li class="list-group-item">Amet quis iste?</li>
-      <li class="list-group-item">Ipsum quaerat porro.</li>
-      <li class="list-group-item">Elit lorem libero.</li>
-      <li class="list-group-item">Ipsum dolore facilis.</li>
-      <li class="list-group-item">Elit ad atque.</li>
-      <li class="list-group-item">Dolor amet sequi!</li>
-      <li class="list-group-item">Consectetur voluptatum facilis!</li>
-      <li class="list-group-item">Sit neque eligendi?</li>
-      <li class="list-group-item">Amet fuga consectetur!</li>
-      <li class="list-group-item">Amet molestias repellat!</li>
-      <li class="list-group-item">Consectetur minima repellendus.</li>
-      <li class="list-group-item grow-btn js-grow-btn">Grow content</li>
-      <li class="list-group-item shrink-btn js-shrink-btn">Shrink content</li>
-    </ul>
-  </div>
-
-
-</div>
-
-<footer class="footer js-footer">
-  <div class="container">
-    <p class="text-muted">Place sticky footer content here.</p>
-  </div>
-</footer>
-
-<!-- JavaScript Includes -->
-<script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../affix.js"></script>
-
-
-<!-- JavaScript Test -->
-<script>
-$(function () {
-  $('.js-affixed-element-top').affix({
-    offset: {
-      top: $('.js-page-header').outerHeight(true) - 10
-    , bottom: $('.js-footer').outerHeight(true) + 10
-    }
-  })
-  // todo(fat): sux you have to do this.
-  .on('affix.bs.affix', function (e) {
-    $(e.target).width(e.target.offsetWidth)
-  })
-
-  $('.js-affixed-element-bottom').affix({
-    offset: {
-      bottom: $('.js-footer').outerHeight(true) + 10
-    }
-  })
-
-  $('.js-grow-btn').on('click', function() {
-    $('.js-content').append('<p>Ipsum corrupti ipsam est temporibus.</p>')
-  })
-  $('.js-shrink-btn').on('click', function() {
-    $('.js-content p').last().remove()
-  })
-})
-</script>
-</body>
-</html>
diff --git a/js/tests/visual/affix.html b/js/tests/visual/affix.html
deleted file mode 100644
index 4d772dc738ce670b98263346c63b9434c1f4ec47..0000000000000000000000000000000000000000
--- a/js/tests/visual/affix.html
+++ /dev/null
@@ -1,306 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <title>Affix</title>
-  <link rel="stylesheet" href="../../../dist/css/bootstrap.min.css">
-
-  <style>
-    /* Test Styles */
-    .affixed-element-top.affix {
-      top: 10px;
-    }
-    .affixed-element-top.affix-bottom {
-      position: absolute;
-    }
-    .affixed-element-bottom {
-      margin-bottom: 0;
-    }
-    .affixed-element-bottom.affix {
-      bottom: 10px;
-    }
-    .affixed-element-bottom.affix-bottom {
-      position: relative;
-    }
-    .grow-btn, .shrink-btn {
-      color: #FFF;
-    }
-    .grow-btn {
-      background-color: #2ECC40;
-    }
-    .grow-btn:hover {
-      background-color: #3D9970;
-    }
-    .shrink-btn {
-      background-color: #FF4136;
-    }
-    .shrink-btn:hover {
-      background-color: #85144B;
-    }
-  </style>
-
-  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
-  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
-  <!--[if lt IE 9]>
-    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
-    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
-  <![endif]-->
-</head>
-<body>
-
-<div class="container">
-
-  <div class="page-header js-page-header">
-    <h1>Affix <small>Bootstrap Visual Test</small></h1>
-  </div>
-
-  <div class="col-md-3">
-    <ul class="list-group affixed-element-top js-affixed-element-top">
-      <li class="list-group-item">Cras justo odio</li>
-      <li class="list-group-item">Dapibus ac facilisis in</li>
-      <li class="list-group-item">Morbi leo risus</li>
-      <li class="list-group-item">Porta ac consectetur ac</li>
-      <li class="list-group-item">Vestibulum at eros</li>
-      <li class="list-group-item">Cras justo odio</li>
-      <li class="list-group-item">Dapibus ac facilisis in</li>
-      <li class="list-group-item">Morbi leo risus</li>
-      <li class="list-group-item">Porta ac consectetur ac</li>
-      <li class="list-group-item">Vestibulum at eros</li>
-      <li class="list-group-item">Cras justo odio</li>
-      <li class="list-group-item">Dapibus ac facilisis in</li>
-      <li class="list-group-item">Morbi leo risus</li>
-      <li class="list-group-item">Porta ac consectetur ac</li>
-      <li class="list-group-item">Vestibulum at eros</li>
-      <li class="list-group-item">Porta ac consectetur ac</li>
-    </ul>
-  </div>
-
-  <div class="col-md-6 js-content">
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-
-  </div>
-
-  <div class="col-md-3">
-    <ul class="list-group affixed-element-bottom js-affixed-element-bottom">
-      <li class="list-group-item">Sit necessitatibus aspernatur.</li>
-      <li class="list-group-item">Adipisicing alias dolor!</li>
-      <li class="list-group-item">Ipsum molestiae impedit.</li>
-      <li class="list-group-item">Amet quis iste?</li>
-      <li class="list-group-item">Ipsum quaerat porro.</li>
-      <li class="list-group-item">Elit lorem libero.</li>
-      <li class="list-group-item">Ipsum dolore facilis.</li>
-      <li class="list-group-item">Elit ad atque.</li>
-      <li class="list-group-item">Dolor amet sequi!</li>
-      <li class="list-group-item">Consectetur voluptatum facilis!</li>
-      <li class="list-group-item">Sit neque eligendi?</li>
-      <li class="list-group-item">Amet fuga consectetur!</li>
-      <li class="list-group-item">Amet molestias repellat!</li>
-      <li class="list-group-item">Consectetur minima repellendus.</li>
-      <li class="list-group-item grow-btn js-grow-btn">Grow content</li>
-      <li class="list-group-item shrink-btn js-shrink-btn">Shrink content</li>
-    </ul>
-  </div>
-
-  <div class="col-md-12 js-footer">
-    <hr>
-
-    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
-
-    <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
-
-    <p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
-
-    <p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-  </div>
-
-</div>
-
-<!-- JavaScript Includes -->
-<script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../affix.js"></script>
-
-
-<!-- JavaScript Test -->
-<script>
-$(function () {
-  $('.js-affixed-element-top').affix({
-    offset: {
-      top: $('.js-page-header').outerHeight(true) - 10
-    , bottom: $('.js-footer').outerHeight(true) + 10
-    }
-  })
-  // todo(fat): sux you have to do this.
-  .on('affix.bs.affix', function (e) {
-    $(e.target).width(e.target.offsetWidth)
-  })
-
-  $('.js-affixed-element-bottom').affix({
-    offset: {
-      bottom: $('.js-footer').outerHeight(true) + 10
-    }
-  })
-
-  $('.js-grow-btn').on('click', function() {
-    $('.js-content').append('<p>Ipsum corrupti ipsam est temporibus.</p>')
-  })
-  $('.js-shrink-btn').on('click', function() {
-    $('.js-content p').last().remove()
-  })
-})
-</script>
-</body>
-</html>
diff --git a/js/tests/visual/alert.html b/js/tests/visual/alert.html
index 0070315a2485ba900b13371f63779704cc9877bc..9e6a939e96f4107db048e75cdb31e88b4dc33480 100644
--- a/js/tests/visual/alert.html
+++ b/js/tests/visual/alert.html
@@ -41,8 +41,8 @@
 
 <!-- JavaScript Includes -->
 <script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../alert.js"></script>
+<script src="../../dist/util.js"></script>
+<script src="../../dist/alert.js"></script>
 
 </body>
 </html>
diff --git a/js/tests/visual/button.html b/js/tests/visual/button.html
index d92a083296352850dd12f2cec0919de60055dd57..a6eed7e05a4fea6be9af75551775c985eed49c42 100644
--- a/js/tests/visual/button.html
+++ b/js/tests/visual/button.html
@@ -22,10 +22,6 @@
     <h1>Button <small>Bootstrap Visual Test</small></h1>
   </div>
 
-  <button type="button" data-loading-text="Loading for 3 seconds..." class="btn btn-primary js-loading-button">
-    Loading state
-  </button>
-
   <button type="button" class="btn btn-primary" data-toggle="button">Single toggle</button>
 
   <div class="btn-group" data-toggle="buttons">
@@ -56,8 +52,8 @@
 
 <!-- JavaScript Includes -->
 <script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../button.js"></script>
+<script src="../../dist/util.js"></script>
+<script src="../../dist/button.js"></script>
 
 <!-- JavaScript Test -->
 <script>
diff --git a/js/tests/visual/carousel.html b/js/tests/visual/carousel.html
index 8dede0921b8c9e027f9b1862977dac7e55b4a531..47dacaa6a0e30edf0826d5521ebde19ccf42121e 100644
--- a/js/tests/visual/carousel.html
+++ b/js/tests/visual/carousel.html
@@ -29,13 +29,13 @@
       <li data-target="#carousel-example-generic" data-slide-to="2" class=""></li>
     </ol>
     <div class="carousel-inner">
-      <div class="item active">
+      <div class="carousel-item active">
         <img alt="First slide" src="http://37.media.tumblr.com/tumblr_m8tay0JcfG1qa42jro1_1280.jpg">
       </div>
-      <div class="item">
+      <div class="carousel-item">
         <img alt="Second slide" src="http://37.media.tumblr.com/tumblr_m8tazfiVYJ1qa42jro1_1280.jpg">
       </div>
-      <div class="item">
+      <div class="carousel-item">
         <img alt="Third slide" src="http://38.media.tumblr.com/tumblr_m8tb2rVsD31qa42jro1_1280.jpg">
       </div>
     </div>
@@ -51,8 +51,8 @@
 
 <!-- JavaScript Includes -->
 <script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../carousel.js"></script>
+<script src="../../dist/util.js"></script>
+<script src="../../dist/carousel.js"></script>
 
 </body>
 </html>
diff --git a/js/tests/visual/collapse.html b/js/tests/visual/collapse.html
index 3b8a42e3d7b36019f5ec7021593e560b3b2bbb44..2ccc787ecd980bae3f5f58ceb9211edfa1d1c63c 100644
--- a/js/tests/visual/collapse.html
+++ b/js/tests/visual/collapse.html
@@ -71,8 +71,8 @@
 
 <!-- JavaScript Includes -->
 <script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../collapse.js"></script>
+<script src="../../dist/util.js"></script>
+<script src="../../dist/collapse.js"></script>
 
 </body>
 </html>
diff --git a/js/tests/visual/dropdown.html b/js/tests/visual/dropdown.html
index 02090b6cc9c58026a95254f7f41b05fdf184d42a..a51267de8444112bbadec2c3621391cb72e7afe4 100644
--- a/js/tests/visual/dropdown.html
+++ b/js/tests/visual/dropdown.html
@@ -22,21 +22,15 @@
     <h1>Dropdown <small>Bootstrap Visual Test</small></h1>
   </div>
 
-  <nav id="navbar-example" class="navbar navbar-default navbar-static" role="navigation">
+  <nav id="navbar-example" class="navbar navbar-default navbar-static-top" role="navigation">
     <div class="container-fluid">
-      <div class="navbar-header">
-        <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".bs-example-js-navbar-collapse">
-          <span class="sr-only">Toggle navigation</span>
-          <span class="icon-bar"></span>
-          <span class="icon-bar"></span>
-          <span class="icon-bar"></span>
-        </button>
-        <a class="navbar-brand" href="#">Project Name</a>
-      </div>
-      <div class="collapse navbar-collapse bs-example-js-navbar-collapse">
-        <ul class="nav navbar-nav">
-          <li class="dropdown">
-            <a id="drop1" href="#" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
+      <button class="navbar-toggler hidden-sm-up" type="button" data-toggle="collapse" data-target="#exCollapsingNavbar2">
+        &#9776;
+      </button>
+      <div class="collapse navbar-toggleable-xs" id="exCollapsingNavbar2">
+        <ul class="nav navbar-nav pull-left">
+          <li class="dropdown nav-item">
+            <a id="drop1" href="#" role="button" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
             <ul class="dropdown-menu" role="menu" aria-labelledby="drop1">
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Action</a></li>
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Another action</a></li>
@@ -45,8 +39,8 @@
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Separated link</a></li>
             </ul>
           </li>
-          <li class="dropdown">
-            <a href="#" id="drop2" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 2 <b class="caret"></b></a>
+          <li class="dropdown nav-item">
+            <a href="#" id="drop2" role="button" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown 2 <b class="caret"></b></a>
             <ul class="dropdown-menu" role="menu" aria-labelledby="drop2">
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Action</a></li>
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Another action</a></li>
@@ -56,9 +50,9 @@
             </ul>
           </li>
         </ul>
-        <ul class="nav navbar-nav navbar-right">
-          <li id="fat-menu" class="dropdown">
-            <a href="#" id="drop3" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 3 <b class="caret"></b></a>
+        <ul class="nav navbar-nav pull-right">
+          <li id="fat-menu" class="dropdown nav-item">
+            <a href="#" id="drop3" role="button" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown 3 <b class="caret"></b></a>
             <ul class="dropdown-menu" role="menu" aria-labelledby="drop3">
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Action</a></li>
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Another action</a></li>
@@ -73,9 +67,9 @@
   </nav>
 
   <ul class="nav nav-pills">
-    <li class="active"><a href="#">Regular link</a></li>
-    <li class="dropdown">
-      <a id="drop4" role="button" data-toggle="dropdown" href="#">Dropdown <b class="caret"></b></a>
+    <li class="active nav-item"><a href="#" class="nav-link">Regular link</a></li>
+    <li class="dropdown nav-item">
+      <a id="drop4" class="nav-link" role="button" data-toggle="dropdown" href="#">Dropdown <b class="caret"></b></a>
       <ul id="menu1" class="dropdown-menu" role="menu" aria-labelledby="drop4">
         <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Action</a></li>
         <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Another action</a></li>
@@ -84,8 +78,8 @@
         <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Separated link</a></li>
       </ul>
     </li>
-    <li class="dropdown">
-      <a id="drop5" role="button" data-toggle="dropdown" href="#">Dropdown 2 <b class="caret"></b></a>
+    <li class="dropdown nav-item">
+      <a id="drop5" class="nav-link" role="button" data-toggle="dropdown" href="#">Dropdown 2 <b class="caret"></b></a>
       <ul id="menu2" class="dropdown-menu" role="menu" aria-labelledby="drop5">
         <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Action</a></li>
         <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Another action</a></li>
@@ -100,9 +94,9 @@
 
 <!-- JavaScript Includes -->
 <script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../dropdown.js"></script>
-<script src="../../collapse.js"></script>
+<script src="../../dist/util.js"></script>
+<script src="../../dist/dropdown.js"></script>
+<script src="../../dist/collapse.js"></script>
 
 </body>
 </html>
diff --git a/js/tests/visual/modal.html b/js/tests/visual/modal.html
index 4342f0ce44d8fbc9fa7f7880d35eae89f1ebd251..ab61a3b16c39b609048efc2d28523cadcc4f1176 100644
--- a/js/tests/visual/modal.html
+++ b/js/tests/visual/modal.html
@@ -141,20 +141,23 @@
 
 <!-- JavaScript Includes -->
 <script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../modal.js"></script>
+
+<script src="../../dist/util.js"></script>
+<script src="../../dist/modal.js"></script>
+<script src="../../dist/collapse.js"></script>
+
+<!-- <script src="../../transition.js"></script>
 <script src="../../tooltip.js"></script>
-<script src="../../popover.js"></script>
-<script src="../../collapse.js"></script>
+<script src="../../popover.js"></script> -->
 
 <!-- JavaScript Test -->
 <script>
 $(function () {
-  $('.js-popover').popover()
-  $('.js-tooltip').tooltip()
-  $('#tall-toggle').click(function () {
-    $('#tall').toggle()
-  })
+  // $('.js-popover').popover()
+  // $('.js-tooltip').tooltip()
+  // $('#tall-toggle').click(function () {
+  //   $('#tall').toggle()
+  // })
 })
 </script>
 
diff --git a/js/tests/visual/popover.html b/js/tests/visual/popover.html
index 0e84f5ceeef8385dc340472b635759114bc72555..ac65572563e0906b0aecb1bfa0f46db4ea4e9191 100644
--- a/js/tests/visual/popover.html
+++ b/js/tests/visual/popover.html
@@ -5,7 +5,7 @@
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <title>Popover</title>
-  <link rel="stylesheet" href="../../../dist/css/bootstrap.min.css">
+  <link rel="stylesheet" href="../../../dist/css/bootstrap.css">
 
   <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
   <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
@@ -39,9 +39,11 @@
 
 <!-- JavaScript Includes -->
 <script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../tooltip.js"></script>
-<script src="../../popover.js"></script>
+<script src="../vendor/tether.min.js"></script>
+<script src="../../dist/util.js"></script>
+<script src="../../dist/tooltip.js"></script>
+<script src="../../dist/popover.js"></script>
+
 
 <!-- JavaScript Test -->
 <script>
diff --git a/js/tests/visual/scrollspy.html b/js/tests/visual/scrollspy.html
index 5952b7e593517f52865a6663b058eb1a89768aeb..9958f90c08c7cd496fef2041894f9c151ae36945 100644
--- a/js/tests/visual/scrollspy.html
+++ b/js/tests/visual/scrollspy.html
@@ -24,21 +24,12 @@
 
   <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
     <div class="container-fluid">
-      <div class="navbar-header">
-        <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".js-navbar-scrollspy">
-          <span class="sr-only">Toggle navigation</span>
-          <span class="icon-bar"></span>
-          <span class="icon-bar"></span>
-          <span class="icon-bar"></span>
-        </button>
-        <a class="navbar-brand" href="#">Project Name</a>
-      </div>
-      <div class="collapse navbar-collapse js-navbar-scrollspy">
+      <div class="js-navbar-scrollspy">
         <ul class="nav navbar-nav">
-          <li class=""><a href="#fat">@fat</a></li>
-          <li class=""><a href="#mdo">@mdo</a></li>
-          <li class="dropdown">
-            <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
+          <li class="nav-item active"><a class="nav-link" href="#fat">@fat</a></li>
+          <li class="nav-item"><a class="nav-link" href="#mdo">@mdo</a></li>
+          <li class="dropdown nav-item">
+            <a href="#" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
             <ul class="dropdown-menu" role="menu">
               <li class=""><a href="#one" tabindex="-1">one</a></li>
               <li><a href="#two" tabindex="-1">two</a></li>
@@ -100,10 +91,10 @@
 
 <!-- JavaScript Includes -->
 <script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../scrollspy.js"></script>
-<script src="../../dropdown.js"></script>
-<script src="../../collapse.js"></script>
+<script src="../../dist/util.js"></script>
+<script src="../../dist/scrollspy.js"></script>
+<script src="../../dist/dropdown.js"></script>
+<script src="../../dist/collapse.js"></script>
 
 </body>
 </html>
diff --git a/js/tests/visual/tab.html b/js/tests/visual/tab.html
index a3fed1e9faa3a02238988246f9588cdbbbf01b63..ff6685fedec148e04ffd946ec1d9f34b700fe54f 100644
--- a/js/tests/visual/tab.html
+++ b/js/tests/visual/tab.html
@@ -35,10 +35,10 @@
   <h4>Tabs without fade</h4>
 
   <ul id="myTab" class="nav nav-tabs">
-    <li class="active"><a href="#home" data-toggle="tab">Home</a></li>
-    <li><a href="#profile" data-toggle="tab">Profile</a></li>
-    <li class="dropdown">
-      <a href="#" id="myTabDrop1" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
+    <li class="active nav-item"><a href="#home" class="nav-link" data-toggle="tab">Home</a></li>
+    <li class="nav-item"><a href="#profile" data-toggle="tab" class="nav-link">Profile</a></li>
+    <li class="dropdown nav-item">
+      <a href="#" id="myTabDrop1" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
       <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop1">
         <li><a href="#dropdown1" tabindex="-1" data-toggle="tab">@fat</a></li>
         <li><a href="#dropdown2" tabindex="-1" data-toggle="tab">@mdo</a></li>
@@ -67,10 +67,10 @@
   <h4>Tabs with fade</h4>
 
   <ul id="myTab1" class="nav nav-tabs">
-    <li class="active"><a href="#home1" data-toggle="tab">Home</a></li>
-    <li><a href="#profile1" data-toggle="tab">Profile</a></li>
-    <li class="dropdown">
-      <a href="#" id="myTabDrop2" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
+    <li class="active nav-item"><a class="nav-link" href="#home1" data-toggle="tab">Home</a></li>
+    <li class="nav-item"><a class="nav-link" href="#profile1" data-toggle="tab">Profile</a></li>
+    <li class="dropdown nav-item">
+      <a href="#" id="myTabDrop2" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
       <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop2">
         <li><a href="#dropdown1-1" tabindex="-1" data-toggle="tab">@fat</a></li>
         <li><a href="#dropdown1-2" tabindex="-1" data-toggle="tab">@mdo</a></li>
@@ -99,10 +99,10 @@
   <h4>Tabs without fade (no initially active pane)</h4>
 
   <ul id="myTab2" class="nav nav-tabs">
-    <li><a href="#home2" data-toggle="tab">Home</a></li>
-    <li><a href="#profile2" data-toggle="tab">Profile</a></li>
-    <li class="dropdown">
-      <a href="#" id="myTabDrop3" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
+    <li class="nav-item"><a class="nav-link" href="#home2" data-toggle="tab">Home</a></li>
+    <li class="nav-item"><a class="nav-link" href="#profile2" data-toggle="tab">Profile</a></li>
+    <li class="dropdown nav-item">
+      <a href="#" id="myTabDrop3" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
       <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop3">
         <li><a href="#dropdown2-1" tabindex="-1" data-toggle="tab">@fat</a></li>
         <li><a href="#dropdown2-2" tabindex="-1" data-toggle="tab">@mdo</a></li>
@@ -131,10 +131,10 @@
   <h4>Tabs with fade (no initially active pane)</h4>
 
   <ul id="myTab3" class="nav nav-tabs">
-    <li><a href="#home3" data-toggle="tab">Home</a></li>
-    <li><a href="#profile3" data-toggle="tab">Profile</a></li>
-    <li class="dropdown">
-      <a href="#" id="myTabDrop4" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
+    <li class="nav-item"><a class="nav-link" href="#home3" data-toggle="tab">Home</a></li>
+    <li class="nav-item"><a class="nav-link" href="#profile3" data-toggle="tab">Profile</a></li>
+    <li class="dropdown nav-item">
+      <a href="#" id="myTabDrop4" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
       <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop4">
         <li><a href="#dropdown3-1" tabindex="-1" data-toggle="tab">@fat</a></li>
         <li><a href="#dropdown3-2" tabindex="-1" data-toggle="tab">@mdo</a></li>
@@ -164,9 +164,9 @@
 
 <!-- JavaScript Includes -->
 <script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../tab.js"></script>
-<script src="../../dropdown.js"></script>
+<script src="../../dist/util.js"></script>
+<script src="../../dist/tab.js"></script>
+<script src="../../dist/dropdown.js"></script>
 
 </body>
 </html>
diff --git a/js/tests/visual/tooltip.html b/js/tests/visual/tooltip.html
index 8d10871c9b5c309ef27278bb7a9adeec08f2dd38..1946dff97f11874d0f7f4aea1e0cc6c2c56dfebe 100644
--- a/js/tests/visual/tooltip.html
+++ b/js/tests/visual/tooltip.html
@@ -5,7 +5,7 @@
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <title>Tooltip</title>
-  <link rel="stylesheet" href="../../../dist/css/bootstrap.min.css">
+  <link rel="stylesheet" href="../../../dist/css/bootstrap.css">
 
   <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
   <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
@@ -22,7 +22,7 @@
     <h1>Tooltip <small>Bootstrap Visual Test</small></h1>
   </div>
 
-  <p class="muted" style="margin-bottom: 0;">Tight pants next level keffiyeh <a href="#" data-toggle="tooltip" title="" data-original-title="Default tooltip">you probably</a> haven't heard of them. Photo booth beard raw denim letterpress vegan messenger bag stumptown. Farm-to-table seitan, mcsweeney's fixie sustainable quinoa 8-bit american apparel <a href="#" data-toggle="tooltip" title="" data-original-title="Another tooltip">have a</a> terry richardson vinyl chambray. Beard stumptown, cardigans banh mi lomo thundercats. Tofu biodiesel williamsburg marfa, four loko mcsweeney's cleanse vegan chambray. A really ironic artisan <a href="#" data-toggle="tooltip" title="" data-original-title="Another one here too">whatever keytar</a>, scenester farm-to-table banksy Austin <a href="#" data-toggle="tooltip" title="" data-original-title="The last tip!">twitter handle</a> freegan cred raw denim single-origin coffee viral.
+  <p class="muted" style="margin-bottom: 0;">Tight pants next level keffiyeh <a href="#" data-toggle="tooltip" title="Default tooltip">you probably</a> haven't heard of them. Photo booth beard raw denim letterpress vegan messenger bag stumptown. Farm-to-table seitan, mcsweeney's fixie sustainable quinoa 8-bit american apparel <a href="#" data-toggle="tooltip" title="Another tooltip">have a</a> terry richardson vinyl chambray. Beard stumptown, cardigans banh mi lomo thundercats. Tofu biodiesel williamsburg marfa, four loko mcsweeney's cleanse vegan chambray. A really ironic artisan <a href="#" data-toggle="tooltip" title="Another one here too">whatever keytar</a>, scenester farm-to-table banksy Austin <a href="#" data-toggle="tooltip" title="The last tip!">twitter handle</a> freegan cred raw denim single-origin coffee viral.
   </p>
   <hr>
   <p>
@@ -36,8 +36,9 @@
 
 <!-- JavaScript Includes -->
 <script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../tooltip.js"></script>
+<script src="../vendor/tether.min.js"></script>
+<script src="../../dist/util.js"></script>
+<script src="../../dist/tooltip.js"></script>
 
 <!-- JavaScript Test -->
 <script>
diff --git a/js/tooltip.js b/js/tooltip.js
deleted file mode 100644
index 0779f139d6ccd8349f5ac1a2a8610a4a2515047e..0000000000000000000000000000000000000000
--- a/js/tooltip.js
+++ /dev/null
@@ -1,514 +0,0 @@
-/* ========================================================================
- * Bootstrap: tooltip.js v3.3.4
- * http://getbootstrap.com/javascript/#tooltip
- * Inspired by the original jQuery.tipsy by Jason Frame
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // TOOLTIP PUBLIC CLASS DEFINITION
-  // ===============================
-
-  var Tooltip = function (element, options) {
-    this.type       = null
-    this.options    = null
-    this.enabled    = null
-    this.timeout    = null
-    this.hoverState = null
-    this.$element   = null
-    this.inState    = null
-
-    this.init('tooltip', element, options)
-  }
-
-  Tooltip.VERSION  = '3.3.4'
-
-  Tooltip.TRANSITION_DURATION = 150
-
-  Tooltip.DEFAULTS = {
-    animation: true,
-    placement: 'top',
-    selector: false,
-    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
-    trigger: 'hover focus',
-    title: '',
-    delay: 0,
-    html: false,
-    container: false,
-    viewport: {
-      selector: 'body',
-      padding: 0
-    }
-  }
-
-  Tooltip.prototype.init = function (type, element, options) {
-    this.enabled   = true
-    this.type      = type
-    this.$element  = $(element)
-    this.options   = this.getOptions(options)
-    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
-    this.inState   = { click: false, hover: false, focus: false }
-
-    if (this.$element[0] instanceof document.constructor && !this.options.selector) {
-      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
-    }
-
-    var triggers = this.options.trigger.split(' ')
-
-    for (var i = triggers.length; i--;) {
-      var trigger = triggers[i]
-
-      if (trigger == 'click') {
-        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
-      } else if (trigger != 'manual') {
-        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
-        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
-
-        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
-        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
-      }
-    }
-
-    this.options.selector ?
-      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
-      this.fixTitle()
-  }
-
-  Tooltip.prototype.getDefaults = function () {
-    return Tooltip.DEFAULTS
-  }
-
-  Tooltip.prototype.getOptions = function (options) {
-    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
-
-    if (options.delay && typeof options.delay == 'number') {
-      options.delay = {
-        show: options.delay,
-        hide: options.delay
-      }
-    }
-
-    return options
-  }
-
-  Tooltip.prototype.getDelegateOptions = function () {
-    var options  = {}
-    var defaults = this.getDefaults()
-
-    this._options && $.each(this._options, function (key, value) {
-      if (defaults[key] != value) options[key] = value
-    })
-
-    return options
-  }
-
-  Tooltip.prototype.enter = function (obj) {
-    var self = obj instanceof this.constructor ?
-      obj : $(obj.currentTarget).data('bs.' + this.type)
-
-    if (!self) {
-      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
-      $(obj.currentTarget).data('bs.' + this.type, self)
-    }
-
-    if (obj instanceof $.Event) {
-      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
-    }
-
-    if (self.tip().hasClass('in') || self.hoverState == 'in') {
-      self.hoverState = 'in'
-      return
-    }
-
-    clearTimeout(self.timeout)
-
-    self.hoverState = 'in'
-
-    if (!self.options.delay || !self.options.delay.show) return self.show()
-
-    self.timeout = setTimeout(function () {
-      if (self.hoverState == 'in') self.show()
-    }, self.options.delay.show)
-  }
-
-  Tooltip.prototype.isInStateTrue = function () {
-    for (var key in this.inState) {
-      if (this.inState[key]) return true
-    }
-
-    return false
-  }
-
-  Tooltip.prototype.leave = function (obj) {
-    var self = obj instanceof this.constructor ?
-      obj : $(obj.currentTarget).data('bs.' + this.type)
-
-    if (!self) {
-      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
-      $(obj.currentTarget).data('bs.' + this.type, self)
-    }
-
-    if (obj instanceof $.Event) {
-      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
-    }
-
-    if (self.isInStateTrue()) return
-
-    clearTimeout(self.timeout)
-
-    self.hoverState = 'out'
-
-    if (!self.options.delay || !self.options.delay.hide) return self.hide()
-
-    self.timeout = setTimeout(function () {
-      if (self.hoverState == 'out') self.hide()
-    }, self.options.delay.hide)
-  }
-
-  Tooltip.prototype.show = function () {
-    var e = $.Event('show.bs.' + this.type)
-
-    if (this.hasContent() && this.enabled) {
-      this.$element.trigger(e)
-
-      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
-      if (e.isDefaultPrevented() || !inDom) return
-      var that = this
-
-      var $tip = this.tip()
-
-      var tipId = this.getUID(this.type)
-
-      this.setContent()
-      $tip.attr('id', tipId)
-      this.$element.attr('aria-describedby', tipId)
-
-      if (this.options.animation) $tip.addClass('fade')
-
-      var placement = typeof this.options.placement == 'function' ?
-        this.options.placement.call(this, $tip[0], this.$element[0]) :
-        this.options.placement
-
-      var autoToken = /\s?auto?\s?/i
-      var autoPlace = autoToken.test(placement)
-      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
-
-      $tip
-        .detach()
-        .css({ top: 0, left: 0, display: 'block' })
-        .addClass(placement)
-        .data('bs.' + this.type, this)
-
-      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
-      this.$element.trigger('inserted.bs.' + this.type)
-
-      var pos          = this.getPosition()
-      var actualWidth  = $tip[0].offsetWidth
-      var actualHeight = $tip[0].offsetHeight
-
-      if (autoPlace) {
-        var orgPlacement = placement
-        var viewportDim = this.getPosition(this.$viewport)
-
-        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :
-                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :
-                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :
-                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :
-                    placement
-
-        $tip
-          .removeClass(orgPlacement)
-          .addClass(placement)
-      }
-
-      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
-
-      this.applyPlacement(calculatedOffset, placement)
-
-      var complete = function () {
-        var prevHoverState = that.hoverState
-        that.$element.trigger('shown.bs.' + that.type)
-        that.hoverState = null
-
-        if (prevHoverState == 'out') that.leave(that)
-      }
-
-      $.support.transition && this.$tip.hasClass('fade') ?
-        $tip
-          .one('bsTransitionEnd', complete)
-          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
-        complete()
-    }
-  }
-
-  Tooltip.prototype.applyPlacement = function (offset, placement) {
-    var $tip   = this.tip()
-    var width  = $tip[0].offsetWidth
-    var height = $tip[0].offsetHeight
-
-    // manually read margins because getBoundingClientRect includes difference
-    var marginTop = parseInt($tip.css('margin-top'), 10)
-    var marginLeft = parseInt($tip.css('margin-left'), 10)
-
-    // we must check for NaN for ie 8/9
-    if (isNaN(marginTop))  marginTop  = 0
-    if (isNaN(marginLeft)) marginLeft = 0
-
-    offset.top  += marginTop
-    offset.left += marginLeft
-
-    // $.fn.offset doesn't round pixel values
-    // so we use setOffset directly with our own function B-0
-    $.offset.setOffset($tip[0], $.extend({
-      using: function (props) {
-        $tip.css({
-          top: Math.round(props.top),
-          left: Math.round(props.left)
-        })
-      }
-    }, offset), 0)
-
-    $tip.addClass('in')
-
-    // check to see if placing tip in new offset caused the tip to resize itself
-    var actualWidth  = $tip[0].offsetWidth
-    var actualHeight = $tip[0].offsetHeight
-
-    if (placement == 'top' && actualHeight != height) {
-      offset.top = offset.top + height - actualHeight
-    }
-
-    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
-
-    if (delta.left) offset.left += delta.left
-    else offset.top += delta.top
-
-    var isVertical          = /top|bottom/.test(placement)
-    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
-    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
-
-    $tip.offset(offset)
-    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
-  }
-
-  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
-    this.arrow()
-      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
-      .css(isVertical ? 'top' : 'left', '')
-  }
-
-  Tooltip.prototype.setContent = function () {
-    var $tip  = this.tip()
-    var title = this.getTitle()
-
-    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
-    $tip.removeClass('fade in top bottom left right')
-  }
-
-  Tooltip.prototype.hide = function (callback) {
-    var that = this
-    var $tip = $(this.$tip)
-    var e    = $.Event('hide.bs.' + this.type)
-
-    function complete() {
-      if (that.hoverState != 'in') $tip.detach()
-      that.$element
-        .removeAttr('aria-describedby')
-        .trigger('hidden.bs.' + that.type)
-      callback && callback()
-    }
-
-    this.$element.trigger(e)
-
-    if (e.isDefaultPrevented()) return
-
-    $tip.removeClass('in')
-
-    $.support.transition && $tip.hasClass('fade') ?
-      $tip
-        .one('bsTransitionEnd', complete)
-        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
-      complete()
-
-    this.hoverState = null
-
-    return this
-  }
-
-  Tooltip.prototype.fixTitle = function () {
-    var $e = this.$element
-    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
-      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
-    }
-  }
-
-  Tooltip.prototype.hasContent = function () {
-    return this.getTitle()
-  }
-
-  Tooltip.prototype.getPosition = function ($element) {
-    $element   = $element || this.$element
-
-    var el     = $element[0]
-    var isBody = el.tagName == 'BODY'
-
-    var elRect    = el.getBoundingClientRect()
-    if (elRect.width == null) {
-      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
-      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
-    }
-    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()
-    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
-    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
-
-    return $.extend({}, elRect, scroll, outerDims, elOffset)
-  }
-
-  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
-    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :
-           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
-           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
-        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
-
-  }
-
-  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
-    var delta = { top: 0, left: 0 }
-    if (!this.$viewport) return delta
-
-    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
-    var viewportDimensions = this.getPosition(this.$viewport)
-
-    if (/right|left/.test(placement)) {
-      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
-      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
-      if (topEdgeOffset < viewportDimensions.top) { // top overflow
-        delta.top = viewportDimensions.top - topEdgeOffset
-      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
-        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
-      }
-    } else {
-      var leftEdgeOffset  = pos.left - viewportPadding
-      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
-      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
-        delta.left = viewportDimensions.left - leftEdgeOffset
-      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
-        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
-      }
-    }
-
-    return delta
-  }
-
-  Tooltip.prototype.getTitle = function () {
-    var title
-    var $e = this.$element
-    var o  = this.options
-
-    title = $e.attr('data-original-title')
-      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
-
-    return title
-  }
-
-  Tooltip.prototype.getUID = function (prefix) {
-    do prefix += ~~(Math.random() * 1000000)
-    while (document.getElementById(prefix))
-    return prefix
-  }
-
-  Tooltip.prototype.tip = function () {
-    if (!this.$tip) {
-      this.$tip = $(this.options.template)
-      if (this.$tip.length != 1) {
-        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
-      }
-    }
-    return this.$tip
-  }
-
-  Tooltip.prototype.arrow = function () {
-    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
-  }
-
-  Tooltip.prototype.enable = function () {
-    this.enabled = true
-  }
-
-  Tooltip.prototype.disable = function () {
-    this.enabled = false
-  }
-
-  Tooltip.prototype.toggleEnabled = function () {
-    this.enabled = !this.enabled
-  }
-
-  Tooltip.prototype.toggle = function (e) {
-    var self = this
-    if (e) {
-      self = $(e.currentTarget).data('bs.' + this.type)
-      if (!self) {
-        self = new this.constructor(e.currentTarget, this.getDelegateOptions())
-        $(e.currentTarget).data('bs.' + this.type, self)
-      }
-    }
-
-    if (e) {
-      self.inState.click = !self.inState.click
-      if (self.isInStateTrue()) self.enter(self)
-      else self.leave(self)
-    } else {
-      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
-    }
-  }
-
-  Tooltip.prototype.destroy = function () {
-    var that = this
-    clearTimeout(this.timeout)
-    this.hide(function () {
-      that.$element.off('.' + that.type).removeData('bs.' + that.type)
-      if (that.$tip) {
-        that.$tip.detach()
-      }
-      that.$tip = null
-      that.$arrow = null
-      that.$viewport = null
-    })
-  }
-
-
-  // TOOLTIP PLUGIN DEFINITION
-  // =========================
-
-  function Plugin(option) {
-    return this.each(function () {
-      var $this   = $(this)
-      var data    = $this.data('bs.tooltip')
-      var options = typeof option == 'object' && option
-
-      if (!data && /destroy|hide/.test(option)) return
-      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
-      if (typeof option == 'string') data[option]()
-    })
-  }
-
-  var old = $.fn.tooltip
-
-  $.fn.tooltip             = Plugin
-  $.fn.tooltip.Constructor = Tooltip
-
-
-  // TOOLTIP NO CONFLICT
-  // ===================
-
-  $.fn.tooltip.noConflict = function () {
-    $.fn.tooltip = old
-    return this
-  }
-
-}(jQuery);
diff --git a/js/transition.js b/js/transition.js
deleted file mode 100644
index f23e6bdfe48b51024a9f58dd99e32cddff35cd96..0000000000000000000000000000000000000000
--- a/js/transition.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ========================================================================
- * Bootstrap: transition.js v3.3.4
- * http://getbootstrap.com/javascript/#transitions
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
-  'use strict';
-
-  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
-  // ============================================================
-
-  function transitionEnd() {
-    var el = document.createElement('bootstrap')
-
-    var transEndEventNames = {
-      WebkitTransition : 'webkitTransitionEnd',
-      MozTransition    : 'transitionend',
-      OTransition      : 'oTransitionEnd otransitionend',
-      transition       : 'transitionend'
-    }
-
-    for (var name in transEndEventNames) {
-      if (el.style[name] !== undefined) {
-        return { end: transEndEventNames[name] }
-      }
-    }
-
-    return false // explicit for ie8 (  ._.)
-  }
-
-  // http://blog.alexmaccaw.com/css-transitions
-  $.fn.emulateTransitionEnd = function (duration) {
-    var called = false
-    var $el = this
-    $(this).one('bsTransitionEnd', function () { called = true })
-    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
-    setTimeout(callback, duration)
-    return this
-  }
-
-  $(function () {
-    $.support.transition = transitionEnd()
-
-    if (!$.support.transition) return
-
-    $.event.special.bsTransitionEnd = {
-      bindType: $.support.transition.end,
-      delegateType: $.support.transition.end,
-      handle: function (e) {
-        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
-      }
-    }
-  })
-
-}(jQuery);
diff --git a/package.json b/package.json
index 107325a254f2d0384bd414e0d218fda8fb9a07f7..5599e0fadffe3602c2110800847d6b51036ca393 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
     "glob": "~5.0.3",
     "grunt": "~0.4.5",
     "grunt-autoprefixer": "~2.2.0",
+    "grunt-babel": "^5.0.0",
     "grunt-banner": "~0.3.1",
     "grunt-contrib-clean": "~0.6.0",
     "grunt-contrib-compress": "~0.13.0",
@@ -54,11 +55,13 @@
     "grunt-html": "~4.0.1",
     "grunt-jekyll": "~0.4.2",
     "grunt-jscs": "~1.8.0",
+    "grunt-line-remover": "0.0.2",
     "grunt-postcss": "^0.3.0",
     "grunt-sass": "^1.0.0",
     "grunt-saucelabs": "~8.6.0",
     "grunt-scss-lint": "^0.3.4",
     "grunt-sed": "~0.1.1",
+    "grunt-stamp": "^0.1.0",
     "load-grunt-tasks": "~3.1.0",
     "markdown-it": "^4.0.1",
     "mq4-hover-shim": "^0.1.0",
@@ -85,6 +88,10 @@
         "exports": "$"
       }
     },
-    "files": ["css", "fonts", "js"]
+    "files": [
+      "css",
+      "fonts",
+      "js"
+    ]
   }
 }
diff --git a/scss/_popover.scss b/scss/_popover.scss
index 7757fc1792f1298b6bb6c67f34b2b68b64d1ab4b..99b2ac56374f8737cce6b0615c0f1f41bd7bc2fc 100644
--- a/scss/_popover.scss
+++ b/scss/_popover.scss
@@ -8,7 +8,7 @@
   top: 0;
   left: 0;
   z-index: $zindex-popover;
-  display: none;
+  display: block;
   max-width: $popover-max-width;
   padding: 1px;
   // Reset font and text properties given new insertion method
@@ -24,14 +24,94 @@
   border: 1px solid $popover-border-color;
   @include border-radius($border-radius-lg);
   @include box-shadow(0 5px 10px rgba(0,0,0,.2));
+
+
+  // Popover directions
+
+  &.popover-top,
+  &.bs-tether-element-attached-bottom  {
+    margin-top: -$popover-arrow-width;
+
+    .popover-arrow {
+      bottom: -$popover-arrow-outer-width;
+      left: 50%;
+      margin-left: -$popover-arrow-outer-width;
+      border-top-color: $popover-arrow-outer-color;
+      border-bottom-width: 0;
+      &:after {
+        bottom: 1px;
+        margin-left: -$popover-arrow-width;
+        content: "";
+        border-top-color: $popover-arrow-color;
+        border-bottom-width: 0;
+      }
+    }
+  }
+
+  &.popover-right,
+  &.bs-tether-element-attached-left {
+    margin-left: $popover-arrow-width;
+
+    .popover-arrow {
+      top: 50%;
+      left: -$popover-arrow-outer-width;
+      margin-top: -$popover-arrow-outer-width;
+      border-right-color: $popover-arrow-outer-color;
+      border-left-width: 0;
+      &:after {
+        bottom: -$popover-arrow-width;
+        left: 1px;
+        content: "";
+        border-right-color: $popover-arrow-color;
+        border-left-width: 0;
+      }
+    }
+  }
+
+  &.popover-bottom,
+  &.bs-tether-element-attached-top {
+    margin-top: $popover-arrow-width;
+
+    .popover-arrow {
+      top: -$popover-arrow-outer-width;
+      left: 50%;
+      margin-left: -$popover-arrow-outer-width;
+      border-top-width: 0;
+      border-bottom-color: $popover-arrow-outer-color;
+      &:after {
+        top: 1px;
+        margin-left: -$popover-arrow-width;
+        content: "";
+        border-top-width: 0;
+        border-bottom-color: $popover-arrow-color;
+      }
+    }
+  }
+
+  &.popover-left,
+  &.bs-tether-element-attached-right {
+   margin-left: -$popover-arrow-width;
+
+   .popover-arrow {
+      top: 50%;
+      right: -$popover-arrow-outer-width;
+      margin-top: -$popover-arrow-outer-width;
+      border-right-width: 0;
+      border-left-color: $popover-arrow-outer-color;
+      &:after {
+        right: 1px;
+        bottom: -$popover-arrow-width;
+        content: "";
+        border-right-width: 0;
+        border-left-color: $popover-arrow-color;
+      }
+    }
+ }
+
 }
 
-// Offset the popover to account for the popover arrow
-.popover-top     { margin-top: -$popover-arrow-width; }
-.popover-right   { margin-left: $popover-arrow-width; }
-.popover-bottom  { margin-top: $popover-arrow-width; }
-.popover-left    { margin-left: -$popover-arrow-width; }
 
+// Offset the popover to account for the popover arrow
 .popover-title {
   padding: 8px 14px;
   margin: 0; // reset heading margin
@@ -68,61 +148,3 @@
   content: "";
   border-width: $popover-arrow-width;
 }
-
-.popover-top > .popover-arrow {
-  bottom: -$popover-arrow-outer-width;
-  left: 50%;
-  margin-left: -$popover-arrow-outer-width;
-  border-top-color: $popover-arrow-outer-color;
-  border-bottom-width: 0;
-  &:after {
-    bottom: 1px;
-    margin-left: -$popover-arrow-width;
-    content: "";
-    border-top-color: $popover-arrow-color;
-    border-bottom-width: 0;
-  }
-}
-.popover-right > .popover-arrow {
-  top: 50%;
-  left: -$popover-arrow-outer-width;
-  margin-top: -$popover-arrow-outer-width;
-  border-right-color: $popover-arrow-outer-color;
-  border-left-width: 0;
-  &:after {
-    bottom: -$popover-arrow-width;
-    left: 1px;
-    content: "";
-    border-right-color: $popover-arrow-color;
-    border-left-width: 0;
-  }
-}
-.popover-bottom > .popover-arrow {
-  top: -$popover-arrow-outer-width;
-  left: 50%;
-  margin-left: -$popover-arrow-outer-width;
-  border-top-width: 0;
-  border-bottom-color: $popover-arrow-outer-color;
-  &:after {
-    top: 1px;
-    margin-left: -$popover-arrow-width;
-    content: "";
-    border-top-width: 0;
-    border-bottom-color: $popover-arrow-color;
-  }
-}
-
-.popover-left > .popover-arrow {
-  top: 50%;
-  right: -$popover-arrow-outer-width;
-  margin-top: -$popover-arrow-outer-width;
-  border-right-width: 0;
-  border-left-color: $popover-arrow-outer-color;
-  &:after {
-    right: 1px;
-    bottom: -$popover-arrow-width;
-    content: "";
-    border-right-width: 0;
-    border-left-color: $popover-arrow-color;
-  }
-}
diff --git a/scss/_tooltip.scss b/scss/_tooltip.scss
index 379d6d5e60868a6ee719b77e9a18836619d59af3..28999861123f58f04896009b291655e1a1b6967f 100644
--- a/scss/_tooltip.scss
+++ b/scss/_tooltip.scss
@@ -16,23 +16,59 @@
   opacity: 0;
 
   &.in { opacity: $tooltip-opacity; }
-}
 
-.tooltip-top {
-  padding: $tooltip-arrow-width 0;
-  margin-top: -3px;
-}
-.tooltip-right {
-  padding: 0 $tooltip-arrow-width;
-  margin-left: 3px;
-}
-.tooltip-bottom {
-  padding: $tooltip-arrow-width 0;
-  margin-top: 3px;
-}
-.tooltip-left {
-  padding: 0 $tooltip-arrow-width;
-  margin-left: -3px;
+  &.tooltip-top,
+  &.bs-tether-element-attached-bottom {
+    padding: $tooltip-arrow-width 0;
+    margin-top: -3px;
+
+    .tooltip-arrow {
+      bottom: 0;
+      left: 50%;
+      margin-left: -$tooltip-arrow-width;
+      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: 3px;
+
+    .tooltip-arrow {
+      top: 50%;
+      left: 0;
+      margin-top: -$tooltip-arrow-width;
+      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: 3px;
+
+    .tooltip-arrow {
+      top: 0;
+      left: 50%;
+      margin-left: -$tooltip-arrow-width;
+      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: -3px;
+
+    .tooltip-arrow {
+      top: 50%;
+      right: 0;
+      margin-top: -$tooltip-arrow-width;
+      border-width: $tooltip-arrow-width 0 $tooltip-arrow-width $tooltip-arrow-width;
+      border-left-color: $tooltip-arrow-color;
+    }
+  }
 }
 
 // Wrapper for the tooltip content
@@ -53,32 +89,4 @@
   height: 0;
   border-color: transparent;
   border-style: solid;
-}
-.tooltip-top .tooltip-arrow {
-  bottom: 0;
-  left: 50%;
-  margin-left: -$tooltip-arrow-width;
-  border-width: $tooltip-arrow-width $tooltip-arrow-width 0;
-  border-top-color: $tooltip-arrow-color;
-}
-.tooltip-right .tooltip-arrow {
-  top: 50%;
-  left: 0;
-  margin-top: -$tooltip-arrow-width;
-  border-width: $tooltip-arrow-width $tooltip-arrow-width $tooltip-arrow-width 0;
-  border-right-color: $tooltip-arrow-color;
-}
-.tooltip-left .tooltip-arrow {
-  top: 50%;
-  right: 0;
-  margin-top: -$tooltip-arrow-width;
-  border-width: $tooltip-arrow-width 0 $tooltip-arrow-width $tooltip-arrow-width;
-  border-left-color: $tooltip-arrow-color;
-}
-.tooltip-bottom .tooltip-arrow {
-  top: 0;
-  left: 50%;
-  margin-left: -$tooltip-arrow-width;
-  border-width: 0 $tooltip-arrow-width $tooltip-arrow-width;
-  border-bottom-color: $tooltip-arrow-color;
-}
+}
\ No newline at end of file