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
