diff --git a/node_modules/mdl-ext/src/accordion/accordion.js b/node_modules/mdl-ext/src/accordion/accordion.js
new file mode 100644
index 0000000..0ef7bef
--- /dev/null
+++ b/node_modules/mdl-ext/src/accordion/accordion.js
@@ -0,0 +1,549 @@
+/**
+ * @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
+ */
+
+/**
+ * A WAI-ARIA friendly accordion component.
+ * An accordion is a collection of expandable panels associated with a common outer container. Panels consist
+ * of a header and an associated content region or tabpanel. The primary use of an Accordion is to present multiple sections
+ * of content on a single page without scrolling, where all of the sections are peers in the application or object hierarchy.
+ * The general look is similar to a tree where each root tree node is an expandable accordion header. The user navigates
+ * and makes the contents of each panel visible (or not) by interacting with the Accordion Header
+ */
+
+import {
+  VK_ENTER,
+  VK_SPACE,
+  VK_END,
+  VK_HOME,
+  VK_ARROW_LEFT,
+  VK_ARROW_UP,
+  VK_ARROW_RIGHT,
+  VK_ARROW_DOWN,
+  IS_EXPANDED,
+  IS_UPGRADED,
+  ARIA_MULTISELECTABLE,
+  ARIA_EXPANDED,
+  ARIA_HIDDEN,
+  ARIA_SELECTED
+} from '../utils/constants';
+
+
+(function() {
+  'use strict';
+  const ACCORDION            = 'mdlext-accordion';
+  const ACCORDION_VERTICAL   = 'mdlext-accordion--vertical';
+  const ACCORDION_HORIZONTAL = 'mdlext-accordion--horizontal';
+  const PANEL                = 'mdlext-accordion__panel';
+  const PANEL_ROLE           = 'presentation';
+  const TAB                  = 'mdlext-accordion__tab';
+  const TAB_CAPTION          = 'mdlext-accordion__tab__caption';
+  const TAB_ROLE             = 'tab';
+  const TABPANEL             = 'mdlext-accordion__tabpanel';
+  const TABPANEL_ROLE        = 'tabpanel';
+  const RIPPLE_EFFECT        = 'mdlext-js-ripple-effect';
+  const RIPPLE               = 'mdlext-accordion__tab--ripple';
+  const ANIMATION_EFFECT     = 'mdlext-js-animation-effect';
+  const ANIMATION            = 'mdlext-accordion__tabpanel--animation';
+
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  const MaterialExtAccordion = function MaterialExtAccordion( element ) {
+
+    // Stores the Accordion HTML element.
+    this.element_ = element;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtAccordion'] = MaterialExtAccordion;
+
+
+  // Helpers
+  const accordionPanelElements = ( element ) => {
+    if(!element) {
+      return {
+        panel: null,
+        tab: null,
+        tabpanel: null
+      };
+    }
+    else if (element.classList.contains(PANEL)) {
+      return {
+        panel: element,
+        tab: element.querySelector(`.${TAB}`),
+        tabpanel: element.querySelector(`.${TABPANEL}`)
+      };
+    }
+    else {
+      return {
+        panel: element.parentNode,
+        tab: element.parentNode.querySelector(`.${TAB}`),
+        tabpanel: element.parentNode.querySelector(`.${TABPANEL}`)
+      };
+    }
+  };
+
+
+  // Private methods.
+
+  /**
+   * Handles custom command event, 'open', 'close', 'toggle' or upgrade
+   * @param event. A custom event
+   * @private
+   */
+  MaterialExtAccordion.prototype.commandHandler_ = function( event ) {
+    event.preventDefault();
+    event.stopPropagation();
+
+    if(event && event.detail) {
+      this.command(event.detail);
+    }
+  };
+
+  /**
+   * Dispatch toggle event
+   * @param {string} state
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.dispatchToggleEvent_ = function ( state, tab, tabpanel ) {
+    const ce = new CustomEvent('toggle', {
+      bubbles: true,
+      cancelable: true,
+      detail: { state: state, tab: tab, tabpanel: tabpanel }
+    });
+    this.element_.dispatchEvent(ce);
+  };
+
+  /**
+   * Open tab
+   * @param {Element} panel
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.openTab_ = function( panel, tab, tabpanel ) {
+    panel.classList.add(IS_EXPANDED);
+    tab.setAttribute(ARIA_EXPANDED, 'true');
+    tabpanel.removeAttribute('hidden');
+    tabpanel.setAttribute(ARIA_HIDDEN, 'false');
+    this.dispatchToggleEvent_('open', tab, tabpanel);
+  };
+
+  /**
+   * Close tab
+   * @param {Element} panel
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.closeTab_ = function( panel, tab, tabpanel ) {
+    panel.classList.remove(IS_EXPANDED);
+    tab.setAttribute(ARIA_EXPANDED, 'false');
+    tabpanel.setAttribute('hidden', '');
+    tabpanel.setAttribute(ARIA_HIDDEN, 'true');
+    this.dispatchToggleEvent_('close', tab, tabpanel);
+  };
+
+  /**
+   * Toggle tab
+   * @param {Element} panel
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.toggleTab_ = function( panel, tab, tabpanel ) {
+    if( !(this.element_.hasAttribute('disabled') || tab.hasAttribute('disabled')) ) {
+      if (tab.getAttribute(ARIA_EXPANDED).toLowerCase() === 'true') {
+        this.closeTab_(panel, tab, tabpanel);
+      }
+      else {
+        if (this.element_.getAttribute(ARIA_MULTISELECTABLE).toLowerCase() !== 'true') {
+          this.closeTabs_();
+        }
+        this.openTab_(panel, tab, tabpanel);
+      }
+    }
+  };
+
+  /**
+   * Open tabs
+   * @private
+   */
+  MaterialExtAccordion.prototype.openTabs_ = function() {
+    if (this.element_.getAttribute(ARIA_MULTISELECTABLE).toLowerCase() === 'true') {
+      [...this.element_.querySelectorAll(`.${ACCORDION} > .${PANEL}`)]
+        .filter(panel => !panel.classList.contains(IS_EXPANDED))
+        .forEach(closedItem => {
+          const tab = closedItem.querySelector(`.${TAB}`);
+          if (!tab.hasAttribute('disabled')) {
+            this.openTab_(closedItem, tab, closedItem.querySelector(`.${TABPANEL}`));
+          }
+        });
+    }
+  };
+
+  /**
+   * Close tabs
+   * @private
+   */
+  MaterialExtAccordion.prototype.closeTabs_ = function() {
+    [...this.element_.querySelectorAll(`.${ACCORDION} > .${PANEL}.${IS_EXPANDED}`)]
+      .forEach( panel => {
+        const tab = panel.querySelector(`.${TAB}`);
+        if(!tab.hasAttribute('disabled')) {
+          this.closeTab_(panel, tab, panel.querySelector(`.${TABPANEL}`));
+        }
+      });
+  };
+
+
+  // Public methods.
+
+  /**
+   * Upgrade an individual accordion tab
+   * @public
+   * @param {Element} tabElement The HTML element for the accordion panel.
+   */
+  MaterialExtAccordion.prototype.upgradeTab = function( tabElement ) {
+
+    const { panel, tab, tabpanel } = accordionPanelElements( tabElement );
+
+    const disableTab = () => {
+      panel.classList.remove(IS_EXPANDED);
+      tab.setAttribute('tabindex', '-1');
+      tab.setAttribute(ARIA_EXPANDED, 'false');
+      tabpanel.setAttribute('hidden', '');
+      tabpanel.setAttribute(ARIA_HIDDEN, 'true');
+    };
+
+    const enableTab = () => {
+      if(!tab.hasAttribute(ARIA_EXPANDED)) {
+        tab.setAttribute(ARIA_EXPANDED, 'false');
+      }
+
+      tab.setAttribute('tabindex', '0');
+
+      if(tab.getAttribute(ARIA_EXPANDED).toLowerCase() === 'true') {
+        panel.classList.add(IS_EXPANDED);
+        tabpanel.removeAttribute('hidden');
+        tabpanel.setAttribute(ARIA_HIDDEN, 'false');
+      }
+      else {
+        panel.classList.remove(IS_EXPANDED);
+        tabpanel.setAttribute('hidden', '');
+        tabpanel.setAttribute(ARIA_HIDDEN, 'true');
+      }
+    };
+
+    // In horizontal layout, caption must have a max-width defined to prevent pushing elements to the right of the caption out of view.
+    // In JsDom, offsetWidth and offsetHeight properties do not work, so this function is not testable.
+    /* istanbul ignore next */
+    const calcMaxTabCaptionWidth = () => {
+
+      const tabCaption = tab.querySelector(`.${TAB_CAPTION}`);
+      if(tabCaption !== null) {
+        const w = [...tab.children]
+          .filter( el => el.classList && !el.classList.contains(TAB_CAPTION) )
+          .reduce( (v, el) => v + el.offsetWidth, 0 );
+
+        const maxWidth = tab.clientHeight - w;
+        if(maxWidth > 0) {
+          tabCaption.style['max-width'] = `${maxWidth}px`;
+        }
+      }
+    };
+
+    const selectTab = () => {
+      if( !tab.hasAttribute(ARIA_SELECTED) ) {
+        [...this.element_.querySelectorAll(`.${TAB}[aria-selected="true"]`)].forEach(
+          selectedTab => selectedTab.removeAttribute(ARIA_SELECTED)
+        );
+        tab.setAttribute(ARIA_SELECTED, 'true');
+      }
+    };
+
+    const tabClickHandler = () => {
+      this.toggleTab_(panel, tab, tabpanel);
+      selectTab();
+    };
+
+    const tabFocusHandler = () => {
+      selectTab();
+    };
+
+    const tabpanelClickHandler = () => {
+      selectTab();
+    };
+
+    const tabpanelFocusHandler = () => {
+      selectTab();
+    };
+
+    const tabKeydownHandler = e => {
+
+      if(this.element_.hasAttribute('disabled')) {
+        return;
+      }
+
+      if ( e.keyCode === VK_END        || e.keyCode === VK_HOME
+        || e.keyCode === VK_ARROW_UP   || e.keyCode === VK_ARROW_LEFT
+        || e.keyCode === VK_ARROW_DOWN || e.keyCode === VK_ARROW_RIGHT ) {
+
+        let nextTab = null;
+        let keyCode = e.keyCode;
+
+        if (keyCode === VK_HOME) {
+          nextTab = this.element_.querySelector(`.${PANEL}:first-child > .${TAB}`);
+          if(nextTab && nextTab.hasAttribute('disabled')) {
+            nextTab = null;
+            keyCode = VK_ARROW_DOWN;
+          }
+        }
+        else if (keyCode === VK_END) {
+          nextTab = this.element_.querySelector(`.${PANEL}:last-child > .${TAB}`);
+          if(nextTab && nextTab.hasAttribute('disabled')) {
+            nextTab = null;
+            keyCode = VK_ARROW_UP;
+          }
+        }
+
+        if(!nextTab) {
+          let nextPanel = panel;
+
+          do {
+            if (keyCode === VK_ARROW_UP || keyCode === VK_ARROW_LEFT) {
+              nextPanel = nextPanel.previousElementSibling;
+              if(!nextPanel) {
+                nextPanel = this.element_.querySelector(`.${PANEL}:last-child`);
+              }
+              if (nextPanel) {
+                nextTab = nextPanel.querySelector(`.${PANEL} > .${TAB}`);
+              }
+            }
+            else if (keyCode === VK_ARROW_DOWN || keyCode === VK_ARROW_RIGHT) {
+              nextPanel = nextPanel.nextElementSibling;
+              if(!nextPanel) {
+                nextPanel = this.element_.querySelector(`.${PANEL}:first-child`);
+              }
+              if (nextPanel) {
+                nextTab = nextPanel.querySelector(`.${PANEL} > .${TAB}`);
+              }
+            }
+
+            if(nextTab && nextTab.hasAttribute('disabled')) {
+              nextTab = null;
+            }
+            else {
+              break;
+            }
+          }
+          while(nextPanel !== panel);
+        }
+
+        if (nextTab) {
+          e.preventDefault();
+          e.stopPropagation();
+          nextTab.focus();
+
+          // Workaround for JSDom testing:
+          // In JsDom 'element.focus()' does not trigger any focus event
+          if(!nextTab.hasAttribute(ARIA_SELECTED)) {
+
+            [...this.element_.querySelectorAll(`.${TAB}[aria-selected="true"]`)]
+              .forEach( selectedTab => selectedTab.removeAttribute(ARIA_SELECTED) );
+
+            nextTab.setAttribute(ARIA_SELECTED, 'true');
+          }
+        }
+      }
+      else if (e.keyCode === VK_ENTER || e.keyCode === VK_SPACE) {
+        e.preventDefault();
+        e.stopPropagation();
+        this.toggleTab_(panel, tab, tabpanel);
+      }
+    };
+
+    if(tab === null) {
+      throw new Error('There must be a tab element for each accordion panel.');
+    }
+
+    if(tabpanel === null) {
+      throw new Error('There must be a tabpanel element for each accordion panel.');
+    }
+
+    panel.setAttribute('role', PANEL_ROLE);
+    tab.setAttribute('role', TAB_ROLE);
+    tabpanel.setAttribute('role', TABPANEL_ROLE);
+
+    if(tab.hasAttribute('disabled')) {
+      disableTab();
+    }
+    else {
+      enableTab();
+    }
+
+    if( this.element_.classList.contains(ACCORDION_HORIZONTAL)) {
+      calcMaxTabCaptionWidth();
+    }
+
+    if (this.element_.classList.contains(RIPPLE_EFFECT)) {
+      tab.classList.add(RIPPLE);
+    }
+
+    if (this.element_.classList.contains(ANIMATION_EFFECT)) {
+      tabpanel.classList.add(ANIMATION);
+    }
+
+    // Remove listeners, just in case ...
+    tab.removeEventListener('click', tabClickHandler);
+    tab.removeEventListener('focus', tabFocusHandler);
+    tab.removeEventListener('keydown', tabKeydownHandler);
+    tabpanel.removeEventListener('click', tabpanelClickHandler);
+    tabpanel.removeEventListener('focus', tabpanelFocusHandler);
+
+    tab.addEventListener('click', tabClickHandler);
+    tab.addEventListener('focus', tabFocusHandler);
+    tab.addEventListener('keydown', tabKeydownHandler);
+    tabpanel.addEventListener('click', tabpanelClickHandler, true);
+    tabpanel.addEventListener('focus', tabpanelFocusHandler, true);
+  };
+  MaterialExtAccordion.prototype['upgradeTab'] = MaterialExtAccordion.prototype.upgradeTab;
+
+
+  /**
+   * Execute command
+   * @param detail
+   */
+  MaterialExtAccordion.prototype.command = function( detail ) {
+
+    const openTab = tabElement => {
+
+      if(tabElement === undefined) {
+        this.openTabs_();
+      }
+      else if(tabElement !== null) {
+        const { panel, tab, tabpanel } = accordionPanelElements( tabElement );
+        if(tab.getAttribute(ARIA_EXPANDED).toLowerCase() !== 'true') {
+          this.toggleTab_(panel, tab, tabpanel);
+        }
+      }
+    };
+
+    const closeTab = tabElement => {
+      if(tabElement === undefined) {
+        this.closeTabs_();
+      }
+      else if(tabElement !== null) {
+        const { panel, tab, tabpanel } = accordionPanelElements( tabElement );
+
+        if(tab.getAttribute(ARIA_EXPANDED).toLowerCase() === 'true') {
+          this.toggleTab_(panel, tab, tabpanel);
+        }
+      }
+    };
+
+    const toggleTab = tabElement => {
+      if(tabElement) {
+        const { panel, tab, tabpanel } = accordionPanelElements( tabElement );
+        this.toggleTab_(panel, tab, tabpanel);
+      }
+    };
+
+
+    if(detail && detail.action) {
+      const { action, target } = detail;
+
+      switch (action.toLowerCase()) {
+        case 'open':
+          openTab(target);
+          break;
+        case 'close':
+          closeTab(target);
+          break;
+        case 'toggle':
+          toggleTab(target);
+          break;
+        case 'upgrade':
+          if(target) {
+            this.upgradeTab(target);
+          }
+          break;
+        default:
+          throw new Error(`Unknown action "${action}". Action must be one of "open", "close", "toggle" or "upgrade"`);
+      }
+    }
+  };
+  MaterialExtAccordion.prototype['command'] = MaterialExtAccordion.prototype.command;
+
+
+  /**
+   * Initialize component
+   */
+  MaterialExtAccordion.prototype.init = function() {
+    if (this.element_) {
+      // Do the init required for this component to work
+      if( !(this.element_.classList.contains(ACCORDION_HORIZONTAL) || this.element_.classList.contains(ACCORDION_VERTICAL))) {
+        throw new Error(`Accordion must have one of the classes "${ACCORDION_HORIZONTAL}" or "${ACCORDION_VERTICAL}"`);
+      }
+
+      this.element_.setAttribute('role', 'tablist');
+
+      if(!this.element_.hasAttribute(ARIA_MULTISELECTABLE)) {
+        this.element_.setAttribute(ARIA_MULTISELECTABLE, 'false');
+      }
+
+      this.element_.removeEventListener('command', this.commandHandler_);
+      this.element_.addEventListener('command', this.commandHandler_.bind(this), false);
+
+      [...this.element_.querySelectorAll(`.${ACCORDION} > .${PANEL}`)].forEach( panel => this.upgradeTab(panel) );
+
+      // Set upgraded flag
+      this.element_.classList.add(IS_UPGRADED);
+    }
+  };
+
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   *
+   * Nothing to downgrade
+   *
+   MaterialExtAccordion.prototype.mdlDowngrade_ = function() {
+     'use strict';
+     console.log('***** MaterialExtAccordion.mdlDowngrade');
+   };
+   */
+
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtAccordion,
+    classAsString: 'MaterialExtAccordion',
+    cssClass: 'mdlext-js-accordion',
+    widget: true
+  });
+})();
