Project import generated by Copybara.

GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/node_modules/mdl-ext/src/lightboard/_lightboard-eqjs.scss b/node_modules/mdl-ext/src/lightboard/_lightboard-eqjs.scss
new file mode 100644
index 0000000..7d2666b
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/_lightboard-eqjs.scss
@@ -0,0 +1,110 @@
+@charset "UTF-8";
+//////////////////////////////////////////////////////////////////////////////////
+//
+// Element queries for _lightbox.scss, based on: https://github.com/Snugug/eq.js
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+@import "../variables";
+@import "../functions";
+
+.mdlext-lightboard {
+
+  @include eq-pts((
+    lightboard_medium_small: strip-unit($mdlext-lightboard-medium-small-breakpoint),
+    lightboard_medium: strip-unit($mdlext-lightboard-medium-breakpoint),
+    lightboard_medium_large: strip-unit($mdlext-lightboard-medium-large-breakpoint),
+    lightboard_large: strip-unit($mdlext-lightboard-large-breakpoint)
+  ));
+
+  ////// small - meduim-small //////
+  @include eq('lightboard_medium_small') {
+    padding: calc((#{$mdlext-lightboard-medium-small-margin} - #{$mdlext-lightboard-medium-small-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-small-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-small-columns} * 100% - #{$mdlext-lightboard-medium-small-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-small-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-small-columns} * 100%);
+      }
+    }
+  }
+
+  ////// meduim-small - medium //////
+  @include eq('lightboard_medium') {
+    padding: calc((#{$mdlext-lightboard-medium-margin} - #{$mdlext-lightboard-medium-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-columns} * 100% - #{$mdlext-lightboard-medium-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-columns} * 100%);
+      }
+    }
+  }
+
+  ////// meduim - medium-large //////
+  @include eq('lightboard_medium_large') {
+    padding: calc((#{$mdlext-lightboard-medium-large-margin} - #{$mdlext-lightboard-medium-large-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-large-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-large-columns} * 100% - #{$mdlext-lightboard-medium-large-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-large-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-large-columns} * 100%);
+      }
+    }
+  }
+
+  ////// meduim-large - large //////
+  @include eq('lightboard_large') {
+    padding: calc((#{$mdlext-lightboard-large-margin} - #{$mdlext-lightboard-large-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-large-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-large-columns} * 100% - #{$mdlext-lightboard-large-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-large-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-large-columns} * 100%);
+      }
+    }
+  }
+}
+
+@include eq-selectors;
+
diff --git a/node_modules/mdl-ext/src/lightboard/_lightboard-media-queries.scss b/node_modules/mdl-ext/src/lightboard/_lightboard-media-queries.scss
new file mode 100644
index 0000000..b87f830
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/_lightboard-media-queries.scss
@@ -0,0 +1,113 @@
+@charset "UTF-8";
+
+//////////////////////////////
+//
+// Lightboard media queries
+//
+//////////////////////////////
+@import "../variables";
+
+////////// Small /////////////
+//@media (max-width: $mdlext-lightboard-medium-small-breakpoint - 1) {
+//  // This is the default, see: _lightboard.scss
+//}
+
+////////// Medium small //////////
+/* stylelint-disable */
+@media (min-width: $mdlext-lightboard-medium-small-breakpoint) and (max-width: $mdlext-lightboard-medium-breakpoint - 1) { /* stylelint-enable */
+  .mdlext-lightboard {
+    padding: calc((#{$mdlext-lightboard-medium-small-margin} - #{$mdlext-lightboard-medium-small-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-small-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-small-columns} * 100% - #{$mdlext-lightboard-medium-small-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-small-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-small-columns} * 100%);
+      }
+    }
+  }
+}
+
+////////// Medium //////////
+/* stylelint-disable */
+@media (min-width: $mdlext-lightboard-medium-breakpoint) and (max-width: $mdlext-lightboard-medium-large-breakpoint - 1) { /* stylelint-enable */
+  .mdlext-lightboard {
+    padding: calc((#{$mdlext-lightboard-medium-margin} - #{$mdlext-lightboard-medium-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-columns} * 100% - #{$mdlext-lightboard-medium-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-columns} * 100%);
+      }
+    }
+  }
+}
+
+////////// Medium large //////////
+/* stylelint-disable */
+@media (min-width: $mdlext-lightboard-medium-large-breakpoint)  and (max-width: $mdlext-lightboard-large-breakpoint - 1) { /* stylelint-enable */
+  .mdlext-lightboard {
+    padding: calc((#{$mdlext-lightboard-medium-large-margin} - #{$mdlext-lightboard-medium-large-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-large-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-large-columns} * 100% - #{$mdlext-lightboard-medium-large-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-large-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-large-columns} * 100%);
+      }
+    }
+  }
+}
+
+////////// Large //////////
+@media (min-width: $mdlext-lightboard-large-breakpoint) {
+  .mdlext-lightboard {
+    padding: calc((#{$mdlext-lightboard-large-margin} - #{$mdlext-lightboard-large-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-large-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-large-columns} * 100% - #{$mdlext-lightboard-large-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-large-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-large-columns} * 100%);
+      }
+    }
+  }
+}
+
diff --git a/node_modules/mdl-ext/src/lightboard/_lightboard.scss b/node_modules/mdl-ext/src/lightboard/_lightboard.scss
new file mode 100644
index 0000000..775d283
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/_lightboard.scss
@@ -0,0 +1,178 @@
+@charset "UTF-8";
+
+/**
+ * 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 lightboard is a translucent surface illuminated from behind, used for situations
+ * where a shape laid upon the surface needs to be seen with high contrast. In the "old days" of photography
+ * photograpers used a lightboard to get a quick view of their slides. The goal is to create a responsive lightbox
+ * design, based on flex layout, similar to what is used in Adobe LightRoom to browse images.
+ */
+
+// Use of this module requires the user to include variables from material-design-lite
+//@import "../../node_modules/material-design-lite/src/variables";
+//@import "../../node_modules/material-design-lite/src/mixins";
+@import "../variables";
+
+ul.mdlext-lightboard {
+  list-style: none;
+}
+
+.mdlext-lightboard {
+  box-sizing: border-box;
+  margin: 0 auto;
+  padding: 0;
+  display: flex;
+  flex-flow:row wrap;
+  align-items: stretch;
+
+  *,
+  *::before,
+  *::after,
+  input[type="search"] {
+    box-sizing: border-box;
+  }
+
+  .mdlext-lightboard__slide {
+    background-color: $mdlext-lightboard-slide-background-color;
+    border: 1px solid $mdlext-lightboard-slide-border-color;
+    border-radius: $mdlext-lightboard-slide-border-radius;
+    box-shadow: $mdlext-lightboard-slide-box-shadow;
+    position: relative;
+    display: block;
+    max-width: $mdlext-lightboard-slide-max-size;
+
+    &::before {
+      // 1:1 ratio
+      // TODO: Use a class for ratio so the grid can display slides with different ratios (16:9, 16:10, 4:3 ...)
+      content: '';
+      display: block;
+      padding-top: 100%;
+    }
+    &:hover,
+    &:active,
+    &:focus {
+      border-color: $mdlext-lightboard-slide-border-color-hover;
+      background-color: $mdlext-lightboard-slide-background-color-hover;
+      box-shadow: $mdlext-lightboard-slide-box-shadow-hover;
+
+      figcaption {
+        color: rgba(0, 0, 0, 1) !important;
+        background-color: rgba(255, 255, 255, 0.2);
+      }
+    }
+    &:focus {
+      outline-offset: -2px;
+      outline-color: $mdlext-lightboard-focus-outline-color;
+    }
+    &[aria-selected='true'] {
+      background-color: $mdlext-lightboard-slide-active-bacground-color;
+
+      figcaption {
+        color: rgba(0, 0, 0, 1) !important;
+        background-color: rgba(255, 255, 255, 0.2);
+      }
+    }
+    &__frame,
+    &__ripple-container {
+      text-decoration: none;
+      display: block;
+      overflow: hidden;
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+
+      &:focus {
+        outline-offset: -2px;
+        outline-color: $mdlext-lightboard-focus-outline-color;
+      }
+      & .mdl-ripple {
+        background: $mdlext-lightboard-ripple-color;
+      }
+      figure {
+        display: block;
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+
+        img {
+          position: absolute;
+          top: 0;
+          left: 0;
+          right: 0;
+          bottom: 0;
+          margin: auto;
+          max-width: 100%;
+          max-height: 100%;
+          border-width: 0;
+          border-radius: $mdlext-lightboard-slide-inner-border-radius;
+        }
+        figcaption {
+          @include typo-caption($colorContrast: false, $usePreferred: true);
+
+          color: $mdlext-lightboard-figcaption-text-color;
+          position: absolute;
+          bottom: -2px;
+          white-space: nowrap;
+          overflow: hidden;
+          max-width: 100%;
+          width: 100%;
+          text-align: center;
+          text-overflow: ellipsis;
+          padding: 4px 0;
+        }
+      }
+      &:hover {
+        figcaption {
+          // As far as I can see there is no way to darken/lighten a text color
+          // defined by MDL, due to the "unqote" functions.
+          // So this is a hack
+          color: rgba(0, 0, 0, 1) !important;
+          background-color: rgba(255, 255, 255, 0.2);
+        }
+      }
+    }
+  }
+}
+
+////// Media / Element queries default, Small //////
+.mdlext-lightboard {
+  padding: calc((#{$mdlext-lightboard-small-margin} - #{$mdlext-lightboard-small-gutter}) / 2);
+
+  .mdlext-lightboard__slide {
+    margin: calc(#{$mdlext-lightboard-small-gutter} / 2);
+    width: calc(1 / #{$mdlext-lightboard-small-columns} * 100% - #{$mdlext-lightboard-small-gutter});
+
+    .mdlext-lightboard__slide__frame figure {
+      margin: $mdlext-lightboard-small-frame-width;
+    }
+  }
+  &.mdlext-lightboard--no-spacing {
+    padding: 0;
+
+    .mdlext-lightboard__slide {
+      margin: 0;
+      width: calc(1 / #{$mdlext-lightboard-small-columns} * 100%);
+    }
+  }
+}
+
+// Import one of _lightboard-media-queries.scss or _lightboard-eq-js.scss to complete SASS
diff --git a/node_modules/mdl-ext/src/lightboard/lightboard.js b/node_modules/mdl-ext/src/lightboard/lightboard.js
new file mode 100644
index 0000000..9a49559
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/lightboard.js
@@ -0,0 +1,332 @@
+/**
+ * @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 lightboard is a translucent surface illuminated from behind, used for situations
+ * where a shape laid upon the surface needs to be seen with high contrast. In the "old days" of photography
+ * photograpers used a lightboard to get a quick view of their slides. The goal is to create a responsive lightbox
+ * design, based on flex layout, similar to what is used in Adobe LightRoom to browse images.
+ */
+
+import {
+  VK_ENTER,
+  VK_SPACE,
+  VK_END,
+  VK_HOME,
+  VK_ARROW_LEFT,
+  VK_ARROW_UP,
+  VK_ARROW_RIGHT,
+  VK_ARROW_DOWN,
+  IS_UPGRADED,
+  MDL_RIPPLE,
+  MDL_RIPPLE_COMPONENT,
+  MDL_RIPPLE_EFFECT,
+  MDL_RIPPLE_EFFECT_IGNORE_EVENTS
+} from '../utils/constants';
+
+const MDL_RIPPLE_CONTAINER = 'mdlext-lightboard__slide__ripple-container';
+
+(function() {
+  'use strict';
+
+  //const LIGHTBOARD = 'mdlext-lightboard';
+  const LIGHTBOARD_ROLE = 'grid';
+  const SLIDE = 'mdlext-lightboard__slide';
+  const SLIDE_ROLE  = 'gridcell';
+  const SLIDE_TABSTOP = 'mdlext-lightboard__slide__frame';
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  const MaterialExtLightboard = function MaterialExtLightboard(element) {
+    // Stores the element.
+    this.element_ = element;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtLightboard'] = MaterialExtLightboard;
+
+
+  // Helpers
+  const getSlide = element => {
+    return element ? element.closest(`.${SLIDE}`) : null;
+  };
+
+
+
+  // Private methods.
+
+  /**
+   * Select a slide, i.e. set aria-selected="true"
+   * @param element
+   * @private
+   */
+  MaterialExtLightboard.prototype.selectSlide_ = function(element) {
+    const slide = getSlide(element);
+    if( slide && !slide.hasAttribute('aria-selected') ) {
+      [...this.element_.querySelectorAll(`.${SLIDE}[aria-selected="true"]`)]
+        .forEach(selectedSlide => selectedSlide.removeAttribute('aria-selected'));
+
+      slide.setAttribute('aria-selected', 'true');
+    }
+  };
+
+
+  /**
+   * Dispatch select event
+   * @param {Element} slide The slide that caused the event
+   * @private
+   */
+  MaterialExtLightboard.prototype.dispatchSelectEvent_ = function ( slide ) {
+    this.element_.dispatchEvent(
+      new CustomEvent('select', {
+        bubbles: true,
+        cancelable: true,
+        detail: { source: slide }
+      })
+    );
+  };
+
+  /**
+   * Handles custom command event, 'first', 'next', 'prev', 'last', 'select' or upgrade
+   * @param event. A custom event
+   * @private
+   */
+  MaterialExtLightboard.prototype.commandHandler_ = function( event ) {
+    event.preventDefault();
+    event.stopPropagation();
+
+    if(event && event.detail) {
+      this.command(event.detail);
+    }
+  };
+
+
+  // Public methods
+
+  /**
+   * Initialize lightboard slides
+   * @public
+   */
+  MaterialExtLightboard.prototype.upgradeSlides = function() {
+
+    const addRipple = slide => {
+      // Use slide frame as ripple container
+      if(!slide.querySelector(`.${MDL_RIPPLE_CONTAINER}`)) {
+        const a = slide.querySelector(`.${SLIDE_TABSTOP}`);
+        if(a) {
+          const rippleContainer = a;
+          rippleContainer.classList.add(MDL_RIPPLE_CONTAINER);
+          rippleContainer.classList.add(MDL_RIPPLE_EFFECT);
+          const ripple = document.createElement('span');
+          ripple.classList.add(MDL_RIPPLE);
+          rippleContainer.appendChild(ripple);
+          componentHandler.upgradeElement(rippleContainer, MDL_RIPPLE_COMPONENT);
+        }
+      }
+    };
+
+    const hasRippleEffect = this.element_.classList.contains(MDL_RIPPLE_EFFECT);
+
+    [...this.element_.querySelectorAll(`.${SLIDE}`)].forEach( slide => {
+
+      slide.setAttribute('role', SLIDE_ROLE);
+
+      if(!slide.querySelector('a')) {
+        slide.setAttribute('tabindex', '0');
+      }
+      if(hasRippleEffect) {
+        addRipple(slide);
+      }
+    });
+  };
+  MaterialExtLightboard.prototype['upgradeSlides'] = MaterialExtLightboard.prototype.upgradeSlides;
+
+
+  /**
+   * Execute command
+   * @param detail
+   * @public
+   */
+  MaterialExtLightboard.prototype.command = function( detail ) {
+
+    const firstSlide = () => {
+      return this.element_.querySelector(`.${SLIDE}:first-child`);
+    };
+
+    const lastSlide = () => {
+      return this.element_.querySelector(`.${SLIDE}:last-child`);
+    };
+
+    const nextSlide = () => {
+      const slide = this.element_.querySelector(`.${SLIDE}[aria-selected="true"]`).nextElementSibling;
+      return slide ? slide : firstSlide();
+    };
+
+    const prevSlide = () => {
+      const slide = this.element_.querySelector(`.${SLIDE}[aria-selected="true"]`).previousElementSibling;
+      return slide ? slide : lastSlide();
+    };
+
+    if(detail && detail.action) {
+
+      const { action, target } = detail;
+
+      let slide;
+      switch (action.toLowerCase()) {
+        case 'select':
+          slide = getSlide(target);
+          this.dispatchSelectEvent_(slide);
+          break;
+        case 'first':
+          slide = firstSlide();
+          break;
+        case 'next':
+          slide = nextSlide();
+          break;
+        case 'prev':
+          slide = prevSlide();
+          break;
+        case 'last':
+          slide = lastSlide();
+          break;
+        case 'upgrade':
+          this.upgradeSlides();
+          break;
+        default:
+          throw new Error(`Unknown action "${action}". Action must be one of "first", "next", "prev", "last", "select" or "upgrade"`);
+      }
+
+      if (slide) {
+        const a = slide.querySelector('a');
+        if (a) {
+          a.focus();
+        }
+        else {
+          slide.focus();
+        }
+
+        // Workaround for JSDom testing:
+        // In JsDom 'element.focus()' does not trigger any focus event
+        if(!slide.hasAttribute('aria-selected')) {
+          this.selectSlide_(slide);
+        }
+
+      }
+    }
+  };
+  MaterialExtLightboard.prototype['command'] = MaterialExtLightboard.prototype.command;
+
+
+  /**
+   * Initialize component
+   */
+  MaterialExtLightboard.prototype.init = function() {
+
+    const keydownHandler = event => {
+
+      if(event.target !== this.element_) {
+        let action;
+        let target;
+        switch (event.keyCode) {
+          case VK_HOME:
+            action = 'first';
+            break;
+          case VK_END:
+            action = 'last';
+            break;
+          case VK_ARROW_UP:
+          case VK_ARROW_LEFT:
+            action = 'prev';
+            break;
+          case VK_ARROW_DOWN:
+          case VK_ARROW_RIGHT:
+            action = 'next';
+            break;
+          case VK_ENTER:
+          case VK_SPACE:
+            action = 'select';
+            target = event.target;
+            break;
+        }
+        if(action)  {
+          event.preventDefault();
+          event.stopPropagation();
+          this.command( { action: action, target: target } );
+        }
+      }
+    };
+
+    const clickHandler = event => {
+      event.preventDefault();
+      event.stopPropagation();
+
+      if(event.target !== this.element_) {
+        this.command( { action: 'select', target: event.target } );
+      }
+    };
+
+    const focusHandler = event => {
+      event.preventDefault();
+      event.stopPropagation();
+
+      if(event.target !== this.element_) {
+        this.selectSlide_(event.target);
+      }
+    };
+
+
+    if (this.element_) {
+      this.element_.setAttribute('role', LIGHTBOARD_ROLE);
+
+      if (this.element_.classList.contains(MDL_RIPPLE_EFFECT)) {
+        this.element_.classList.add(MDL_RIPPLE_EFFECT_IGNORE_EVENTS);
+      }
+
+      // Remove listeners, just in case ...
+      this.element_.removeEventListener('command', this.commandHandler_);
+      this.element_.removeEventListener('keydown', keydownHandler);
+      this.element_.removeEventListener('click', clickHandler);
+      this.element_.removeEventListener('focus', focusHandler);
+
+      this.element_.addEventListener('command', this.commandHandler_.bind(this), false);
+      this.element_.addEventListener('keydown', keydownHandler, true);
+      this.element_.addEventListener('click', clickHandler, true);
+      this.element_.addEventListener('focus', focusHandler, true);
+
+      this.upgradeSlides();
+
+      this.element_.classList.add(IS_UPGRADED);
+    }
+  };
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  /* jshint undef:false */
+  componentHandler.register({
+    constructor: MaterialExtLightboard,
+    classAsString: 'MaterialExtLightboard',
+    cssClass: 'mdlext-js-lightboard',
+    widget: true
+  });
+
+})();
diff --git a/node_modules/mdl-ext/src/lightboard/readme.md b/node_modules/mdl-ext/src/lightboard/readme.md
new file mode 100644
index 0000000..429e88e
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/readme.md
@@ -0,0 +1,447 @@
+# Lightboard
+
+![Lightboard](../../etc/lightboard.png)
+
+Thumbnails in a responsive, fluent grid.
+
+## Introduction
+A lightboard is a translucent surface illuminated from behind, used for situations where a shape laid 
+upon the surface needs to be seen with high contrast. In the "old days" of photography photograpers 
+used a lightboard to get a quick view of, sorting and organizing their slides.
+
+The Material Design Lite Ext (MDLEXT) lightboard is defined and enclosed by a container element. The slides are 
+distributed in a row column fashion, with repect to the available screen size. The slides scales proportionally to fill 
+available horizontal space, or the available content size, depending on the type of queries you choose to apply 
+for your responsive breakpoints. The number of slides per row depends on available space. The component 
+adds `role='grid'` to the lightboard and `role='gridcell` to the individual slides.
+
+The Material Design Lite Ext (MDLEXT) lightboard has two versions; one version based on media queries and one version 
+based on **element queries**.
+
+### How to use the eq.js version of MDLEXT lightboard
+
+ 1. Install [eq.js](https://github.com/Snugug/eq.js).
+```sh
+$ npm install --save eq.js
+```
+
+ 2. Import `mdl-ext-eqjs.scss` in your main SASS file. Remove `mdl-ext.scss` - they can not co exist.
+```css
+@import '../node_modules/mdl-ext/src/mdl-ext-eqjs';
+```
+
+ 3. Import or Require `eq.js`.  
+```javascript
+const eqjs = require('eq.js'); // ... or:  import eqjs from 'eq.js';
+```
+
+&nbsp;4. Upgrade DOM and trigger `eq.js`<br/>
+If you're loading html fragments, using e.g. Ajax, then upgrade DOM and trigger `eq.js` after page load.
+
+```javascript
+window.fetch(href, {method: 'get'})
+ .then(response => response.text())
+ .then(text => {
+   contentPanelEl.insertAdjacentHTML('afterbegin', text);
+
+    // Upgrade DOM
+    componentHandler.upgradeDom();
+
+   // Trigger eq.js
+   eqjs.refreshNodes();
+   eqjs.query(undefined, true);
+})
+.catch(err => console.error(err));
+```
+
+An example of how to use `eq.js` in a SPA can be found [here](https://github.com/leifoolsen/mdl-webpack).                           
+
+## To include a MDLEXT lightboard component
+&nbsp;1. Code a `<ul>` element with `class="mdlext-lightboard mdlext-js-lightboard"` to hold the lightboard slides.
+```html
+<ul class="mdlext-lightboard mdlext-js-lightboard">
+</ul>
+```
+
+&nbsp;2. Code a `<li>` element with `class="mdlext-lightboard__slide"`  to hold an individual slide.
+```html
+<ul class="mdlext-lightboard mdlext-js-lightboard">
+  <li class="mdlext-lightboard__slide">
+  <li>
+</ul>
+```
+
+&nbsp;3. Code an `<a href="#">` element with `class="mdlext-lightboard__slide__frame"`  to hold the slide frame. Optionally add a href to a large version of the image shown in the slide.
+```html
+<ul class="mdlext-lightboard mdlext-js-lightboard">
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+    </a>  
+  <li>
+</ul>
+```
+
+&nbsp;4. Code a `<figure>` element (decorates frame and center image in slide).  
+```html
+<ul class="mdlext-lightboard mdlext-js-lightboard">
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+      </figure>
+    </a>  
+  <li>
+</ul>
+```
+
+&nbsp;5. Inside the `<figure>` element add an `<img>` element with reference to the thumbnail image to be shown in slide. Optionally add a `<figcaption>` element to hold the image title.    
+```html
+<ul class="mdlext-lightboard mdlext-js-lightboard">
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D802591.jpg" title="Whooper swans in flight"/>
+        <figcaption>_D802591.jpg</figcaption>
+      </figure>
+    </a>  
+  <li>
+</ul>
+```
+
+&nbsp;6. Repeat steps 2..5 for each slide required.
+
+### Example
+Lightboard with eight slides, ripple effect on each slide, no spacing between slides, subscribes to lightboard `select` event.
+
+```html
+<ul id="lightboard-1" class="mdlext-lightboard mdlext-js-lightboard
+  mdlext-lightboard--no-spacing
+  mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events">
+
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D802141.jpg" title="Northern goshawk with prey"/>
+        <figcaption>_D802141.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D802591.jpg" title="Whooper swans in flight"/>
+        <figcaption>_D802591.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D804370-3.jpg" title="European green woodpecker"/>
+        <figcaption>_D804370-3.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D808689.jpg" title="The bridge"/>
+        <figcaption>_D808689.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D802181.jpg" title="Landscape in blue pastel"/>
+        <figcaption>_D802181.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D800912.jpg" title="Hiking the mountains of Dovre"/>
+        <figcaption>_D800912.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D809453-_D809457-4.jpg" title="Train to nowhwere. Ny Aalesund, Spitsbergen." />
+        <figcaption>_D809453-_D809457-4.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_DSC8214.jpg" title="Blues"/>
+        <figcaption>_DSC8214.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+</ul>
+
+<script>
+  window.addEventListener('load', function() {
+    var lightboard = document.querySelector('#lightboard-1');
+    lightboard.addEventListener('select', function(e) {
+      console.log('Slide selected. Source:', e.detail.source);
+    });
+  });
+</script>
+```
+
+## Keyboard interaction
+The lightboard interacts with the following keyboard keys.
+
+*   `Tab` - When focus is on a slide, pressing the `Tab` key moves focus in the following manner:
+    1.  If interactive glyphs or menus are present in the slide frame, focus moves to each in order. (Not implemented yet)
+    2.  The next `Tab` key press moves focus as follows:
+        *   If there is a next slide, focus moves to the next slide.
+        *   If focus is on the last slide, focus moves to the first focusable element outside the lightboard component.
+*   `Left arrow` - Moves focus to the previous slide. If the current slide is the first slide, focus moves to the last slide.
+*   `Right arrow` - Moves focus to the next slide. If the current slide is the last slide, focus moves to the first slide.
+*   `Up arrow` - behaves the same as left arrow.
+*   `Down arrow` - behaves the same as right arrow.
+*   `End` - When focus is on a slide, an `End` key press moves focus to the last slide.
+*   `Home` - When focus is on a slide, a `Home` key press moves focus to the first slide.
+*   `Enter/Space` - When focus is on slide, pressing `Enter`/`Space` selects that particular slide. The lightboard emits a **select** event.
+*   `Shift+Tab` - Generally the reverse of `Tab`.
+
+
+## Events
+Interaction with the component programmatically is performed receiving events from the component or by sending events to 
+the component (or by using the public api).  
+
+### Events the component listenes to
+A client can send a `command` custom event to the lightboard. The command event holds a detail object defining the action 
+to perform and a optionally a target for the action.
+
+The detail object has the following structure:
+
+```javascript
+detail: { 
+  action, // "first", "last", "next", "prev", "upgrade" or "select" 
+  target  // Target, the slide that should be affected by the event 
+}
+```
+
+Possible actions are:
+
+#### first
+Focuses the first slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+ce = new CustomEvent('command', { detail: { action : 'first' } });
+myLightboard.dispatchEvent(ce);
+```
+
+#### last
+Focuses the last slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+ce = new CustomEvent('command', { detail: { action : 'last' } });
+myLightboard.dispatchEvent(ce);
+```
+
+#### next
+Focuses the next slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+ce = new CustomEvent('command', { detail: { action : 'next' } });
+myLightboard.dispatchEvent(ce);
+```
+
+#### prev
+Focuses the previous slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+ce = new CustomEvent('command', { detail: { action : 'prev' } });
+myLightboard.dispatchEvent(ce);
+```
+
+#### select
+Selects a slide, i.e. adds `aria-selected="true"` on the targeted slide. The lightboard responds with a `select` event.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+slide = lightboard.querySelector('.mdlext-lightboard__slide:nth-child(2)');
+ce = new CustomEvent('command', { detail: { action : 'prev', target: slide } });
+myLightboard.dispatchEvent(ce);
+```
+
+#### upgrade
+Upgrade slides. If you add slides to the lightboard after the page has loaded, you must call `upgrade` to 
+notify the lightboard component about the new slides.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+slide = 
+   '<li class="mdlext-lightboard__slide">'
+  +'  <a href="#" class="mdlext-lightboard__slide__frame">'
+  +'    <figure>'
+  +'      <img src="_D802181.jpg" title="Landscape in blue pastel"/>'
+  +'      <figcaption>_D802181.jpg</figcaption>'
+  +'    </figure>'
+  +'  </a>'
+  +'</li>';
+
+myLightboard.insertAdjacentHTML('beforeend', slide);
+ce = new CustomEvent('command', { detail: { action : 'upgrade' } });
+myLightboard.dispatchEvent(ce);
+```
+
+### Events emitted from the component
+The lightboard emits a custom `select` event when a slide is clicked. The event has a detail object with the following content:
+```
+{
+  source  // the slide instance that caused the event
+}
+```
+
+Set up an event listener to receive the select event.
+```javascript
+document.querySelector('#my-lightboard').addEventListener('select', function(e) {
+  console.log('Slide selected:', e.detail.source);
+});
+```
+
+Trigger the event.
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+slide = lightboard.querySelector('.mdlext-lightboard__slide:nth-child(2)');
+ce = new CustomEvent('command', { detail: { action : 'select', target: slide } });
+myLightboard.dispatchEvent(ce);
+```
+
+## Public methods
+
+### upgradeSlides()
+Upgrade slides. If you add slides to the lightboard after the page has loaded, you must call `upgradeSlides` to 
+notify the component about the new slides.
+
+```javascript
+slide = 
+   '<li class="mdlext-lightboard__slide">'
+  +'  <a href="#" class="mdlext-lightboard__slide__frame">'
+  +'    <figure>'
+  +'      <img src="_D802181.jpg" title="Landscape in blue pastel"/>'
+  +'      <figcaption>_D802181.jpg</figcaption>'
+  +'    </figure>'
+  +'  </a>'
+  +'</li>';
+
+myLightboard = document.querySelector('#my-lightboard');
+myLightboard.insertAdjacentHTML('beforeend', slide);
+myLightboard.MaterialExtLightboard.upgradeSlides();
+```
+
+### command( detail )
+Executes an action, optionally targeting a specific slide. The actions corresponds to the custom events defined for this 
+component.
+ 
+The detail object parameter has the following structure:
+```javascript
+detail: { 
+  action, // "first", "last", "next", "prev", "upgrade" or "select" 
+  target  // Target, the slide that should be affected by the event 
+}
+```
+
+Possible actions are:
+
+#### first: command( {action: 'first' } )
+Focuses the first slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+myLightboard.MaterialExtLightboard.command( {action: 'first'} );
+```
+
+#### last: command( {action: 'last' } )
+Focuses the last slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+myLightboard.MaterialExtLightboard.command( {action: 'last'} );
+```
+
+#### next: command( {action: 'next' } )
+Focuses the next slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+myLightboard.MaterialExtLightboard.command( {action: 'next'} );
+```
+
+#### prev: command( {action: 'prev' } )
+Focuses the previous slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+myLightboard.MaterialExtLightboard.command( {action: 'prev'} );
+```
+
+#### select: command( {action: 'first', target: slide } )
+Selects a slide, i.e. adds `aria-selected="true"` on the targeted slide. The lightboard responds with a `select` event.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+slide = lightboard.querySelector('.mdlext-lightboard__slide:nth-child(2)');
+myLightboard.MaterialExtLightboard.command( {action: 'prev', target: slide} );
+```
+
+#### upgrade: command( {action: 'upgrade' } )
+Upgrade slides. If you add slides to the lightboard after the page has loaded, you must call `upgrade` to 
+notify the lightboard component about the new slides.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+slide = 
+   '<li class="mdlext-lightboard__slide">'
+  +'  <a href="#" class="mdlext-lightboard__slide__frame">'
+  +'    <figure>'
+  +'      <img src="_D802181.jpg" title="Landscape in blue pastel"/>'
+  +'      <figcaption>_D802181.jpg</figcaption>'
+  +'    </figure>'
+  +'  </a>'
+  +'</li>';
+
+myLightboard.insertAdjacentHTML('beforeend', slide);
+myLightboard.MaterialExtLightboard.command( {action: 'upgrade'} );
+```
+
+## Configuration options
+
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to the lightboard.
+The table below lists the available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|--------------|--------|---------|
+| `mdlext-lightboard` | Defines a container as an MDLEXT lightboard component | Required on `<ul>` element |
+| `mdlext-js-lightboard` | Assigns basic MDL behavior to lightboard | Required on `<ul>` element |
+| `mdlext-lightboard--no-spacing` | Modifies the slides to have no margin between them. | Optional on `<ul>` element |
+| `mdlext-lightboard__slide` | Defines a slide | Required on `<li>` element |
+| `mdlext-lightboard__slide__frame` | Defines the slide frame, makes the frame focusable and selectable | Required on `<a>` element. First inner element of `<li>`  |
+| `mdl-js-ripple-effect` | Applies ripple click effect to slides | Optional; goes on "outer" `<ul>` element |
+| `mdl-js-ripple-effect--ignore-events` |  | Should be added when the component initializes, but that does not seem to happen due to bug/limitation in MDL. For now, add this class if `mdl-js-ripple-effect` class is applied |
+
+
+A lightboard and its assosiated slides has the following roles.
+
+| Attribute | Effect | Remarks |
+|-----------|--------|---------|
+| `role="grid"` | Defines the lightboard as a WAI-ARIA grid | Added to `mdlext-lightboard` when component innitializes |
+| `role="gridcell"` | Defines the slide as a WAI-ARIA cell | Added to `mdlext-lightboard__slide` when component innitializes |
+| `aria-selected` | Defines a slide as selected | Added to `mdlext-lightboard__slide` when a slide is clicked |
+
+
+## How to use the component programmatically
+Refer to [snippets/lightboard.html](./snippets/lightboard.html) or the [tests](../../test/lightboard/lightboard.spec.js) 
+for detailed usage.
diff --git a/node_modules/mdl-ext/src/lightboard/snippets/lightboard.html b/node_modules/mdl-ext/src/lightboard/snippets/lightboard.html
new file mode 100644
index 0000000..555a4d8
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/snippets/lightboard.html
@@ -0,0 +1,174 @@
+<p style="margin-bottom:32px;">A lightboard is a translucent surface illuminated from behind, used for
+  situations where a shape laid upon the surface needs to be seen with high contrast. In the "old days"
+  of photography photograpers used a lightboard to get a quick view of, sorting and organizing their slides.
+</p>
+
+<ul id="lightboard-1" class="mdlext-lightboard mdlext-js-lightboard mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events">
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D802141.jpg" title="Northern goshawk with prey"/>
+        <figcaption>_D802141.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D802591.jpg" title="Whooper swans in flight"/>
+        <figcaption>_D802591.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D804370-3.jpg" title="European green woodpecker"/>
+        <figcaption>_D804370-3.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D808689.jpg" title="The bridge"/>
+        <figcaption>_D808689.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D802181.jpg" title="Landscape in blue pastel"/>
+        <figcaption>_D802181.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800912.jpg" title="Hiking the mountains of Dovre"/>
+        <figcaption>_D800912.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D809453-_D809457-4.jpg" title="Train to nowhwere. Ny Aalesund, Spitsbergen." />
+        <figcaption>_D809453-_D809457-4.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_DSC8214.jpg" title="Blues"/>
+        <figcaption>_DSC8214.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800017.jpg" />
+        <figcaption>_D800017.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800023.jpg" />
+        <figcaption>_D800023.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800851.jpg" />
+        <figcaption>_D800851.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800166.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800951.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801188.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801205-2.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801274.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801392.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801952-4.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D807603.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D807689.jpg" />
+      </figure>
+    </a>
+  </li>
+</ul>
+
+<p class="mdl-typography--caption" style="margin-top: 32px;">
+  All images appearing in this page are the exclusive property of Leif Olsen and are protected under the United States and International Copyright laws.
+  The images may not be reproduced or manipulated without the written permission of Leif Olsen.
+  Use of any image as the basis for another photographic concept or illustration (digital, artist rendering or alike) is a violation of the United States and International Copyright laws.
+  All images are copyrighted &copy; Leif Olsen, 2016.
+</p>
+
+<script>
+  window.addEventListener('load', function() {
+    var lightboard = document.querySelector('#lightboard-1');
+    lightboard.addEventListener('select', function(e) {
+      console.log('Slide selected. Source:', e.detail.source);
+    });
+  });
+</script>