[
  {
    "path": ".github/contributing.md",
    "content": "## Submitting issues\n\n### Reduced test case required\n\nAll bug reports and problem issues require a [**reduced test case**](http://css-tricks.com/reduced-test-cases/). Create one by forking any one of the [CodePen examples](http://codepen.io/desandro/tag/masonry-docs) from [the docs](http://masonry.desanro.com).\n\n**CodePens**\n\n+ [Basic layout](http://codepen.io/desandro/pen/osFxj)\n+ [Fluid layout](http://codepen.io/desandro/pen/JFpeg)\n+ [imagesLoaded progress](http://codepen.io/desandro/pen/RPKgEN)\n+ [layout method](http://codepen.io/desandro/pen/JdEyYQ)\n\n**Test cases**\n\n+ A reduced test case clearly demonstrates the bug or issue.\n+ It contains the bare minimum HTML, CSS, and JavaScript required to demonstrate the bug.\n+ A link to your production site is **not** a reduced test case.\n\nProviding a reduced test case is the best way to get your issue addressed. Without a reduced test case, your issue may be closed.\n"
  },
  {
    "path": ".github/issue_template.md",
    "content": "<!-- Thanks for submitting an issue! All bug reports and problem issues require a **reduced test case**. Create one by forking any one of the CodePen examples from the docs. See guidelines link above. -->\n\n**Test case:** http://codepen.io/desandro/pen/osFxj\n"
  },
  {
    "path": ".gitignore",
    "content": "components/\nbower_components/\nnode_modules/\nsandbox/**/bundle.js\n"
  },
  {
    "path": ".jshintrc",
    "content": "{\n  \"browser\": true,\n  \"devel\": false,\n  \"strict\": true,\n  \"undef\": true,\n  \"unused\": true\n}\n"
  },
  {
    "path": "README.md",
    "content": "# Masonry\n\n_Cascading grid layout library_\n\nMasonry works by placing elements in optimal position based on available vertical space, sort of like a mason fitting stones in a wall. You’ve probably seen it in use all over the Internet.\n\nSee [masonry.desandro.com](https://masonry.desandro.com) for complete docs and demos.\n\n## Install\n\n### Download\n\n+ [masonry.pkgd.js](https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.js) un-minified, or\n+ [masonry.pkgd.min.js](https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js) minified\n\n### CDN\n\nLink directly to Masonry files on [unpkg](https://unpkg.com/).\n\n``` html\n<script src=\"https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.js\"></script>\n<!-- or -->\n<script src=\"https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js\"></script>\n```\n\n### Package managers\n\n[npm](https://www.npmjs.com/package/masonry-layout): `npm install masonry-layout --save`\n\nBower: `bower install masonry-layout --save`\n\n## Support Masonry development\n\nMasonry has been actively maintained and improved upon for 8 years, with 900 GitHub issues closed. Please consider supporting its development by [purchasing a license for one of Metafizzy's commercial libraries](https://metafizzy.co).\n\n## Initialize\n\nWith jQuery\n\n``` js\n$('.grid').masonry({\n  // options...\n  itemSelector: '.grid-item',\n  columnWidth: 200\n});\n```\n\nWith vanilla JavaScript\n\n``` js\n// vanilla JS\n// init with element\nvar grid = document.querySelector('.grid');\nvar msnry = new Masonry( grid, {\n  // options...\n  itemSelector: '.grid-item',\n  columnWidth: 200\n});\n\n// init with selector\nvar msnry = new Masonry( '.grid', {\n  // options...\n});\n```\n\nWith HTML\n\nAdd a `data-masonry` attribute to your element. Options can be set in JSON in the value.\n\n``` html\n<div class=\"grid\" data-masonry='{ \"itemSelector\": \".grid-item\", \"columnWidth\": 200 }'>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item\"></div>\n  ...\n</div>\n```\n\n## License\n\nMasonry is released under the [MIT license](http://desandro.mit-license.org). Have at it.\n\n* * *\n\nMade by David DeSandro\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"masonry-layout\",\n  \"description\": \"Cascading grid layout library\",\n  \"main\": \"masonry.js\",\n  \"dependencies\": {\n    \"get-size\": \"^2.0.2\",\n    \"outlayer\": \"^2.1.0\"\n  },\n  \"devDependencies\": {\n    \"jquery-bridget\": \"~2.0.0\",\n    \"qunit\": \"^1.12\",\n    \"jquery\": \">=1.4.3 <4\"\n  },\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\",\n    \"sandbox/\",\n    \"gulpfile.js\",\n    \"package.json\",\n    \"composer.json\"\n  ],\n  \"homepage\": \"https://masonry.desandro.com\",\n  \"authors\": [\n    \"David DeSandro\"\n  ],\n  \"keywords\": [\n    \"masonry\",\n    \"layout\",\n    \"outlayer\"\n  ],\n  \"license\": \"MIT\",\n  \"moduleType\": [\n    \"amd\",\n    \"globals\",\n    \"node\"\n  ]\n}\n"
  },
  {
    "path": "composer.json",
    "content": "{\n  \"name\": \"desandro/masonry\",\n  \"description\": \"Cascading grid layout library\",\n  \"type\": \"component\",\n  \"keywords\": [\"javascript\", \"library\", \"grid\", \"browser\", \"dom\", \"layout\", \"outlayer\"],\n  \"homepage\": \"https://masonry.desandro.com\",\n  \"license\": \"MIT\",\n  \"authors\": [\n    {\n      \"name\": \"David DeSandro\",\n      \"homepage\": \"http://desandro.com/\",\n      \"role\": \"developer\"\n    }\n  ]\n}\n"
  },
  {
    "path": "dist/masonry.pkgd.js",
    "content": "/*!\n * Masonry PACKAGED v4.2.2\n * Cascading grid layout library\n * https://masonry.desandro.com\n * MIT License\n * by David DeSandro\n */\n\n/**\n * Bridget makes jQuery widgets\n * v2.0.1\n * MIT license\n */\n\n/* jshint browser: true, strict: true, undef: true, unused: true */\n\n( function( window, factory ) {\n  // universal module definition\n  /*jshint strict: false */ /* globals define, module, require */\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {\n      return factory( window, jQuery );\n    });\n  } else if ( typeof module == 'object' && module.exports ) {\n    // CommonJS\n    module.exports = factory(\n      window,\n      require('jquery')\n    );\n  } else {\n    // browser global\n    window.jQueryBridget = factory(\n      window,\n      window.jQuery\n    );\n  }\n\n}( window, function factory( window, jQuery ) {\n'use strict';\n\n// ----- utils ----- //\n\nvar arraySlice = Array.prototype.slice;\n\n// helper function for logging errors\n// $.error breaks jQuery chaining\nvar console = window.console;\nvar logError = typeof console == 'undefined' ? function() {} :\n  function( message ) {\n    console.error( message );\n  };\n\n// ----- jQueryBridget ----- //\n\nfunction jQueryBridget( namespace, PluginClass, $ ) {\n  $ = $ || jQuery || window.jQuery;\n  if ( !$ ) {\n    return;\n  }\n\n  // add option method -> $().plugin('option', {...})\n  if ( !PluginClass.prototype.option ) {\n    // option setter\n    PluginClass.prototype.option = function( opts ) {\n      // bail out if not an object\n      if ( !$.isPlainObject( opts ) ){\n        return;\n      }\n      this.options = $.extend( true, this.options, opts );\n    };\n  }\n\n  // make jQuery plugin\n  $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {\n    if ( typeof arg0 == 'string' ) {\n      // method call $().plugin( 'methodName', { options } )\n      // shift arguments by 1\n      var args = arraySlice.call( arguments, 1 );\n      return methodCall( this, arg0, args );\n    }\n    // just $().plugin({ options })\n    plainCall( this, arg0 );\n    return this;\n  };\n\n  // $().plugin('methodName')\n  function methodCall( $elems, methodName, args ) {\n    var returnValue;\n    var pluginMethodStr = '$().' + namespace + '(\"' + methodName + '\")';\n\n    $elems.each( function( i, elem ) {\n      // get instance\n      var instance = $.data( elem, namespace );\n      if ( !instance ) {\n        logError( namespace + ' not initialized. Cannot call methods, i.e. ' +\n          pluginMethodStr );\n        return;\n      }\n\n      var method = instance[ methodName ];\n      if ( !method || methodName.charAt(0) == '_' ) {\n        logError( pluginMethodStr + ' is not a valid method' );\n        return;\n      }\n\n      // apply method, get return value\n      var value = method.apply( instance, args );\n      // set return value if value is returned, use only first value\n      returnValue = returnValue === undefined ? value : returnValue;\n    });\n\n    return returnValue !== undefined ? returnValue : $elems;\n  }\n\n  function plainCall( $elems, options ) {\n    $elems.each( function( i, elem ) {\n      var instance = $.data( elem, namespace );\n      if ( instance ) {\n        // set options & init\n        instance.option( options );\n        instance._init();\n      } else {\n        // initialize new instance\n        instance = new PluginClass( elem, options );\n        $.data( elem, namespace, instance );\n      }\n    });\n  }\n\n  updateJQuery( $ );\n\n}\n\n// ----- updateJQuery ----- //\n\n// set $.bridget for v1 backwards compatibility\nfunction updateJQuery( $ ) {\n  if ( !$ || ( $ && $.bridget ) ) {\n    return;\n  }\n  $.bridget = jQueryBridget;\n}\n\nupdateJQuery( jQuery || window.jQuery );\n\n// -----  ----- //\n\nreturn jQueryBridget;\n\n}));\n\n/**\n * EvEmitter v1.1.0\n * Lil' event emitter\n * MIT License\n */\n\n/* jshint unused: true, undef: true, strict: true */\n\n( function( global, factory ) {\n  // universal module definition\n  /* jshint strict: false */ /* globals define, module, window */\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD - RequireJS\n    define( 'ev-emitter/ev-emitter',factory );\n  } else if ( typeof module == 'object' && module.exports ) {\n    // CommonJS - Browserify, Webpack\n    module.exports = factory();\n  } else {\n    // Browser globals\n    global.EvEmitter = factory();\n  }\n\n}( typeof window != 'undefined' ? window : this, function() {\n\n\n\nfunction EvEmitter() {}\n\nvar proto = EvEmitter.prototype;\n\nproto.on = function( eventName, listener ) {\n  if ( !eventName || !listener ) {\n    return;\n  }\n  // set events hash\n  var events = this._events = this._events || {};\n  // set listeners array\n  var listeners = events[ eventName ] = events[ eventName ] || [];\n  // only add once\n  if ( listeners.indexOf( listener ) == -1 ) {\n    listeners.push( listener );\n  }\n\n  return this;\n};\n\nproto.once = function( eventName, listener ) {\n  if ( !eventName || !listener ) {\n    return;\n  }\n  // add event\n  this.on( eventName, listener );\n  // set once flag\n  // set onceEvents hash\n  var onceEvents = this._onceEvents = this._onceEvents || {};\n  // set onceListeners object\n  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};\n  // set flag\n  onceListeners[ listener ] = true;\n\n  return this;\n};\n\nproto.off = function( eventName, listener ) {\n  var listeners = this._events && this._events[ eventName ];\n  if ( !listeners || !listeners.length ) {\n    return;\n  }\n  var index = listeners.indexOf( listener );\n  if ( index != -1 ) {\n    listeners.splice( index, 1 );\n  }\n\n  return this;\n};\n\nproto.emitEvent = function( eventName, args ) {\n  var listeners = this._events && this._events[ eventName ];\n  if ( !listeners || !listeners.length ) {\n    return;\n  }\n  // copy over to avoid interference if .off() in listener\n  listeners = listeners.slice(0);\n  args = args || [];\n  // once stuff\n  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];\n\n  for ( var i=0; i < listeners.length; i++ ) {\n    var listener = listeners[i]\n    var isOnce = onceListeners && onceListeners[ listener ];\n    if ( isOnce ) {\n      // remove listener\n      // remove before trigger to prevent recursion\n      this.off( eventName, listener );\n      // unset once flag\n      delete onceListeners[ listener ];\n    }\n    // trigger listener\n    listener.apply( this, args );\n  }\n\n  return this;\n};\n\nproto.allOff = function() {\n  delete this._events;\n  delete this._onceEvents;\n};\n\nreturn EvEmitter;\n\n}));\n\n/*!\n * getSize v2.0.3\n * measure size of elements\n * MIT license\n */\n\n/* jshint browser: true, strict: true, undef: true, unused: true */\n/* globals console: false */\n\n( function( window, factory ) {\n  /* jshint strict: false */ /* globals define, module */\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( 'get-size/get-size',factory );\n  } else if ( typeof module == 'object' && module.exports ) {\n    // CommonJS\n    module.exports = factory();\n  } else {\n    // browser global\n    window.getSize = factory();\n  }\n\n})( window, function factory() {\n'use strict';\n\n// -------------------------- helpers -------------------------- //\n\n// get a number from a string, not a percentage\nfunction getStyleSize( value ) {\n  var num = parseFloat( value );\n  // not a percent like '100%', and a number\n  var isValid = value.indexOf('%') == -1 && !isNaN( num );\n  return isValid && num;\n}\n\nfunction noop() {}\n\nvar logError = typeof console == 'undefined' ? noop :\n  function( message ) {\n    console.error( message );\n  };\n\n// -------------------------- measurements -------------------------- //\n\nvar measurements = [\n  'paddingLeft',\n  'paddingRight',\n  'paddingTop',\n  'paddingBottom',\n  'marginLeft',\n  'marginRight',\n  'marginTop',\n  'marginBottom',\n  'borderLeftWidth',\n  'borderRightWidth',\n  'borderTopWidth',\n  'borderBottomWidth'\n];\n\nvar measurementsLength = measurements.length;\n\nfunction getZeroSize() {\n  var size = {\n    width: 0,\n    height: 0,\n    innerWidth: 0,\n    innerHeight: 0,\n    outerWidth: 0,\n    outerHeight: 0\n  };\n  for ( var i=0; i < measurementsLength; i++ ) {\n    var measurement = measurements[i];\n    size[ measurement ] = 0;\n  }\n  return size;\n}\n\n// -------------------------- getStyle -------------------------- //\n\n/**\n * getStyle, get style of element, check for Firefox bug\n * https://bugzilla.mozilla.org/show_bug.cgi?id=548397\n */\nfunction getStyle( elem ) {\n  var style = getComputedStyle( elem );\n  if ( !style ) {\n    logError( 'Style returned ' + style +\n      '. Are you running this code in a hidden iframe on Firefox? ' +\n      'See https://bit.ly/getsizebug1' );\n  }\n  return style;\n}\n\n// -------------------------- setup -------------------------- //\n\nvar isSetup = false;\n\nvar isBoxSizeOuter;\n\n/**\n * setup\n * check isBoxSizerOuter\n * do on first getSize() rather than on page load for Firefox bug\n */\nfunction setup() {\n  // setup once\n  if ( isSetup ) {\n    return;\n  }\n  isSetup = true;\n\n  // -------------------------- box sizing -------------------------- //\n\n  /**\n   * Chrome & Safari measure the outer-width on style.width on border-box elems\n   * IE11 & Firefox<29 measures the inner-width\n   */\n  var div = document.createElement('div');\n  div.style.width = '200px';\n  div.style.padding = '1px 2px 3px 4px';\n  div.style.borderStyle = 'solid';\n  div.style.borderWidth = '1px 2px 3px 4px';\n  div.style.boxSizing = 'border-box';\n\n  var body = document.body || document.documentElement;\n  body.appendChild( div );\n  var style = getStyle( div );\n  // round value for browser zoom. desandro/masonry#928\n  isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200;\n  getSize.isBoxSizeOuter = isBoxSizeOuter;\n\n  body.removeChild( div );\n}\n\n// -------------------------- getSize -------------------------- //\n\nfunction getSize( elem ) {\n  setup();\n\n  // use querySeletor if elem is string\n  if ( typeof elem == 'string' ) {\n    elem = document.querySelector( elem );\n  }\n\n  // do not proceed on non-objects\n  if ( !elem || typeof elem != 'object' || !elem.nodeType ) {\n    return;\n  }\n\n  var style = getStyle( elem );\n\n  // if hidden, everything is 0\n  if ( style.display == 'none' ) {\n    return getZeroSize();\n  }\n\n  var size = {};\n  size.width = elem.offsetWidth;\n  size.height = elem.offsetHeight;\n\n  var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';\n\n  // get all measurements\n  for ( var i=0; i < measurementsLength; i++ ) {\n    var measurement = measurements[i];\n    var value = style[ measurement ];\n    var num = parseFloat( value );\n    // any 'auto', 'medium' value will be 0\n    size[ measurement ] = !isNaN( num ) ? num : 0;\n  }\n\n  var paddingWidth = size.paddingLeft + size.paddingRight;\n  var paddingHeight = size.paddingTop + size.paddingBottom;\n  var marginWidth = size.marginLeft + size.marginRight;\n  var marginHeight = size.marginTop + size.marginBottom;\n  var borderWidth = size.borderLeftWidth + size.borderRightWidth;\n  var borderHeight = size.borderTopWidth + size.borderBottomWidth;\n\n  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;\n\n  // overwrite width and height if we can get it from style\n  var styleWidth = getStyleSize( style.width );\n  if ( styleWidth !== false ) {\n    size.width = styleWidth +\n      // add padding and border unless it's already including it\n      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );\n  }\n\n  var styleHeight = getStyleSize( style.height );\n  if ( styleHeight !== false ) {\n    size.height = styleHeight +\n      // add padding and border unless it's already including it\n      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );\n  }\n\n  size.innerWidth = size.width - ( paddingWidth + borderWidth );\n  size.innerHeight = size.height - ( paddingHeight + borderHeight );\n\n  size.outerWidth = size.width + marginWidth;\n  size.outerHeight = size.height + marginHeight;\n\n  return size;\n}\n\nreturn getSize;\n\n});\n\n/**\n * matchesSelector v2.0.2\n * matchesSelector( element, '.selector' )\n * MIT license\n */\n\n/*jshint browser: true, strict: true, undef: true, unused: true */\n\n( function( window, factory ) {\n  /*global define: false, module: false */\n  'use strict';\n  // universal module definition\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( 'desandro-matches-selector/matches-selector',factory );\n  } else if ( typeof module == 'object' && module.exports ) {\n    // CommonJS\n    module.exports = factory();\n  } else {\n    // browser global\n    window.matchesSelector = factory();\n  }\n\n}( window, function factory() {\n  'use strict';\n\n  var matchesMethod = ( function() {\n    var ElemProto = window.Element.prototype;\n    // check for the standard method name first\n    if ( ElemProto.matches ) {\n      return 'matches';\n    }\n    // check un-prefixed\n    if ( ElemProto.matchesSelector ) {\n      return 'matchesSelector';\n    }\n    // check vendor prefixes\n    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];\n\n    for ( var i=0; i < prefixes.length; i++ ) {\n      var prefix = prefixes[i];\n      var method = prefix + 'MatchesSelector';\n      if ( ElemProto[ method ] ) {\n        return method;\n      }\n    }\n  })();\n\n  return function matchesSelector( elem, selector ) {\n    return elem[ matchesMethod ]( selector );\n  };\n\n}));\n\n/**\n * Fizzy UI utils v2.0.7\n * MIT license\n */\n\n/*jshint browser: true, undef: true, unused: true, strict: true */\n\n( function( window, factory ) {\n  // universal module definition\n  /*jshint strict: false */ /*globals define, module, require */\n\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( 'fizzy-ui-utils/utils',[\n      'desandro-matches-selector/matches-selector'\n    ], function( matchesSelector ) {\n      return factory( window, matchesSelector );\n    });\n  } else if ( typeof module == 'object' && module.exports ) {\n    // CommonJS\n    module.exports = factory(\n      window,\n      require('desandro-matches-selector')\n    );\n  } else {\n    // browser global\n    window.fizzyUIUtils = factory(\n      window,\n      window.matchesSelector\n    );\n  }\n\n}( window, function factory( window, matchesSelector ) {\n\n\n\nvar utils = {};\n\n// ----- extend ----- //\n\n// extends objects\nutils.extend = function( a, b ) {\n  for ( var prop in b ) {\n    a[ prop ] = b[ prop ];\n  }\n  return a;\n};\n\n// ----- modulo ----- //\n\nutils.modulo = function( num, div ) {\n  return ( ( num % div ) + div ) % div;\n};\n\n// ----- makeArray ----- //\n\nvar arraySlice = Array.prototype.slice;\n\n// turn element or nodeList into an array\nutils.makeArray = function( obj ) {\n  if ( Array.isArray( obj ) ) {\n    // use object if already an array\n    return obj;\n  }\n  // return empty array if undefined or null. #6\n  if ( obj === null || obj === undefined ) {\n    return [];\n  }\n\n  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';\n  if ( isArrayLike ) {\n    // convert nodeList to array\n    return arraySlice.call( obj );\n  }\n\n  // array of single index\n  return [ obj ];\n};\n\n// ----- removeFrom ----- //\n\nutils.removeFrom = function( ary, obj ) {\n  var index = ary.indexOf( obj );\n  if ( index != -1 ) {\n    ary.splice( index, 1 );\n  }\n};\n\n// ----- getParent ----- //\n\nutils.getParent = function( elem, selector ) {\n  while ( elem.parentNode && elem != document.body ) {\n    elem = elem.parentNode;\n    if ( matchesSelector( elem, selector ) ) {\n      return elem;\n    }\n  }\n};\n\n// ----- getQueryElement ----- //\n\n// use element as selector string\nutils.getQueryElement = function( elem ) {\n  if ( typeof elem == 'string' ) {\n    return document.querySelector( elem );\n  }\n  return elem;\n};\n\n// ----- handleEvent ----- //\n\n// enable .ontype to trigger from .addEventListener( elem, 'type' )\nutils.handleEvent = function( event ) {\n  var method = 'on' + event.type;\n  if ( this[ method ] ) {\n    this[ method ]( event );\n  }\n};\n\n// ----- filterFindElements ----- //\n\nutils.filterFindElements = function( elems, selector ) {\n  // make array of elems\n  elems = utils.makeArray( elems );\n  var ffElems = [];\n\n  elems.forEach( function( elem ) {\n    // check that elem is an actual element\n    if ( !( elem instanceof HTMLElement ) ) {\n      return;\n    }\n    // add elem if no selector\n    if ( !selector ) {\n      ffElems.push( elem );\n      return;\n    }\n    // filter & find items if we have a selector\n    // filter\n    if ( matchesSelector( elem, selector ) ) {\n      ffElems.push( elem );\n    }\n    // find children\n    var childElems = elem.querySelectorAll( selector );\n    // concat childElems to filterFound array\n    for ( var i=0; i < childElems.length; i++ ) {\n      ffElems.push( childElems[i] );\n    }\n  });\n\n  return ffElems;\n};\n\n// ----- debounceMethod ----- //\n\nutils.debounceMethod = function( _class, methodName, threshold ) {\n  threshold = threshold || 100;\n  // original method\n  var method = _class.prototype[ methodName ];\n  var timeoutName = methodName + 'Timeout';\n\n  _class.prototype[ methodName ] = function() {\n    var timeout = this[ timeoutName ];\n    clearTimeout( timeout );\n\n    var args = arguments;\n    var _this = this;\n    this[ timeoutName ] = setTimeout( function() {\n      method.apply( _this, args );\n      delete _this[ timeoutName ];\n    }, threshold );\n  };\n};\n\n// ----- docReady ----- //\n\nutils.docReady = function( callback ) {\n  var readyState = document.readyState;\n  if ( readyState == 'complete' || readyState == 'interactive' ) {\n    // do async to allow for other scripts to run. metafizzy/flickity#441\n    setTimeout( callback );\n  } else {\n    document.addEventListener( 'DOMContentLoaded', callback );\n  }\n};\n\n// ----- htmlInit ----- //\n\n// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/\nutils.toDashed = function( str ) {\n  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {\n    return $1 + '-' + $2;\n  }).toLowerCase();\n};\n\nvar console = window.console;\n/**\n * allow user to initialize classes via [data-namespace] or .js-namespace class\n * htmlInit( Widget, 'widgetName' )\n * options are parsed from data-namespace-options\n */\nutils.htmlInit = function( WidgetClass, namespace ) {\n  utils.docReady( function() {\n    var dashedNamespace = utils.toDashed( namespace );\n    var dataAttr = 'data-' + dashedNamespace;\n    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );\n    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );\n    var elems = utils.makeArray( dataAttrElems )\n      .concat( utils.makeArray( jsDashElems ) );\n    var dataOptionsAttr = dataAttr + '-options';\n    var jQuery = window.jQuery;\n\n    elems.forEach( function( elem ) {\n      var attr = elem.getAttribute( dataAttr ) ||\n        elem.getAttribute( dataOptionsAttr );\n      var options;\n      try {\n        options = attr && JSON.parse( attr );\n      } catch ( error ) {\n        // log error, do not initialize\n        if ( console ) {\n          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +\n          ': ' + error );\n        }\n        return;\n      }\n      // initialize\n      var instance = new WidgetClass( elem, options );\n      // make available via $().data('namespace')\n      if ( jQuery ) {\n        jQuery.data( elem, namespace, instance );\n      }\n    });\n\n  });\n};\n\n// -----  ----- //\n\nreturn utils;\n\n}));\n\n/**\n * Outlayer Item\n */\n\n( function( window, factory ) {\n  // universal module definition\n  /* jshint strict: false */ /* globals define, module, require */\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD - RequireJS\n    define( 'outlayer/item',[\n        'ev-emitter/ev-emitter',\n        'get-size/get-size'\n      ],\n      factory\n    );\n  } else if ( typeof module == 'object' && module.exports ) {\n    // CommonJS - Browserify, Webpack\n    module.exports = factory(\n      require('ev-emitter'),\n      require('get-size')\n    );\n  } else {\n    // browser global\n    window.Outlayer = {};\n    window.Outlayer.Item = factory(\n      window.EvEmitter,\n      window.getSize\n    );\n  }\n\n}( window, function factory( EvEmitter, getSize ) {\n'use strict';\n\n// ----- helpers ----- //\n\nfunction isEmptyObj( obj ) {\n  for ( var prop in obj ) {\n    return false;\n  }\n  prop = null;\n  return true;\n}\n\n// -------------------------- CSS3 support -------------------------- //\n\n\nvar docElemStyle = document.documentElement.style;\n\nvar transitionProperty = typeof docElemStyle.transition == 'string' ?\n  'transition' : 'WebkitTransition';\nvar transformProperty = typeof docElemStyle.transform == 'string' ?\n  'transform' : 'WebkitTransform';\n\nvar transitionEndEvent = {\n  WebkitTransition: 'webkitTransitionEnd',\n  transition: 'transitionend'\n}[ transitionProperty ];\n\n// cache all vendor properties that could have vendor prefix\nvar vendorProperties = {\n  transform: transformProperty,\n  transition: transitionProperty,\n  transitionDuration: transitionProperty + 'Duration',\n  transitionProperty: transitionProperty + 'Property',\n  transitionDelay: transitionProperty + 'Delay'\n};\n\n// -------------------------- Item -------------------------- //\n\nfunction Item( element, layout ) {\n  if ( !element ) {\n    return;\n  }\n\n  this.element = element;\n  // parent layout class, i.e. Masonry, Isotope, or Packery\n  this.layout = layout;\n  this.position = {\n    x: 0,\n    y: 0\n  };\n\n  this._create();\n}\n\n// inherit EvEmitter\nvar proto = Item.prototype = Object.create( EvEmitter.prototype );\nproto.constructor = Item;\n\nproto._create = function() {\n  // transition objects\n  this._transn = {\n    ingProperties: {},\n    clean: {},\n    onEnd: {}\n  };\n\n  this.css({\n    position: 'absolute'\n  });\n};\n\n// trigger specified handler for event type\nproto.handleEvent = function( event ) {\n  var method = 'on' + event.type;\n  if ( this[ method ] ) {\n    this[ method ]( event );\n  }\n};\n\nproto.getSize = function() {\n  this.size = getSize( this.element );\n};\n\n/**\n * apply CSS styles to element\n * @param {Object} style\n */\nproto.css = function( style ) {\n  var elemStyle = this.element.style;\n\n  for ( var prop in style ) {\n    // use vendor property if available\n    var supportedProp = vendorProperties[ prop ] || prop;\n    elemStyle[ supportedProp ] = style[ prop ];\n  }\n};\n\n // measure position, and sets it\nproto.getPosition = function() {\n  var style = getComputedStyle( this.element );\n  var isOriginLeft = this.layout._getOption('originLeft');\n  var isOriginTop = this.layout._getOption('originTop');\n  var xValue = style[ isOriginLeft ? 'left' : 'right' ];\n  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];\n  var x = parseFloat( xValue );\n  var y = parseFloat( yValue );\n  // convert percent to pixels\n  var layoutSize = this.layout.size;\n  if ( xValue.indexOf('%') != -1 ) {\n    x = ( x / 100 ) * layoutSize.width;\n  }\n  if ( yValue.indexOf('%') != -1 ) {\n    y = ( y / 100 ) * layoutSize.height;\n  }\n  // clean up 'auto' or other non-integer values\n  x = isNaN( x ) ? 0 : x;\n  y = isNaN( y ) ? 0 : y;\n  // remove padding from measurement\n  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;\n  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;\n\n  this.position.x = x;\n  this.position.y = y;\n};\n\n// set settled position, apply padding\nproto.layoutPosition = function() {\n  var layoutSize = this.layout.size;\n  var style = {};\n  var isOriginLeft = this.layout._getOption('originLeft');\n  var isOriginTop = this.layout._getOption('originTop');\n\n  // x\n  var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';\n  var xProperty = isOriginLeft ? 'left' : 'right';\n  var xResetProperty = isOriginLeft ? 'right' : 'left';\n\n  var x = this.position.x + layoutSize[ xPadding ];\n  // set in percentage or pixels\n  style[ xProperty ] = this.getXValue( x );\n  // reset other property\n  style[ xResetProperty ] = '';\n\n  // y\n  var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';\n  var yProperty = isOriginTop ? 'top' : 'bottom';\n  var yResetProperty = isOriginTop ? 'bottom' : 'top';\n\n  var y = this.position.y + layoutSize[ yPadding ];\n  // set in percentage or pixels\n  style[ yProperty ] = this.getYValue( y );\n  // reset other property\n  style[ yResetProperty ] = '';\n\n  this.css( style );\n  this.emitEvent( 'layout', [ this ] );\n};\n\nproto.getXValue = function( x ) {\n  var isHorizontal = this.layout._getOption('horizontal');\n  return this.layout.options.percentPosition && !isHorizontal ?\n    ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';\n};\n\nproto.getYValue = function( y ) {\n  var isHorizontal = this.layout._getOption('horizontal');\n  return this.layout.options.percentPosition && isHorizontal ?\n    ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';\n};\n\nproto._transitionTo = function( x, y ) {\n  this.getPosition();\n  // get current x & y from top/left\n  var curX = this.position.x;\n  var curY = this.position.y;\n\n  var didNotMove = x == this.position.x && y == this.position.y;\n\n  // save end position\n  this.setPosition( x, y );\n\n  // if did not move and not transitioning, just go to layout\n  if ( didNotMove && !this.isTransitioning ) {\n    this.layoutPosition();\n    return;\n  }\n\n  var transX = x - curX;\n  var transY = y - curY;\n  var transitionStyle = {};\n  transitionStyle.transform = this.getTranslate( transX, transY );\n\n  this.transition({\n    to: transitionStyle,\n    onTransitionEnd: {\n      transform: this.layoutPosition\n    },\n    isCleaning: true\n  });\n};\n\nproto.getTranslate = function( x, y ) {\n  // flip cooridinates if origin on right or bottom\n  var isOriginLeft = this.layout._getOption('originLeft');\n  var isOriginTop = this.layout._getOption('originTop');\n  x = isOriginLeft ? x : -x;\n  y = isOriginTop ? y : -y;\n  return 'translate3d(' + x + 'px, ' + y + 'px, 0)';\n};\n\n// non transition + transform support\nproto.goTo = function( x, y ) {\n  this.setPosition( x, y );\n  this.layoutPosition();\n};\n\nproto.moveTo = proto._transitionTo;\n\nproto.setPosition = function( x, y ) {\n  this.position.x = parseFloat( x );\n  this.position.y = parseFloat( y );\n};\n\n// ----- transition ----- //\n\n/**\n * @param {Object} style - CSS\n * @param {Function} onTransitionEnd\n */\n\n// non transition, just trigger callback\nproto._nonTransition = function( args ) {\n  this.css( args.to );\n  if ( args.isCleaning ) {\n    this._removeStyles( args.to );\n  }\n  for ( var prop in args.onTransitionEnd ) {\n    args.onTransitionEnd[ prop ].call( this );\n  }\n};\n\n/**\n * proper transition\n * @param {Object} args - arguments\n *   @param {Object} to - style to transition to\n *   @param {Object} from - style to start transition from\n *   @param {Boolean} isCleaning - removes transition styles after transition\n *   @param {Function} onTransitionEnd - callback\n */\nproto.transition = function( args ) {\n  // redirect to nonTransition if no transition duration\n  if ( !parseFloat( this.layout.options.transitionDuration ) ) {\n    this._nonTransition( args );\n    return;\n  }\n\n  var _transition = this._transn;\n  // keep track of onTransitionEnd callback by css property\n  for ( var prop in args.onTransitionEnd ) {\n    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];\n  }\n  // keep track of properties that are transitioning\n  for ( prop in args.to ) {\n    _transition.ingProperties[ prop ] = true;\n    // keep track of properties to clean up when transition is done\n    if ( args.isCleaning ) {\n      _transition.clean[ prop ] = true;\n    }\n  }\n\n  // set from styles\n  if ( args.from ) {\n    this.css( args.from );\n    // force redraw. http://blog.alexmaccaw.com/css-transitions\n    var h = this.element.offsetHeight;\n    // hack for JSHint to hush about unused var\n    h = null;\n  }\n  // enable transition\n  this.enableTransition( args.to );\n  // set styles that are transitioning\n  this.css( args.to );\n\n  this.isTransitioning = true;\n\n};\n\n// dash before all cap letters, including first for\n// WebkitTransform => -webkit-transform\nfunction toDashedAll( str ) {\n  return str.replace( /([A-Z])/g, function( $1 ) {\n    return '-' + $1.toLowerCase();\n  });\n}\n\nvar transitionProps = 'opacity,' + toDashedAll( transformProperty );\n\nproto.enableTransition = function(/* style */) {\n  // HACK changing transitionProperty during a transition\n  // will cause transition to jump\n  if ( this.isTransitioning ) {\n    return;\n  }\n\n  // make `transition: foo, bar, baz` from style object\n  // HACK un-comment this when enableTransition can work\n  // while a transition is happening\n  // var transitionValues = [];\n  // for ( var prop in style ) {\n  //   // dash-ify camelCased properties like WebkitTransition\n  //   prop = vendorProperties[ prop ] || prop;\n  //   transitionValues.push( toDashedAll( prop ) );\n  // }\n  // munge number to millisecond, to match stagger\n  var duration = this.layout.options.transitionDuration;\n  duration = typeof duration == 'number' ? duration + 'ms' : duration;\n  // enable transition styles\n  this.css({\n    transitionProperty: transitionProps,\n    transitionDuration: duration,\n    transitionDelay: this.staggerDelay || 0\n  });\n  // listen for transition end event\n  this.element.addEventListener( transitionEndEvent, this, false );\n};\n\n// ----- events ----- //\n\nproto.onwebkitTransitionEnd = function( event ) {\n  this.ontransitionend( event );\n};\n\nproto.onotransitionend = function( event ) {\n  this.ontransitionend( event );\n};\n\n// properties that I munge to make my life easier\nvar dashedVendorProperties = {\n  '-webkit-transform': 'transform'\n};\n\nproto.ontransitionend = function( event ) {\n  // disregard bubbled events from children\n  if ( event.target !== this.element ) {\n    return;\n  }\n  var _transition = this._transn;\n  // get property name of transitioned property, convert to prefix-free\n  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;\n\n  // remove property that has completed transitioning\n  delete _transition.ingProperties[ propertyName ];\n  // check if any properties are still transitioning\n  if ( isEmptyObj( _transition.ingProperties ) ) {\n    // all properties have completed transitioning\n    this.disableTransition();\n  }\n  // clean style\n  if ( propertyName in _transition.clean ) {\n    // clean up style\n    this.element.style[ event.propertyName ] = '';\n    delete _transition.clean[ propertyName ];\n  }\n  // trigger onTransitionEnd callback\n  if ( propertyName in _transition.onEnd ) {\n    var onTransitionEnd = _transition.onEnd[ propertyName ];\n    onTransitionEnd.call( this );\n    delete _transition.onEnd[ propertyName ];\n  }\n\n  this.emitEvent( 'transitionEnd', [ this ] );\n};\n\nproto.disableTransition = function() {\n  this.removeTransitionStyles();\n  this.element.removeEventListener( transitionEndEvent, this, false );\n  this.isTransitioning = false;\n};\n\n/**\n * removes style property from element\n * @param {Object} style\n**/\nproto._removeStyles = function( style ) {\n  // clean up transition styles\n  var cleanStyle = {};\n  for ( var prop in style ) {\n    cleanStyle[ prop ] = '';\n  }\n  this.css( cleanStyle );\n};\n\nvar cleanTransitionStyle = {\n  transitionProperty: '',\n  transitionDuration: '',\n  transitionDelay: ''\n};\n\nproto.removeTransitionStyles = function() {\n  // remove transition\n  this.css( cleanTransitionStyle );\n};\n\n// ----- stagger ----- //\n\nproto.stagger = function( delay ) {\n  delay = isNaN( delay ) ? 0 : delay;\n  this.staggerDelay = delay + 'ms';\n};\n\n// ----- show/hide/remove ----- //\n\n// remove element from DOM\nproto.removeElem = function() {\n  this.element.parentNode.removeChild( this.element );\n  // remove display: none\n  this.css({ display: '' });\n  this.emitEvent( 'remove', [ this ] );\n};\n\nproto.remove = function() {\n  // just remove element if no transition support or no transition\n  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {\n    this.removeElem();\n    return;\n  }\n\n  // start transition\n  this.once( 'transitionEnd', function() {\n    this.removeElem();\n  });\n  this.hide();\n};\n\nproto.reveal = function() {\n  delete this.isHidden;\n  // remove display: none\n  this.css({ display: '' });\n\n  var options = this.layout.options;\n\n  var onTransitionEnd = {};\n  var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');\n  onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;\n\n  this.transition({\n    from: options.hiddenStyle,\n    to: options.visibleStyle,\n    isCleaning: true,\n    onTransitionEnd: onTransitionEnd\n  });\n};\n\nproto.onRevealTransitionEnd = function() {\n  // check if still visible\n  // during transition, item may have been hidden\n  if ( !this.isHidden ) {\n    this.emitEvent('reveal');\n  }\n};\n\n/**\n * get style property use for hide/reveal transition end\n * @param {String} styleProperty - hiddenStyle/visibleStyle\n * @returns {String}\n */\nproto.getHideRevealTransitionEndProperty = function( styleProperty ) {\n  var optionStyle = this.layout.options[ styleProperty ];\n  // use opacity\n  if ( optionStyle.opacity ) {\n    return 'opacity';\n  }\n  // get first property\n  for ( var prop in optionStyle ) {\n    return prop;\n  }\n};\n\nproto.hide = function() {\n  // set flag\n  this.isHidden = true;\n  // remove display: none\n  this.css({ display: '' });\n\n  var options = this.layout.options;\n\n  var onTransitionEnd = {};\n  var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');\n  onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;\n\n  this.transition({\n    from: options.visibleStyle,\n    to: options.hiddenStyle,\n    // keep hidden stuff hidden\n    isCleaning: true,\n    onTransitionEnd: onTransitionEnd\n  });\n};\n\nproto.onHideTransitionEnd = function() {\n  // check if still hidden\n  // during transition, item may have been un-hidden\n  if ( this.isHidden ) {\n    this.css({ display: 'none' });\n    this.emitEvent('hide');\n  }\n};\n\nproto.destroy = function() {\n  this.css({\n    position: '',\n    left: '',\n    right: '',\n    top: '',\n    bottom: '',\n    transition: '',\n    transform: ''\n  });\n};\n\nreturn Item;\n\n}));\n\n/*!\n * Outlayer v2.1.1\n * the brains and guts of a layout library\n * MIT license\n */\n\n( function( window, factory ) {\n  'use strict';\n  // universal module definition\n  /* jshint strict: false */ /* globals define, module, require */\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD - RequireJS\n    define( 'outlayer/outlayer',[\n        'ev-emitter/ev-emitter',\n        'get-size/get-size',\n        'fizzy-ui-utils/utils',\n        './item'\n      ],\n      function( EvEmitter, getSize, utils, Item ) {\n        return factory( window, EvEmitter, getSize, utils, Item);\n      }\n    );\n  } else if ( typeof module == 'object' && module.exports ) {\n    // CommonJS - Browserify, Webpack\n    module.exports = factory(\n      window,\n      require('ev-emitter'),\n      require('get-size'),\n      require('fizzy-ui-utils'),\n      require('./item')\n    );\n  } else {\n    // browser global\n    window.Outlayer = factory(\n      window,\n      window.EvEmitter,\n      window.getSize,\n      window.fizzyUIUtils,\n      window.Outlayer.Item\n    );\n  }\n\n}( window, function factory( window, EvEmitter, getSize, utils, Item ) {\n'use strict';\n\n// ----- vars ----- //\n\nvar console = window.console;\nvar jQuery = window.jQuery;\nvar noop = function() {};\n\n// -------------------------- Outlayer -------------------------- //\n\n// globally unique identifiers\nvar GUID = 0;\n// internal store of all Outlayer intances\nvar instances = {};\n\n\n/**\n * @param {Element, String} element\n * @param {Object} options\n * @constructor\n */\nfunction Outlayer( element, options ) {\n  var queryElement = utils.getQueryElement( element );\n  if ( !queryElement ) {\n    if ( console ) {\n      console.error( 'Bad element for ' + this.constructor.namespace +\n        ': ' + ( queryElement || element ) );\n    }\n    return;\n  }\n  this.element = queryElement;\n  // add jQuery\n  if ( jQuery ) {\n    this.$element = jQuery( this.element );\n  }\n\n  // options\n  this.options = utils.extend( {}, this.constructor.defaults );\n  this.option( options );\n\n  // add id for Outlayer.getFromElement\n  var id = ++GUID;\n  this.element.outlayerGUID = id; // expando\n  instances[ id ] = this; // associate via id\n\n  // kick it off\n  this._create();\n\n  var isInitLayout = this._getOption('initLayout');\n  if ( isInitLayout ) {\n    this.layout();\n  }\n}\n\n// settings are for internal use only\nOutlayer.namespace = 'outlayer';\nOutlayer.Item = Item;\n\n// default options\nOutlayer.defaults = {\n  containerStyle: {\n    position: 'relative'\n  },\n  initLayout: true,\n  originLeft: true,\n  originTop: true,\n  resize: true,\n  resizeContainer: true,\n  // item options\n  transitionDuration: '0.4s',\n  hiddenStyle: {\n    opacity: 0,\n    transform: 'scale(0.001)'\n  },\n  visibleStyle: {\n    opacity: 1,\n    transform: 'scale(1)'\n  }\n};\n\nvar proto = Outlayer.prototype;\n// inherit EvEmitter\nutils.extend( proto, EvEmitter.prototype );\n\n/**\n * set options\n * @param {Object} opts\n */\nproto.option = function( opts ) {\n  utils.extend( this.options, opts );\n};\n\n/**\n * get backwards compatible option value, check old name\n */\nproto._getOption = function( option ) {\n  var oldOption = this.constructor.compatOptions[ option ];\n  return oldOption && this.options[ oldOption ] !== undefined ?\n    this.options[ oldOption ] : this.options[ option ];\n};\n\nOutlayer.compatOptions = {\n  // currentName: oldName\n  initLayout: 'isInitLayout',\n  horizontal: 'isHorizontal',\n  layoutInstant: 'isLayoutInstant',\n  originLeft: 'isOriginLeft',\n  originTop: 'isOriginTop',\n  resize: 'isResizeBound',\n  resizeContainer: 'isResizingContainer'\n};\n\nproto._create = function() {\n  // get items from children\n  this.reloadItems();\n  // elements that affect layout, but are not laid out\n  this.stamps = [];\n  this.stamp( this.options.stamp );\n  // set container style\n  utils.extend( this.element.style, this.options.containerStyle );\n\n  // bind resize method\n  var canBindResize = this._getOption('resize');\n  if ( canBindResize ) {\n    this.bindResize();\n  }\n};\n\n// goes through all children again and gets bricks in proper order\nproto.reloadItems = function() {\n  // collection of item elements\n  this.items = this._itemize( this.element.children );\n};\n\n\n/**\n * turn elements into Outlayer.Items to be used in layout\n * @param {Array or NodeList or HTMLElement} elems\n * @returns {Array} items - collection of new Outlayer Items\n */\nproto._itemize = function( elems ) {\n\n  var itemElems = this._filterFindItemElements( elems );\n  var Item = this.constructor.Item;\n\n  // create new Outlayer Items for collection\n  var items = [];\n  for ( var i=0; i < itemElems.length; i++ ) {\n    var elem = itemElems[i];\n    var item = new Item( elem, this );\n    items.push( item );\n  }\n\n  return items;\n};\n\n/**\n * get item elements to be used in layout\n * @param {Array or NodeList or HTMLElement} elems\n * @returns {Array} items - item elements\n */\nproto._filterFindItemElements = function( elems ) {\n  return utils.filterFindElements( elems, this.options.itemSelector );\n};\n\n/**\n * getter method for getting item elements\n * @returns {Array} elems - collection of item elements\n */\nproto.getItemElements = function() {\n  return this.items.map( function( item ) {\n    return item.element;\n  });\n};\n\n// ----- init & layout ----- //\n\n/**\n * lays out all items\n */\nproto.layout = function() {\n  this._resetLayout();\n  this._manageStamps();\n\n  // don't animate first layout\n  var layoutInstant = this._getOption('layoutInstant');\n  var isInstant = layoutInstant !== undefined ?\n    layoutInstant : !this._isLayoutInited;\n  this.layoutItems( this.items, isInstant );\n\n  // flag for initalized\n  this._isLayoutInited = true;\n};\n\n// _init is alias for layout\nproto._init = proto.layout;\n\n/**\n * logic before any new layout\n */\nproto._resetLayout = function() {\n  this.getSize();\n};\n\n\nproto.getSize = function() {\n  this.size = getSize( this.element );\n};\n\n/**\n * get measurement from option, for columnWidth, rowHeight, gutter\n * if option is String -> get element from selector string, & get size of element\n * if option is Element -> get size of element\n * else use option as a number\n *\n * @param {String} measurement\n * @param {String} size - width or height\n * @private\n */\nproto._getMeasurement = function( measurement, size ) {\n  var option = this.options[ measurement ];\n  var elem;\n  if ( !option ) {\n    // default to 0\n    this[ measurement ] = 0;\n  } else {\n    // use option as an element\n    if ( typeof option == 'string' ) {\n      elem = this.element.querySelector( option );\n    } else if ( option instanceof HTMLElement ) {\n      elem = option;\n    }\n    // use size of element, if element\n    this[ measurement ] = elem ? getSize( elem )[ size ] : option;\n  }\n};\n\n/**\n * layout a collection of item elements\n * @api public\n */\nproto.layoutItems = function( items, isInstant ) {\n  items = this._getItemsForLayout( items );\n\n  this._layoutItems( items, isInstant );\n\n  this._postLayout();\n};\n\n/**\n * get the items to be laid out\n * you may want to skip over some items\n * @param {Array} items\n * @returns {Array} items\n */\nproto._getItemsForLayout = function( items ) {\n  return items.filter( function( item ) {\n    return !item.isIgnored;\n  });\n};\n\n/**\n * layout items\n * @param {Array} items\n * @param {Boolean} isInstant\n */\nproto._layoutItems = function( items, isInstant ) {\n  this._emitCompleteOnItems( 'layout', items );\n\n  if ( !items || !items.length ) {\n    // no items, emit event with empty array\n    return;\n  }\n\n  var queue = [];\n\n  items.forEach( function( item ) {\n    // get x/y object from method\n    var position = this._getItemLayoutPosition( item );\n    // enqueue\n    position.item = item;\n    position.isInstant = isInstant || item.isLayoutInstant;\n    queue.push( position );\n  }, this );\n\n  this._processLayoutQueue( queue );\n};\n\n/**\n * get item layout position\n * @param {Outlayer.Item} item\n * @returns {Object} x and y position\n */\nproto._getItemLayoutPosition = function( /* item */ ) {\n  return {\n    x: 0,\n    y: 0\n  };\n};\n\n/**\n * iterate over array and position each item\n * Reason being - separating this logic prevents 'layout invalidation'\n * thx @paul_irish\n * @param {Array} queue\n */\nproto._processLayoutQueue = function( queue ) {\n  this.updateStagger();\n  queue.forEach( function( obj, i ) {\n    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );\n  }, this );\n};\n\n// set stagger from option in milliseconds number\nproto.updateStagger = function() {\n  var stagger = this.options.stagger;\n  if ( stagger === null || stagger === undefined ) {\n    this.stagger = 0;\n    return;\n  }\n  this.stagger = getMilliseconds( stagger );\n  return this.stagger;\n};\n\n/**\n * Sets position of item in DOM\n * @param {Outlayer.Item} item\n * @param {Number} x - horizontal position\n * @param {Number} y - vertical position\n * @param {Boolean} isInstant - disables transitions\n */\nproto._positionItem = function( item, x, y, isInstant, i ) {\n  if ( isInstant ) {\n    // if not transition, just set CSS\n    item.goTo( x, y );\n  } else {\n    item.stagger( i * this.stagger );\n    item.moveTo( x, y );\n  }\n};\n\n/**\n * Any logic you want to do after each layout,\n * i.e. size the container\n */\nproto._postLayout = function() {\n  this.resizeContainer();\n};\n\nproto.resizeContainer = function() {\n  var isResizingContainer = this._getOption('resizeContainer');\n  if ( !isResizingContainer ) {\n    return;\n  }\n  var size = this._getContainerSize();\n  if ( size ) {\n    this._setContainerMeasure( size.width, true );\n    this._setContainerMeasure( size.height, false );\n  }\n};\n\n/**\n * Sets width or height of container if returned\n * @returns {Object} size\n *   @param {Number} width\n *   @param {Number} height\n */\nproto._getContainerSize = noop;\n\n/**\n * @param {Number} measure - size of width or height\n * @param {Boolean} isWidth\n */\nproto._setContainerMeasure = function( measure, isWidth ) {\n  if ( measure === undefined ) {\n    return;\n  }\n\n  var elemSize = this.size;\n  // add padding and border width if border box\n  if ( elemSize.isBorderBox ) {\n    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +\n      elemSize.borderLeftWidth + elemSize.borderRightWidth :\n      elemSize.paddingBottom + elemSize.paddingTop +\n      elemSize.borderTopWidth + elemSize.borderBottomWidth;\n  }\n\n  measure = Math.max( measure, 0 );\n  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';\n};\n\n/**\n * emit eventComplete on a collection of items events\n * @param {String} eventName\n * @param {Array} items - Outlayer.Items\n */\nproto._emitCompleteOnItems = function( eventName, items ) {\n  var _this = this;\n  function onComplete() {\n    _this.dispatchEvent( eventName + 'Complete', null, [ items ] );\n  }\n\n  var count = items.length;\n  if ( !items || !count ) {\n    onComplete();\n    return;\n  }\n\n  var doneCount = 0;\n  function tick() {\n    doneCount++;\n    if ( doneCount == count ) {\n      onComplete();\n    }\n  }\n\n  // bind callback\n  items.forEach( function( item ) {\n    item.once( eventName, tick );\n  });\n};\n\n/**\n * emits events via EvEmitter and jQuery events\n * @param {String} type - name of event\n * @param {Event} event - original event\n * @param {Array} args - extra arguments\n */\nproto.dispatchEvent = function( type, event, args ) {\n  // add original event to arguments\n  var emitArgs = event ? [ event ].concat( args ) : args;\n  this.emitEvent( type, emitArgs );\n\n  if ( jQuery ) {\n    // set this.$element\n    this.$element = this.$element || jQuery( this.element );\n    if ( event ) {\n      // create jQuery event\n      var $event = jQuery.Event( event );\n      $event.type = type;\n      this.$element.trigger( $event, args );\n    } else {\n      // just trigger with type if no event available\n      this.$element.trigger( type, args );\n    }\n  }\n};\n\n// -------------------------- ignore & stamps -------------------------- //\n\n\n/**\n * keep item in collection, but do not lay it out\n * ignored items do not get skipped in layout\n * @param {Element} elem\n */\nproto.ignore = function( elem ) {\n  var item = this.getItem( elem );\n  if ( item ) {\n    item.isIgnored = true;\n  }\n};\n\n/**\n * return item to layout collection\n * @param {Element} elem\n */\nproto.unignore = function( elem ) {\n  var item = this.getItem( elem );\n  if ( item ) {\n    delete item.isIgnored;\n  }\n};\n\n/**\n * adds elements to stamps\n * @param {NodeList, Array, Element, or String} elems\n */\nproto.stamp = function( elems ) {\n  elems = this._find( elems );\n  if ( !elems ) {\n    return;\n  }\n\n  this.stamps = this.stamps.concat( elems );\n  // ignore\n  elems.forEach( this.ignore, this );\n};\n\n/**\n * removes elements to stamps\n * @param {NodeList, Array, or Element} elems\n */\nproto.unstamp = function( elems ) {\n  elems = this._find( elems );\n  if ( !elems ){\n    return;\n  }\n\n  elems.forEach( function( elem ) {\n    // filter out removed stamp elements\n    utils.removeFrom( this.stamps, elem );\n    this.unignore( elem );\n  }, this );\n};\n\n/**\n * finds child elements\n * @param {NodeList, Array, Element, or String} elems\n * @returns {Array} elems\n */\nproto._find = function( elems ) {\n  if ( !elems ) {\n    return;\n  }\n  // if string, use argument as selector string\n  if ( typeof elems == 'string' ) {\n    elems = this.element.querySelectorAll( elems );\n  }\n  elems = utils.makeArray( elems );\n  return elems;\n};\n\nproto._manageStamps = function() {\n  if ( !this.stamps || !this.stamps.length ) {\n    return;\n  }\n\n  this._getBoundingRect();\n\n  this.stamps.forEach( this._manageStamp, this );\n};\n\n// update boundingLeft / Top\nproto._getBoundingRect = function() {\n  // get bounding rect for container element\n  var boundingRect = this.element.getBoundingClientRect();\n  var size = this.size;\n  this._boundingRect = {\n    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,\n    top: boundingRect.top + size.paddingTop + size.borderTopWidth,\n    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),\n    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )\n  };\n};\n\n/**\n * @param {Element} stamp\n**/\nproto._manageStamp = noop;\n\n/**\n * get x/y position of element relative to container element\n * @param {Element} elem\n * @returns {Object} offset - has left, top, right, bottom\n */\nproto._getElementOffset = function( elem ) {\n  var boundingRect = elem.getBoundingClientRect();\n  var thisRect = this._boundingRect;\n  var size = getSize( elem );\n  var offset = {\n    left: boundingRect.left - thisRect.left - size.marginLeft,\n    top: boundingRect.top - thisRect.top - size.marginTop,\n    right: thisRect.right - boundingRect.right - size.marginRight,\n    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom\n  };\n  return offset;\n};\n\n// -------------------------- resize -------------------------- //\n\n// enable event handlers for listeners\n// i.e. resize -> onresize\nproto.handleEvent = utils.handleEvent;\n\n/**\n * Bind layout to window resizing\n */\nproto.bindResize = function() {\n  window.addEventListener( 'resize', this );\n  this.isResizeBound = true;\n};\n\n/**\n * Unbind layout to window resizing\n */\nproto.unbindResize = function() {\n  window.removeEventListener( 'resize', this );\n  this.isResizeBound = false;\n};\n\nproto.onresize = function() {\n  this.resize();\n};\n\nutils.debounceMethod( Outlayer, 'onresize', 100 );\n\nproto.resize = function() {\n  // don't trigger if size did not change\n  // or if resize was unbound. See #9\n  if ( !this.isResizeBound || !this.needsResizeLayout() ) {\n    return;\n  }\n\n  this.layout();\n};\n\n/**\n * check if layout is needed post layout\n * @returns Boolean\n */\nproto.needsResizeLayout = function() {\n  var size = getSize( this.element );\n  // check that this.size and size are there\n  // IE8 triggers resize on body size change, so they might not be\n  var hasSizes = this.size && size;\n  return hasSizes && size.innerWidth !== this.size.innerWidth;\n};\n\n// -------------------------- methods -------------------------- //\n\n/**\n * add items to Outlayer instance\n * @param {Array or NodeList or Element} elems\n * @returns {Array} items - Outlayer.Items\n**/\nproto.addItems = function( elems ) {\n  var items = this._itemize( elems );\n  // add items to collection\n  if ( items.length ) {\n    this.items = this.items.concat( items );\n  }\n  return items;\n};\n\n/**\n * Layout newly-appended item elements\n * @param {Array or NodeList or Element} elems\n */\nproto.appended = function( elems ) {\n  var items = this.addItems( elems );\n  if ( !items.length ) {\n    return;\n  }\n  // layout and reveal just the new items\n  this.layoutItems( items, true );\n  this.reveal( items );\n};\n\n/**\n * Layout prepended elements\n * @param {Array or NodeList or Element} elems\n */\nproto.prepended = function( elems ) {\n  var items = this._itemize( elems );\n  if ( !items.length ) {\n    return;\n  }\n  // add items to beginning of collection\n  var previousItems = this.items.slice(0);\n  this.items = items.concat( previousItems );\n  // start new layout\n  this._resetLayout();\n  this._manageStamps();\n  // layout new stuff without transition\n  this.layoutItems( items, true );\n  this.reveal( items );\n  // layout previous items\n  this.layoutItems( previousItems );\n};\n\n/**\n * reveal a collection of items\n * @param {Array of Outlayer.Items} items\n */\nproto.reveal = function( items ) {\n  this._emitCompleteOnItems( 'reveal', items );\n  if ( !items || !items.length ) {\n    return;\n  }\n  var stagger = this.updateStagger();\n  items.forEach( function( item, i ) {\n    item.stagger( i * stagger );\n    item.reveal();\n  });\n};\n\n/**\n * hide a collection of items\n * @param {Array of Outlayer.Items} items\n */\nproto.hide = function( items ) {\n  this._emitCompleteOnItems( 'hide', items );\n  if ( !items || !items.length ) {\n    return;\n  }\n  var stagger = this.updateStagger();\n  items.forEach( function( item, i ) {\n    item.stagger( i * stagger );\n    item.hide();\n  });\n};\n\n/**\n * reveal item elements\n * @param {Array}, {Element}, {NodeList} items\n */\nproto.revealItemElements = function( elems ) {\n  var items = this.getItems( elems );\n  this.reveal( items );\n};\n\n/**\n * hide item elements\n * @param {Array}, {Element}, {NodeList} items\n */\nproto.hideItemElements = function( elems ) {\n  var items = this.getItems( elems );\n  this.hide( items );\n};\n\n/**\n * get Outlayer.Item, given an Element\n * @param {Element} elem\n * @param {Function} callback\n * @returns {Outlayer.Item} item\n */\nproto.getItem = function( elem ) {\n  // loop through items to get the one that matches\n  for ( var i=0; i < this.items.length; i++ ) {\n    var item = this.items[i];\n    if ( item.element == elem ) {\n      // return item\n      return item;\n    }\n  }\n};\n\n/**\n * get collection of Outlayer.Items, given Elements\n * @param {Array} elems\n * @returns {Array} items - Outlayer.Items\n */\nproto.getItems = function( elems ) {\n  elems = utils.makeArray( elems );\n  var items = [];\n  elems.forEach( function( elem ) {\n    var item = this.getItem( elem );\n    if ( item ) {\n      items.push( item );\n    }\n  }, this );\n\n  return items;\n};\n\n/**\n * remove element(s) from instance and DOM\n * @param {Array or NodeList or Element} elems\n */\nproto.remove = function( elems ) {\n  var removeItems = this.getItems( elems );\n\n  this._emitCompleteOnItems( 'remove', removeItems );\n\n  // bail if no items to remove\n  if ( !removeItems || !removeItems.length ) {\n    return;\n  }\n\n  removeItems.forEach( function( item ) {\n    item.remove();\n    // remove item from collection\n    utils.removeFrom( this.items, item );\n  }, this );\n};\n\n// ----- destroy ----- //\n\n// remove and disable Outlayer instance\nproto.destroy = function() {\n  // clean up dynamic styles\n  var style = this.element.style;\n  style.height = '';\n  style.position = '';\n  style.width = '';\n  // destroy items\n  this.items.forEach( function( item ) {\n    item.destroy();\n  });\n\n  this.unbindResize();\n\n  var id = this.element.outlayerGUID;\n  delete instances[ id ]; // remove reference to instance by id\n  delete this.element.outlayerGUID;\n  // remove data for jQuery\n  if ( jQuery ) {\n    jQuery.removeData( this.element, this.constructor.namespace );\n  }\n\n};\n\n// -------------------------- data -------------------------- //\n\n/**\n * get Outlayer instance from element\n * @param {Element} elem\n * @returns {Outlayer}\n */\nOutlayer.data = function( elem ) {\n  elem = utils.getQueryElement( elem );\n  var id = elem && elem.outlayerGUID;\n  return id && instances[ id ];\n};\n\n\n// -------------------------- create Outlayer class -------------------------- //\n\n/**\n * create a layout class\n * @param {String} namespace\n */\nOutlayer.create = function( namespace, options ) {\n  // sub-class Outlayer\n  var Layout = subclass( Outlayer );\n  // apply new options and compatOptions\n  Layout.defaults = utils.extend( {}, Outlayer.defaults );\n  utils.extend( Layout.defaults, options );\n  Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions  );\n\n  Layout.namespace = namespace;\n\n  Layout.data = Outlayer.data;\n\n  // sub-class Item\n  Layout.Item = subclass( Item );\n\n  // -------------------------- declarative -------------------------- //\n\n  utils.htmlInit( Layout, namespace );\n\n  // -------------------------- jQuery bridge -------------------------- //\n\n  // make into jQuery plugin\n  if ( jQuery && jQuery.bridget ) {\n    jQuery.bridget( namespace, Layout );\n  }\n\n  return Layout;\n};\n\nfunction subclass( Parent ) {\n  function SubClass() {\n    Parent.apply( this, arguments );\n  }\n\n  SubClass.prototype = Object.create( Parent.prototype );\n  SubClass.prototype.constructor = SubClass;\n\n  return SubClass;\n}\n\n// ----- helpers ----- //\n\n// how many milliseconds are in each unit\nvar msUnits = {\n  ms: 1,\n  s: 1000\n};\n\n// munge time-like parameter into millisecond number\n// '0.4s' -> 40\nfunction getMilliseconds( time ) {\n  if ( typeof time == 'number' ) {\n    return time;\n  }\n  var matches = time.match( /(^\\d*\\.?\\d*)(\\w*)/ );\n  var num = matches && matches[1];\n  var unit = matches && matches[2];\n  if ( !num.length ) {\n    return 0;\n  }\n  num = parseFloat( num );\n  var mult = msUnits[ unit ] || 1;\n  return num * mult;\n}\n\n// ----- fin ----- //\n\n// back in global\nOutlayer.Item = Item;\n\nreturn Outlayer;\n\n}));\n\n/*!\n * Masonry v4.2.2\n * Cascading grid layout library\n * https://masonry.desandro.com\n * MIT License\n * by David DeSandro\n */\n\n( function( window, factory ) {\n  // universal module definition\n  /* jshint strict: false */ /*globals define, module, require */\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( [\n        'outlayer/outlayer',\n        'get-size/get-size'\n      ],\n      factory );\n  } else if ( typeof module == 'object' && module.exports ) {\n    // CommonJS\n    module.exports = factory(\n      require('outlayer'),\n      require('get-size')\n    );\n  } else {\n    // browser global\n    window.Masonry = factory(\n      window.Outlayer,\n      window.getSize\n    );\n  }\n\n}( window, function factory( Outlayer, getSize ) {\n\n\n\n// -------------------------- masonryDefinition -------------------------- //\n\n  // create an Outlayer layout class\n  var Masonry = Outlayer.create('masonry');\n  // isFitWidth -> fitWidth\n  Masonry.compatOptions.fitWidth = 'isFitWidth';\n\n  var proto = Masonry.prototype;\n\n  proto._resetLayout = function() {\n    this.getSize();\n    this._getMeasurement( 'columnWidth', 'outerWidth' );\n    this._getMeasurement( 'gutter', 'outerWidth' );\n    this.measureColumns();\n\n    // reset column Y\n    this.colYs = [];\n    for ( var i=0; i < this.cols; i++ ) {\n      this.colYs.push( 0 );\n    }\n\n    this.maxY = 0;\n    this.horizontalColIndex = 0;\n  };\n\n  proto.measureColumns = function() {\n    this.getContainerWidth();\n    // if columnWidth is 0, default to outerWidth of first item\n    if ( !this.columnWidth ) {\n      var firstItem = this.items[0];\n      var firstItemElem = firstItem && firstItem.element;\n      // columnWidth fall back to item of first element\n      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||\n        // if first elem has no width, default to size of container\n        this.containerWidth;\n    }\n\n    var columnWidth = this.columnWidth += this.gutter;\n\n    // calculate columns\n    var containerWidth = this.containerWidth + this.gutter;\n    var cols = containerWidth / columnWidth;\n    // fix rounding errors, typically with gutters\n    var excess = columnWidth - containerWidth % columnWidth;\n    // if overshoot is less than a pixel, round up, otherwise floor it\n    var mathMethod = excess && excess < 1 ? 'round' : 'floor';\n    cols = Math[ mathMethod ]( cols );\n    this.cols = Math.max( cols, 1 );\n  };\n\n  proto.getContainerWidth = function() {\n    // container is parent if fit width\n    var isFitWidth = this._getOption('fitWidth');\n    var container = isFitWidth ? this.element.parentNode : this.element;\n    // check that this.size and size are there\n    // IE8 triggers resize on body size change, so they might not be\n    var size = getSize( container );\n    this.containerWidth = size && size.innerWidth;\n  };\n\n  proto._getItemLayoutPosition = function( item ) {\n    item.getSize();\n    // how many columns does this brick span\n    var remainder = item.size.outerWidth % this.columnWidth;\n    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';\n    // round if off by 1 pixel, otherwise use ceil\n    var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );\n    colSpan = Math.min( colSpan, this.cols );\n    // use horizontal or top column position\n    var colPosMethod = this.options.horizontalOrder ?\n      '_getHorizontalColPosition' : '_getTopColPosition';\n    var colPosition = this[ colPosMethod ]( colSpan, item );\n    // position the brick\n    var position = {\n      x: this.columnWidth * colPosition.col,\n      y: colPosition.y\n    };\n    // apply setHeight to necessary columns\n    var setHeight = colPosition.y + item.size.outerHeight;\n    var setMax = colSpan + colPosition.col;\n    for ( var i = colPosition.col; i < setMax; i++ ) {\n      this.colYs[i] = setHeight;\n    }\n\n    return position;\n  };\n\n  proto._getTopColPosition = function( colSpan ) {\n    var colGroup = this._getTopColGroup( colSpan );\n    // get the minimum Y value from the columns\n    var minimumY = Math.min.apply( Math, colGroup );\n\n    return {\n      col: colGroup.indexOf( minimumY ),\n      y: minimumY,\n    };\n  };\n\n  /**\n   * @param {Number} colSpan - number of columns the element spans\n   * @returns {Array} colGroup\n   */\n  proto._getTopColGroup = function( colSpan ) {\n    if ( colSpan < 2 ) {\n      // if brick spans only one column, use all the column Ys\n      return this.colYs;\n    }\n\n    var colGroup = [];\n    // how many different places could this brick fit horizontally\n    var groupCount = this.cols + 1 - colSpan;\n    // for each group potential horizontal position\n    for ( var i = 0; i < groupCount; i++ ) {\n      colGroup[i] = this._getColGroupY( i, colSpan );\n    }\n    return colGroup;\n  };\n\n  proto._getColGroupY = function( col, colSpan ) {\n    if ( colSpan < 2 ) {\n      return this.colYs[ col ];\n    }\n    // make an array of colY values for that one group\n    var groupColYs = this.colYs.slice( col, col + colSpan );\n    // and get the max value of the array\n    return Math.max.apply( Math, groupColYs );\n  };\n\n  // get column position based on horizontal index. #873\n  proto._getHorizontalColPosition = function( colSpan, item ) {\n    var col = this.horizontalColIndex % this.cols;\n    var isOver = colSpan > 1 && col + colSpan > this.cols;\n    // shift to next row if item can't fit on current row\n    col = isOver ? 0 : col;\n    // don't let zero-size items take up space\n    var hasSize = item.size.outerWidth && item.size.outerHeight;\n    this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex;\n\n    return {\n      col: col,\n      y: this._getColGroupY( col, colSpan ),\n    };\n  };\n\n  proto._manageStamp = function( stamp ) {\n    var stampSize = getSize( stamp );\n    var offset = this._getElementOffset( stamp );\n    // get the columns that this stamp affects\n    var isOriginLeft = this._getOption('originLeft');\n    var firstX = isOriginLeft ? offset.left : offset.right;\n    var lastX = firstX + stampSize.outerWidth;\n    var firstCol = Math.floor( firstX / this.columnWidth );\n    firstCol = Math.max( 0, firstCol );\n    var lastCol = Math.floor( lastX / this.columnWidth );\n    // lastCol should not go over if multiple of columnWidth #425\n    lastCol -= lastX % this.columnWidth ? 0 : 1;\n    lastCol = Math.min( this.cols - 1, lastCol );\n    // set colYs to bottom of the stamp\n\n    var isOriginTop = this._getOption('originTop');\n    var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +\n      stampSize.outerHeight;\n    for ( var i = firstCol; i <= lastCol; i++ ) {\n      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );\n    }\n  };\n\n  proto._getContainerSize = function() {\n    this.maxY = Math.max.apply( Math, this.colYs );\n    var size = {\n      height: this.maxY\n    };\n\n    if ( this._getOption('fitWidth') ) {\n      size.width = this._getContainerFitWidth();\n    }\n\n    return size;\n  };\n\n  proto._getContainerFitWidth = function() {\n    var unusedCols = 0;\n    // count unused columns\n    var i = this.cols;\n    while ( --i ) {\n      if ( this.colYs[i] !== 0 ) {\n        break;\n      }\n      unusedCols++;\n    }\n    // fit container to columns that have been used\n    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;\n  };\n\n  proto.needsResizeLayout = function() {\n    var previousWidth = this.containerWidth;\n    this.getContainerWidth();\n    return previousWidth != this.containerWidth;\n  };\n\n  return Masonry;\n\n}));\n\n"
  },
  {
    "path": "gulpfile.js",
    "content": "/*jshint node: true, strict: false */\n\nvar fs = require('fs');\nvar gulp = require('gulp');\nvar rename = require('gulp-rename');\nvar replace = require('gulp-replace');\n\n// ----- hint ----- //\n\nvar jshint = require('gulp-jshint');\n\ngulp.task( 'hint-js', function() {\n  return gulp.src('masonry.js')\n    .pipe( jshint() )\n    .pipe( jshint.reporter('default') );\n});\n\ngulp.task( 'hint-test', function() {\n  return gulp.src('test/unit/*.js')\n    .pipe( jshint() )\n    .pipe( jshint.reporter('default') );\n});\n\ngulp.task( 'hint-task', function() {\n  return gulp.src('gulpfile.js')\n    .pipe( jshint() )\n    .pipe( jshint.reporter('default') );\n});\n\nvar jsonlint = require('gulp-json-lint');\n\ngulp.task( 'jsonlint', function() {\n  return gulp.src( '*.json' )\n    .pipe( jsonlint() )\n    .pipe( jsonlint.report('verbose') );\n});\n\ngulp.task( 'hint', [ 'hint-js', 'hint-test', 'hint-task', 'jsonlint' ]);\n\n// -------------------------- RequireJS makes pkgd -------------------------- //\n\n// regex for banner comment\nvar reBannerComment = new RegExp('^\\\\s*(?:\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)\\\\s*');\n\nfunction getBanner() {\n  var src = fs.readFileSync( 'masonry.js', 'utf8' );\n  var matches = src.match( reBannerComment );\n  var banner = matches[0].replace( 'Masonry', 'Masonry PACKAGED' );\n  return banner;\n}\n\nfunction addBanner( str ) {\n  return replace( /^/, str );\n}\n\nvar rjsOptimize = require('gulp-requirejs-optimize');\n\ngulp.task( 'requirejs', function() {\n  var banner = getBanner();\n  // HACK src is not needed\n  // should refactor rjsOptimize to produce src\n  return gulp.src('masonry.js')\n    .pipe( rjsOptimize({\n      baseUrl: 'bower_components',\n      optimize: 'none',\n      include: [\n        'jquery-bridget/jquery-bridget',\n        'masonry/masonry'\n      ],\n      paths: {\n        masonry: '../',\n        jquery: 'empty:'\n      }\n    }) )\n    // remove named module\n    .pipe( replace( \"'masonry/masonry',\", '' ) )\n    // add banner\n    .pipe( addBanner( banner ) )\n    .pipe( rename('masonry.pkgd.js') )\n    .pipe( gulp.dest('dist') );\n});\n\n\n// ----- uglify ----- //\n\nvar uglify = require('gulp-uglify');\n\ngulp.task( 'uglify', [ 'requirejs' ], function() {\n  var banner = getBanner();\n  gulp.src('dist/masonry.pkgd.js')\n    .pipe( uglify() )\n    // add banner\n    .pipe( addBanner( banner ) )\n    .pipe( rename('masonry.pkgd.min.js') )\n    .pipe( gulp.dest('dist') );\n});\n\n// ----- version ----- //\n\n// set version in source files\n\nvar minimist = require('minimist');\nvar gutil = require('gulp-util');\nvar chalk = require('chalk');\n\n// use gulp version -t 1.2.3\ngulp.task( 'version', function() {\n  var args = minimist( process.argv.slice(3) );\n  var version = args.t;\n  if ( !version || !/^\\d\\.\\d+\\.\\d+/.test( version ) ) {\n    gutil.log( 'invalid version: ' + chalk.red( version ) );\n    return;\n  }\n  gutil.log( 'ticking version to ' + chalk.green( version ) );\n\n  gulp.src('masonry.js')\n    .pipe( replace( /Masonry v\\d\\.\\d+\\.\\d+/, 'Masonry v' + version ) )\n    .pipe( gulp.dest('.') );\n\n  gulp.src( [ 'package.json' ] )\n    .pipe( replace( /\"version\": \"\\d\\.\\d+\\.\\d+\"/, '\"version\": \"' + version + '\"' ) )\n    .pipe( gulp.dest('.') );\n});\n\n// ----- default ----- //\n\ngulp.task( 'default', [\n  'hint',\n  'uglify'\n]);\n"
  },
  {
    "path": "masonry.js",
    "content": "/*!\n * Masonry v4.2.2\n * Cascading grid layout library\n * https://masonry.desandro.com\n * MIT License\n * by David DeSandro\n */\n\n( function( window, factory ) {\n  // universal module definition\n  /* jshint strict: false */ /*globals define, module, require */\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( [\n        'outlayer/outlayer',\n        'get-size/get-size'\n      ],\n      factory );\n  } else if ( typeof module == 'object' && module.exports ) {\n    // CommonJS\n    module.exports = factory(\n      require('outlayer'),\n      require('get-size')\n    );\n  } else {\n    // browser global\n    window.Masonry = factory(\n      window.Outlayer,\n      window.getSize\n    );\n  }\n\n}( window, function factory( Outlayer, getSize ) {\n\n'use strict';\n\n// -------------------------- masonryDefinition -------------------------- //\n\n  // create an Outlayer layout class\n  var Masonry = Outlayer.create('masonry');\n  // isFitWidth -> fitWidth\n  Masonry.compatOptions.fitWidth = 'isFitWidth';\n\n  var proto = Masonry.prototype;\n\n  proto._resetLayout = function() {\n    this.getSize();\n    this._getMeasurement( 'columnWidth', 'outerWidth' );\n    this._getMeasurement( 'gutter', 'outerWidth' );\n    this.measureColumns();\n\n    // reset column Y\n    this.colYs = [];\n    for ( var i=0; i < this.cols; i++ ) {\n      this.colYs.push( 0 );\n    }\n\n    this.maxY = 0;\n    this.horizontalColIndex = 0;\n  };\n\n  proto.measureColumns = function() {\n    this.getContainerWidth();\n    // if columnWidth is 0, default to outerWidth of first item\n    if ( !this.columnWidth ) {\n      var firstItem = this.items[0];\n      var firstItemElem = firstItem && firstItem.element;\n      // columnWidth fall back to item of first element\n      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||\n        // if first elem has no width, default to size of container\n        this.containerWidth;\n    }\n\n    var columnWidth = this.columnWidth += this.gutter;\n\n    // calculate columns\n    var containerWidth = this.containerWidth + this.gutter;\n    var cols = containerWidth / columnWidth;\n    // fix rounding errors, typically with gutters\n    var excess = columnWidth - containerWidth % columnWidth;\n    // if overshoot is less than a pixel, round up, otherwise floor it\n    var mathMethod = excess && excess < 1 ? 'round' : 'floor';\n    cols = Math[ mathMethod ]( cols );\n    this.cols = Math.max( cols, 1 );\n  };\n\n  proto.getContainerWidth = function() {\n    // container is parent if fit width\n    var isFitWidth = this._getOption('fitWidth');\n    var container = isFitWidth ? this.element.parentNode : this.element;\n    // check that this.size and size are there\n    // IE8 triggers resize on body size change, so they might not be\n    var size = getSize( container );\n    this.containerWidth = size && size.innerWidth;\n  };\n\n  proto._getItemLayoutPosition = function( item ) {\n    item.getSize();\n    // how many columns does this brick span\n    var remainder = item.size.outerWidth % this.columnWidth;\n    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';\n    // round if off by 1 pixel, otherwise use ceil\n    var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );\n    colSpan = Math.min( colSpan, this.cols );\n    // use horizontal or top column position\n    var colPosMethod = this.options.horizontalOrder ?\n      '_getHorizontalColPosition' : '_getTopColPosition';\n    var colPosition = this[ colPosMethod ]( colSpan, item );\n    // position the brick\n    var position = {\n      x: this.columnWidth * colPosition.col,\n      y: colPosition.y\n    };\n    // apply setHeight to necessary columns\n    var setHeight = colPosition.y + item.size.outerHeight;\n    var setMax = colSpan + colPosition.col;\n    for ( var i = colPosition.col; i < setMax; i++ ) {\n      this.colYs[i] = setHeight;\n    }\n\n    return position;\n  };\n\n  proto._getTopColPosition = function( colSpan ) {\n    var colGroup = this._getTopColGroup( colSpan );\n    // get the minimum Y value from the columns\n    var minimumY = Math.min.apply( Math, colGroup );\n\n    return {\n      col: colGroup.indexOf( minimumY ),\n      y: minimumY,\n    };\n  };\n\n  /**\n   * @param {Number} colSpan - number of columns the element spans\n   * @returns {Array} colGroup\n   */\n  proto._getTopColGroup = function( colSpan ) {\n    if ( colSpan < 2 ) {\n      // if brick spans only one column, use all the column Ys\n      return this.colYs;\n    }\n\n    var colGroup = [];\n    // how many different places could this brick fit horizontally\n    var groupCount = this.cols + 1 - colSpan;\n    // for each group potential horizontal position\n    for ( var i = 0; i < groupCount; i++ ) {\n      colGroup[i] = this._getColGroupY( i, colSpan );\n    }\n    return colGroup;\n  };\n\n  proto._getColGroupY = function( col, colSpan ) {\n    if ( colSpan < 2 ) {\n      return this.colYs[ col ];\n    }\n    // make an array of colY values for that one group\n    var groupColYs = this.colYs.slice( col, col + colSpan );\n    // and get the max value of the array\n    return Math.max.apply( Math, groupColYs );\n  };\n\n  // get column position based on horizontal index. #873\n  proto._getHorizontalColPosition = function( colSpan, item ) {\n    var col = this.horizontalColIndex % this.cols;\n    var isOver = colSpan > 1 && col + colSpan > this.cols;\n    // shift to next row if item can't fit on current row\n    col = isOver ? 0 : col;\n    // don't let zero-size items take up space\n    var hasSize = item.size.outerWidth && item.size.outerHeight;\n    this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex;\n\n    return {\n      col: col,\n      y: this._getColGroupY( col, colSpan ),\n    };\n  };\n\n  proto._manageStamp = function( stamp ) {\n    var stampSize = getSize( stamp );\n    var offset = this._getElementOffset( stamp );\n    // get the columns that this stamp affects\n    var isOriginLeft = this._getOption('originLeft');\n    var firstX = isOriginLeft ? offset.left : offset.right;\n    var lastX = firstX + stampSize.outerWidth;\n    var firstCol = Math.floor( firstX / this.columnWidth );\n    firstCol = Math.max( 0, firstCol );\n    var lastCol = Math.floor( lastX / this.columnWidth );\n    // lastCol should not go over if multiple of columnWidth #425\n    lastCol -= lastX % this.columnWidth ? 0 : 1;\n    lastCol = Math.min( this.cols - 1, lastCol );\n    // set colYs to bottom of the stamp\n\n    var isOriginTop = this._getOption('originTop');\n    var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +\n      stampSize.outerHeight;\n    for ( var i = firstCol; i <= lastCol; i++ ) {\n      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );\n    }\n  };\n\n  proto._getContainerSize = function() {\n    this.maxY = Math.max.apply( Math, this.colYs );\n    var size = {\n      height: this.maxY\n    };\n\n    if ( this._getOption('fitWidth') ) {\n      size.width = this._getContainerFitWidth();\n    }\n\n    return size;\n  };\n\n  proto._getContainerFitWidth = function() {\n    var unusedCols = 0;\n    // count unused columns\n    var i = this.cols;\n    while ( --i ) {\n      if ( this.colYs[i] !== 0 ) {\n        break;\n      }\n      unusedCols++;\n    }\n    // fit container to columns that have been used\n    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;\n  };\n\n  proto.needsResizeLayout = function() {\n    var previousWidth = this.containerWidth;\n    this.getContainerWidth();\n    return previousWidth != this.containerWidth;\n  };\n\n  return Masonry;\n\n}));\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"masonry-layout\",\n  \"version\": \"4.2.2\",\n  \"description\": \"Cascading grid layout library\",\n  \"main\": \"masonry.js\",\n  \"dependencies\": {\n    \"get-size\": \"^2.0.2\",\n    \"outlayer\": \"^2.1.0\"\n  },\n  \"devDependencies\": {\n    \"chalk\": \"^1.1.1\",\n    \"gulp\": \"^3.9.0\",\n    \"gulp-jshint\": \"^2.0.0\",\n    \"gulp-json-lint\": \"^0.1.0\",\n    \"gulp-rename\": \"^1.2.2\",\n    \"gulp-replace\": \"^0.5.4\",\n    \"gulp-requirejs-optimize\": \"metafizzy/gulp-requirejs-optimize\",\n    \"gulp-uglify\": \"^1.5.1\",\n    \"gulp-util\": \"^3.0.7\",\n    \"jquery\": \">=1.4.3 <4\",\n    \"jquery-bridget\": \"~2.0.0\",\n    \"jshint\": \"^2.8.0\",\n    \"minimist\": \"^1.2.0\",\n    \"qunitjs\": \"^1.12\"\n  },\n  \"directories\": {\n    \"test\": \"test\"\n  },\n  \"scripts\": {\n    \"test\": \"test/index.html\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/desandro/masonry.git\"\n  },\n  \"keywords\": [\n    \"DOM\",\n    \"browser\",\n    \"grid\",\n    \"layout\",\n    \"outlayer\"\n  ],\n  \"author\": \"David DeSandro\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/desandro/masonry/issues\"\n  },\n  \"homepage\": \"https://masonry.desandro.com\",\n  \"files\": [\n    \"dist\",\n    \"masonry.js\"\n  ]\n}\n"
  },
  {
    "path": "sandbox/add-items.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>add items</title>\n\n  <style>\n  * {\n    -webkit-box-sizing: border-box;\n            box-sizing: border-box;\n  }\n\n  .grid {\n    background: #DDD;\n  }\n  \n  /* clearfix */\n  .grid:after {\n    display: block;\n    content: '';\n    clear: both;\n  }\n\n\n  .grid-sizer,\n  .grid-item {\n    width: 25%;\n  }\n\n  .grid-item {\n    border: 1px solid;\n    background: #09F;\n    height: 100px;\n  }\n\n  .grid-item--width2 { width: 50%; }\n\n  .grid-item--height2 { height: 160px; }\n\n  .grid-item--height3 { height: 220px; }\n\n  </style>\n\n</head>\n<body>\n\n  <h1>add items</h1>\n\n  <p>\n    <button class=\"prepend-button\">Prepend button</button>\n    <button class=\"append-button\">Append button</button>\n  </p>\n\n  <div class=\"grid\">\n    <div class=\"grid-sizer\"></div>\n    <div class=\"grid-item grid-item--width2\"></div>\n    <div class=\"grid-item grid-item--height2\"></div>\n  </div>\n\n\n<script src=\"../bower_components/ev-emitter/ev-emitter.js\"></script>\n<script src=\"../bower_components/get-size/get-size.js\"></script>\n<script src=\"../bower_components/desandro-matches-selector/matches-selector.js\"></script>\n<script src=\"../bower_components/fizzy-ui-utils/utils.js\"></script>\n<script src=\"../bower_components/outlayer/item.js\"></script>\n<script src=\"../bower_components/outlayer/outlayer.js\"></script>\n\n<script src=\"../masonry.js\"></script>\n\n<script>\nfunction getItemElement() {\n  var elem = document.createElement('div');\n  var wRand = Math.random();\n  var hRand = Math.random();\n  var widthClass = wRand > 0.8 ? 'grid-item--width3' :\n    wRand > 0.6 ? 'grid-item--width2' : '';\n  var heightClass = hRand > 0.8 ? 'grid-item--height3' :\n    hRand > 0.5 ? 'grid-item--height2' : '';\n  elem.className = 'grid-item ' + widthClass + ' ' + heightClass;\n  return elem;\n};\n\nvar msnry = new Masonry( '.grid', {\n  columnWidth: '.grid-sizer',\n  percentPosition: true\n});\n\ndocument.querySelector('.prepend-button').addEventListener( 'click', function() {\n  var itemElem = getItemElement();\n  msnry.element.insertBefore( itemElem, msnry.element.firstChild );\n  msnry.prepended( itemElem );\n});\n\ndocument.querySelector('.append-button').addEventListener( 'click', function() {\n  var itemElem = getItemElement();\n  msnry.element.appendChild( itemElem );\n  msnry.appended( itemElem );\n});\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "sandbox/basic.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>basic</title>\n\n  <link rel=\"stylesheet\" href=\"sandbox.css\" />\n\n</head>\n<body>\n\n  <h1>basic</h1>\n\n  <div id=\"basic\" class=\"container\">\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item w2 h2\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h5\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h5\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n<script src=\"../bower_components/ev-emitter/ev-emitter.js\"></script>\n<script src=\"../bower_components/get-size/get-size.js\"></script>\n<script src=\"../bower_components/desandro-matches-selector/matches-selector.js\"></script>\n<script src=\"../bower_components/fizzy-ui-utils/utils.js\"></script>\n<script src=\"../bower_components/outlayer/item.js\"></script>\n<script src=\"../bower_components/outlayer/outlayer.js\"></script>\n\n<script src=\"../masonry.js\"></script>\n\n<script>\nvar container = document.querySelector('#basic');\nvar msnry = new Masonry( container, {\n  columnWidth: 60\n});\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "sandbox/bottom-up.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>bottom up</title>\n\n  <link rel=\"stylesheet\" href=\"sandbox.css\" />\n\n  <style>\n    #stamped .stamp1 {\n      width: 30%;\n      height: 100px;\n      left: 30%;\n      bottom: 20px;\n    }\n\n    #stamped .stamp2 {\n      width: 200px;\n      height: 50px;\n      left: 20px;\n      bottom: 50px;\n    }\n  </style>\n\n</head>\n<body>\n\n  <h1>bottom up</h1>\n\n  <div id=\"basic\" class=\"container\">\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item w2 h2\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h5\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h5\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n  <div id=\"stamped\" class=\"container\">\n    <div class=\"stamp stamp1\"></div>\n    <div class=\"stamp stamp2\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item w2 h2\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h5\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h5\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n<script src=\"../bower_components/ev-emitter/ev-emitter.js\"></script>\n<script src=\"../bower_components/get-size/get-size.js\"></script>\n<script src=\"../bower_components/desandro-matches-selector/matches-selector.js\"></script>\n<script src=\"../bower_components/fizzy-ui-utils/utils.js\"></script>\n<script src=\"../bower_components/outlayer/item.js\"></script>\n<script src=\"../bower_components/outlayer/outlayer.js\"></script>\n\n<script src=\"../masonry.js\"></script>\n\n<script>\n( function() {\n  var container = document.querySelector('#basic');\n  var msnry = new Masonry( container, {\n    isOriginTop: false,\n    columnWidth: 60\n  });\n})();\n\n( function() {\n  var container = document.querySelector('#stamped');\n  var msnry = new Masonry( container, {\n    itemSelector: '.item',\n    isOriginTop: false,\n    columnWidth: 60,\n    gutter: 10,\n    stamp: '.stamp'\n  });\n})();\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "sandbox/browserify/index.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>browserify</title>\n\n  <link rel=\"stylesheet\" href=\"../sandbox.css\" />\n\n</head>\n<body>\n\n  <h1>browserify</h1>\n\n  <div id=\"basic\" class=\"container\">\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item w2 h2\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h5\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h5\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n<script src=\"bundle.js\"></script>\n\n</body>\n</html>\n"
  },
  {
    "path": "sandbox/browserify/main.js",
    "content": "// vanilla js\n\nvar Masonry = require('../../masonry');\n\nnew Masonry( '#basic', {\n  columnWidth: 60\n});\n\n// jquery\n\n// var $ = require('jquery');\n// var jQBridget = require('jquery-bridget');\n// var Masonry = require('../../masonry');\n//\n// $.bridget( 'masonry', Masonry );\n//\n// $('#basic').masonry({\n//   columnWidth: 60\n// });\n"
  },
  {
    "path": "sandbox/element-sizing.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>element sizing</title>\n\n  <link rel=\"stylesheet\" href=\"sandbox.css\" />\n  <style>\n/*    #container { width: 501px; }*/\n    .item, .grid-sizer { width: 20%; }\n    .item.w2 { width: 40%; }\n    .item.w3 { width: 60%; }\n  </style>\n</head>\n<body>\n\n  <h1>element sizing</h1>\n\n  <div id=\"container\" class=\"container\">\n    <div class=\"grid-sizer\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item w2 h2\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h5\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h5\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n<script src=\"../bower_components/ev-emitter/ev-emitter.js\"></script>\n<script src=\"../bower_components/get-size/get-size.js\"></script>\n<script src=\"../bower_components/desandro-matches-selector/matches-selector.js\"></script>\n<script src=\"../bower_components/fizzy-ui-utils/utils.js\"></script>\n<script src=\"../bower_components/outlayer/item.js\"></script>\n<script src=\"../bower_components/outlayer/outlayer.js\"></script>\n\n<script src=\"../masonry.js\"></script>\n\n<script>\nvar container = document.querySelector('#container');\nvar msnry = new Masonry( container, {\n  columnWidth: '.grid-sizer',\n  percentPosition: true\n});\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "sandbox/fit-width.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>fit width</title>\n\n  <link rel=\"stylesheet\" href=\"sandbox.css\" />\n\n  <style>\n    .container {\n      margin: 0 auto;\n    }\n  </style>\n\n</head>\n<body>\n\n  <h1>fit width</h1>\n\n  <div class=\"container\">\n    <div class=\"item w2\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2 h2\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item w2 h3\"></div>\n    <div class=\"item w4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w4\"></div>\n    <div class=\"item w2 h5\"></div>\n    <div class=\"item w4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item w2 h5\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item w2 h3\"></div>\n    <div class=\"item w4\"></div>\n    <div class=\"item w2\"></div>\n  </div>\n\n<script src=\"../bower_components/ev-emitter/ev-emitter.js\"></script>\n<script src=\"../bower_components/get-size/get-size.js\"></script>\n<script src=\"../bower_components/desandro-matches-selector/matches-selector.js\"></script>\n<script src=\"../bower_components/fizzy-ui-utils/utils.js\"></script>\n<script src=\"../bower_components/outlayer/item.js\"></script>\n<script src=\"../bower_components/outlayer/outlayer.js\"></script>\n\n<script src=\"../masonry.js\"></script>\n\n<script>\nvar msnry = new Masonry( '.container', {\n  fitWidth: true,\n  columnWidth: 120\n});\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "sandbox/fluid.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>fluid</title>\n\n  <style>\n  * {\n    -webkit-box-sizing: border-box;\n            box-sizing: border-box;\n  }\n\n  .grid {\n    background: #DDD;\n  }\n  \n  /* clearfix */\n  .grid:after {\n    display: block;\n    content: '';\n    clear: both;\n  }\n\n\n  .grid-sizer,\n  .grid-item {\n    width: 25%;\n  }\n\n  .grid-item {\n    border: 1px solid;\n    background: #09F;\n    height: 100px;\n  }\n\n  .grid-item--width2 { width: 50%; }\n\n  .grid-item--height2 { height: 160px; }\n\n  .grid-item--height3 { height: 220px; }\n\n  </style>\n\n</head>\n<body>\n\n  <h1>fluid</h1>\n\n  <div class=\"grid\">\n    <div class=\"grid-sizer\"></div>\n    <div class=\"grid-item grid-item--width2\"></div>\n    <div class=\"grid-item\"></div>\n    <div class=\"grid-item grid-item--height3\"></div>\n    <div class=\"grid-item\"></div>\n    <div class=\"grid-item grid-item--width2 grid-item--height2\"></div>\n    <div class=\"grid-item\"></div>\n    <div class=\"grid-item\"></div>\n    <div class=\"grid-item grid-item--width2\"></div>\n    <div class=\"grid-item grid-item--height3\"></div>\n    <div class=\"grid-item\"></div>\n    <div class=\"grid-item\"></div>\n  </div>\n\n\n<script src=\"../bower_components/ev-emitter/ev-emitter.js\"></script>\n<script src=\"../bower_components/get-size/get-size.js\"></script>\n<script src=\"../bower_components/desandro-matches-selector/matches-selector.js\"></script>\n<script src=\"../bower_components/fizzy-ui-utils/utils.js\"></script>\n<script src=\"../bower_components/outlayer/item.js\"></script>\n<script src=\"../bower_components/outlayer/outlayer.js\"></script>\n\n<script src=\"../masonry.js\"></script>\n\n<script>\nvar msnry = new Masonry( '.grid', {\n  columnWidth: '.grid-sizer',\n  percentPosition: true\n});\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "sandbox/horizontal-order.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\" />\n  <meta name=\"viewport\" content=\"width=device-width\" />\n\n  <title>horizontal order</title>\n\n  <style>\n  * { box-sizing: border-box; }\n\n  body { font-family: sans-serif; }\n\n  .grid {\n    background: #DDD;\n    max-width: 900px;\n    margin-bottom: 60px;\n  }\n\n  .grid-item {\n    float: left;\n    width: 150px;\n    height: 150px;\n    border: 1px solid #333;\n    color: white;\n    font-size: 20px;\n    background: #19F;\n    counter-increment: grid-item;\n  }\n\n  .grid-item:before {\n    content: counter(grid-item);\n    padding: 10px;\n  }\n\n  .grid-item--width2 { width: 300px; }\n  .grid-item--width3 { width: 450px; }\n\n  .grid-item--height2 { height: 200px; }\n  .grid-item--height3 { height: 250px; }\n\n  .grid-item.is-zero { height: 0; border: none; }\n\n  .stamp {\n    border: 1px solid #333;\n    background: #E21;\n    position: absolute;\n  }\n\n  .stamp--1 {\n    width: 300px;\n    height: 200px;\n    right: 0;\n    top: 0;\n  }\n  </style>\n\n</head>\n<body>\n\n  <h1>horizontal order</h1>\n\n<div class=\"grid grid--1\">\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height3\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item is-zero\"></div>\n  <div class=\"grid-item grid-item--width2\"></div>\n  <div class=\"grid-item grid-item--height3\"></div>\n  <div class=\"grid-item grid-item--width3\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--width3\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n  <div class=\"grid-item\"></div>\n</div>\n\n<div class=\"grid grid--2\">\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height3\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height3\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height3\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height3\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n</div>\n\n<div class=\"grid grid--3\">\n  <div class=\"stamp stamp--1\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height3\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height3\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height2\"></div>\n  <div class=\"grid-item\"></div>\n  <div class=\"grid-item grid-item--height3\"></div>\n  <div class=\"grid-item\"></div>\n</div>\n\n<script src=\"../bower_components/ev-emitter/ev-emitter.js\"></script>\n<script src=\"../bower_components/get-size/get-size.js\"></script>\n<script src=\"../bower_components/desandro-matches-selector/matches-selector.js\"></script>\n<script src=\"../bower_components/fizzy-ui-utils/utils.js\"></script>\n<script src=\"../bower_components/outlayer/item.js\"></script>\n<script src=\"../bower_components/outlayer/outlayer.js\"></script>\n\n<script src=\"../masonry.js\"></script>\n\n<script>\nnew Masonry( '.grid--1', {\n  itemSelector: '.grid-item',\n  horizontalOrder: true,\n});\n\nnew Masonry( '.grid--2', {\n  itemSelector: '.grid-item',\n  horizontalOrder: true,\n});\n\nnew Masonry( '.grid--3', {\n  itemSelector: '.grid-item',\n  horizontalOrder: true,\n  stamp: '.stamp',\n})\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "sandbox/jquery.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>jQuery</title>\n\n  <link rel=\"stylesheet\" href=\"sandbox.css\" />\n\n</head>\n<body>\n\n  <h1>jQuery</h1>\n\n  <div id=\"basic\" class=\"container\">\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item w2 h2\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h5\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h5\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n<script src=\"../bower_components/jquery/dist/jquery.min.js\"></script>\n<script src=\"../bower_components/jquery-bridget/jquery-bridget.js\"></script>\n\n<script src=\"../bower_components/ev-emitter/ev-emitter.js\"></script>\n<script src=\"../bower_components/get-size/get-size.js\"></script>\n<script src=\"../bower_components/desandro-matches-selector/matches-selector.js\"></script>\n<script src=\"../bower_components/fizzy-ui-utils/utils.js\"></script>\n<script src=\"../bower_components/outlayer/item.js\"></script>\n<script src=\"../bower_components/outlayer/outlayer.js\"></script>\n\n<script src=\"../masonry.js\"></script>\n\n<script>\n$('#basic').masonry({\n  columnWidth: 60\n});\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "sandbox/require-js/index.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>require js</title>\n\n  <link rel=\"stylesheet\" href=\"../sandbox.css\" />\n  <script data-main=\"main\" src=\"https://unpkg.com/requirejs@2.1/require.js\"></script>\n\n</head>\n<body>\n\n  <h1>require js</h1>\n\n  <div id=\"basic\" class=\"container\">\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item w2 h2\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h5\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h5\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n</body>\n</html>\n"
  },
  {
    "path": "sandbox/require-js/main.js",
    "content": "/*global requirejs: false*/\n\n// -------------------------- pkgd -------------------------- //\n\n/*\nrequirejs( [ '../../dist/masonry.pkgd' ], function( Masonry ) {\n  new Masonry( document.querySelector('#basic') );\n});\n// */\n\n// -------------------------- bower -------------------------- //\n\n/*\nrequirejs.config({\n  baseUrl: '../bower_components'\n});\n\nrequirejs( [ '../masonry' ], function( Masonry ) {\n  new Masonry( document.querySelector('#basic') );\n});\n// */\n\n// -------------------------- pkgd & jQuery -------------------------- //\n\n// /*\nrequirejs.config({\n  paths: {\n    jquery: '../../bower_components/jquery/dist/jquery'\n  }\n});\n\nrequirejs( [ 'require', 'jquery', '../../dist/masonry.pkgd' ],\n  function( require, $, Masonry ) {\n    require( [\n      'jquery-bridget/jquery-bridget'\n    ],\n    function() {\n      $.bridget( 'masonry', Masonry );\n      $('#basic').masonry({\n        columnWidth: 60\n      });\n    }\n  );\n});\n// */\n\n// -------------------------- bower & jQuery -------------------------- //\n\n/*\nrequirejs.config({\n  baseUrl: '../bower_components',\n  paths: {\n    jquery: 'jquery/dist/jquery'\n  }\n});\n\nrequirejs( [\n    'jquery',\n    '../masonry',\n    'jquery-bridget/jquery-bridget'\n  ],\n  function( $, Masonry )  {\n    $.bridget( 'masonry', Masonry );\n    $('#basic').masonry({\n      columnWidth: 60\n    });\n  }\n);\n// */"
  },
  {
    "path": "sandbox/right-to-left.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>right to left</title>\n\n  <link rel=\"stylesheet\" href=\"sandbox.css\" />\n\n  <style>\n    #stamped .stamp1 {\n      width: 30%;\n      height: 100px;\n      left: 30%;\n      top: 20px;\n      margin: 10px;\n    }\n\n    #stamped .stamp2 {\n      width: 200px;\n      height: 50px;\n      left: 20px;\n      top: 50px;\n    }\n  </style>\n\n</head>\n<body>\n\n  <h1>right to left</h1>\n\n  <div id=\"basic\" class=\"container\">\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item w2 h2\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h5\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h5\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n  <div id=\"stamped\" class=\"container\">\n    <div class=\"stamp stamp1\"></div>\n    <div class=\"stamp stamp2\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item w2 h2\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h4\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h5\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2 h5\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w3\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n<script src=\"../bower_components/ev-emitter/ev-emitter.js\"></script>\n<script src=\"../bower_components/get-size/get-size.js\"></script>\n<script src=\"../bower_components/desandro-matches-selector/matches-selector.js\"></script>\n<script src=\"../bower_components/fizzy-ui-utils/utils.js\"></script>\n<script src=\"../bower_components/outlayer/item.js\"></script>\n<script src=\"../bower_components/outlayer/outlayer.js\"></script>\n\n<script src=\"../masonry.js\"></script>\n\n<script>\n( function() {\n  var container = document.querySelector('#basic');\n  var msnry = new Masonry( container, {\n    originLeft: false,\n    columnWidth: 60\n  });\n})();\n\n( function() {\n  var container = document.querySelector('#stamped');\n  var msnry = new Masonry( container, {\n    itemSelector: '.item',\n    originLeft: false,\n    columnWidth: 60,\n    gutter: 10,\n    stamp: '.stamp'\n  });\n})();\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "sandbox/sandbox.css",
    "content": "* {\n  box-sizing: border-box;\n}\n\n.container {\n  background: #EEE;\n  width: 50%;\n  margin-bottom: 20px;\n}\n\n.item {\n  width:  60px;\n  height: 60px;\n  float: left;\n  border: 1px solid;\n  background: #09F;\n}\n\n.item.w2 { width: 120px; }\n.item.w3 { width: 180px; }\n.item.w4 { width: 240px; }\n\n.item.h2 { height: 100px; }\n.item.h3 { height: 160px; }\n.item.h4 { height: 220px; }\n.item.h5 { height: 280px; }\n\n.stamp {\n  background: red;\n  opacity: 0.75;\n  position: absolute;\n  border: 1px solid;\n}\n"
  },
  {
    "path": "sandbox/stamps.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>stamps</title>\n\n\n  <link rel=\"stylesheet\" href=\"sandbox.css\" />\n\n  <style>\n\n  #alpha .stamp1 {\n    width: 30%;\n    height: 100px;\n    left: 30%;\n    top: 20px;\n  }\n\n  #alpha .stamp2 {\n    width: 200px;\n    height: 50px;\n    left: 20px;\n    top: 50px;\n  }\n\n  #beta {\n    border-style: solid;\n    border-width: 40px 30px 20px 10px;\n    padding: 10px 20px 30px 40px;\n  }\n\n  #beta .stamp1 {\n    width: 30%;\n    height: 100px;\n    left: 10%;\n    top: 20px;\n  }\n\n  #beta .stamp2 {\n    width: 200px;\n    height: 50px;\n    right: 20px;\n    top: 50px;\n  }\n\n  </style>\n\n</head>\n<body>\n\n  <h1>stamps</h1>\n\n  <div id=\"alpha\" class=\"container\">\n    <div class=\"stamp stamp1\"></div>\n    <div class=\"stamp stamp2\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item h2\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n  <div id=\"beta\" class=\"container\">\n    <div class=\"stamp stamp2\"></div>\n    <div class=\"stamp stamp1\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item h2\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n<script src=\"../bower_components/ev-emitter/ev-emitter.js\"></script>\n<script src=\"../bower_components/get-size/get-size.js\"></script>\n<script src=\"../bower_components/desandro-matches-selector/matches-selector.js\"></script>\n<script src=\"../bower_components/fizzy-ui-utils/utils.js\"></script>\n<script src=\"../bower_components/outlayer/item.js\"></script>\n<script src=\"../bower_components/outlayer/outlayer.js\"></script>\n\n<script src=\"../masonry.js\"></script>\n\n<script>\n( function() {\n  var container = document.querySelector('#alpha');\n  var msnry = new Masonry( container, {\n    itemSelector: '.item',\n    columnWidth: 60,\n    gutter: 10,\n    stamp: '.stamp'\n  });\n\n})();\n( function() {\n  var container = document.querySelector('#beta');\n  var msnry = new Masonry( container, {\n    columnWidth: 60,\n    gutter: 10,\n    stamp: '.stamp'\n  });\n\n})();\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "test/.jshintrc",
    "content": "{\n  \"browser\": true,\n  \"devel\": false,\n  \"undef\": true,\n  \"unused\": true,\n  \"globals\": {\n    \"getSize\": false,\n    \"Masonry\": false,\n    \"checkItemPositions\": false,\n    \"QUnit\": false\n  }\n}\n"
  },
  {
    "path": "test/helpers.js",
    "content": "window.checkItemPositions = function( msnry, assert, positions ) {\n  var i = 0;\n  var position = positions[i];\n  while ( position ) {\n    var style = msnry.items[i].element.style;\n    for ( var prop in position ) {\n      var value = position[ prop ] + 'px';\n      var message = 'item ' + i + ' ' + prop + ' = ' + value;\n      assert.equal( style[ prop ], value, message );\n    }\n    i++;\n    position = positions[i];\n  }\n};\n"
  },
  {
    "path": "test/index.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>Masonry tests</title>\n\n  <link rel=\"stylesheet\" href=\"tests.css\" />\n  <link rel=\"stylesheet\" href=\"../bower_components/qunit/qunit/qunit.css\" />\n\n<script src=\"../bower_components/ev-emitter/ev-emitter.js\"></script>\n<script src=\"../bower_components/get-size/get-size.js\"></script>\n<script src=\"../bower_components/jquery-bridget/jquery-bridget.js\"></script>\n<script src=\"../bower_components/desandro-matches-selector/matches-selector.js\"></script>\n<script src=\"../bower_components/fizzy-ui-utils/utils.js\"></script>\n<script src=\"../bower_components/outlayer/item.js\"></script>\n<script src=\"../bower_components/outlayer/outlayer.js\"></script>\n<script src=\"../bower_components/qunit/qunit/qunit.js\"></script>\n<script src=\"../masonry.js\"></script>\n\n<script src=\"helpers.js\"></script>\n<!-- tests -->\n<script src=\"unit/basic-layout.js\"></script>\n<script src=\"unit/gutter.js\"></script>\n<script src=\"unit/stamp.js\"></script>\n<script src=\"unit/fit-width.js\"></script>\n<script src=\"unit/empty.js\"></script>\n<script src=\"unit/zero-column-width.js\"></script>\n<script src=\"unit/element-sizing.js\"></script>\n<script src=\"unit/pixel-rounding.js\"></script>\n<script src=\"unit/horizontal-order.js\"></script>\n\n</head>\n<body>\n\n  <h1>Masonry tests</h1>\n\n  <div id=\"qunit\"></div>\n\n  <h2>Basic layout top left</h2>\n\n  <div id=\"basic-layout-top-left\" class=\"container basic-layout\">\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w2\"></div>\n  </div>\n\n  <h2>Basic layout top right</h2>\n  <div id=\"basic-layout-top-right\" class=\"container basic-layout\">\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w2\"></div>\n  </div>\n\n  <h2>Basic layout bottom left</h2>\n  <div id=\"basic-layout-bottom-left\" class=\"container basic-layout\">\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w2\"></div>\n  </div>\n\n  <h2>Basic layout bottom right</h2>\n  <div id=\"basic-layout-bottom-right\" class=\"container basic-layout\">\n    <div class=\"item\"></div>\n    <div class=\"item h4\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w2\"></div>\n  </div>\n\n  <h2>Gutter</h2>\n  <div id=\"gutter\" class=\"container has-stamp\">\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item h3\"></div>\n    <div class=\"item w2\"></div>\n  </div>\n\n  <h2>Stamp</h2>\n  <div id=\"stamp-top-left\" class=\"container has-stamp\">\n    <div class=\"stamp stamp1\"></div>\n    <div class=\"stamp stamp2\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n  <div id=\"stamp-column-width-multiple\" class=\"container has-stamp\">\n    <div class=\"stamp stamp1\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n  <div id=\"stamp-bottom-right\" class=\"container has-stamp\">\n    <div class=\"stamp stamp1\"></div>\n    <div class=\"stamp stamp2\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n  <h2>fit width</h2>\n  <div id=\"fit-width\">\n    <div class=\"container\">\n      <div class=\"item\"></div>\n      <div class=\"item h2\"></div>\n      <div class=\"item h3\"></div>\n    </div>\n  </div>\n\n  <h2>Empty</h2>\n  <div id=\"empty\" class=\"container\"></div>\n\n  <h2>zero columnWidth</h2>\n  <div id=\"zero-column-width\" class=\"container\">\n    <div class=\"item hidden\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n  <h2>Element sizing</h2>\n  <div id=\"element-sizing\" class=\"container\">\n    <div class=\"grid-sizer\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item w2\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n  <h2>Pixel rounding</h2>\n  <div id=\"pixel-rounding\" class=\"container\">\n    <div class=\"gutter-sizer\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n    <div class=\"item\"></div>\n  </div>\n\n  <h2>Horizontal order</h2>\n  <div id=\"horizontal-order\" class=\"container\">\n    <div class=\"item h3\">1</div>\n    <div class=\"item h2\">2</div>\n    <div class=\"item\">3</div>\n    <div class=\"item\">4</div>\n    <div class=\"item h3\">5</div>\n    <div class=\"item h2\">6</div>\n    <div class=\"item\">7</div>\n    <div class=\"item\">8</div>\n    <div class=\"item\">9</div>\n  </div>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "test/tests.css",
    "content": "* {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\nbody {\n  font-family: sans-serif;\n}\n\n.container {\n  background: #EEE;\n  width: 180px;\n  margin-bottom: 20px;\n  position: relative;\n}\n\n.item {\n  width:  60px;\n  height: 30px;\n  float: left;\n  border: 1px solid;\n  background: #09F;\n}\n\n.item.w2 { width: 120px; }\n.item.w3 { width: 180px; }\n\n.item.h2 { height:  50px; }\n.item.h3 { height:  70px; }\n.item.h4 { height:  90px; }\n.item.h5 { height: 110px; }\n\n.stamp {\n  background: red;\n  opacity: 0.75;\n  position: absolute;\n  border: 1px solid;\n}\n\n\n/* ---- gutter ---- */\n\n#gutter {\n  width: 220px;\n}\n\n#gutter .item.w2 { width: 140px; }\n\n/* ---- stamp ---- */\n\n.has-stamp .item { width: 45px; }\n\n/* stout, in the middle */\n.has-stamp .stamp1 {\n  width: 40px;\n  height: 30px;\n}\n\n/* really wide */\n.has-stamp .stamp2 {\n  width: 200px;\n  height: 20px;\n}\n\n#stamp-top-left .stamp1 {\n  left: 70px;\n  top: 10px;\n}\n\n#stamp-top-left .stamp2 {\n  left: -5px;\n  top: 0;\n}\n\n#stamp-column-width-multiple .stamp1 {\n  width: 90px;\n  left: 45px;\n  top: 0;\n}\n\n#stamp-bottom-right .stamp1 {\n  right: 70px;\n  bottom: 10px;\n}\n\n#stamp-bottom-right .stamp2 {\n  right: -5px;\n  bottom: 0;\n}\n\n/* ---- fit width ---- */\n\n#fit-width {\n  width: 160px;\n  background: #CCC;\n}\n\n#fit-width .container {\n  margin: 0 auto;\n}\n\n/* ----  ---- */\n\n#zero-column-width .hidden {\n  display: none;\n}\n\n/* ---- element-sizing ---- */\n\n#element-sizing {\n  width: 181px;\n}\n\n#element-sizing .item,\n#element-sizing .grid-sizer { width: 20%; }\n\n#element-sizing .item.w2 { width: 40%; }\n\n/* ---- pixel-rounding ---- */\n\n#pixel-rounding {\n  width: 170px;\n}\n\n#pixel-rounding .item { width: 28.667%; }\n#pixel-rounding .gutter-sizer { width: 7%; }\n"
  },
  {
    "path": "test/unit/basic-layout.js",
    "content": "QUnit.test( 'basic layout top left', function( assert ) {\n  var msnry = new Masonry( '#basic-layout-top-left', {\n    columnWidth: 60\n  });\n\n  checkItemPositions( msnry, assert, {\n    0: {\n      left: 0,\n      top: 0\n    },\n    1: {\n      left: 60,\n      top: 0\n    },\n    2: {\n      left: 120,\n      top: 0\n    },\n    3: {\n      left: 0,\n      top: 30\n    },\n    4: {\n      left: 60,\n      top: 90\n    }\n  });\n\n});\n\nQUnit.test( 'basic layout top right', function( assert ) {\n  var msnry = new Masonry( '#basic-layout-top-right', {\n    isOriginLeft: false,\n    columnWidth: 60\n  });\n\n  checkItemPositions( msnry, assert, {\n    0: {\n      right: 0,\n      top: 0\n    },\n    1: {\n      right: 60,\n      top: 0\n    },\n    2: {\n      right: 120,\n      top: 0\n    },\n    3: {\n      right: 0,\n      top: 30\n    },\n    4: {\n      right: 60,\n      top: 90\n    }\n  });\n\n});\n\nQUnit.test( 'basic layout bottom left', function( assert ) {\n  var msnry = new Masonry( '#basic-layout-bottom-left', {\n    isOriginTop: false,\n    columnWidth: 60\n  });\n\n  checkItemPositions( msnry, assert, {\n    0: {\n      left: 0,\n      bottom: 0\n    },\n    1: {\n      left: 60,\n      bottom: 0\n    },\n    2: {\n      left: 120,\n      bottom: 0\n    },\n    3: {\n      left: 0,\n      bottom: 30\n    },\n    4: {\n      left: 60,\n      bottom: 90\n    }\n  });\n\n});\n\nQUnit.test( 'basic layout bottom right', function( assert ) {\n  var msnry = new Masonry( '#basic-layout-bottom-right', {\n    isOriginLeft: false,\n    isOriginTop: false,\n    columnWidth: 60\n  });\n\n  checkItemPositions( msnry, assert, {\n    0: {\n      right: 0,\n      bottom: 0\n    },\n    1: {\n      right: 60,\n      bottom: 0\n    },\n    2: {\n      right: 120,\n      bottom: 0\n    },\n    3: {\n      right: 0,\n      bottom: 30\n    },\n    4: {\n      right: 60,\n      bottom: 90\n    }\n  });\n\n});\n"
  },
  {
    "path": "test/unit/element-sizing.js",
    "content": "QUnit.test( 'element sizing', function( assert ) {\n  var container = document.querySelector('#element-sizing');\n  var msnry = new Masonry( container, {\n    columnWidth: '.grid-sizer',\n    itemSelector: '.item',\n    transitionDuration: 0\n  });\n\n  var lastItem = msnry.items[3];\n\n  var containerWidth = 170;\n  while ( containerWidth < 190 ) {\n    container.style.width = containerWidth + 'px';\n    msnry.layout();\n    assert.equal( lastItem.position.y, 0,'4th item on top row, container width = ' + containerWidth );\n    containerWidth++;\n  }\n\n});\n"
  },
  {
    "path": "test/unit/empty.js",
    "content": "QUnit.test( 'empty', function( assert ) {\n\n  var container = document.querySelector('#empty');\n  var msnry = new Masonry( container );\n\n  assert.ok( true, 'empty masonry did not throw error' );\n  assert.equal( msnry.columnWidth, getSize( container ).innerWidth, 'columnWidth = innerWidth' );\n\n});\n"
  },
  {
    "path": "test/unit/fit-width.js",
    "content": "QUnit.test( 'fit width', function( assert ) {\n\n  var container = document.querySelector('#fit-width .container');\n  var msnry = new Masonry( container, {\n    columnWidth: 60,\n    isFitWidth: true\n  });\n\n  assert.equal( msnry.cols, 2, '2 columns' );\n  assert.equal( msnry.cols * msnry.columnWidth + 'px', container.style.width, 'width set to match' );\n\n});\n"
  },
  {
    "path": "test/unit/gutter.js",
    "content": "QUnit.test( 'gutter', function( assert ) {\n\n  var msnry = new Masonry( '#gutter', {\n    columnWidth: 60,\n    gutter: 20\n  });\n\n  checkItemPositions( msnry, assert, {\n    0: { left: 0, top: 0 },\n    1: { left: 80, top: 0 },\n    2: { left: 160, top: 0 },\n    3: { left: 0, top: 30 }\n  });\n\n});\n"
  },
  {
    "path": "test/unit/horizontal-order.js",
    "content": "QUnit.test( 'horizontal order', function( assert ) {\n\n  var grid = document.querySelector('#horizontal-order');\n  var itemElems = grid.querySelectorAll('.item');\n  new Masonry( grid, {\n    horizontalOrder: true,\n  });\n\n  // items should match %3 column\n  for ( var i=0; i < itemElems.length; i++ ) {\n    var itemElem = itemElems[i];\n    var col = i % 3;\n    var left = col * 60 + 'px';\n    var message = 'item ' + (i+1) + ', column' + (col + 1);\n    assert.equal( itemElem.style.left, left, message );\n  }\n\n});\n"
  },
  {
    "path": "test/unit/pixel-rounding.js",
    "content": "QUnit.test( 'pixel rounding', function( assert ) {\n  var container = document.querySelector('#pixel-rounding');\n  var msnry = new Masonry( container, {\n    gutter: '.gutter-sizer',\n    itemSelector: '.item',\n    transitionDuration: 0\n  });\n\n  var lastItem = msnry.items[2];\n\n  var containerWidth = 170;\n  while ( containerWidth < 210 ) {\n    container.style.width = containerWidth + 'px';\n    msnry.layout();\n    assert.equal( lastItem.position.y, 0,'3rd item on top row, container width = ' + containerWidth );\n    containerWidth++;\n  }\n\n});\n"
  },
  {
    "path": "test/unit/stamp.js",
    "content": "QUnit.test( 'stamp top left', function( assert ) {\n\n  var msnry = new Masonry( '#stamp-top-left', {\n    itemSelector: '.item',\n    stamp: '.stamp'\n  });\n\n  checkItemPositions( msnry, assert, {\n    0: { left: 0, top: 20 },\n    1: { left: 135, top: 20 },\n    2: { left: 45, top: 40 },\n    3: { left: 90, top: 40 }\n  });\n\n});\n\nQUnit.test( 'stamp columnWidth multiple', function( assert ) {\n\n  var msnry = new Masonry( '#stamp-column-width-multiple', {\n    itemSelector: '.item',\n    stamp: '.stamp'\n  });\n\n  checkItemPositions( msnry, assert, {\n    0: { left: 0, top: 0 },\n    1: { left: 135, top: 0 },\n    2: { left: 0, top: 30 },\n    3: { left: 45, top: 30 }\n  });\n\n});\n\nQUnit.test( 'stamp bottom right', function( assert ) {\n\n  var msnry = new Masonry( '#stamp-bottom-right', {\n    itemSelector: '.item',\n    stamp: '.stamp',\n    isOriginLeft: false,\n    isOriginTop: false\n  });\n\n  checkItemPositions( msnry, assert, {\n    0: { right: 0, bottom: 20 },\n    1: { right: 135, bottom: 20 },\n    2: { right: 45, bottom: 40 },\n    3: { right: 90, bottom: 40 }\n  });\n\n});\n"
  },
  {
    "path": "test/unit/zero-column-width.js",
    "content": "QUnit.test( 'zero column width', function( assert ) {\n  var msnry = new Masonry( '#zero-column-width' );\n  assert.equal( msnry.columnWidth, 180, 'columnWidth = container innerWidth');\n});\n"
  }
]