diff --git a/node_modules/mdl-ext/es/utils/constants.js b/node_modules/mdl-ext/es/utils/constants.js
new file mode 100644
index 0000000..2d063e2
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/constants.js
@@ -0,0 +1,63 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+var VK_TAB = 9;
+var VK_ENTER = 13;
+var VK_ESC = 27;
+var VK_SPACE = 32;
+var VK_PAGE_UP = 33;
+var VK_PAGE_DOWN = 34;
+var VK_END = 35;
+var VK_HOME = 36;
+var VK_ARROW_LEFT = 37;
+var VK_ARROW_UP = 38;
+var VK_ARROW_RIGHT = 39;
+var VK_ARROW_DOWN = 40;
+
+var ARIA_EXPANDED = 'aria-expanded';
+var ARIA_HIDDEN = 'aria-hidden';
+var ARIA_MULTISELECTABLE = 'aria-multiselectable';
+var ARIA_SELECTED = 'aria-selected';
+
+var IS_DIRTY = 'is-dirty';
+var IS_DISABLED = 'is-disabled';
+var IS_EXPANDED = 'is-expanded';
+var IS_FOCUSED = 'is-focused';
+var IS_INVALID = 'is-invalid';
+var IS_UPGRADED = 'is-upgraded';
+var DATA_UPGRADED = 'data-upgraded';
+
+var MDL_RIPPLE = 'mdl-ripple';
+var MDL_RIPPLE_COMPONENT = 'MaterialRipple';
+var MDL_RIPPLE_EFFECT = 'mdl-js-ripple-effect';
+var MDL_RIPPLE_EFFECT_IGNORE_EVENTS = 'mdl-js-ripple-effect--ignore-events';
+
+exports.VK_TAB = VK_TAB;
+exports.VK_ENTER = VK_ENTER;
+exports.VK_ESC = VK_ESC;
+exports.VK_SPACE = VK_SPACE;
+exports.VK_PAGE_UP = VK_PAGE_UP;
+exports.VK_PAGE_DOWN = VK_PAGE_DOWN;
+exports.VK_END = VK_END;
+exports.VK_HOME = VK_HOME;
+exports.VK_ARROW_LEFT = VK_ARROW_LEFT;
+exports.VK_ARROW_UP = VK_ARROW_UP;
+exports.VK_ARROW_RIGHT = VK_ARROW_RIGHT;
+exports.VK_ARROW_DOWN = VK_ARROW_DOWN;
+exports.ARIA_EXPANDED = ARIA_EXPANDED;
+exports.ARIA_HIDDEN = ARIA_HIDDEN;
+exports.ARIA_MULTISELECTABLE = ARIA_MULTISELECTABLE;
+exports.ARIA_SELECTED = ARIA_SELECTED;
+exports.IS_DIRTY = IS_DIRTY;
+exports.IS_DISABLED = IS_DISABLED;
+exports.IS_EXPANDED = IS_EXPANDED;
+exports.IS_FOCUSED = IS_FOCUSED;
+exports.IS_INVALID = IS_INVALID;
+exports.IS_UPGRADED = IS_UPGRADED;
+exports.DATA_UPGRADED = DATA_UPGRADED;
+exports.MDL_RIPPLE = MDL_RIPPLE;
+exports.MDL_RIPPLE_COMPONENT = MDL_RIPPLE_COMPONENT;
+exports.MDL_RIPPLE_EFFECT = MDL_RIPPLE_EFFECT;
+exports.MDL_RIPPLE_EFFECT_IGNORE_EVENTS = MDL_RIPPLE_EFFECT_IGNORE_EVENTS;
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/debounce-function.js b/node_modules/mdl-ext/es/utils/debounce-function.js
new file mode 100644
index 0000000..27f977c
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/debounce-function.js
@@ -0,0 +1,89 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _apply = require("babel-runtime/core-js/reflect/apply");
+
+var _apply2 = _interopRequireDefault(_apply);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Debouncing enforces that a function not be called again until a certain
+ * amount of time has passed without it being called.
+ *
+ * @see https://css-tricks.com/the-difference-between-throttling-and-debouncing/
+ * @see https://github.com/webmodules/raf-debounce
+ * @see https://github.com/moszeed/es6-promise-debounce
+ * @see https://gist.github.com/philbirnie/893950093611d5c1dff4246a572cfbeb/
+ * @see https://github.com/SliceMeNice-ES6/event-utils/blob/master/debounce.js
+ * @see https://github.com/jeromedecoster/raf-funcs
+ * @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/
+ * @see http://davidwalsh.name/javascript-debounce-function
+ *
+ * @param callback the callback
+ * @param threshold optional delay, default to 250 ms, min to 1000/60ms ms
+ * @param context  optional context of this, default to global
+ * @return {Function} reference to immediate and cancel
+ */
+var MIN_THRESHOLD = 1000 / 60;
+
+var debounceFunction = function debounceFunction(callback) {
+  var threshold = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 250;
+  var context = arguments[2];
+
+
+  if (threshold < MIN_THRESHOLD) {
+    threshold = MIN_THRESHOLD;
+  }
+
+  if (!context) {
+    context = this || window;
+  }
+
+  var next = null;
+  var start = 0;
+
+  return function () {
+    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+      args[_key] = arguments[_key];
+    }
+
+    var _cancel = function _cancel() {
+      if (next) {
+        window.cancelAnimationFrame(next);
+        next = null;
+      }
+    };
+
+    var execute = function execute() {
+      _cancel();
+      return (0, _apply2.default)(callback, context, args);
+    };
+
+    var later = function later() {
+      if (threshold - (Date.now() - start) <= 0) {
+        return execute();
+      }
+      next = window.requestAnimationFrame(later);
+    };
+
+    _cancel();
+    start = Date.now();
+    next = window.requestAnimationFrame(later);
+
+    return {
+      cancel: function cancel() {
+        return _cancel();
+      },
+      immediate: function immediate() {
+        return execute();
+      }
+    };
+  };
+};
+
+exports.default = debounceFunction;
+module.exports = exports["default"];
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/dom-utils.js b/node_modules/mdl-ext/es/utils/dom-utils.js
new file mode 100644
index 0000000..3f63f90
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/dom-utils.js
@@ -0,0 +1,424 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.tether = exports.removeChildElements = exports.moveElements = exports.isRectInsideWindowViewport = exports.isFocusable = exports.getScrollParents = exports.getParentElements = exports.getWindowViewport = undefined;
+
+var _isNan = require('babel-runtime/core-js/number/is-nan');
+
+var _isNan2 = _interopRequireDefault(_isNan);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Remove child element(s)
+ * element.innerHTNL = '' has a performance penality!
+ * @see http://jsperf.com/empty-an-element/16
+ * @see http://jsperf.com/force-reflow
+ * @param element
+ * @param forceReflow
+ */
+var removeChildElements = function removeChildElements(element) {
+  var forceReflow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
+
+
+  // See: http://jsperf.com/empty-an-element/16
+  while (element.lastChild) {
+    element.removeChild(element.lastChild);
+  }
+  if (forceReflow) {
+    // See: http://jsperf.com/force-reflow
+    var d = element.style.display;
+
+    element.style.display = 'none';
+    element.style.display = d;
+  }
+};
+
+/**
+ * Moves child elements from a DOM node to another dom node.
+ * @param source {HTMLElement}
+ * @param target {HTMLElement} If the target parameter is ommited, a document fragment is created
+ * @return {HTMLElement} The target node
+ *
+ * @example
+ * // Moves child elements from a DOM node to another dom node.
+ * moveElements(source, destination);
+ *
+ * @example
+ * // If the second parameter is ommited, a document fragment is created:
+ * let fragment = moveElements(source);
+ *
+ * @See: https://github.com/webmodules/dom-move
+ */
+var moveElements = function moveElements(source, target) {
+  if (!target) {
+    target = source.ownerDocument.createDocumentFragment();
+  }
+  while (source.firstChild) {
+    target.appendChild(source.firstChild);
+  }
+  return target;
+};
+
+/**
+ * Get the browser viewport dimensions
+ * @see http://stackoverflow.com/questions/1248081/get-the-browser-viewport-dimensions-with-javascript
+ * @return {{windowWidth: number, windowHeight: number}}
+ */
+var getWindowViewport = function getWindowViewport() {
+  return {
+    viewportWidth: Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0),
+    viewportHeight: Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
+  };
+};
+
+/**
+ * Check whether an element is in the window viewport
+ * @see http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport/
+ * @param top
+ * @param left
+ * @param bottom
+ * @param right
+ * @return {boolean} true if rectangle is inside window viewport, otherwise false
+ */
+var isRectInsideWindowViewport = function isRectInsideWindowViewport(_ref) {
+  var top = _ref.top,
+      left = _ref.left,
+      bottom = _ref.bottom,
+      right = _ref.right;
+
+  var _getWindowViewport = getWindowViewport(),
+      viewportWidth = _getWindowViewport.viewportWidth,
+      viewportHeight = _getWindowViewport.viewportHeight;
+
+  return top >= 0 && left >= 0 && bottom <= viewportHeight && right <= viewportWidth;
+};
+
+/**
+ * Get a list of parent elements that can possibly scroll
+ * @param el the element to get parents for
+ * @returns {Array}
+ */
+var getScrollParents = function getScrollParents(el) {
+  var elements = [];
+
+  /*
+  for (el = el.parentNode; el; el = el.parentNode) {
+    const cs = window.getComputedStyle(el);
+    if(!(cs.overflowY === 'hidden' && cs.overflowX === 'hidden')) {
+      elements.unshift(el);
+    }
+    if(el === document.body) {
+      break;
+    }
+  }
+  */
+
+  var element = el.parentNode;
+  while (element) {
+    var cs = window.getComputedStyle(element);
+    if (!(cs.overflowY === 'hidden' && cs.overflowX === 'hidden')) {
+      elements.unshift(element);
+    }
+    if (element === document.body) {
+      break;
+    }
+    element = element.parentNode;
+  }
+
+  return elements;
+};
+
+/**
+ * Get a list of parent elements, from a given element to a given element
+ * @param {HTMLElement} from
+ * @param {HTMLElement} to
+ * @return {Array<HTMLElement>} the parent elements, not including from and to
+ */
+var getParentElements = function getParentElements(from, to) {
+  var result = [];
+  var element = from.parentNode;
+  while (element) {
+    if (element === to) {
+      break;
+    }
+    result.unshift(element);
+    element = element.parentNode;
+  }
+  return result;
+};
+
+/**
+ * Position element next to button
+ *
+ * Positioning strategy
+ *  1. element.height > viewport.height
+ *     let element.height = viewport.heigt
+ *     let element.overflow-y = auto
+ *  2. element.width > viewport.width
+ *     let element.width = viewport.width
+ *  3. position element below button, align left edge of element with button left
+ *       done if element inside viewport
+ *  4. position element below button, align right edge of element with button right
+ *       done if element inside viewport
+ *  5. positions element above button, aligns left edge of element with button left
+ *       done if element inside viewport
+ *  6. position element above the control element, aligned to its right.
+ *       done if element inside viewport
+ *  7. position element at button right hand side, aligns element top with button top
+ *       done if element inside viewport
+ *  8. position element at button left hand side, aligns element top with button top
+ *       done if element inside viewport
+ *  9. position element inside viewport
+ *     1. position element at viewport bottom
+ *     2. position element at button right hand side
+ *        done if element inside viewport
+ *     3. position element at button left hand side
+ *       done if element inside viewport
+ *     4. position element at viewport right
+ * 10. done
+ *
+ */
+var tether = function tether(controlledBy, element) {
+  var controlRect = controlledBy.getBoundingClientRect();
+
+  // 1. will element height fit inside window viewport?
+
+  var _getWindowViewport2 = getWindowViewport(),
+      viewportWidth = _getWindowViewport2.viewportWidth,
+      viewportHeight = _getWindowViewport2.viewportHeight;
+
+  element.style.height = 'auto';
+  //element.style.overflowY = 'hidden';
+  if (element.offsetHeight > viewportHeight) {
+    element.style.height = viewportHeight + 'px';
+    element.style.overflowY = 'auto';
+  }
+
+  // 2. will element width fit inside window viewport?
+  element.style.width = 'auto';
+  if (element.offsetWidth > viewportWidth) {
+    element.style.width = viewportWidth + 'px';
+  }
+
+  var elementRect = element.getBoundingClientRect();
+
+  // element to control distance
+  var dy = controlRect.top - elementRect.top;
+  var dx = controlRect.left - elementRect.left;
+
+  // element rect, window coordinates relative to top,left of control
+  var top = elementRect.top + dy;
+  var left = elementRect.left + dx;
+  var bottom = top + elementRect.height;
+  var right = left + elementRect.width;
+
+  // Position relative to control
+  var ddy = dy;
+  var ddx = dx;
+
+  if (isRectInsideWindowViewport({
+    top: top + controlRect.height,
+    left: left,
+    bottom: bottom + controlRect.height,
+    right: right
+  })) {
+    // 3 position element below the control element, aligned to its left
+    ddy = controlRect.height + dy;
+    //console.log('***** 3');
+  } else if (isRectInsideWindowViewport({
+    top: top + controlRect.height,
+    left: left + controlRect.width - elementRect.width,
+    bottom: bottom + controlRect.height,
+    right: left + controlRect.width
+  })) {
+    // 4 position element below the control element, aligned to its right
+    ddy = controlRect.height + dy;
+    ddx = dx + controlRect.width - elementRect.width;
+    //console.log('***** 4');
+  } else if (isRectInsideWindowViewport({
+    top: top - elementRect.height,
+    left: left,
+    bottom: bottom - elementRect.height,
+    right: right
+  })) {
+    // 5. position element above the control element, aligned to its left.
+    ddy = dy - elementRect.height;
+    //console.log('***** 5');
+  } else if (isRectInsideWindowViewport({
+    top: top - elementRect.height,
+    left: left + controlRect.width - elementRect.width,
+    bottom: bottom - elementRect.height,
+    right: left + controlRect.width
+  })) {
+    // 6. position element above the control element, aligned to its right.
+    ddy = dy - elementRect.height;
+    ddx = dx + controlRect.width - elementRect.width;
+    //console.log('***** 6');
+  } else if (isRectInsideWindowViewport({
+    top: top,
+    left: left + controlRect.width,
+    bottom: bottom,
+    right: right + controlRect.width
+  })) {
+    // 7. position element at button right hand side
+    ddx = controlRect.width + dx;
+    //console.log('***** 7');
+  } else if (isRectInsideWindowViewport({
+    top: top,
+    left: left - controlRect.width,
+    bottom: bottom,
+    right: right - controlRect.width
+  })) {
+    // 8. position element at button left hand side
+    ddx = dx - elementRect.width;
+    //console.log('***** 8');
+  } else {
+    // 9. position element inside viewport, near controlrect if possible
+    //console.log('***** 9');
+
+    // 9.1 position element near controlrect bottom
+    ddy = dy - bottom + viewportHeight;
+    if (top + controlRect.height >= 0 && bottom + controlRect.height <= viewportHeight) {
+      ddy = controlRect.height + dy;
+    } else if (top - elementRect.height >= 0 && bottom - elementRect.height <= viewportHeight) {
+      ddy = dy - elementRect.height;
+    }
+
+    if (left + elementRect.width + controlRect.width <= viewportWidth) {
+      // 9.2 Position element at button right hand side
+      ddx = controlRect.width + dx;
+      //console.log('***** 9.2');
+    } else if (left - elementRect.width >= 0) {
+      // 9.3 Position element at button left hand side
+      ddx = dx - elementRect.width;
+      //console.log('***** 9.3');
+    } else {
+      // 9.4 position element at (near) viewport right
+      var r = left + elementRect.width - viewportWidth;
+      ddx = dx - r;
+      //console.log('***** 9.4');
+    }
+  }
+
+  // 10. done
+  element.style.top = element.offsetTop + ddy + 'px';
+  element.style.left = element.offsetLeft + ddx + 'px';
+  //console.log('***** 10. done');
+};
+
+/**
+ * Check if the given element can receive focus
+ * @param {HTMLElement} element the element to check
+ * @return {boolean} true if the element is focusable, otherwise false
+ */
+var isFocusable = function isFocusable(element) {
+  // https://github.com/stephenmathieson/is-focusable/blob/master/index.js
+  // http://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus
+
+  if (element.hasAttribute('tabindex')) {
+    var tabindex = element.getAttribute('tabindex');
+    if (!(0, _isNan2.default)(tabindex)) {
+      return parseInt(tabindex) > -1;
+    }
+  }
+
+  if (element.hasAttribute('contenteditable') && element.getAttribute('contenteditable') !== 'false') {
+    // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes#attr-contenteditable
+    return true;
+  }
+
+  // natively focusable, but only when enabled
+  var selector = /input|select|textarea|button|details/i;
+  var name = element.nodeName;
+  if (selector.test(name)) {
+    return element.type.toLowerCase() !== 'hidden' && !element.disabled;
+  }
+
+  // anchors and area must have an href
+  if (name === 'A' || name === 'AREA') {
+    return !!element.href;
+  }
+
+  if (name === 'IFRAME') {
+    // Check visible iframe
+    var cs = window.getComputedStyle(element);
+    return cs.getPropertyValue('display').toLowerCase() !== 'none';
+  }
+
+  return false;
+};
+
+/**
+ * Get a list of offset parents for given element
+ * @see https://www.benpickles.com/articles/51-finding-a-dom-nodes-common-ancestor-using-javascript
+ * @param el the element
+ * @return {Array} a list of offset parents
+ */
+/*
+const offsetParents = (el) => {
+  const elements = [];
+  for (; el; el = el.offsetParent) {
+    elements.unshift(el);
+  }
+  if(!elements.find(e => e === document.body)) {
+    elements.unshift(document.body);
+  }
+  return elements;
+};
+*/
+
+/**
+ * Finds the common offset ancestor of two DOM nodes
+ * @see https://www.benpickles.com/articles/51-finding-a-dom-nodes-common-ancestor-using-javascript
+ * @see https://gist.github.com/benpickles/4059636
+ * @param a
+ * @param b
+ * @return {Element} The common offset ancestor of a and b
+ */
+/*
+const commonOffsetAncestor = (a, b) => {
+  const parentsA = offsetParents(a);
+  const parentsB = offsetParents(b);
+
+  for (let i = 0; i < parentsA.length; i++) {
+    if (parentsA[i] !== parentsB[i]) return parentsA[i-1];
+  }
+};
+*/
+
+/**
+ * Calculate position relative to a target element
+ * @see http://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
+ * @param target
+ * @param el
+ * @return {{top: number, left: number}}
+ */
+/*
+const calcPositionRelativeToTarget = (target, el) => {
+  let top = 0;
+  let left = 0;
+
+  while(el) {
+    top += (el.offsetTop - el.scrollTop + el.clientTop) || 0;
+    left += (el.offsetLeft - el.scrollLeft + el.clientLeft) || 0;
+    el = el.offsetParent;
+
+    if(el === target) {
+      break;
+    }
+  }
+  return { top: top, left: left };
+};
+*/
+
+exports.getWindowViewport = getWindowViewport;
+exports.getParentElements = getParentElements;
+exports.getScrollParents = getScrollParents;
+exports.isFocusable = isFocusable;
+exports.isRectInsideWindowViewport = isRectInsideWindowViewport;
+exports.moveElements = moveElements;
+exports.removeChildElements = removeChildElements;
+exports.tether = tether;
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/easing.js b/node_modules/mdl-ext/es/utils/easing.js
new file mode 100644
index 0000000..95da687
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/easing.js
@@ -0,0 +1,22 @@
+'use strict';
+
+// See: http://robertpenner.com/easing/
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+var easeInOutQuad = function easeInOutQuad(t, b, c, d) {
+  t /= d / 2;
+  if (t < 1) return c / 2 * t * t + b;
+  t--;
+  return -c / 2 * (t * (t - 2) - 1) + b;
+};
+
+var inOutQuintic = function inOutQuintic(t, b, c, d) {
+  var ts = (t /= d) * t;
+  var tc = ts * t;
+  return b + c * (6 * tc * ts + -15 * ts * ts + 10 * tc);
+};
+
+exports.easeInOutQuad = easeInOutQuad;
+exports.inOutQuintic = inOutQuintic;
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/full-throttle.js b/node_modules/mdl-ext/es/utils/full-throttle.js
new file mode 100644
index 0000000..da32123
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/full-throttle.js
@@ -0,0 +1,52 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _apply = require("babel-runtime/core-js/reflect/apply");
+
+var _apply2 = _interopRequireDefault(_apply);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Since some events can fire at a high rate, the event handler should be limited to execute computationally
+ * expensive operations, such as DOM modifications, inside a single rendered frame.
+ * When listening to e.g. scroll and resize events, the browser tends to fire off more events per
+ * second than are actually useful. For instance, if your event listener sets some element positions, then it
+ * is possible for those positions to be updated multiple times in a single rendered frame. In this case, all of
+ * the layout calculations triggered by setting the elements' positions will be wasted except for the one time that
+ * it runs immediately prior to the browser rendering the updated layout to the screen.
+ * To avoid wasting cycles, we can use requestAnimationFrame to only run the event listener once just before the page
+ * is rendered to the screen.
+ * *
+ * @param callback the function to throttle
+ * @param context  optional context of this, default to global
+ * @return {function(...[*])}
+ */
+var fullThrottle = function fullThrottle(callback, context) {
+
+  if (!context) {
+    context = undefined || window;
+  }
+
+  var throttling = false;
+
+  return function () {
+    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+      args[_key] = arguments[_key];
+    }
+
+    if (!throttling) {
+      throttling = true;
+      window.requestAnimationFrame(function () {
+        throttling = false;
+        return (0, _apply2.default)(callback, context, args);
+      });
+    }
+  };
+};
+
+exports.default = fullThrottle;
+module.exports = exports["default"];
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/index.js b/node_modules/mdl-ext/es/utils/index.js
new file mode 100644
index 0000000..4ef9db4
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/index.js
@@ -0,0 +1,15 @@
+'use strict';
+
+require('./constants');
+
+require('./dom-utils');
+
+require('./string-utils');
+
+require('./json-utils');
+
+require('./full-throttle');
+
+require('./easing');
+
+require('./interval-function');
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/interval-function.js b/node_modules/mdl-ext/es/utils/interval-function.js
new file mode 100644
index 0000000..abe7f9b
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/interval-function.js
@@ -0,0 +1,96 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+var MIN_INERVAL = 1000 / 60;
+
+/**
+ * Trigger a callback at a given interval
+ * @param interval defaults to 1000/60 ms
+ * @return {function()} reference to start, stop, immediate and started
+ */
+
+var intervalFunction = function intervalFunction() {
+  var interval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MIN_INERVAL;
+
+
+  var lapse = interval < MIN_INERVAL ? MIN_INERVAL : interval;
+  var cb = undefined;
+  var next = null;
+  var timeElapsed = 0;
+
+  var execute = function execute() {
+    var f = cb(timeElapsed);
+    if (!f) {
+      cancel();
+    }
+  };
+
+  var cancel = function cancel() {
+    if (next) {
+      window.cancelAnimationFrame(next);
+    }
+    next = null;
+    timeElapsed = 0;
+  };
+
+  var _start = function _start() {
+    var timeStart = Date.now();
+
+    var loop = function loop(now) {
+      if (next) {
+        next = window.requestAnimationFrame(function () {
+          return loop(Date.now());
+        });
+
+        timeElapsed += now - timeStart;
+
+        if (timeElapsed >= lapse) {
+          execute();
+          if ((timeElapsed -= lapse) > lapse) {
+            // time elapsed - interval_ > interval_ , indicates inactivity
+            // Could be due to browser minimized, tab changed, screen saver started, computer sleep, and so on
+            timeElapsed = 0;
+          }
+        }
+        timeStart = now;
+      }
+    };
+
+    next = 1; // a truthy value for first loop
+    loop(timeStart);
+  };
+
+  return {
+    get started() {
+      return next != null;
+    },
+    get interval() {
+      return lapse;
+    },
+    set interval(value) {
+      lapse = value < MIN_INERVAL ? MIN_INERVAL : value;
+    },
+    start: function start(callback) {
+      if (typeof callback !== 'function') {
+        throw new TypeError('callback parameter must be a function');
+      }
+      cb = callback;
+      _start();
+    },
+    immediate: function immediate() {
+      if (!cb) {
+        throw new ReferenceError('callback parameter is not defined. Call start before immediate.');
+      }
+      execute();
+    },
+
+    stop: function stop() {
+      return cancel();
+    }
+  };
+};
+
+exports.default = intervalFunction;
+module.exports = exports['default'];
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/json-utils.js b/node_modules/mdl-ext/es/utils/json-utils.js
new file mode 100644
index 0000000..50be006
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/json-utils.js
@@ -0,0 +1,31 @@
+'use strict';
+
+/**
+ * Converts a JSON string to object
+ * @param jsonString
+ * @param source
+ */
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.jsonStringToObject = undefined;
+
+var _assign = require('babel-runtime/core-js/object/assign');
+
+var _assign2 = _interopRequireDefault(_assign);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var jsonStringToObject = function jsonStringToObject(jsonString) {
+  var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+  var s = jsonString.replace(/'/g, '"');
+  try {
+    return (0, _assign2.default)(source, JSON.parse(s));
+  } catch (e) {
+    throw new Error('Failed to parse json string: ' + s + '. Error: ' + e.message);
+  }
+};
+
+exports.jsonStringToObject = jsonStringToObject;
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/resize-observer.js b/node_modules/mdl-ext/es/utils/resize-observer.js
new file mode 100644
index 0000000..37f0e0d
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/resize-observer.js
@@ -0,0 +1,377 @@
+'use strict';
+
+var _getIterator2 = require('babel-runtime/core-js/get-iterator');
+
+var _getIterator3 = _interopRequireDefault(_getIterator2);
+
+var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
+
+var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
+
+var _createClass2 = require('babel-runtime/helpers/createClass');
+
+var _createClass3 = _interopRequireDefault(_createClass2);
+
+var _intervalFunction = require('./interval-function');
+
+var _intervalFunction2 = _interopRequireDefault(_intervalFunction);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+(function (window, document) {
+  'use strict';
+
+  if (typeof window.ResizeObserver !== 'undefined') {
+    return;
+  }
+
+  document.resizeObservers = [];
+
+  /**
+   * The content rect is defined in section 2.3 ResizeObserverEntry of the spec
+   * @param target the element to calculate the content rect for
+   * @return {{top: (Number|number), left: (Number|number), width: number, height: number}}
+   *
+   * Note:
+   * Avoid using margins on the observed element. The calculation can return incorrect values when margins are involved.
+   *
+   * The following CSS will report incorrect width (Chrome OSX):
+   *
+   * <div id="outer" style="width: 300px; height:300px; background-color: green;overflow:auto;">
+   *   <div id="observed" style="width: 400px; height:400px; background-color: yellow; margin:30px; border: 20px solid red; padding:10px;">
+   *   </div>
+   * </div>
+   *
+   * The calculated width is 280. The actual (correct) width is 340 since Chrome clips the margin.
+   *
+   * Use an outer container if you really need a "margin":
+   *
+   * <div id="outer" style="width: 300px; height:300px; background-color: green;overflow:auto; padding:30px;">
+   *   <div id="observed" style="width: 400px; height:400px; background-color: yellow; margin: 0; border: 20px solid red; padding:10px;">
+   *   </div>
+   * </div>
+   *
+   * A more detailed explanation can be fund here:
+   * http://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
+   */
+  var getContentRect = function getContentRect(target) {
+    var cs = window.getComputedStyle(target);
+    var r = target.getBoundingClientRect();
+    var top = parseFloat(cs.paddingTop) || 0;
+    var left = parseFloat(cs.paddingLeft) || 0;
+    var width = r.width - ((parseFloat(cs.marginLeft) || 0) + (parseFloat(cs.marginRight) || 0) + (parseFloat(cs.borderLeftWidth) || 0) + (parseFloat(cs.borderRightWidth) || 0) + left + (parseFloat(cs.paddingRight) || 0));
+    var height = r.height - ((parseFloat(cs.marginTop) || 0) + (parseFloat(cs.marginBottom) || 0) + (parseFloat(cs.borderTopWidth) || 0) + (parseFloat(cs.borderBottomWidth) || 0) + top + (parseFloat(cs.paddingBottom) || 0));
+    return { width: width, height: height, top: top, left: left };
+  };
+
+  var dimensionHasChanged = function dimensionHasChanged(target, lastWidth, lastHeight) {
+    var _getContentRect = getContentRect(target),
+        width = _getContentRect.width,
+        height = _getContentRect.height;
+
+    return width !== lastWidth || height !== lastHeight;
+  };
+
+  /**
+   * ResizeObservation holds observation information for a single Element.
+   * @param target
+   * @return {{target: *, broadcastWidth, broadcastHeight, isOrphan: (function()), isActive: (function())}}
+   * @constructor
+   */
+  var ResizeObservation = function ResizeObservation(target) {
+    var _getContentRect2 = getContentRect(target),
+        width = _getContentRect2.width,
+        height = _getContentRect2.height;
+
+    return {
+      target: target,
+      broadcastWidth: width,
+      broadcastHeight: height,
+
+      isOrphan: function isOrphan() {
+        return !this.target || !this.target.parentNode;
+      },
+      isActive: function isActive() {
+        return dimensionHasChanged(this.target, this.broadcastWidth, this.broadcastHeight);
+      }
+    };
+  };
+
+  /**
+   * A snapshot of the observed element
+   * @param target
+   * @param rect
+   * @return {{target: *, contentRect: *}}
+   * @constructor
+   */
+  var ResizeObserverEntry = function ResizeObserverEntry(target, rect) {
+    return {
+      target: target,
+      contentRect: rect
+    };
+  };
+
+  /**
+   * The ResizeObserver is used to observe changes to Element's content rect.
+   */
+
+  var ResizeObserver = function () {
+
+    /**
+     * Constructor for instantiating new Resize observers.
+     * @param callback void (sequence<ResizeObserverEntry> entries). The function which will be called on each resize.
+     * @throws {TypeError}
+     */
+    function ResizeObserver(callback) {
+      (0, _classCallCheck3.default)(this, ResizeObserver);
+
+
+      if (typeof callback !== 'function') {
+        throw new TypeError('callback parameter must be a function');
+      }
+
+      this.callback_ = callback;
+      this.observationTargets_ = [];
+      this.activeTargets_ = [];
+
+      document.resizeObservers.push(this);
+    }
+
+    /**
+     * A list of ResizeObservations. It represents all Elements being observed.
+     *
+     * @return {Array}
+     */
+
+
+    (0, _createClass3.default)(ResizeObserver, [{
+      key: 'observe',
+
+
+      /**
+       * Adds target to the list of observed elements.
+       * @param {HTMLElement} target The target to observe
+       */
+      value: function observe(target) {
+        if (target) {
+          if (!(target instanceof HTMLElement)) {
+            throw new TypeError('target parameter must be an HTMLElement');
+          }
+          if (!this.observationTargets_.find(function (t) {
+            return t.target === target;
+          })) {
+            this.observationTargets_.push(ResizeObservation(target));
+            resizeController.start();
+          }
+        }
+      }
+
+      /**
+       * Removes target from the list of observed elements.
+       * @param target The target to remove
+       */
+
+    }, {
+      key: 'unobserve',
+      value: function unobserve(target) {
+        var i = this.observationTargets_.findIndex(function (t) {
+          return t.target === target;
+        });
+        if (i > -1) {
+          this.observationTargets_.splice(i, 1);
+        }
+      }
+
+      /**
+       * Stops the ResizeObserver instance from receiving notifications of resize changes.
+       * Until the observe() method is used again, observer's callback will not be invoked.
+       */
+
+    }, {
+      key: 'disconnect',
+      value: function disconnect() {
+        this.observationTargets_ = [];
+        this.activeTargets_ = [];
+      }
+
+      /**
+       * Removes the ResizeObserver from the list of observers
+       */
+
+    }, {
+      key: 'destroy',
+      value: function destroy() {
+        var _this = this;
+
+        this.disconnect();
+        var i = document.resizeObservers.findIndex(function (o) {
+          return o === _this;
+        });
+        if (i > -1) {
+          document.resizeObservers.splice(i, 1);
+        }
+      }
+    }, {
+      key: 'deleteOrphansAndPopulateActiveTargets_',
+      value: function deleteOrphansAndPopulateActiveTargets_() {
+
+        // Works, but two iterations
+        //this.observationTargets_ = this.observationTargets_.filter( resizeObervation => !resizeObervation.isOrphan());
+        //this.activeTargets_ = this.observationTargets_.filter( resizeObervation => resizeObervation.isActive());
+
+        // Same result as above, one iteration
+        /*
+        this.activeTargets_ = [];
+        let n = this.observationTargets_.length-1;
+        while(n >= 0) {
+          if(this.observationTargets_[n].isOrphan()) {
+            this.observationTargets_.splice(n, 1);
+          }
+          else if(this.observationTargets_[n].isActive()) {
+            this.activeTargets_.push(this.observationTargets_[n]);
+          }
+          n -= 1;
+        }
+        */
+
+        // Same result as above - but reduce is cooler :-)
+        this.activeTargets_ = this.observationTargets_.reduceRight(function (prev, resizeObservation, index, arr) {
+          if (resizeObservation.isOrphan()) {
+            arr.splice(index, 1);
+          } else if (resizeObservation.isActive()) {
+            prev.push(resizeObservation);
+          }
+          return prev;
+        }, []);
+      }
+    }, {
+      key: 'broadcast_',
+      value: function broadcast_() {
+        this.deleteOrphansAndPopulateActiveTargets_();
+        if (this.activeTargets_.length > 0) {
+          var entries = [];
+          var _iteratorNormalCompletion = true;
+          var _didIteratorError = false;
+          var _iteratorError = undefined;
+
+          try {
+            for (var _iterator = (0, _getIterator3.default)(this.activeTargets_), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+              var resizeObservation = _step.value;
+
+              var rect = getContentRect(resizeObservation.target);
+              resizeObservation.broadcastWidth = rect.width;
+              resizeObservation.broadcastHeight = rect.height;
+              entries.push(ResizeObserverEntry(resizeObservation.target, rect));
+            }
+          } catch (err) {
+            _didIteratorError = true;
+            _iteratorError = err;
+          } finally {
+            try {
+              if (!_iteratorNormalCompletion && _iterator.return) {
+                _iterator.return();
+              }
+            } finally {
+              if (_didIteratorError) {
+                throw _iteratorError;
+              }
+            }
+          }
+
+          this.callback_(entries);
+          this.activeTargets_ = [];
+        }
+      }
+    }, {
+      key: 'observationTargets',
+      get: function get() {
+        return this.observationTargets_;
+      }
+
+      /**
+       *  A list of ResizeObservations. It represents all Elements whose size has
+       *  changed since last observation broadcast that are eligible for broadcast.
+       *
+       * @return {Array}
+       */
+
+    }, {
+      key: 'activeTargets',
+      get: function get() {
+        return this.activeTargets_;
+      }
+    }]);
+    return ResizeObserver;
+  }();
+
+  //let interval = require('./interval-function');
+
+  /**
+   * Broadcasts Element.resize events
+   * @return {{start: (function()), stop: (function())}}
+   * @constructor
+   */
+
+
+  var ResizeController = function ResizeController() {
+
+    var shouldStop = function shouldStop() {
+      return document.resizeObservers.findIndex(function (resizeObserver) {
+        return resizeObserver.observationTargets.length > 0;
+      }) > -1;
+    };
+
+    var execute = function execute() {
+      //console.log('***** Execute');
+      var _iteratorNormalCompletion2 = true;
+      var _didIteratorError2 = false;
+      var _iteratorError2 = undefined;
+
+      try {
+        for (var _iterator2 = (0, _getIterator3.default)(document.resizeObservers), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+          var resizeObserver = _step2.value;
+
+          resizeObserver.broadcast_();
+        }
+      } catch (err) {
+        _didIteratorError2 = true;
+        _iteratorError2 = err;
+      } finally {
+        try {
+          if (!_iteratorNormalCompletion2 && _iterator2.return) {
+            _iterator2.return();
+          }
+        } finally {
+          if (_didIteratorError2) {
+            throw _iteratorError2;
+          }
+        }
+      }
+
+      return shouldStop();
+    };
+
+    var interval = (0, _intervalFunction2.default)(200);
+
+    return {
+      start: function start() {
+        if (!interval.started) {
+          //console.log('***** Start poll');
+          interval.start(execute);
+        }
+      }
+    };
+  };
+
+  window.ResizeObserver = ResizeObserver;
+
+  var resizeController = ResizeController();
+  //console.log('***** ResizeObserver ready');
+})(window, document);
+/**
+ * An API for observing changes to Element’s size.
+ *
+ * @See https://wicg.github.io/ResizeObserver/
+ * @ee https://github.com/pelotoncycle/resize-observer
+ *
+ */
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/string-utils.js b/node_modules/mdl-ext/es/utils/string-utils.js
new file mode 100644
index 0000000..ab0045a
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/string-utils.js
@@ -0,0 +1,114 @@
+'use strict';
+
+/**
+ * @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.
+ */
+
+/**
+ * A javascript utility for conditionally creating a list of strings.
+ * The function takes any number of arguments which can be a string or object.
+ * Inspired by (but not copied from) JedWatson/classnames, https://github.com/JedWatson/classnames
+ *
+ * @param  {*} args the strings and/or objects to
+ * @return {Array} a list of strings
+ * @example
+ * // Returns ['foo', 'bar', 'baz', 'quux']
+ * stringList(', ', 'foo', { bar: true, duck: false }, 'baz', { quux: true });
+ * @example see the tests for more examples
+ */
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.stringList = exports.randomString = exports.joinStrings = undefined;
+
+var _keys = require('babel-runtime/core-js/object/keys');
+
+var _keys2 = _interopRequireDefault(_keys);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var stringList = function stringList() {
+  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+    args[_key] = arguments[_key];
+  }
+
+  var isString = function isString(str) {
+    return str != null && typeof str === 'string';
+  };
+
+  var flatten = function flatten(list) {
+    return list.reduce(function (a, b) {
+      return a.concat(Array.isArray(b) ? flatten(b) : b);
+    }, []);
+  };
+
+  var objectToStrings = function objectToStrings(arg) {
+    return (0, _keys2.default)(arg).filter(function (key) {
+      return arg[key];
+    }).map(function (key) {
+      return key;
+    });
+  };
+
+  return args.filter(function (arg) {
+    return !!arg;
+  }).map(function (arg) {
+    return isString(arg) ? arg : objectToStrings(arg);
+  }).reduce(function (result, arg) {
+    return result.concat(Array.isArray(arg) ? flatten(arg) : arg);
+  }, []);
+};
+
+/**
+ * A simple javascript utility for conditionally joining strings together.
+ * The function takes a delimiter string and any number of arguments which can be a string or object.
+ *
+ * @param delimiter delimiter to separate joined strings
+ * @param  {*} args the strings and/or objects to join
+ * @return {String} the joined strings
+ * @example
+ * // Returns 'foo, bar, baz, quux'
+ * joinStrings(', ', 'foo', { bar: true, duck: false }, 'baz', { quux: true });
+ * @example see the tests for more examples
+ */
+var joinStrings = function joinStrings() {
+  for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+    args[_key2 - 1] = arguments[_key2];
+  }
+
+  var delimiter = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ' ';
+  return stringList.apply(undefined, args).join(delimiter);
+};
+
+/**
+ * Generates a random string with a given length
+ * @param n {Integer} length of generated string
+ * @see http://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript
+ * @return {String} the random string
+ * @example
+ * // Returns e.g. 'pd781w0y'
+ * randomString(8);
+ * @example see the tests for more examples
+ */
+var randomString = function randomString() {
+  var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 12;
+  return Array(n + 1).join((Math.random().toString(36) + '00000000000000000').slice(2, 18)).slice(0, n);
+};
+
+exports.joinStrings = joinStrings;
+exports.randomString = randomString;
+exports.stringList = stringList;
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/throttle-function.js b/node_modules/mdl-ext/es/utils/throttle-function.js
new file mode 100644
index 0000000..03a5cea
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/throttle-function.js
@@ -0,0 +1,84 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _apply = require("babel-runtime/core-js/reflect/apply");
+
+var _apply2 = _interopRequireDefault(_apply);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Throttling enforces a maximum number of times a function can be called over time.
+ *
+ * @param callback the function to throttle
+ * @param delay optional delay, default to 1000/60ms
+ * @param context optional context of this, default to global window
+ * @returns {Function} reference to immediate and cancel functions
+ * @see https://developer.mozilla.org/en-US/docs/Web/Events/resize#Example
+ * @see https://gist.github.com/yoavniran/d1d33f278bb7744d55c3
+ * @see https://github.com/pelotoncycle/frame-throttle
+ * @see https://github.com/jeromedecoster/raf-funcs
+ */
+var MIN_DELAY = 1000 / 60;
+
+var throttleFunction = function throttleFunction(callback) {
+  var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : MIN_DELAY;
+  var context = arguments[2];
+
+
+  if (delay < MIN_DELAY) {
+    delay = MIN_DELAY;
+  }
+
+  if (!context) {
+    context = undefined || window;
+  }
+
+  var next = null;
+  var start = 0;
+
+  return function () {
+    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+      args[_key] = arguments[_key];
+    }
+
+    var _cancel = function _cancel() {
+      if (next !== null) {
+        window.cancelAnimationFrame(next);
+        next = null;
+      }
+    };
+
+    var execute = function execute() {
+      _cancel();
+      return (0, _apply2.default)(callback, context, args);
+    };
+
+    var later = function later() {
+      if (delay - (Date.now() - start) <= 0) {
+        return execute();
+      }
+      next = window.requestAnimationFrame(later);
+    };
+
+    if (next === null) {
+      start = Date.now();
+      next = window.requestAnimationFrame(later);
+    }
+
+    return {
+      cancel: function cancel() {
+        return _cancel();
+      },
+      immediate: function immediate() {
+        return execute();
+      }
+    };
+  };
+};
+
+exports.default = throttleFunction;
+module.exports = exports["default"];
\ No newline at end of file
