diff --git a/node_modules/mdl-ext/es/carousel/carousel.js b/node_modules/mdl-ext/es/carousel/carousel.js
new file mode 100644
index 0000000..51b9451
--- /dev/null
+++ b/node_modules/mdl-ext/es/carousel/carousel.js
@@ -0,0 +1,718 @@
+'use strict';
+
+var _isInteger = require('babel-runtime/core-js/number/is-integer');
+
+var _isInteger2 = _interopRequireDefault(_isInteger);
+
+var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
+
+var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
+
+var _assign = require('babel-runtime/core-js/object/assign');
+
+var _assign2 = _interopRequireDefault(_assign);
+
+var _intervalFunction = require('../utils/interval-function');
+
+var _intervalFunction2 = _interopRequireDefault(_intervalFunction);
+
+var _easing = require('../utils/easing');
+
+var _jsonUtils = require('../utils/json-utils');
+
+var _constants = require('../utils/constants');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/**
+ * Image carousel
+ */
+
+var MDL_RIPPLE_CONTAINER = 'mdlext-carousel__slide__ripple-container';
+
+(function () {
+  'use strict';
+
+  //const CAROUSEL = 'mdlext-carousel';
+
+  var SLIDE = 'mdlext-carousel__slide';
+  var ROLE = 'list';
+  var SLIDE_ROLE = 'listitem';
+
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  var MaterialExtCarousel = function MaterialExtCarousel(element) {
+    // Stores the element.
+    this.element_ = element;
+
+    // Default config
+    this.config_ = {
+      interactive: true,
+      autostart: false,
+      type: 'slide',
+      interval: 1000,
+      animationLoop: (0, _intervalFunction2.default)(1000)
+    };
+
+    this.scrollAnimation_ = (0, _intervalFunction2.default)(33);
+
+    // Initialize instance.
+    this.init();
+  };
+
+  window['MaterialExtCarousel'] = MaterialExtCarousel;
+
+  /**
+   * Start slideshow animation
+   * @private
+   */
+  MaterialExtCarousel.prototype.startSlideShow_ = function () {
+    var _this = this;
+
+    var nextSlide = function nextSlide() {
+      var slide = _this.element_.querySelector('.' + SLIDE + '[aria-selected]');
+      if (slide) {
+        slide.removeAttribute('aria-selected');
+        slide = slide.nextElementSibling;
+      }
+      if (!slide) {
+        slide = _this.element_.querySelector('.' + SLIDE + ':first-child');
+        _this.animateScroll_(0);
+      }
+      if (slide) {
+        _this.moveSlideIntoViewport_(slide);
+        slide.setAttribute('aria-selected', '');
+        _this.emitSelectEvent_('next', null, slide);
+        return true;
+      }
+      return false;
+    };
+
+    var nextScroll = function nextScroll(direction) {
+      var nextDirection = direction;
+
+      if ('next' === direction && _this.element_.scrollLeft === _this.element_.scrollWidth - _this.element_.clientWidth) {
+        nextDirection = 'prev';
+      } else if (_this.element_.scrollLeft === 0) {
+        nextDirection = 'next';
+      }
+      var x = 'next' === nextDirection ? Math.min(_this.element_.scrollLeft + _this.element_.clientWidth, _this.element_.scrollWidth - _this.element_.clientWidth) : Math.max(_this.element_.scrollLeft - _this.element_.clientWidth, 0);
+
+      _this.animateScroll_(x, 1000);
+      return nextDirection;
+    };
+
+    if (!this.config_.animationLoop.started) {
+      (function () {
+        _this.config_.animationLoop.interval = _this.config_.interval;
+        var direction = 'next';
+
+        if ('scroll' === _this.config_.type) {
+          _this.config_.animationLoop.start(function () {
+            direction = nextScroll(direction);
+            return true; // It runs until cancelSlideShow_ is triggered
+          });
+        } else {
+          nextSlide();
+          _this.config_.animationLoop.start(function () {
+            return nextSlide(); // It runs until cancelSlideShow_ is triggered
+          });
+        }
+      })();
+    }
+
+    // TODO: Pause animation when carousel is not in browser viewport or user changes tab
+  };
+
+  /**
+   * Cancel slideshow if running. Emmits a 'pause' event
+   * @private
+   */
+  MaterialExtCarousel.prototype.cancelSlideShow_ = function () {
+    if (this.config_.animationLoop.started) {
+      this.config_.animationLoop.stop();
+      this.emitSelectEvent_('pause', _constants.VK_ESC, this.element_.querySelector('.' + SLIDE + '[aria-selected]'));
+    }
+  };
+
+  /**
+   * Animate scroll
+   * @param newPosition
+   * @param newDuration
+   * @param completedCallback
+   * @private
+   */
+  MaterialExtCarousel.prototype.animateScroll_ = function (newPosition, newDuration, completedCallback) {
+    var _this2 = this;
+
+    var start = this.element_.scrollLeft;
+    var distance = newPosition - start;
+
+    if (distance !== 0) {
+      (function () {
+        var duration = Math.max(Math.min(Math.abs(distance), newDuration || 400), 100); // duration is between 100 and newDuration||400ms||distance
+        var t = 0;
+        _this2.scrollAnimation_.stop();
+        _this2.scrollAnimation_.start(function (timeElapsed) {
+          t += timeElapsed;
+          if (t < duration) {
+            _this2.element_.scrollLeft = (0, _easing.inOutQuintic)(t, start, distance, duration);
+            return true;
+          } else {
+            _this2.element_.scrollLeft = newPosition;
+            if (completedCallback) {
+              completedCallback();
+            }
+            return false;
+          }
+        });
+      })();
+    } else {
+      if (completedCallback) {
+        completedCallback();
+      }
+    }
+  };
+
+  /**
+   * Execute commend
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.command_ = function (event) {
+    var _this3 = this;
+
+    var x = 0;
+    var slide = null;
+    var a = event.detail.action.toLowerCase();
+
+    // Cancel slideshow if running
+    this.cancelSlideShow_();
+
+    switch (a) {
+      case 'first':
+        slide = this.element_.querySelector('.' + SLIDE + ':first-child');
+        break;
+
+      case 'last':
+        x = this.element_.scrollWidth - this.element_.clientWidth;
+        slide = this.element_.querySelector('.' + SLIDE + ':last-child');
+        break;
+
+      case 'scroll-prev':
+        x = Math.max(this.element_.scrollLeft - this.element_.clientWidth, 0);
+        break;
+
+      case 'scroll-next':
+        x = Math.min(this.element_.scrollLeft + this.element_.clientWidth, this.element_.scrollWidth - this.element_.clientWidth);
+        break;
+
+      case 'next':
+      case 'prev':
+        slide = this.element_.querySelector('.' + SLIDE + '[aria-selected]');
+        if (slide) {
+          slide = a === 'next' ? slide.nextElementSibling : slide.previousElementSibling;
+          this.setAriaSelected_(slide);
+          this.emitSelectEvent_(a, null, slide);
+        }
+        return;
+
+      case 'play':
+        (0, _assign2.default)(this.config_, event.detail);
+        this.startSlideShow_();
+        return;
+
+      case 'pause':
+        return;
+
+      default:
+        return;
+    }
+
+    this.animateScroll_(x, undefined, function () {
+      if ('scroll-next' === a || 'scroll-prev' === a) {
+        var slides = _this3.getSlidesInViewport_();
+        if (slides.length > 0) {
+          slide = 'scroll-next' === a ? slides[0] : slides[slides.length - 1];
+        }
+      }
+      _this3.setAriaSelected_(slide);
+      _this3.emitSelectEvent_(a, null, slide);
+    });
+  };
+
+  /**
+   * Handles custom command event, 'scroll-prev', 'scroll-next', 'first', 'last', next, prev, play, pause
+   * @param event. A custom event
+   * @private
+   */
+  MaterialExtCarousel.prototype.commandHandler_ = function (event) {
+    event.preventDefault();
+    event.stopPropagation();
+    if (event.detail && event.detail.action) {
+      this.command_(event);
+    }
+  };
+
+  /**
+   * Handle keypress
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.keyDownHandler_ = function (event) {
+
+    if (event && event.target && event.target !== this.element_) {
+
+      var action = 'first';
+
+      if (event.keyCode === _constants.VK_HOME || event.keyCode === _constants.VK_END || event.keyCode === _constants.VK_PAGE_UP || event.keyCode === _constants.VK_PAGE_DOWN) {
+
+        event.preventDefault();
+        if (event.keyCode === _constants.VK_END) {
+          action = 'last';
+        } else if (event.keyCode === _constants.VK_PAGE_UP) {
+          action = 'scroll-prev';
+        } else if (event.keyCode === _constants.VK_PAGE_DOWN) {
+          action = 'scroll-next';
+        }
+
+        var cmd = new CustomEvent('select', {
+          detail: {
+            action: action
+          }
+        });
+        this.command_(cmd);
+      } else if (event.keyCode === _constants.VK_TAB || event.keyCode === _constants.VK_ENTER || event.keyCode === _constants.VK_SPACE || event.keyCode === _constants.VK_ARROW_UP || event.keyCode === _constants.VK_ARROW_LEFT || event.keyCode === _constants.VK_ARROW_DOWN || event.keyCode === _constants.VK_ARROW_RIGHT) {
+
+        var slide = getSlide_(event.target);
+
+        if (!slide) {
+          return;
+        }
+
+        // Cancel slideshow if running
+        this.cancelSlideShow_();
+
+        switch (event.keyCode) {
+          case _constants.VK_ARROW_UP:
+          case _constants.VK_ARROW_LEFT:
+            action = 'prev';
+            slide = slide.previousElementSibling;
+            break;
+
+          case _constants.VK_ARROW_DOWN:
+          case _constants.VK_ARROW_RIGHT:
+            action = 'next';
+            slide = slide.nextElementSibling;
+            break;
+
+          case _constants.VK_TAB:
+            if (event.shiftKey) {
+              action = 'prev';
+              slide = slide.previousElementSibling;
+            } else {
+              action = 'next';
+              slide = slide.nextElementSibling;
+            }
+            break;
+
+          case _constants.VK_SPACE:
+          case _constants.VK_ENTER:
+            action = 'select';
+            break;
+        }
+
+        if (slide) {
+          event.preventDefault();
+          setFocus_(slide);
+          this.emitSelectEvent_(action, event.keyCode, slide);
+        }
+      }
+    }
+  };
+
+  /**
+   * Handle dragging
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.dragHandler_ = function (event) {
+    var _this4 = this;
+
+    event.preventDefault();
+
+    // Cancel slideshow if running
+    this.cancelSlideShow_();
+
+    var updating = false;
+    var rAFDragId = 0;
+
+    var startX = event.clientX || (event.touches !== undefined ? event.touches[0].clientX : 0);
+    var prevX = startX;
+    var targetElement = event.target;
+
+    var update = function update(e) {
+      var currentX = e.clientX || (e.touches !== undefined ? e.touches[0].clientX : 0);
+      var dx = prevX - currentX;
+
+      if (dx < 0) {
+        _this4.element_.scrollLeft = Math.max(_this4.element_.scrollLeft + dx, 0);
+      } else if (dx > 0) {
+        _this4.element_.scrollLeft = Math.min(_this4.element_.scrollLeft + dx, _this4.element_.scrollWidth - _this4.element_.clientWidth);
+      }
+
+      prevX = currentX;
+      updating = false;
+    };
+
+    // drag handler
+    var drag = function drag(e) {
+      e.preventDefault();
+
+      if (!updating) {
+        rAFDragId = window.requestAnimationFrame(function () {
+          return update(e);
+        });
+        updating = true;
+      }
+    };
+
+    // end drag handler
+    var endDrag = function endDrag(e) {
+      e.preventDefault();
+
+      _this4.element_.removeEventListener('mousemove', drag);
+      _this4.element_.removeEventListener('touchmove', drag);
+      window.removeEventListener('mouseup', endDrag);
+      window.removeEventListener('touchend', endDrag);
+
+      // cancel any existing drag rAF, see: http://www.html5rocks.com/en/tutorials/speed/animations/
+      window.cancelAnimationFrame(rAFDragId);
+
+      var slide = getSlide_(targetElement);
+      setFocus_(slide);
+      _this4.emitSelectEvent_('click', null, slide);
+    };
+
+    this.element_.addEventListener('mousemove', drag);
+    this.element_.addEventListener('touchmove', drag);
+    window.addEventListener('mouseup', endDrag);
+    window.addEventListener('touchend', endDrag);
+  };
+
+  /**
+   * Handle click
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.clickHandler_ = function (event) {
+    // Click is handled by drag
+    event.preventDefault();
+  };
+
+  /**
+   * Handle focus
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.focusHandler_ = function (event) {
+    var slide = getSlide_(event.target);
+    if (slide) {
+      // The last focused/selected slide has 'aria-selected', even if focus is lost
+      this.setAriaSelected_(slide);
+      slide.classList.add(_constants.IS_FOCUSED);
+    }
+  };
+
+  /**
+   * Handle blur
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.blurHandler_ = function (event) {
+    var slide = getSlide_(event.target);
+    if (slide) {
+      slide.classList.remove(_constants.IS_FOCUSED);
+    }
+  };
+
+  /**
+   * Emits a custeom 'select' event
+   * @param command
+   * @param keyCode
+   * @param slide
+   * @private
+   */
+  MaterialExtCarousel.prototype.emitSelectEvent_ = function (command, keyCode, slide) {
+
+    if (slide) {
+      this.moveSlideIntoViewport_(slide);
+
+      var evt = new CustomEvent('select', {
+        bubbles: true,
+        cancelable: true,
+        detail: {
+          command: command,
+          keyCode: keyCode,
+          source: slide
+        }
+      });
+      this.element_.dispatchEvent(evt);
+    }
+  };
+
+  /**
+   * Get the first visible slide in component viewport
+   * @private
+   */
+  MaterialExtCarousel.prototype.getSlidesInViewport_ = function () {
+    var carouselRect = this.element_.getBoundingClientRect();
+
+    var slidesInViewport = [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE))).filter(function (slide) {
+      var slideRect = slide.getBoundingClientRect();
+      return slideRect.left >= carouselRect.left && slideRect.right <= carouselRect.right;
+    });
+    return slidesInViewport;
+  };
+
+  /**
+   * Move slide into component viewport - if needed
+   * @param slide
+   * @private
+   */
+  MaterialExtCarousel.prototype.moveSlideIntoViewport_ = function (slide) {
+    var carouselRect = this.element_.getBoundingClientRect();
+    var slideRect = slide.getBoundingClientRect();
+
+    if (slideRect.left < carouselRect.left) {
+      var x = this.element_.scrollLeft - (carouselRect.left - slideRect.left);
+      this.animateScroll_(x);
+    } else if (slideRect.right > carouselRect.right) {
+      var _x = this.element_.scrollLeft - (carouselRect.right - slideRect.right);
+      this.animateScroll_(_x);
+    }
+  };
+
+  /**
+   * Removes 'aria-selected' from all slides in carousel
+   * @private
+   */
+  MaterialExtCarousel.prototype.setAriaSelected_ = function (slide) {
+    if (slide) {
+      [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE + '[aria-selected]'))).forEach(function (slide) {
+        return slide.removeAttribute('aria-selected');
+      });
+      slide.setAttribute('aria-selected', '');
+    }
+  };
+
+  /**
+   * Removes event listeners
+   * @private
+   */
+  MaterialExtCarousel.prototype.removeListeners_ = function () {
+    this.element_.removeEventListener('focus', this.focusHandler_);
+    this.element_.removeEventListener('blur', this.blurHandler_);
+    this.element_.removeEventListener('keydown', this.keyDownHandler_);
+    this.element_.removeEventListener('mousedown', this.dragHandler_);
+    this.element_.removeEventListener('touchstart', this.dragHandler_);
+    this.element_.removeEventListener('click', this.clickHandler_, false);
+    this.element_.removeEventListener('command', this.commandHandler_);
+    this.element_.removeEventListener('mdl-componentdowngraded', this.mdlDowngrade_);
+  };
+
+  // Helpers
+  var getSlide_ = function getSlide_(element) {
+    return element.closest('.' + SLIDE);
+  };
+
+  var setFocus_ = function setFocus_(slide) {
+    if (slide) {
+      slide.focus();
+    }
+  };
+
+  var addRipple_ = function addRipple_(slide) {
+    if (!slide.querySelector('.' + MDL_RIPPLE_CONTAINER)) {
+      var rippleContainer = document.createElement('span');
+      rippleContainer.classList.add(MDL_RIPPLE_CONTAINER);
+      rippleContainer.classList.add(_constants.MDL_RIPPLE_EFFECT);
+      var ripple = document.createElement('span');
+      ripple.classList.add(_constants.MDL_RIPPLE);
+      rippleContainer.appendChild(ripple);
+
+      var img = slide.querySelector('img');
+      if (img) {
+        // rippleContainer blocks image title
+        rippleContainer.title = img.title;
+      }
+      slide.appendChild(rippleContainer);
+      componentHandler.upgradeElement(rippleContainer, _constants.MDL_RIPPLE_COMPONENT);
+    }
+  };
+  // End helpers
+
+
+  // Public methods.
+
+  /**
+   * Cancel animation - if running.
+   *
+   * @public
+   */
+  MaterialExtCarousel.prototype.stopAnimation = function () {
+    this.config_.animationLoop.stop();
+  };
+  MaterialExtCarousel.prototype['stopAnimation'] = MaterialExtCarousel.prototype.stopAnimation;
+
+  /**
+   * Upgrade slides
+   * Use if more list elements are added later (dynamically)
+   *
+   * @public
+   */
+  MaterialExtCarousel.prototype.upgradeSlides = function () {
+    var _this5 = this;
+
+    var hasRippleEffect = this.element_.classList.contains(_constants.MDL_RIPPLE_EFFECT);
+
+    [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE))).forEach(function (slide) {
+
+      slide.setAttribute('role', SLIDE_ROLE);
+
+      if (_this5.config_.interactive) {
+        if (!slide.getAttribute('tabindex')) {
+          slide.setAttribute('tabindex', '0');
+        }
+        if (hasRippleEffect) {
+          addRipple_(slide);
+        }
+      } else {
+        slide.setAttribute('tabindex', '-1');
+      }
+    });
+  };
+  MaterialExtCarousel.prototype['upgradeSlides'] = MaterialExtCarousel.prototype.upgradeSlides;
+
+  /**
+   * Get config object
+   *
+   * @public
+   */
+  MaterialExtCarousel.prototype.getConfig = function () {
+    return this.config_;
+  };
+  MaterialExtCarousel.prototype['getConfig'] = MaterialExtCarousel.prototype.getConfig;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtCarousel.prototype.init = function () {
+
+    if (this.element_) {
+      // Config
+      if (this.element_.hasAttribute('data-config')) {
+        this.config_ = (0, _jsonUtils.jsonStringToObject)(this.element_.getAttribute('data-config'), this.config_);
+      }
+
+      // Wai-Aria
+      this.element_.setAttribute('role', ROLE);
+
+      // Prefer tabindex -1
+      if (!(0, _isInteger2.default)(this.element_.getAttribute('tabindex'))) {
+        this.element_.setAttribute('tabindex', -1);
+      }
+
+      // Remove listeners, just in case ...
+      this.removeListeners_();
+
+      if (this.config_.interactive) {
+
+        // Ripple
+        var hasRippleEffect = this.element_.classList.contains(_constants.MDL_RIPPLE_EFFECT);
+        if (hasRippleEffect) {
+          this.element_.classList.add(_constants.MDL_RIPPLE_EFFECT_IGNORE_EVENTS);
+        }
+
+        // Listen to focus/blur events
+        this.element_.addEventListener('focus', this.focusHandler_.bind(this), true);
+        this.element_.addEventListener('blur', this.blurHandler_.bind(this), true);
+
+        // Listen to keyboard events
+        this.element_.addEventListener('keydown', this.keyDownHandler_.bind(this), false);
+
+        // Listen to drag events
+        this.element_.addEventListener('mousedown', this.dragHandler_.bind(this), false);
+        this.element_.addEventListener('touchstart', this.dragHandler_.bind(this), false);
+
+        // Listen to click events
+        this.element_.addEventListener('click', this.clickHandler_.bind(this), false);
+      }
+
+      // Listen to custom 'command' event
+      this.element_.addEventListener('command', this.commandHandler_.bind(this), false);
+
+      // Listen to 'mdl-componentdowngraded' event
+      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
+
+      // Slides collection
+      this.upgradeSlides();
+
+      // Set upgraded flag
+      this.element_.classList.add(_constants.IS_UPGRADED);
+
+      if (this.config_.autostart) {
+        // Start slideshow
+        this.startSlideShow_();
+      }
+    }
+  };
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   */
+  MaterialExtCarousel.prototype.mdlDowngrade_ = function () {
+    'use strict';
+    //console.log('***** MaterialExtCarousel.mdlDowngrade_');
+
+    // Stop animation - if any
+
+    this.stopAnimation();
+
+    // Remove listeners
+    this.removeListeners_();
+  };
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtCarousel,
+    classAsString: 'MaterialExtCarousel',
+    cssClass: 'mdlext-js-carousel',
+    widget: true
+  });
+})();
\ No newline at end of file
