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
