(function (factory) {
	typeof define === 'function' && define.amd ? define(factory) :
	factory();
})((function () { 'use strict';

	function getDefaultExportFromCjs (x) {
		return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
	}

	var masonry = {exports: {}};

	var outlayer = {exports: {}};

	var evEmitter$1 = {exports: {}};

	/**
	 * EvEmitter v1.1.0
	 * Lil' event emitter
	 * MIT License
	 */
	var evEmitter = evEmitter$1.exports;
	var hasRequiredEvEmitter;
	function requireEvEmitter() {
	  if (hasRequiredEvEmitter) return evEmitter$1.exports;
	  hasRequiredEvEmitter = 1;
	  (function (module) {
	    /* jshint unused: true, undef: true, strict: true */

	    (function (global, factory) {
	      // universal module definition
	      /* jshint strict: false */ /* globals define, module, window */
	      if (module.exports) {
	        // CommonJS - Browserify, Webpack
	        module.exports = factory();
	      } else {
	        // Browser globals
	        global.EvEmitter = factory();
	      }
	    })(typeof window != 'undefined' ? window : evEmitter, function () {

	      function EvEmitter() {}
	      var proto = EvEmitter.prototype;
	      proto.on = function (eventName, listener) {
	        if (!eventName || !listener) {
	          return;
	        }
	        // set events hash
	        var events = this._events = this._events || {};
	        // set listeners array
	        var listeners = events[eventName] = events[eventName] || [];
	        // only add once
	        if (listeners.indexOf(listener) == -1) {
	          listeners.push(listener);
	        }
	        return this;
	      };
	      proto.once = function (eventName, listener) {
	        if (!eventName || !listener) {
	          return;
	        }
	        // add event
	        this.on(eventName, listener);
	        // set once flag
	        // set onceEvents hash
	        var onceEvents = this._onceEvents = this._onceEvents || {};
	        // set onceListeners object
	        var onceListeners = onceEvents[eventName] = onceEvents[eventName] || {};
	        // set flag
	        onceListeners[listener] = true;
	        return this;
	      };
	      proto.off = function (eventName, listener) {
	        var listeners = this._events && this._events[eventName];
	        if (!listeners || !listeners.length) {
	          return;
	        }
	        var index = listeners.indexOf(listener);
	        if (index != -1) {
	          listeners.splice(index, 1);
	        }
	        return this;
	      };
	      proto.emitEvent = function (eventName, args) {
	        var listeners = this._events && this._events[eventName];
	        if (!listeners || !listeners.length) {
	          return;
	        }
	        // copy over to avoid interference if .off() in listener
	        listeners = listeners.slice(0);
	        args = args || [];
	        // once stuff
	        var onceListeners = this._onceEvents && this._onceEvents[eventName];
	        for (var i = 0; i < listeners.length; i++) {
	          var listener = listeners[i];
	          var isOnce = onceListeners && onceListeners[listener];
	          if (isOnce) {
	            // remove listener
	            // remove before trigger to prevent recursion
	            this.off(eventName, listener);
	            // unset once flag
	            delete onceListeners[listener];
	          }
	          // trigger listener
	          listener.apply(this, args);
	        }
	        return this;
	      };
	      proto.allOff = function () {
	        delete this._events;
	        delete this._onceEvents;
	      };
	      return EvEmitter;
	    });
	  })(evEmitter$1);
	  return evEmitter$1.exports;
	}

	var getSize = {exports: {}};

	/*!
	 * getSize v2.0.3
	 * measure size of elements
	 * MIT license
	 */
	var hasRequiredGetSize;
	function requireGetSize() {
	  if (hasRequiredGetSize) return getSize.exports;
	  hasRequiredGetSize = 1;
	  (function (module) {
	    /* jshint browser: true, strict: true, undef: true, unused: true */
	    /* globals console: false */

	    (function (window, factory) {
	      /* jshint strict: false */ /* globals define, module */
	      if (module.exports) {
	        // CommonJS
	        module.exports = factory();
	      } else {
	        // browser global
	        window.getSize = factory();
	      }
	    })(window, function factory() {

	      // -------------------------- helpers -------------------------- //

	      // get a number from a string, not a percentage
	      function getStyleSize(value) {
	        var num = parseFloat(value);
	        // not a percent like '100%', and a number
	        var isValid = value.indexOf('%') == -1 && !isNaN(num);
	        return isValid && num;
	      }
	      function noop() {}
	      var logError = typeof console == 'undefined' ? noop : function (message) {
	        console.error(message);
	      };

	      // -------------------------- measurements -------------------------- //

	      var measurements = ['paddingLeft', 'paddingRight', 'paddingTop', 'paddingBottom', 'marginLeft', 'marginRight', 'marginTop', 'marginBottom', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth', 'borderBottomWidth'];
	      var measurementsLength = measurements.length;
	      function getZeroSize() {
	        var size = {
	          width: 0,
	          height: 0,
	          innerWidth: 0,
	          innerHeight: 0,
	          outerWidth: 0,
	          outerHeight: 0
	        };
	        for (var i = 0; i < measurementsLength; i++) {
	          var measurement = measurements[i];
	          size[measurement] = 0;
	        }
	        return size;
	      }

	      // -------------------------- getStyle -------------------------- //

	      /**
	       * getStyle, get style of element, check for Firefox bug
	       * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
	       */
	      function getStyle(elem) {
	        var style = getComputedStyle(elem);
	        if (!style) {
	          logError('Style returned ' + style + '. Are you running this code in a hidden iframe on Firefox? ' + 'See https://bit.ly/getsizebug1');
	        }
	        return style;
	      }

	      // -------------------------- setup -------------------------- //

	      var isSetup = false;
	      var isBoxSizeOuter;

	      /**
	       * setup
	       * check isBoxSizerOuter
	       * do on first getSize() rather than on page load for Firefox bug
	       */
	      function setup() {
	        // setup once
	        if (isSetup) {
	          return;
	        }
	        isSetup = true;

	        // -------------------------- box sizing -------------------------- //

	        /**
	         * Chrome & Safari measure the outer-width on style.width on border-box elems
	         * IE11 & Firefox<29 measures the inner-width
	         */
	        var div = document.createElement('div');
	        div.style.width = '200px';
	        div.style.padding = '1px 2px 3px 4px';
	        div.style.borderStyle = 'solid';
	        div.style.borderWidth = '1px 2px 3px 4px';
	        div.style.boxSizing = 'border-box';
	        var body = document.body || document.documentElement;
	        body.appendChild(div);
	        var style = getStyle(div);
	        // round value for browser zoom. desandro/masonry#928
	        isBoxSizeOuter = Math.round(getStyleSize(style.width)) == 200;
	        getSize.isBoxSizeOuter = isBoxSizeOuter;
	        body.removeChild(div);
	      }

	      // -------------------------- getSize -------------------------- //

	      function getSize(elem) {
	        setup();

	        // use querySeletor if elem is string
	        if (typeof elem == 'string') {
	          elem = document.querySelector(elem);
	        }

	        // do not proceed on non-objects
	        if (!elem || typeof elem != 'object' || !elem.nodeType) {
	          return;
	        }
	        var style = getStyle(elem);

	        // if hidden, everything is 0
	        if (style.display == 'none') {
	          return getZeroSize();
	        }
	        var size = {};
	        size.width = elem.offsetWidth;
	        size.height = elem.offsetHeight;
	        var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';

	        // get all measurements
	        for (var i = 0; i < measurementsLength; i++) {
	          var measurement = measurements[i];
	          var value = style[measurement];
	          var num = parseFloat(value);
	          // any 'auto', 'medium' value will be 0
	          size[measurement] = !isNaN(num) ? num : 0;
	        }
	        var paddingWidth = size.paddingLeft + size.paddingRight;
	        var paddingHeight = size.paddingTop + size.paddingBottom;
	        var marginWidth = size.marginLeft + size.marginRight;
	        var marginHeight = size.marginTop + size.marginBottom;
	        var borderWidth = size.borderLeftWidth + size.borderRightWidth;
	        var borderHeight = size.borderTopWidth + size.borderBottomWidth;
	        var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;

	        // overwrite width and height if we can get it from style
	        var styleWidth = getStyleSize(style.width);
	        if (styleWidth !== false) {
	          size.width = styleWidth + (
	          // add padding and border unless it's already including it
	          isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth);
	        }
	        var styleHeight = getStyleSize(style.height);
	        if (styleHeight !== false) {
	          size.height = styleHeight + (
	          // add padding and border unless it's already including it
	          isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight);
	        }
	        size.innerWidth = size.width - (paddingWidth + borderWidth);
	        size.innerHeight = size.height - (paddingHeight + borderHeight);
	        size.outerWidth = size.width + marginWidth;
	        size.outerHeight = size.height + marginHeight;
	        return size;
	      }
	      return getSize;
	    });
	  })(getSize);
	  return getSize.exports;
	}

	var utils = {exports: {}};

	var matchesSelector = {exports: {}};

	/**
	 * matchesSelector v2.0.2
	 * matchesSelector( element, '.selector' )
	 * MIT license
	 */
	var hasRequiredMatchesSelector;
	function requireMatchesSelector() {
	  if (hasRequiredMatchesSelector) return matchesSelector.exports;
	  hasRequiredMatchesSelector = 1;
	  (function (module) {
	    /*jshint browser: true, strict: true, undef: true, unused: true */

	    (function (window, factory) {

	      // universal module definition
	      if (module.exports) {
	        // CommonJS
	        module.exports = factory();
	      } else {
	        // browser global
	        window.matchesSelector = factory();
	      }
	    })(window, function factory() {

	      var matchesMethod = function () {
	        var ElemProto = window.Element.prototype;
	        // check for the standard method name first
	        if (ElemProto.matches) {
	          return 'matches';
	        }
	        // check un-prefixed
	        if (ElemProto.matchesSelector) {
	          return 'matchesSelector';
	        }
	        // check vendor prefixes
	        var prefixes = ['webkit', 'moz', 'ms', 'o'];
	        for (var i = 0; i < prefixes.length; i++) {
	          var prefix = prefixes[i];
	          var method = prefix + 'MatchesSelector';
	          if (ElemProto[method]) {
	            return method;
	          }
	        }
	      }();
	      return function matchesSelector(elem, selector) {
	        return elem[matchesMethod](selector);
	      };
	    });
	  })(matchesSelector);
	  return matchesSelector.exports;
	}

	/**
	 * Fizzy UI utils v2.0.7
	 * MIT license
	 */
	var hasRequiredUtils;
	function requireUtils() {
	  if (hasRequiredUtils) return utils.exports;
	  hasRequiredUtils = 1;
	  (function (module) {
	    /*jshint browser: true, undef: true, unused: true, strict: true */

	    (function (window, factory) {
	      // universal module definition
	      /*jshint strict: false */ /*globals define, module, require */

	      if (module.exports) {
	        // CommonJS
	        module.exports = factory(window, requireMatchesSelector());
	      } else {
	        // browser global
	        window.fizzyUIUtils = factory(window, window.matchesSelector);
	      }
	    })(window, function factory(window, matchesSelector) {

	      var utils = {};

	      // ----- extend ----- //

	      // extends objects
	      utils.extend = function (a, b) {
	        for (var prop in b) {
	          a[prop] = b[prop];
	        }
	        return a;
	      };

	      // ----- modulo ----- //

	      utils.modulo = function (num, div) {
	        return (num % div + div) % div;
	      };

	      // ----- makeArray ----- //

	      var arraySlice = Array.prototype.slice;

	      // turn element or nodeList into an array
	      utils.makeArray = function (obj) {
	        if (Array.isArray(obj)) {
	          // use object if already an array
	          return obj;
	        }
	        // return empty array if undefined or null. #6
	        if (obj === null || obj === undefined) {
	          return [];
	        }
	        var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
	        if (isArrayLike) {
	          // convert nodeList to array
	          return arraySlice.call(obj);
	        }

	        // array of single index
	        return [obj];
	      };

	      // ----- removeFrom ----- //

	      utils.removeFrom = function (ary, obj) {
	        var index = ary.indexOf(obj);
	        if (index != -1) {
	          ary.splice(index, 1);
	        }
	      };

	      // ----- getParent ----- //

	      utils.getParent = function (elem, selector) {
	        while (elem.parentNode && elem != document.body) {
	          elem = elem.parentNode;
	          if (matchesSelector(elem, selector)) {
	            return elem;
	          }
	        }
	      };

	      // ----- getQueryElement ----- //

	      // use element as selector string
	      utils.getQueryElement = function (elem) {
	        if (typeof elem == 'string') {
	          return document.querySelector(elem);
	        }
	        return elem;
	      };

	      // ----- handleEvent ----- //

	      // enable .ontype to trigger from .addEventListener( elem, 'type' )
	      utils.handleEvent = function (event) {
	        var method = 'on' + event.type;
	        if (this[method]) {
	          this[method](event);
	        }
	      };

	      // ----- filterFindElements ----- //

	      utils.filterFindElements = function (elems, selector) {
	        // make array of elems
	        elems = utils.makeArray(elems);
	        var ffElems = [];
	        elems.forEach(function (elem) {
	          // check that elem is an actual element
	          if (!(elem instanceof HTMLElement)) {
	            return;
	          }
	          // add elem if no selector
	          if (!selector) {
	            ffElems.push(elem);
	            return;
	          }
	          // filter & find items if we have a selector
	          // filter
	          if (matchesSelector(elem, selector)) {
	            ffElems.push(elem);
	          }
	          // find children
	          var childElems = elem.querySelectorAll(selector);
	          // concat childElems to filterFound array
	          for (var i = 0; i < childElems.length; i++) {
	            ffElems.push(childElems[i]);
	          }
	        });
	        return ffElems;
	      };

	      // ----- debounceMethod ----- //

	      utils.debounceMethod = function (_class, methodName, threshold) {
	        threshold = threshold || 100;
	        // original method
	        var method = _class.prototype[methodName];
	        var timeoutName = methodName + 'Timeout';
	        _class.prototype[methodName] = function () {
	          var timeout = this[timeoutName];
	          clearTimeout(timeout);
	          var args = arguments;
	          var _this = this;
	          this[timeoutName] = setTimeout(function () {
	            method.apply(_this, args);
	            delete _this[timeoutName];
	          }, threshold);
	        };
	      };

	      // ----- docReady ----- //

	      utils.docReady = function (callback) {
	        var readyState = document.readyState;
	        if (readyState == 'complete' || readyState == 'interactive') {
	          // do async to allow for other scripts to run. metafizzy/flickity#441
	          setTimeout(callback);
	        } else {
	          document.addEventListener('DOMContentLoaded', callback);
	        }
	      };

	      // ----- htmlInit ----- //

	      // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
	      utils.toDashed = function (str) {
	        return str.replace(/(.)([A-Z])/g, function (match, $1, $2) {
	          return $1 + '-' + $2;
	        }).toLowerCase();
	      };
	      var console = window.console;
	      /**
	       * allow user to initialize classes via [data-namespace] or .js-namespace class
	       * htmlInit( Widget, 'widgetName' )
	       * options are parsed from data-namespace-options
	       */
	      utils.htmlInit = function (WidgetClass, namespace) {
	        utils.docReady(function () {
	          var dashedNamespace = utils.toDashed(namespace);
	          var dataAttr = 'data-' + dashedNamespace;
	          var dataAttrElems = document.querySelectorAll('[' + dataAttr + ']');
	          var jsDashElems = document.querySelectorAll('.js-' + dashedNamespace);
	          var elems = utils.makeArray(dataAttrElems).concat(utils.makeArray(jsDashElems));
	          var dataOptionsAttr = dataAttr + '-options';
	          var jQuery = window.jQuery;
	          elems.forEach(function (elem) {
	            var attr = elem.getAttribute(dataAttr) || elem.getAttribute(dataOptionsAttr);
	            var options;
	            try {
	              options = attr && JSON.parse(attr);
	            } catch (error) {
	              // log error, do not initialize
	              if (console) {
	                console.error('Error parsing ' + dataAttr + ' on ' + elem.className + ': ' + error);
	              }
	              return;
	            }
	            // initialize
	            var instance = new WidgetClass(elem, options);
	            // make available via $().data('namespace')
	            if (jQuery) {
	              jQuery.data(elem, namespace, instance);
	            }
	          });
	        });
	      };

	      // -----  ----- //

	      return utils;
	    });
	  })(utils);
	  return utils.exports;
	}

	var item = {exports: {}};

	/**
	 * Outlayer Item
	 */
	var hasRequiredItem;
	function requireItem() {
	  if (hasRequiredItem) return item.exports;
	  hasRequiredItem = 1;
	  (function (module) {
	    (function (window, factory) {
	      // universal module definition
	      /* jshint strict: false */ /* globals define, module, require */
	      if (module.exports) {
	        // CommonJS - Browserify, Webpack
	        module.exports = factory(requireEvEmitter(), requireGetSize());
	      } else {
	        // browser global
	        window.Outlayer = {};
	        window.Outlayer.Item = factory(window.EvEmitter, window.getSize);
	      }
	    })(window, function factory(EvEmitter, getSize) {

	      // ----- helpers ----- //
	      function isEmptyObj(obj) {
	        for (var prop in obj) {
	          return false;
	        }
	        prop = null;
	        return true;
	      }

	      // -------------------------- CSS3 support -------------------------- //

	      var docElemStyle = document.documentElement.style;
	      var transitionProperty = typeof docElemStyle.transition == 'string' ? 'transition' : 'WebkitTransition';
	      var transformProperty = typeof docElemStyle.transform == 'string' ? 'transform' : 'WebkitTransform';
	      var transitionEndEvent = {
	        WebkitTransition: 'webkitTransitionEnd',
	        transition: 'transitionend'
	      }[transitionProperty];

	      // cache all vendor properties that could have vendor prefix
	      var vendorProperties = {
	        transform: transformProperty,
	        transition: transitionProperty,
	        transitionDuration: transitionProperty + 'Duration',
	        transitionProperty: transitionProperty + 'Property',
	        transitionDelay: transitionProperty + 'Delay'
	      };

	      // -------------------------- Item -------------------------- //

	      function Item(element, layout) {
	        if (!element) {
	          return;
	        }
	        this.element = element;
	        // parent layout class, i.e. Masonry, Isotope, or Packery
	        this.layout = layout;
	        this.position = {
	          x: 0,
	          y: 0
	        };
	        this._create();
	      }

	      // inherit EvEmitter
	      var proto = Item.prototype = Object.create(EvEmitter.prototype);
	      proto.constructor = Item;
	      proto._create = function () {
	        // transition objects
	        this._transn = {
	          ingProperties: {},
	          clean: {},
	          onEnd: {}
	        };
	        this.css({
	          position: 'absolute'
	        });
	      };

	      // trigger specified handler for event type
	      proto.handleEvent = function (event) {
	        var method = 'on' + event.type;
	        if (this[method]) {
	          this[method](event);
	        }
	      };
	      proto.getSize = function () {
	        this.size = getSize(this.element);
	      };

	      /**
	       * apply CSS styles to element
	       * @param {Object} style
	       */
	      proto.css = function (style) {
	        var elemStyle = this.element.style;
	        for (var prop in style) {
	          // use vendor property if available
	          var supportedProp = vendorProperties[prop] || prop;
	          elemStyle[supportedProp] = style[prop];
	        }
	      };

	      // measure position, and sets it
	      proto.getPosition = function () {
	        var style = getComputedStyle(this.element);
	        var isOriginLeft = this.layout._getOption('originLeft');
	        var isOriginTop = this.layout._getOption('originTop');
	        var xValue = style[isOriginLeft ? 'left' : 'right'];
	        var yValue = style[isOriginTop ? 'top' : 'bottom'];
	        var x = parseFloat(xValue);
	        var y = parseFloat(yValue);
	        // convert percent to pixels
	        var layoutSize = this.layout.size;
	        if (xValue.indexOf('%') != -1) {
	          x = x / 100 * layoutSize.width;
	        }
	        if (yValue.indexOf('%') != -1) {
	          y = y / 100 * layoutSize.height;
	        }
	        // clean up 'auto' or other non-integer values
	        x = isNaN(x) ? 0 : x;
	        y = isNaN(y) ? 0 : y;
	        // remove padding from measurement
	        x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
	        y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
	        this.position.x = x;
	        this.position.y = y;
	      };

	      // set settled position, apply padding
	      proto.layoutPosition = function () {
	        var layoutSize = this.layout.size;
	        var style = {};
	        var isOriginLeft = this.layout._getOption('originLeft');
	        var isOriginTop = this.layout._getOption('originTop');

	        // x
	        var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
	        var xProperty = isOriginLeft ? 'left' : 'right';
	        var xResetProperty = isOriginLeft ? 'right' : 'left';
	        var x = this.position.x + layoutSize[xPadding];
	        // set in percentage or pixels
	        style[xProperty] = this.getXValue(x);
	        // reset other property
	        style[xResetProperty] = '';

	        // y
	        var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
	        var yProperty = isOriginTop ? 'top' : 'bottom';
	        var yResetProperty = isOriginTop ? 'bottom' : 'top';
	        var y = this.position.y + layoutSize[yPadding];
	        // set in percentage or pixels
	        style[yProperty] = this.getYValue(y);
	        // reset other property
	        style[yResetProperty] = '';
	        this.css(style);
	        this.emitEvent('layout', [this]);
	      };
	      proto.getXValue = function (x) {
	        var isHorizontal = this.layout._getOption('horizontal');
	        return this.layout.options.percentPosition && !isHorizontal ? x / this.layout.size.width * 100 + '%' : x + 'px';
	      };
	      proto.getYValue = function (y) {
	        var isHorizontal = this.layout._getOption('horizontal');
	        return this.layout.options.percentPosition && isHorizontal ? y / this.layout.size.height * 100 + '%' : y + 'px';
	      };
	      proto._transitionTo = function (x, y) {
	        this.getPosition();
	        // get current x & y from top/left
	        var curX = this.position.x;
	        var curY = this.position.y;
	        var didNotMove = x == this.position.x && y == this.position.y;

	        // save end position
	        this.setPosition(x, y);

	        // if did not move and not transitioning, just go to layout
	        if (didNotMove && !this.isTransitioning) {
	          this.layoutPosition();
	          return;
	        }
	        var transX = x - curX;
	        var transY = y - curY;
	        var transitionStyle = {};
	        transitionStyle.transform = this.getTranslate(transX, transY);
	        this.transition({
	          to: transitionStyle,
	          onTransitionEnd: {
	            transform: this.layoutPosition
	          },
	          isCleaning: true
	        });
	      };
	      proto.getTranslate = function (x, y) {
	        // flip cooridinates if origin on right or bottom
	        var isOriginLeft = this.layout._getOption('originLeft');
	        var isOriginTop = this.layout._getOption('originTop');
	        x = isOriginLeft ? x : -x;
	        y = isOriginTop ? y : -y;
	        return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
	      };

	      // non transition + transform support
	      proto.goTo = function (x, y) {
	        this.setPosition(x, y);
	        this.layoutPosition();
	      };
	      proto.moveTo = proto._transitionTo;
	      proto.setPosition = function (x, y) {
	        this.position.x = parseFloat(x);
	        this.position.y = parseFloat(y);
	      };

	      // ----- transition ----- //

	      /**
	       * @param {Object} style - CSS
	       * @param {Function} onTransitionEnd
	       */

	      // non transition, just trigger callback
	      proto._nonTransition = function (args) {
	        this.css(args.to);
	        if (args.isCleaning) {
	          this._removeStyles(args.to);
	        }
	        for (var prop in args.onTransitionEnd) {
	          args.onTransitionEnd[prop].call(this);
	        }
	      };

	      /**
	       * proper transition
	       * @param {Object} args - arguments
	       *   @param {Object} to - style to transition to
	       *   @param {Object} from - style to start transition from
	       *   @param {Boolean} isCleaning - removes transition styles after transition
	       *   @param {Function} onTransitionEnd - callback
	       */
	      proto.transition = function (args) {
	        // redirect to nonTransition if no transition duration
	        if (!parseFloat(this.layout.options.transitionDuration)) {
	          this._nonTransition(args);
	          return;
	        }
	        var _transition = this._transn;
	        // keep track of onTransitionEnd callback by css property
	        for (var prop in args.onTransitionEnd) {
	          _transition.onEnd[prop] = args.onTransitionEnd[prop];
	        }
	        // keep track of properties that are transitioning
	        for (prop in args.to) {
	          _transition.ingProperties[prop] = true;
	          // keep track of properties to clean up when transition is done
	          if (args.isCleaning) {
	            _transition.clean[prop] = true;
	          }
	        }

	        // set from styles
	        if (args.from) {
	          this.css(args.from);
	          // force redraw. http://blog.alexmaccaw.com/css-transitions
	          this.element.offsetHeight;
	        }
	        // enable transition
	        this.enableTransition(args.to);
	        // set styles that are transitioning
	        this.css(args.to);
	        this.isTransitioning = true;
	      };

	      // dash before all cap letters, including first for
	      // WebkitTransform => -webkit-transform
	      function toDashedAll(str) {
	        return str.replace(/([A-Z])/g, function ($1) {
	          return '-' + $1.toLowerCase();
	        });
	      }
	      var transitionProps = 'opacity,' + toDashedAll(transformProperty);
	      proto.enableTransition = function /* style */
	      () {
	        // HACK changing transitionProperty during a transition
	        // will cause transition to jump
	        if (this.isTransitioning) {
	          return;
	        }

	        // make `transition: foo, bar, baz` from style object
	        // HACK un-comment this when enableTransition can work
	        // while a transition is happening
	        // var transitionValues = [];
	        // for ( var prop in style ) {
	        //   // dash-ify camelCased properties like WebkitTransition
	        //   prop = vendorProperties[ prop ] || prop;
	        //   transitionValues.push( toDashedAll( prop ) );
	        // }
	        // munge number to millisecond, to match stagger
	        var duration = this.layout.options.transitionDuration;
	        duration = typeof duration == 'number' ? duration + 'ms' : duration;
	        // enable transition styles
	        this.css({
	          transitionProperty: transitionProps,
	          transitionDuration: duration,
	          transitionDelay: this.staggerDelay || 0
	        });
	        // listen for transition end event
	        this.element.addEventListener(transitionEndEvent, this, false);
	      };

	      // ----- events ----- //

	      proto.onwebkitTransitionEnd = function (event) {
	        this.ontransitionend(event);
	      };
	      proto.onotransitionend = function (event) {
	        this.ontransitionend(event);
	      };

	      // properties that I munge to make my life easier
	      var dashedVendorProperties = {
	        '-webkit-transform': 'transform'
	      };
	      proto.ontransitionend = function (event) {
	        // disregard bubbled events from children
	        if (event.target !== this.element) {
	          return;
	        }
	        var _transition = this._transn;
	        // get property name of transitioned property, convert to prefix-free
	        var propertyName = dashedVendorProperties[event.propertyName] || event.propertyName;

	        // remove property that has completed transitioning
	        delete _transition.ingProperties[propertyName];
	        // check if any properties are still transitioning
	        if (isEmptyObj(_transition.ingProperties)) {
	          // all properties have completed transitioning
	          this.disableTransition();
	        }
	        // clean style
	        if (propertyName in _transition.clean) {
	          // clean up style
	          this.element.style[event.propertyName] = '';
	          delete _transition.clean[propertyName];
	        }
	        // trigger onTransitionEnd callback
	        if (propertyName in _transition.onEnd) {
	          var onTransitionEnd = _transition.onEnd[propertyName];
	          onTransitionEnd.call(this);
	          delete _transition.onEnd[propertyName];
	        }
	        this.emitEvent('transitionEnd', [this]);
	      };
	      proto.disableTransition = function () {
	        this.removeTransitionStyles();
	        this.element.removeEventListener(transitionEndEvent, this, false);
	        this.isTransitioning = false;
	      };

	      /**
	       * removes style property from element
	       * @param {Object} style
	      **/
	      proto._removeStyles = function (style) {
	        // clean up transition styles
	        var cleanStyle = {};
	        for (var prop in style) {
	          cleanStyle[prop] = '';
	        }
	        this.css(cleanStyle);
	      };
	      var cleanTransitionStyle = {
	        transitionProperty: '',
	        transitionDuration: '',
	        transitionDelay: ''
	      };
	      proto.removeTransitionStyles = function () {
	        // remove transition
	        this.css(cleanTransitionStyle);
	      };

	      // ----- stagger ----- //

	      proto.stagger = function (delay) {
	        delay = isNaN(delay) ? 0 : delay;
	        this.staggerDelay = delay + 'ms';
	      };

	      // ----- show/hide/remove ----- //

	      // remove element from DOM
	      proto.removeElem = function () {
	        this.element.parentNode.removeChild(this.element);
	        // remove display: none
	        this.css({
	          display: ''
	        });
	        this.emitEvent('remove', [this]);
	      };
	      proto.remove = function () {
	        // just remove element if no transition support or no transition
	        if (!parseFloat(this.layout.options.transitionDuration)) {
	          this.removeElem();
	          return;
	        }

	        // start transition
	        this.once('transitionEnd', function () {
	          this.removeElem();
	        });
	        this.hide();
	      };
	      proto.reveal = function () {
	        delete this.isHidden;
	        // remove display: none
	        this.css({
	          display: ''
	        });
	        var options = this.layout.options;
	        var onTransitionEnd = {};
	        var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
	        onTransitionEnd[transitionEndProperty] = this.onRevealTransitionEnd;
	        this.transition({
	          from: options.hiddenStyle,
	          to: options.visibleStyle,
	          isCleaning: true,
	          onTransitionEnd: onTransitionEnd
	        });
	      };
	      proto.onRevealTransitionEnd = function () {
	        // check if still visible
	        // during transition, item may have been hidden
	        if (!this.isHidden) {
	          this.emitEvent('reveal');
	        }
	      };

	      /**
	       * get style property use for hide/reveal transition end
	       * @param {String} styleProperty - hiddenStyle/visibleStyle
	       * @returns {String}
	       */
	      proto.getHideRevealTransitionEndProperty = function (styleProperty) {
	        var optionStyle = this.layout.options[styleProperty];
	        // use opacity
	        if (optionStyle.opacity) {
	          return 'opacity';
	        }
	        // get first property
	        for (var prop in optionStyle) {
	          return prop;
	        }
	      };
	      proto.hide = function () {
	        // set flag
	        this.isHidden = true;
	        // remove display: none
	        this.css({
	          display: ''
	        });
	        var options = this.layout.options;
	        var onTransitionEnd = {};
	        var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
	        onTransitionEnd[transitionEndProperty] = this.onHideTransitionEnd;
	        this.transition({
	          from: options.visibleStyle,
	          to: options.hiddenStyle,
	          // keep hidden stuff hidden
	          isCleaning: true,
	          onTransitionEnd: onTransitionEnd
	        });
	      };
	      proto.onHideTransitionEnd = function () {
	        // check if still hidden
	        // during transition, item may have been un-hidden
	        if (this.isHidden) {
	          this.css({
	            display: 'none'
	          });
	          this.emitEvent('hide');
	        }
	      };
	      proto.destroy = function () {
	        this.css({
	          position: '',
	          left: '',
	          right: '',
	          top: '',
	          bottom: '',
	          transition: '',
	          transform: ''
	        });
	      };
	      return Item;
	    });
	  })(item);
	  return item.exports;
	}

	/*!
	 * Outlayer v2.1.1
	 * the brains and guts of a layout library
	 * MIT license
	 */
	var hasRequiredOutlayer;
	function requireOutlayer() {
	  if (hasRequiredOutlayer) return outlayer.exports;
	  hasRequiredOutlayer = 1;
	  (function (module) {
	    (function (window, factory) {

	      // universal module definition
	      /* jshint strict: false */ /* globals define, module, require */
	      if (module.exports) {
	        // CommonJS - Browserify, Webpack
	        module.exports = factory(window, requireEvEmitter(), requireGetSize(), requireUtils(), requireItem());
	      } else {
	        // browser global
	        window.Outlayer = factory(window, window.EvEmitter, window.getSize, window.fizzyUIUtils, window.Outlayer.Item);
	      }
	    })(window, function factory(window, EvEmitter, getSize, utils, Item) {

	      // ----- vars ----- //
	      var console = window.console;
	      var jQuery = window.jQuery;
	      var noop = function () {};

	      // -------------------------- Outlayer -------------------------- //

	      // globally unique identifiers
	      var GUID = 0;
	      // internal store of all Outlayer intances
	      var instances = {};

	      /**
	       * @param {Element, String} element
	       * @param {Object} options
	       * @constructor
	       */
	      function Outlayer(element, options) {
	        var queryElement = utils.getQueryElement(element);
	        if (!queryElement) {
	          if (console) {
	            console.error('Bad element for ' + this.constructor.namespace + ': ' + (queryElement || element));
	          }
	          return;
	        }
	        this.element = queryElement;
	        // add jQuery
	        if (jQuery) {
	          this.$element = jQuery(this.element);
	        }

	        // options
	        this.options = utils.extend({}, this.constructor.defaults);
	        this.option(options);

	        // add id for Outlayer.getFromElement
	        var id = ++GUID;
	        this.element.outlayerGUID = id; // expando
	        instances[id] = this; // associate via id

	        // kick it off
	        this._create();
	        var isInitLayout = this._getOption('initLayout');
	        if (isInitLayout) {
	          this.layout();
	        }
	      }

	      // settings are for internal use only
	      Outlayer.namespace = 'outlayer';
	      Outlayer.Item = Item;

	      // default options
	      Outlayer.defaults = {
	        containerStyle: {
	          position: 'relative'
	        },
	        initLayout: true,
	        originLeft: true,
	        originTop: true,
	        resize: true,
	        resizeContainer: true,
	        // item options
	        transitionDuration: '0.4s',
	        hiddenStyle: {
	          opacity: 0,
	          transform: 'scale(0.001)'
	        },
	        visibleStyle: {
	          opacity: 1,
	          transform: 'scale(1)'
	        }
	      };
	      var proto = Outlayer.prototype;
	      // inherit EvEmitter
	      utils.extend(proto, EvEmitter.prototype);

	      /**
	       * set options
	       * @param {Object} opts
	       */
	      proto.option = function (opts) {
	        utils.extend(this.options, opts);
	      };

	      /**
	       * get backwards compatible option value, check old name
	       */
	      proto._getOption = function (option) {
	        var oldOption = this.constructor.compatOptions[option];
	        return oldOption && this.options[oldOption] !== undefined ? this.options[oldOption] : this.options[option];
	      };
	      Outlayer.compatOptions = {
	        // currentName: oldName
	        initLayout: 'isInitLayout',
	        horizontal: 'isHorizontal',
	        layoutInstant: 'isLayoutInstant',
	        originLeft: 'isOriginLeft',
	        originTop: 'isOriginTop',
	        resize: 'isResizeBound',
	        resizeContainer: 'isResizingContainer'
	      };
	      proto._create = function () {
	        // get items from children
	        this.reloadItems();
	        // elements that affect layout, but are not laid out
	        this.stamps = [];
	        this.stamp(this.options.stamp);
	        // set container style
	        utils.extend(this.element.style, this.options.containerStyle);

	        // bind resize method
	        var canBindResize = this._getOption('resize');
	        if (canBindResize) {
	          this.bindResize();
	        }
	      };

	      // goes through all children again and gets bricks in proper order
	      proto.reloadItems = function () {
	        // collection of item elements
	        this.items = this._itemize(this.element.children);
	      };

	      /**
	       * turn elements into Outlayer.Items to be used in layout
	       * @param {Array or NodeList or HTMLElement} elems
	       * @returns {Array} items - collection of new Outlayer Items
	       */
	      proto._itemize = function (elems) {
	        var itemElems = this._filterFindItemElements(elems);
	        var Item = this.constructor.Item;

	        // create new Outlayer Items for collection
	        var items = [];
	        for (var i = 0; i < itemElems.length; i++) {
	          var elem = itemElems[i];
	          var item = new Item(elem, this);
	          items.push(item);
	        }
	        return items;
	      };

	      /**
	       * get item elements to be used in layout
	       * @param {Array or NodeList or HTMLElement} elems
	       * @returns {Array} items - item elements
	       */
	      proto._filterFindItemElements = function (elems) {
	        return utils.filterFindElements(elems, this.options.itemSelector);
	      };

	      /**
	       * getter method for getting item elements
	       * @returns {Array} elems - collection of item elements
	       */
	      proto.getItemElements = function () {
	        return this.items.map(function (item) {
	          return item.element;
	        });
	      };

	      // ----- init & layout ----- //

	      /**
	       * lays out all items
	       */
	      proto.layout = function () {
	        this._resetLayout();
	        this._manageStamps();

	        // don't animate first layout
	        var layoutInstant = this._getOption('layoutInstant');
	        var isInstant = layoutInstant !== undefined ? layoutInstant : !this._isLayoutInited;
	        this.layoutItems(this.items, isInstant);

	        // flag for initalized
	        this._isLayoutInited = true;
	      };

	      // _init is alias for layout
	      proto._init = proto.layout;

	      /**
	       * logic before any new layout
	       */
	      proto._resetLayout = function () {
	        this.getSize();
	      };
	      proto.getSize = function () {
	        this.size = getSize(this.element);
	      };

	      /**
	       * get measurement from option, for columnWidth, rowHeight, gutter
	       * if option is String -> get element from selector string, & get size of element
	       * if option is Element -> get size of element
	       * else use option as a number
	       *
	       * @param {String} measurement
	       * @param {String} size - width or height
	       * @private
	       */
	      proto._getMeasurement = function (measurement, size) {
	        var option = this.options[measurement];
	        var elem;
	        if (!option) {
	          // default to 0
	          this[measurement] = 0;
	        } else {
	          // use option as an element
	          if (typeof option == 'string') {
	            elem = this.element.querySelector(option);
	          } else if (option instanceof HTMLElement) {
	            elem = option;
	          }
	          // use size of element, if element
	          this[measurement] = elem ? getSize(elem)[size] : option;
	        }
	      };

	      /**
	       * layout a collection of item elements
	       * @api public
	       */
	      proto.layoutItems = function (items, isInstant) {
	        items = this._getItemsForLayout(items);
	        this._layoutItems(items, isInstant);
	        this._postLayout();
	      };

	      /**
	       * get the items to be laid out
	       * you may want to skip over some items
	       * @param {Array} items
	       * @returns {Array} items
	       */
	      proto._getItemsForLayout = function (items) {
	        return items.filter(function (item) {
	          return !item.isIgnored;
	        });
	      };

	      /**
	       * layout items
	       * @param {Array} items
	       * @param {Boolean} isInstant
	       */
	      proto._layoutItems = function (items, isInstant) {
	        this._emitCompleteOnItems('layout', items);
	        if (!items || !items.length) {
	          // no items, emit event with empty array
	          return;
	        }
	        var queue = [];
	        items.forEach(function (item) {
	          // get x/y object from method
	          var position = this._getItemLayoutPosition(item);
	          // enqueue
	          position.item = item;
	          position.isInstant = isInstant || item.isLayoutInstant;
	          queue.push(position);
	        }, this);
	        this._processLayoutQueue(queue);
	      };

	      /**
	       * get item layout position
	       * @param {Outlayer.Item} item
	       * @returns {Object} x and y position
	       */
	      proto._getItemLayoutPosition = function /* item */
	      () {
	        return {
	          x: 0,
	          y: 0
	        };
	      };

	      /**
	       * iterate over array and position each item
	       * Reason being - separating this logic prevents 'layout invalidation'
	       * thx @paul_irish
	       * @param {Array} queue
	       */
	      proto._processLayoutQueue = function (queue) {
	        this.updateStagger();
	        queue.forEach(function (obj, i) {
	          this._positionItem(obj.item, obj.x, obj.y, obj.isInstant, i);
	        }, this);
	      };

	      // set stagger from option in milliseconds number
	      proto.updateStagger = function () {
	        var stagger = this.options.stagger;
	        if (stagger === null || stagger === undefined) {
	          this.stagger = 0;
	          return;
	        }
	        this.stagger = getMilliseconds(stagger);
	        return this.stagger;
	      };

	      /**
	       * Sets position of item in DOM
	       * @param {Outlayer.Item} item
	       * @param {Number} x - horizontal position
	       * @param {Number} y - vertical position
	       * @param {Boolean} isInstant - disables transitions
	       */
	      proto._positionItem = function (item, x, y, isInstant, i) {
	        if (isInstant) {
	          // if not transition, just set CSS
	          item.goTo(x, y);
	        } else {
	          item.stagger(i * this.stagger);
	          item.moveTo(x, y);
	        }
	      };

	      /**
	       * Any logic you want to do after each layout,
	       * i.e. size the container
	       */
	      proto._postLayout = function () {
	        this.resizeContainer();
	      };
	      proto.resizeContainer = function () {
	        var isResizingContainer = this._getOption('resizeContainer');
	        if (!isResizingContainer) {
	          return;
	        }
	        var size = this._getContainerSize();
	        if (size) {
	          this._setContainerMeasure(size.width, true);
	          this._setContainerMeasure(size.height, false);
	        }
	      };

	      /**
	       * Sets width or height of container if returned
	       * @returns {Object} size
	       *   @param {Number} width
	       *   @param {Number} height
	       */
	      proto._getContainerSize = noop;

	      /**
	       * @param {Number} measure - size of width or height
	       * @param {Boolean} isWidth
	       */
	      proto._setContainerMeasure = function (measure, isWidth) {
	        if (measure === undefined) {
	          return;
	        }
	        var elemSize = this.size;
	        // add padding and border width if border box
	        if (elemSize.isBorderBox) {
	          measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + elemSize.borderLeftWidth + elemSize.borderRightWidth : elemSize.paddingBottom + elemSize.paddingTop + elemSize.borderTopWidth + elemSize.borderBottomWidth;
	        }
	        measure = Math.max(measure, 0);
	        this.element.style[isWidth ? 'width' : 'height'] = measure + 'px';
	      };

	      /**
	       * emit eventComplete on a collection of items events
	       * @param {String} eventName
	       * @param {Array} items - Outlayer.Items
	       */
	      proto._emitCompleteOnItems = function (eventName, items) {
	        var _this = this;
	        function onComplete() {
	          _this.dispatchEvent(eventName + 'Complete', null, [items]);
	        }
	        var count = items.length;
	        if (!items || !count) {
	          onComplete();
	          return;
	        }
	        var doneCount = 0;
	        function tick() {
	          doneCount++;
	          if (doneCount == count) {
	            onComplete();
	          }
	        }

	        // bind callback
	        items.forEach(function (item) {
	          item.once(eventName, tick);
	        });
	      };

	      /**
	       * emits events via EvEmitter and jQuery events
	       * @param {String} type - name of event
	       * @param {Event} event - original event
	       * @param {Array} args - extra arguments
	       */
	      proto.dispatchEvent = function (type, event, args) {
	        // add original event to arguments
	        var emitArgs = event ? [event].concat(args) : args;
	        this.emitEvent(type, emitArgs);
	        if (jQuery) {
	          // set this.$element
	          this.$element = this.$element || jQuery(this.element);
	          if (event) {
	            // create jQuery event
	            var $event = jQuery.Event(event);
	            $event.type = type;
	            this.$element.trigger($event, args);
	          } else {
	            // just trigger with type if no event available
	            this.$element.trigger(type, args);
	          }
	        }
	      };

	      // -------------------------- ignore & stamps -------------------------- //

	      /**
	       * keep item in collection, but do not lay it out
	       * ignored items do not get skipped in layout
	       * @param {Element} elem
	       */
	      proto.ignore = function (elem) {
	        var item = this.getItem(elem);
	        if (item) {
	          item.isIgnored = true;
	        }
	      };

	      /**
	       * return item to layout collection
	       * @param {Element} elem
	       */
	      proto.unignore = function (elem) {
	        var item = this.getItem(elem);
	        if (item) {
	          delete item.isIgnored;
	        }
	      };

	      /**
	       * adds elements to stamps
	       * @param {NodeList, Array, Element, or String} elems
	       */
	      proto.stamp = function (elems) {
	        elems = this._find(elems);
	        if (!elems) {
	          return;
	        }
	        this.stamps = this.stamps.concat(elems);
	        // ignore
	        elems.forEach(this.ignore, this);
	      };

	      /**
	       * removes elements to stamps
	       * @param {NodeList, Array, or Element} elems
	       */
	      proto.unstamp = function (elems) {
	        elems = this._find(elems);
	        if (!elems) {
	          return;
	        }
	        elems.forEach(function (elem) {
	          // filter out removed stamp elements
	          utils.removeFrom(this.stamps, elem);
	          this.unignore(elem);
	        }, this);
	      };

	      /**
	       * finds child elements
	       * @param {NodeList, Array, Element, or String} elems
	       * @returns {Array} elems
	       */
	      proto._find = function (elems) {
	        if (!elems) {
	          return;
	        }
	        // if string, use argument as selector string
	        if (typeof elems == 'string') {
	          elems = this.element.querySelectorAll(elems);
	        }
	        elems = utils.makeArray(elems);
	        return elems;
	      };
	      proto._manageStamps = function () {
	        if (!this.stamps || !this.stamps.length) {
	          return;
	        }
	        this._getBoundingRect();
	        this.stamps.forEach(this._manageStamp, this);
	      };

	      // update boundingLeft / Top
	      proto._getBoundingRect = function () {
	        // get bounding rect for container element
	        var boundingRect = this.element.getBoundingClientRect();
	        var size = this.size;
	        this._boundingRect = {
	          left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
	          top: boundingRect.top + size.paddingTop + size.borderTopWidth,
	          right: boundingRect.right - (size.paddingRight + size.borderRightWidth),
	          bottom: boundingRect.bottom - (size.paddingBottom + size.borderBottomWidth)
	        };
	      };

	      /**
	       * @param {Element} stamp
	      **/
	      proto._manageStamp = noop;

	      /**
	       * get x/y position of element relative to container element
	       * @param {Element} elem
	       * @returns {Object} offset - has left, top, right, bottom
	       */
	      proto._getElementOffset = function (elem) {
	        var boundingRect = elem.getBoundingClientRect();
	        var thisRect = this._boundingRect;
	        var size = getSize(elem);
	        var offset = {
	          left: boundingRect.left - thisRect.left - size.marginLeft,
	          top: boundingRect.top - thisRect.top - size.marginTop,
	          right: thisRect.right - boundingRect.right - size.marginRight,
	          bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
	        };
	        return offset;
	      };

	      // -------------------------- resize -------------------------- //

	      // enable event handlers for listeners
	      // i.e. resize -> onresize
	      proto.handleEvent = utils.handleEvent;

	      /**
	       * Bind layout to window resizing
	       */
	      proto.bindResize = function () {
	        window.addEventListener('resize', this);
	        this.isResizeBound = true;
	      };

	      /**
	       * Unbind layout to window resizing
	       */
	      proto.unbindResize = function () {
	        window.removeEventListener('resize', this);
	        this.isResizeBound = false;
	      };
	      proto.onresize = function () {
	        this.resize();
	      };
	      utils.debounceMethod(Outlayer, 'onresize', 100);
	      proto.resize = function () {
	        // don't trigger if size did not change
	        // or if resize was unbound. See #9
	        if (!this.isResizeBound || !this.needsResizeLayout()) {
	          return;
	        }
	        this.layout();
	      };

	      /**
	       * check if layout is needed post layout
	       * @returns Boolean
	       */
	      proto.needsResizeLayout = function () {
	        var size = getSize(this.element);
	        // check that this.size and size are there
	        // IE8 triggers resize on body size change, so they might not be
	        var hasSizes = this.size && size;
	        return hasSizes && size.innerWidth !== this.size.innerWidth;
	      };

	      // -------------------------- methods -------------------------- //

	      /**
	       * add items to Outlayer instance
	       * @param {Array or NodeList or Element} elems
	       * @returns {Array} items - Outlayer.Items
	      **/
	      proto.addItems = function (elems) {
	        var items = this._itemize(elems);
	        // add items to collection
	        if (items.length) {
	          this.items = this.items.concat(items);
	        }
	        return items;
	      };

	      /**
	       * Layout newly-appended item elements
	       * @param {Array or NodeList or Element} elems
	       */
	      proto.appended = function (elems) {
	        var items = this.addItems(elems);
	        if (!items.length) {
	          return;
	        }
	        // layout and reveal just the new items
	        this.layoutItems(items, true);
	        this.reveal(items);
	      };

	      /**
	       * Layout prepended elements
	       * @param {Array or NodeList or Element} elems
	       */
	      proto.prepended = function (elems) {
	        var items = this._itemize(elems);
	        if (!items.length) {
	          return;
	        }
	        // add items to beginning of collection
	        var previousItems = this.items.slice(0);
	        this.items = items.concat(previousItems);
	        // start new layout
	        this._resetLayout();
	        this._manageStamps();
	        // layout new stuff without transition
	        this.layoutItems(items, true);
	        this.reveal(items);
	        // layout previous items
	        this.layoutItems(previousItems);
	      };

	      /**
	       * reveal a collection of items
	       * @param {Array of Outlayer.Items} items
	       */
	      proto.reveal = function (items) {
	        this._emitCompleteOnItems('reveal', items);
	        if (!items || !items.length) {
	          return;
	        }
	        var stagger = this.updateStagger();
	        items.forEach(function (item, i) {
	          item.stagger(i * stagger);
	          item.reveal();
	        });
	      };

	      /**
	       * hide a collection of items
	       * @param {Array of Outlayer.Items} items
	       */
	      proto.hide = function (items) {
	        this._emitCompleteOnItems('hide', items);
	        if (!items || !items.length) {
	          return;
	        }
	        var stagger = this.updateStagger();
	        items.forEach(function (item, i) {
	          item.stagger(i * stagger);
	          item.hide();
	        });
	      };

	      /**
	       * reveal item elements
	       * @param {Array}, {Element}, {NodeList} items
	       */
	      proto.revealItemElements = function (elems) {
	        var items = this.getItems(elems);
	        this.reveal(items);
	      };

	      /**
	       * hide item elements
	       * @param {Array}, {Element}, {NodeList} items
	       */
	      proto.hideItemElements = function (elems) {
	        var items = this.getItems(elems);
	        this.hide(items);
	      };

	      /**
	       * get Outlayer.Item, given an Element
	       * @param {Element} elem
	       * @param {Function} callback
	       * @returns {Outlayer.Item} item
	       */
	      proto.getItem = function (elem) {
	        // loop through items to get the one that matches
	        for (var i = 0; i < this.items.length; i++) {
	          var item = this.items[i];
	          if (item.element == elem) {
	            // return item
	            return item;
	          }
	        }
	      };

	      /**
	       * get collection of Outlayer.Items, given Elements
	       * @param {Array} elems
	       * @returns {Array} items - Outlayer.Items
	       */
	      proto.getItems = function (elems) {
	        elems = utils.makeArray(elems);
	        var items = [];
	        elems.forEach(function (elem) {
	          var item = this.getItem(elem);
	          if (item) {
	            items.push(item);
	          }
	        }, this);
	        return items;
	      };

	      /**
	       * remove element(s) from instance and DOM
	       * @param {Array or NodeList or Element} elems
	       */
	      proto.remove = function (elems) {
	        var removeItems = this.getItems(elems);
	        this._emitCompleteOnItems('remove', removeItems);

	        // bail if no items to remove
	        if (!removeItems || !removeItems.length) {
	          return;
	        }
	        removeItems.forEach(function (item) {
	          item.remove();
	          // remove item from collection
	          utils.removeFrom(this.items, item);
	        }, this);
	      };

	      // ----- destroy ----- //

	      // remove and disable Outlayer instance
	      proto.destroy = function () {
	        // clean up dynamic styles
	        var style = this.element.style;
	        style.height = '';
	        style.position = '';
	        style.width = '';
	        // destroy items
	        this.items.forEach(function (item) {
	          item.destroy();
	        });
	        this.unbindResize();
	        var id = this.element.outlayerGUID;
	        delete instances[id]; // remove reference to instance by id
	        delete this.element.outlayerGUID;
	        // remove data for jQuery
	        if (jQuery) {
	          jQuery.removeData(this.element, this.constructor.namespace);
	        }
	      };

	      // -------------------------- data -------------------------- //

	      /**
	       * get Outlayer instance from element
	       * @param {Element} elem
	       * @returns {Outlayer}
	       */
	      Outlayer.data = function (elem) {
	        elem = utils.getQueryElement(elem);
	        var id = elem && elem.outlayerGUID;
	        return id && instances[id];
	      };

	      // -------------------------- create Outlayer class -------------------------- //

	      /**
	       * create a layout class
	       * @param {String} namespace
	       */
	      Outlayer.create = function (namespace, options) {
	        // sub-class Outlayer
	        var Layout = subclass(Outlayer);
	        // apply new options and compatOptions
	        Layout.defaults = utils.extend({}, Outlayer.defaults);
	        utils.extend(Layout.defaults, options);
	        Layout.compatOptions = utils.extend({}, Outlayer.compatOptions);
	        Layout.namespace = namespace;
	        Layout.data = Outlayer.data;

	        // sub-class Item
	        Layout.Item = subclass(Item);

	        // -------------------------- declarative -------------------------- //

	        utils.htmlInit(Layout, namespace);

	        // -------------------------- jQuery bridge -------------------------- //

	        // make into jQuery plugin
	        if (jQuery && jQuery.bridget) {
	          jQuery.bridget(namespace, Layout);
	        }
	        return Layout;
	      };
	      function subclass(Parent) {
	        function SubClass() {
	          Parent.apply(this, arguments);
	        }
	        SubClass.prototype = Object.create(Parent.prototype);
	        SubClass.prototype.constructor = SubClass;
	        return SubClass;
	      }

	      // ----- helpers ----- //

	      // how many milliseconds are in each unit
	      var msUnits = {
	        ms: 1,
	        s: 1000
	      };

	      // munge time-like parameter into millisecond number
	      // '0.4s' -> 40
	      function getMilliseconds(time) {
	        if (typeof time == 'number') {
	          return time;
	        }
	        var matches = time.match(/(^\d*\.?\d*)(\w*)/);
	        var num = matches && matches[1];
	        var unit = matches && matches[2];
	        if (!num.length) {
	          return 0;
	        }
	        num = parseFloat(num);
	        var mult = msUnits[unit] || 1;
	        return num * mult;
	      }

	      // ----- fin ----- //

	      // back in global
	      Outlayer.Item = Item;
	      return Outlayer;
	    });
	  })(outlayer);
	  return outlayer.exports;
	}

	/*!
	 * Masonry v4.2.2
	 * Cascading grid layout library
	 * https://masonry.desandro.com
	 * MIT License
	 * by David DeSandro
	 */
	var hasRequiredMasonry;
	function requireMasonry() {
	  if (hasRequiredMasonry) return masonry.exports;
	  hasRequiredMasonry = 1;
	  (function (module) {
	    (function (window, factory) {
	      // universal module definition
	      /* jshint strict: false */ /*globals define, module, require */
	      if (module.exports) {
	        // CommonJS
	        module.exports = factory(requireOutlayer(), requireGetSize());
	      } else {
	        // browser global
	        window.Masonry = factory(window.Outlayer, window.getSize);
	      }
	    })(window, function factory(Outlayer, getSize) {

	      // -------------------------- masonryDefinition -------------------------- //

	      // create an Outlayer layout class
	      var Masonry = Outlayer.create('masonry');
	      // isFitWidth -> fitWidth
	      Masonry.compatOptions.fitWidth = 'isFitWidth';
	      var proto = Masonry.prototype;
	      proto._resetLayout = function () {
	        this.getSize();
	        this._getMeasurement('columnWidth', 'outerWidth');
	        this._getMeasurement('gutter', 'outerWidth');
	        this.measureColumns();

	        // reset column Y
	        this.colYs = [];
	        for (var i = 0; i < this.cols; i++) {
	          this.colYs.push(0);
	        }
	        this.maxY = 0;
	        this.horizontalColIndex = 0;
	      };
	      proto.measureColumns = function () {
	        this.getContainerWidth();
	        // if columnWidth is 0, default to outerWidth of first item
	        if (!this.columnWidth) {
	          var firstItem = this.items[0];
	          var firstItemElem = firstItem && firstItem.element;
	          // columnWidth fall back to item of first element
	          this.columnWidth = firstItemElem && getSize(firstItemElem).outerWidth ||
	          // if first elem has no width, default to size of container
	          this.containerWidth;
	        }
	        var columnWidth = this.columnWidth += this.gutter;

	        // calculate columns
	        var containerWidth = this.containerWidth + this.gutter;
	        var cols = containerWidth / columnWidth;
	        // fix rounding errors, typically with gutters
	        var excess = columnWidth - containerWidth % columnWidth;
	        // if overshoot is less than a pixel, round up, otherwise floor it
	        var mathMethod = excess && excess < 1 ? 'round' : 'floor';
	        cols = Math[mathMethod](cols);
	        this.cols = Math.max(cols, 1);
	      };
	      proto.getContainerWidth = function () {
	        // container is parent if fit width
	        var isFitWidth = this._getOption('fitWidth');
	        var container = isFitWidth ? this.element.parentNode : this.element;
	        // check that this.size and size are there
	        // IE8 triggers resize on body size change, so they might not be
	        var size = getSize(container);
	        this.containerWidth = size && size.innerWidth;
	      };
	      proto._getItemLayoutPosition = function (item) {
	        item.getSize();
	        // how many columns does this brick span
	        var remainder = item.size.outerWidth % this.columnWidth;
	        var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
	        // round if off by 1 pixel, otherwise use ceil
	        var colSpan = Math[mathMethod](item.size.outerWidth / this.columnWidth);
	        colSpan = Math.min(colSpan, this.cols);
	        // use horizontal or top column position
	        var colPosMethod = this.options.horizontalOrder ? '_getHorizontalColPosition' : '_getTopColPosition';
	        var colPosition = this[colPosMethod](colSpan, item);
	        // position the brick
	        var position = {
	          x: this.columnWidth * colPosition.col,
	          y: colPosition.y
	        };
	        // apply setHeight to necessary columns
	        var setHeight = colPosition.y + item.size.outerHeight;
	        var setMax = colSpan + colPosition.col;
	        for (var i = colPosition.col; i < setMax; i++) {
	          this.colYs[i] = setHeight;
	        }
	        return position;
	      };
	      proto._getTopColPosition = function (colSpan) {
	        var colGroup = this._getTopColGroup(colSpan);
	        // get the minimum Y value from the columns
	        var minimumY = Math.min.apply(Math, colGroup);
	        return {
	          col: colGroup.indexOf(minimumY),
	          y: minimumY
	        };
	      };

	      /**
	       * @param {Number} colSpan - number of columns the element spans
	       * @returns {Array} colGroup
	       */
	      proto._getTopColGroup = function (colSpan) {
	        if (colSpan < 2) {
	          // if brick spans only one column, use all the column Ys
	          return this.colYs;
	        }
	        var colGroup = [];
	        // how many different places could this brick fit horizontally
	        var groupCount = this.cols + 1 - colSpan;
	        // for each group potential horizontal position
	        for (var i = 0; i < groupCount; i++) {
	          colGroup[i] = this._getColGroupY(i, colSpan);
	        }
	        return colGroup;
	      };
	      proto._getColGroupY = function (col, colSpan) {
	        if (colSpan < 2) {
	          return this.colYs[col];
	        }
	        // make an array of colY values for that one group
	        var groupColYs = this.colYs.slice(col, col + colSpan);
	        // and get the max value of the array
	        return Math.max.apply(Math, groupColYs);
	      };

	      // get column position based on horizontal index. #873
	      proto._getHorizontalColPosition = function (colSpan, item) {
	        var col = this.horizontalColIndex % this.cols;
	        var isOver = colSpan > 1 && col + colSpan > this.cols;
	        // shift to next row if item can't fit on current row
	        col = isOver ? 0 : col;
	        // don't let zero-size items take up space
	        var hasSize = item.size.outerWidth && item.size.outerHeight;
	        this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex;
	        return {
	          col: col,
	          y: this._getColGroupY(col, colSpan)
	        };
	      };
	      proto._manageStamp = function (stamp) {
	        var stampSize = getSize(stamp);
	        var offset = this._getElementOffset(stamp);
	        // get the columns that this stamp affects
	        var isOriginLeft = this._getOption('originLeft');
	        var firstX = isOriginLeft ? offset.left : offset.right;
	        var lastX = firstX + stampSize.outerWidth;
	        var firstCol = Math.floor(firstX / this.columnWidth);
	        firstCol = Math.max(0, firstCol);
	        var lastCol = Math.floor(lastX / this.columnWidth);
	        // lastCol should not go over if multiple of columnWidth #425
	        lastCol -= lastX % this.columnWidth ? 0 : 1;
	        lastCol = Math.min(this.cols - 1, lastCol);
	        // set colYs to bottom of the stamp

	        var isOriginTop = this._getOption('originTop');
	        var stampMaxY = (isOriginTop ? offset.top : offset.bottom) + stampSize.outerHeight;
	        for (var i = firstCol; i <= lastCol; i++) {
	          this.colYs[i] = Math.max(stampMaxY, this.colYs[i]);
	        }
	      };
	      proto._getContainerSize = function () {
	        this.maxY = Math.max.apply(Math, this.colYs);
	        var size = {
	          height: this.maxY
	        };
	        if (this._getOption('fitWidth')) {
	          size.width = this._getContainerFitWidth();
	        }
	        return size;
	      };
	      proto._getContainerFitWidth = function () {
	        var unusedCols = 0;
	        // count unused columns
	        var i = this.cols;
	        while (--i) {
	          if (this.colYs[i] !== 0) {
	            break;
	          }
	          unusedCols++;
	        }
	        // fit container to columns that have been used
	        return (this.cols - unusedCols) * this.columnWidth - this.gutter;
	      };
	      proto.needsResizeLayout = function () {
	        var previousWidth = this.containerWidth;
	        this.getContainerWidth();
	        return previousWidth != this.containerWidth;
	      };
	      return Masonry;
	    });
	  })(masonry);
	  return masonry.exports;
	}

	var masonryExports = requireMasonry();
	const Masonry = /*@__PURE__*/getDefaultExportFromCjs(masonryExports);

	/* Export what's needed to the global namespace. */
	const _global = typeof globalThis !== 'undefined' ? globalThis : self;
	_global.Masonry = Masonry;

}));
//# sourceMappingURL=index.js.map
