Project import generated by Copybara.

GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/node_modules/mdl-ext/src/collapsible/_collapsible.scss b/node_modules/mdl-ext/src/collapsible/_collapsible.scss
new file mode 100644
index 0000000..745676d
--- /dev/null
+++ b/node_modules/mdl-ext/src/collapsible/_collapsible.scss
@@ -0,0 +1,36 @@
+@charset "UTF-8";
+
+/**
+ * @license
+ * Copyright 2016-2017 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
+ */
+
+.mdlext-collapsible {
+  box-sizing: border-box;
+  cursor: pointer;
+}
+
+.mdlext-collapsible-group,
+.mdlext-collapsible-region {
+  box-sizing: border-box;
+
+  &[hidden] {
+    @include mdlext-visually-hidden;
+    pointer-events: none;
+  }
+}
diff --git a/node_modules/mdl-ext/src/collapsible/collapsible.js b/node_modules/mdl-ext/src/collapsible/collapsible.js
new file mode 100644
index 0000000..862fffb
--- /dev/null
+++ b/node_modules/mdl-ext/src/collapsible/collapsible.js
@@ -0,0 +1,437 @@
+/**
+ * @license
+ * Copyright 2016-2017 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 collapsible is a component to mark expandable and collapsible regions.
+ * The component use the aria-expanded state to indicate whether regions of
+ * the content are collapsible, and to expose whether a region is currently
+ * expanded or collapsed.
+ * @see https://www.w3.org/WAI/GL/wiki/Using_the_WAI-ARIA_aria-expanded_state_to_mark_expandable_and_collapsible_regions
+ */
+
+import {
+  IS_UPGRADED,
+  VK_SPACE,
+  VK_ENTER,
+} from '../utils/constants';
+
+import { randomString } from '../utils/string-utils';
+import { getParentElements, isFocusable } from '../utils/dom-utils';
+
+const JS_COLLAPSIBLE = 'mdlext-js-collapsible';
+const COLLAPSIBLE_CONTROL_CLASS = 'mdlext-collapsible';
+const COLLAPSIBLE_GROUP_CLASS = 'mdlext-collapsible-group';
+const COLLAPSIBLE_REGION_CLASS = 'mdlext-collapsible-region';
+
+/**
+ * The collapsible component
+ */
+
+class Collapsible {
+  element_ = null;
+  controlElement_ = null;
+
+  /**
+   * @constructor
+   * @param {HTMLElement} element The element that this component is connected to.
+   */
+  constructor(element) {
+    this.element_ = element;
+    this.init();
+  }
+
+  keyDownHandler = event => {
+    if (event.keyCode === VK_ENTER || event.keyCode === VK_SPACE) {
+      event.preventDefault();
+
+      // Trigger click
+      (event.target || this.controlElement).dispatchEvent(
+        new MouseEvent('click', {
+          bubbles: true,
+          cancelable: true,
+          view: window
+        })
+      );
+    }
+  };
+
+  clickHandler = event => {
+    if(!this.isDisabled) {
+      if(event.target !== this.controlElement) {
+        // Do not toggle if a focusable element inside the control element triggered the event
+        const p = getParentElements(event.target, this.controlElement);
+        p.push(event.target);
+        if(p.find( el => isFocusable(el))) {
+          return;
+        }
+      }
+      this.toggle();
+    }
+  };
+
+  get element() {
+    return this.element_;
+  }
+
+  get controlElement() {
+    return this.controlElement_;
+  }
+
+  get isDisabled() {
+    return (this.controlElement.hasAttribute('disabled') &&
+      this.controlElement.getAttribute('disabled').toLowerCase() !== 'false') ||
+      (this.controlElement.hasAttribute('aria-disabled') &&
+      this.controlElement.getAttribute('aria-disabled').toLowerCase() !== 'false');
+  }
+
+  get isExpanded() {
+    return this.controlElement.hasAttribute('aria-expanded') &&
+      this.controlElement.getAttribute('aria-expanded').toLowerCase() === 'true';
+  }
+
+  get regionIds() {
+    return this.controlElement.hasAttribute('aria-controls')
+      ? this.controlElement.getAttribute('aria-controls').split(' ')
+      : [];
+  }
+
+  get regionElements() {
+    return this.regionIds
+      .map(id => document.querySelector(`#${id}`))
+      .filter( el => el != null);
+  }
+
+  collapse() {
+    if(!this.isDisabled && this.isExpanded) {
+      if(this.dispatchToggleEvent('collapse')) {
+        this.controlElement.setAttribute('aria-expanded', 'false');
+        const regions = this.regionElements.slice(0);
+        for (let i = regions.length - 1; i >= 0; --i) {
+          regions[i].setAttribute('hidden', '');
+        }
+      }
+    }
+  }
+
+  expand() {
+    if(!this.isDisabled && !this.isExpanded) {
+      if(this.dispatchToggleEvent('expand')) {
+        this.controlElement.setAttribute('aria-expanded', 'true');
+        this.regionElements.forEach(region => region.removeAttribute('hidden'));
+      }
+    }
+  }
+
+  toggle() {
+    if (this.isExpanded) {
+      this.collapse();
+    }
+    else {
+      this.expand();
+    }
+  }
+
+  dispatchToggleEvent(action) {
+    return this.element.dispatchEvent(
+      new CustomEvent('toggle', {
+        bubbles: true,
+        cancelable: true,
+        detail: {
+          action: action
+        }
+      })
+    );
+  }
+
+  disableToggle() {
+    this.controlElement.setAttribute('aria-disabled', true);
+  }
+
+  enableToggle() {
+    this.controlElement.removeAttribute('aria-disabled');
+  }
+
+  addRegionId(regionId) {
+    const ids = this.regionIds;
+    if(!ids.find(id => regionId === id)) {
+      ids.push(regionId);
+      this.controlElement.setAttribute('aria-controls', ids.join(' '));
+    }
+  }
+
+  addRegionElement(region) {
+    if(!(region.classList.contains(COLLAPSIBLE_GROUP_CLASS) ||
+      region.classList.contains(COLLAPSIBLE_REGION_CLASS))) {
+      region.classList.add(COLLAPSIBLE_GROUP_CLASS);
+    }
+
+    if(!region.hasAttribute('role')) {
+      const role = region.classList.contains(COLLAPSIBLE_GROUP_CLASS) ? 'group' : 'region';
+      region.setAttribute('role', role);
+    }
+
+    if(!region.hasAttribute('id')) {
+      region.id = `${region.getAttribute('role')}-${randomString()}`;
+    }
+
+    if(this.isExpanded) {
+      region.removeAttribute('hidden');
+    }
+    else {
+      region.setAttribute('hidden', '');
+    }
+    this.addRegionId(region.id);
+  }
+
+  removeRegionElement(region) {
+    if(region && region.id) {
+      const ids = this.regionIds.filter(id => id === region.id);
+      this.controlElement.setAttribute('aria-controls', ids.join(' '));
+    }
+  }
+
+  removeListeners() {
+    this.controlElement.removeEventListener('keydown', this.keyDownHandler);
+    this.controlElement.removeEventListener('click', this.clickHandler);
+  }
+
+  init() {
+    const initControl = () => {
+      // Find the button element
+      this.controlElement_ = this.element.querySelector(`.${COLLAPSIBLE_CONTROL_CLASS}`) || this.element;
+
+      // Add "aria-expanded" attribute if not present
+      if(!this.controlElement.hasAttribute('aria-expanded')) {
+        this.controlElement.setAttribute('aria-expanded', 'false');
+      }
+
+      // Add role=button if control != <button>
+      if(this.controlElement.nodeName.toLowerCase() !== 'button') {
+        this.controlElement.setAttribute('role', 'button');
+      }
+
+      // Add tabindex
+      if(!isFocusable(this.controlElement) && !this.controlElement.hasAttribute('tabindex')) {
+        this.controlElement.setAttribute('tabindex', '0');
+      }
+    };
+
+    const initRegions = () => {
+      let regions = [];
+      if(!this.controlElement.hasAttribute('aria-controls')) {
+        // Add siblings as collapsible region(s)
+        let r = this.element.nextElementSibling;
+        while(r) {
+          if(r.classList.contains(COLLAPSIBLE_GROUP_CLASS) ||
+            r.classList.contains(COLLAPSIBLE_REGION_CLASS)) {
+            regions.push(r);
+          }
+          else if(r.classList.contains(JS_COLLAPSIBLE)) {
+            // A new collapsible component
+            break;
+          }
+          r = r.nextElementSibling;
+        }
+      }
+      else {
+        regions = this.regionElements;
+      }
+      regions.forEach(region => this.addRegionElement(region));
+    };
+
+    const addListeners = () => {
+      this.controlElement.addEventListener('keydown', this.keyDownHandler);
+      this.controlElement.addEventListener('click', this.clickHandler);
+    };
+
+    initControl();
+    initRegions();
+    this.removeListeners();
+    addListeners();
+  }
+
+  downgrade() {
+    this.removeListeners();
+  }
+
+}
+
+(function() {
+  'use strict';
+
+  /**
+   * @constructor
+   * @param {HTMLElement} element The element that will be upgraded.
+   */
+  const MaterialExtCollapsible = function MaterialExtCollapsible(element) {
+    this.element_ = element;
+    this.collapsible = null;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtCollapsible'] = MaterialExtCollapsible;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtCollapsible.prototype.init = function() {
+    if (this.element_) {
+      this.collapsible = new Collapsible(this.element_);
+      this.element_.classList.add(IS_UPGRADED);
+
+      // Listen to 'mdl-componentdowngraded' event
+      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
+    }
+  };
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   */
+  MaterialExtCollapsible.prototype.mdlDowngrade_ = function() {
+    this.collapsible.downgrade();
+  };
+
+
+  // Public methods.
+
+  /**
+   * Get control element.
+   * @return {HTMLElement} element The element that controls the collapsible region.
+   * @public
+   */
+  MaterialExtCollapsible.prototype.getControlElement = function() {
+    return this.collapsible.controlElement;
+  };
+  MaterialExtCollapsible.prototype['getControlElement'] = MaterialExtCollapsible.prototype.getControlElement;
+
+  /**
+   * Get region elements controlled by this collapsible
+   * @returns {Array<HTMLElement>} the collapsible region elements
+   * @public
+   */
+  MaterialExtCollapsible.prototype.getRegionElements = function() {
+    return this.collapsible.regionElements;
+  };
+  MaterialExtCollapsible.prototype['getRegionElements'] = MaterialExtCollapsible.prototype.getRegionElements;
+
+  /**
+   * Add region elements.
+   * @param {Array<HTMLElement>} elements The element that will be upgraded.
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.addRegionElements = function(...elements) {
+    elements.forEach(element => this.collapsible.addRegionElement(element));
+  };
+  MaterialExtCollapsible.prototype['addRegionElements'] = MaterialExtCollapsible.prototype.addRegionElements;
+
+  /**
+   * Remove collapsible region(s) from component.
+   * Note: This operation does not delete the element from the DOM tree.
+   * @param {Array<HTMLElement>} elements The element that will be upgraded.
+   * @public
+   */
+  MaterialExtCollapsible.prototype.removeRegionElements = function(...elements) {
+    elements.forEach(element => this.collapsible.removeRegionElement(element));
+  };
+  MaterialExtCollapsible.prototype['removeRegionElements'] = MaterialExtCollapsible.prototype.removeRegionElements;
+
+  /**
+   * Expand collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.expand = function() {
+    this.collapsible.expand();
+  };
+  MaterialExtCollapsible.prototype['expand'] = MaterialExtCollapsible.prototype.expand;
+
+  /**
+   * Collapse collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.collapse = function() {
+    this.collapsible.collapse();
+  };
+  MaterialExtCollapsible.prototype['collapse'] = MaterialExtCollapsible.prototype.collapse;
+
+  /**
+   * Toggle collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.toggle = function() {
+    this.collapsible.toggle();
+  };
+  MaterialExtCollapsible.prototype['toggle'] = MaterialExtCollapsible.prototype.toggle;
+
+  /**
+   * Check whether component has aria-expanded state true
+   * @return {Boolean} true if aria-expanded="true", otherwise false
+   */
+  MaterialExtCollapsible.prototype.isExpanded = function() {
+    return this.collapsible.isExpanded;
+  };
+  MaterialExtCollapsible.prototype['isExpanded'] = MaterialExtCollapsible.prototype.isExpanded;
+
+  /**
+   * Check whether component has aria-disabled state set to true
+   * @return {Boolean} true if aria-disabled="true", otherwise false
+   */
+  MaterialExtCollapsible.prototype.isDisabled = function() {
+    return this.collapsible.isDisabled;
+  };
+  MaterialExtCollapsible.prototype['isDisabled'] = MaterialExtCollapsible.prototype.isDisabled;
+
+  /**
+   * Disables toggling of collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.disableToggle = function() {
+    this.collapsible.disableToggle();
+  };
+  MaterialExtCollapsible.prototype['disableToggle'] = MaterialExtCollapsible.prototype.disableToggle;
+
+  /**
+   * Enables toggling of collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.enableToggle = function() {
+    this.collapsible.enableToggle();
+  };
+  MaterialExtCollapsible.prototype['enableToggle'] = MaterialExtCollapsible.prototype.enableToggle;
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtCollapsible,
+    classAsString: 'MaterialExtCollapsible',
+    cssClass: JS_COLLAPSIBLE,
+    widget: true
+  });
+
+})();
diff --git a/node_modules/mdl-ext/src/collapsible/readme.md b/node_modules/mdl-ext/src/collapsible/readme.md
new file mode 100644
index 0000000..553e48a
--- /dev/null
+++ b/node_modules/mdl-ext/src/collapsible/readme.md
@@ -0,0 +1,467 @@
+# Collapsible
+
+**Collapsed**
+
+![Collapsible collapsed](../../etc/collapsible-collapsed.jpg)
+
+**Expanded**
+
+![Collapsible expanded](../../etc/collapsible-expanded.jpg)
+
+A collapsible is a component to mark expandable and collapsible regions. It has 
+states, roles, attributes and behaviour in accordance with guidelines given in 
+[Using the WAI-ARIA aria-expanded state to mark expandable and collapsible regions](https://www.w3.org/WAI/GL/wiki/Using_the_WAI-ARIA_aria-expanded_state_to_mark_expandable_and_collapsible_regions),
+[ARIA Authoring Practices, Button](https://www.w3.org/TR/wai-aria-practices-1.1/#button), 
+and [Building Accessible Buttons with ARIA: A11y](http://www.deque.com/blog/accessible-aria-buttons/)
+
+## Collapse All the Things
+The collapsible acts as a "pluggable" component. It uses a `<button>` element or 
+an element with `role="button"` to control one or more collapsible regions. You 
+can make virtually any HTML element collapsible by adding two classes, 
+`mdlext-js-collapsible` to the element that should control the collapsible 
+region(s), and one of the classes `mdlext-collapsible-group` or 
+`mdlext-collapsible-region` to the element that should collapse/expand. The 
+collapsible component uses the 
+[aria-controls](https://www.w3.org/TR/wai-aria/states_and_properties#aria-controls) 
+property to hold a list of one or more collapsible regions. The 
+[aria-expanded](https://www.w3.org/TR/wai-aria/states_and_properties#aria-expanded) 
+state indicates whether region(s) controlled by the component is currently 
+expanded or collapsed.
+
+## To include a MDLEXT collapsible component:
+&nbsp;1. Code a `<button>` element; this is the clickable toggle that will show and hide the collapsible 
+region(s). Inside the button, code a `<span>` element to hold the button caption text.
+
+```html
+<button>
+  <span>Click to toggle</span>
+</button>
+```
+
+&nbsp;2. Add the `mdlext-js-collapsible` class to define the element as a collapsible component.
+
+```html
+<button class="mdlext-js-collapsible">
+  <span>Click to toggle</span>
+</button>
+```
+
+&nbsp;3. Optionally add the `mdlext-collapsible` class, which will add a pointer 
+cursor to the collapsible component.
+
+```html
+<button class="mdlext-js-collapsible mdlext-collapsible">
+  <span>Click to toggle</span>
+</button>
+```
+
+&nbsp;4. Optionally add a state icon. Code a `<i>` element with class 
+`mdlext-aria-expanded-more-less`. The state icon should indicate whether the 
+collapsible region is expanded or not.
+
+```html
+<button class="mdlext-js-collapsible">
+  <span>Click to toggle</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</button>
+```
+
+&nbsp;5. Code a `<div>` element with class `mdlext-collapsible-group` or
+`mdlext-collapsible-region` to define the element as a collapsible region. 
+
+```html
+<div class="mdlext-collapsible-group">
+</div>
+```
+
+&nbsp;6. Add content inside the collapsible container. 
+
+```html
+<div class="mdlext-collapsible-group">
+  <p>Content goes here ...</p>
+</div>
+```
+
+After page load, the component will add all required Aria states, roles and 
+attributes not already present in markup. 
+
+```html
+<button class="mdlext-js-collapsible is-upgraded" 
+  data-upgraded=",MaterialExtCollapsible" 
+  aria-expanded="false" aria-controls="group-4ek31z6jeeag">
+  <span>Click to toggle</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</button>
+<div class="mdlext-collapsible-group" id="group-4ek31z6jeeag" role="group" hidden>
+  <p>Content goes here ...</p>
+</div>
+```
+
+Instead of letting the collapsible component add all the WAI-ARIA stuff, 
+add it yourself in markup. The component will not override attributes already 
+present in markup.
+
+```html
+<div class="mdlext-js-collapsible" role="button" 
+  aria-expanded="false" aria-controls="group-1">
+  <span>Click to toggle</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</div>
+<div class="mdlext-collapsible-group" id="group-1" role="group" hidden>
+  <p>Content Region #1 goes here ...</p>
+</div>
+```
+
+### role="group" vs role="region"
+The group role is used to identify a set of user interface objects which, in 
+contrast with a region, are not intended to be included in a table of contents 
+or a page summary (such as the structures that are dynamically created by a 
+script or assistive technologies); a group should not be considered a major 
+perceivable section on a page. When the role is added to an element, the browser 
+will send out an accessible group event to assistive technology products which 
+can then notify the user about it.
+
+To define an element as collapsible add one of the classes  
+`mdlext-collapsible-group` or `mdlext-collapsible-region`. The component will
+set the role attribute to `group` or `region` accordingly.
+
+[Group](https://www.w3.org/TR/wai-aria/roles#group): A set of user interface
+objects which are not intended to be included in a page summary or table of 
+contents by assistive technologies.
+
+[Region](https://www.w3.org/TR/wai-aria/roles#region): A large perceivable 
+section of a web page or document, that is important enough to be included in a 
+page summary or table of contents, for example, an area of the page containing 
+live sporting event statistics. 
+
+### Use a `<div>` element as a collapsible component.
+It's easier to style a div compared to a button. For example, you can not style 
+a button as a flexible box! 
+ 
+```html
+<div class="mdlext-js-collapsible mdlext-collapsible" aria-expanded="true">
+  <span>Click to toggle</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</div>
+<div class="mdlext-collapsible-region">
+  <p>Content goes here ...</p>
+</div>
+```
+
+For further control with styling, it is possible to wrap the button element 
+inside the collapsible component. The wrapped element becomes the clickable/focusable
+area and **must** have class `mdlext-collapsible` applied.
+
+```html
+<header class="mdlext-js-collapsible" aria-expanded="true">
+  <div class="mdlext-collapsible"> 
+    <span>Click to toggle</span>
+    <i class="mdlext-aria-expanded-more-less"></i>
+  </div>  
+</header>
+<div class="mdlext-collapsible-region">
+  <p>Content goes here ...</p>
+</div>
+```
+
+### one-to-many
+You can create a one-to-many relationship by supplying a space separated list of 
+ids, representing different, simultaneously controlled elements.
+
+```html
+<div class="medext-js-collapsible">
+  <div class="mdlext-collapsible" role="button" 
+    aria-controls="collapsible-1 collapsible-3">A topic</div>
+</div>
+
+<div id="collapsible-1" class="mdlext-collapsible-group">
+  <p>Topic 1 is all about being Topic 1 and may or 
+  may not have anything to do with other topics.</p>
+</div>
+
+<div id="collapsible-2" class="mdlext-collapsible-group">
+  <p>Topic 2 is all about being Topic 2 and may or 
+  may not have anything to do with other topics.</p>
+</div>
+
+<div id="collapsible-3" class="mdlext-collapsible-group">
+  <p>Topic 3 is all about being Topic 3 and may or 
+  may not have anything to do with other topics.</p>
+</div>
+```
+
+If the `aria-controls` attribute is provided in markup, the component will not 
+attempt to determine corresponding collapsible regions. In the markup above,
+only `collapsible-1` and `collapsible-3` will be controlled by the component.
+
+Remove the `aria-controls` attribute if you want the component to determine the 
+collapsible regions to be included.
+
+### Examples
+
+**Collapsibles, with many collapsible regions.**
+
+```html
+<!-- first collapsible -->
+<button class="mdlext-js-collapsible mdlext-collapsible">
+  <span>Click to toggle collapsible #1</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</button>
+<div class="mdlext-collapsible-region">
+  <p>#1.1</p>
+</div>
+<div class="mdlext-collapsible-region">
+  <p>#1.2</p>
+</div>
+
+<!-- second collapsible -->
+<header class="mdlext-js-collapsible mdlext-collapsible">
+  <span>Click to toggle collapsible #2</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</header>
+<div class="mdlext-collapsible-region">
+  <p>#2.1</p>
+</div>
+
+<p>This paragraph will not collapse</p>
+
+<div class="mdlext-collapsible-region">
+  <p>#2.2</p>
+</div>
+<div class="mdlext-collapsible-region">
+  <p>#2.3</p>
+</div>
+```
+
+**Nested collapsibles.**
+
+```html
+<style>
+  .mdlext-collapsible-region .mdlext-js-collapsible,
+  .mdlext-collapsible-region .mdlext-collapsible-region {
+    margin-left: 16px;
+  }
+</style>
+
+<button class="mdlext-js-collapsible mdl-button mdl-button--colored mdl-button--raised">
+  Click to toggle
+</button>
+<div class="mdlext-collapsible-region">
+  <p>A collapsible region</p>
+
+  <button class="mdlext-js-collapsible mdl-button mdl-button--accent mdl-button--raised">
+    Click to toggle nested #1
+  </button>
+  <div class="mdlext-collapsible-region">
+    <p>A nested collapsible region</p>
+
+    <button class="mdlext-js-collapsible mdl-button mdl-button--raised 
+      mdl-button--colored mdl-color--deep-orange-100">
+      Click to toggle nested #2
+    </button>
+    <div class="mdlext-collapsible-region">
+      <p>Last region</p>
+    </div>
+  </div>
+</div>
+```
+
+**Collapsible MDL Card.**
+
+```html
+<!-- The card need some styling to act as a collapsible -->
+<style>
+  .mdl-card.welcome-card {
+    min-height: 0;
+    max-width: 640px;
+    width: auto;
+  }
+  .mdl-card.welcome-card > .mdl-card__title {
+    -webkit-box-pack: start;
+    -webkit-justify-content: flex-start;
+    -ms-flex-pack: start;
+    justify-content: flex-start;
+    height: 176px;
+    min-height: 64px;
+    padding-top: 0;
+    padding-bottom: 0;
+    color: #fff;
+    background: url('./assets/welcome_card.jpg') top / cover;
+  }
+  .mdl-card.welcome-card .mdl-card__title:focus {
+    /* Must focus ring must be inside title since mdl-card has overflow:hidden */
+    outline-offset: -4px;
+  }
+  .mdl-card.welcome-card .mdl-card__title > * {
+    -webkit-align-self: center;
+    -ms-flex-item-align: center;
+    align-self: center;
+  }
+  .mdl-card.welcome-card .mdl-card__supporting-text {
+    width: auto;
+  }
+  .mdl-card.welcome-card .mdl-card__actions {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+  }
+  .welcome-card > .mdl-card__title .mdl-card__title-text {
+    -webkit-align-self: flex-end;
+    -ms-flex-item-align: end;
+    align-self: flex-end;
+    padding-bottom: 16px;
+  }
+  .welcome-card > .mdl-card__title[aria-expanded='false'] {
+    height: 64px;
+  }
+  .welcome-card > .mdl-card__title[aria-expanded='false'] .mdl-card__title-text {
+    -webkit-align-self: center;
+    -ms-flex-item-align: center;
+    align-self: center;
+    padding-bottom: 0;
+  }
+  .welcome-card > .mdl-card__menu {
+    color: #ffffff;
+  }
+</style>
+
+<div class="welcome-card mdl-card mdl-shadow--2dp">
+  <header class="mdl-card__title mdlext-js-collapsible mdlext-collapsible">
+    <h2 class="mdl-card__title-text">A Collapsible Card</h2>
+  </header>
+  <section class="mdl-card__supporting-text mdlext-collapsible-region">
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+    Mauris sagittis pellentesque lacus eleifend lacinia...
+  </section>
+  <footer class="mdl-card__actions mdl-card--border mdlext-collapsible-region">
+    <button class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
+      Get Started
+    </button>
+  </footer>
+  <div class="mdl-card__menu">
+    <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+      <i class="material-icons">share</i>
+    </button>
+  </div>
+</div>
+```
+
+**Create your own state icon with SASS.**
+
+The [_mixins.scss](../_mixins.scss) has a mixin which can be used to create custom state icons.  
+
+```sass
+@charset "UTF-8";
+.my-aria-expanded-state {
+  @include mdlext-aria-expanded-toggle($icon: 'arrow_downward', $icon-expanded: 'arrow_upward');
+}
+```
+
+### More examples
+* The [snippets/collapsible.html](./snippets/collapsible.html) and the [tests](../../test/collapsible/collapsible.spec.js) provides more detailed examples.
+* Try out the [live demo](http://leifoolsen.github.io/mdl-ext/demo/collapsible.html)
+
+## Characteristics
+
+### Keyboard interaction 
+* <kbd>Space</kbd> or <kbd>Enter</kbd>: toggle the corresponding collapsible region(s).
+
+### Mouse interaction 
+* <kbd>Click</kbd>: toggle the corresponding collapsible region(s).
+    
+## Events
+The collapsible component emits a custom `toggle` event when the component is clicked, 
+<kbd>Enter</kbd> key or <kbd>Space</kbd> key is pressed or one of the methods `expand`. 
+`collapse` or `toggle` is called. The event is emitted before the actual toggling 
+occurs. Call `event.preventDefault()` to cancel toggling.
+
+The detail object parameter has the following structure:
+```javascript
+detail: {
+  action // 'expand' or collapse'  
+}
+```
+Set up an event listener to receive the toggle event.
+```javascript
+var someCondition = false;
+document.querySelector('#my-collapsible').addEventListener('toggle', function(e) {
+  console.log('Toggle action:', e.detail.action);
+  if(someCondition) {
+    // Stop toggling
+    e.preventDefault();
+  }
+  someCondition = !someCondition;
+});
+```
+
+## Public methods
+
+### getControlElement()
+Get the element that controls the collapsible region(s).
+
+### getRegionElements()
+Get region elements controlled by this collapsible.
+
+### addRegionElements(...elements)
+Add collapsible region(s).
+
+### removeRegionElements(...elements)
+Remove collapsible region(s).
+
+### expand()
+Expand corresponding collapsible region(s).
+
+### collapse()
+Collapse corresponding collapsible region(s).
+
+### toggle()
+Toggle corresponding collapsible region(s).
+```javascript
+const component = document.querySelector('#my-collapsible');
+component.MaterialExtCollapsible.toggle();
+```
+### isExpanded()
+Check whether component has aria-expanded state set to true.
+
+### isDisabled()
+Check whether component has aria-disabled state set to true.
+
+### enableToggle()
+Enables toggling of collapsible region(s).
+
+### disableToggle()
+Disables toggling of collapsible region(s).
+
+## Configuration options
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to the accordion. 
+
+### Available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|--------------|--------|---------|
+|`mdlext-js-collapsible`| Assigns basic MDL behavior to collapsible. | Required. |
+|`mdlext-collapsible`| Defines container as an MDL component. | Optional. |
+|`mdlext-collapsible-group`| Defines container as a collapsible group. | Required. Either `mdlext-collapsible-group` or `mdlext-collapsible-region` must be present to make a container collapsible. |
+|`mdlext-collapsible-region`| Defines container as a collapsible region. | Required. |
+
+### Available WAI-ARIA roles, states, and properties
+
+| Attribute | Description | Remarks |
+|-----------|-------------|---------|
+|`role="button`| The element that toggles a region has role [button](http://www.w3.org/TR/wai-aria-1.1/#button). | Added by component if not present |
+|`tabindex`| Indicates whether an element is focusable. | A value less than 0, e.g. -1, indicates that the element is not focusable. Tabindex="0" added by component if not present |
+|`aria-controls`| Identfies the content on the page, using IDREFs, that this collapsible controls. | Added by component if not present. |
+|`aria-expanded`| The element with role `button` has [aria-expanded](https://www.w3.org/TR/wai-aria-1.1/#aria-expanded) set to `true` if the corresponding region(s) is open, oterwise false. | Defaults to `aria-expanded="false"`. Set `aria-expanded="true"` if you want a region to open during page load. |
+|`aria-disabled`| When a collapsible should not be toggable, set `aria-disabled` to `true`. | Optional. If this attribute is present, the collapsible region(s) will not toggle. |
+|`disabled`| Indicates that a collapsible component and it's corresponding region(s) is disabled, otherwise not present. | Optional. If this attribute is present, the collapsible regions will not toggle. |
+|`role="group`| Identifies an element as a collapsible [group](https://www.w3.org/TR/wai-aria/roles#group). | Required on container with class `mdlext-collapsible-group`. Added by component if not present. |
+|`role="region`| Identifies an element as a collapsible [region](https://www.w3.org/TR/wai-aria/roles#region). | Required on container with class `mdlext-collapsible-region`. Added by component if not present. |
+|`hidden`| Visually hides a collapsible region. | Added by component if component has `aria-expanded="false"`. |
+|`id`| The collapsible region must have an id. | A random id is added if not present. The IDREF is used by the `aria-controls` attribute to identify the collapsible region. |
+
+## Other collapsible examples
+* [ARIA Examples, Progressive collapsibles](http://heydonworks.com/practical_aria_examples/#progressive-collapsibles)
+* [Open Ajax, Example 20 - Hide/Show: Region follows button](http://oaa-accessibility.org/example/20/)
+* [Open Ajax, Example 21 - Hide/Show: Region does not follow button](http://oaa-accessibility.org/example/21/)
+* [Open Ajax, Example 22 - Hide/Show: Region is exclusive](http://oaa-accessibility.org/example/22/)
diff --git a/node_modules/mdl-ext/src/collapsible/snippets/collapsible.html b/node_modules/mdl-ext/src/collapsible/snippets/collapsible.html
new file mode 100644
index 0000000..f959654
--- /dev/null
+++ b/node_modules/mdl-ext/src/collapsible/snippets/collapsible.html
@@ -0,0 +1,237 @@
+<p>A collapsible is a component to mark expandable and collapsible regions.
+  It has states, roles, attributes and behavior in accordance with guidelines given in
+  <a href="https://www.w3.org/WAI/GL/wiki/Using_the_WAI-ARIA_aria-expanded_state_to_mark_expandable_and_collapsible_regions">
+    Using the WAI-ARIA aria-expanded state to mark expandable and collapsible regions
+  </a>.
+</p>
+<article>
+  <button class="mdlext-js-collapsible" style="padding: 8px;">
+    <span>Click to toggle (button)</span>
+    <i class="mdlext-aria-expanded-more-less"></i>
+  </button>
+  <div class="mdlext-collapsible-group"><p>A collapsible region #1.1</p></div>
+  <div class="mdlext-collapsible-group"><p>A collapsible region #1.2</p></div>
+  <div class="mdlext-collapsible-group"><p>A collapsible region #1.3</p></div>
+</article>
+
+<article style="margin-top: 16px;">
+  <div class="mdlext-js-collapsible mdlext-collapsible" style="padding: 8px;">
+    <span>Click to toggle (div)</span>
+    <i class="mdlext-aria-expanded-more-less"></i>
+  </div>
+  <div class="mdlext-collapsible-region"><p>A collapsible region #2.1</p></div>
+  <div class="mdlext-collapsible-region"><p>A collapsible region #2.2</p></div>
+  <div class="mdlext-collapsible-region"><p>A collapsible region #2.3</p></div>
+</article>
+
+
+<style>
+  .mdl-card.demo-card,
+  .mdl-card.welcome-card {
+    min-height: 0;
+    width: auto;
+    margin-top: 16px;
+    margin-bottom: 16px;
+    max-width: 640px;
+  }
+  .mdl-card.demo-card .mdl-card__media,
+  .mdl-card.welcome-card .mdl-card__media {
+    margin: 0;
+    text-align: center;
+  }
+  .mdl-card.demo-card .mdl-card__media > img,
+  .mdl-card.welcome-card .mdl-card__media > img {
+    max-width: 100%;
+    height: auto;
+  }
+  .mdl-card.demo-card .mdl-card__title,
+  .mdl-card.welcome-card .mdl-card__title {
+    /* Fix bug in _card.scss */
+    -webkit-box-pack: start;
+    -webkit-justify-content: flex-start;
+    -ms-flex-pack: start;
+    justify-content: flex-start;
+    /* end fix */
+
+    padding-top: 0;
+    padding-bottom: 0;
+    min-height: 64px;
+  }
+  .mdl-card.demo-card .mdl-card__title:focus,
+  .mdl-card.welcome-card .mdl-card__title:focus {
+    /* Must focus ring must be inside title since mdl-card has overflow:hidden */
+    outline-offset: -4px;
+  }
+  .mdl-card.demo-card .mdl-card__title > *,
+  .mdl-card.welcome-card .mdl-card__title > * {
+    -webkit-align-self: center;
+    -ms-flex-item-align: center;
+    align-self: center;
+  }
+  .mdl-card.demo-card .mdl-card__supporting-text,
+  .mdl-card.welcome-card .mdl-card__supporting-text {
+    width: auto;
+  }
+  .mdl-card.demo-card .mdl-card__actions,
+  .mdl-card.welcome-card .mdl-card__actions {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+  }
+  .welcome-card > .mdl-card__title {
+    color: #fff;
+    height: 176px;
+    background: url('./assets/welcome_card.jpg') top / cover;
+  }
+  .welcome-card > .mdl-card__title[aria-expanded='false'] {
+    height: 64px;
+  }
+  .welcome-card > .mdl-card__title .mdl-card__title-text {
+    -webkit-align-self: flex-end;
+    -ms-flex-item-align: end;
+    align-self: flex-end;
+    padding-bottom: 16px;
+  }
+  .welcome-card > .mdl-card__title[aria-expanded='false'] .mdl-card__title-text {
+    -webkit-align-self: center;
+    -ms-flex-item-align: center;
+    align-self: center;
+    padding-bottom: 0;
+  }
+  .welcome-card > .mdl-card__menu {
+    color: #fff;
+  }
+
+  table.info {
+    width: 100%
+  }
+  table.info th {
+    padding-right: 40px;
+    vertical-align: middle;
+    text-align: left;
+    width: 120px;
+  }
+</style>
+
+<div class="welcome-card mdl-card mdl-shadow--2dp">
+  <header class="mdl-card__title mdlext-js-collapsible mdlext-collapsible" aria-expanded="true">
+    <h2 class="mdl-card__title-text">A Collapsible Card</h2>
+  </header>
+  <section class="mdl-card__supporting-text mdlext-collapsible-group">
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+    Mauris sagittis pellentesque lacus eleifend lacinia...
+  </section>
+  <footer class="mdl-card__actions mdl-card--border mdlext-collapsible-group">
+    <button class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
+      Get Started
+    </button>
+  </footer>
+  <div class="mdl-card__menu">
+    <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+      <i class="material-icons">share</i>
+    </button>
+  </div>
+</div>
+
+
+<style>
+  .mdlext-collapsible-group .mdlext-js-collapsible,
+  .mdlext-collapsible-group .mdlext-collapsible-group {
+    margin-left: 16px;
+  }
+</style>
+
+<button class="mdlext-js-collapsible mdl-button mdl-button--colored mdl-button--raised">Click to toggle</button>
+<div class="mdlext-collapsible-group">
+  <p>A collapsible region</p>
+
+  <button class="mdlext-js-collapsible mdl-button mdl-button--accent mdl-button--raised">Click to toggle nested #1</button>
+  <div class="mdlext-collapsible-group">
+    <p>A nested collapsible region</p>
+
+    <button class="mdlext-js-collapsible mdl-button mdl-button--colored mdl-color--deep-orange-100 mdl-button--raised">Click to toggle nested #2</button>
+    <div class="mdlext-collapsible-group">
+      <p>Last region</p>
+    </div>
+  </div>
+</div>
+
+
+<div id="another-card" class="mdl-card demo-card mdl-shadow--2dp mdlext-dark-color-theme">
+  <header class="mdl-card__title mdl-color--primary mdl-color-text--primary-contrast mdlext-js-collapsible mdlext-collapsible">
+    <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+      <i class="material-icons">view_headline</i>
+    </button>
+    <h2 class="mdl-card__title-text">Another collapsible card</h2>
+    <div class="mdl-layout-spacer"></div>
+    <i class="material-icons md-36 mdlext-aria-expanded-more-less"></i>
+  </header>
+  <figure class="mdl-card__media mdlext-collapsible-region">
+    <img src="./images/_DSC7535-2.jpg" alt="">
+  </figure>
+  <section style="margin-top:16px" class="mdl-card__supporting-text mdlext-collapsible-region">
+    <table class="info">
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+        <td class="mdl-color--primary-dark mdl-color-text--primary-contrast">primary dark</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary</th>
+        <td class="mdl-color--primary mdl-color-text--primary-contrast">primary</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">accent</th>
+        <td class="mdl-color--accent mdl-color-text--accent-contrast">accent</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+        <td class="mdl-color--primary-contrast mdl-color-text--primary-dark">primary dark, inverted</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary</th>
+        <td class="mdl-color--primary-contrast mdl-color-text--primary">primary, inverted</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">accent</th>
+        <td class="mdl-color--accent-contrast mdl-color-text--accent">accent, inverted</td>
+      </tr>
+    </table>
+  </section>
+
+  <div class="mdl-card__supporting-text mdlext-collapsible-region">
+    Card Supporting Text
+  </div>
+
+  <footer class="mdl-card__actions mdl-card--border">
+    <button id="read-more" class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
+      Read more
+    </button>
+    <div class="mdl-layout-spacer"></div>
+    <button class="mdl-button mdl-button--icon"><i class="material-icons">radio</i></button>
+    <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+    <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+  </footer>
+</div>
+
+
+
+<script>
+  (function() {
+    'use strict';
+    window.addEventListener('load', function() {
+
+      document.querySelector('#read-more').addEventListener('click', function (e) {
+        var collapsible = document.querySelector('#another-card .mdlext-js-collapsible');
+        collapsible.MaterialExtCollapsible.expand();
+      });
+
+      document.querySelector('#another-card').addEventListener('toggle', function (e) {
+        console.log('Toggle action:', e.detail.action);
+      });
+
+    });
+
+  }());
+
+</script>